diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/config.mk u-boot-2011.06/arch/arm/config.mk
--- u-boot-2011.06_original/arch/arm/config.mk	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/config.mk	2014-07-29 17:28:38.819972000 +0800
@@ -21,7 +21,8 @@
 # MA 02111-1307 USA
 #
 
-CROSS_COMPILE ?= arm-linux-
+#CROSS_COMPILE ?= arm-linux-
+CROSS_COMPILE ?= arm-none-eabi-
 
 ifndef CONFIG_STANDALONE_LOAD_ADDR
 ifeq ($(SOC),omap3)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/debug.c u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/debug.c
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/debug.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/debug.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,18 @@
+#include <common.h>
+
+void debug_enable(void)
+{
+    unsigned long i;
+    asm ("mrc p15, 0, %0, c1, c1, 0":"=r" (i));
+    i |= 0x1;
+    asm ("mcr p15, 0, %0, c1, c1, 0": :"r" (i));
+}
+
+void debug_disable(void)
+{
+    unsigned long i;
+    asm ("mrc p15, 0, %0, c1, c1, 0":"=r" (i));
+    i &= (~0x1);
+    asm ("mcr p15, 0, %0, c1, c1, 0": :"r" (i));
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/interrupts.c u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/interrupts.c
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/interrupts.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/interrupts.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,7 @@
+#include <common.h>
+
+void do_irq (struct pt_regs *pt_regs)
+{
+    cnc1800l_do_interrupt();
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/Makefile u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/Makefile
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,46 @@
+#
+# (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)lib$(SOC).o
+
+COBJS	= timer.o debug.o 
+SOBJS	= reset.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/reset.S u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/reset.S
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/reset.S	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/reset.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,22 @@
+#include <config.h>
+/*
+ * Processor reset for Nomadik
+ */
+
+	.align 5
+.globl reset_cpu
+reset_cpu:
+	ldr  r1, WDT_BASE
+	mov  r2, #0
+	strh r2, [r1, #0x4]        /* WDT_TORR, minimum value */
+	strh r2, [r1, #0x6]
+	strh r2, [r1, #0x8]        /* WDT_CCVR, minimum value */
+	strh r2, [r1, #0xa]
+	mov  r2, #1
+	strh r2, [r1, #0x0]        /* WDT_CR, enable WDT and generated System Reset */
+
+_loop_forever:
+	b	_loop_forever
+
+WDT_BASE:
+	.word   0x801e1000
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/timer.c u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/timer.c
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cnc1800l/timer.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cnc1800l/timer.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,225 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.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
+ */
+
+#include <common.h>
+
+#define TIMER_CLOCK             (378000000 / 8)
+#define COUNT_TO_USEC(x)        ((x) * 4 / 189)
+#define USEC_TO_COUNT(x)        ((x) * 189 / 4)
+#define TICKS_PER_HZ            (TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)          ((x) / TICKS_PER_HZ)
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the decrementing 32 bit timer as an increasing count */
+#define READ_TIMER()  ((ulong)((ulong)0xffffffff - cnc1800l_apb_read32(CONFIG_SYS_TIMERBASE+4))) //
+
+static ulong timestamp;
+static ulong lastdec;
+
+/* ORION only support 8/16bit write to APB bus */
+static void cnc1800l_apb_write32(ulong addr, ulong data)
+{
+    *(volatile ushort *)(addr + 0) = (ushort)(data);
+    *(volatile ushort *)(addr + 2) = (ushort)(data >> 16);
+}
+
+static ulong cnc1800l_apb_read32(ulong addr)
+{
+
+    ulong timeval_high,timeval_high2, timeval;
+
+    timeval_high = *(volatile ushort *)(addr + 2);
+
+    timeval =  *(volatile ushort *)(addr);
+
+    timeval_high2= *((volatile ushort *)(addr + 2));
+
+    if (timeval_high2  != timeval_high) { 
+        timeval = (timeval_high2 << 16) | (*(volatile ushort *)(addr));
+    } 
+    else
+        timeval = timeval_high << 16 | timeval;
+
+
+    return timeval;
+}
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init (void)
+{
+	cnc1800l_apb_write32((CONFIG_SYS_TIMERBASE + 0), CONFIG_SYS_TIMER_RELOAD);	/* TimerLoad */
+	cnc1800l_apb_write32((CONFIG_SYS_TIMERBASE + 4), CONFIG_SYS_TIMER_RELOAD);	/* TimerValue */
+	cnc1800l_apb_write32((CONFIG_SYS_TIMERBASE + 8), 0x1);
+
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+#if 0
+ulong get_timer (ulong base)
+{
+	return get_timer_masked () - base;
+}
+#else
+ulong get_timer (ulong base)
+{
+    return  TICKS_TO_HZ(READ_TIMER()) - base;
+}
+#endif
+
+ulong get_timer_u(ulong base)
+{
+	return COUNT_TO_USEC(READ_TIMER()- base);
+}
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+#if 0
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay (unsigned long usec)
+{
+	ulong tmo, tmp;
+
+    tmo = usec * (CONFIG_SYS_PCLK_FREQ / (1000 * 1000));
+
+	tmp = get_timer (0);		/* get current timestamp */
+	if( (tmo + tmp + 1) < tmp )	/* if setting this fordward will roll time stamp */
+		reset_timer_masked ();	/* reset "advancing" timestamp to 0, set lastdec value */
+	else
+		tmo += tmp;		/* else, set advancing stamp wake up time */
+
+	while (get_timer_masked () < tmo)/* loop till event */
+		/*NOP*/;
+}
+#else
+void __udelay (unsigned long usec)
+{
+	ulong ini, end;
+
+	ini = READ_TIMER();
+	end = ini + USEC_TO_COUNT(usec);
+	while ((signed)(end - READ_TIMER()) > 0)
+		;
+}
+#endif
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	lastdec = READ_TIMER();  /* capure current decrementer value time */
+	timestamp = 0;	       /* start "advancing" time stamp from 0 */
+}
+
+#if 0
+ulong get_timer_masked (void)
+{
+	ulong now = READ_TIMER();		/* current tick value */
+
+	if (lastdec >= now) {		/* normal mode (non roll) */
+		/* normal mode */
+		timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
+	} else {			/* we have overflow of the count down timer */
+		/* nts = ts + ld + (TLV - now)
+		 * ts=old stamp, ld=time that passed before passing through -1
+		 * (TLV-now) amount of time after passing though -1
+		 * nts = new "advancing time stamp"...it could also roll and cause problems.
+		 */
+		timestamp += lastdec + TIMER_LOAD_VAL - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked (unsigned long usec)
+{
+	ulong tmo;
+	ulong endtime;
+	signed long diff;
+
+    tmo = usec * (CONFIG_SYS_HZ / (1000 * 1000));
+
+	endtime = get_timer_masked () + tmo;
+
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
+}
+#endif
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+ 
+unsigned long long get_ticks_u(void)
+{
+	return get_timer_u(0);
+}
+
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+	ulong tbclk;
+
+	tbclk = CONFIG_SYS_HZ;
+	return tbclk;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm1176/cpu.c u-boot-2011.06/arch/arm/cpu/arm1176/cpu.c
--- u-boot-2011.06_original/arch/arm/cpu/arm1176/cpu.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm1176/cpu.c	2014-07-29 17:28:38.819972000 +0800
@@ -57,6 +57,8 @@
 	return 0;
 }
 
+
+
 /* flush I/D-cache */
 static void cache_flush (void)
 {
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/interrupts.c u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/interrupts.c
--- u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/interrupts.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/interrupts.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,7 @@
+#include <common.h>
+
+void do_irq (struct pt_regs *pt_regs)
+{
+    orion_do_interrupt();
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/Makefile u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/Makefile
--- u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,46 @@
+#
+# (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)lib$(SOC).o
+
+COBJS	= timer.o interrupts.o
+SOBJS	= reset.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/reset.S u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/reset.S
--- u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/reset.S	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/reset.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,22 @@
+#include <config.h>
+/*
+ * Processor reset for Nomadik
+ */
+
+	.align 5
+.globl reset_cpu
+reset_cpu:
+	ldr  r1, WDT_BASE
+	mov  r2, #0
+	strh r2, [r1, #0x4]        /* WDT_TORR, minimum value */
+	strh r2, [r1, #0x6]
+	strh r2, [r1, #0x8]        /* WDT_CCVR, minimum value */
+	strh r2, [r1, #0xa]
+	mov  r2, #1
+	strh r2, [r1, #0x0]        /* WDT_CR, enable WDT and generated System Reset */
+
+_loop_forever:
+	b	_loop_forever
+
+WDT_BASE:
+	.word   0x101e1000
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/timer.c u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/timer.c
--- u-boot-2011.06_original/arch/arm/cpu/arm926ejs/csm1800h/timer.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm926ejs/csm1800h/timer.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,201 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.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
+ */
+
+#include <common.h>
+
+#define TIMER_CLOCK             (378000000 / 8)
+#define COUNT_TO_USEC(x)        ((x) * 4 / 189)
+#define USEC_TO_COUNT(x)        ((x) * 189 / 4)
+#define TICKS_PER_HZ            (TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)          ((x) / TICKS_PER_HZ)
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the decrementing 32 bit timer as an increasing count */
+#define READ_TIMER()  (0 - orion_apb_read32(CONFIG_SYS_TIMERBASE+4))
+
+static ulong timestamp;
+static ulong lastdec;
+
+/* ORION only support 8/16bit write to APB bus */
+static void orion_apb_write32(ulong addr, ulong data)
+{
+    *(volatile ushort *)(addr + 0) = (ushort)(data);
+    *(volatile ushort *)(addr + 2) = (ushort)(data >> 16);
+}
+
+static ulong orion_apb_read32(ulong addr)
+{
+    ulong data;
+    data  = *(volatile ushort *)(addr + 0);
+    data |= (*(volatile ushort *)(addr + 2) << 16);
+    return data;
+}
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init (void)
+{
+	orion_apb_write32((CONFIG_SYS_TIMERBASE + 0), CONFIG_SYS_TIMER_RELOAD);	/* TimerLoad */
+	orion_apb_write32((CONFIG_SYS_TIMERBASE + 4), CONFIG_SYS_TIMER_RELOAD);	/* TimerValue */
+	orion_apb_write32((CONFIG_SYS_TIMERBASE + 8), 0x1);
+
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+#if 0
+ulong get_timer (ulong base)
+{
+	return get_timer_masked () - base;
+}
+#else
+ulong get_timer (ulong base)
+{
+    return  TICKS_TO_HZ(READ_TIMER()) - base;
+}
+#endif
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+#if 0
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay (unsigned long usec)
+{
+	ulong tmo, tmp;
+
+    tmo = usec * (CONFIG_SYS_PCLK_FREQ / (1000 * 1000));
+
+	tmp = get_timer (0);		/* get current timestamp */
+	if( (tmo + tmp + 1) < tmp )	/* if setting this fordward will roll time stamp */
+		reset_timer_masked ();	/* reset "advancing" timestamp to 0, set lastdec value */
+	else
+		tmo += tmp;		/* else, set advancing stamp wake up time */
+
+	while (get_timer_masked () < tmo)/* loop till event */
+		/*NOP*/;
+}
+#else
+void __udelay (unsigned long usec)
+{
+	ulong ini, end;
+
+	ini = READ_TIMER();
+	end = ini + USEC_TO_COUNT(usec);
+	while ((signed)(end - READ_TIMER()) > 0)
+		;
+}
+#endif
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	lastdec = READ_TIMER();  /* capure current decrementer value time */
+	timestamp = 0;	       /* start "advancing" time stamp from 0 */
+}
+
+#if 0
+ulong get_timer_masked (void)
+{
+	ulong now = READ_TIMER();		/* current tick value */
+
+	if (lastdec >= now) {		/* normal mode (non roll) */
+		/* normal mode */
+		timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
+	} else {			/* we have overflow of the count down timer */
+		/* nts = ts + ld + (TLV - now)
+		 * ts=old stamp, ld=time that passed before passing through -1
+		 * (TLV-now) amount of time after passing though -1
+		 * nts = new "advancing time stamp"...it could also roll and cause problems.
+		 */
+		timestamp += lastdec + TIMER_LOAD_VAL - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked (unsigned long usec)
+{
+	ulong tmo;
+	ulong endtime;
+	signed long diff;
+
+    tmo = usec * (CONFIG_SYS_HZ / (1000 * 1000));
+
+	endtime = get_timer_masked () + tmo;
+
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
+}
+#endif
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+	ulong tbclk;
+
+	tbclk = CONFIG_SYS_HZ;
+	return tbclk;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/arm926ejs/start.S u-boot-2011.06/arch/arm/cpu/arm926ejs/start.S
--- u-boot-2011.06_original/arch/arm/cpu/arm926ejs/start.S	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/arm926ejs/start.S	2014-07-29 17:28:38.819972000 +0800
@@ -175,6 +175,24 @@
 	bl	cpu_init_crit
 #endif
 
+#ifdef CONFIG_ARCH_CSM1800
+
+#define PINMUX_UART_ENABLE     0x42110008
+#define PINMUX_ETHER_ENABLE    0x42110020
+
+/* set pinmux to enable uart 0 */
+	ldr  r0,=(PINMUX_UART_ENABLE)
+	mov  r1,#1
+	str  r1,[r0]
+
+/* set pinmux to enable ethernet */
+	ldr  r0,=(PINMUX_ETHER_ENABLE)
+	mov  r1,#0
+	str  r1,[r0]
+
+
+#endif
+
 /* Set stackpointer in internal RAM to call board_init_f */
 call_board_init_f:
 	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
@@ -268,9 +286,10 @@
 	add	r0, r0, #4
 	cmp	r0, r1
 	bne	clbss_l
-
+/*
 	bl coloured_LED_init
 	bl red_LED_on
+*/
 #endif
 
 /*
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cache_v7.c u-boot-2011.06/arch/arm/cpu/armv7/cache_v7.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cache_v7.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cache_v7.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,394 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <linux/types.h>
+#include <common.h>
+#include <asm/armv7.h>
+#include <asm/utils.h>
+
+#define ARMV7_DCACHE_INVAL_ALL		1
+#define ARMV7_DCACHE_CLEAN_INVAL_ALL	2
+#define ARMV7_DCACHE_INVAL_RANGE	3
+#define ARMV7_DCACHE_CLEAN_INVAL_RANGE	4
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+/*
+ * Write the level and type you want to Cache Size Selection Register(CSSELR)
+ * to get size details from Current Cache Size ID Register(CCSIDR)
+ */
+static void set_csselr(u32 level, u32 type)
+{	u32 csselr = level << 1 | type;
+
+	/* Write to Cache Size Selection Register(CSSELR) */
+	asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr));
+}
+
+static u32 get_ccsidr(void)
+{
+	u32 ccsidr;
+
+	/* Read current CP15 Cache Size ID Register */
+	asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
+	return ccsidr;
+}
+
+static u32 get_clidr(void)
+{
+	u32 clidr;
+
+	/* Read current CP15 Cache Level ID Register */
+	asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr));
+	return clidr;
+}
+
+static void v7_inval_dcache_level_setway(u32 level, u32 num_sets,
+					 u32 num_ways, u32 way_shift,
+					 u32 log2_line_len)
+{
+	int way, set, setway;
+
+	/*
+	 * For optimal assembly code:
+	 *	a. count down
+	 *	b. have bigger loop inside
+	 */
+	for (way = num_ways - 1; way >= 0 ; way--) {
+		for (set = num_sets - 1; set >= 0; set--) {
+			setway = (level << 1) | (set << log2_line_len) |
+				 (way << way_shift);
+			/* Invalidate data/unified cache line by set/way */
+			asm volatile ("	mcr p15, 0, %0, c7, c6, 2"
+					: : "r" (setway));
+		}
+	}
+	/* DSB to make sure the operation is complete */
+	CP15DSB;
+}
+
+static void v7_clean_inval_dcache_level_setway(u32 level, u32 num_sets,
+					       u32 num_ways, u32 way_shift,
+					       u32 log2_line_len)
+{
+	int way, set, setway;
+
+	/*
+	 * For optimal assembly code:
+	 *	a. count down
+	 *	b. have bigger loop inside
+	 */
+	for (way = num_ways - 1; way >= 0 ; way--) {
+		for (set = num_sets - 1; set >= 0; set--) {
+			setway = (level << 1) | (set << log2_line_len) |
+				 (way << way_shift);
+			/*
+			 * Clean & Invalidate data/unified
+			 * cache line by set/way
+			 */
+			asm volatile ("	mcr p15, 0, %0, c7, c14, 2"
+					: : "r" (setway));
+		}
+	}
+	/* DSB to make sure the operation is complete */
+	CP15DSB;
+}
+
+static void v7_maint_dcache_level_setway(u32 level, u32 operation)
+{
+	u32 ccsidr;
+	u32 num_sets, num_ways, log2_line_len, log2_num_ways;
+	u32 way_shift;
+
+	set_csselr(level, ARMV7_CSSELR_IND_DATA_UNIFIED);
+
+	ccsidr = get_ccsidr();
+
+	log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >>
+				CCSIDR_LINE_SIZE_OFFSET) + 2;
+	/* Converting from words to bytes */
+	log2_line_len += 2;
+
+	num_ways  = ((ccsidr & CCSIDR_ASSOCIATIVITY_MASK) >>
+			CCSIDR_ASSOCIATIVITY_OFFSET) + 1;
+	num_sets  = ((ccsidr & CCSIDR_NUM_SETS_MASK) >>
+			CCSIDR_NUM_SETS_OFFSET) + 1;
+	/*
+	 * According to ARMv7 ARM number of sets and number of ways need
+	 * not be a power of 2
+	 */
+	log2_num_ways = log_2_n_round_up(num_ways);
+
+	way_shift = (32 - log2_num_ways);
+	if (operation == ARMV7_DCACHE_INVAL_ALL) {
+		v7_inval_dcache_level_setway(level, num_sets, num_ways,
+				      way_shift, log2_line_len);
+	} else if (operation == ARMV7_DCACHE_CLEAN_INVAL_ALL) {
+		v7_clean_inval_dcache_level_setway(level, num_sets, num_ways,
+						   way_shift, log2_line_len);
+	}
+}
+
+static void v7_maint_dcache_all(u32 operation)
+{
+	u32 level, cache_type, level_start_bit = 0;
+
+	u32 clidr = get_clidr();
+
+	for (level = 0; level < 7; level++) {
+		cache_type = (clidr >> level_start_bit) & 0x7;
+		if ((cache_type == ARMV7_CLIDR_CTYPE_DATA_ONLY) ||
+		    (cache_type == ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA) ||
+		    (cache_type == ARMV7_CLIDR_CTYPE_UNIFIED))
+			v7_maint_dcache_level_setway(level, operation);
+		level_start_bit += 3;
+	}
+}
+
+static void v7_dcache_clean_inval_range(u32 start,
+					u32 stop, u32 line_len)
+{
+	u32 mva;
+
+	/* Align start to cache line boundary */
+	start &= ~(line_len - 1);
+	for (mva = start; mva < stop; mva = mva + line_len) {
+		/* DCCIMVAC - Clean & Invalidate data cache by MVA to PoC */
+		asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (mva));
+	}
+}
+
+static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
+{
+	u32 mva;
+
+	/*
+	 * If start address is not aligned to cache-line do not
+	 * invalidate the first cache-line
+	 */
+	if (start & (line_len - 1)) {
+		printf("ERROR: %s - start address is not aligned - 0x%08x\n",
+			__func__, start);
+		/* move to next cache line */
+		start = (start + line_len - 1) & ~(line_len - 1);
+	}
+
+	/*
+	 * If stop address is not aligned to cache-line do not
+	 * invalidate the last cache-line
+	 */
+	if (stop & (line_len - 1)) {
+		printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
+			__func__, stop);
+		/* align to the beginning of this cache line */
+		stop &= ~(line_len - 1);
+	}
+
+	for (mva = start; mva < stop; mva = mva + line_len) {
+		/* DCIMVAC - Invalidate data cache by MVA to PoC */
+		asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (mva));
+	}
+}
+
+static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
+{
+	u32 line_len, ccsidr;
+
+	ccsidr = get_ccsidr();
+	line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >>
+			CCSIDR_LINE_SIZE_OFFSET) + 2;
+	/* Converting from words to bytes */
+	line_len += 2;
+	/* converting from log2(linelen) to linelen */
+	line_len = 1 << line_len;
+
+	switch (range_op) {
+	case ARMV7_DCACHE_CLEAN_INVAL_RANGE:
+		v7_dcache_clean_inval_range(start, stop, line_len);
+		break;
+	case ARMV7_DCACHE_INVAL_RANGE:
+		v7_dcache_inval_range(start, stop, line_len);
+		break;
+	}
+
+	/* DSB to make sure the operation is complete */
+	CP15DSB;
+}
+
+/* Invalidate TLB */
+static void v7_inval_tlb(void)
+{
+	/* Invalidate entire unified TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+	/* Invalidate entire data TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
+	/* Invalidate entire instruction TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
+	/* Full system DSB - make sure that the invalidation is complete */
+	CP15DSB;
+	/* Full system ISB - make sure the instruction stream sees it */
+	CP15ISB;
+}
+
+void invalidate_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
+
+	v7_outer_cache_inval_all();
+}
+
+/*
+ * Performs a clean & invalidation of the entire data cache
+ * at all levels
+ */
+void flush_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_CLEAN_INVAL_ALL);
+
+	v7_outer_cache_flush_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache used:
+ * Affects the range [start, stop - 1]
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE);
+
+	v7_outer_cache_inval_range(start, stop);
+}
+
+/*
+ * Flush range(clean & invalidate) from all levels of D-cache/unified
+ * cache used:
+ * Affects the range [start, stop - 1]
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_CLEAN_INVAL_RANGE);
+
+	v7_outer_cache_flush_range(start, stop);
+}
+
+void arm_init_before_mmu(void)
+{
+	v7_outer_cache_enable();
+	invalidate_dcache_all();
+	v7_inval_tlb();
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+	flush_dcache_range(start, stop);
+	v7_inval_tlb();
+}
+
+/*
+ * Flush range from all levels of d-cache/unified-cache used:
+ * Affects the range [start, start + size - 1]
+ */
+void  flush_cache(unsigned long start, unsigned long size)
+{
+	flush_dcache_range(start, start + size);
+}
+#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void arm_init_before_mmu(void)
+{
+}
+
+void  flush_cache(unsigned long start, unsigned long size)
+{
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+}
+
+void arm_init_domains(void)
+{
+}
+#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
+
+#ifndef CONFIG_SYS_ICACHE_OFF
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+	/*
+	 * Invalidate all instruction caches to PoU.
+	 * Also flushes branch target cache.
+	 */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+
+	/* Invalidate entire branch predictor array */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
+
+	/* Full system DSB - make sure that the invalidation is complete */
+	CP15DSB;
+
+	/* ISB - make sure the instruction stream sees it */
+	CP15ISB;
+}
+#else
+void invalidate_icache_all(void)
+{
+}
+#endif
+
+/*
+ * Stub implementations for outer cache operations
+ */
+void __v7_outer_cache_enable(void)
+{
+}
+void v7_outer_cache_enable(void)
+	__attribute__((weak, alias("__v7_outer_cache_enable")));
+
+void __v7_outer_cache_disable(void)
+{
+}
+void v7_outer_cache_disable(void)
+	__attribute__((weak, alias("__v7_outer_cache_disable")));
+
+void __v7_outer_cache_flush_all(void)
+{
+}
+void v7_outer_cache_flush_all(void)
+	__attribute__((weak, alias("__v7_outer_cache_flush_all")));
+
+void __v7_outer_cache_inval_all(void)
+{
+}
+void v7_outer_cache_inval_all(void)
+	__attribute__((weak, alias("__v7_outer_cache_inval_all")));
+
+void __v7_outer_cache_flush_range(u32 start, u32 end)
+{
+}
+void v7_outer_cache_flush_range(u32 start, u32 end)
+	__attribute__((weak, alias("__v7_outer_cache_flush_range")));
+
+void __v7_outer_cache_inval_range(u32 start, u32 end)
+{
+}
+void v7_outer_cache_inval_range(u32 start, u32 end)
+	__attribute__((weak, alias("__v7_outer_cache_inval_range")));
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/interrupts.c u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/interrupts.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/interrupts.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/interrupts.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,6 @@
+#include <common.h>
+void do_irq (struct pt_regs *pt_regs)
+{
+    extern int cnc1900_do_interrupt(void);
+    cnc1900_do_interrupt();
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/Makefile u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/Makefile
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,46 @@
+#
+# (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)lib$(SOC).o
+
+COBJS	= timer.o soc.o interrupts.o
+SOBJS	= reset.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/reset.S u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/reset.S
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/reset.S	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/reset.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,19 @@
+#include <config.h>
+/*
+ * Processor reset for CNC1900
+ */
+
+	.align 5
+.globl reset_cpu
+reset_cpu:
+	ldr  r1, WDT_BASE
+	mov  r2, #9
+	str r2, [r1, #0x28]        /* WDT_CR, enable WDT and generated System Reset */
+	mov  r2, #1
+	str r2, [r1, #0x20]        /* WDT_TORR, minimum value */
+
+_loop_forever:
+	b	_loop_forever
+
+WDT_BASE:
+	.word   0x80020600
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/soc.c u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/soc.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/soc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/soc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#include <common.h>
+#include <errno.h>
+
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
+
+#if defined(CONFIG_DRIVER_CN100)
+extern int cn100_initialize(bd_t *bis, int index);
+#endif
+
+int cpu_eth_init(bd_t *bis)
+{
+	int rc = -ENODEV;
+#if defined(CONFIG_DRIVER_CN100)
+	rc = cn100_initialize(bis, 0);
+#if defined(CONFIG_DRIVER_CN100_MULTI)
+	rc = cn100_initialize(bis, 1);
+#endif
+#endif
+	return rc;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/timer.c u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/timer.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cnc1900/timer.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cnc1900/timer.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2012
+ * Xiaodong Fan <xiaodong.fan@cavium.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
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CONFIG_SYS_CPU_TWD	0x80020600
+
+#define TWD_TIMER_LOAD			(CONFIG_SYS_CPU_TWD + 0x00)
+#define TWD_TIMER_COUNTER		(CONFIG_SYS_CPU_TWD + 0x04)
+#define TWD_TIMER_CONTROL		(CONFIG_SYS_CPU_TWD + 0x08)
+#define TWD_TIMER_INTSTAT		(CONFIG_SYS_CPU_TWD + 0x0C)
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the decrementing 32 bit timer as an increasing count */
+#define READ_TIMER()  ((ulong)((ulong)TIMER_LOAD_VAL - __raw_readl(TWD_TIMER_COUNTER)))
+
+#define HW_REG_READ( ByteAddr )      (*(volatile unsigned int*)(ByteAddr))
+
+unsigned int get_timer_freq(void)
+{
+	unsigned int timer_rate_hz;
+	unsigned int pll_cpu_div_f, pll_cpu_div_q;
+	
+	pll_cpu_div_f = (HW_REG_READ(0xb2100318) >> 6) & 0x7f;
+	pll_cpu_div_q = (HW_REG_READ(0xb2100318) >> 3) & 0x7;	
+	timer_rate_hz = ((pll_cpu_div_f + 1) / pll_cpu_div_q * 27000000)>>1;
+
+	return timer_rate_hz;
+}
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+	unsigned int tmp;
+	tmp=gd->timer_rate_hz/CONFIG_SYS_HZ;
+
+	do_div(tick, tmp);
+
+	return tick;
+}
+
+unsigned long long usec_to_tick(unsigned long long usec)
+{
+	unsigned int tmp;
+	tmp=gd->timer_rate_hz/1000000;
+	usec *= tmp;
+
+	return usec;
+}
+
+int timer_init(void)
+{
+	__raw_writel(TIMER_LOAD_VAL, TWD_TIMER_LOAD);
+	__raw_writel(0x03, TWD_TIMER_CONTROL);
+
+  gd->timer_rate_hz = get_timer_freq();
+  gd->tbu = gd->tbl = 0;
+
+	return 0;
+}
+
+/*
+ * Get the current 64 bit timer tick count
+ */
+unsigned long long get_ticks(void)
+{
+	ulong now = READ_TIMER();
+
+	/* increment tbu if tbl has rolled over */
+	if (now < gd->tbl)
+		gd->tbu++;
+	gd->tbl = now;
+
+	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
+}
+
+void __udelay(unsigned long usec)
+{
+	unsigned long long start;
+	ulong tmo;
+
+	start = get_ticks();		/* get current timestamp */
+	tmo = usec_to_tick(usec);	/* convert usecs to ticks */
+	while ((get_ticks() - start) < tmo)
+		;			/* loop till time has passed */
+}
+
+/* msecs	*/
+ulong get_timer(ulong base)
+{
+	ulong current_time = tick_to_time(get_ticks());
+
+	return current_time - base;
+}
+
+/*
+ * Return the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return gd->timer_rate_hz;
+}
+
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/cpu.c u-boot-2011.06/arch/arm/cpu/armv7/cpu.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/cpu.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/cpu.c	2014-07-29 17:28:38.819972000 +0800
@@ -39,6 +39,8 @@
 #include <asm/arch/sys_proto.h>
 #endif
 
+extern void invalidate_dcache(void);
+
 static void cache_flush(void);
 
 int cleanup_before_linux(void)
@@ -59,7 +61,7 @@
 
 	/* invalidate I-cache */
 	cache_flush();
-
+	invalidate_dcache();
 #ifndef CONFIG_L2_OFF
 	/* turn off L2 cache */
 	l2_cache_disable();
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/Makefile u-boot-2011.06/arch/arm/cpu/armv7/Makefile
--- u-boot-2011.06_original/arch/arm/cpu/armv7/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -28,6 +28,7 @@
 START	:= start.o
 COBJS	:= cpu.o
 COBJS  += syslib.o
+COBJS	+= cache_v7.o
 
 SRCS	:= $(START:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/s5p-common/timer.c u-boot-2011.06/arch/arm/cpu/armv7/s5p-common/timer.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/s5p-common/timer.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/s5p-common/timer.c	2014-07-29 17:28:38.819972000 +0800
@@ -69,7 +69,7 @@
 void __udelay(unsigned long usec)
 {
 	struct s5p_timer *const timer = s5p_get_base_timer();
-	unsigned long tmo, tmp, count_value;
+   	unsigned long tmo, tmp, count_value;
 
 	count_value = readl(&timer->tcntb4);
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/start.S u-boot-2011.06/arch/arm/cpu/armv7/start.S
--- u-boot-2011.06_original/arch/arm/cpu/armv7/start.S	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/start.S	2014-10-27 11:54:35.916774000 +0800
@@ -50,7 +50,11 @@
 _not_used:		.word not_used
 _irq:			.word irq
 _fiq:			.word fiq
+#ifdef UBOOT_VERSIONTAG
+_pad:			.word (0x12345678 + (UBOOT_VERSIONTAG << 24)) 
+#else
 _pad:			.word 0x12345678 /* now 16*4=64 */
+#endif
 .global _end_vect
 _end_vect:
 
@@ -98,6 +102,11 @@
 	.word _end - _start
 
 #ifdef CONFIG_USE_IRQ
+
+/* IRQ stack memory (calculated at run-time) + 8 bytes */
+.globl IRQ_STACK_START_IN
+IRQ_STACK_START_IN:
+	.word	0x0badc0de
 /* IRQ stack memory (calculated at run-time) */
 .globl IRQ_STACK_START
 IRQ_STACK_START:
@@ -109,10 +118,6 @@
 	.word 0x0badc0de
 #endif
 
-/* IRQ stack memory (calculated at run-time) + 8 bytes */
-.globl IRQ_STACK_START_IN
-IRQ_STACK_START_IN:
-	.word	0x0badc0de
 
 /*
  * the actual reset code
@@ -155,6 +160,23 @@
 	bl	cpu_init_crit
 #endif
 
+        /* 
+         * The PIC(Position Independent Code) codes such as hdmi or OTA are occupying the BSS segment,
+         * move them behind the BSS segment.
+         */
+        adr r3, _start
+        ldr r0, _end_ofs
+        add r0, r0, r3        /* now r0 is equal _end */
+        ldr r1, _bss_end_ofs
+        add r1, r1, r3        /* now r1 is equal __bss_end__ */
+        ldr r2, =(CONFIG_UBOOT_EXTERNAL_PROC_LEN)
+        add r2, r0, r2
+mov_PIC_codes:
+        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
+        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
+        cmp     r0, r2                  /* until source end address [r2]    */
+        blo     mov_PIC_codes
+
 /* Set stackpointer in internal RAM to call board_init_f */
 call_board_init_f:
 	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
@@ -498,4 +520,4 @@
 	bad_save_user_regs
 	bl	do_fiq
 
-#endif
+#endif/*CONFIG_USE_IRQ*/
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/cpu/armv7/tegra2/board.c u-boot-2011.06/arch/arm/cpu/armv7/tegra2/board.c
--- u-boot-2011.06_original/arch/arm/cpu/armv7/tegra2/board.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/cpu/armv7/tegra2/board.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,4 +1,4 @@
-/*
+_*
  *  (C) Copyright 2010,2011
  *  NVIDIA Corporation <www.nvidia.com>
  *
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/arch-cnc1900/sys_proto.h u-boot-2011.06/arch/arm/include/asm/arch-cnc1900/sys_proto.h
--- u-boot-2011.06_original/arch/arm/include/asm/arch-cnc1900/sys_proto.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/arch-cnc1900/sys_proto.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2011 Cavium Inc.
+ * Xiaodong Fan <xiaodong.fan@caviumnetworks.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
+ */
+
+#ifndef _CNC1900_SYS_PROTO_H
+#define _CNC1900_SYS_PROTO_H
+
+void invalidate_dcache(void);
+
+#endif 
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/arch-csm1800h/gpio.h u-boot-2011.06/arch/arm/include/asm/arch-csm1800h/gpio.h
--- u-boot-2011.06_original/arch/arm/include/asm/arch-csm1800h/gpio.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/arch-csm1800h/gpio.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * 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 __NMK_GPIO_H__
+#define __NMK_GPIO_H__
+
+/*
+ * These functions are called from the soft-i2c driver, but
+ * are also used by board files to set output bits.
+ */
+
+enum nmk_af { /* alternate function settings */
+	GPIO_GPIO = 0,
+	GPIO_ALT_A,
+	GPIO_ALT_B,
+	GPIO_ALT_C
+};
+
+extern void nmk_gpio_af(int gpio, int alternate_function);
+extern void nmk_gpio_dir(int gpio, int dir);
+extern void nmk_gpio_set(int gpio, int val);
+extern int nmk_gpio_get(int gpio);
+
+#endif /* __NMK_GPIO_H__ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/arch-csm1800h/hardware.1 u-boot-2011.06/arch/arm/include/asm/arch-csm1800h/hardware.1
--- u-boot-2011.06_original/arch/arm/include/asm/arch-csm1800h/hardware.1	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/arch-csm1800h/hardware.1	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * -------------------------------------------------------------------------
+ *
+ *  linux/include/asm-arm/arch-davinci/hardware.h
+ *
+ *  Copyright (C) 2006 Texas Instruments.
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+#include <asm/sizes.h>
+
+#define	REG(addr)	(*(volatile unsigned int *)(addr))
+#define REG_P(addr)	((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int *	dv_reg_p;
+
+/*
+ * Base register addresses
+ *
+ * NOTE:  some of these DM6446-specific addresses DO NOT WORK
+ * on other DaVinci chips.  Double check them before you try
+ * using the addresses ... or PSC module identifiers, etc.
+ */
+#ifndef CONFIG_SOC_DA8XX
+
+#define DAVINCI_DMA_3PCC_BASE			(0x01c00000)
+#define DAVINCI_DMA_3PTC0_BASE			(0x01c10000)
+#define DAVINCI_DMA_3PTC1_BASE			(0x01c10400)
+#define DAVINCI_UART0_BASE			(0x01c20000)
+#define DAVINCI_UART1_BASE			(0x01c20400)
+#define DAVINCI_I2C_BASE			(0x01c21000)
+#define DAVINCI_TIMER0_BASE			(0x01c21400)
+#define DAVINCI_TIMER1_BASE			(0x01c21800)
+#define DAVINCI_WDOG_BASE			(0x01c21c00)
+#define DAVINCI_PWM0_BASE			(0x01c22000)
+#define DAVINCI_PWM1_BASE			(0x01c22400)
+#define DAVINCI_PWM2_BASE			(0x01c22800)
+#define DAVINCI_SYSTEM_MODULE_BASE		(0x01c40000)
+#define DAVINCI_PLL_CNTRL0_BASE			(0x01c40800)
+#define DAVINCI_PLL_CNTRL1_BASE			(0x01c40c00)
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE		(0x01c41000)
+#define DAVINCI_ARM_INTC_BASE			(0x01c48000)
+#define DAVINCI_USB_OTG_BASE			(0x01c64000)
+#define DAVINCI_CFC_ATA_BASE			(0x01c66000)
+#define DAVINCI_SPI_BASE			(0x01c66800)
+#define DAVINCI_GPIO_BASE			(0x01c67000)
+#define DAVINCI_VPSS_REGS_BASE			(0x01c70000)
+#if !defined(CONFIG_SOC_DM646X)
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	(0x02000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE	(0x04000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	(0x06000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE	(0x08000000)
+#endif
+#define DAVINCI_DDR_BASE			(0x80000000)
+
+#ifdef CONFIG_SOC_DM644X
+#define DAVINCI_UART2_BASE			0x01c20800
+#define DAVINCI_UHPI_BASE			0x01c67800
+#define DAVINCI_EMAC_CNTRL_REGS_BASE		0x01c80000
+#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE	0x01c81000
+#define DAVINCI_EMAC_WRAPPER_RAM_BASE		0x01c82000
+#define DAVINCI_MDIO_CNTRL_REGS_BASE		0x01c84000
+#define DAVINCI_IMCOP_BASE			0x01cc0000
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x01e00000
+#define DAVINCI_VLYNQ_BASE			0x01e01000
+#define DAVINCI_ASP_BASE			0x01e02000
+#define DAVINCI_MMC_SD_BASE			0x01e10000
+#define DAVINCI_MS_BASE				0x01e20000
+#define DAVINCI_VLYNQ_REMOTE_BASE		0x0c000000
+
+#elif defined(CONFIG_SOC_DM355)
+#define DAVINCI_MMC_SD1_BASE			0x01e00000
+#define DAVINCI_ASP0_BASE			0x01e02000
+#define DAVINCI_ASP1_BASE			0x01e04000
+#define DAVINCI_UART2_BASE			0x01e06000
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x01e10000
+#define DAVINCI_MMC_SD0_BASE			0x01e11000
+
+#elif defined(CONFIG_SOC_DM365)
+#define DAVINCI_MMC_SD1_BASE			0x01d00000
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x01d10000
+#define DAVINCI_MMC_SD0_BASE			0x01d11000
+
+#elif defined(CONFIG_SOC_DM646X)
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x20008000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x42000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE	0x44000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	0x46000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE	0x48000000
+
+#endif
+
+#else /* CONFIG_SOC_DA8XX */
+
+#define DAVINCI_UART0_BASE			0x01c42000
+#define DAVINCI_UART1_BASE			0x01d0c000
+#define DAVINCI_UART2_BASE			0x01d0d000
+#define DAVINCI_I2C0_BASE			0x01c22000
+#define DAVINCI_I2C1_BASE			0x01e28000
+#define DAVINCI_TIMER0_BASE			0x01c20000
+#define DAVINCI_TIMER1_BASE			0x01c21000
+#define DAVINCI_WDOG_BASE			0x01c21000
+#define DAVINCI_PLL_CNTRL0_BASE			0x01c11000
+#define DAVINCI_PSC0_BASE			0x01c10000
+#define DAVINCI_PSC1_BASE			0x01e27000
+#define DAVINCI_SPI0_BASE			0x01c41000
+#define DAVINCI_USB_OTG_BASE			0x01e00000
+#define DAVINCI_SPI1_BASE			(cpu_is_da830() ? \
+						0x01e12000 : 0x01f0e000)
+#define DAVINCI_GPIO_BASE			0x01e26000
+#define DAVINCI_EMAC_CNTRL_REGS_BASE		0x01e23000
+#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE	0x01e22000
+#define DAVINCI_EMAC_WRAPPER_RAM_BASE		0x01e20000
+#define DAVINCI_MDIO_CNTRL_REGS_BASE		0x01e24000
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x68000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x40000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	0x60000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE	0x62000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE	0x64000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE	0x66000000
+#define DAVINCI_DDR_EMIF_CTRL_BASE		0xb0000000
+#define DAVINCI_DDR_EMIF_DATA_BASE		0xc0000000
+#define DAVINCI_INTC_BASE			0xfffee000
+#define DAVINCI_BOOTCFG_BASE			0x01c14000
+#define JTAG_ID_REG                            (DAVINCI_BOOTCFG_BASE + 0x18)
+
+#define GPIO_BANK2_REG_DIR_ADDR			(DAVINCI_GPIO_BASE + 0x38)
+#define GPIO_BANK2_REG_OPDATA_ADDR		(DAVINCI_GPIO_BASE + 0x3c)
+#define GPIO_BANK2_REG_SET_ADDR			(DAVINCI_GPIO_BASE + 0x40)
+#define GPIO_BANK2_REG_CLR_ADDR			(DAVINCI_GPIO_BASE + 0x44)
+#endif /* CONFIG_SOC_DA8XX */
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN		0
+#define DAVINCI_GPSC_DSPDOMAIN		1
+
+#ifndef CONFIG_SOC_DA8XX
+
+#define DAVINCI_LPSC_VPSSMSTR		0
+#define DAVINCI_LPSC_VPSSSLV		1
+#define DAVINCI_LPSC_TPCC		2
+#define DAVINCI_LPSC_TPTC0		3
+#define DAVINCI_LPSC_TPTC1		4
+#define DAVINCI_LPSC_EMAC		5
+#define DAVINCI_LPSC_EMAC_WRAPPER	6
+#define DAVINCI_LPSC_MDIO		7
+#define DAVINCI_LPSC_IEEE1394		8
+#define DAVINCI_LPSC_USB		9
+#define DAVINCI_LPSC_ATA		10
+#define DAVINCI_LPSC_VLYNQ		11
+#define DAVINCI_LPSC_UHPI		12
+#define DAVINCI_LPSC_DDR_EMIF		13
+#define DAVINCI_LPSC_AEMIF		14
+#define DAVINCI_LPSC_MMC_SD		15
+#define DAVINCI_LPSC_MEMSTICK		16
+#define DAVINCI_LPSC_McBSP		17
+#define DAVINCI_LPSC_I2C		18
+#define DAVINCI_LPSC_UART0		19
+#define DAVINCI_LPSC_UART1		20
+#define DAVINCI_LPSC_UART2		21
+#define DAVINCI_LPSC_SPI		22
+#define DAVINCI_LPSC_PWM0		23
+#define DAVINCI_LPSC_PWM1		24
+#define DAVINCI_LPSC_PWM2		25
+#define DAVINCI_LPSC_GPIO		26
+#define DAVINCI_LPSC_TIMER0		27
+#define DAVINCI_LPSC_TIMER1		28
+#define DAVINCI_LPSC_TIMER2		29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS	30
+#define DAVINCI_LPSC_ARM		31
+#define DAVINCI_LPSC_SCR2		32
+#define DAVINCI_LPSC_SCR3		33
+#define DAVINCI_LPSC_SCR4		34
+#define DAVINCI_LPSC_CROSSBAR		35
+#define DAVINCI_LPSC_CFG27		36
+#define DAVINCI_LPSC_CFG3		37
+#define DAVINCI_LPSC_CFG5		38
+#define DAVINCI_LPSC_GEM		39
+#define DAVINCI_LPSC_IMCOP		40
+
+#define DAVINCI_DM646X_LPSC_EMAC	14
+#define DAVINCI_DM646X_LPSC_UART0	26
+#define DAVINCI_DM646X_LPSC_I2C		31
+#define DAVINCI_DM646X_LPSC_TIMER0	34
+
+#else /* CONFIG_SOC_DA8XX */
+
+enum davinci_lpsc_ids {
+	DAVINCI_LPSC_TPCC = 0,
+	DAVINCI_LPSC_TPTC0,
+	DAVINCI_LPSC_TPTC1,
+	DAVINCI_LPSC_AEMIF,
+	DAVINCI_LPSC_SPI0,
+	DAVINCI_LPSC_MMC_SD,
+	DAVINCI_LPSC_AINTC,
+	DAVINCI_LPSC_ARM_RAM_ROM,
+	DAVINCI_LPSC_SECCTL_KEYMGR,
+	DAVINCI_LPSC_UART0,
+	DAVINCI_LPSC_SCR0,
+	DAVINCI_LPSC_SCR1,
+	DAVINCI_LPSC_SCR2,
+	DAVINCI_LPSC_DMAX,
+	DAVINCI_LPSC_ARM,
+	DAVINCI_LPSC_GEM,
+	/* for LPSCs in PSC1, offset from 32 for differentiation */
+	DAVINCI_LPSC_PSC1_BASE = 32,
+	DAVINCI_LPSC_USB11,
+	DAVINCI_LPSC_USB20,
+	DAVINCI_LPSC_GPIO,
+	DAVINCI_LPSC_UHPI,
+	DAVINCI_LPSC_EMAC,
+	DAVINCI_LPSC_DDR_EMIF,
+	DAVINCI_LPSC_McASP0,
+	DAVINCI_LPSC_McASP1,
+	DAVINCI_LPSC_McASP2,
+	DAVINCI_LPSC_SPI1,
+	DAVINCI_LPSC_I2C1,
+	DAVINCI_LPSC_UART1,
+	DAVINCI_LPSC_UART2,
+	DAVINCI_LPSC_LCDC,
+	DAVINCI_LPSC_ePWM,
+	DAVINCI_LPSC_eCAP,
+	DAVINCI_LPSC_eQEP,
+	DAVINCI_LPSC_SCR_P0,
+	DAVINCI_LPSC_SCR_P1,
+	DAVINCI_LPSC_CR_P3,
+	DAVINCI_LPSC_L3_CBA_RAM
+};
+
+#endif /* CONFIG_SOC_DA8XX */
+
+void lpsc_on(unsigned int id);
+void dsp_on(void);
+
+void davinci_enable_uart0(void);
+void davinci_enable_emac(void);
+void davinci_enable_i2c(void);
+void davinci_errata_workarounds(void);
+
+#ifndef CONFIG_SOC_DA8XX
+
+/* Some PSC defines */
+#define PSC_CHP_SHRTSW			(0x01c40038)
+#define PSC_GBLCTL			(0x01c41010)
+#define PSC_EPCPR			(0x01c41070)
+#define PSC_EPCCR			(0x01c41078)
+#define PSC_PTCMD			(0x01c41120)
+#define PSC_PTSTAT			(0x01c41128)
+#define PSC_PDSTAT			(0x01c41200)
+#define PSC_PDSTAT1			(0x01c41204)
+#define PSC_PDCTL			(0x01c41300)
+#define PSC_PDCTL1			(0x01c41304)
+
+#define PSC_MDCTL_BASE			(0x01c41a00)
+#define PSC_MDSTAT_BASE			(0x01c41800)
+
+#define VDD3P3V_PWDN			(0x01c40048)
+#define UART0_PWREMU_MGMT		(0x01c20030)
+
+#define PSC_SILVER_BULLET		(0x01c41a20)
+
+#else /* CONFIG_SOC_DA8XX */
+
+#define PSC_PSC0_MODULE_ID_CNT		16
+#define PSC_PSC1_MODULE_ID_CNT		32
+
+struct davinci_psc_regs {
+	dv_reg	revid;
+	dv_reg	rsvd0[71];
+	dv_reg	ptcmd;
+	dv_reg	rsvd1;
+	dv_reg	ptstat;
+	dv_reg	rsvd2[437];
+	union {
+		struct {
+			dv_reg	mdstat[PSC_PSC0_MODULE_ID_CNT];
+			dv_reg	rsvd3[112];
+			dv_reg	mdctl[PSC_PSC0_MODULE_ID_CNT];
+		} psc0;
+		struct {
+			dv_reg	mdstat[PSC_PSC1_MODULE_ID_CNT];
+			dv_reg	rsvd3[96];
+			dv_reg	mdctl[PSC_PSC1_MODULE_ID_CNT];
+		} psc1;
+	};
+};
+
+#define davinci_psc0_regs ((struct davinci_psc_regs *)DAVINCI_PSC0_BASE)
+#define davinci_psc1_regs ((struct davinci_psc_regs *)DAVINCI_PSC1_BASE)
+
+#endif /* CONFIG_SOC_DA8XX */
+
+#ifndef CONFIG_SOC_DA8XX
+
+/* Miscellania... */
+#define VBPR				(0x20000020)
+
+/* NOTE:  system control modules are *highly* chip-specific, both
+ * as to register content (e.g. for muxing) and which registers exist.
+ */
+#define PINMUX0				0x01c40000
+#define PINMUX1				0x01c40004
+#define PINMUX2				0x01c40008
+#define PINMUX3				0x01c4000c
+#define PINMUX4				0x01c40010
+
+#else /* CONFIG_SOC_DA8XX */
+
+struct davinci_pllc_regs {
+	dv_reg	revid;
+	dv_reg	rsvd1[56];
+	dv_reg	rstype;
+	dv_reg	rsvd2[6];
+	dv_reg	pllctl;
+	dv_reg	ocsel;
+	dv_reg	rsvd3[2];
+	dv_reg	pllm;
+	dv_reg	prediv;
+	dv_reg	plldiv1;
+	dv_reg	plldiv2;
+	dv_reg	plldiv3;
+	dv_reg	oscdiv;
+	dv_reg	postdiv;
+	dv_reg	rsvd4[3];
+	dv_reg	pllcmd;
+	dv_reg	pllstat;
+	dv_reg	alnctl;
+	dv_reg	dchange;
+	dv_reg	cken;
+	dv_reg	ckstat;
+	dv_reg	systat;
+	dv_reg	rsvd5[3];
+	dv_reg	plldiv4;
+	dv_reg	plldiv5;
+	dv_reg	plldiv6;
+	dv_reg	plldiv7;
+	dv_reg	rsvd6[32];
+	dv_reg	emucnt0;
+	dv_reg	emucnt1;
+};
+
+#define davinci_pllc_regs ((struct davinci_pllc_regs *)DAVINCI_PLL_CNTRL0_BASE)
+#define DAVINCI_PLLC_DIV_MASK	0x1f
+
+#define ASYNC3          get_async3_src()
+#define PLL1_SYSCLK2		((1 << 16) | 0x2)
+#define DAVINCI_SPI1_CLKID  (cpu_is_da830() ? 2 : ASYNC3)
+/* Clock IDs */
+enum davinci_clk_ids {
+	DAVINCI_SPI0_CLKID = 2,
+	DAVINCI_UART2_CLKID = 2,
+	DAVINCI_MDIO_CLKID = 4,
+	DAVINCI_ARM_CLKID = 6,
+	DAVINCI_PLLM_CLKID = 0xff,
+	DAVINCI_PLLC_CLKID = 0x100,
+	DAVINCI_AUXCLK_CLKID = 0x101
+};
+
+int clk_get(enum davinci_clk_ids id);
+
+/* Boot config */
+struct davinci_syscfg_regs {
+	dv_reg	revid;
+	dv_reg	rsvd[13];
+	dv_reg	kick0;
+	dv_reg	kick1;
+	dv_reg	rsvd1[56];
+	dv_reg	pinmux[20];
+	dv_reg	suspsrc;
+	dv_reg	chipsig;
+	dv_reg	chipsig_clr;
+	dv_reg	cfgchip0;
+	dv_reg	cfgchip1;
+	dv_reg	cfgchip2;
+	dv_reg	cfgchip3;
+	dv_reg	cfgchip4;
+};
+
+#define davinci_syscfg_regs \
+	((struct davinci_syscfg_regs *)DAVINCI_BOOTCFG_BASE)
+
+/* Emulation suspend bits */
+#define DAVINCI_SYSCFG_SUSPSRC_EMAC		(1 << 5)
+#define DAVINCI_SYSCFG_SUSPSRC_I2C		(1 << 16)
+#define DAVINCI_SYSCFG_SUSPSRC_SPI0		(1 << 21)
+#define DAVINCI_SYSCFG_SUSPSRC_SPI1		(1 << 22)
+#define DAVINCI_SYSCFG_SUSPSRC_UART2		(1 << 20)
+#define DAVINCI_SYSCFG_SUSPSRC_TIMER0		(1 << 27)
+
+/* Interrupt controller */
+struct davinci_aintc_regs {
+	dv_reg	revid;
+	dv_reg	cr;
+	dv_reg	dummy0[2];
+	dv_reg	ger;
+	dv_reg	dummy1[219];
+	dv_reg	ecr1;
+	dv_reg	ecr2;
+	dv_reg	ecr3;
+	dv_reg	dummy2[1117];
+	dv_reg	hier;
+};
+
+#define davinci_aintc_regs ((struct davinci_aintc_regs *)DAVINCI_INTC_BASE)
+
+struct davinci_uart_ctrl_regs {
+	dv_reg	revid1;
+	dv_reg	revid2;
+	dv_reg	pwremu_mgmt;
+	dv_reg	mdr;
+};
+
+#define DAVINCI_UART_CTRL_BASE 0x28
+#define DAVINCI_UART0_CTRL_ADDR (DAVINCI_UART0_BASE + DAVINCI_UART_CTRL_BASE)
+#define DAVINCI_UART1_CTRL_ADDR (DAVINCI_UART1_BASE + DAVINCI_UART_CTRL_BASE)
+#define DAVINCI_UART2_CTRL_ADDR (DAVINCI_UART2_BASE + DAVINCI_UART_CTRL_BASE)
+
+#define davinci_uart0_ctrl_regs \
+	((struct davinci_uart_ctrl_regs *)DAVINCI_UART0_CTRL_ADDR)
+#define davinci_uart1_ctrl_regs \
+	((struct davinci_uart_ctrl_regs *)DAVINCI_UART1_CTRL_ADDR)
+#define davinci_uart2_ctrl_regs \
+	((struct davinci_uart_ctrl_regs *)DAVINCI_UART2_CTRL_ADDR)
+
+/* UART PWREMU_MGMT definitions */
+#define DAVINCI_UART_PWREMU_MGMT_FREE	(1 << 0)
+#define DAVINCI_UART_PWREMU_MGMT_URRST	(1 << 13)
+#define DAVINCI_UART_PWREMU_MGMT_UTRST	(1 << 14)
+
+static inline int cpu_is_da830(void)
+{
+	unsigned int jtag_id	= REG(JTAG_ID_REG);
+	unsigned short part_no	= (jtag_id >> 12) & 0xffff;
+
+	return ((part_no == 0xb7df) ? 1 : 0);
+}
+static inline int cpu_is_da850(void)
+{
+	unsigned int jtag_id    = REG(JTAG_ID_REG);
+	unsigned short part_no  = (jtag_id >> 12) & 0xffff;
+
+	return ((part_no == 0xb7d1) ? 1 : 0);
+}
+
+static inline int get_async3_src(void)
+{
+	return (REG(&davinci_syscfg_regs->cfgchip3) & 0x10) ?
+			PLL1_SYSCLK2 : 2;
+}
+
+#endif /* CONFIG_SOC_DA8XX */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/arch-tegra2/sys_proto.h u-boot-2011.06/arch/arm/include/asm/arch-tegra2/sys_proto.h
--- u-boot-2011.06_original/arch/arm/include/asm/arch-tegra2/sys_proto.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/arch-tegra2/sys_proto.h	2014-07-29 17:28:38.819972000 +0800
@@ -30,6 +30,6 @@
 
 void invalidate_dcache(void);
 
-extern const struct tegra2_sysinfo sysinfo;
+extern const struct tegra1_sysinfo sysinfo;
 
 #endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/armv7.h u-boot-2011.06/arch/arm/include/asm/armv7.h
--- u-boot-2011.06_original/arch/arm/include/asm/armv7.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/armv7.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef ARMV7_H
+#define ARMV7_H
+
+/* Cortex-A9 revisions */
+#define MIDR_CORTEX_A9_R0P1	0x410FC091
+#define MIDR_CORTEX_A9_R1P2	0x411FC092
+#define MIDR_CORTEX_A9_R1P3	0x411FC093
+#define MIDR_CORTEX_A9_R2P10	0x412FC09A
+
+/* Cortex-A15 revisions */
+#define MIDR_CORTEX_A15_R0P0	0x410FC0F0
+#define MIDR_CORTEX_A15_R2P2	0x412FC0F2
+
+/* Cortex-A7 revisions */
+#define MIDR_CORTEX_A7_R0P0	0x410FC070
+
+#define MIDR_PRIMARY_PART_MASK	0xFF0FFFF0
+
+/* ID_PFR1 feature fields */
+#define CPUID_ARM_SEC_SHIFT		4
+#define CPUID_ARM_SEC_MASK		(0xF << CPUID_ARM_SEC_SHIFT)
+#define CPUID_ARM_VIRT_SHIFT		12
+#define CPUID_ARM_VIRT_MASK		(0xF << CPUID_ARM_VIRT_SHIFT)
+#define CPUID_ARM_GENTIMER_SHIFT	16
+#define CPUID_ARM_GENTIMER_MASK		(0xF << CPUID_ARM_GENTIMER_SHIFT)
+
+/* valid bits in CBAR register / PERIPHBASE value */
+#define CBAR_MASK			0xFFFF8000
+
+/* CCSIDR */
+#define CCSIDR_LINE_SIZE_OFFSET		0
+#define CCSIDR_LINE_SIZE_MASK		0x7
+#define CCSIDR_ASSOCIATIVITY_OFFSET	3
+#define CCSIDR_ASSOCIATIVITY_MASK	(0x3FF << 3)
+#define CCSIDR_NUM_SETS_OFFSET		13
+#define CCSIDR_NUM_SETS_MASK		(0x7FFF << 13)
+
+/*
+ * Values for InD field in CSSELR
+ * Selects the type of cache
+ */
+#define ARMV7_CSSELR_IND_DATA_UNIFIED	0
+#define ARMV7_CSSELR_IND_INSTRUCTION	1
+
+/* Values for Ctype fields in CLIDR */
+#define ARMV7_CLIDR_CTYPE_NO_CACHE		0
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_ONLY	1
+#define ARMV7_CLIDR_CTYPE_DATA_ONLY		2
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA	3
+#define ARMV7_CLIDR_CTYPE_UNIFIED		4
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+/*
+ * CP15 Barrier instructions
+ * Please note that we have separate barrier instructions in ARMv7
+ * However, we use the CP15 based instructtions because we use
+ * -march=armv5 in U-Boot
+ */
+#define CP15ISB	asm volatile ("mcr     p15, 0, %0, c7, c5, 4" : : "r" (0))
+#define CP15DSB	asm volatile ("mcr     p15, 0, %0, c7, c10, 4" : : "r" (0))
+#define CP15DMB	asm volatile ("mcr     p15, 0, %0, c7, c10, 5" : : "r" (0))
+
+void v7_outer_cache_enable(void);
+void v7_outer_cache_disable(void);
+void v7_outer_cache_flush_all(void);
+void v7_outer_cache_inval_all(void);
+void v7_outer_cache_flush_range(u32 start, u32 end);
+void v7_outer_cache_inval_range(u32 start, u32 end);
+
+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
+
+int armv7_switch_nonsec(void);
+int armv7_switch_hyp(void);
+
+/* defined in assembly file */
+unsigned int _nonsec_init(void);
+void _smp_pen(void);
+void _switch_to_hyp(void);
+#endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */
+
+#endif /* ! __ASSEMBLY__ */
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/cache.h u-boot-2011.06/arch/arm/include/asm/cache.h
--- u-boot-2011.06_original/arch/arm/include/asm/cache.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/cache.h	2014-07-29 17:28:38.819972000 +0800
@@ -42,4 +42,15 @@
 void l2_cache_enable(void);
 void l2_cache_disable(void);
 
+/*
+ * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
+ * use that value for aligning DMA buffers unless the board config has specified
+ * an alternate cache line size.
+ */
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+#define ARCH_DMA_MINALIGN	CONFIG_SYS_CACHELINE_SIZE
+#else
+#define ARCH_DMA_MINALIGN	64
+#endif
+
 #endif /* _ASM_CACHE_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/global_data.h u-boot-2011.06/arch/arm/include/asm/global_data.h
--- u-boot-2011.06_original/arch/arm/include/asm/global_data.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/global_data.h	2014-11-19 00:41:17.367468000 +0800
@@ -73,6 +73,20 @@
 #if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
 	unsigned long	tlb_addr;
 #endif
+
+#if defined(CONFIG_SPI_FLASH_CNC1800L) || defined(CONFIG_SPI_FLASH_CNC1900)
+	sfinf_t 	*sf_inf;
+	unsigned char 	sf_alen;
+	unsigned char 	sf_boot;
+	unsigned 	sf_rspd;
+	unsigned 	sf_wspd;
+	unsigned 	sf_size;
+#endif
+#ifdef CONFIG_ARCH_CNC1900
+	unsigned int cpu_freq;
+	unsigned int ddr_freq;
+	int uart_locked;
+#endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/io.h u-boot-2011.06/arch/arm/include/asm/io.h
--- u-boot-2011.06_original/arch/arm/include/asm/io.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/io.h	2014-07-29 17:28:38.819972000 +0800
@@ -75,7 +75,7 @@
 #define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
 #define __arch_putl(v,a)		(*(volatile unsigned int *)(a) = (v))
 
-extern inline void __raw_writesb(unsigned int addr, const void *data, int bytelen)
+static inline void __raw_writesb(unsigned int addr, const void *data, int bytelen)
 {
 	uint8_t *buf = (uint8_t *)data;
 	while(bytelen--)
@@ -89,14 +89,14 @@
 		__arch_putw(*buf++, addr);
 }
 
-extern inline void __raw_writesl(unsigned int addr, const void *data, int longlen)
+static inline void __raw_writesl(unsigned int addr, const void *data, int longlen)
 {
 	uint32_t *buf = (uint32_t *)data;
 	while(longlen--)
 		__arch_putl(*buf++, addr);
 }
 
-extern inline void __raw_readsb(unsigned int addr, void *data, int bytelen)
+static inline void __raw_readsb(unsigned int addr, void *data, int bytelen)
 {
 	uint8_t *buf = (uint8_t *)data;
 	while(bytelen--)
@@ -110,7 +110,7 @@
 		*buf++ = __arch_getw(addr);
 }
 
-extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
+static inline void __raw_readsl(unsigned int addr, void *data, int longlen)
 {
 	uint32_t *buf = (uint32_t *)data;
 	while(longlen--)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/system.h u-boot-2011.06/arch/arm/include/asm/system.h
--- u-boot-2011.06_original/arch/arm/include/asm/system.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/system.h	2014-07-29 17:28:38.819972000 +0800
@@ -61,6 +61,12 @@
 
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
+#ifdef __ARM_ARCH_7A__
+#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#else
+#define wfi()
+#endif
+
 static inline unsigned int get_cr(void)
 {
 	unsigned int val;
@@ -75,6 +81,51 @@
 	isb();
 }
 
+static inline unsigned int get_dacr(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c3, c0, 0	@ get DACR" : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c3, c0, 0	@ set DACR"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
+/* options available for data cache on each page */
+enum dcache_option {
+	DCACHE_OFF = 0x12,
+	DCACHE_WRITETHROUGH = 0x1a,
+	DCACHE_WRITEBACK = 0x1e,
+};
+
+/* Size of an MMU section */
+enum {
+	MMU_SECTION_SHIFT	= 20,
+	MMU_SECTION_SIZE	= 1 << MMU_SECTION_SHIFT,
+};
+
+/**
+ * Change the cache settings for a region.
+ *
+ * \param start		start address of memory region to change
+ * \param size		size of memory region to change
+ * \param option	dcache option to select
+ */
+void mmu_set_region_dcache_behaviour(u32 start, int size,
+				     enum dcache_option option);
+
+/**
+ * Register an update to the page tables, and flush the TLB
+ *
+ * \param start		start address of update in page table
+ * \param stop		stop address of update in page table
+ */
+void mmu_page_table_flush(unsigned long start, unsigned long stop);
+
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/u-boot-arm.h u-boot-2011.06/arch/arm/include/asm/u-boot-arm.h
--- u-boot-2011.06_original/arch/arm/include/asm/u-boot-arm.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/u-boot-arm.h	2014-07-29 17:28:38.819972000 +0800
@@ -72,6 +72,7 @@
 void	udelay_masked		(unsigned long usec);
 
 /* cpu/.../timer.c */
+unsigned long long usec_to_tick(unsigned long long usec);
 int	timer_init		(void);
 
 #endif	/* _U_BOOT_ARM_H_ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/u-boot.h u-boot-2011.06/arch/arm/include/asm/u-boot.h
--- u-boot-2011.06_original/arch/arm/include/asm/u-boot.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/u-boot.h	2014-07-29 17:28:38.819972000 +0800
@@ -39,6 +39,7 @@
 typedef struct bd_info {
     int			bi_baudrate;	/* serial console baudrate */
     unsigned long	bi_ip_addr;	/* IP Address */
+    unsigned char	bi_enetaddr[6]; /* Ethernet adress */
     ulong	        bi_arch_number;	/* unique id for this board */
     ulong	        bi_boot_params;	/* where this board expects params */
     struct				/* RAM configuration */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/include/asm/utils.h u-boot-2011.06/arch/arm/include/asm/utils.h
--- u-boot-2011.06_original/arch/arm/include/asm/utils.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/arch/arm/include/asm/utils.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+static inline s32 log_2_n_round_up(u32 n)
+{
+	s32 log2n = -1;
+	u32 temp = n;
+
+	while (temp) {
+		log2n++;
+		temp >>= 1;
+	}
+
+	if (n & (n - 1))
+		return log2n + 1; /* not power of 2 - round up */
+	else
+		return log2n; /* power of 2 */
+}
+
+static inline s32 log_2_n_round_down(u32 n)
+{
+	s32 log2n = -1;
+	u32 temp = n;
+
+	while (temp) {
+		log2n++;
+		temp >>= 1;
+	}
+
+	return log2n;
+}
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/lib/board.c u-boot-2011.06/arch/arm/lib/board.c
--- u-boot-2011.06_original/arch/arm/lib/board.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/lib/board.c	2015-05-29 14:38:58.047483000 +0800
@@ -74,8 +74,7 @@
 #define CONFIG_IDENT_STRING ""
 #endif
 
-const char version_string[] =
-	U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;
+const char version_string[] = U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING ;
 
 #ifdef CONFIG_DRIVER_RTL8019
 extern void rtl8019_get_enetaddr (uchar * addr);
@@ -111,6 +110,8 @@
 void inline __blue_LED_off(void) {}
 void blue_LED_off(void) __attribute__((weak, alias("__blue_LED_off")));
 
+extern void sec_env_relocate(void);
+
 /************************************************************************
  * Init Utilities							*
  ************************************************************************
@@ -137,6 +138,7 @@
 static int display_banner (void)
 {
 	printf ("\n\n%s\n\n", version_string);
+    printf ("Configured for target [%s]\n",TARGET_CONFIGURATION_NAME);
 	debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
 	       _TEXT_BASE,
 	       _bss_start_ofs+_TEXT_BASE, _bss_end_ofs+_TEXT_BASE);
@@ -270,7 +272,7 @@
 	bd_t *bd;
 	init_fnc_t **init_fnc_ptr;
 	gd_t *id;
-	ulong addr, addr_sp;
+	ulong addr, addr_sp, addr_tmp;
 
 	/* Pointer is writable since we allocated a register for it */
 	gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
@@ -352,6 +354,11 @@
 #endif /* CONFIG_LCD */
 
 	/*
+	  * reserve memory for hdmi PIC or dvu PIC code that will be combined after u-boot.bin
+	  */
+	addr -= CONFIG_UBOOT_EXTERNAL_PROC_LEN;
+
+	/*
 	 * reserve memory for U-Boot code, data & bss
 	 * round down to next 4 kB limit
 	 */
@@ -359,6 +366,11 @@
 	addr &= ~(4096 - 1);
 
 	debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
+	
+    /* Move the PIC codes behind the BSS segment */
+    addr_tmp=addr+gd->mon_len;
+    memcpy( (void*) addr_tmp , (void*) (_TEXT_BASE+_bss_end_ofs) , CONFIG_UBOOT_EXTERNAL_PROC_LEN );
+    debug ("\nUboot external codes at: %08lx\n",addr_tmp);
 
 #ifndef CONFIG_PRELOADER
 	/*
@@ -438,12 +450,16 @@
 void board_init_r (gd_t *id, ulong dest_addr)
 {
 	char *s;
-	bd_t *bd;
+	bd_t *bd=NULL;
 	ulong malloc_start;
 #if !defined(CONFIG_SYS_NO_FLASH)
 	ulong flash_size;
 #endif
+	bd=bd;
 
+#if defined(CONFIG_SPI_FLASH_CNC1800L) || defined(CONFIG_SPI_FLASH_CNC1900)
+    ulong size=0;
+#endif
 	gd = id;
 	bd = gd->bd;
 
@@ -451,6 +467,18 @@
 
 	monitor_flash_len = _end_ofs;
 	debug ("monitor flash len: %08lX\n", monitor_flash_len);
+#ifdef CONFIG_USE_IRQ
+    unsigned int cnt;
+    unsigned int *dest,*source;
+    dest=0;
+    source=(unsigned int *)dest_addr;
+    //printf("start vector copy,source=0x%X,dest=0x%X.\n",(unsigned int)source,(unsigned int)dest);
+    for(cnt=0;cnt<0x3c/4;cnt++)
+    {
+        *dest++=*source++;
+    }
+    //printf("%x,%x,%x,%x,%x,%x,%x,%x\n",*(unsigned int *)0,*(unsigned int *)4,*(unsigned int *)8,*(unsigned int *)12,*(unsigned int *)16,*(unsigned int *)20,*(unsigned int *)24,*(unsigned int *)28);
+#endif
 	board_init();	/* Setup chipselects */
 
 #ifdef CONFIG_SERIAL_MULTI
@@ -470,6 +498,18 @@
 	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
 	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
 
+#if defined(CONFIG_SPI_FLASH_CNC1800L) || defined(CONFIG_SPI_FLASH_CNC1900)
+if (seeprom_probe() > 0) {
+		puts("Legacy SPI ");
+		size = gd->sf_inf->sector_size*gd->sf_inf->n_sectors;
+
+		if (gd->sf_size % 0x100000)
+			printf("Flash Size: %dKB\n", gd->sf_size/1024);
+		else
+			printf("Flash Size: %dMB\n", gd->sf_size/1024/1024);
+	}
+#endif
+
 #if !defined(CONFIG_SYS_NO_FLASH)
 	puts ("Flash: ");
 
@@ -518,6 +558,11 @@
 
 	/* initialize environment */
 	env_relocate ();
+#if defined(CONFIG_CMD_SEC_NVEDIT)
+    /* Initialize factory default environment. */
+    sec_env_relocate();
+#endif
+
 
 #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
 	arm_pci_init();
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/lib/bootm.c u-boot-2011.06/arch/arm/lib/bootm.c
--- u-boot-2011.06_original/arch/arm/lib/bootm.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/lib/bootm.c	2014-07-29 17:28:38.819972000 +0800
@@ -31,6 +31,9 @@
 #include <fdt_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
+#undef debug
+#define debug printf
+
 
 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \
     defined (CONFIG_CMDLINE_TAG) || \
@@ -146,6 +149,11 @@
 #ifdef CONFIG_INITRD_TAG
 	if (images->rd_start && images->rd_end)
 		setup_initrd_tag (bd, images->rd_start, images->rd_end);
+
+extern ulong ramdisk_start, ramdisk_end;
+
+	if (ramdisk_start && ramdisk_end)
+		setup_initrd_tag (bd, ramdisk_start, ramdisk_end);
 #endif
 	setup_end_tag(bd);
 #endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/lib/cache.c u-boot-2011.06/arch/arm/lib/cache.c
--- u-boot-2011.06_original/arch/arm/lib/cache.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/lib/cache.c	2014-07-29 17:28:38.819972000 +0800
@@ -2,32 +2,16 @@
  * (C) Copyright 2002
  * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 /* for now: just dummy functions to satisfy the linker */
 
 #include <common.h>
 
-void  flush_cache (unsigned long dummy1, unsigned long dummy2)
+void  __flush_cache(unsigned long start, unsigned long size)
 {
-#if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
+#if defined(CONFIG_ARM1136)
 	void arm1136_cache_flush(void);
 
 	arm1136_cache_flush();
@@ -38,10 +22,30 @@
 	/* disable write buffer as well (page 2-22) */
 	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 #endif
-#ifdef CONFIG_OMAP34XX
-	void v7_flush_cache_all(void);
-
-	v7_flush_cache_all();
-#endif
 	return;
 }
+void  flush_cache(unsigned long start, unsigned long size)
+	__attribute__((weak, alias("__flush_cache")));
+
+/*
+ * Default implementation:
+ * do a range flush for the entire range
+ */
+void	__flush_dcache_all(void)
+{
+	flush_cache(0, ~0);
+}
+void	flush_dcache_all(void)
+	__attribute__((weak, alias("__flush_dcache_all")));
+
+
+/*
+ * Default implementation of enable_caches()
+ * Real implementation should be in platform code
+ */
+void __enable_caches(void)
+{
+	puts("WARNING: Caches not enabled\n");
+}
+void enable_caches(void)
+	__attribute__((weak, alias("__enable_caches")));
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/lib/cache-cp15.c u-boot-2011.06/arch/arm/lib/cache-cp15.c
--- u-boot-2011.06_original/arch/arm/lib/cache-cp15.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/lib/cache-cp15.c	2014-10-30 20:54:29.112101000 +0800
@@ -2,38 +2,28 @@
  * (C) Copyright 2002
  * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
 #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
-#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
-
-#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
-#define CACHE_SETUP	0x1a
-#else
-#define CACHE_SETUP	0x1e
-#endif
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
 DECLARE_GLOBAL_DATA_PTR;
 
+void __arm_init_before_mmu(void)
+{
+}
+void arm_init_before_mmu(void)
+	__attribute__((weak, alias("__arm_init_before_mmu")));
+
+__weak void arm_init_domains(void)
+{
+}
+
 static void cp_delay (void)
 {
 	volatile int i;
@@ -44,9 +34,41 @@
 	asm volatile("" : : : "memory");
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+void set_section_dcache(int section, enum dcache_option option)
+{
+	u32 *page_table = (u32 *)gd->tlb_addr;
+	u32 value;
+
+	value = (section << MMU_SECTION_SHIFT) | (3 << 10);
+	value |= option;
+	page_table[section] = value;
+}
+
+void __mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+	debug("%s: Warning: not implemented\n", __func__);
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+	__attribute__((weak, alias("__mmu_page_table_flush")));
+
+void mmu_set_region_dcache_behaviour(u32 start, int size,
+				     enum dcache_option option)
 {
 	u32 *page_table = (u32 *)gd->tlb_addr;
+	u32 upto, end;
+
+	end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT;
+	start = start >> MMU_SECTION_SHIFT;
+	debug("%s: start=%x, size=%x, option=%d\n", __func__, start, size,
+	      option);
+	for (upto = start; upto < end; upto++)
+		set_section_dcache(upto, option);
+	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
+}
+
+__weak void dram_bank_mmu_setup(int bank)
+{
 	bd_t *bd = gd->bd;
 	int	i;
 
@@ -54,20 +76,35 @@
 	for (i = bd->bi_dram[bank].start >> 20;
 	     i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
 	     i++) {
-		page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+		set_section_dcache(i, DCACHE_WRITETHROUGH);
+#else
+		set_section_dcache(i, DCACHE_WRITEBACK);
+#endif
+	}
+#ifdef DDR_SIZE_512M
+	for (i = (0x10000000 >> 20);
+	     i < (0x20000000 >> 20);
+	     i++) {
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+        set_section_dcache(i, DCACHE_WRITETHROUGH);
+#else
+        set_section_dcache(i, DCACHE_WRITEBACK);
+#endif
 	}
+#endif
 }
 
 /* to activate the MMU we need to set up virtual memory: use 1M areas */
 static inline void mmu_setup(void)
 {
-	u32 *page_table = (u32 *)gd->tlb_addr;
 	int i;
 	u32 reg;
 
+	arm_init_before_mmu();
 	/* Set up an identity-mapping for all 4GB, rw for everyone */
 	for (i = 0; i < 4096; i++)
-		page_table[i] = i << 20 | (3 << 10) | 0x12;
+		set_section_dcache(i, DCACHE_OFF);
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		dram_bank_mmu_setup(i);
@@ -75,23 +112,31 @@
 
 	/* Copy the page table address to cp15 */
 	asm volatile("mcr p15, 0, %0, c2, c0, 0"
-		     : : "r" (page_table) : "memory");
+		     : : "r" (gd->tlb_addr) : "memory");
 	/* Set the access control to all-supervisor */
 	asm volatile("mcr p15, 0, %0, c3, c0, 0"
 		     : : "r" (~0));
+
+	arm_init_domains();
+
 	/* and enable the mmu */
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
 	set_cr(reg | CR_M);
 }
 
+static int mmu_enabled(void)
+{
+	return get_cr() & CR_M;
+}
+
 /* cache_bit must be either CR_I or CR_C */
 static void cache_enable(uint32_t cache_bit)
 {
 	uint32_t reg;
 
 	/* The data cache is not active unless the mmu is enabled too */
-	if (cache_bit == CR_C)
+	if ((cache_bit == CR_C) && !mmu_enabled())
 		mmu_setup();
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
@@ -103,22 +148,25 @@
 {
 	uint32_t reg;
 
+	reg = get_cr();
+	cp_delay();
+
 	if (cache_bit == CR_C) {
 		/* if cache isn;t enabled no need to disable */
-		reg = get_cr();
 		if ((reg & CR_C) != CR_C)
 			return;
 		/* if disabling data cache, disable mmu too */
 		cache_bit |= CR_M;
-		flush_cache(0, ~0);
 	}
 	reg = get_cr();
 	cp_delay();
+	if (cache_bit == (CR_C | CR_M))
+		flush_dcache_all();
 	set_cr(reg & ~cache_bit);
 }
 #endif
 
-#ifdef CONFIG_SYS_NO_ICACHE
+#ifdef CONFIG_SYS_ICACHE_OFF
 void icache_enable (void)
 {
 	return;
@@ -150,7 +198,7 @@
 }
 #endif
 
-#ifdef CONFIG_SYS_NO_DCACHE
+#ifdef CONFIG_SYS_DCACHE_OFF
 void dcache_enable (void)
 {
 	return;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/arch/arm/lib/interrupts.c u-boot-2011.06/arch/arm/lib/interrupts.c
--- u-boot-2011.06_original/arch/arm/lib/interrupts.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/arch/arm/lib/interrupts.c	2014-07-29 17:28:38.819972000 +0800
@@ -51,6 +51,7 @@
 	FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
 
 	return arch_interrupt_init();
+	return 0;
 }
 
 /* enable IRQ interrupts */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/auto_update_1900.c u-boot-2011.06/board/cavium/cnc1900/auto_update_1900.c
--- u-boot-2011.06_original/board/cavium/cnc1900/auto_update_1900.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/auto_update_1900.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,625 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#include <usb.h>
+
+#include <jffs2/jffs2.h>
+#include <nand.h>
+//#include <cnc1800l_spi.h>
+
+#ifdef CONFIG_SYS_HUSH_PARSER
+#include <hush.h>
+#endif
+
+
+#ifdef CONFIG_AUTO_UPDATE
+
+#if 0
+#ifndef CONFIG_USB_OHCI_NEW
+#error "must define CONFIG_USB_OHCI"
+#endif
+
+#ifndef CONFIG_USB_STORAGE
+#error "must define CONFIG_USB_STORAGE"
+#endif
+
+#ifndef CONFIG_CMD_FAT
+#error "must define CONFIG_CMD_FAT"
+#endif
+#endif
+
+#undef AU_DEBUG
+
+#undef debug
+#ifdef	AU_DEBUG
+#define debug(fmt,args...)	printf (fmt ,##args)
+#else
+#define debug(fmt,args...)
+#endif	/* AU_DEBUG */
+
+/* possible names of files on the USB stick. */
+#define AU_FIRMWARE	"u-boot.img"
+#define AU_KERNEL	"uimage"
+#define AU_RAMDISK	"ramdisk.img"
+static  char *filename = "misc.img";
+//#define RESET_AFTER_USB_UPGRADE
+
+struct flash_layout {
+	long start;
+	long end;
+};
+
+unsigned int bootargs_len = 0;
+unsigned int bootcmd_len = 0;
+
+static int au_usb_stor_curr_dev; /* current device */
+
+/* index of each file in the following arrays */
+#define IDX_FIRMWARE	0
+#define IDX_KERNEL	1
+#define IDX_RAMDISK	2
+
+/* max. number of files which could interest us */
+#define AU_MAXFILES 3
+
+#define BOOT_START	0x34400000
+
+/* pointers to file names */
+char *aufile[AU_MAXFILES];
+
+/* sizes of flash areas for each file */
+long ausize[AU_MAXFILES];
+
+/* the index table of the file type */
+int autype[AU_MAXFILES] = { \
+	IH_TYPE_FIRMWARE, IH_TYPE_KERNEL, IH_TYPE_RAMDISK};
+
+/* the index table of the OS type */
+int ostype[AU_MAXFILES] = { \
+	IH_OS_LINUX, IH_OS_LINUX, IH_OS_LINUX}; //Reduce the probability of ramdom while we only upgrade uboot. --leiyu,2011.12.13
+
+/* array of flash areas start and end addresses */
+struct flash_layout aufl_layout[AU_MAXFILES]={{0}};
+
+#define VALID_ADDR 	(CONFIG_USB_UPGRADE_DATA_ADDR + 4 + bootargs_len + bootcmd_len + 48)
+
+/* externals */
+extern int fat_register_device(block_dev_desc_t *, int);
+extern int file_fat_detectfs(void);
+extern long file_fat_read(const char *, void *, unsigned long);
+//extern int i2c_read (unsigned char, unsigned int, int , unsigned char* , int);
+extern int flash_sect_erase(ulong, ulong);
+extern int flash_sect_protect (int, ulong, ulong);
+extern int flash_write (char *, ulong, ulong);
+/* change char* to void* to shutup the compiler */
+extern block_dev_desc_t *get_dev (const char*, int);
+extern int u_boot_hush_start(void);
+extern int do_sflasher(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_sflashre(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_usb(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_fat_fsload(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_call_external_proc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_cncflash(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_sflashwr(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_mem_md(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); 
+extern int do_flerase(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); 
+extern int do_mem_cmp(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); 
+extern int do_mem_cp(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); 
+
+int au_check_cksum_valid(long nbytes)
+{
+	image_header_t *hdr;
+	unsigned long checksum;
+
+	hdr = (image_header_t *)(VALID_ADDR);
+
+	/* check the data CRC */
+	checksum = ntohl(hdr->ih_dcrc);
+
+	if (crc32 (0, (uchar *)(VALID_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) {
+		printf ("usb upgrade file bad data checksum\n");
+		return -1;
+	}
+	return 0;
+}
+
+int au_check_header_valid(int idx, long nbytes)
+{
+	image_header_t *hdr;
+	unsigned long checksum;
+
+	hdr = (image_header_t *)VALID_ADDR;
+	/* check the easy ones first */
+#undef CHECK_VALID_DEBUG
+#ifdef CHECK_VALID_DEBUG
+	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
+	printf("arch %#x %#x ", hdr->ih_arch, IH_ARCH_ARM);
+	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
+	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+#endif
+	if (nbytes < sizeof(*hdr)) {
+		printf ("Image %s bad header SIZE\n", aufile[idx]);
+		return -1;
+	}
+	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_ARCH_ARM) {
+		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
+		return -1;
+	}
+	/* check the hdr CRC */
+	checksum = ntohl(hdr->ih_hcrc);
+	hdr->ih_hcrc = 0;
+
+	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+		printf ("Image %s bad header checksum\n", aufile[idx]);
+		return -1;
+	}
+	hdr->ih_hcrc = htonl(checksum);
+	/* check the type - could do this all in one gigantic if() */
+	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+		printf ("Image %s wrong type\n", aufile[idx]);
+		return -1;
+	}
+	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+		printf ("Image %s wrong type\n", aufile[idx]);
+		return -1;
+	}
+
+	/* recycle checksum */
+	checksum = ntohl(hdr->ih_size);
+	/* for kernel and app the image header must also fit into flash */
+	if (idx != IDX_FIRMWARE)
+		checksum += sizeof(*hdr);
+	/* check the size does not exceed space in flash. HUSH scripts */
+	/* all have ausize[] set to 0 */
+	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
+		printf ("Image %s is bigger than FLASH\n", aufile[idx]);
+		return -1;
+	}
+	return 0;
+}
+
+void decrypt(char * addr, int nbytes)
+{
+	int i;
+
+	for (i = 0; i < nbytes; i++) {
+		*addr++ ^= 0xE3;
+	}
+}
+
+int au_do_update(int idx, char * address)
+{
+	image_header_t *hdr;
+	unsigned int start, end;
+	char *addr;
+	int off=0;
+	int rc=0;
+	unsigned int nbytes;
+	char argv0[20];
+	char argv1[20];
+	char argv2[20];
+	char argv3[20];
+	char argv4[20];
+	off=off;
+
+	hdr = (image_header_t *)address;
+
+	start = aufl_layout[idx].start;
+	end = aufl_layout[idx].end;
+
+	/* unprotect the address range */
+	/* this assumes that ONLY the firmware is protected!
+	   if (idx == IDX_FIRMWARE) {
+	   flash_sect_protect(0, AU_FL_FIRMWARE_ST, aufl_layout[idx+1].start-1);
+	   }
+	   */
+
+	/*
+	 * erase the address range.
+	 */
+	/* Add By River 12.16.2008 */
+	switch( hdr->ih_type )
+	{
+		case IH_TYPE_FIRMWARE:
+			//			fpc_init_show("E.Ub");
+			break;
+
+		case IH_TYPE_KERNEL:
+			//			fpc_init_show("E.uI");
+			break;
+
+		case IH_TYPE_RAMDISK:
+			//			fpc_init_show("E.FS");
+			break;
+
+		default:
+			break;
+	}
+	debug ("flash_sect_erase(%lx, %lx);\n", start, end);
+
+	/*--------------------------------------------------------------------*/
+	/* 20091021 River's suggestion                                        */
+	/*--------------------------------------------------------------------*/
+
+	if(( hdr->ih_type == IH_TYPE_KERNEL )||( hdr->ih_type == IH_TYPE_RAMDISK ))
+	{
+		sprintf( argv0, "%s", "nand" );
+		sprintf( argv1, "%s", "erase" );
+		sprintf( argv2, "%X", start );
+		sprintf( argv3, "%X", end-start );
+
+		char *argv[] = {
+			argv0,
+			argv1,
+			argv2,
+			argv3
+		};
+
+		printf("running:%s %s %s %s\n", argv0, argv1, argv2, argv3);
+		rc = do_nand( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+		printf ("nand erase %X %X finished!\n",start,end-start);
+	}
+	/* Modify By River 27.04.2009 */
+	else if( hdr->ih_type == IH_TYPE_FIRMWARE )
+	{
+		sprintf( argv0, "%s", "sfer" );
+		sprintf( argv1, "%x", start );
+		sprintf( argv2, "%x", end-start );
+
+		char *argv[] = {
+			argv0,
+			argv1,
+			argv2
+		};
+		printf("running:%s %s %s\n", argv0, argv1, argv2);
+		rc = do_sflasher( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+		printf ("spi flash erase finished!\n");
+	}
+	/*--------------------------------------------------------------------*/
+
+
+	mdelay(100);
+	/* strip the header for the U-boot */
+	if (hdr->ih_type != IH_TYPE_KERNEL) {
+		addr = (char *)((char *)hdr + sizeof(*hdr));
+		off = 0;
+		nbytes = ntohl(hdr->ih_size);
+	} else {
+		addr = (char *)hdr;
+		off = sizeof(*hdr);
+		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+	}
+
+	/* copy the data from RAM to FLASH */
+	/* Add By River 12.16.2008 */
+	switch( hdr->ih_type )
+	{
+		case IH_TYPE_FIRMWARE:
+			//			fpc_init_show("P.Ub");
+			break;
+
+		case IH_TYPE_KERNEL:
+			//			fpc_init_show("P.uI");
+			break;
+
+		case IH_TYPE_RAMDISK:
+			//			fpc_init_show("P.FS");
+			break;
+
+		default:
+			break;
+	}
+
+
+	if(( hdr->ih_type == IH_TYPE_KERNEL )||( hdr->ih_type == IH_TYPE_RAMDISK ))
+	{
+		sprintf( argv0, "%s", "nand" );
+		sprintf( argv1, "%s", "write.jffs2" );
+		sprintf( argv2, "%x", (unsigned int)addr );
+		sprintf( argv3, "%x", start );
+		sprintf( argv4, "%x", nbytes );
+		char *argv[] = {
+			argv0,
+			argv1,
+			argv2,
+			argv3,
+			argv4
+		};
+		printf("running:%s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4);
+		rc = do_nand( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	}
+	if(hdr->ih_type == IH_TYPE_FIRMWARE)
+	{
+		sprintf( argv0, "%s", "sfwr" );
+		sprintf( argv1, "%x", (unsigned int)addr );
+		sprintf( argv2, "%x", start );
+		sprintf( argv3, "%x", nbytes );
+		char *argv[] = {
+			argv0,
+			argv1,
+			argv2,
+			argv3
+		};
+		printf("running:%s %s %s %s\n", argv0, argv1, argv2, argv3);
+		rc = do_sflashwr( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	}
+	else
+	{
+		printf("flash_write(%p, %x %x)\n", addr, start, nbytes);
+		debug ("flash_write(%p, %x %x)\n", addr, start, nbytes);
+		/* rc = flash_write(addr, start, nbytes);*/
+	}
+	printf("flash write finished!\n");
+	if (rc != 0) {
+		printf("Flashing failed due to error %d\n", rc);
+		return -1;
+	}
+
+	/* check the dcrc of the copy
+	   if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+	   printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
+	   return -1;
+	   }
+	   */
+
+	/* protect the address range */
+	/* this assumes that ONLY the firmware is protected!
+	   if (idx == IDX_FIRMWARE)
+	   flash_sect_protect(1, AU_FL_FIRMWARE_ST, aufl_layout[idx+1].start-1);
+	   */
+	return 0;
+}
+
+/*
+ * this is called from board_init() after the hardware has been set up
+ * and is usable. That seems like a good time to do this.
+ * Right now the return value is ignored.
+ */
+int do_auto_update(unsigned int size)
+{
+	block_dev_desc_t *stor_dev;
+	long sz;
+	int i, j, res=0, bitmap_first=0, old_ctrlc;
+	//char *env;
+	long start, end;
+	long actual_size=0;
+	image_header_t *hdr;
+	char * addr;
+	char st[9], len[9];
+	char *ptr = (char *)CONFIG_USB_UPGRADE_DATA_ADDR;
+	char *ep;
+	char *bootargs = NULL;
+	char *bootcmd = NULL;
+	actual_size=actual_size;
+	bitmap_first=bitmap_first;
+	res=res;
+	/* initialize the array of file names */
+	memset(aufile, 0, sizeof(aufile));
+	aufile[IDX_FIRMWARE] = AU_FIRMWARE;
+	aufile[IDX_KERNEL] = AU_KERNEL;
+	aufile[IDX_RAMDISK] = AU_RAMDISK;
+	/* initialize the array of flash sizes */
+	memset(ausize, 0, sizeof(ausize));
+	/* make sure that we see CTRL-C and save the old state */
+	old_ctrlc = disable_ctrlc(0);
+
+	if(!size){
+		au_usb_stor_curr_dev = -1;
+		/* start USB */
+		if (usb_stop() < 0) {
+			debug ("usb_stop failed\n");
+			return -1;
+		}
+		if (usb_init() < 0) {
+			debug ("usb_init failed\n");
+			return -1;
+		}
+
+		/*
+		 * check whether a storage device is attached (assume that it's
+		 * a USB memory stick, since nothing else should be attached).
+		 */
+		au_usb_stor_curr_dev = usb_stor_scan(0);
+		if (au_usb_stor_curr_dev == -1) {
+			debug ("No device found. Not initialized?\n");
+			return -1;
+		}
+
+		//		fpc_init_show("Upda");	/* Add By River 12.16.2008 */
+
+		/* check whether it has a partition table */
+		stor_dev = get_dev("usb", 0);
+		if (stor_dev == NULL) {
+			debug ("uknown device type\n");
+			return -1;
+		}
+		if (fat_register_device(stor_dev, 1) != 0) {
+			debug ("Unable to use USB %d:%d for fatls\n",
+					au_usb_stor_curr_dev, 1);
+			return -1;
+		}
+		if (file_fat_detectfs() != 0) {
+			debug ("file_fat_detectfs failed\n");
+		}
+
+		/*
+		 * now check whether start and end are defined using environment
+		 * variables.
+		 */
+		/*start = -1;
+		  end = 0;
+		  env = getenv("firmware_st");
+		  if (env != NULL)
+		  start = simple_strtoul(env, NULL, 16);
+		  env = getenv("firmware_nd");
+		  if (env != NULL)
+		  end = simple_strtoul(env, NULL, 16);
+		  if (start >= 0 && end && end > start) {
+		  ausize[IDX_FIRMWARE] = (end + 1) - start;
+		  aufl_layout[0].start = start;
+		  aufl_layout[0].end = end;
+		  }
+		  start = -1;
+		  end = 0;
+		  env = getenv("kernel_st");
+		  if (env != NULL)
+		  start = simple_strtoul(env, NULL, 16);
+		  env = getenv("kernel_nd");
+		  if (env != NULL)
+		  end = simple_strtoul(env, NULL, 16);
+		  if (start >= 0 && end && end > start) {
+		  ausize[IDX_KERNEL] = (end + 1) - start;
+		  aufl_layout[1].start = start;
+		  aufl_layout[1].end = end;
+		  }
+		  start = -1;
+		  end = 0;
+		  env = getenv("ramdisk_st");
+		  if (env != NULL)
+		  start = simple_strtoul(env, NULL, 16);
+		  env = getenv("ramdisk_nd");
+		  if (env != NULL)
+		  end = simple_strtoul(env, NULL, 16);
+		  if (start >= 0 && end && end > start) {
+		  ausize[IDX_KERNEL] = (end + 1) - start;
+		  aufl_layout[2].start = start;
+		  aufl_layout[2].end = end;
+		  }*/
+		/* make certain that HUSH is runnable */
+		u_boot_hush_start();
+
+		bitmap_first = 0;
+		// the first byte is the string length of bootargs
+
+		//		fpc_init_show("Read");	/* Add By River 12.16.2008 */
+
+		sz = file_fat_read(filename, (void*)(CONFIG_USB_UPGRADE_DATA_ADDR), 0);
+		if (sz <= 0) {
+			debug ("file %s not found\n", filename);
+			return -1;
+		}
+	}else{
+		size -= 256;
+		sz = size;
+		printf("Upgrade directly from RAM: 0x%08x, size = 0x%08x\n", (unsigned int)CONFIG_USB_UPGRADE_DATA_ADDR,(unsigned int) sz);
+	}
+
+	//	dcache_enable();
+
+	decrypt((char *)CONFIG_USB_UPGRADE_DATA_ADDR, sz);
+	bootargs_len = (*ptr << 8) | (*(ptr+1));
+	printf("bootargs_len = %d\n",bootargs_len);
+	ptr +=2;
+	bootcmd_len = (*ptr << 8) | (*(ptr+1));
+	printf("bootcmd_len = %d\n",bootcmd_len);
+	bootargs = malloc(bootargs_len + 1);
+	memcpy( (void*) bootargs, (void*) ( CONFIG_USB_UPGRADE_DATA_ADDR + 4) , bootargs_len);
+	bootargs[bootargs_len] = '\0';
+	printf("[bootargs]: %s\n", bootargs);
+	bootcmd = malloc(bootcmd_len + 1);
+	memcpy(bootcmd, (void*)( CONFIG_USB_UPGRADE_DATA_ADDR + 4 + bootargs_len), bootcmd_len);
+	bootcmd[bootcmd_len] = '\0';
+	printf("[bootcmd]: %s\n", bootcmd);
+
+	ptr = (char*) ( CONFIG_USB_UPGRADE_DATA_ADDR + 4 + bootargs_len + bootcmd_len );
+	for (i = 0; i < 3; i++) {
+		for(j = 0; j < 8; j++) {
+			st[j] = *ptr++;
+		}
+		st[j] = '\0';
+		for(j = 0; j < 8; j++) {
+			len[j] = *ptr++;
+		}
+		len[j] = '\0';
+
+		start = simple_strtoul(st, &ep, 16);
+		if (ep == st || *ep != '\0') {
+			printf("simple_strtoul return error!\n");
+			return -1;
+		}
+
+		end = simple_strtoul(len, &ep, 16);
+		if (ep == st || *ep != '\0') 
+		{
+			printf("simple_strtoul return error!\n");
+			return -1;
+		}
+		if (end == 0)
+			continue;
+
+		if (start >= end) {
+			printf("Start address beyond end address\n");
+			return -1;
+		}
+		ausize[i] = (end + 1) - start;
+		aufl_layout[i].start = start;
+		aufl_layout[i].end = end;
+		printf("%s: 0x%lX--0x%lX\n", aufile[i], aufl_layout[i].start, aufl_layout[i].end);
+	}
+
+	hdr = (image_header_t *)(VALID_ADDR);
+	actual_size = ntohl(hdr->ih_size);
+	if (au_check_cksum_valid(sz) < 0) {
+		debug ("%s checksum not valid\n", filename);
+		return -1;
+	}
+
+	//	dcache_disable();
+	addr = (char*) (VALID_ADDR + sizeof(image_header_t) );
+	/* just loop thru all the possible files */
+	for (i = 0; i < AU_MAXFILES; i++) {
+		hdr = (image_header_t *)addr;
+		if (hdr->ih_type == autype[i] && hdr->ih_os == ostype[i]) {
+			res = au_do_update(i, addr);
+			addr += (sizeof(image_header_t) + ntohl(hdr->ih_size));
+		}
+	}
+
+	if (bootargs_len != 0){
+		setenv("bootargs", bootargs);
+	}
+	if (bootcmd_len != 0){
+		setenv("bootcmd", bootcmd);
+	}
+	if ((bootargs_len != 0) || (bootcmd_len != 0)){
+		int i = 0;
+		for(i = 0; i< 500; i++)
+			udelay(1000);
+		saveenv();
+	}
+
+	free(bootargs);
+	free(bootcmd);
+
+	usb_stop();
+	/* restore the old state */
+	disable_ctrlc(old_ctrlc);
+
+	//	fpc_init_show("rebt");	/* Add By River 12.16.2008 */
+	//while(1){};
+#ifdef RESET_AFTER_USB_UPGRADE
+	do_reset( NULL, 0, 0, NULL );
+#endif
+	return 0;
+}
+#endif /* CONFIG_AUTO_UPDATE */
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/cnc1900.c u-boot-2011.06/board/cavium/cnc1900/cnc1900.c
--- u-boot-2011.06_original/board/cavium/cnc1900/cnc1900.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/cnc1900.c	2015-09-25 11:55:28.920111000 +0800
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2012
+ * Cavium Networks xiaodong.fan@cavium.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
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <spi_flash.h>
+#include "irqs.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PINMUX_I2C_ENABLE 0xb2110004
+#define PINMUX_UART_ENABLE 0xb2110008
+#define PINMUX_SPI_ENABLE 0xb211000c
+#define PINMUX_SMI_ENABLE 0xb2110010
+#define PINMUX_DISPLAY_ENABLE 0xb2110014
+#define PINMUX_ETHER_ENABLE 0xb2110020
+
+#define TEST_IRQ
+
+#define HW_REG_READ( ByteAddr )      (*(volatile unsigned int*)(ByteAddr))
+
+#ifndef CONFIG_SF_DEFAULT_SPEED
+# define CONFIG_SF_DEFAULT_SPEED	1000000
+#endif
+#ifndef CONFIG_SF_DEFAULT_MODE
+# define CONFIG_SF_DEFAULT_MODE		SPI_MODE_3
+#endif
+
+
+#ifdef CONFIG_USE_IRQ
+irq_handle cnc1900_irq_vector[NR_IRQS];
+void * cnc1900_irq_data[NR_IRQS];
+
+extern int gpio_hw_set_direct(int gpio_id, int dir);
+extern int gpio_hw_write(int gpio_id, unsigned short data);
+
+void cnc1900_irq_enable(unsigned int irq)
+{
+    if (irq>=0 && irq< NR_IRQS)
+        *(((unsigned int*)(GIC_DIST_BASE+0x100 + (irq / 32) * 4))) = 1 << (irq % 32);
+}
+
+void cnc1900_irq_disable(unsigned int irq)
+{
+    if (irq>=0 && irq< NR_IRQS)
+        *(((unsigned int*)(GIC_DIST_BASE + 0x180 + (irq / 32) * 4))) = 1 << (irq % 32);
+}
+
+void cnc1900_register_irq(int irq, irq_handle irq_r, void * irq_data)
+{
+    if (irq>=0 && irq< NR_IRQS) {
+        cnc1900_irq_vector[irq] = irq_r;
+        cnc1900_irq_data[irq] = irq_data;
+    }
+}
+
+void cnc1900_unregister_irq(int irq)
+{
+    if (irq>=0 && irq< NR_IRQS) {
+        cnc1900_irq_vector[irq] = NULL;
+        cnc1900_irq_data[irq] = NULL;
+    }
+}
+
+#ifdef TEST_IRQ
+/*for test only*/
+extern int gpio_num_for_blink;
+int blink_toggle = 1;
+int wd_timer_irq_handle(unsigned int irq, void * data)
+{
+	//printf("in wd_timer_irq_handle \n");
+	blink_toggle = !blink_toggle;
+	if(-1 != gpio_num_for_blink){
+		gpio_hw_set_direct(gpio_num_for_blink, 1);
+		gpio_hw_write(gpio_num_for_blink, blink_toggle);
+	}
+	return 0;
+ }
+
+void disable_and_unregister_wd_timer_irq(void)
+{
+	 cnc1900_irq_disable(30);
+        cnc1900_unregister_irq(30);
+}
+
+void register_and_enable_wd_timer_irq(unsigned int ticks)
+{
+	printf("ticks = %d\n", ticks);
+    //write WD Timer Interrupt Status Register
+    //clear the possible unwanted interrupt request before enable WD timer interrupt
+    (*( (volatile unsigned int*)(CNC1900_CA9_TWD+0x2C) )) = 1;
+
+    //write WD Timer Load Register, delay time
+    (*( (volatile unsigned int*)(CNC1900_CA9_TWD+0x20) )) = ticks;
+
+    //write WD Timer Control Register
+    //WD mode = 0
+    //IRQ enable = 1
+    //Auto reload = 1
+    //WD enable = 1
+    (*( (volatile unsigned int*)(CNC1900_CA9_TWD+0x28) )) = 7;   
+
+    cnc1900_register_irq(30, wd_timer_irq_handle, (void *) NULL);
+    cnc1900_irq_enable(30);
+}
+
+#endif
+
+int arch_interrupt_init(void)
+{
+    int i;
+
+    for (i=0; i< NR_IRQS; i++) {
+        cnc1900_irq_vector[i] = NULL;
+        cnc1900_irq_data[i] = NULL;
+    }
+
+    //set Vector Base Address Register to 0.
+    __asm__ __volatile__(
+        "mov r0, #0                                  @prepare data \n\t"
+        "mcr p15, 0, r0, c12, c0, 0                  @Write CP15 Vector Base Address Register \n\t"
+        :::"r0");
+
+    //set all shareable peripheral interrupts as secure interrupt
+    for(i=0;i<3;i++)
+    {
+        *(((unsigned int*)(GIC_DIST_BASE+0x80))+i)=0;
+    }
+
+    //set all shareable peripheral interrupts as level sensitive, high active
+    for(i=0;i<4;i++)
+    {
+        *(((unsigned int*)(GIC_DIST_BASE+0xc00+0x8))+i)=0x55555555;
+    }
+
+    //set the priority of all shareable peripheral interrupts to 0(the highest priority)
+    for(i=0;i<24;i++)
+    {
+        *(((unsigned int*)(GIC_DIST_BASE+0x400))+i)=0;
+    }
+
+    //set all PPI and SPI target to all CPU interface
+    for(i=0;i<24;i++)
+    {
+        *(((unsigned int*)(GIC_DIST_BASE+0x800))+i)=0x11111111;
+    }
+
+    //disable all interrupts
+    for(i=0;i<3;i++)
+    {
+        *(((unsigned int*)(GIC_DIST_BASE+0x180))+i)=0xFFFFFFFF;
+    }
+
+    //set the priority mask of cpu interface to 8'hff(the lowest priority)
+    *(((unsigned int*)(GIC_CPU_BASE+0x4)))=0xf0;
+    
+    //set the binary point position of cpu interface to 8'hff(not grouping interrupt)
+    *(((unsigned int*)(GIC_CPU_BASE+0x8)))=0xff;
+
+    //enable all interrupts in CPU interface
+    //set all interrupts are sent to CPU through IRQ pin
+    *(((unsigned int*)(GIC_CPU_BASE+0x0)))=0x3;
+
+    //enable all interrupts in interrupt distributor
+    *(((unsigned int*)(GIC_DIST_BASE+0x0)))=0x1;
+
+    //disable low interrupt latency
+    __asm__ __volatile__(
+        "mrc p15, 0, r0, c1, c0, 0   @read CP15 system control register \n\t"
+        "and r0, r0, #0xffdfffff     @clear FI bit to 0 \n\t"
+        "mcr p15, 0, r0, c1, c0, 0   @write CP15 system control register \n\t"
+        :::"r0");
+
+    //setup_wd_timer_irq(300000000);
+    return 0;
+}
+
+int cnc1900_do_interrupt(void)
+{
+    int vec;
+    //read interrupt ID and acknowlege this interrupt.
+    vec = (*( (volatile unsigned int*)(GIC_CPU_BASE+0xC)));
+
+    if(vec<NR_IRQS)
+    {
+        if (NULL != cnc1900_irq_vector[vec]) 
+        {
+            cnc1900_irq_vector[vec](vec,cnc1900_irq_data[vec]);
+        }
+    }
+
+    //end this interrupt.
+    (*( (volatile unsigned int*)(GIC_CPU_BASE+0x10)))=vec;
+
+    return 0;
+}
+#endif
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+const unsigned int pll_cpu_div_qv[4] = {1, 2, 4, 6};
+int board_init(void)
+{
+	unsigned int pll_cpu_div_f, pll_cpu_div_q;
+	unsigned int pll_ddr_div_f, pll_ddr_div_q;
+	unsigned long long big = (2LL << 32) * 27000000, div;
+
+    gd->bd->bi_arch_number = 1662;
+    gd->bd->bi_boot_params = 0x00000100;
+    icache_enable();
+
+#ifdef CONFIG_SPI_FLASH_CNC1900 
+	spi__init();
+#endif
+
+	pll_cpu_div_f = (HW_REG_READ(0xb2100318) >> 6) & 0x7f;
+	pll_cpu_div_q = (HW_REG_READ(0xb2100318) >> 3) & 0x7;
+
+	pll_ddr_div_f = (HW_REG_READ(0xb2100338)) & 0x3fffffff;
+	pll_ddr_div_q = (HW_REG_READ(0xb2100334)) & 0x1f;
+
+	div = (unsigned long long)pll_ddr_div_f * (2 * pll_ddr_div_q + 2);
+	gd->ddr_freq = lldiv(big, div) * 2;
+	gd->cpu_freq = (unsigned int)lldiv((unsigned long long)(pll_cpu_div_f + 1) * 54000000LL, pll_cpu_div_qv[pll_cpu_div_q]);
+#if 0
+	printf("CPU / DDR: %dMHz / %dMHz\n", gd->cpu_freq / 1000000, gd->ddr_freq / 1000000);
+#endif
+	
+
+    return 0;
+}
+
+int board_late_init(void)
+{
+	unsigned int miniloader_signature;
+	char *current_env = getenv("uboot_image");
+	char *new_env;
+
+#ifndef CONFIG_SPI_FLASH_CNC1900 
+	spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+#endif
+
+
+	miniloader_signature = *((volatile unsigned int *)(0x7000000));
+	if((miniloader_signature & 0xffff0000) == 0xdead0000){
+		new_env = (miniloader_signature & 1)?"2":"1";
+		/* Save new env only if it is different from the current one */
+		if(current_env == NULL || *current_env != *new_env){
+			setenv("uboot_image", new_env);
+			saveenv();
+		}
+	}
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE,
+				    CONFIG_SYS_SDRAM_SIZE);
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+}
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/irqs.h u-boot-2011.06/board/cavium/cnc1900/irqs.h
--- u-boot-2011.06_original/board/cavium/cnc1900/irqs.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/irqs.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,174 @@
+#ifndef __ORION_IRQS_H__
+#define __ORION_IRQS_H__
+
+
+typedef int (* irq_handle)(unsigned int, void *);
+
+
+#define GIC_CPU_BASE           (0x80020000+0x100)
+#define CNC1900_CA9_TWD        (0x80020000+0x600)
+#define GIC_DIST_BASE          (0x80020000+0x1000)
+
+
+
+
+#define PA_VIC_BASE		    0x80140000
+#define VIC_IRQ_STATUS	0x28	/*mask status*/
+#define VIC_IRQ_ENABLE	0
+#define VIC_IRQ_MASK	8	
+
+#define INT_VICSOURCE21                 21      
+#define INT_VICSOURCE22                 22     
+#define INT_VICSOURCE23                 23     
+#define INT_VICSOURCE24                 24      
+#define INT_VICSOURCE25                 25    
+#define INT_VICSOURCE26                 26      
+#define INT_VICSOURCE27                 27      
+#define INT_VICSOURCE28                 28      
+#define INT_VICSOURCE29                 29        /* Ethernet */
+#define INT_VICSOURCE30                 30      
+#define INT_VICSOURCE31                 31    
+
+
+#define IRQ_VIC_START		0
+#define IRQ_WDOGINT		(IRQ_VIC_START + INT_WDOGINT)
+#define IRQ_SOFTINT		(IRQ_VIC_START + INT_SOFTINT)
+#define IRQ_COMMRx		(IRQ_VIC_START + INT_COMMRx)
+#define IRQ_COMMTx		(IRQ_VIC_START + INT_COMMTx)
+#define IRQ_TIMERINT0_1		(IRQ_VIC_START + INT_TIMERINT0_1)
+#define IRQ_TIMERINT2_3		(IRQ_VIC_START + INT_TIMERINT2_3)
+#define IRQ_GPIOINT0		(IRQ_VIC_START + INT_GPIOINT0)
+#define IRQ_GPIOINT1		(IRQ_VIC_START + INT_GPIOINT1)
+#define IRQ_GPIOINT2		(IRQ_VIC_START + INT_GPIOINT2)
+#define IRQ_GPIOINT3		(IRQ_VIC_START + INT_GPIOINT3)
+#define IRQ_RTCINT		(IRQ_VIC_START + INT_RTCINT)
+#define IRQ_SSPINT		(IRQ_VIC_START + INT_SSPINT)
+#define IRQ_UARTINT0		(IRQ_VIC_START + INT_UARTINT0)
+#define IRQ_UARTINT1		(IRQ_VIC_START + INT_UARTINT1)
+#define IRQ_UARTINT2		(IRQ_VIC_START + INT_UARTINT2)
+#define IRQ_SCIINT		(IRQ_VIC_START + INT_SCIINT)
+#define IRQ_CLCDINT		(IRQ_VIC_START + INT_CLCDINT)
+#define IRQ_DMAINT		(IRQ_VIC_START + INT_DMAINT)
+#define IRQ_PWRFAILINT 		(IRQ_VIC_START + INT_PWRFAILINT)
+#define IRQ_MBXINT		(IRQ_VIC_START + INT_MBXINT)
+#define IRQ_GNDINT		(IRQ_VIC_START + INT_GNDINT)
+#define IRQ_VICSOURCE21		(IRQ_VIC_START + INT_VICSOURCE21)
+#define IRQ_VICSOURCE22		(IRQ_VIC_START + INT_VICSOURCE22)
+#define IRQ_VICSOURCE23		(IRQ_VIC_START + INT_VICSOURCE23)
+#define IRQ_VICSOURCE24		(IRQ_VIC_START + INT_VICSOURCE24)
+#define IRQ_VICSOURCE25		(IRQ_VIC_START + INT_VICSOURCE25)
+#define IRQ_VICSOURCE26		(IRQ_VIC_START + INT_VICSOURCE26)
+#define IRQ_VICSOURCE27		(IRQ_VIC_START + INT_VICSOURCE27)
+#define IRQ_VICSOURCE28		(IRQ_VIC_START + INT_VICSOURCE28)
+#define IRQ_VICSOURCE29		(IRQ_VIC_START + INT_VICSOURCE29)
+#define IRQ_VICSOURCE30		(IRQ_VIC_START + INT_VICSOURCE30)
+#define IRQ_VICSOURCE31		(IRQ_VIC_START + INT_VICSOURCE31)
+#define IRQ_VIC_END		    (IRQ_VIC_START + 31)
+
+#define IRQMASK_WDOGINT		INTMASK_WDOGINT
+#define IRQMASK_SOFTINT		INTMASK_SOFTINT
+#define IRQMASK_COMMRx 		INTMASK_COMMRx
+#define IRQMASK_COMMTx 		INTMASK_COMMTx
+#define IRQMASK_TIMERINT0_1	INTMASK_TIMERINT0_1
+#define IRQMASK_TIMERINT2_3	INTMASK_TIMERINT2_3
+#define IRQMASK_GPIOINT0	INTMASK_GPIOINT0
+#define IRQMASK_GPIOINT1	INTMASK_GPIOINT1
+#define IRQMASK_GPIOINT2	INTMASK_GPIOINT2
+#define IRQMASK_GPIOINT3	INTMASK_GPIOINT3
+#define IRQMASK_RTCINT 		INTMASK_RTCINT
+#define IRQMASK_SSPINT 		INTMASK_SSPINT
+#define IRQMASK_UARTINT0	INTMASK_UARTINT0
+#define IRQMASK_UARTINT1	INTMASK_UARTINT1
+#define IRQMASK_UARTINT2	INTMASK_UARTINT2
+#define IRQMASK_SCIINT 		INTMASK_SCIINT
+#define IRQMASK_CLCDINT		INTMASK_CLCDINT
+#define IRQMASK_DMAINT 		INTMASK_DMAINT
+#define IRQMASK_PWRFAILINT	INTMASK_PWRFAILINT
+#define IRQMASK_MBXINT 		INTMASK_MBXINT
+#define IRQMASK_GNDINT 		INTMASK_GNDINT
+#define IRQMASK_VICSOURCE21	INTMASK_VICSOURCE21
+#define IRQMASK_VICSOURCE22	INTMASK_VICSOURCE22
+#define IRQMASK_VICSOURCE23	INTMASK_VICSOURCE23
+#define IRQMASK_VICSOURCE24	INTMASK_VICSOURCE24
+#define IRQMASK_VICSOURCE25	INTMASK_VICSOURCE25
+#define IRQMASK_VICSOURCE26	INTMASK_VICSOURCE26
+#define IRQMASK_VICSOURCE27	INTMASK_VICSOURCE27
+#define IRQMASK_VICSOURCE28	INTMASK_VICSOURCE28
+#define IRQMASK_VICSOURCE29	INTMASK_VICSOURCE29
+#define IRQMASK_VICSOURCE30	INTMASK_VICSOURCE30
+#define IRQMASK_VICSOURCE31	INTMASK_VICSOURCE31
+
+/* 
+ *  FIQ interrupts definitions are the same the INT definitions.
+ */
+#define FIQ_WDOGINT		INT_WDOGINT
+#define FIQ_SOFTINT		INT_SOFTINT
+#define FIQ_COMMRx		INT_COMMRx
+#define FIQ_COMMTx		INT_COMMTx
+#define FIQ_TIMERINT0_1		INT_TIMERINT0_1
+#define FIQ_TIMERINT2_3		INT_TIMERINT2_3
+#define FIQ_GPIOINT0		INT_GPIOINT0
+#define FIQ_GPIOINT1		INT_GPIOINT1
+#define FIQ_GPIOINT2		INT_GPIOINT2
+#define FIQ_GPIOINT3		INT_GPIOINT3
+#define FIQ_RTCINT		INT_RTCINT
+#define FIQ_SSPINT		INT_SSPINT
+#define FIQ_UARTINT0		INT_UARTINT0
+#define FIQ_UARTINT1		INT_UARTINT1
+#define FIQ_UARTINT2		INT_UARTINT2
+#define FIQ_SCIINT		INT_SCIINT
+#define FIQ_CLCDINT		INT_CLCDINT
+#define FIQ_DMAINT		INT_DMAINT
+#define FIQ_PWRFAILINT 		INT_PWRFAILINT
+#define FIQ_MBXINT		INT_MBXINT
+#define FIQ_GNDINT		INT_GNDINT
+#define FIQ_VICSOURCE21		INT_VICSOURCE21
+#define FIQ_VICSOURCE22		INT_VICSOURCE22
+#define FIQ_VICSOURCE23		INT_VICSOURCE23
+#define FIQ_VICSOURCE24		INT_VICSOURCE24
+#define FIQ_VICSOURCE25		INT_VICSOURCE25
+#define FIQ_VICSOURCE26		INT_VICSOURCE26
+#define FIQ_VICSOURCE27		INT_VICSOURCE27
+#define FIQ_VICSOURCE28		INT_VICSOURCE28
+#define FIQ_VICSOURCE29		INT_VICSOURCE29
+#define FIQ_VICSOURCE30		INT_VICSOURCE30
+#define FIQ_VICSOURCE31		INT_VICSOURCE31
+
+
+#define FIQMASK_WDOGINT		INTMASK_WDOGINT
+#define FIQMASK_SOFTINT		INTMASK_SOFTINT
+#define FIQMASK_COMMRx 		INTMASK_COMMRx
+#define FIQMASK_COMMTx 		INTMASK_COMMTx
+#define FIQMASK_TIMERINT0_1	INTMASK_TIMERINT0_1
+#define FIQMASK_TIMERINT2_3	INTMASK_TIMERINT2_3
+#define FIQMASK_GPIOINT0	INTMASK_GPIOINT0
+#define FIQMASK_GPIOINT1	INTMASK_GPIOINT1
+#define FIQMASK_GPIOINT2	INTMASK_GPIOINT2
+#define FIQMASK_GPIOINT3	INTMASK_GPIOINT3
+#define FIQMASK_RTCINT 		INTMASK_RTCINT
+#define FIQMASK_SSPINT 		INTMASK_SSPINT
+#define FIQMASK_UARTINT0	INTMASK_UARTINT0
+#define FIQMASK_UARTINT1	INTMASK_UARTINT1
+#define FIQMASK_UARTINT2	INTMASK_UARTINT2
+#define FIQMASK_SCIINT 		INTMASK_SCIINT
+#define FIQMASK_CLCDINT		INTMASK_CLCDINT
+#define FIQMASK_DMAINT 		INTMASK_DMAINT
+#define FIQMASK_PWRFAILINT	INTMASK_PWRFAILINT
+#define FIQMASK_MBXINT 		INTMASK_MBXINT
+#define FIQMASK_GNDINT 		INTMASK_GNDINT
+#define FIQMASK_VICSOURCE21	INTMASK_VICSOURCE21
+#define FIQMASK_VICSOURCE22	INTMASK_VICSOURCE22
+#define FIQMASK_VICSOURCE23	INTMASK_VICSOURCE23
+#define FIQMASK_VICSOURCE24	INTMASK_VICSOURCE24
+#define FIQMASK_VICSOURCE25	INTMASK_VICSOURCE25
+#define FIQMASK_VICSOURCE26	INTMASK_VICSOURCE26
+#define FIQMASK_VICSOURCE27	INTMASK_VICSOURCE27
+#define FIQMASK_VICSOURCE28	INTMASK_VICSOURCE28
+#define FIQMASK_VICSOURCE29	INTMASK_VICSOURCE29
+#define FIQMASK_VICSOURCE30	INTMASK_VICSOURCE30
+#define FIQMASK_VICSOURCE31	INTMASK_VICSOURCE31
+
+#define NR_IRQS			96
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/lowlevel_init.S u-boot-2011.06/board/cavium/cnc1900/lowlevel_init.S
--- u-boot-2011.06_original/board/cavium/cnc1900/lowlevel_init.S	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/lowlevel_init.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,110 @@
+/*
+ * Board specific setup info
+ *
+ * xiaodong fan, <xiaodong.fan@caviumnetworks.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
+ */
+
+#include <config.h>
+#include <version.h>
+
+        
+/* Set up the platform, once the cpu has been initialized */
+.globl lowlevel_init
+lowlevel_init:
+	mov  pc, lr
+
+
+.globl invalidate_dcache
+invalidate_dcache:
+	stmdb	r13!,{r0,r1,r2,r3,r14}
+	@invalidate instruction cache
+    
+    mov	r1, #0
+    mcr p15, 0, r1, c7, c1, 0
+
+    mcr	p15, 0, r1, c7, c5, 0
+
+	@ invalidate the i&d tlb entries
+	mcr	p15, 0, r1, c8, c5, 0
+	mcr	p15, 0, r1, c8, c6, 0
+
+	@ Now flush the Dcache
+	mov	r0, #0
+	@ 256 cache lines
+	mov	r1, #256
+
+invalidate_loop:
+	add	r1, r1, #-1
+	mov	r0, r1, lsl #5
+	@ invalidate d-cache using line (way0)
+	mcr	p15, 0, r0, c7, c6, 2
+
+	orr	r2, r0, #(1<<30)
+	@ invalidate d-cache using line (way1)
+	mcr	p15, 0, r2, c7, c6, 2
+
+	orr	r2, r0, #(2<<30)
+	@ invalidate d-cache using line (way2)
+	mcr	p15, 0, r2, c7, c6, 2
+
+	orr	r2, r0, #(3<<30)
+	@ invalidate d-cache using line (way3)
+	mcr	p15, 0, r2, c7, c6, 2
+	cmp	r1, #0
+	bne	invalidate_loop
+    mov r1, #0
+    mcr	p15, 0, r1, c7, c10, 4	@ DSB
+    mcr	p15, 0, r1, c7, c5, 4	@ ISB
+      
+	@ FIXME: should have 1900's L2 disabled too?
+    /*invalidate TLB */
+    mov r1, #0x0   
+    mcr p15, 0, r1, c8, c3, 0 
+    mcr	p15, 0, r1, c7, c10, 4	@ DSB
+    mcr	p15, 0, r1, c7, c5, 4	@ ISB
+  
+    /*invalidate branch predictor */
+    mov r1, #0x0
+    mcr p15, 0, r1, c7, c1, 6   
+    mcr	p15, 0, r1, c7, c10, 4	@ DSB
+    mcr	p15, 0, r1, c7, c5, 4	@ ISB
+invalidate_done:
+    ldmia	r13!,{r0,r1,r2,r3,pc}
+
+
+ 
+//void flush_and_then_invalidate_L1_data_cache(unsigned char* p, unsigned int size);
+
+        
+.globl flush_and_then_invalidate_L1_data_cache
+flush_and_then_invalidate_L1_data_cache:     /*function definition*/
+    add r2, r0, r1
+    and r0, r0, #0xffffffe0     /* align the MVA to cache line boundary */
+flush_and_then_invalidate_L1_data_cache_loop:   
+    cmp r0, r2
+    bhi end_flush_and_then_invalidate_L1_data_cache_loop
+    mcr p15, 0, r0, c7, c14, 1  /*issue the command of clean & invalidate data cache line by MVA to point of coherency*/
+    add r0, r0, #0x10           /*move to next cache line*/
+    b flush_and_then_invalidate_L1_data_cache_loop
+end_flush_and_then_invalidate_L1_data_cache_loop: 
+    mcr	p15, 0, r1, c7, c10, 4	@ DSB
+    mcr	p15, 0, r1, c7, c5, 4	@ ISB
+    bx lr
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/Makefile u-boot-2011.06/board/cavium/cnc1900/Makefile
--- u-boot-2011.06_original/board/cavium/cnc1900/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/Makefile	2015-05-29 15:18:31.577595000 +0800
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2004
+# ARM Ltd.
+# Philippe Robin, <philippe.robin@arm.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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= cnc1900.o power_clock.o
+SOBJS	:= lowlevel_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/power_clock.c u-boot-2011.06/board/cavium/cnc1900/power_clock.c
--- u-boot-2011.06_original/board/cavium/cnc1900/power_clock.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/power_clock.c	2015-05-18 19:41:06.764203000 +0800
@@ -0,0 +1,1692 @@
+/****************************************************************************
+  * Copyright (C) 2011 Cavium Inc.
+  * All rights reserved
+  *
+  * [RELEASE HISTORY]                           
+  * VERSION  DATE       AUTHOR                  DESCRIPTION
+  * 0.1      11-10-10       Jia Ma           		Original
+  ****************************************************************************
+*/
+
+#include <linux/types.h>
+#include <common.h>
+#include <asm/byteorder.h>
+#include <malloc.h>
+#include "cnc_util.h"
+#include "power_clock.h"
+
+#define df_clk_write(a,v) (*(volatile unsigned int*)(a) = (v))
+#define df_clk_read(a)    (*(volatile unsigned int*)(a))
+#if 0
+typedef struct _DISP_PLL_CFG_
+{
+  DISP_CLOCK_MODE mode;
+  double          frequency;
+  unsigned int    tve_sys_divider;
+  unsigned int    tve_m;
+  unsigned int    tve_fb;
+}DISP_PLL_CFG;
+#endif 
+#define power_clk_base CNC1900_ID_SCS
+#define power_clk_write(a,v) (*(volatile unsigned int*)(power_clk_base+((a)&0xfff)) = (v))
+#define power_clk_read(a)    (*(volatile unsigned int*)(power_clk_base+((a)&0xfff)))
+#if 0
+static DISP_PLL_CFG disp_pll_cfg[] = {
+	{_YUV_NTSC                   , 27000000  , 7  , 4  , 15} , 
+	{_YUV_PAL                    , 27000000  , 7  , 4  , 15} , 
+	{_YUV_480P                   , 27000000  , 7  , 4  , 15} , 
+	{_YUV_576P                   , 27000000  , 7  , 4  , 15} , 
+	{_YUV_720P_50Hz              , 74250000  , 0  , 2  , 21} , 
+	{_YUV_720P_60Hz              , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080I_50Hz             , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080I_60Hz             , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080I_50Hz_1250_Total  , 72000000  , 0  , 0  , 0}  , 
+	{_YUV_1080P_24Hz             , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080P_25Hz             , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080P_30Hz             , 74250000  , 0  , 2  , 21} , 
+	{_YUV_1080P_50Hz             , 148500000 , 0  , 2  , 21} , 
+	{_YUV_1080P_60Hz             , 148500000 , 0  , 2  , 21} , 
+	{_RGB_DMT_640x350_85Hz       , 31500000  , 12 , 9  , 20} , 
+	{_RGB_DMT_640x400_85Hz       , 31500000  , 12 , 9  , 20} , 
+	{_RGB_DMT_720x400_85Hz       , 35500000  , 0  , 8  , 20} , 
+	{_RGB_DMT_640x480_60Hz       , 25175000  , 15 , 15 , 27} , 
+	{_RGB_DMT_640x480_72Hz       , 31500000  , 12 , 9  , 20} , 
+	{_RGB_DMT_640x480_75Hz       , 31500000  , 12 , 9  , 20} , 
+	{_RGB_DMT_640x480_85Hz       , 36000000  , 0  , 6  , 15} , 
+	{_RGB_DMT_800x600_56Hz       , 36000000  , 0  , 6  , 15} , 
+	{_RGB_DMT_800x600_60Hz       , 40000000  , 0  , 0  , 0}  , 
+	{_RGB_DMT_800x600_72Hz       , 50000000  , 0  , 7  , 25} , 
+	{_RGB_DMT_800x600_75Hz       , 49500000  , 0  , 6  , 21} , 
+	{_RGB_DMT_800x600_85Hz       , 56250000  , 0  , 6  , 24} , 
+	{_RGB_DMT_848x480_60Hz       , 33750000  , 0  , 6  , 14} , 
+	{_RGB_DMT_1024x768_43Hz      , 44900000  , 0  , 6  , 19} , 
+	{_RGB_DMT_1024x768_60Hz      , 65000000  , 0  , 5  , 23} , 
+	{_RGB_DMT_1024x768_70Hz      , 75000000  , 0  , 0  , 0}  , 
+	{_RGB_DMT_1024x768_75Hz      , 78750000  , 0  , 5  , 28} , 
+	{_RGB_DMT_1024x768_85Hz      , 94500000  , 4  , 3  , 20} , 
+	{_RGB_DMT_1152x864_75Hz      , 108000000 , 0  , 2  , 15} , 
+	{_RGB_DMT_1280x768_60Hz_RED  , 68250000  , 0  , 0  , 0}  , 
+	{_RGB_DMT_1280x768_60Hz      , 79500000  , 0  , 0  , 0}  , 
+	{_RGB_DMT_1280x768_75Hz      , 102250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1280x768_85Hz      , 157500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1280x960_60Hz      , 108000000 , 0  , 2  , 15} , 
+	{_RGB_DMT_1280x960_85Hz      , 148500000 , 0  , 2  , 21} , 
+	{_RGB_DMT_1280x1024_60Hz     , 108000000 , 0  , 2  , 15} , 
+	{_RGB_DMT_1280x1024_75Hz     , 135000000 , 0  , 2  , 19} , 
+	{_RGB_DMT_1280x1024_85Hz     , 157500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1360x768_60Hz      , 85500000  , 0  , 3  , 18} , 
+	{_RGB_DMT_1400x1050_60Hz_RED , 101000000 , 0  , 2  , 14} , 
+	{_RGB_DMT_1400x1050_60Hz     , 121750000 , 0  , 2  , 17} , 
+	{_RGB_DMT_1400x1050_75Hz     , 156000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1400x1050_85Hz     , 179500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1440x900_60Hz_RED  , 88750000  , 0  , 0  , 0}  , 
+	{_RGB_DMT_1440x900_60Hz      , 106500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1440x900_75Hz      , 136750000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1440x900_85Hz      , 157000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1600x1200_60Hz     , 162000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1600x1200_65Hz     , 175500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1600x1200_70Hz     , 189000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1600x1200_75Hz     , 202500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1600x1200_85Hz     , 229500000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1680x1050_60Hz_RED , 119000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1680x1050_60Hz     , 146250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1680x1050_75Hz     , 187000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1680x1050_85Hz     , 214750000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1792x1344_60Hz     , 204750000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1792x1344_75Hz     , 261000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1856x1392_60Hz     , 218250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1856x1392_75Hz     , 288000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1200_60Hz_RED , 154000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1200_60Hz     , 193250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1200_75Hz     , 245250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1200_85Hz     , 281250000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1440_60Hz     , 234000000 , 0  , 0  , 0}  , 
+	{_RGB_DMT_1920x1440_75Hz     , 297000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x480_50Hz       , 19750000  , 19 , 13 , 18} , 
+	{_RGB_CVT_640x480_60Hz       , 23875000  , 16 , 13 , 22} , 
+	{_RGB_CVT_640x480_75Hz       , 30625000  , 0  , 11 , 24} , 
+	{_RGB_CVT_640x480_85Hz       , 35625000  , 0  , 11 , 28} , 
+	{_RGB_CVT_800x600_50Hz       , 31125000  , 12 , 10 , 22} , 
+	{_RGB_CVT_800x600_60Hz       , 38125000  , 10 , 6  , 16} , 
+	{_RGB_CVT_800x600_75Hz       , 48875000  , 0  , 8  , 28} , 
+	{_RGB_CVT_800x600_85Hz       , 56500000  , 0  , 5  , 20} , 
+	{_RGB_CVT_1024x768_50Hz      , 51750000  , 0  , 6  , 22} , 
+	{_RGB_CVT_1024x768_60Hz      , 64125000  , 0  , 4  , 18} , 
+	{_RGB_CVT_1024x768_75Hz      , 81750000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1024x768_85Hz      , 94250000  , 4  , 3  , 20} , 
+	{_RGB_CVT_1280x960_50Hz      , 83000000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x960_60Hz      , 102000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x960_75Hz      , 129875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x960_85Hz      , 149375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1400x1050_50Hz     , 99750000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1400x1050_60Hz     , 122500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1400x1050_75Hz     , 155875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1400x1050_85Hz     , 179125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1200_50Hz     , 132375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1200_60Hz     , 160875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1200_75Hz     , 205875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1200_85Hz     , 234625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1800x1350_50Hz     , 168250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1800x1350_60Hz     , 204500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1800x1350_75Hz     , 261250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1800x1350_85Hz     , 299625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1536_50Hz     , 218625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1536_60Hz     , 267000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1536_75Hz     , 340500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1536_85Hz     , 388125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1920_50Hz     , 346000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1920_60Hz     , 421375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1920_75Hz     , 533750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1920_85Hz     , 611125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x1024_50Hz     , 89375000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x1024_60Hz     , 108875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x1024_75Hz     , 138500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x1024_85Hz     , 159375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x360_50Hz       , 14750000  , 26 , 22 , 23} , 
+	{_RGB_CVT_640x360_60Hz       , 17875000  , 21 , 22 , 28} , 
+	{_RGB_CVT_640x360_75Hz       , 22500000  , 17 , 9  , 14} , 
+	{_RGB_CVT_640x360_85Hz       , 25750000  , 0  , 11 , 20} , 
+	{_RGB_CVT_848x480_50Hz       , 26000000  , 0  , 14 , 26} , 
+	{_RGB_CVT_848x480_60Hz       , 31500000  , 12 , 9  , 20} , 
+	{_RGB_CVT_848x480_75Hz       , 40875000  , 0  , 5  , 14} , 
+	{_RGB_CVT_848x480_85Hz       , 47250000  , 8  , 6  , 20} , 
+	{_RGB_CVT_1024x576_50Hz      , 37875000  , 10 , 10 , 27} , 
+	{_RGB_CVT_1024x576_60Hz      , 46875000  , 8  , 6  , 20} , 
+	{_RGB_CVT_1024x576_75Hz      , 60625000  , 0  , 4  , 17} , 
+	{_RGB_CVT_1024x576_85Hz      , 69125000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x720_50Hz      , 60375000  , 0  , 4  , 17} , 
+	{_RGB_CVT_1280x720_60Hz      , 74375000  , 0  , 4  , 21} , 
+	{_RGB_CVT_1280x720_75Hz      , 95625000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x720_85Hz      , 110000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x900_50Hz      , 97000000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x900_60Hz      , 118875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x900_75Hz      , 152125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x900_85Hz      , 174750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1080_50Hz     , 141375000 , 0  , 2  , 20} , 
+	{_RGB_CVT_1920x1080_60Hz     , 172750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1080_75Hz     , 220500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1080_85Hz     , 252875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1152_50Hz     , 162125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1152_60Hz     , 198000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1152_75Hz     , 252500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1152_85Hz     , 289500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1440_50Hz     , 256000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1440_60Hz     , 311750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1440_75Hz     , 396750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1440_85Hz     , 454250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x400_50Hz       , 16375000  , 23 , 14 , 16} , 
+	{_RGB_CVT_640x400_60Hz       , 19875000  , 19 , 19 , 27} , 
+	{_RGB_CVT_640x400_75Hz       , 25000000  , 15 , 14 , 25} , 
+	{_RGB_CVT_640x400_85Hz       , 29125000  , 13 , 13 , 27} , 
+	{_RGB_CVT_768x480_50Hz       , 23625000  , 16 , 12 , 20} , 
+	{_RGB_CVT_768x480_60Hz       , 28625000  , 13 , 8  , 16} , 
+	{_RGB_CVT_768x480_75Hz       , 37250000  , 0  , 8  , 21} , 
+	{_RGB_CVT_768x480_85Hz       , 42500000  , 0  , 7  , 21} , 
+	{_RGB_CVT_1024x640_50Hz      , 42625000  , 0  , 6  , 18} , 
+	{_RGB_CVT_1024x640_60Hz      , 52750000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1024x640_75Hz      , 67375000  , 0  , 3  , 14} , 
+	{_RGB_CVT_1024x640_85Hz      , 77625000  , 0  , 4  , 22} , 
+	{_RGB_CVT_1280x800_50Hz      , 68500000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x800_60Hz      , 83375000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x800_75Hz      , 107250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x800_85Hz      , 123375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1000_50Hz     , 108625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1000_60Hz     , 133125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1000_75Hz     , 169125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1000_85Hz     , 194125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1200_50Hz     , 158000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1200_60Hz     , 193125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1200_75Hz     , 246500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1200_85Hz     , 282625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1280_50Hz     , 181125000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1280_60Hz     , 221250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1280_75Hz     , 280500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1280_85Hz     , 321625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1600_50Hz     , 285750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1600_60Hz     , 348000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1600_75Hz     , 442750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1600_85Hz     , 507000000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x480_60Hz_RED   , 22750000  , 0  , 16 , 26} , 
+	{_RGB_CVT_800x600_60Hz_RED   , 34375000  , 11 , 11 , 27} , 
+	{_RGB_CVT_1024x768_60Hz_RED  , 54500000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x960_60Hz_RED  , 83375000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1400x1050_60Hz_RED , 99000000  , 0  , 3  , 21} , 
+	{_RGB_CVT_1600x1200_60Hz_RED , 128000000 , 0  , 2  , 18} , 
+	{_RGB_CVT_1800x1350_60Hz_RED , 160625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1536_60Hz_RED , 206250000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1920_60Hz_RED , 318500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1280x1024_60Hz_RED , 89000000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x360_60Hz_RED   , 17000000  , 22 , 23 , 28} , 
+	{_RGB_CVT_848x480_60Hz_RED   , 28875000  , 13 , 7  , 14} , 
+	{_RGB_CVT_1024x576_60Hz_RED  , 40875000  , 0  , 5  , 14} , 
+	{_RGB_CVT_1280x720_60Hz_RED  , 62500000  , 0  , 5  , 22} , 
+	{_RGB_CVT_1600x900_60Hz_RED  , 96000000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1080_60Hz_RED , 136500000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1152_60Hz_RED , 154625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1440_60Hz_RED , 238750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_640x400_60Hz_RED   , 18875000  , 20 , 15 , 20} , 
+	{_RGB_CVT_768x480_60Hz_RED   , 26500000  , 0  , 15 , 28} , 
+	{_RGB_CVT_1024x640_60Hz_RED  , 45500000  , 0  , 8  , 26} , 
+	{_RGB_CVT_1280x800_60Hz_RED  , 69500000  , 0  , 0  , 0}  , 
+	{_RGB_CVT_1600x1000_60Hz_RED , 106625000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_1920x1200_60Hz_RED , 151750000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2048x1280_60Hz_RED , 171875000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_2560x1600_60Hz_RED , 265375000 , 0  , 0  , 0}  , 
+	{_RGB_CVT_800x480_60Hz,295000000,13,11,23},
+	{_RGB_CVT_1366x768_60Hz,70200000,0,5,25},
+};
+#endif
+void clock_disp_reset(DISP_ID ID,CLOCK_RESET ResetOrSet)
+{
+    int reg_val = 0;
+
+    reg_val = df_clk_read(CLOCK_SOFT_RESET);
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = reg_val & ((_disp1) ? 0xffffdfff : 0xffffefff);
+    } else {
+        reg_val = reg_val | ((_disp1) ? 0x2000 : 0x1000);
+    }
+
+    df_clk_write(CLOCK_SOFT_RESET,reg_val);
+
+    return;
+}
+#if 0
+int clock_dispset_clockmode0(DISP_ID ID,DISP_CLOCK_MODE DispName)
+{
+    int rt = 0;
+
+    if (ID == _disp0) {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_tve_pll);
+    } else {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_sys_pll);
+    }
+
+    return (rt);
+}
+
+int clock_dispset_clockmode1(DISP_ID ID,DISP_CLOCK_MODE DispName)
+{
+    int rt = 0;
+
+    if (ID == _disp0) {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_sys_pll);
+    } else {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_tve_pll);
+    }
+
+    return (rt);
+}
+
+int clock_dispset_clockmode2(DISP_ID ID,DISP_CLOCK_MODE DispName)
+{
+    int rt = 0;
+
+    if (ID == _disp0) {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_tve_pll);
+    } else {
+        rt = clock_dispset_clockmoderaw(ID,DispName,_tve_pll);
+    }
+
+    return (rt);
+}
+#endif
+#if 0
+
+static void clock_dispclock_gating(DISP_ID ID)
+{
+    int reg_val = 0;
+
+    //0.1 Disable output
+    if (ID==_disp0) {
+        reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+        df_clk_write(CLOCK_PLL_CLK_EN, reg_val&0xffffffaf);
+    } else {
+        reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+        df_clk_write(CLOCK_PLL_CLK_EN, reg_val&0xffffffdf);
+    }
+
+#if 0
+    //0.2 Gate Clock
+    if (ID==_disp0) {
+        reg_val = df_clk_read(CLOCK_TVE_SEL);
+        df_clk_write(CLOCK_TVE_SEL, reg_val&0xfffffffc);
+    } else {
+        reg_val = df_clk_read(CLOCK_TVE_SEL);
+        df_clk_write(CLOCK_TVE_SEL, reg_val&0xfffcffff);
+    }
+#endif
+    return;
+}
+
+void clock_disptve_pllmode(POWER_MODE PowerMode)
+{
+    unsigned int reg_val = 0;
+
+    if (PowerMode == _clock_wake) {
+        reg_val = df_clk_read(CLOCK_PLL_SLEEP_N);
+        df_clk_write(CLOCK_PLL_SLEEP_N, reg_val|0x1);
+
+        udelay(100);
+
+        reg_val = df_clk_read(CLOCK_PLL_SLEEP_N);
+        df_clk_write(CLOCK_PLL_SLEEP_N, reg_val|0x2);
+    } else {
+        reg_val = df_clk_read(CLOCK_PLL_SLEEP_N);
+        df_clk_write(CLOCK_PLL_SLEEP_N, reg_val&0xfffffffd);
+
+        udelay(10);
+
+        reg_val = df_clk_read(CLOCK_PLL_SLEEP_N);
+        df_clk_write(CLOCK_PLL_SLEEP_N, reg_val&0xfffffffe);
+    }
+
+    return;
+}
+
+void clock_dispsys_pllmode(POWER_MODE PowerMode)
+{
+    //Not Implemented.
+    return;
+}
+
+int clock_dispset_clockmoderaw(DISP_ID ID,DISP_CLOCK_MODE DispName,DISP_CLOCK_SOURCE ClockSource)
+{
+    int IsValid=0;
+    unsigned int reg_val = 0;
+    unsigned int Disp;
+    unsigned int TveClk0;
+    unsigned int TveClk6;
+    unsigned int HdmiTmds;
+    DISP_PLL_CFG *pdisp_pll_cfg=NULL;
+
+    pdisp_pll_cfg=&disp_pll_cfg[DispName];
+
+    //0.Check Valid or not
+    if (ClockSource==_sys_pll) {
+        IsValid = pdisp_pll_cfg->tve_sys_divider !=0;
+    } else {
+        IsValid=((pdisp_pll_cfg->tve_fb!=0) && (pdisp_pll_cfg->tve_m!=0));
+    }
+
+    //1.Config Clock
+    if (IsValid) {
+        //1.0 Gate Clock of Display source
+        clock_dispclock_gating(ID);
+
+        //1.1 Disable Power Down PLL
+        if (ClockSource==_sys_pll) {
+            clock_dispsys_pllmode(_clock_sleep);
+        } else {
+#if 0
+            //gate off DIVM;
+            reg_val = df_clk_read(CLOCK_PLL_TVE_DIV);
+            df_clk_write(CLOCK_PLL_TVE_DIV, reg_val&0xffff7fff);
+#endif
+            udelay(200);
+
+            clock_disptve_pllmode(_clock_sleep);
+        }
+
+	clock_disp_reset(ID, _do_reset);
+
+        //1.3 Config Mux and PLL Parameters
+        //1.3.1 Config the PLL Parameters
+#if 0
+        if (ClockSource == _sys_pll) {
+            reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+
+            if (ID==_disp0) {
+                reg_val = ((reg_val&0xffffffe0) | pdisp_pll_cfg->tve_sys_divider);
+            } else {
+                reg_val = ((reg_val&0xffffe0ff) | (pdisp_pll_cfg->tve_sys_divider<<8));
+            }
+
+            df_clk_write(CLOCK_CLK_GEN_DIV, reg_val);
+        } else {
+            reg_val = df_clk_read(CLOCK_PLL_TVE_DIV);
+
+            reg_val = (reg_val&0xffff0000)| pdisp_pll_cfg->tve_m;
+            reg_val = reg_val|(pdisp_pll_cfg->tve_fb <<8);
+            reg_val |= 0x8000;
+
+            df_clk_write(CLOCK_PLL_TVE_DIV, reg_val);
+        }
+#else
+	if(ID==_disp0){
+		reg_val = df_clk_read(CLOCK_PLL_TVE_DIV);
+
+		reg_val = (reg_val&0xffff0000)| pdisp_pll_cfg->tve_m;
+		reg_val = reg_val|(pdisp_pll_cfg->tve_fb <<8);
+		reg_val |= 0x8000;
+
+		df_clk_write(CLOCK_PLL_TVE_DIV, reg_val);
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+
+		reg_val = ((reg_val&0xffffe0ff) | (pdisp_pll_cfg->tve_sys_divider<<8));
+
+		df_clk_write(CLOCK_CLK_GEN_DIV, reg_val);
+        }
+#endif
+        //1.3.2 Wait 2us for PLL generating a stable clock
+        udelay(500);
+
+        //1.3.3 PLL Clock Wake
+        if (ClockSource==_sys_pll) {
+            clock_dispsys_pllmode(_clock_wake);
+        } else {
+            clock_disptve_pllmode(_clock_wake);
+        }
+
+        //1.3.4 Config Clock Switcher Level #1
+#if 0
+        reg_val = df_clk_read(CLOCK_TVE_SEL);
+        if (ID==_disp0) {
+            if (ClockSource==_sys_pll) {
+                reg_val = (reg_val & 0xfffffffc)|0x1;
+            } else {
+                reg_val = (reg_val & 0xfffffffc)|0x2;
+            }
+
+        } else {
+            if (ClockSource==_sys_pll) {
+                reg_val = (reg_val & 0xfffcffff)|0x10000;
+            } else {
+                reg_val = (reg_val & 0xfffcffff)|0x20000;
+            }
+        }
+        df_clk_write(CLOCK_TVE_SEL,reg_val);
+#endif
+        //1.3.5 Config Divider
+        reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+        switch (DispName) {
+        case _YUV_NTSC:
+        case _YUV_PAL:
+            Disp  	=4;
+            TveClk0	=2;
+            TveClk6 =4;
+            HdmiTmds=4;
+            break;
+        case _YUV_480P:
+        case _YUV_576P:
+            Disp  	=4;
+            TveClk0	=2;
+            TveClk6 =2;
+            HdmiTmds=4;
+            break;
+        case _YUV_1080I_50Hz:
+        case _YUV_1080I_60Hz:
+        case _YUV_720P_50Hz:
+        case _YUV_720P_60Hz:
+        case _YUV_1080P_24Hz:
+        case _YUV_1080P_25Hz:
+        case _YUV_1080P_30Hz:
+        case _YUV_1080I_50Hz_1250_Total:
+            Disp  	=4;
+            TveClk0	=2;
+            TveClk6 =4;
+            HdmiTmds=4;
+            break;
+        case _YUV_1080P_50Hz:
+        case _YUV_1080P_60Hz:
+            Disp  	=2;
+            TveClk0	=2;
+            TveClk6 =4;
+            HdmiTmds=2;
+            break;
+        default:
+            Disp  	=2;
+            TveClk0	=2;
+            TveClk6 =4;
+            HdmiTmds=2;
+        }
+
+        if (ID==_disp0) {
+            reg_val &= 0xffff0000;
+            reg_val |= (HdmiTmds<<12);
+            reg_val |= (Disp<<8);
+            reg_val |= (TveClk6<<4);
+            reg_val |= TveClk0;
+        } else {
+            reg_val &= 0xf000ffff;
+            reg_val |= (Disp<<24);
+            reg_val |= (TveClk6<<20);
+            reg_val |= (TveClk0<<16);
+        }
+
+        df_clk_write(CLOCK_TVE_DIV_N,reg_val);
+
+	    clock_disp_reset(ID, _do_set);
+
+        //1.3.6 wait 1 us for stable
+        udelay(50);//?
+
+        //1.3.7 Enable
+        reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+
+        if (ID==_disp0) {
+            reg_val |= 0x50;
+        } else {
+            reg_val |= 0x20;
+        }
+
+        df_clk_write(CLOCK_PLL_CLK_EN, reg_val);
+    } 
+	else {
+       	return (-1); 
+    }
+
+    return (0);
+}
+
+
+void clock_dispset_dac0mode(POWER_MODE PowerMode)
+{
+    unsigned int reg_val = 0;
+
+    reg_val = df_clk_read(CLOCK_DAC_POWER_DOWN);
+
+    if (PowerMode==_clock_sleep) {
+        reg_val |= 0x7;
+    } else {
+        reg_val &= 0xfffffff8;
+    }
+
+    df_clk_write(CLOCK_DAC_POWER_DOWN, reg_val);
+
+    return;
+}
+
+void clock_dispset_dac1mode(POWER_MODE PowerMode)
+{
+    unsigned int reg_val = 0;
+
+    reg_val = df_clk_read(CLOCK_DAC_POWER_DOWN);
+
+    if (PowerMode==_clock_sleep) {
+        reg_val |= 0x38;
+    } else {
+        reg_val &= 0xffffffc7;
+    }
+
+    df_clk_write(CLOCK_DAC_POWER_DOWN, reg_val);
+
+    return;
+}
+#endif
+void clock_dac0_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if(ClockEna == _clock_disable){
+		reg_val = power_clk_read(VDAC0_CTRL);
+		power_clk_write(VDAC0_CTRL, reg_val&(~(0x7<<3)));
+	}
+	else{
+		reg_val = power_clk_read(VDAC0_CTRL);
+		power_clk_write(VDAC0_CTRL, reg_val|(0x7<<3)|0xfffffc0);
+
+	}
+	return;
+}
+
+void clock_dac1_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if(ClockEna == _clock_disable){
+		reg_val = power_clk_read(VDAC1_CTRL);
+		power_clk_write(VDAC1_CTRL, reg_val&(~(0x7<<3)));
+	}
+	else{
+		reg_val = power_clk_read(VDAC1_CTRL);
+		power_clk_write(VDAC1_CTRL, reg_val|(0x1<<3)|0xfffffc0);
+	}
+	return;
+}
+
+enum disp0_pll_cfg {
+   target_freq       ,
+   ref_div           ,
+   fbdiv             ,
+   postdiv1          ,
+   postdiv2          ,
+   disp0_div         ,
+   disp0_clk0_div     ,
+   disp0_clk234_div   ,
+   disp0_clk6_div
+};
+//Display
+static const unsigned int disp0_pll_cfg[70][9] =
+{   //target_freq   ref_div  fbdiv  postdiv1  postdiv2  disp0_div  disp0_clk0_div  disp0_clk234_div  disp0_clk6_div
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+                                                                                                                			//
+    {  148351648,     13,    1125,     7,       1,         2,          2,            2,               4 },          // 6,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+                                                                                                                //
+    {   27000000,      1,      63,     7,       2,         4,          2,            2,               2 },          //
+    {   27000000,      1,      63,     7,       2,         4,          2,            2,               2 },          //
+    {   27027000,     20,    1802,     5,       4,         4,          2,            2,               2 },          //
+
+#if 1
+    {   13500000,      1,      63,     7,       2,         8,          2,            2,               4 },          //
+    {   13500000,      1,      63,     7,       2,         8,          2,            2,               4 },          //
+    {   13513500,     20,    1802,     5,       4,         8,          2,            2,               4 },        
+#else
+    {   13500000,      1,      63,     7,       2,         4,          2,            2,               4 },          //
+    {   13500000,      1,      63,     7,       2,         4,          2,            2,               4 },          //
+    {   13513500,     20,    1802,     5,       4,         4,          2,            2,               4 },          // ,
+#endif                                                                                                                //
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   35500000,      1,      71,     6,       1,         8,          0,            0,               0 },          // 00,
+    {   25200000,     1,    84,     5,       2,         8,          0,            0,               0 },
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   36000000,      1,      60,     5,       2,         4,          0,            0,               0 },          //
+    {   36000000,      1,      60,     5,       2,         4,          0,            0,               0 },          //
+    {   40000000,      1,      90,     6,       3,         3,          0,            0,               0 },          //
+    {   50000000,      1,      50,     4,       3,         2,          0,            0,               0 },          //
+    {   49500000,      1,      99,     4,       3,         4,          0,            0,               0 },          //
+    {   56250000,      1,      75,     4,       2,         4,          0,            0,               0 },          //
+    {   73250000,      4,     293,     4,       2,         3,          0,            0,               0 },          //
+                                                                                                                //
+    {   33750000,      1,      90,     4,       2,         8,          0,            0,               0 },          //
+                                                                                                                //
+    {   44900000,      6,     449,     5,       4,         2,          0,            0,               0 },          //
+    {   65000000,      1,      65,     4,       2,         3,          0,            0,               0 },          //
+    {   75000000,      1,      75,     4,       2,         3,          0,            0,               0 },          //
+    {   78750000,      2,     105,     4,       2,         2,          0,            0,               0 },          //
+    {   94500000,      1,      63,     4,       2,         2,          0,            0,               0 },          //
+    {  115500000,      1,      77,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   68250000,      2,      91,     4,       2,         2,          0,            0,               0 },          //
+    {   79500000,      1,      53,     4,       2,         2,          0,            0,               0 },          //
+    {  102250000,      6,     409,     4,       2,         2,          0,            0,               0 },          //
+    {  117500000,      3,     235,     4,       2,         2,          0,            0,               0 },          //
+    {  104250000,      2,     139,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   71000000,      1,      71,     4,       2,         3,          0,            0,               0 },          //
+    {   83500000,      2,     167,     4,       2,         3,          0,            0,               0 },          //
+    {  106500000,      1,      71,     4,       2,         2,          0,            0,               0 },          //
+    {  122500000,      3,     245,     4,       2,         2,          0,            0,               0 },          //
+    {  146250000,      2,     195,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+    {  135000000,      1,      45,     4,       1,         2,          0,            0,               0 },          //
+    {  157500000,      2,     105,     4,       1,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   85500000,      1,      57,     4,       2,         2,          0,            0,               0 },          //
+    {  148250000,      8,     593,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  101000000,      3,     202,     4,       2,         2,          0,            0,               0 },          //
+    {  121750000,      6,     487,     4,       2,         2,          0,            0,               0 },          //
+    {  156000000,      1,      52,     4,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {   88750000,      4,     355,     4,       2,         3,          0,            0,               0 },          //
+    {  106500000,      1,      71,     4,       2,         2,          0,            0,               0 },          //
+    {  136750000,      8,     547,     6,       1,         2,          0,            0,               0 },          //
+    {  157000000,      2,     157,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  162000000,      1,      81,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  119000000,      6,     476,     4,       2,         2,          0,            0,               0 },          //
+    {  146250000,      2,     195,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  154000000,      2,     154,     6,       1,         2,          0,            0,               0 },           //
+
+    {   25175000,     20,    1007,     6,       1,         8,          0,            0,               0 },          //
+};
+
+void clock_disp0_setclock(CLOCK_DISP0_MODE mode_disp0)
+{
+    unsigned int   div_m               = 0;
+    unsigned int   div_fb              = 0;
+    unsigned int   div_fb_29_27;
+    unsigned int   div_fb_25_23;
+    unsigned int   div_fb_19_17;
+    unsigned int   div_fb_16_13;
+    unsigned int   div_fb_9_8;
+    unsigned int   div_fb_7_5;
+    unsigned int   div_fb_3_1;
+    unsigned int   data;
+
+    div_m  = (disp0_pll_cfg[mode_disp0][fbdiv] & 0xE00) >> 9;
+    div_fb_29_27 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x1C0) << 21;
+    div_fb_25_23 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x038) << 20;
+    div_fb_19_17 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x007) << 17;
+    div_fb_16_13 = (disp0_pll_cfg[mode_disp0][ref_div] & 0x00f) << 13;
+    div_fb_9_8   = (disp0_pll_cfg[mode_disp0][ref_div] & 0x030) << 4;
+    div_fb_7_5   = (disp0_pll_cfg[mode_disp0][postdiv1] & 0x007) << 5;
+    div_fb_3_1   = (disp0_pll_cfg[mode_disp0][postdiv2] & 0x007) << 1;
+
+    div_fb       = div_fb_29_27 | div_fb_25_23 | div_fb_19_17 | div_fb_16_13 | div_fb_9_8 | div_fb_7_5 | div_fb_3_1;
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFFFEF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable tve clock, disp clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFFC;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //tve pll & divider reset
+
+    power_clk_write(PLL_TVE_PARA_Q, div_m);
+    power_clk_write(PLL_TVE_PARA_F, div_fb);    //tve pll parameter
+    data = power_clk_read(CLOCK_TVE_DIV_N ) & 0x0FFFF000;
+    power_clk_write(CLOCK_TVE_DIV_N, (data | (disp0_pll_cfg[mode_disp0][disp0_clk234_div] << 28) | (disp0_pll_cfg[mode_disp0][disp0_div] << 8) | (disp0_pll_cfg[mode_disp0][disp0_clk6_div] << 4) | disp0_pll_cfg[mode_disp0][disp0_clk0_div]));    //tve divider
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000001;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000002;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000010;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable tve clock, disp clock
+
+}
+
+enum disp1_pll_postdiv {
+   target_freq_disp1  ,
+   sys_div          ,
+   disp1_div         ,
+   disp1_clk0_div     ,
+   disp1_clk234_div   ,
+   disp1_clk6_div
+};
+
+static const unsigned int disp1_cfg[8][6] =
+{   //target_freq    sys_div  disp1_div  disp1_clk0_div  disp1_clk234_div  disp1_clk6_div
+    {   27000000,       10,        4,          2,            2,               2 },          //  576P
+    {   27000000,       10,        4,          2,            2,               2 },          //   480P
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL
+    {   27000000,       10,        4,          2,            2,               4 },          //    NTSL
+    {   27000000,       10,        4,          2,            2,               4 },          //   SECAM
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL_M
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL_N
+    {   27000000,       10,        4,          2,            2,               4 },          //    PAL_CN
+};
+void clock_disp1_setclock(CLOCK_DISP1_MODE mode_disp1)
+{
+    unsigned int   data;
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFFFDF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable tve clock, disp clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFFD;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //tve divider reset
+
+    data = (power_clk_read(CLK_SRC_SEL ) & 0xFFF0FFFF) | 0x00050000;
+    power_clk_write(CLK_SRC_SEL, data);        //select sys pll as disp1 clock source
+
+    data = power_clk_read(CLOCK_TVE_DIV_N ) & 0xF0000FFF;
+    power_clk_write(CLOCK_TVE_DIV_N, (data | (disp1_cfg[mode_disp1][disp1_div] << 24) | (disp1_cfg[mode_disp1][disp1_clk6_div] << 20) | (disp1_cfg[mode_disp1][disp1_clk234_div] << 16) | (disp1_cfg[mode_disp1][disp1_clk0_div] << 12)));    //tve divider
+
+    data = power_clk_read(CLOCK_CLK_GEN_DIV ) & 0xFFFF03FF;
+    power_clk_write(CLOCK_CLK_GEN_DIV, (data | (disp1_cfg[mode_disp1][sys_div] << 10)) );    //cpu/sys  divider
+
+    udelay(10);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000002;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000020;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable tve clock, disp clock
+
+}
+
+
+void clock_tve0_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<4)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<4));
+	}
+	return;
+}
+
+void clock_df_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<17)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<17));
+	}
+	return;
+}
+
+void clock_ahb2_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<19)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<19));
+	}
+	return;
+}
+
+void clock_video_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<23)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<23));
+	}
+	return;
+}
+
+void clock_cpu_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<30)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<30));
+	}
+	return;
+}
+
+void clock_cpusrc_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<31)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<31));
+	}
+	return;
+}
+
+void clock_vpb_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<28)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<28));
+	}
+	return;
+}
+
+void clock_vpbinput_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<29)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<29));
+	}
+	return;
+}
+#if 0
+void clock_hdmiset_clockmode(DISP_CLOCK_MODE DispMode,TMDS_CLOCK_MODE ClockMode)
+{
+    int iHdmiTmds,iTMDSDivEna;
+    unsigned int reg_val = 0;
+
+    //0.1 Gating HDMI_TMDS_CLK
+    reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+    df_clk_write(CLOCK_TVE_DIV_N, reg_val&(~(0xf<<12)));
+
+    //0.2 Disable
+    reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+    df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<6)));
+
+    //0.2 Config DIV
+    switch (DispMode) {
+    case 	_YUV_NTSC:
+    case	_YUV_PAL:
+    case    _YUV_480P:
+    case    _YUV_576P:
+        switch (ClockMode) {
+        case _1x_disp_clk:
+            iHdmiTmds=4;
+            reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+            df_clk_write(CLOCK_TVE_DIV_N, reg_val|(0x4<<12));
+            break;
+        case _2x_disp_clk:
+            iHdmiTmds =2;
+            reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+            df_clk_write(CLOCK_TVE_DIV_N, reg_val|(0x2<<12));
+            break;
+        case _4x_disp_clk:
+            iHdmiTmds =1;
+            reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+            df_clk_write(CLOCK_TVE_DIV_N, reg_val|(0x1<<12));
+            break;
+        default:
+            ;
+        }
+        break;
+    case	_YUV_720P_50Hz:
+    case	_YUV_720P_60Hz:
+    case	_YUV_1080I_50Hz:
+    case	_YUV_1080I_60Hz:
+    case    _YUV_1080P_24Hz:
+    case 	_YUV_1080P_25Hz:
+    case 	_YUV_1080P_30Hz:
+        iHdmiTmds =4;
+        reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+        df_clk_write(CLOCK_TVE_DIV_N, reg_val&(~(0xf<<12)));
+        df_clk_write(CLOCK_TVE_DIV_N, reg_val|(0x4<<12));
+        break;
+    default:
+        iHdmiTmds =2;
+        reg_val = df_clk_read(CLOCK_TVE_DIV_N);
+        df_clk_write(CLOCK_TVE_DIV_N, reg_val&(~(0xf<<12)));
+        df_clk_write(CLOCK_TVE_DIV_N, reg_val|(0x2<<12));
+
+    }
+
+    //0.3 Wait 1 us for stable
+    udelay(1);
+    //0.4 Enable
+    iTMDSDivEna=1;//CLOCK_REG_FMT(clock->iTMDSDivEna,6,1);
+    reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+    df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<6));
+
+    return ;
+}
+
+void clock_ddcset_clockmode(DDC_CLOCK_MODE ClockMode)
+{
+    unsigned int reg_val=0;
+    int iDDCDiv;
+    //0 Gate Clock
+    iDDCDiv =0;//16/5
+    reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+    df_clk_write(CLOCK_CLK_GEN_DIV, reg_val&(~(0x1f<<16)));
+
+    switch (ClockMode) {
+    case _ddc_clk_high:
+        iDDCDiv =10;    //70K
+        reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+        df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|(0xA<<16));
+        break;
+    case _ddc_clk_middle:   //60K
+        iDDCDiv =12;
+        reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+        df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|(0xC<<16));
+        break;
+    case _ddc_clk_low:     //50K
+        iDDCDiv =14;
+        reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+        df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|(0xE<<16));
+        break;
+    default:
+        ;
+    }
+
+    return;
+}
+
+void clock_cecset_clockmode(Cec_CLOCK_MODE ClockMode)
+{
+	unsigned int reg_val=0;
+
+	reg_val = df_clk_read(CLOCK_CLK_GEN_DIV);
+	reg_val &= (~0xff);
+
+	switch (ClockMode){
+		case _Cec_94P5M:
+		df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|0x3);
+		break;
+		case _Cec_2P1M:
+		df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|0xb3);
+		break;
+		case _Cec_1P48M:
+		df_clk_write(CLOCK_CLK_GEN_DIV, reg_val|0xfe);
+		break;
+	}
+
+	return;
+}
+
+typedef struct _AUDIO_PLL_CFG_ {
+    AUDIO_CLOCK_MODE ClockMode;
+    unsigned int Freq;
+    unsigned int HPD;
+    unsigned int Jitter;
+} AUDIO_PLL_CFG;
+AUDIO_PLL_CFG audio_pll;
+
+static AUDIO_PLL_CFG audio_pll_cfg []= {
+    {_AUDIO_192KHz		,	0x67f	,	1	,	0x5f370+0x90+0xa48	},
+    {_AUDIO_96KHz		,	1920	,	3	,	0x656d0	},
+    {_AUDIO_88_2KHz		,	1764	,	4	,	0x146d0	},
+    {_AUDIO_64KHz		,	1280	,	5	,	0x3d6d0	},
+    {_AUDIO_44_1KHz		,	882		,	8	,	0x146d0	},
+    {_AUDIO_48KHz		,	960		,	7	,	0x296d0	},
+    {_AUDIO_32KHz		,	640		,	11	,	0x156d0	},
+    {_AUDIO_24KHz		,	480		,	15	,	0x0b6d0	},
+    {_AUDIO_22_05KHz 	,	441		,	16	,	0x146d0	},
+    {_AUDIO_16KHz		,	320		,	23	,	0x16d0	},
+    {_AUDIO_12KHz		,	240		,	30	,	0xb6d0	},
+    {_AUDIO_11_025KHz	,	220		,	33	,	0x6a50	},
+    {_AUDIO_8KHz 		,	160		,	46	,	0x16d0	},
+
+};
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE AudioClockMode)
+{
+    int SleepOrNot =0;
+    AUDIO_PLL_CFG *paudio_pll_cfg =NULL;
+    paudio_pll_cfg =&audio_pll_cfg[AudioClockMode];
+    //0.0 Get PLL Parameters
+
+    audio_pll.Freq = df_clk_read(CLOCK_AUD_FREQ);
+    audio_pll.HPD = df_clk_read(CLOCK_AUD_HPD);
+    audio_pll.Jitter = df_clk_read(CLOCK_AUD_JITTER);
+    if ((audio_pll.Freq==paudio_pll_cfg->Freq)&&
+            (audio_pll.HPD==paudio_pll_cfg->HPD)&&
+            (audio_pll.Jitter==paudio_pll_cfg->Jitter)) {
+        SleepOrNot =0;
+    } else {
+        SleepOrNot =1;
+    }
+
+    //0.1 Config PLL if needed
+    if (SleepOrNot) {
+        //1.0 Disable PLL output
+        //clock_audio_clockena(_clock_disable);	// lixun: for audio noise
+
+        //1.1 Config PLL
+        audio_pll.Freq =paudio_pll_cfg->Freq;
+        audio_pll.HPD=paudio_pll_cfg->HPD;
+        audio_pll.Jitter=paudio_pll_cfg->Jitter;
+
+        //1.2 Update The para to PLL
+        df_clk_write(CLOCK_AUD_FREQ, audio_pll.Freq);
+        df_clk_write(CLOCK_AUD_HPD, audio_pll.HPD);
+        df_clk_write(CLOCK_AUD_JITTER, audio_pll.Jitter);
+
+        //1.3 Sleep 200 us for Clock stable
+        udelay(50);
+
+        //1.4 Enable PLL output
+        clock_audio_clockena(_clock_enable);
+
+    }
+    return;
+
+}
+
+void clock_audio_clockena(CLOCK_ENA ClockEna)
+{
+    int iAudioClkEna;
+    unsigned int reg_val=0;
+
+    if (ClockEna == _clock_enable) {
+        iAudioClkEna = 1;//8/1
+        reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+        df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<22));
+    } else {
+        iAudioClkEna = 0;
+        reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+        df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<22)));
+    }
+
+    return;
+}
+
+//Xport
+void clock_xportInput_clocksel(int ClockSel) //0:SYS_CLK27 1:AV_CLK27
+{
+    int iXportClkSel;
+    unsigned int reg_val;
+
+    iXportClkSel = ClockSel & 0x1;
+
+    reg_val = df_clk_read(CLOCK_XPORT_CLK_SEL);
+    df_clk_write(CLOCK_XPORT_CLK_SEL, reg_val=iXportClkSel?1:0);
+    return;
+}
+
+//Video
+void clock_video_setClock(VIDEO_CLOCK_MODE ClockMode)
+{
+    unsigned int reg_val;
+    int iDivVideo;
+
+    //0 Gate Clock
+    iDivVideo =0;//CLOCK_PLL_AVS_DIV 0/4
+    reg_val = df_clk_read(CLOCK_PLL_AVS_DIV);
+    df_clk_write(CLOCK_PLL_AVS_DIV, reg_val&(~0xf));
+
+    switch (ClockMode) {
+    case _VIDEO_189M:
+        iDivVideo	=4;
+        reg_val = df_clk_read(CLOCK_PLL_AVS_DIV);
+        df_clk_write(CLOCK_PLL_AVS_DIV, reg_val|0x4);
+        break;
+    case _VIDEO_151_2M:
+        iDivVideo	=5;
+        reg_val = df_clk_read(CLOCK_PLL_AVS_DIV);
+        df_clk_write(CLOCK_PLL_AVS_DIV, reg_val|0x5);
+        break;
+    case _VIDEO_126M:
+        iDivVideo	=6;
+        reg_val = df_clk_read(CLOCK_PLL_AVS_DIV);
+        df_clk_write(CLOCK_PLL_AVS_DIV, reg_val|0x6);
+        break;
+    case _VIDEO_108M:
+        iDivVideo	=7;
+        reg_val = df_clk_read(CLOCK_PLL_AVS_DIV);
+        df_clk_write(CLOCK_PLL_AVS_DIV, reg_val|0x7);
+        break;
+    default:
+        printf("wrong mode set \n");
+    }
+
+    return;
+}
+
+//USB
+
+void power_usb0phy_down(POWER_MODE PowerMode)
+{
+    int iUSBPhyAnlogBlockPD;
+    unsigned int reg_val;
+
+    if (PowerMode==_clock_sleep) {
+        iUSBPhyAnlogBlockPD |=0x1;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|(0x1<<2));
+    } else {
+        iUSBPhyAnlogBlockPD &=0x2;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val&(~(0x1<<2)));
+    }
+
+    return;
+
+}
+void power_usb1phy_down(POWER_MODE PowerMode)
+{
+    int iUSBPhyAnlogBlockPD;
+    unsigned int reg_val;
+
+    if (PowerMode==_clock_sleep) {
+        iUSBPhyAnlogBlockPD |=0x2;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|(0x2<<2));
+    } else {
+        iUSBPhyAnlogBlockPD &=0x1;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val&(~(0x2<<2)));
+    }
+
+    return;
+
+}
+void power_audio_on(POWER_MODE PowerMode)
+{
+    unsigned int reg_val;
+
+    if (PowerMode==_clock_wake) {
+        reg_val = df_clk_read(CLOCK_AUD_POWER_ON);
+        df_clk_write(CLOCK_AUD_POWER_ON, (reg_val|0x1));
+    } else {
+        reg_val = df_clk_read(CLOCK_AUD_POWER_ON);
+        df_clk_write(CLOCK_AUD_POWER_ON, reg_val&(~(0x1)));
+    }
+
+    return;
+}
+void clock_usb1phy_bypassenable(void)
+{
+    int iUSBPhyBypass;
+    unsigned int reg_val;
+
+    iUSBPhyBypass =3;
+    reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+    df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|0x3);
+
+    return;
+
+}
+void clock_usb1phy_bypassdisable(void)
+{
+    int iUSBPhyBypass;
+    unsigned int reg_val;
+    iUSBPhyBypass =1;
+    reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+    df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|0x1);
+    return;
+
+}
+
+//Reset
+
+void clock_ddr_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+    int reset=0;
+
+    if (ResetOrSet==_do_reset) {
+        reset =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~0x1));
+    } else {
+        reset=1;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|0x1);
+    }
+
+    return;
+
+}
+
+void clock_audio_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+    int iUSBPhyBypass;
+
+    if (ResetOrSet==_do_reset) {
+        iUSBPhyBypass =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<3)));
+    } else {
+        iUSBPhyBypass=1;
+        reg_val = df_clk_read(CLOCK_USB_ULPI_BYPASS);
+        df_clk_write(CLOCK_USB_ULPI_BYPASS, reg_val|(0x1<<3));
+    }
+
+    return;
+
+}
+
+void clock_hdmi_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+    int iHDMIRst;
+
+    if (ResetOrSet==_do_reset) {
+        iHDMIRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<19)));
+    } else {
+        iHDMIRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<19));
+    }
+
+    return;
+}
+
+void clock_coda_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+    int iCodaRst;
+
+    if (ResetOrSet==_do_reset) {
+        iCodaRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<18)));
+    } else {
+        iCodaRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<18));
+    }
+
+    return;
+}
+
+void clock_usbphy_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+    int iUSBPhyRst;
+
+    if (ResetOrSet==_do_reset) {
+        iUSBPhyRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<17)));
+    } else {
+        iUSBPhyRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<17));
+    }
+
+    return;
+
+}
+
+void clock_vib_reset(CLOCK_RESET ResetOrSet)
+{
+    int iVIBRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iVIBRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<16)));
+    } else {
+        iVIBRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<16));
+    }
+
+    return;
+
+
+}
+
+void clock_tve0_reset(CLOCK_RESET ResetOrSet)
+{
+    int iTVE0Rst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iTVE0Rst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<14)));
+    } else {
+        iTVE0Rst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<14));
+    }
+
+    return;
+
+
+}
+
+void clock_tve1_reset(CLOCK_RESET ResetOrSet)
+{
+    int iTVE1Rst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iTVE1Rst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<15)));
+    } else {
+        iTVE1Rst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<15));
+    }
+
+    return;
+
+
+}
+
+void clock_disp0_reset(CLOCK_RESET ResetOrSet)
+{
+    int iDisp0Rst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iDisp0Rst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<12)));
+    } else {
+        iDisp0Rst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<12));
+    }
+
+    return;
+
+}
+
+void clock_disp1_reset(CLOCK_RESET ResetOrSet)
+{
+    int iDisp1Rst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iDisp1Rst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<13)));
+    } else {
+        iDisp1Rst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<13));
+    }
+
+    return;
+
+}
+
+void clock_df_reset(CLOCK_RESET ResetOrSet)
+{
+    int iDFRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iDFRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<11)));
+    } else {
+        iDFRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<11));
+    }
+
+    return;
+
+}
+
+void clock_gfx_reset(CLOCK_RESET ResetOrSet)
+{
+    int iDeintRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iDeintRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<7)));
+    } else {
+        iDeintRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<7));
+    }
+
+    return;
+
+}
+
+void clock_video_reset(CLOCK_RESET ResetOrSet)
+{
+    int iVideoRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iVideoRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<6)));
+    } else {
+        iVideoRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<6));
+    }
+
+    return;
+
+}
+
+void clock_crypto_reset(CLOCK_RESET ResetOrSet)
+{
+    int iSATARst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iSATARst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<5)));
+    } else {
+        iSATARst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<5));
+    }
+
+    return;
+
+}
+
+void clock_usb_reset(CLOCK_RESET ResetOrSet)
+{
+    int iUSBRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iUSBRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<4)));
+    } else {
+        iUSBRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<4));
+    }
+
+    return;
+
+}
+void clock_ether_reset(CLOCK_RESET ResetOrSet)
+{
+    int iEtherRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iEtherRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<2)));
+    } else {
+        iEtherRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<2));
+    }
+
+    return;
+
+}
+void clock_xport_reset(CLOCK_RESET ResetOrSet)
+{
+    int iXportRst;
+    unsigned int reg_val;
+    if (ResetOrSet==_do_reset) {
+        iXportRst =0;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<1)));
+    } else {
+        iXportRst=1;
+        reg_val = df_clk_read(CLOCK_SOFT_RESET);
+        df_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<1));
+    }
+
+    return;
+
+}
+
+void clock_video_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<23));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<23)));
+	}
+
+	return;
+}
+
+void clock_vib_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<28));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<28)));
+	}
+
+	return;
+}
+
+void clock_coda_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<16));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<16)));
+	}
+
+	return;
+}
+
+void clock_gfx_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<18));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<18)));
+	}
+
+	return;
+}
+
+void clock_crypto_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<20));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<20)));
+	}
+
+	return;
+}
+
+void clock_tms_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(1<<6));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<6)));
+	}
+
+	return;
+}
+
+void clock_cec_clockena(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val;
+
+	if (ClockEna == _clock_enable) {
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<26));
+	}
+	else{
+		reg_val = df_clk_read(CLOCK_PLL_CLK_EN);
+		df_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<26)));
+	}
+
+	return;
+}
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/board/cavium/cnc1900/power_clock.h u-boot-2011.06/board/cavium/cnc1900/power_clock.h
--- u-boot-2011.06_original/board/cavium/cnc1900/power_clock.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/board/cavium/cnc1900/power_clock.h	2015-05-18 19:41:06.764203000 +0800
@@ -0,0 +1,428 @@
+#ifndef __POWER_CLOCK_H__
+#define __POWER_CLOCK_H__
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+typedef enum _CLOCK_REG_BANK_
+{
+  CNC1900_ID_SCS                    =0xB2100000,
+
+  CLOCK_ID_BASE                     =(CNC1900_ID_SCS+(0<<2)),
+  CLOCK_PLL_BASE                    =(CNC1900_ID_SCS+(0x40<<2)),
+  CLOCK_MUX_BASE                    =(CNC1900_ID_SCS+(0x50<<2)),
+  CLOCK_RESET_BASE                  =(CNC1900_ID_SCS+(0x80<<2)),
+  PLL_PARA_BASE                     =(CNC1900_ID_SCS+(0xC0<<2)),
+  VDAC_BASE                         =(CNC1900_ID_SCS+(0xD4<<2)),
+  CPU_PWR_BASE                      =(CNC1900_ID_SCS+(0xD8<<2)),
+
+  CLOCK_ID_LO                       =(CLOCK_ID_BASE+(0<<2)),
+  CLOCK_ID_HI                       =(CLOCK_ID_BASE+(1<<2)),
+
+  //B2100100
+  CLOCK_PLL_AVS_DIV                 =(CLOCK_PLL_BASE+(1<<2)),       
+  CLOCK_AUD_DIV                     =(CLOCK_PLL_BASE+(6<<2)),
+  CLOCK_CLK_GEN_DIV                 =(CLOCK_PLL_BASE+(8<<2)),
+
+  //B2100140
+  CLOCK_PLL_CLK_EN                  =(CLOCK_MUX_BASE+(0<<2)),
+  CLK_SRC_SEL                       =(CLOCK_MUX_BASE+(1<<2)),
+  CLOCK_TVE_DIV_N		            =(CLOCK_MUX_BASE+(2<<2)),
+
+  //B2100200
+  CLOCK_SOFT_RESET                  =(CLOCK_RESET_BASE+(0<<2)),
+  CLOCK_CLK_RESET                   =(CLOCK_RESET_BASE+(1<<2)),
+  CLOCK_PLL_SLEEP_N                 =(CLOCK_RESET_BASE+(3<<2)),
+  CLOCK_HDMI_CLK_SEL                =(CLOCK_RESET_BASE+(6<<2)),
+  SB_CTRL                           =(CLOCK_RESET_BASE+(7<<2)),
+  SB_STATUS                         =(CLOCK_RESET_BASE+(8<<2)),
+
+  //B2100300
+  CPUCLK_ST_INT                     =(PLL_PARA_BASE+ (5<<2)),
+  PLL_CPU_DIV                       =(PLL_PARA_BASE+ (6<<2)),
+  PLL_TVE_PARA_Q                    =(PLL_PARA_BASE+ (7<<2)),
+  PLL_TVE_PARA_F                    =(PLL_PARA_BASE+ (8<<2)),
+  PLL_AUD_PARA_Q                    =(PLL_PARA_BASE+ (9<<2)),
+  PLL_AUD_PARA_F                    =(PLL_PARA_BASE+ (0x0A<<2)),
+  PLL_SYS_PARA_Q                    =(PLL_PARA_BASE+ (0x0B<<2)),
+  PLL_SYS_PARA_F                    =(PLL_PARA_BASE+ (0x0C<<2)),
+  PLL_DDR_PARA_Q                    =(PLL_PARA_BASE+ (0x0D<<2)),
+  PLL_DDR_PARA_F                    =(PLL_PARA_BASE+ (0x0E<<2)),
+  PLL_NEWDIV                        =(PLL_PARA_BASE+ (0x0F<<2)),
+  PLL_CODA_PARA_Q                   =(PLL_PARA_BASE+ (0x11<<2)),
+  PLL_CODA_PARA_F                   =(PLL_PARA_BASE+ (0x12<<2)),
+  CPU_PWR_MODE                   	=(PLL_PARA_BASE+ (0x20<<2)),
+  PLL_CLK_EN                   		=(PLL_PARA_BASE+ (0x50<<2)),
+
+  //B2100350
+  VDAC0_CTRL                        =(VDAC_BASE    + (0<<2)),
+  VDAC1_CTRL                        =(VDAC_BASE    + (1<<2)),
+  VDAC_CABLE_DET                    =(VDAC_BASE    + (2<<2)),
+
+  //B2100360
+  CPU_POWER_STATUS                  =(CPU_PWR_BASE + (0<<2)),
+  CPU_POWER_CTRL                    =(CPU_PWR_BASE + (1<<2)),
+  CPU_RST_CTRL                      =(CPU_PWR_BASE + (2<<2)),
+  CPU_SCU_EV_ABORT                  =(CPU_PWR_BASE + (3<<2)),
+  CPU_SCU_CHRC_CNT                  =(CPU_PWR_BASE + (4<<2)),
+  CPU_POWER_MODE                    =(CPU_PWR_BASE + (8<<2)),
+  USB_CTRL                          =(CPU_PWR_BASE + (0x0C<<2)),
+  STC_CTRL                          =(CPU_PWR_BASE + (0x10<<2)),
+
+  CLOCK_REG_SIZE = 0x1000,
+}CLOCK_REG_BANK;
+
+typedef enum _POWER_MODE_
+{
+	_clock_sleep =0,
+	_clock_wake  =1,
+}POWER_MODE;
+
+typedef enum _CLOCK_RESET_
+{
+  _do_reset =0,
+  _do_set   =1,
+}CLOCK_RESET;
+
+typedef enum _CLOCK_ENA_
+{
+        _clock_enable =1,
+        _clock_disable =0,
+}CLOCK_ENA;
+
+//Display
+typedef enum _DISP_ID_
+{
+  _disp0 =0,
+  _disp1 =1,
+}DISP_ID;
+
+typedef enum _disp_clock_source_
+{
+  _sys_pll =0,
+  _tve_pll =1,
+}DISP_CLOCK_SOURCE;
+
+typedef enum _CLOCK_DISP0_MODE_e_ {                
+    _YUV_1080P_60Hz             ,          
+    _YUV_1080P_50Hz             ,          
+    _YUV_1080P_30Hz             ,          
+    _YUV_1080P_25Hz             ,          
+    _YUV_1080P_24Hz             ,          
+    _YUV_1080I_60Hz             ,          
+    _YUV_1080I_50Hz             ,          
+    _YUV_720P_60Hz              ,          
+    _YUV_720P_50Hz              ,          
+
+    _YUV_1080P_59p94Hz          ,          
+    _YUV_1080P_29p97Hz          ,          
+    _YUV_1080P_23p98Hz          ,          
+    _YUV_1080I_59p94Hz          ,          
+    _YUV_720P_59p94Hz           ,          
+
+    _YUV_576P_50Hz              ,          
+    _YUV_480P_59p94Hz              ,          
+    _YUV_480P_60Hz           ,          
+    _YUV_PAL                    ,          
+    _YUV_NTSC                   ,          
+    _YUV_480I_60Hz           ,          
+
+    _RGB_DMT_640x350_85Hz       ,          
+    _RGB_DMT_640x400_85Hz       ,          
+    _RGB_DMT_720x400_85Hz       ,          
+    _RGB_DMT_640x480_60Hz       ,          
+    _RGB_DMT_640x480_72Hz       ,          
+    _RGB_DMT_640x480_75Hz       ,          
+    _RGB_DMT_640x480_85Hz       ,          
+    _RGB_DMT_800x600_56Hz       ,          
+    _RGB_DMT_800x600_60Hz       ,          
+    _RGB_DMT_800x600_72Hz       ,          
+    _RGB_DMT_800x600_75Hz       ,          
+    _RGB_DMT_800x600_85Hz       ,          
+    _RGB_DMT_800x600_120Hz_RED  ,          
+
+    _RGB_DMT_848x480_60Hz       ,          
+
+    _RGB_DMT_1024x768_43Hz      ,          
+    _RGB_DMT_1024x768_60Hz      ,          
+    _RGB_DMT_1024x768_70Hz      ,          
+    _RGB_DMT_1024x768_75Hz      ,          
+    _RGB_DMT_1024x768_85Hz      ,          
+    _RGB_DMT_1024x768_120Hz_RED ,          
+
+    _RGB_DMT_1152x864_75Hz      ,          
+
+    _RGB_DMT_1280x768_60Hz_RED  ,          
+    _RGB_DMT_1280x768_60Hz      ,          
+    _RGB_DMT_1280x768_75Hz      ,          
+    _RGB_DMT_1280x768_85Hz      ,          
+    _RGB_DMT_1280x768_120Hz_RED ,          
+
+    _RGB_DMT_1280x800_60Hz_RED  ,          
+    _RGB_DMT_1280x800_60Hz      ,          
+    _RGB_DMT_1280x800_75Hz      ,          
+    _RGB_DMT_1280x800_85Hz      ,          
+    _RGB_DMT_1280x800_120Hz_RED ,          
+
+    _RGB_DMT_1280x960_60Hz      ,          
+    _RGB_DMT_1280x960_85Hz      ,          
+
+    _RGB_DMT_1280x1024_60Hz     ,          
+    _RGB_DMT_1280x1024_75Hz     ,          
+    _RGB_DMT_1280x1024_85Hz     ,          
+
+    _RGB_DMT_1360x768_60Hz      ,          
+    _RGB_DMT_1360x768_120Hz_RED ,          
+
+    _RGB_DMT_1400x1050_60Hz_RED ,          
+    _RGB_DMT_1400x1050_60Hz     ,          
+    _RGB_DMT_1400x1050_75Hz     ,          
+
+    _RGB_DMT_1440x900_60Hz_RED  ,          
+    _RGB_DMT_1440x900_60Hz      ,          
+    _RGB_DMT_1440x900_75Hz      ,          
+    _RGB_DMT_1440x900_85Hz      ,          
+
+    _RGB_DMT_1600x1200_60Hz     ,          
+
+    _RGB_DMT_1680x1050_60Hz_RED ,          
+    _RGB_DMT_1680x1050_60Hz     ,          
+
+    _RGB_DMT_1920x1200_60Hz_RED,
+    _RGB_DMT_640x480_59P94Hz,
+}CLOCK_DISP0_MODE;
+
+typedef enum _CLOCK_DISP1_MODE_e_
+{
+    _YUV_576P_50Hz_disp1,
+    _YUV_480P_60Hz_disp1,
+    _YUV_PAL_disp1,
+    _YUV_NTSC_disp1,
+    _YUV_SECAM_disp1,
+    _YUV_PAL_M_disp1,
+    _YUV_PAL_N_disp1,
+    _YUV_PAL_CN_disp1,
+}CLOCK_DISP1_MODE;
+//double ClockDispFreq(DISP_CLOCK_MODE DispName);
+#if 0
+void clock_disp_reset(DISP_ID ID,CLOCK_RESET ResetOrSet);
+int clock_dispset_clockmode0(DISP_ID ID,DISP_CLOCK_MODE DispName); //OutIF 0 :HD+VGA+SD  OutIF1:SD
+int clock_dispset_clockmode1(DISP_ID ID,DISP_CLOCK_MODE DispName); //OutIF 0:VGA+SD         OutIF1:HD + SD
+int clock_dispset_clockmode2(DISP_ID ID,DISP_CLOCK_MODE DispName); //OutIF 0:HD               OutIF1:HD
+int clock_dispset_clockmoderaw(DISP_ID ID,DISP_CLOCK_MODE DispName,DISP_CLOCK_SOURCE ClockSource);
+void clock_dispset_dac0mode(POWER_MODE PowerMode);
+void clock_dispset_dac1mode(POWER_MODE PowerMode); //DAC 0 Is the CVBS DAC DAC1 is the YPbPr and VGA DAC
+void clock_disptve_pllmode(POWER_MODE PowerMode);
+void clock_dispsys_pllmode(POWER_MODE PowerMode);
+void clock_hdmiset_clockmode(DISP_CLOCK_MODE DispMode,TMDS_CLOCK_MODE ClockMode);
+
+#endif
+void clock_dac1_enaclock(CLOCK_ENA ClockEna);
+void clock_dac0_enaclock(CLOCK_ENA ClockEna);
+void clock_disp0_setclock(CLOCK_DISP0_MODE mode_disp0);
+void clock_disp1_setclock(CLOCK_DISP1_MODE mode_disp1);
+void clock_df_enaclock(CLOCK_ENA ClockEna);
+void clock_tve0_enaclock(CLOCK_ENA ClockEna);
+void clock_ahb2_enaclock(CLOCK_ENA ClockEna);
+void clock_video_enaclock(CLOCK_ENA ClockEna);
+void clock_cpu_enaclock(CLOCK_ENA ClockEna);
+void clock_cpusrc_enaclock(CLOCK_ENA ClockEna);
+void clock_vpb_enaclock(CLOCK_ENA ClockEna);
+void clock_vpbinput_enaclock(CLOCK_ENA ClockEna);
+//----------------------------------------------------------------
+//Note: The Display Can support five modes,These modes depends on three
+//         different clock source select modes.
+//Note: In 1800l, only mode0 are supported: OutIF0 :HD+VGA+SD  OutIF1:SD
+//----------------------------------------------------------------
+//Disp #0     Disp#1               Disp0 Source          Disp1Source
+//----------------------------------------------------------------
+//HD            SD                     TVE_PLL                 SYS_PLL     ------Mode 0
+//HD            HD                     TVE_PLL                 TVE_PLL     ------Mode 2
+//VGA          SD                     TVE_PLL                 SYS_PLL     ------Mode 0
+//VGA          HD                     SYS_PLL                 TVE_PLL     ------Mode 1
+//SD            HD                     SYS_PLL                 TVE_PLL     ------Mode 1
+//----------------------------------------------------------------
+#if 0
+typedef enum _TMDS_CLOCK_MODE_
+{
+	_1x_disp_clk =0,
+	_2x_disp_clk =1,
+	_4x_disp_clk =3,
+}TMDS_CLOCK_MODE;
+
+typedef enum _DDC_CLOCK_MODE_
+{
+	_ddc_clk_high 		=0,
+	_ddc_clk_middle		=1,
+	_ddc_clk_low		=2,
+}DDC_CLOCK_MODE;
+
+void clock_ddcset_clockmode(DDC_CLOCK_MODE ClockMode);
+//!!!!!!!This function must be employed after set DF clock
+
+//Audio
+typedef enum _AUDIO_CLOCK_MODE_
+{
+	_AUDIO_192KHz           =0,
+	_AUDIO_96KHz 		=1,
+	_AUDIO_88_2KHz		=2,
+	_AUDIO_64KHz		=3,
+	_AUDIO_44_1KHz		=4,
+	_AUDIO_48KHz		=5,
+	_AUDIO_32KHz		=6,
+	_AUDIO_24KHz		=7,
+	_AUDIO_22_05KHz		=8,
+	_AUDIO_16KHz		=9,
+	_AUDIO_12KHz		=10,
+	_AUDIO_11_025KHz	=11,
+	_AUDIO_8KHz	        =12,
+}AUDIO_CLOCK_MODE;
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE AudioClockMode);
+//int ClockAudioPLLMode(POWER_MODE PowerMode);
+//int ClockSPDIFSetClock(AUDIO_CLOCK_MODE ClockMode);
+
+//USB
+int ClockUSB0PhyPowerDown(POWER_MODE PowerMode);
+int ClockUSB1PhyPowerDown(POWER_MODE PowerMode);
+int ClockUSB1PhyBypassEnable(void);
+int ClockUSB1PhyBypassDisable(void);
+
+//Xport
+int ClockXportInputClockSel(int ClockSel); //0:SYS_CLK27 1:AV_CLK27
+
+//Video
+typedef enum _VIDEO_CLOCK_MODE_
+{
+	_VIDEO_189M			=0, //756/4
+	_VIDEO_151_2M		        =1, //756/5
+	_VIDEO_126M			=2, //756/6
+	_VIDEO_108M			=3, //756/7
+}VIDEO_CLOCK_MODE;
+int ClockCodaSetClock(VIDEO_CLOCK_MODE ClockMode);
+
+
+typedef enum _Cec_CLOCK_MODE_
+{
+        _Cec_94P5M                     =0, //378/4 (para should be set to N-1, 3)
+        _Cec_2P1M                      =1, //378/180(para should be set to N-1, 179)
+        _Cec_1P48M                     =2, //378/255(para should be set to N-1, 254)
+}Cec_CLOCK_MODE;
+void clock_cecset_clockmode(Cec_CLOCK_MODE ClockMode);
+
+typedef enum _AV_CLOCK_MODE_
+{
+        _AV_189M                     =0, //756/4
+        _AV_126M                     =1, //756/6
+        _AV_50P4M                    =2, //756/15
+}AV_CLOCK_MODE;
+int ClockAVSetClock(AV_CLOCK_MODE ClockMode);
+
+typedef enum _AHB_CLOCK_MODE_             //ClockGEN for AHB(AHB1 & CRYPTO/AHB2/APB Clock)
+{
+        _AHB_189M                     =0, //756/4
+        _AHB_126M                     =1, //756/6
+        _AHB_108M                     =2, //756/7
+}AHB_CLOCK_MODE;
+int ClockAHBSetClock(AHB_CLOCK_MODE ClockMode);
+
+/*
+typedef enum _AHB2_CLOCK_MODE_             
+{
+        _AHB2_189M                    =0, //756/4
+        _AHB2_126M                    =1, //756/6
+        _AHB2_108M                    =2, //756/7
+        _AHB2_94P5M                   =3, //756/8
+}AHB2_CLOCK_MODE;
+int ClockAHB2SetClock(AHB2_CLOCK_MODE ClockMode);
+
+typedef enum _APB_CLOCK_MODE_            
+{
+        _APB_94P5M                     =0, //756/8
+        _APB_47P25M                    =1, //756/16
+        _APB_24P38M                     =2, //756/31
+}APB_CLOCK_MODE;
+int ClockAPBSetClock(APB_CLOCK_MODE ClockMode);
+*/
+
+typedef enum _GFX_CLOCK_MODE_
+{
+        _GFX_189M                     =0, //756/4
+        _GFX_126M                     =1, //756/6
+        _GFX_50P4M                    =2, //756/15
+}GFX_CLOCK_MODE;
+int ClockGFXSetClock(GFX_CLOCK_MODE ClockMode);
+
+typedef enum _DF_CLOCK_MODE_
+{
+        _DF_189M                     =0, //756/4
+        _DF_126M                     =1, //756/6
+        _DF_50P4M                    =2, //756/15
+}DF_CLOCK_MODE;
+int ClockDFSetClock(DF_CLOCK_MODE ClockMode);
+
+typedef enum _SD_CLOCK_MODE_             
+{
+        _SD_108M                       =0, //756/7
+        _SD_94P5M                      =1, //756/8
+        _SD_47P25M                     =2, //756/16
+        _SD_24P38M                     =3, //756/31
+}SD_CLOCK_MODE;
+int ClockSDSetClock(SD_CLOCK_MODE ClockMode);
+
+//Reset
+int ClockDramportAReset(CLOCK_RESET ResetOrSet);
+void clock_hdmi_reset(CLOCK_RESET ResetOrSet);
+void clock_coda_reset(CLOCK_RESET ResetOrSet);
+int ClockUSBPhyReset(CLOCK_RESET ResetOrSet);
+void clock_vib_reset(CLOCK_RESET ResetOrSet);
+int ClockTVE0Reset(CLOCK_RESET ResetOrSet);
+int ClockTVE1Reset(CLOCK_RESET ResetOrSet);
+int ClockDisp0Reset(CLOCK_RESET ResetOrSet);
+void clock_disp1_reset(CLOCK_RESET ResetOrSet);
+void clock_df_reset(CLOCK_RESET ResetOrSet);
+void  clock_gfx_reset(CLOCK_RESET ResetOrSet);
+void clock_video_reset(CLOCK_RESET ResetOrSet);
+int ClockAudioReset(CLOCK_RESET ResetOrSet);
+int ClockUSBReset(CLOCK_RESET ResetOrSet);
+int ClockEtherReset(CLOCK_RESET ResetOrSet);
+int ClockXportReset(CLOCK_RESET ResetOrSet);
+int ClockDDRReset(CLOCK_RESET ResetOrSet);
+void clock_crypto_reset(CLOCK_RESET ResetOrSet);
+
+//Clock Enable/disable
+void clock_ddc_clockena(CLOCK_ENA ClockEna);
+void clock_cec_clockena(CLOCK_ENA ClockEna);
+int ClockDramportAClockEna(CLOCK_ENA ClockEna);
+void clock_video_clockena(CLOCK_ENA ClockEna);
+int ClockXportClockEna(CLOCK_ENA ClockEna);
+void clock_vib_clockena(CLOCK_ENA ClockEna);
+int ClockCryptoClockEna(CLOCK_ENA ClockEna);
+int ClockGfxClockEna(CLOCK_ENA ClockEna);
+int ClockDFClockEna(CLOCK_ENA ClockEna);
+void clock_coda_clockena(CLOCK_ENA ClockEna);
+int ClockAudpllClockEna(CLOCK_ENA ClockEna);
+void clock_tms_clockena(CLOCK_ENA ClockEna);
+int ClockTve0ClockEna(CLOCK_ENA ClockEna);
+int ClockTve1ClockEna(CLOCK_ENA ClockEna);
+int ClockDramcpuClockEna(CLOCK_ENA ClockEna);
+int ClockDDRClockEna(CLOCK_ENA ClockEna);
+int ClockAhb1ClockEna(CLOCK_ENA ClockEna);
+int ClockAhbClockEna(CLOCK_ENA ClockEna);        //Ahb2/APB clock Ena
+int ClockAudDACIFClockEna(CLOCK_ENA ClockEna);   //SigmaDAC clock Ena
+int ClockSDClockEna(CLOCK_ENA ClockEna);      
+void clock_audio_clockena(CLOCK_ENA ClockEna);
+void clock_gfx_clockena(CLOCK_ENA ClockEna);
+void clock_crypto_clockena(CLOCK_ENA ClockEna);
+void clock_vib_clockena(CLOCK_ENA ClockEna);
+void clock_video_clockena(CLOCK_ENA ClockEna);
+void clock_coda_clockena(CLOCK_ENA ClockEna);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/boards.cfg u-boot-2011.06/boards.cfg
--- u-boot-2011.06_original/boards.cfg	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/boards.cfg	2015-03-16 11:19:40.877878000 +0800
@@ -120,9 +120,9 @@
 mgcoge3un                    arm         arm926ejs   km_arm              keymile        kirkwood
 guruplug                     arm         arm926ejs   -                   Marvell        kirkwood
 mv88f6281gtw_ge              arm         arm926ejs   -                   Marvell        kirkwood
-openrd_base                  arm         arm926ejs   openrd              Marvell        kirkwood        openrd:BOARD_IS_OPENRD_BASE
-openrd_client                arm         arm926ejs   openrd              Marvell        kirkwood        openrd:BOARD_IS_OPENRD_CLIENT
-openrd_ultimate              arm         arm926ejs   openrd              Marvell        kirkwood        openrd:BOARD_IS_OPENRD_ULTIMATE
+openrd_base                  arm         arm926ejs   openrd              Marvell        kirkwood    openrd:BOARD_IS_OPENRD_BASE
+openrd_client                arm         arm926ejs   openrd              Marvell        kirkwood    openrd:BOARD_IS_OPENRD_CLIENT
+openrd_ultimate              arm         arm926ejs   openrd              Marvell        kirkwood    openrd:BOARD_IS_OPENRD_ULTIMATE
 rd6281a                      arm         arm926ejs   -                   Marvell        kirkwood
 sheevaplug                   arm         arm926ejs   -                   Marvell        kirkwood
 dockstar                     arm         arm926ejs   -                   Seagate        kirkwood
@@ -130,17 +130,30 @@
 imx27lite                    arm         arm926ejs   imx27lite           logicpd        mx27
 magnesium                    arm         arm926ejs   imx27lite           logicpd        mx27
 nhk8815                      arm         arm926ejs   nhk8815             st             nomadik
-nhk8815_onenand              arm         arm926ejs   nhk8815             st             nomadik       nhk8815:BOOT_ONENAND
+orion                        arm         arm926ejs   orion               celestial      csm1800h 
+nhk8815_onenand              arm         arm926ejs   nhk8815             st             nomadik     nhk8815:BOOT_ONENAND
 omap5912osk                  arm         arm926ejs   -                   ti             omap
 edminiv2                     arm         arm926ejs   -                   LaCie          orion5x
-dkb			     arm         arm926ejs   -                   Marvell        pantheon
+dkb			                 arm         arm926ejs   -                   Marvell        pantheon
+
+83XX_SONY                    arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNW83XX_SONY
+83XX_SONY_VEDETT                   arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNW83XX_SONY_VEDETT
+1900_EVB                     arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_EVB
+1900_HDK                     arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_HDK
+83XX_OTT_EMMC                arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNW83XX_OTT_EMMC
+83XX_VMS_MINI                arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNW83XX_VMS_MINI
+83XX_ZINWELL                 arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_ZINWELL
+1900_FJ_RX                   arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_FJ_RX
+1900_FJ_TX                   arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_FJ_RX
+1900_FPGA                    arm         armv7       cnc1900             cavium         cnc1900     cnc1900:TARGET_NAME=CNC1900_FPGA
+
 ca9x4_ct_vxp                 arm         armv7       vexpress            armltd
-efikamx                      arm         armv7       efikamx             -              mx5		mx51evk:IMX_CONFIG=board/efikamx/imximage.cfg
-mx51evk                      arm         armv7       mx51evk             freescale      mx5		mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
-mx53evk                      arm         armv7       mx53evk             freescale      mx5		mx53evk:IMX_CONFIG=board/freescale/mx53evk/imximage.cfg
-mx53loco                     arm         armv7       mx53loco            freescale      mx5		mx53loco:IMX_CONFIG=board/freescale/mx53loco/imximage.cfg
-mx53smd                      arm         armv7       mx53smd             freescale      mx5		mx53smd:IMX_CONFIG=board/freescale/mx53smd/imximage.cfg
-vision2                      arm         armv7       vision2             ttcontrol      mx5		vision2:IMX_CONFIG=board/ttcontrol/vision2/imximage_hynix.cfg
+efikamx                      arm         armv7       efikamx             -              mx5         mx51evk:IMX_CONFIG=board/efikamx/imximage.cfg
+mx51evk                      arm         armv7       mx51evk             freescale      mx5         mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
+mx53evk                      arm         armv7       mx53evk             freescale      mx5         mx53evk:IMX_CONFIG=board/freescale/mx53evk/imximage.cfg
+mx53loco                     arm         armv7       mx53loco            freescale      mx5         mx53loco:IMX_CONFIG=board/freescale/mx53loco/imximage.cfg
+mx53smd                      arm         armv7       mx53smd             freescale      mx5         mx53smd:IMX_CONFIG=board/freescale/mx53smd/imximage.cfg
+vision2                      arm         armv7       vision2             ttcontrol      mx5         vision2:IMX_CONFIG=board/ttcontrol/vision2/imximage_hynix.cfg
 cm_t35                       arm         armv7       cm_t35              -              omap3
 omap3_overo                  arm         armv7       overo               -              omap3
 omap3_pandora                arm         armv7       pandora             -              omap3
diff '--exclude=.svn' -Naur u-boot-2011.06_original/build.sh u-boot-2011.06/build.sh
--- u-boot-2011.06_original/build.sh	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/build.sh	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,19 @@
+rm -f u-boot.bin
+CNC_PLATFORM_NAME=${CNC_PLATFORM##*/}
+make ${CNC_PLATFORM_NAME} CNC_PLATFORM_NAME=${CNC_PLATFORM_NAME} CUSTOMER_NAME=${CUSTOMER_NAME}
+#make CNC_PLATFORM_NAME=${CNC_PLATFORM_NAME} CUSTOMER_NAME=${CUSTOMER_NAME} clean
+#make CNC_PLATFORM_NAME=${CNC_PLATFORM_NAME} CUSTOMER_NAME=${CUSTOMER_NAME}
+
+#if 
+#test -f u-boot.bin
+#then
+#	cp u-boot.bin ../../miniloader/uboot_signing
+#	pushd ./
+#	cd ../../miniloader/uboot_signing
+#	./sample_uboot_only_signing.sh
+#	popd
+#	cp ../../miniloader/uboot_signing/signed_u-boot.bin .
+#else
+#	echo ""
+#	echo "ERROR: U-Boot build is failed"
+#fi
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_andrboot.c u-boot-2011.06/common/cmd_andrboot.c
--- u-boot-2011.06_original/common/cmd_andrboot.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_andrboot.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+
+/*
+ * Android command support
+ */
+#include <asm/byteorder.h>
+#include <common.h>
+#include <command.h>
+
+#define BOOT_MAGIC "ANDROID!"
+#define BOOT_MAGIC_SIZE 8
+#define BOOT_NAME_SIZE 16
+#define BOOT_ARGS_SIZE 512
+
+struct boot_img_hdr
+{
+	unsigned char magic[BOOT_MAGIC_SIZE];
+
+	unsigned kernel_size;  /* size in bytes */
+	unsigned kernel_addr;  /* physical load addr */
+
+	unsigned ramdisk_size; /* size in bytes */
+	unsigned ramdisk_addr; /* physical load addr */
+
+	unsigned second_size;  /* size in bytes */
+	unsigned second_addr;  /* physical load addr */
+
+	unsigned tags_addr;	/* physical addr for kernel tags */
+	unsigned page_size;	/* flash page size we assume */
+	unsigned unused[2];	/* future expansion: should be 0 */
+
+	unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
+	
+	unsigned char cmdline[BOOT_ARGS_SIZE];
+
+	unsigned id[8]; /* timestamp / checksum / sha1 / etc */
+};
+
+/*
+** +-----------------+ 
+** | boot header	 | 1 page
+** +-----------------+
+** | kernel		  | n pages  
+** +-----------------+
+** | ramdisk		 | m pages  
+** +-----------------+
+** | second stage	| o pages
+** +-----------------+
+**
+** n = (kernel_size + page_size - 1) / page_size
+** m = (ramdisk_size + page_size - 1) / page_size
+** o = (second_size + page_size - 1) / page_size
+**
+** 0. all entities are page_size aligned in flash
+** 1. kernel and ramdisk are required (size != 0)
+** 2. second is optional (second_size == 0 -> no second)
+** 3. load each element (kernel, ramdisk, second) at
+**	the specified physical address (kernel_addr, etc)
+** 4. prepare tags at tag_addr.  kernel_args[] is
+**	appended to the kernel commandline in the tags.
+** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
+** 6. if second_size != 0: jump to second_addr
+**	else: jump to kernel_addr
+*/
+
+ulong ramdisk_start, ramdisk_end; 
+
+int do_andr_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct boot_img_hdr *hdr;
+	ulong offset;
+	int length, pagesize = 2048;
+//	int ret = -1;
+	char str[32];
+
+	offset = simple_strtoul(argv[1], NULL, 16);
+	length = pagesize;
+
+	hdr = (struct boot_img_hdr *)offset;
+
+	printf("kernel  @ %x (%d bytes)\n", hdr->kernel_addr, hdr->kernel_size);
+	printf("ramdisk @ %x (%d bytes)\n\n\n", hdr->ramdisk_addr, hdr->ramdisk_size);
+
+	if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
+		printf("INVALID BOOT IMAGE HEADER\n");
+		return -1;
+	}
+
+	offset += length;
+	length = (hdr->kernel_size + (pagesize - 1)) & (~(pagesize - 1));
+
+	memcpy( (void*) ( hdr->kernel_addr - 0x40) , (void*) offset, length);
+
+	offset += length;
+	length = (hdr->ramdisk_size + (pagesize - 1)) & (~(pagesize - 1));
+
+	if (offset != hdr->ramdisk_addr)
+		memcpy( (void*) hdr->ramdisk_addr, (void*) offset, length);
+
+	if (hdr->cmdline[0]) 
+		setenv("bootargs", (char *)hdr->cmdline);
+
+	ramdisk_start = hdr->ramdisk_addr;
+	ramdisk_end = ramdisk_start + hdr->ramdisk_size;
+
+	sprintf(str, "bootm 0x%x", hdr->kernel_addr - 0x40);
+	return run_command(str, 0);
+}
+
+U_BOOT_CMD(
+	andrboot, 2, 1,	do_andr_boot,
+	"boot android image",
+	"[addr]\n	- boot android boot image stored in memory"
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_autoboot.c u-boot-2011.06/common/cmd_autoboot.c
--- u-boot-2011.06_original/common/cmd_autoboot.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_autoboot.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+
+/*
+ * Android command support
+ */
+#include <asm/byteorder.h>
+#include <common.h>
+#include <command.h>
+
+#define BOOT_START_SECTOR 0x2022
+#define RECOVERY_START_SECTOR 0x6022
+
+#define CNC1900_SMEM_RESERVED 0x8001FFF0
+
+int do_auto_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char str[64];
+	int offset = BOOT_START_SECTOR;
+	char *p = (char*) CNC1900_SMEM_RESERVED;
+
+	if (strcmp(p, "recovery") == 0)
+		offset = RECOVERY_START_SECTOR;
+
+	sprintf(str, "mmc read 0x800000 0x%x 0x3000", offset);
+	run_command(str, 0);
+
+	memset(p, 0x0, 0xF);
+	return run_command("andrboot 0x800000", 0);
+}
+
+U_BOOT_CMD(
+	autoboot, 1, 0,	do_auto_boot,
+	"auto boot android boot or recovery partition",
+	""
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_bdinfo.c u-boot-2011.06/common/cmd_bdinfo.c
--- u-boot-2011.06_original/common/cmd_bdinfo.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_bdinfo.c	2014-07-29 17:28:38.819972000 +0800
@@ -353,6 +353,10 @@
 	print_num("irq_sp", gd->irq_sp);	/* irq stack pointer */
 	print_num("sp start ", gd->start_addr_sp);
 	print_num("FB base  ", gd->fb_base);
+#ifdef CONFIG_ARCH_CNC1900
+	printf("cpu freq = %d\n", gd->cpu_freq);
+	printf("ddr freq = %d\n", gd->ddr_freq);
+#endif
 	return 0;
 }
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_bootm.c u-boot-2011.06/common/cmd_bootm.c
--- u-boot-2011.06_original/common/cmd_bootm.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_bootm.c	2014-10-31 15:24:33.291947000 +0800
@@ -21,7 +21,7 @@
  * MA 02111-1307 USA
  */
 
-
+#define USE_SECURE_IMAGE_ON_NON_SECURE_PART 0
 /*
  * Boot support
  */
@@ -37,6 +37,8 @@
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
 
+#include "cnc_util.h"
+
 #if defined(CONFIG_CMD_USB)
 #include <usb.h>
 #endif
@@ -67,6 +69,40 @@
 #define CONFIG_SYS_BOOTM_LEN	0x800000	/* use 8MByte as default max gunzip size */
 #endif
 
+//#define DEBUG_BOOTM
+#ifdef	DEBUG_BOOTM
+#define debug_bootm(fmt,args...)	printf (fmt ,##args)
+#else
+#define debug_bootm(fmt,args...)
+#endif	/* DEBUG_BOOTM */
+
+#define BLOB_HEADER_IDENTIFIER  (0x22113344)
+typedef struct stage2blobHeader_s
+{
+	unsigned numImages;
+	unsigned reserved[3];
+	unsigned mHdrId;
+	unsigned mLength;
+	unsigned mSignLen;
+	char mVersion[256];
+	unsigned char md5sum[16];
+	unsigned mCrc32;
+}stage2blobHeader_s;
+
+typedef struct
+{
+	unsigned numImages;
+	unsigned reserved[3];
+	unsigned mHdrId;
+	unsigned mLength;
+	unsigned mSignLen;
+	char mVersion[256];
+	unsigned char md5sum[16];
+	unsigned mCrc32;
+	unsigned char mKeyLadder[48];
+	unsigned char reserve[32];
+}stage2blobHeader_s_new;
+
 #ifdef CONFIG_BZIP2
 extern void bz_internal_error(int);
 #endif
@@ -86,6 +122,8 @@
 static void fixup_silent_linux (void);
 #endif
 
+static void fixup_bootargs_linux(void);
+
 static image_header_t *image_get_kernel (ulong img_addr, int verify);
 #if defined(CONFIG_FIT)
 static int fit_check_kernel (const void *fit, int os_noffset, int verify);
@@ -103,7 +141,7 @@
  *  - disabled interrupts.
  */
 typedef int boot_os_fn (int flag, int argc, char * const argv[],
-			bootm_headers_t *images); /* pointers to os/initrd/fdt */
+		bootm_headers_t *images); /* pointers to os/initrd/fdt */
 
 #ifdef CONFIG_BOOTM_LINUX
 extern boot_os_fn do_bootm_linux;
@@ -166,31 +204,34 @@
 void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
 
 #if defined(__ARM__)
-  #define IH_INITRD_ARCH IH_ARCH_ARM
+#define IH_INITRD_ARCH IH_ARCH_ARM
 #elif defined(__avr32__)
-  #define IH_INITRD_ARCH IH_ARCH_AVR32
+#define IH_INITRD_ARCH IH_ARCH_AVR32
 #elif defined(__bfin__)
-  #define IH_INITRD_ARCH IH_ARCH_BLACKFIN
+#define IH_INITRD_ARCH IH_ARCH_BLACKFIN
 #elif defined(__I386__)
-  #define IH_INITRD_ARCH IH_ARCH_I386
+#define IH_INITRD_ARCH IH_ARCH_I386
 #elif defined(__M68K__)
-  #define IH_INITRD_ARCH IH_ARCH_M68K
+#define IH_INITRD_ARCH IH_ARCH_M68K
 #elif defined(__microblaze__)
-  #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE
+#define IH_INITRD_ARCH IH_ARCH_MICROBLAZE
 #elif defined(__mips__)
-  #define IH_INITRD_ARCH IH_ARCH_MIPS
+#define IH_INITRD_ARCH IH_ARCH_MIPS
 #elif defined(__nios2__)
-  #define IH_INITRD_ARCH IH_ARCH_NIOS2
+#define IH_INITRD_ARCH IH_ARCH_NIOS2
 #elif defined(__PPC__)
-  #define IH_INITRD_ARCH IH_ARCH_PPC
+#define IH_INITRD_ARCH IH_ARCH_PPC
 #elif defined(__sh__)
-  #define IH_INITRD_ARCH IH_ARCH_SH
+#define IH_INITRD_ARCH IH_ARCH_SH
 #elif defined(__sparc__)
-  #define IH_INITRD_ARCH IH_ARCH_SPARC
+#define IH_INITRD_ARCH IH_ARCH_SPARC
 #else
 # error Unknown CPU type
 #endif
 
+static unsigned int g_new_security = 0;
+static unsigned int g_cnc_image_loaded = 0;
+
 static void bootm_start_lmb(void)
 {
 #ifdef CONFIG_LMB
@@ -218,7 +259,6 @@
 
 	memset ((void *)&images, 0, sizeof (images));
 	images.verify = getenv_yesno ("verify");
-
 	bootm_start_lmb();
 
 	/* get kernel image header, start address and length */
@@ -231,50 +271,50 @@
 
 	/* get image parameters */
 	switch (genimg_get_format (os_hdr)) {
-	case IMAGE_FORMAT_LEGACY:
-		images.os.type = image_get_type (os_hdr);
-		images.os.comp = image_get_comp (os_hdr);
-		images.os.os = image_get_os (os_hdr);
+		case IMAGE_FORMAT_LEGACY:
+			images.os.type = image_get_type (os_hdr);
+			images.os.comp = image_get_comp (os_hdr);
+			images.os.os = image_get_os (os_hdr);
 
-		images.os.end = image_get_image_end (os_hdr);
-		images.os.load = image_get_load (os_hdr);
-		break;
+			images.os.end = image_get_image_end (os_hdr);
+			images.os.load = image_get_load (os_hdr);
+			break;
 #if defined(CONFIG_FIT)
-	case IMAGE_FORMAT_FIT:
-		if (fit_image_get_type (images.fit_hdr_os,
-					images.fit_noffset_os, &images.os.type)) {
-			puts ("Can't get image type!\n");
-			show_boot_progress (-109);
-			return 1;
-		}
+		case IMAGE_FORMAT_FIT:
+			if (fit_image_get_type (images.fit_hdr_os,
+						images.fit_noffset_os, &images.os.type)) {
+				puts ("Can't get image type!\n");
+				show_boot_progress (-109);
+				return 1;
+			}
 
-		if (fit_image_get_comp (images.fit_hdr_os,
-					images.fit_noffset_os, &images.os.comp)) {
-			puts ("Can't get image compression!\n");
-			show_boot_progress (-110);
-			return 1;
-		}
+			if (fit_image_get_comp (images.fit_hdr_os,
+						images.fit_noffset_os, &images.os.comp)) {
+				puts ("Can't get image compression!\n");
+				show_boot_progress (-110);
+				return 1;
+			}
 
-		if (fit_image_get_os (images.fit_hdr_os,
-					images.fit_noffset_os, &images.os.os)) {
-			puts ("Can't get image OS!\n");
-			show_boot_progress (-111);
-			return 1;
-		}
+			if (fit_image_get_os (images.fit_hdr_os,
+						images.fit_noffset_os, &images.os.os)) {
+				puts ("Can't get image OS!\n");
+				show_boot_progress (-111);
+				return 1;
+			}
 
-		images.os.end = fit_get_end (images.fit_hdr_os);
+			images.os.end = fit_get_end (images.fit_hdr_os);
 
-		if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
-					&images.os.load)) {
-			puts ("Can't get image load address!\n");
-			show_boot_progress (-112);
-			return 1;
-		}
-		break;
+			if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
+						&images.os.load)) {
+				puts ("Can't get image load address!\n");
+				show_boot_progress (-112);
+				return 1;
+			}
+			break;
 #endif
-	default:
-		puts ("ERROR: unknown image format type!\n");
-		return 1;
+		default:
+			puts ("ERROR: unknown image format type!\n");
+			return 1;
 	}
 
 	/* find kernel entry point */
@@ -295,20 +335,20 @@
 	}
 
 	if (((images.os.type == IH_TYPE_KERNEL) ||
-	     (images.os.type == IH_TYPE_MULTI)) &&
-	    (images.os.os == IH_OS_LINUX)) {
+				(images.os.type == IH_TYPE_MULTI)) &&
+			(images.os.os == IH_OS_LINUX)) {
 		/* find ramdisk */
 		ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
 				&images.rd_start, &images.rd_end);
 		if (ret) {
-			puts ("Ramdisk image is corrupt or invalid\n");
+			printf ("%sRamdisk image is corrupted or invalid\n%s" , ColorRed, ColorNormal);
 			return 1;
 		}
 
 #if defined(CONFIG_OF_LIBFDT)
 		/* find flattened device tree */
 		ret = boot_get_fdt (flag, argc, argv, &images,
-				    &images.ft_addr, &images.ft_len);
+				&images.ft_addr, &images.ft_len);
 		if (ret) {
 			puts ("Could not find a valid device tree\n");
 			return 1;
@@ -343,103 +383,103 @@
 	const char *type_name = genimg_get_type_name (os.type);
 
 	switch (comp) {
-	case IH_COMP_NONE:
-		if (load == blob_start || load == image_start) {
-			printf ("   XIP %s ... ", type_name);
-		} else {
-			printf ("   Loading %s ... ", type_name);
-			memmove_wd ((void *)load, (void *)image_start,
-					image_len, CHUNKSZ);
-		}
-		*load_end = load + image_len;
-		puts("OK\n");
-		break;
+		case IH_COMP_NONE:
+			if (load == blob_start || load == image_start) {
+				printf ("   XIP %s ... ", type_name);
+			} else {
+				printf ("   Loading %s ... ,load=0x%X,image_start=0x%X,image_len=0x%X\n", type_name, (unsigned int)load, (unsigned int) image_start, (unsigned int) image_len);
+				memmove_wd ((void *)load, (void *)image_start,
+						image_len, CHUNKSZ);
+			}
+			*load_end = load + image_len;
+			puts("OK\n");
+			break;
 #ifdef CONFIG_GZIP
-	case IH_COMP_GZIP:
-		printf ("   Uncompressing %s ... ", type_name);
-		if (gunzip ((void *)load, unc_len,
-					(uchar *)image_start, &image_len) != 0) {
-			puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
-				"- must RESET board to recover\n");
-			if (boot_progress)
-				show_boot_progress (-6);
-			return BOOTM_ERR_RESET;
-		}
+		case IH_COMP_GZIP:
+			printf ("   Uncompressing %s ... ", type_name);
+			if (gunzip ((void *)load, unc_len,
+						(uchar *)image_start, &image_len) != 0) {
+				puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
+						"- must RESET board to recover\n");
+				if (boot_progress)
+					show_boot_progress (-6);
+				return BOOTM_ERR_RESET;
+			}
 
-		*load_end = load + image_len;
-		break;
+			*load_end = load + image_len;
+			break;
 #endif /* CONFIG_GZIP */
 #ifdef CONFIG_BZIP2
-	case IH_COMP_BZIP2:
-		printf ("   Uncompressing %s ... ", type_name);
-		/*
-		 * If we've got less than 4 MB of malloc() space,
-		 * use slower decompression algorithm which requires
-		 * at most 2300 KB of memory.
-		 */
-		int i = BZ2_bzBuffToBuffDecompress ((char*)load,
+		case IH_COMP_BZIP2:
+			printf ("   Uncompressing %s ... ", type_name);
+			/*
+			 * If we've got less than 4 MB of malloc() space,
+			 * use slower decompression algorithm which requires
+			 * at most 2300 KB of memory.
+			 */
+			int i = BZ2_bzBuffToBuffDecompress ((char*)load,
 					&unc_len, (char *)image_start, image_len,
 					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
-		if (i != BZ_OK) {
-			printf ("BUNZIP2: uncompress or overwrite error %d "
-				"- must RESET board to recover\n", i);
-			if (boot_progress)
-				show_boot_progress (-6);
-			return BOOTM_ERR_RESET;
-		}
+			if (i != BZ_OK) {
+				printf ("BUNZIP2: uncompress or overwrite error %d "
+						"- must RESET board to recover\n", i);
+				if (boot_progress)
+					show_boot_progress (-6);
+				return BOOTM_ERR_RESET;
+			}
 
-		*load_end = load + unc_len;
-		break;
+			*load_end = load + unc_len;
+			break;
 #endif /* CONFIG_BZIP2 */
 #ifdef CONFIG_LZMA
-	case IH_COMP_LZMA: {
-		SizeT lzma_len = unc_len;
-		printf ("   Uncompressing %s ... ", type_name);
-
-		ret = lzmaBuffToBuffDecompress(
-			(unsigned char *)load, &lzma_len,
-			(unsigned char *)image_start, image_len);
-		unc_len = lzma_len;
-		if (ret != SZ_OK) {
-			printf ("LZMA: uncompress or overwrite error %d "
-				"- must RESET board to recover\n", ret);
-			show_boot_progress (-6);
-			return BOOTM_ERR_RESET;
-		}
-		*load_end = load + unc_len;
-		break;
-	}
+		case IH_COMP_LZMA: {
+					   SizeT lzma_len = unc_len;
+					   printf ("   Uncompressing %s ... ", type_name);
+
+					   ret = lzmaBuffToBuffDecompress(
+							   (unsigned char *)load, &lzma_len,
+							   (unsigned char *)image_start, image_len);
+					   unc_len = lzma_len;
+					   if (ret != SZ_OK) {
+						   printf ("LZMA: uncompress or overwrite error %d "
+								   "- must RESET board to recover\n", ret);
+						   show_boot_progress (-6);
+						   return BOOTM_ERR_RESET;
+					   }
+					   *load_end = load + unc_len;
+					   break;
+				   }
 #endif /* CONFIG_LZMA */
 #ifdef CONFIG_LZO
-	case IH_COMP_LZO:
-		printf ("   Uncompressing %s ... ", type_name);
+		case IH_COMP_LZO:
+				   printf ("   Uncompressing %s ... ", type_name);
 
-		ret = lzop_decompress((const unsigned char *)image_start,
-					  image_len, (unsigned char *)load,
-					  &unc_len);
-		if (ret != LZO_E_OK) {
-			printf ("LZO: uncompress or overwrite error %d "
-			      "- must RESET board to recover\n", ret);
-			if (boot_progress)
-				show_boot_progress (-6);
-			return BOOTM_ERR_RESET;
-		}
+				   ret = lzop_decompress((const unsigned char *)image_start,
+						   image_len, (unsigned char *)load,
+						   &unc_len);
+				   if (ret != LZO_E_OK) {
+					   printf ("LZO: uncompress or overwrite error %d "
+							   "- must RESET board to recover\n", ret);
+					   if (boot_progress)
+						   show_boot_progress (-6);
+					   return BOOTM_ERR_RESET;
+				   }
 
-		*load_end = load + unc_len;
-		break;
+				   *load_end = load + unc_len;
+				   break;
 #endif /* CONFIG_LZO */
-	default:
-		printf ("Unimplemented compression type %d\n", comp);
-		return BOOTM_ERR_UNIMPLEMENTED;
+		default:
+				   printf ("Unimplemented compression type %d\n", comp);
+				   return BOOTM_ERR_UNIMPLEMENTED;
 	}
 	puts ("OK\n");
-	debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
+	debug_bootm ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
 	if (boot_progress)
 		show_boot_progress (7);
 
 	if ((load < blob_end) && (*load_end > blob_start)) {
-		debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
-		debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);
+		debug_bootm ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
+		debug_bootm ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);
 
 		return BOOTM_ERR_OVERLAP;
 	}
@@ -516,16 +556,16 @@
 	switch (state) {
 		ulong load_end;
 		case BOOTM_STATE_START:
-			/* should never occur */
-			break;
+		/* should never occur */
+		break;
 		case BOOTM_STATE_LOADOS:
-			ret = bootm_load_os(images.os, &load_end, 0);
-			if (ret)
-				return ret;
+		ret = bootm_load_os(images.os, &load_end, 0);
+		if (ret)
+			return ret;
 
-			lmb_reserve(&images.lmb, images.os.load,
-					(load_end - images.os.load));
-			break;
+		lmb_reserve(&images.lmb, images.os.load,
+				(load_end - images.os.load));
+		break;
 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
 		case BOOTM_STATE_RAMDISK:
 		{
@@ -533,7 +573,7 @@
 			char str[17];
 
 			ret = boot_ramdisk_high(&images.lmb, images.rd_start,
-				rd_len, &images.initrd_start, &images.initrd_end);
+					rd_len, &images.initrd_start, &images.initrd_end);
 			if (ret)
 				return ret;
 
@@ -542,43 +582,1060 @@
 			sprintf(str, "%lx", images.initrd_end);
 			setenv("initrd_end", str);
 		}
-			break;
+		break;
 #endif
 #if defined(CONFIG_OF_LIBFDT)
 		case BOOTM_STATE_FDT:
 		{
 			boot_fdt_add_mem_rsv_regions(&images.lmb,
-						     images.ft_addr);
+					images.ft_addr);
 			ret = boot_relocate_fdt(&images.lmb,
-				&images.ft_addr, &images.ft_len);
+					&images.ft_addr, &images.ft_len);
 			break;
 		}
 #endif
 		case BOOTM_STATE_OS_CMDLINE:
-			ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images);
-			if (ret)
-				printf ("cmdline subcommand not supported\n");
-			break;
+		ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images);
+		if (ret)
+			printf ("cmdline subcommand not supported\n");
+		break;
 		case BOOTM_STATE_OS_BD_T:
-			ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images);
-			if (ret)
-				printf ("bdt subcommand not supported\n");
-			break;
+		ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images);
+		if (ret)
+			printf ("bdt subcommand not supported\n");
+		break;
 		case BOOTM_STATE_OS_PREP:
-			ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images);
-			if (ret)
-				printf ("prep subcommand not supported\n");
-			break;
+		ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images);
+		if (ret)
+			printf ("prep subcommand not supported\n");
+		break;
 		case BOOTM_STATE_OS_GO:
-			disable_interrupts();
-			arch_preboot_os();
-			boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
-			break;
+		disable_interrupts();
+		arch_preboot_os();
+		boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
+		break;
 	}
 
 	return ret;
 }
 
+extern int otp_read_version(unsigned short *version);
+extern int otp_write_version(unsigned short version);
+
+int GetMkImageHeader_New(void* apBuffer, UInt32* apSize, UInt8 * apHeaderType, UInt16 *apVersion)
+{
+	image_header_t* pImgHdr;
+	UInt32 Magic=0;
+	Magic=Magic;
+
+	pImgHdr = (image_header_t *)apBuffer;
+
+	Magic =  image_get_magic (pImgHdr);
+	*apSize = image_get_size (pImgHdr) + sizeof(image_header_t) ; //Add header also.
+	*apHeaderType = pImgHdr->ih_type;
+	*apVersion = image_get_ver(pImgHdr);
+
+	debug_bootm( " MAGIC=%08x \n" , Magic ) ;	/* Image Header Magic Number	*/
+	debug_bootm( " Size=%d , 0x%08x\n"  , *apSize , *apSize) ;	/* Image Header Magic Number	*/
+
+	if (!image_check_magic (pImgHdr))
+	{
+		printf( "%sERROR:Unknow image format\n%s", ColorRed, ColorNormal);
+		return -1;
+	}
+
+	*apSize = 256 * ((*apSize + 256-1)/256) ;//aligned to 256.
+
+	debug_bootm("It looks like good image\n");
+	debug_bootm("MAGIC=%08x \n" , Magic ) ;	/* Image Header Magic Number	*/
+	debug_bootm("Size=%d , 0x%08x\n"  , *apSize , *apSize) ;	/* Image size */
+	debug_bootm("Version=%d , 0x%08x\n"  , *apVersion , *apVersion) ;	/* Image version */
+	return 0;
+}
+
+int GetMkImageHeader(void* apBuffer, UInt32* apSize, UInt8 * apHeaderType )
+{
+	image_header_t* pImgHdr;
+	UInt32 Magic=0;
+	Magic=Magic;
+
+	pImgHdr = (image_header_t *)apBuffer;
+
+	Magic =  image_get_magic (pImgHdr);
+	*apSize = image_get_size (pImgHdr) + sizeof(image_header_t) ; //Add header also.
+	*apHeaderType = pImgHdr->ih_type;
+
+	debug_bootm( " MAGIC=%08x \n" , Magic ) ;	/* Image Header Magic Number	*/
+	debug_bootm( " Size=%d , 0x%08x\n"  , *apSize , *apSize) ;	/* Image Header Magic Number	*/
+
+	if (!image_check_magic (pImgHdr))
+	{
+		printf( "%sERROR:Unknow image format\n%s", ColorRed, ColorNormal);
+		return -1;
+	}
+
+	*apSize = 256 * ((*apSize + 256-1)/256) ;//aligned to 256.
+
+	debug_bootm("It looks like good image\n");
+	debug_bootm("MAGIC=%08x \n" , Magic ) ;	/* Image Header Magic Number	*/
+	debug_bootm("Size=%d , 0x%08x\n"  , *apSize , *apSize) ;	/* Image Header Magic Number	*/
+	return 0;
+}
+
+int IsItEncryptedImage(UInt32 aKernelAddress)
+{
+	image_header_t* pImgHdr;
+	if ( 0xFFFFFFFF != aKernelAddress )
+	{
+		pImgHdr = (image_header_t *)aKernelAddress;
+
+		if (!image_check_magic (pImgHdr))
+		{
+			printf ("Looks like encrypted uImage found\n");
+			setenv("verify", "no");
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int CNC_DecryptImageIfRequired( UInt32 aKernelAddress, UInt32 aRamFsAddress, UInt32 aBlobAddress, int* apEncryptedKernelFound )
+{
+	int Status=-1;
+	image_header_t* pImgHdr;
+	UInt32 ReadSize=0;
+
+	UInt8 ImageHeaderType;
+	UInt8 ComputedHashBuffer[32 + 256];
+	UInt8 SourceHash[32 +256];
+	UInt8 BackupHashAndRsa[16+16+256];
+	UInt8 TempBuf[512]; //Backup buffer
+	UInt32 ActualImageLength=0;
+
+	* apEncryptedKernelFound = 0;
+	if ( 0xFFFFFFFF != aKernelAddress )
+	{
+		pImgHdr = (image_header_t *)aKernelAddress;
+
+		if (!image_check_magic (pImgHdr))
+		{
+			debug_bootm ("Looks like encrypted uImage found\n");
+			setenv("verify","no");
+			//----------------------------------------------------------------
+			memcpy ( TempBuf, (void*) aKernelAddress , sizeof (char) * 512);
+			Status = Cnc_InPlaceDecryptOnlyImage(aKernelAddress, 256);
+			Status =  GetMkImageHeader( (void*) aKernelAddress, & ActualImageLength, & ImageHeaderType );
+			if(-1 == Status)
+			{
+				printf("ERROR: Get kernel image header error!\n");
+				return -1;
+			}
+			//Restore encrypted content.
+			memcpy ( (void*) aKernelAddress, TempBuf, sizeof (char) * 512);
+			//----------------------------------------------------------------
+			debug_bootm("ActualImageLength = %d (0x%08X)\n", ActualImageLength ,  ActualImageLength );
+			ReadSize = 256 * ( ( ActualImageLength + 256 - 1 ) / 256 ); //256 bytes of RSA, 32 bytes for hash, aligned to 256.
+			debug_bootm("ReadSize = %d (0x%08X)\n", ReadSize, ReadSize);
+			//---------------------------------------------------------------
+
+			//DVU may corrupt data following specified legnth (upto 64 bytes)
+			//so better backup, hash and RSA
+			memcpy(BackupHashAndRsa, (void*) (aKernelAddress + ActualImageLength), sizeof(BackupHashAndRsa) );
+			debug_bootm("------ BackupHashAndRsa ---------\n");
+			//Cnc_DumpMemory(BackupHashAndRsa, 8);
+			debug_bootm("---------------\n");
+			memcpy(SourceHash, (void*) (aKernelAddress + ActualImageLength), 16 );
+			debug_bootm("-----  SourceHash ----------\n");
+			//Cnc_DumpMemory(SourceHash, 8);
+			debug_bootm("---------------\n");
+			Status = Cnc_DecryptImageGetHash(aKernelAddress, aKernelAddress, ReadSize, ComputedHashBuffer, 16 );
+			Status =  GetMkImageHeader( (void*) aKernelAddress, & ReadSize, & ImageHeaderType );
+			if( (-1 == Status) || (IH_TYPE_KERNEL != ImageHeaderType) )
+			{
+				printf( "%sERROR: while parsing image header Hdr type=%d\n%s" , ColorRed,  ImageHeaderType, ColorNormal);
+				return -1;
+			}
+			debug_bootm("-----  SourceHash ----------\n");
+			//Cnc_DumpMemory(SourceHash, 8);
+			debug_bootm("------  ComputedHashBuffer --------\n");
+			//Cnc_DumpMemory(ComputedHashBuffer, 8);
+			debug_bootm("---------------\n");
+			//Check hash & RSA signature
+			if ( 0 == memcmp( SourceHash, ComputedHashBuffer, 16 ) )
+			{
+				debug_bootm("uIamge Hash is matching, now we will check RSA\n");
+				if ( 0 == Cnc_ImgHybRsa_Verify (BackupHashAndRsa, (UInt32) (BackupHashAndRsa + 32),(UInt8*) pkey) )
+				{
+					* apEncryptedKernelFound = 1;
+				}
+				else
+				{
+					printf("uImage RSA fails\n");
+					return -1;
+				}
+			}
+			else
+			{
+				printf("uImage Hash failed\n");
+				//you reach here - means image was corrupted
+				return -1;
+			}
+		}
+		else
+		{
+			//printf( "%s%sWARNING: Unencrypted kernel found\n%s", BlinkOn, ColorRed, ColorNormal);
+		}
+		debug_bootm ("OK\n");
+	}
+
+	//------------------------
+	if ( ( 0xFFFFFFFF != aRamFsAddress ) && (1 == * apEncryptedKernelFound ) )
+	{
+		pImgHdr = (image_header_t *)aRamFsAddress;
+
+		if (!image_check_magic (pImgHdr))
+		{
+			debug_bootm ("Looks like encrypted RamFs found\n");
+			setenv("verify","no");
+			//-----------------------------------------------------------------------------
+			memcpy ( TempBuf, (void*) aRamFsAddress , sizeof (char) * 512);
+			Status = Cnc_InPlaceDecryptOnlyImage(aRamFsAddress, 256);
+			Status =  GetMkImageHeader( (void*) aRamFsAddress, & ActualImageLength , & ImageHeaderType );
+			if (-1 == Status)
+			{
+				printf("ERROR: Get Ramfs image header error!\n");
+				return -1;
+			}
+
+			//Restore encrypted content.
+			memcpy ( (void*) aRamFsAddress, TempBuf, sizeof (char) * 512);//Restore encrypted content.
+			//----------------------------------------------------------------------------------------
+			debug_bootm("ActualImageLength = %d (0x%08X)\n", ActualImageLength ,  ActualImageLength );
+			ReadSize = 256 * ( (ActualImageLength + 256 -1 ) / 256 ); //256 bytes of RSA, 32 bytes for hash, aligned to 256.
+			debug_bootm("ReadSize = %d (0x%08X)\n", ReadSize, ReadSize);
+			//--------------------------------------------------------------------------------------
+			//DVU may corrupt data following specified legnth (upto 64 bytes)
+			//so better backup, hash and RSA
+			memcpy(BackupHashAndRsa, (void*) (aRamFsAddress + ActualImageLength), sizeof(BackupHashAndRsa) );
+			debug_bootm("------ BackupHashAndRsa ---------\n");
+			//Cnc_DumpMemory(BackupHashAndRsa, 8);
+			debug_bootm("---------------\n");
+
+			memcpy(SourceHash, (void*) (aRamFsAddress + ActualImageLength), 16 );
+			debug_bootm("---------------\n");
+			//Cnc_DumpMemory(SourceHash, 8);
+			debug_bootm("---------------\n");
+			Status = Cnc_DecryptImageGetHash(aRamFsAddress, aRamFsAddress, ReadSize, ComputedHashBuffer, 16);
+			Status =  GetMkImageHeader( (void*) aRamFsAddress, & ReadSize , &ImageHeaderType );
+			if ( (-1 == Status) || (IH_TYPE_RAMDISK	 != ImageHeaderType) )
+			{
+				printf( "%sERROR: while parsing image header Hdr type=%d\n%s", ColorRed  , ImageHeaderType, ColorNormal);
+				return -1;
+			}
+			//Check RSA signature -
+			debug_bootm("---------------\n");
+			//Cnc_DumpMemory(SourceHash, 8);
+			debug_bootm("---------------\n");
+			//Cnc_DumpMemory(ComputedHashBuffer, 8);
+			debug_bootm("---------------\n");
+			if ( 0 == memcmp( SourceHash, ComputedHashBuffer, 16 ) )
+			{
+				debug_bootm("rootfs Hash is matching, now we will check RSA\n");
+				if ( 0 == Cnc_ImgHybRsa_Verify (BackupHashAndRsa, (UInt32) (BackupHashAndRsa + 32), (UInt8*) pkey) )
+				{
+				}
+				else
+				{
+					debug_bootm("ramdisk - rsa failed\n");
+					return -1;
+				}
+			}
+			else
+			{
+				debug_bootm("ramdisk - hash failed\n");
+				//you reach here - means image was corrupted
+				return -1;
+			}
+		}
+		else
+		{
+			if (1 == * apEncryptedKernelFound )
+			{
+				printf( "%sERROR: Kernel was secured, but file system was insecure. this illegal configuration\n%s", ColorRed, ColorNormal);
+				printf( "%s       Please contact vendor\n%s" , ColorRed, ColorNormal );
+				return -1;
+			}
+			printf("%s%sWARNING: Unencrypted RamFs found\n%s",BlinkOn, ColorRed, ColorNormal);
+		}
+		debug_bootm ("OK\n");
+	}
+	//---------------------------
+	if( (0xFFFFFFFF != aBlobAddress ) && (1 == * apEncryptedKernelFound ) )
+	{
+		stage2blobHeader_s* pStage2BlobHdr = (stage2blobHeader_s*)aBlobAddress ;
+		if ( BLOB_HEADER_IDENTIFIER == pStage2BlobHdr->mHdrId )
+		{
+			debug_bootm ("Looks like encrypted Blob found \n");
+
+			int Length = pStage2BlobHdr->mLength;//payload length
+			debug_bootm("HDR=%08X Length=%08X\n", pStage2BlobHdr->mHdrId  , Length);
+
+			Length = Length -32;
+
+			//strip header
+			memcpy( (void*) aBlobAddress ,
+					(void*)( aBlobAddress + sizeof (*pStage2BlobHdr)),
+					Length + 256 + 32);
+
+			memcpy(BackupHashAndRsa, (void*) (aBlobAddress + Length), sizeof(BackupHashAndRsa) );
+			memcpy(SourceHash, (void*) (aBlobAddress + Length), 16 );
+
+			Status = Cnc_DecryptImageGetHash(aBlobAddress, aBlobAddress, Length, ComputedHashBuffer, 16 );
+			//It is valid blob. we are doing inplace decryption so need for any further memcpy.
+			//Check RSA signature
+			if ( 0 == memcmp( SourceHash, ComputedHashBuffer, 16 ) )
+			{
+				debug_bootm("Blob hash is matching, let's check rsa now\n");
+				if ( 0 == Cnc_ImgHybRsa_Verify (BackupHashAndRsa, (UInt32) (BackupHashAndRsa + 32), (UInt8*) blob_pkey) )
+				{
+				}
+				else
+				{
+					printf("%sERROR: RSA failed\n%s" ,  ColorRed, ColorNormal );
+					return -1;
+				}
+			}
+			else
+			{
+				//you reach here - means image was corrupted
+				printf("ERROR: BLOB was corrupted!\n");
+				return -1;
+			}
+		}
+		else
+		{
+			if (1 == * apEncryptedKernelFound )
+			{
+				printf("%s%sERROR:Invalid blob. please contact vendor\n%s" , BlinkOn, ColorRed, ColorNormal);
+				return -1;
+			}
+			printf("%s%sWARNING:Invalid blob. You are using unsecure kernel, so blob is not required, proceeding for debug purpose only. Please report to your vendor\n%s" , BlinkOn, ColorYellow, ColorNormal);
+			return 0;
+		}
+		debug_bootm("OK\n");
+	}
+	//---------------------------
+	return 0;
+}
+
+int CNC_DecryptImageIfRequired_New( UInt32 aKernelAddress, UInt32 aRamFsAddress, UInt32 aBlobAddress, int* apEncryptedKernelFound, UInt16 *ImageVersion )
+{
+	int Status=-1;
+	image_header_t* pImgHdr;
+	UInt32 ReadSize=0;
+
+	UInt8 ImageHeaderType;
+	UInt8 TempBuf[512]; //Backup buffer
+	UInt32 ActualImageLength=0;
+
+	UInt16 KernelImageVersion;
+	UInt16 RamfsImageVersion;
+
+	* apEncryptedKernelFound = 0;
+	if ( 0xFFFFFFFF != aKernelAddress )
+	{
+		pImgHdr = (image_header_t *)aKernelAddress;
+
+		if (!image_check_magic (pImgHdr))
+		{
+			debug_bootm ("Looks like encrypted uImage found\n");
+			setenv("verify","no");
+			if(!dcache_status()){
+				dcache_enable();
+			}
+			//----------------------------------------------------------------
+			memcpy ( TempBuf, (void*) (aKernelAddress+64) , sizeof (char) * 512);
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aKernelAddress, aKernelAddress+64, 256);
+			Status =  GetMkImageHeader_New( (void*) (aKernelAddress+64), & ActualImageLength, & ImageHeaderType, &KernelImageVersion );
+			if(-1 == Status)
+			{
+				return -1;
+			}
+			//Restore encrypted content.
+			memcpy ( (void*) (aKernelAddress+64), TempBuf, sizeof (char) * 512);
+			//----------------------------------------------------------------
+			debug_bootm("ActualImageLength = %d (0x%08X)\n", ActualImageLength ,  ActualImageLength );
+			ReadSize = 256 * ( ( ActualImageLength + 256 - 1 ) / 256 ); //256 bytes of RSA, 32 bytes for hash, aligned to 256.
+			debug_bootm("ReadSize = %d (0x%08X)\n", ReadSize, ReadSize);
+			//---------------------------------------------------------------
+
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aKernelAddress, aKernelAddress+64, ReadSize+256);
+			Status = GetMkImageHeader( (void*) (aKernelAddress+64), & ReadSize, & ImageHeaderType );
+			if( (-1 == Status) || (IH_TYPE_KERNEL != ImageHeaderType) )
+			{
+				printf( "%sERROR: while parsing image header Hdr type=%d\n%s" , ColorRed,  ImageHeaderType, ColorNormal);
+				return -1;
+			}
+
+			//Check RSA signature
+			if ( 0 == ImgRsa_Verify (aKernelAddress+64, ReadSize, aKernelAddress+64+ReadSize, KERNEL) )
+			{
+				debug_bootm("uImage RSA pass!\n");
+				* apEncryptedKernelFound = 1;
+			}
+			else
+			{
+				debug_bootm("uImage RSA fails\n");
+				return -1;
+			}
+			dcache_disable();
+		}
+		else
+		{
+			//printf( "%s%sWARNING: Unencrypted kernel found\n%s", BlinkOn, ColorRed, ColorNormal);
+		}
+		debug_bootm ("OK\n");
+	}
+
+	//------------------------
+	if ( ( 0xFFFFFFFF != aRamFsAddress ) && (1 == * apEncryptedKernelFound ) )
+	{
+		pImgHdr = (image_header_t *)aRamFsAddress;
+
+		if (!image_check_magic (pImgHdr))
+		{
+			debug_bootm ("Looks like encrypted RamFs found\n");
+			setenv("verify","no");
+			if(!dcache_status()){
+				dcache_enable();
+			}
+			//-----------------------------------------------------------------------------
+			memcpy ( TempBuf, (void*) (aRamFsAddress+64) , sizeof (char) * 512);
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aRamFsAddress, aRamFsAddress+64, 256);
+			Status =  GetMkImageHeader_New( (void*) (aRamFsAddress+64), & ActualImageLength , & ImageHeaderType, &RamfsImageVersion );
+			if (-1 == Status)
+			{
+				return -1;
+			}
+			//Restore encrypted content.
+			memcpy ( (void*) (aRamFsAddress+64), TempBuf, sizeof (char) * 512);
+			//----------------------------------------------------------------------------------------
+			debug_bootm("ActualImageLength = %d (0x%08X)\n", ActualImageLength ,  ActualImageLength );
+			ReadSize = 256 * ( (ActualImageLength + 256 -1 ) / 256 ); //256 bytes of RSA, 32 bytes for hash, aligned to 256.
+			debug_bootm("ReadSize = %d (0x%08X)\n", ReadSize, ReadSize);
+			//--------------------------------------------------------------------------------------
+
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aRamFsAddress, aRamFsAddress+64, ReadSize+256);
+			Status =  GetMkImageHeader( (void*) (aRamFsAddress+64), & ReadSize , &ImageHeaderType );
+			if ( (-1 == Status) || (IH_TYPE_RAMDISK	 != ImageHeaderType) )
+			{
+				printf( "%sERROR: while parsing image header Hdr type=%d\n%s", ColorRed  , ImageHeaderType, ColorNormal);
+				return -1;
+			}
+
+			//Check RSA signature
+			debug_bootm("now check RSA\n");
+			if ( 0 == ImgRsa_Verify (aRamFsAddress+64, ReadSize, aRamFsAddress+64+ReadSize, RAMDISK) )
+			{
+				debug_bootm("ramdisk RSA pass!\n");
+			}
+			else
+			{
+				debug_bootm("ramdisk - rsa failed\n");
+				return -1;
+			}
+			dcache_disable();
+		}
+		else
+		{
+			if (1 == * apEncryptedKernelFound )
+			{
+				printf( "%sERROR: Kernel was secured, but file system was insecure. this illegal configuration\n%s", ColorRed, ColorNormal);
+				printf( "%s       Please contact vendor\n%s" , ColorRed, ColorNormal );
+				return -1;
+			}
+			printf("%s%sWARNING: Unencrypted RamFs found\n%s",BlinkOn, ColorRed, ColorNormal);
+		}
+		debug_bootm ("OK\n");
+	}
+
+	if ( KernelImageVersion == RamfsImageVersion )
+		*ImageVersion = KernelImageVersion;
+	else
+	{
+		printf( "%sERROR: Kernel Image version and Ramfs Image version don't match. illegal image found\n%s", ColorRed, ColorNormal);
+		printf( "%s       Please contact vendor\n%s" , ColorRed, ColorNormal );
+		return -1;
+	}
+
+	//---------------------------
+	if( (0xFFFFFFFF != aBlobAddress ) && (1 == * apEncryptedKernelFound ) )
+	{
+		stage2blobHeader_s_new* pStage2BlobHdr = (stage2blobHeader_s_new*)aBlobAddress ;
+		if ( BLOB_HEADER_IDENTIFIER == pStage2BlobHdr->mHdrId )
+		{
+			debug_bootm ("Looks like encrypted Blob found \n");
+
+			long BlobVersion = simple_strtol(pStage2BlobHdr->mVersion, NULL, 10);
+			if ((BlobVersion == 1 && g_new_security == 1) ||
+					(BlobVersion == 2 && g_new_security == 0))
+			{
+				printf("%sERROR: blob version %ld is not expected, please contact vendor\n%s", ColorRed, BlobVersion, ColorNormal);
+				return -1;
+			}
+
+			int Length = pStage2BlobHdr->mLength;//payload length
+			debug_bootm("HDR=%08X Length=%08X\n", pStage2BlobHdr->mHdrId  , Length);
+
+			Status = Cnc_InPlaceDecryptOnlyImage_AES(pStage2BlobHdr->mKeyLadder, aBlobAddress+sizeof(stage2blobHeader_s_new), Length+256);
+
+			//strip header
+			memcpy( (void*) aBlobAddress ,
+					(void*)( aBlobAddress + sizeof (stage2blobHeader_s_new)),
+					Length + 256);
+
+			if ( 0 == ImgRsa_Verify (aBlobAddress, Length, aBlobAddress+Length, RAW) )
+			{
+				debug_bootm("Blob RSA pass!\n");
+			}
+			else
+			{
+				debug_bootm("%sERROR: RSA failed\n%s" ,  ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+		else
+		{
+			if (1 == * apEncryptedKernelFound )
+			{
+				printf("%s%sERROR:Invalid blob. please contact vendor\n%s" , BlinkOn, ColorRed, ColorNormal);
+				return -1;
+			}
+			printf("%s%sWARNING:Invalid blob. You are using unsecure kernel, so blob is not required, proceeding for debug purpose only. Please report to your vendor\n%s" , BlinkOn, ColorYellow, ColorNormal);
+			return 0;
+		}
+		debug_bootm("OK\n");
+	}
+	//---------------------------
+	return 0;
+}
+
+UInt32 GetKernelImageLength(UInt32 aKernelLoadAddress)
+{
+	int ret=0;
+	UInt32 Length=0;
+	image_header_t* pImgHdr;
+	int Status;
+	UInt32 ActualImageLength=0;
+	UInt8 ImageHeaderType;
+	ret=ret;
+
+	ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "kernel" , aKernelLoadAddress ,64+256);
+
+	pImgHdr = (image_header_t *)aKernelLoadAddress;
+
+	if (! image_check_magic (pImgHdr))
+	{
+		debug_bootm ("Looks like encrypted uImage found\n");
+		if (g_new_security)
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aKernelLoadAddress, aKernelLoadAddress+64, 256);
+		}
+		else
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage(aKernelLoadAddress, 256);
+		}
+	}
+	if (g_new_security)
+	{
+		Status =  GetMkImageHeader( (void*) (aKernelLoadAddress+64), & ActualImageLength, & ImageHeaderType );
+	}
+	else
+	{
+		Status =  GetMkImageHeader( (void*) aKernelLoadAddress, & ActualImageLength, & ImageHeaderType );
+	}
+	if ( 0 == Status )
+	{
+		debug_bootm("kernel length=%d\n",ActualImageLength );
+		Length = ActualImageLength;
+	}
+	else{
+		printf("%sERROR,GetMkImageHeader for kernel!\n%s",ColorRed,ColorNormal);
+		Length = 0xffffffff;
+		return Length;
+	}
+	Length = ( (Length + (128*1024) - 1) / (128*1024) ) * (128*1024) ;
+	return Length;
+}
+
+UInt32 GetKernel_f_ImageLength(UInt32 aKernelLoadAddress)
+{
+	int ret=0;
+	UInt32 Length=0;
+	image_header_t* pImgHdr;
+	int Status;
+	UInt32 ActualImageLength=0;
+	UInt8 ImageHeaderType;
+	ret=ret;
+
+	ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "kernel_f" , aKernelLoadAddress ,64+256);
+
+	pImgHdr = (image_header_t *)aKernelLoadAddress;
+
+	if (! image_check_magic (pImgHdr))
+	{
+		debug_bootm ("Looks like encrypted uImage found\n");
+		if (g_new_security)
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aKernelLoadAddress, aKernelLoadAddress+64, 256);
+		}
+		else
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage(aKernelLoadAddress, 256);
+		}
+	}
+	if (g_new_security)
+	{
+		Status =  GetMkImageHeader( (void*) (aKernelLoadAddress+64), & ActualImageLength, & ImageHeaderType );
+	}
+	else
+	{
+		Status =  GetMkImageHeader( (void*) aKernelLoadAddress, & ActualImageLength, & ImageHeaderType );
+	}
+	if ( 0 == Status )
+	{
+		debug_bootm("kernel_f length=%d\n",ActualImageLength);
+		Length = ActualImageLength;
+	}
+	else{
+		printf("%sERROR,GetMkImageHeader for kernel_f!\n%s",ColorRed,ColorNormal);
+		Length = 0xffffffff;
+		return Length;
+	}
+	Length = ( (Length + (128*1024) - 1) / (128*1024) ) * (128*1024) ;
+	return Length;
+}
+
+UInt32 GetRamFsImageLength(UInt32 aRamFsLoadAddress)
+{
+	int ret=0;
+	UInt32 Length=0;
+	image_header_t* pImgHdr;
+	int Status;
+	UInt32 ActualImageLength=0;
+	UInt8 ImageHeaderType;
+	ret=ret;
+	ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "rootfs" , aRamFsLoadAddress ,64+256);
+
+	pImgHdr = (image_header_t *)aRamFsLoadAddress;
+
+	if (!image_check_magic (pImgHdr))
+	{
+		debug_bootm ("Looks like encrypted RamFs found\n");
+		if (g_new_security)
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aRamFsLoadAddress, aRamFsLoadAddress+64, 256);
+		}
+		else
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage(aRamFsLoadAddress, 256);
+		}
+	}
+	if (g_new_security)
+	{
+		Status =  GetMkImageHeader( (void*) (aRamFsLoadAddress + 64), & ActualImageLength , & ImageHeaderType );
+	}
+	else
+	{
+		Status =  GetMkImageHeader( (void*) aRamFsLoadAddress, & ActualImageLength , & ImageHeaderType );
+	}
+	if (0  == Status)
+	{
+		debug_bootm("rootfs length=%d\n",ActualImageLength);
+		Length = ActualImageLength;
+	}
+	else{
+		printf("%sERROR,GetMkImageHeader for RamFs!\n%s",ColorRed,ColorNormal);
+		Length = 0xffffffff;
+		return Length;
+	}
+	Length = ( (Length + (128*1024) - 1) / (128*1024) ) * (128*1024) ;
+	return Length;
+}
+
+UInt32 GetRamFs_f_ImageLength(UInt32 aRamFsLoadAddress)
+{
+	int ret=0;
+	UInt32 Length=0;
+	image_header_t* pImgHdr;
+	int Status;
+	UInt32 ActualImageLength=0;
+	UInt8 ImageHeaderType;
+	ret=ret;
+	ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "rootfs_f" , aRamFsLoadAddress ,64+256);
+
+	pImgHdr = (image_header_t *)aRamFsLoadAddress;
+
+	if (!image_check_magic (pImgHdr))
+	{
+		debug_bootm ("Looks like encrypted RamFs found\n");
+		if (g_new_security)
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage_AES((unsigned char *)aRamFsLoadAddress, aRamFsLoadAddress+64, 256);
+		}
+		else
+		{
+			Status = Cnc_InPlaceDecryptOnlyImage(aRamFsLoadAddress, 256);
+		}
+	}
+	if (g_new_security)
+	{
+		Status =  GetMkImageHeader( (void*) (aRamFsLoadAddress + 64), & ActualImageLength , & ImageHeaderType );
+	}
+	else
+	{
+		Status =  GetMkImageHeader( (void*) aRamFsLoadAddress, & ActualImageLength , & ImageHeaderType );
+	}
+	if (0  == Status)
+	{
+		debug_bootm("rootfs_f length=%d\n",ActualImageLength);
+		Length = ActualImageLength;
+	}
+	else{
+		printf("%sERROR,GetMkImageHeader for RamFs_f!\n%s",ColorRed,ColorNormal);
+		Length = 0xffffffff;
+		return Length;
+	}
+	Length = ( (Length + (128*1024) - 1) / (128*1024) ) * (128*1024) ;
+	return Length;
+}
+
+
+static char NewArgvList[3][16];
+static char* NewArgv[3];
+static int NewArgc;
+
+int LoadCurrentImages(void)
+{
+	int		ret;
+	char* pKernelAddressInString=NULL;
+	char* pRootFsAddressInString=NULL;
+	char* pBlobAddressInString=NULL;
+	UInt32 KernelLoadAddress=0xFFFFFFFF;
+	UInt32 RootfsLoadAddress=0xFFFFFFFF;
+	UInt32 BlobLoadAddress=0xFFFFFFFF;
+	int EncryptedImageFound=0;
+	UInt32 KernelLength=0;
+	UInt32 RamFsLength=0;
+	UInt16 ImageVersionNum;
+	UInt16 OTP_Version;
+
+	pKernelAddressInString = getenv("kernel_load_addr");
+	debug_bootm("kernel_load_addr=%s\n",pKernelAddressInString);
+	pRootFsAddressInString = getenv("rootfs_load_addr");
+	debug_bootm("rootfs_load_addr=%s\n",pRootFsAddressInString);
+	pBlobAddressInString   = getenv("blob_load_addr");
+	debug_bootm("blob_load_addr=%s\n",pBlobAddressInString);
+
+	NewArgc = 0;
+	sprintf( NewArgvList[NewArgc] , "bootm");
+	NewArgc++;
+
+	if (NULL != pKernelAddressInString)
+	{
+		KernelLoadAddress = simple_strtol( pKernelAddressInString , 0, 16);
+		KernelLength = GetKernelImageLength(KernelLoadAddress);
+		if(0xffffffff == KernelLength){
+			printf("%sERROR: Read kernel!\n%s",ColorRed,ColorNormal);
+			return -1;
+		}
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "kernel" , KernelLoadAddress, 64+KernelLength+256 );
+		if ( 0 != ret )
+		{
+			printf("ERROR: Read kernel!\n");
+			return -1;
+		}
+		if (g_new_security)
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , KernelLoadAddress+64);
+		}
+		else
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , KernelLoadAddress);
+		}
+		NewArgc++;
+	}
+	if (NULL != pRootFsAddressInString)
+	{
+		RootfsLoadAddress = simple_strtol( pRootFsAddressInString , 0, 16);
+		RamFsLength = GetRamFsImageLength(RootfsLoadAddress);
+		if(0xffffffff == RamFsLength){
+			printf("%sERROR: Read Ramfs!\n%s",ColorRed,ColorNormal);
+			return -1;
+		}
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "rootfs" , RootfsLoadAddress, 64+RamFsLength+256 );
+		if ( 0 != ret )
+		{
+			printf("ERROR: Read rootfs!\n");
+			return -1;
+		}
+		if (g_new_security)
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , RootfsLoadAddress+64);
+		}
+		else
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , RootfsLoadAddress);
+		}
+		NewArgc++;
+	}
+	if (NULL != pBlobAddressInString)
+	{
+		BlobLoadAddress = simple_strtol( pBlobAddressInString , 0, 16);
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "blob" , BlobLoadAddress , 0xFFFFFFFF);
+		if ( 0 != ret )
+		{
+			printf("ERROR: Read blob!\n");
+			return -1;
+		}
+	}
+
+	if (1 == SecHWGetRSAEnable() )
+	{
+		//It is secure chip. go for decryption
+		if (g_new_security)
+		{
+			ret = CNC_DecryptImageIfRequired_New( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound, &ImageVersionNum );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Unable to decrypt CNC83xx image, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+			// anti-rollback control
+			if ( 0 > otp_read_version(&OTP_Version))
+			{
+				printf( "%s%sERROR: Unable to get OTP version, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+			if ( ImageVersionNum == OTP_Version + 1)
+			{
+				if (0 > otp_write_version(ImageVersionNum))
+				{
+					printf( "%s%sERROR: Unable to update OTP version, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+					return -1;
+				}
+			}
+			else if ( ImageVersionNum == OTP_Version )
+			{
+				// Version match.
+				//printf( "%sVersion Match: OTP version %d, image version %d.\n%s", ColorGreen, OTP_Version, ImageVersionNum, ColorNormal );
+			}
+			else
+			{
+				printf( "%sERROR: Invalid version of image, going to boot factory image.\n%s", ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+		else
+		{
+			ret = CNC_DecryptImageIfRequired( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Unable to decrypt CNC83xx image, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+	}
+	else
+	{
+		printf("%sUNSECURE 83XX found on your board%s\n", ColorYellow, ColorNormal);
+		if ( 0 == IsItEncryptedImage(KernelLoadAddress) )
+		{
+			ret = -1;
+			printf ("%sERROR: You are using UNSECURE Chip, in order to run secure software you need secure chip. Please contact Vendor\n%s", ColorRed, ColorWhite);
+#if (USE_SECURE_IMAGE_ON_NON_SECURE_PART)
+			printf ("%s%sWARNING: For Debug purpose only we will run secure image on unsecure chip\n%s" , BlinkOn , ColorRed, ColorWhite);
+			ret = CNC_DecryptImageIfRequired( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Unable to decrypt CNC83xx image, please contact vendor\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+#endif
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int LoadFailSafeImages(void)
+{
+	int		ret;
+	char* pKernelAddressInString=NULL;
+	char* pRootFsAddressInString=NULL;
+	char* pBlobAddressInString=NULL;
+	UInt32 KernelLoadAddress=0xFFFFFFFF;
+	UInt32 RootfsLoadAddress=0xFFFFFFFF;
+	UInt32 BlobLoadAddress=0xFFFFFFFF;
+	int EncryptedImageFound=0;
+	UInt32 KernelLength=0;
+	UInt32 RamFsLength=0;
+	UInt16 FailSafeImageVersionNum;
+	UInt16 OTP_Version;
+
+	printf("%sTrying to load fail-safe image\n%s", ColorYellow, ColorNormal);
+
+	pKernelAddressInString = getenv("kernel_load_addr");
+	printf("kernel_load_addr=%s\n",pKernelAddressInString);
+	pRootFsAddressInString = getenv("rootfs_load_addr");
+	printf("rootfs_load_addr=%s\n",pRootFsAddressInString);
+	pBlobAddressInString   = getenv("blob_load_addr");
+	printf("blob_load_addr=%s\n",pBlobAddressInString);
+
+	NewArgc = 0;
+	sprintf( NewArgvList[NewArgc] , "bootm");
+	NewArgc++;
+
+	if (NULL != pKernelAddressInString)
+	{
+		KernelLoadAddress = simple_strtol( pKernelAddressInString , 0, 16);
+		KernelLength = GetKernel_f_ImageLength(KernelLoadAddress);
+		if(0xffffffff == KernelLength){
+			printf("%sERROR: Read kernel_f!\n%s",ColorRed,ColorNormal);
+			return -1;
+		}
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "kernel_f" , KernelLoadAddress, 64+KernelLength+256 );
+		if ( 0 != ret )
+		{
+			return -1;
+		}
+		if (g_new_security)
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , KernelLoadAddress+64);
+		}
+		else
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , KernelLoadAddress);
+		}
+		NewArgc++;
+	}
+	if (NULL != pRootFsAddressInString)
+	{
+		RootfsLoadAddress = simple_strtol( pRootFsAddressInString , 0, 16);
+		RamFsLength = GetRamFs_f_ImageLength(RootfsLoadAddress);
+		if(0xffffffff == RamFsLength){
+			printf("%sERROR: Read Ramfs_f!\n%s",ColorRed,ColorNormal);
+			return -1;
+		}
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "rootfs_f" , RootfsLoadAddress, 64+RamFsLength+256 );
+		if ( 0 != ret )
+		{
+			return -1;
+		}
+		if (g_new_security)
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , RootfsLoadAddress+64);
+		}
+		else
+		{
+			sprintf( NewArgvList[NewArgc] , "0x%08X" , RootfsLoadAddress);
+		}
+		NewArgc++;
+	}
+	if (NULL != pBlobAddressInString)
+	{
+		BlobLoadAddress = simple_strtol( pBlobAddressInString , 0, 16);
+		ret = cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "blob" , BlobLoadAddress, 0xFFFFFFFF );
+		if ( 0 != ret )
+		{
+			return -1;
+		}
+	}
+
+	/* Check it SCS_ActivationBit is set before proceeding */
+	if (1 == SecHWGetRSAEnable() )
+	{
+		//It is secure chip. go for decryption
+		if (g_new_security)
+		{
+			ret = CNC_DecryptImageIfRequired_New( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound, &FailSafeImageVersionNum );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Error occured to decrypt CNC83xx image, please contact vendor\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+			// anti-rollback control
+			if ( 0 > otp_read_version(&OTP_Version))
+			{
+				printf( "%s%sERROR: Unable to get OTP version, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+			if ( ( FailSafeImageVersionNum == OTP_Version ) 
|| ( FailSafeImageVersionNum == OTP_Version - 1 ) )
+			{
+				// version match.
+				//printf( "%sVersion Match: OTP version %d, fail safe image version %d.\n%s", ColorGreen, OTP_Version, FailSafeImageVersionNum, ColorNormal );
+			}
+			else
+			{
+				printf( "%s%sERROR: Invalid version of factory image, please contact vendor.\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+		else
+		{
+			ret = CNC_DecryptImageIfRequired( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Error occured to decrypt CNC83xx image, please contact vendor\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+	}
+	else
+	{
+		printf("%sUNSECURE 83XX found on your board%s\n", ColorYellow, ColorNormal);
+		if ( 0 == IsItEncryptedImage(KernelLoadAddress) )
+		{
+			ret = -1;
+			printf ("%sERROR: You are using UNSECURE Chip, in order to run secure software you need secure chip. Please contact Vendor\n%s", ColorRed, ColorWhite);
+#if (USE_SECURE_IMAGE_ON_NON_SECURE_PART)
+			printf ("%s%sWARNING: For Debug purpose only we will run secure image on unsecure chip\n%s" , BlinkOn , ColorRed, ColorWhite);
+			ret = CNC_DecryptImageIfRequired( KernelLoadAddress, RootfsLoadAddress, BlobLoadAddress, &EncryptedImageFound );
+			if ( 0 != ret )
+			{
+				printf( "%s%sERROR: Error occured to decrypt CNC83xx image, please contact vendor\n%s", BlinkOn, ColorRed, ColorNormal );
+				return -1;
+			}
+#endif
+			return ret;
+		}
+	}
+	return 0;
+}
+
+void update_boot_image_flag(char flag)
+{
+	char *boot_image = getenv("boot_image");
+
+	if (flag == 0 && boot_image != NULL)
+	{
+		setenv("boot_image", NULL);
+		saveenv();
+	}
+	else if (flag == 1 && ( boot_image == NULL || boot_image[0] != '1' ) )
+	{
+		setenv("boot_image", "1");
+		saveenv();
+	}
+	else if (flag == 2 && ( boot_image == NULL || boot_image[0] != '2' ) )
+	{
+		setenv("boot_image", "2");
+		saveenv();
+	}
+
+	return;
+}
+
 /*******************************************************************/
 /* bootm - boot application image from image in memory */
 /*******************************************************************/
@@ -588,7 +1645,51 @@
 	ulong		iflag;
 	ulong		load_end = 0;
 	int		ret;
+	int i;
 	boot_os_fn	*boot_fn;
+	UInt32 Address=0;
+	Address=Address;
+	//char* pKernelAddressInString=NULL;
+	//char* pRootFsAddressInString=NULL;
+	//char* pBlobAddressInString=NULL;
+	//UInt32 KernelLoadAddress=0xFFFFFFFF;
+	//UInt32 RootfsLoadAddress=0xFFFFFFFF;
+	//UInt32 BlobLoadAddress=0xFFFFFFFF;
+
+	//TakeBackup of current args, arglist
+	for(i=0;i<3;i++)
+	{
+		NewArgv[i] = & NewArgvList[i][0];
+	}
+	//----
+
+	g_cnc_image_loaded = 0;
+	//For CNC - bootm is customized - bootm don't need any argument.
+	if ( 1 == argc )
+	{
+		if ( 0 == LoadCurrentImages() )
+		{
+			//Present new list. because by default bootm will not have any parameter for CNC
+			argv = NewArgv;
+			argc = NewArgc;
+			g_cnc_image_loaded = 1;
+			update_boot_image_flag(1);
+		}
+		else if ( 0 == LoadFailSafeImages() )
+		{
+			//Present new list. because by default bootm will not have any parameter for CNC
+			argv = NewArgv;
+			argc = NewArgc;
+			g_cnc_image_loaded = 2;
+			update_boot_image_flag(2);
+		}
+	}
+
+	if (argc > 1 )
+	{
+		Address = simple_strtoul(argv[1], NULL, 16);
+	}
+
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	static int relocated = 0;
 
@@ -603,9 +1704,9 @@
 #endif
 
 	/* determine if we have a sub command */
-	if (argc > 1) {
+	if (argc > 1)
+	{
 		char *endp;
-
 		simple_strtoul(argv[1], &endp, 16);
 		/* endp pointing to NULL means that argv[1] was just a
 		 * valid number, pass it along to the normal bootm processing
@@ -620,8 +1721,28 @@
 	}
 
 	if (bootm_start(cmdtp, flag, argc, argv))
-		return 1;
-
+	{
+		/*
+		 * when failed to boot up CNC non-secure image, load fail safe image and boot.
+		 */
+		if ( (1 == g_cnc_image_loaded) && (0 == LoadFailSafeImages()) )
+		{
+			//Present new list. because by default bootm will not have any parameter for CNC
+			argv = NewArgv;
+			argc = NewArgc;
+			update_boot_image_flag(2);
+			if (bootm_start(cmdtp, flag, argc, argv))
+			{
+				update_boot_image_flag(0);
+				return 1;
+			}
+		}
+		else
+		{
+			update_boot_image_flag(0);
+			return 1;
+		}
+	}
 	/*
 	 * We have reached the point of no return: we are going to
 	 * overwrite all exception vector code, so we cannot easily
@@ -651,10 +1772,10 @@
 			if (images.legacy_hdr_valid) {
 				if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
 					puts ("WARNING: legacy format multi component "
-						"image overwritten\n");
+							"image overwritten\n");
 			} else {
 				puts ("ERROR: new format image overwritten - "
-					"must RESET the board to recover\n");
+						"must RESET the board to recover\n");
 				show_boot_progress (-113);
 				do_reset (cmdtp, flag, argc, argv);
 			}
@@ -684,13 +1805,15 @@
 		fixup_silent_linux();
 #endif
 
+	fixup_bootargs_linux();
+
 	boot_fn = boot_os[images.os.os];
 
 	if (boot_fn == NULL) {
 		if (iflag)
 			enable_interrupts();
 		printf ("ERROR: booting os '%s' (%d) is not supported\n",
-			genimg_get_os_name(images.os.os), images.os.os);
+				genimg_get_os_name(images.os.os), images.os.os);
 		show_boot_progress (-8);
 		return 1;
 	}
@@ -708,6 +1831,12 @@
 	return 1;
 }
 
+int do_boots (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	g_new_security = 1;
+	return do_bootm(cmdtp, flag, argc, argv);
+}
+
 /**
  * image_get_kernel - verify legacy format kernel image
  * @img_addr: in RAM address of the legacy format image to be verified
@@ -742,11 +1871,13 @@
 
 	if (verify) {
 		puts ("   Verifying Checksum ... ");
+#if 0
 		if (!image_check_dcrc (hdr)) {
 			printf ("Bad Data CRC\n");
 			show_boot_progress (-3);
 			return NULL;
 		}
+#endif
 		puts ("OK\n");
 	}
 	show_boot_progress (4);
@@ -836,21 +1967,21 @@
 	/* find out kernel image address */
 	if (argc < 2) {
 		img_addr = load_addr;
-		debug ("*  kernel: default image load address = 0x%08lx\n",
+		debug_bootm ("*  kernel: default image load address = 0x%08lx\n",
 				load_addr);
 #if defined(CONFIG_FIT)
 	} else if (fit_parse_conf (argv[1], load_addr, &img_addr,
-							&fit_uname_config)) {
-		debug ("*  kernel: config '%s' from image at 0x%08lx\n",
+				&fit_uname_config)) {
+		debug_bootm ("*  kernel: config '%s' from image at 0x%08lx\n",
 				fit_uname_config, img_addr);
 	} else if (fit_parse_subimage (argv[1], load_addr, &img_addr,
-							&fit_uname_kernel)) {
-		debug ("*  kernel: subimage '%s' from image at 0x%08lx\n",
+				&fit_uname_kernel)) {
+		debug_bootm ("*  kernel: subimage '%s' from image at 0x%08lx\n",
 				fit_uname_kernel, img_addr);
 #endif
 	} else {
 		img_addr = simple_strtoul(argv[1], NULL, 16);
-		debug ("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
+		debug_bootm ("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
 	}
 
 	show_boot_progress (1);
@@ -861,160 +1992,167 @@
 	/* check image type, for FIT images get FIT kernel node */
 	*os_data = *os_len = 0;
 	switch (genimg_get_format ((void *)img_addr)) {
-	case IMAGE_FORMAT_LEGACY:
-		printf ("## Booting kernel from Legacy Image at %08lx ...\n",
-				img_addr);
-		hdr = image_get_kernel (img_addr, images->verify);
-		if (!hdr)
-			return NULL;
-		show_boot_progress (5);
+		case IMAGE_FORMAT_LEGACY:
+			printf ("## Booting kernel from Legacy Image at %08lx ...\n",
+					img_addr);
+			hdr = image_get_kernel (img_addr, images->verify);
+			if (!hdr)
+				return NULL;
+			show_boot_progress (5);
 
-		/* get os_data and os_len */
-		switch (image_get_type (hdr)) {
-		case IH_TYPE_KERNEL:
-			*os_data = image_get_data (hdr);
-			*os_len = image_get_data_size (hdr);
-			break;
-		case IH_TYPE_MULTI:
-			image_multi_getimg (hdr, 0, os_data, os_len);
-			break;
-		case IH_TYPE_STANDALONE:
-			*os_data = image_get_data (hdr);
-			*os_len = image_get_data_size (hdr);
-			break;
-		default:
-			printf ("Wrong Image Type for %s command\n", cmdtp->name);
-			show_boot_progress (-5);
-			return NULL;
-		}
+			/* get os_data and os_len */
+			switch (image_get_type (hdr)) {
+				case IH_TYPE_KERNEL:
+					*os_data = image_get_data (hdr);
+					*os_len = image_get_data_size (hdr);
+					break;
+				case IH_TYPE_MULTI:
+					image_multi_getimg (hdr, 0, os_data, os_len);
+					break;
+				case IH_TYPE_STANDALONE:
+					*os_data = image_get_data (hdr);
+					*os_len = image_get_data_size (hdr);
+					break;
+				default:
+					printf ("Wrong Image Type for %s command\n", cmdtp->name);
+					show_boot_progress (-5);
+					return NULL;
+			}
 
-		/*
-		 * copy image header to allow for image overwrites during kernel
-		 * decompression.
-		 */
-		memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
+			/*
+			 * copy image header to allow for image overwrites during kernel
+			 * decompression.
+			 */
+			memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
 
-		/* save pointer to image header */
-		images->legacy_hdr_os = hdr;
+			/* save pointer to image header */
+			images->legacy_hdr_os = hdr;
 
-		images->legacy_hdr_valid = 1;
-		show_boot_progress (6);
-		break;
+			images->legacy_hdr_valid = 1;
+			show_boot_progress (6);
+			break;
 #if defined(CONFIG_FIT)
-	case IMAGE_FORMAT_FIT:
-		fit_hdr = (void *)img_addr;
-		printf ("## Booting kernel from FIT Image at %08lx ...\n",
-				img_addr);
-
-		if (!fit_check_format (fit_hdr)) {
-			puts ("Bad FIT kernel image format!\n");
-			show_boot_progress (-100);
-			return NULL;
-		}
-		show_boot_progress (100);
-
-		if (!fit_uname_kernel) {
-			/*
-			 * no kernel image node unit name, try to get config
-			 * node first. If config unit node name is NULL
-			 * fit_conf_get_node() will try to find default config node
-			 */
-			show_boot_progress (101);
-			cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
-			if (cfg_noffset < 0) {
-				show_boot_progress (-101);
+		case IMAGE_FORMAT_FIT:
+			fit_hdr = (void *)img_addr;
+			printf ("## Booting kernel from FIT Image at %08lx ...\n",
+					img_addr);
+
+			if (!fit_check_format (fit_hdr)) {
+				puts ("Bad FIT kernel image format!\n");
+				show_boot_progress (-100);
 				return NULL;
 			}
-			/* save configuration uname provided in the first
-			 * bootm argument
-			 */
-			images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
-			printf ("   Using '%s' configuration\n", images->fit_uname_cfg);
-			show_boot_progress (103);
+			show_boot_progress (100);
 
-			os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
-			fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
-		} else {
-			/* get kernel component image node offset */
-			show_boot_progress (102);
-			os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel);
-		}
-		if (os_noffset < 0) {
-			show_boot_progress (-103);
-			return NULL;
-		}
+			if (!fit_uname_kernel) {
+				/*
+				 * no kernel image node unit name, try to get config
+				 * node first. If config unit node name is NULL
+				 * fit_conf_get_node() will try to find default config node
+				 */
+				show_boot_progress (101);
+				cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+				if (cfg_noffset < 0) {
+					show_boot_progress (-101);
+					return NULL;
+				}
+				/* save configuration uname provided in the first
+				 * bootm argument
+				 */
+				images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
+				printf ("   Using '%s' configuration\n", images->fit_uname_cfg);
+				show_boot_progress (103);
 
-		printf ("   Trying '%s' kernel subimage\n", fit_uname_kernel);
+				os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
+				fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
+			} else {
+				/* get kernel component image node offset */
+				show_boot_progress (102);
+				os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel);
+			}
+			if (os_noffset < 0) {
+				show_boot_progress (-103);
+				return NULL;
+			}
 
-		show_boot_progress (104);
-		if (!fit_check_kernel (fit_hdr, os_noffset, images->verify))
-			return NULL;
+			printf ("   Trying '%s' kernel subimage\n", fit_uname_kernel);
 
-		/* get kernel image data address and length */
-		if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) {
-			puts ("Could not find kernel subimage data!\n");
-			show_boot_progress (-107);
-			return NULL;
-		}
-		show_boot_progress (108);
+			show_boot_progress (104);
+			if (!fit_check_kernel (fit_hdr, os_noffset, images->verify))
+				return NULL;
 
-		*os_len = len;
-		*os_data = (ulong)data;
-		images->fit_hdr_os = fit_hdr;
-		images->fit_uname_os = fit_uname_kernel;
-		images->fit_noffset_os = os_noffset;
-		break;
+			/* get kernel image data address and length */
+			if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) {
+				puts ("Could not find kernel subimage data!\n");
+				show_boot_progress (-107);
+				return NULL;
+			}
+			show_boot_progress (108);
+
+			*os_len = len;
+			*os_data = (ulong)data;
+			images->fit_hdr_os = fit_hdr;
+			images->fit_uname_os = fit_uname_kernel;
+			images->fit_noffset_os = os_noffset;
+			break;
 #endif
-	default:
-		printf ("Wrong Image Format for %s command\n", cmdtp->name);
-		show_boot_progress (-108);
-		return NULL;
+		default:
+			printf ("Wrong Image Format for %s command\n", cmdtp->name);
+			show_boot_progress (-108);
+			return NULL;
 	}
 
-	debug ("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
+	debug_bootm ("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
 			*os_data, *os_len, *os_len);
 
 	return (void *)img_addr;
 }
 
 U_BOOT_CMD(
-	bootm,	CONFIG_SYS_MAXARGS,	1,	do_bootm,
-	"boot application image from memory",
-	"[addr [arg ...]]\n    - boot application image stored in memory\n"
-	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
-	"\t'arg' can be the address of an initrd image\n"
+		bootm,	CONFIG_SYS_MAXARGS,	1,	do_bootm,
+		"boot application image from memory",
+		"[addr [arg ...]]\n    - boot application image stored in memory\n"
+		"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
+		"\t'arg' can be the address of an initrd image\n"
 #if defined(CONFIG_OF_LIBFDT)
-	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
-	"\ta third argument is required which is the address of the\n"
-	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
-	"\tuse a '-' for the second argument. If you do not pass a third\n"
-	"\ta bd_info struct will be passed instead\n"
+		"\tWhen booting a Linux kernel which requires a flat device-tree\n"
+		"\ta third argument is required which is the address of the\n"
+		"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
+		"\tuse a '-' for the second argument. If you do not pass a third\n"
+		"\ta bd_info struct will be passed instead\n"
 #endif
 #if defined(CONFIG_FIT)
-	"\t\nFor the new multi component uImage format (FIT) addresses\n"
-	"\tmust be extened to include component or configuration unit name:\n"
-	"\taddr:<subimg_uname> - direct component image specification\n"
-	"\taddr#<conf_uname>   - configuration specification\n"
-	"\tUse iminfo command to get the list of existing component\n"
-	"\timages and configurations.\n"
-#endif
-	"\nSub-commands to do part of the bootm sequence.  The sub-commands "
-	"must be\n"
-	"issued in the order below (it's ok to not issue all sub-commands):\n"
-	"\tstart [addr [arg ...]]\n"
-	"\tloados  - load OS image\n"
+		"\t\nFor the new multi component uImage format (FIT) addresses\n"
+		"\tmust be extened to include component or configuration unit name:\n"
+		"\taddr:<subimg_uname> - direct component image specification\n"
+		"\taddr#<conf_uname>   - configuration specification\n"
+		"\tUse iminfo command to get the list of existing component\n"
+		"\timages and configurations.\n"
+#endif
+"\nSub-commands to do part of the bootm sequence.  The sub-commands "
+"must be\n"
+"issued in the order below (it's ok to not issue all sub-commands):\n"
+"\tstart [addr [arg ...]]\n"
+"\tloados  - load OS image\n"
 #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
-	"\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
+"\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
 #endif
 #if defined(CONFIG_OF_LIBFDT)
-	"\tfdt     - relocate flat device tree\n"
+"\tfdt     - relocate flat device tree\n"
 #endif
-	"\tcmdline - OS specific command line processing/setup\n"
-	"\tbdt     - OS specific bd_t processing\n"
-	"\tprep    - OS specific prep before relocation or go\n"
-	"\tgo      - start OS"
+"\tcmdline - OS specific command line processing/setup\n"
+"\tbdt     - OS specific bd_t processing\n"
+"\tprep    - OS specific prep before relocation or go\n"
+"\tgo      - start OS"
 );
 
+U_BOOT_CMD(
+		boots,	CONFIG_SYS_MAXARGS,	1,	do_boots,
+		"boot Cavium new secure image.\n",
+		"boot Cavium new secure image.\n"
+	  );
+
+
 /*******************************************************************/
 /* bootd - boot default image */
 /*******************************************************************/
@@ -1028,24 +2166,24 @@
 		rcode = 1;
 #else
 	if (parse_string_outer (getenv ("bootcmd"),
-			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
+				FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
 		rcode = 1;
 #endif
 	return rcode;
 }
 
 U_BOOT_CMD(
-	boot,	1,	1,	do_bootd,
-	"boot default, i.e., run 'bootcmd'",
-	""
-);
+		boot,	1,	1,	do_bootd,
+		"boot default, i.e., run 'bootcmd'",
+		""
+	  );
 
 /* keep old command name "bootd" for backward compatibility */
 U_BOOT_CMD(
-	bootd, 1,	1,	do_bootd,
-	"boot default, i.e., run 'bootcmd'",
-	""
-);
+		bootd, 1,	1,	do_bootd,
+		"boot default, i.e., run 'bootcmd'",
+		""
+	  );
 
 #endif
 
@@ -1079,61 +2217,61 @@
 	printf ("\n## Checking Image at %08lx ...\n", addr);
 
 	switch (genimg_get_format (hdr)) {
-	case IMAGE_FORMAT_LEGACY:
-		puts ("   Legacy image found\n");
-		if (!image_check_magic (hdr)) {
-			puts ("   Bad Magic Number\n");
-			return 1;
-		}
+		case IMAGE_FORMAT_LEGACY:
+			puts ("   Legacy image found\n");
+			if (!image_check_magic (hdr)) {
+				puts ("   Bad Magic Number\n");
+				return 1;
+			}
 
-		if (!image_check_hcrc (hdr)) {
-			puts ("   Bad Header Checksum\n");
-			return 1;
-		}
+			if (!image_check_hcrc (hdr)) {
+				puts ("   Bad Header Checksum\n");
+				return 1;
+			}
 
-		image_print_contents (hdr);
+			image_print_contents (hdr);
 
-		puts ("   Verifying Checksum ... ");
-		if (!image_check_dcrc (hdr)) {
-			puts ("   Bad Data CRC\n");
-			return 1;
-		}
-		puts ("OK\n");
-		return 0;
+			puts ("   Verifying Checksum ... ");
+			if (!image_check_dcrc (hdr)) {
+				puts ("   Bad Data CRC\n");
+				return 1;
+			}
+			puts ("OK\n");
+			return 0;
 #if defined(CONFIG_FIT)
-	case IMAGE_FORMAT_FIT:
-		puts ("   FIT image found\n");
+		case IMAGE_FORMAT_FIT:
+			puts ("   FIT image found\n");
 
-		if (!fit_check_format (hdr)) {
-			puts ("Bad FIT image format!\n");
-			return 1;
-		}
+			if (!fit_check_format (hdr)) {
+				puts ("Bad FIT image format!\n");
+				return 1;
+			}
 
-		fit_print_contents (hdr);
+			fit_print_contents (hdr);
 
-		if (!fit_all_image_check_hashes (hdr)) {
-			puts ("Bad hash in FIT image!\n");
-			return 1;
-		}
+			if (!fit_all_image_check_hashes (hdr)) {
+				puts ("Bad hash in FIT image!\n");
+				return 1;
+			}
 
-		return 0;
+			return 0;
 #endif
-	default:
-		puts ("Unknown image format!\n");
-		break;
+		default:
+			puts ("Unknown image format!\n");
+			break;
 	}
 
 	return 1;
 }
 
 U_BOOT_CMD(
-	iminfo,	CONFIG_SYS_MAXARGS,	1,	do_iminfo,
-	"print header information for application image",
-	"addr [addr ...]\n"
-	"    - print header information for application image starting at\n"
-	"      address 'addr' in memory; this includes verification of the\n"
-	"      image contents (magic number, header and payload checksums)"
-);
+		iminfo,	CONFIG_SYS_MAXARGS,	1,	do_iminfo,
+		"print header information for application image",
+		"addr [addr ...]\n"
+		"    - print header information for application image starting at\n"
+		"      address 'addr' in memory; this includes verification of the\n"
+		"      image contents (magic number, header and payload checksums)"
+	  );
 #endif
 
 
@@ -1148,7 +2286,7 @@
 	void *hdr;
 
 	for (i = 0, info = &flash_info[0];
-		i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
+			i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
 
 		if (info->flash_id == FLASH_UNKNOWN)
 			goto next_bank;
@@ -1159,31 +2297,31 @@
 				goto next_sector;
 
 			switch (genimg_get_format (hdr)) {
-			case IMAGE_FORMAT_LEGACY:
-				if (!image_check_hcrc (hdr))
-					goto next_sector;
-
-				printf ("Legacy Image at %08lX:\n", (ulong)hdr);
-				image_print_contents (hdr);
-
-				puts ("   Verifying Checksum ... ");
-				if (!image_check_dcrc (hdr)) {
-					puts ("Bad Data CRC\n");
-				} else {
-					puts ("OK\n");
-				}
-				break;
+				case IMAGE_FORMAT_LEGACY:
+					if (!image_check_hcrc (hdr))
+						goto next_sector;
+
+					printf ("Legacy Image at %08lX:\n", (ulong)hdr);
+					image_print_contents (hdr);
+
+					puts ("   Verifying Checksum ... ");
+					if (!image_check_dcrc (hdr)) {
+						puts ("Bad Data CRC\n");
+					} else {
+						puts ("OK\n");
+					}
+					break;
 #if defined(CONFIG_FIT)
-			case IMAGE_FORMAT_FIT:
-				if (!fit_check_format (hdr))
-					goto next_sector;
-
-				printf ("FIT Image at %08lX:\n", (ulong)hdr);
-				fit_print_contents (hdr);
-				break;
+				case IMAGE_FORMAT_FIT:
+					if (!fit_check_format (hdr))
+						goto next_sector;
+
+					printf ("FIT Image at %08lX:\n", (ulong)hdr);
+					fit_print_contents (hdr);
+					break;
 #endif
-			default:
-				goto next_sector;
+				default:
+					goto next_sector;
 			}
 
 next_sector:		;
@@ -1195,12 +2333,12 @@
 }
 
 U_BOOT_CMD(
-	imls,	1,		1,	do_imls,
-	"list all images found in flash",
-	"\n"
-	"    - Prints information about all images found at sector\n"
-	"      boundaries in flash."
-);
+		imls,	1,		1,	do_imls,
+		"list all images found in flash",
+		"\n"
+		"    - Prints information about all images found at sector\n"
+		"      boundaries in flash."
+	  );
 #endif
 
 /*******************************************************************/
@@ -1216,7 +2354,7 @@
 	if (!(gd->flags & GD_FLG_SILENT))
 		return;
 
-	debug ("before silent fix-up: %s\n", cmdline);
+	debug_bootm ("before silent fix-up: %s\n", cmdline);
 	if (cmdline) {
 		if ((start = strstr (cmdline, "console=")) != NULL) {
 			end = strchr (start, ' ');
@@ -1234,10 +2372,44 @@
 	}
 
 	setenv ("bootargs", buf);
-	debug ("after silent fix-up: %s\n", buf);
+	debug_bootm ("after silent fix-up: %s\n", buf);
 }
 #endif /* CONFIG_SILENT_CONSOLE */
 
+static void fixup_bootargs_linux ()
+{
+	char buf[1024], *start, *end;
+	char *cmdline = getenv ("bootargs");
+	char *ethbuff;
+
+	ethbuff = getenv("ethaddr");
+	if(ethbuff != NULL){
+
+		debug_bootm ("before add ethaddr fix-up: %s\n", cmdline);
+		if (cmdline) {
+			if ((start = strstr (cmdline, "ethaddr=")) != NULL) {
+				end = strchr (start, ' ');
+				strncpy (buf, cmdline, (start - cmdline + 8));
+				strcat(buf,ethbuff);
+				if (end){
+					strcpy (buf + (start - cmdline + 8+17), end);
+				}
+				else {
+					buf[start - cmdline + 8+17] = '\0';
+				}
+			} else {
+				strcpy (buf, cmdline);
+				strcat (buf, " ethaddr=");
+				strcat (buf, ethbuff);
+			}
+		} else {
+			strcpy (buf, "ethaddr=");
+			strcat(buf,ethbuff);
+		}
+		setenv ("bootargs", buf);
+		debug_bootm ("after add ethaddr fix-up: %s\n", buf);
+	}
+}
 
 /*******************************************************************/
 /* OS booting routines */
@@ -1245,7 +2417,7 @@
 
 #ifdef CONFIG_BOOTM_NETBSD
 static int do_bootm_netbsd (int flag, int argc, char * const argv[],
-			    bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	void (*loader)(bd_t *, image_header_t *, char *, char *);
 	image_header_t *os_hdr, *hdr;
@@ -1314,7 +2486,7 @@
 	loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
 
 	printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
-		(ulong)loader);
+			(ulong)loader);
 
 	show_boot_progress (15);
 
@@ -1333,7 +2505,7 @@
 
 #ifdef CONFIG_LYNXKDI
 static int do_bootm_lynxkdi (int flag, int argc, char * const argv[],
-			     bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	image_header_t *hdr = &images->legacy_hdr_os_copy;
 
@@ -1355,7 +2527,7 @@
 
 #ifdef CONFIG_BOOTM_RTEMS
 static int do_bootm_rtems (int flag, int argc, char * const argv[],
-			   bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	void (*entry_point)(bd_t *);
 
@@ -1372,7 +2544,7 @@
 	entry_point = (void (*)(bd_t *))images->ep;
 
 	printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
-		(ulong)entry_point);
+			(ulong)entry_point);
 
 	show_boot_progress (15);
 
@@ -1388,7 +2560,7 @@
 
 #if defined(CONFIG_BOOTM_OSE)
 static int do_bootm_ose (int flag, int argc, char * const argv[],
-			   bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	void (*entry_point)(void);
 
@@ -1405,7 +2577,7 @@
 	entry_point = (void (*)(void))images->ep;
 
 	printf ("## Transferring control to OSE (at address %08lx) ...\n",
-		(ulong)entry_point);
+			(ulong)entry_point);
 
 	show_boot_progress (15);
 
@@ -1421,7 +2593,7 @@
 
 #if defined(CONFIG_CMD_ELF)
 static int do_bootm_vxworks (int flag, int argc, char * const argv[],
-			     bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	char str[80];
 
@@ -1443,7 +2615,7 @@
 }
 
 static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
-			    bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	char *local_args[2];
 	char str[16];
@@ -1469,7 +2641,7 @@
 
 #ifdef CONFIG_INTEGRITY
 static int do_bootm_integrity (int flag, int argc, char * const argv[],
-			   bootm_headers_t *images)
+		bootm_headers_t *images)
 {
 	void (*entry_point)(void);
 
@@ -1486,7 +2658,7 @@
 	entry_point = (void (*)(void))images->ep;
 
 	printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n",
-		(ulong)entry_point);
+			(ulong)entry_point);
 
 	show_boot_progress (15);
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_boots.c u-boot-2011.06/common/cmd_boots.c
--- u-boot-2011.06_original/common/cmd_boots.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_boots.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1853 @@
+#if 0
+/*
+ *      @file   cmd_boots.c
+ *      @author Santosh Shukla <sshukla@mvista.com>
+ *      @date   Jan 2012
+ *
+ *      @brief  Command for booting secure kernels.
+ *
+ *      File contains 'boots' command and  'esp1800l_flash_util' tool.
+ *
+ *      'Boots' does image decryption and authentication for field, factory, and blob images
+ *      (reads data from NAND). Within this there is support for normal factory vs field
+ *      boot option, as well as pingpong_boot which allows for switching factory vs field
+ *      boot as images are upgraded.
+ *
+ *      esp1800l_flash_util: This is a helper function used to flash images that can be
+ *      decrypted/authenticated by 'boots'
+ *
+ *      Usage info for esp1800l_flash_util:
+ *
+ *      1. usb start; fatload usb 0 0x2100000 image.sbin
+ *
+ *      Default Field or Blob Image:
+ *      2. esp1800l_flash_util 0x2100000
+ *         esp1800l_flash_util --upgrade 0x2100000
+ *         esp1800l_flash_util --force   0x2100000
+ *
+ *      For Factory Image:
+ *      3. esp1800l_flash_util --factory 0x2100000
+ *         esp1800l_flash_util --factory --upgrade 0x2100000
+ *         esp1800l_flash_util --factory --force 0x2100000
+ *
+ */
+
+#include <common.h>
+#include <rsa_verify.h>
+#include <sha256.h>
+#include <asm/global_data.h>
+#include <asm/errno.h>
+#include <customer_specific_definitions.h>
+
+#include "cnc_util.h"
+
+
+extern unsigned accum_busy_wait_time;
+extern unsigned accum_page_read_time;
+extern unsigned accum_pgrd;
+extern unsigned accum_ecccalc;
+extern unsigned accum_correct;
+
+static void filter_bootargs(void);
+
+/*
+ * Global data (for the gd->relocaddr)
+ */
+DECLARE_GLOBAL_DATA_PTR;
+
+// #define DEBUG
+
+
+
+typedef struct __FlashImageInfo_t
+{
+	uint32_t mHdrType;                              // Sanity check of image before
+#define UBOOT_IDENTIFIER  (0x11223344)    		// fail-safe/factory uboot
+#define KERNEL_IDENTIFIER (0x87543223)    		// Fail-safe/factory kernel
+#define BLOB_IDENTIFIER   (0x22113344)    		// APP_SIG :: HDCP + DTCP + ...
+	// processing!
+	uint32_t mSourceAddressInFlash;
+	uint32_t mDestinationAddressInDram;
+	uint32_t mLength;                               // image len + image_signature len
+	uint32_t mSignLen;                              // size of signature len.
+	uint32_t mActiveImage;                          // for future use: could be factory
+	// or field type
+	char mVersionNo[256];                           // svn revision for Linux/u-boot
+	uint32_t mCrc32;                                // crc of ImageInfo_t header
+
+}FlashImageInfo_t;	// size of ImageInfo_t : 284 Byte
+
+
+/*
+ * Addresses in NAND
+ */
+
+/* Field headers  */
+#define CAVM18_FIELD_HDR_LEN			(128*1024)
+
+/* Factory headers */
+#define CAVM18_FACT_HDR_KERNEL_OFFSET		(0x1000)
+#define CAVM18_FACT_HDR_BLOB_OFFSET		(0x2000)
+#define CAVM18_FACT_HDR_LEN			(128*1024)
+
+/* Blob headers */
+#define CAVM18_BLOB_HDR_OLD_FLSH_ADDR		(0x003e0000) // 1k: Blob
+#define CAVM18_BLOB_HDR_LEN			(0x1000)
+
+#define SECTOR_SIZE	(128*1024) /* 128K sector size */
+
+/*
+ * DRAM addresses
+ */
+#define CAVM18_FIELD_HDR_DRAM_ADDR		0x06000000
+#define CAVM18_FACT_HDR_DRAM_ADDR		0x02000000
+
+/* Crypto Engine Out DDR Address  */
+#define CRYPTO_OUT_KERNEL_DRAM_ADDR	0x08080000 // Size 32MByte range - 0x8080000 to 0xa080000
+#define MAX_KERNEL_IMAGE_SIZE           0x2000000  // 32 MB
+
+/* image header workspace */
+#define HEADER_DRAM_ADDR		0x5000000
+#define HEADER_DRAM_SIZE		0x2000
+
+#define READ_BACK_IMAGE_RAM_ADDR	0x6000000 // Image copy to ddr - imglen could be < 32Mbyte
+/* ImageInfo look-up table for all image types */
+FlashImageInfo_t FlashImgHdr[5] = {
+	/*	Img_Sig	           SrcFlashAddr DstRAMAddr Img_len  sig_len ActImg   SVN Rev CRC Dummy  */
+	{ BLOB_IDENTIFIER,                                      /* image type */
+		(CAVM18_BLOB_HDR_FLSH_ADDR + CAVM18_BLOB_HDR_LEN),   /* source address in flash */
+		0x08000000,                                           /* destination address in RAM */
+		0,                                                    /* image length */
+		0,                                                    /* signature length */
+		1,                                                    /* 1 = field, 0 = factory */
+		"",                                                   /* version information */
+		0 },                                                  /* CRC32 */
+
+	{ KERNEL_IDENTIFIER,
+		FACTORY_KERNEL_FLASH_ADDR,
+		0x06020000,
+		0,
+		0,
+		0,
+		"",
+		0 }, /* For Fact Kernel: Active Img */
+
+	{ KERNEL_IDENTIFIER,
+		FIELD_KERNEL_FLASH_ADDR,
+		0x06020000,
+		0,
+		0,
+		1,
+		"",
+		0 }, /* For Field kernel : Active Img */
+
+	{ UBOOT_IDENTIFIER,
+		FACTORY_UBOOT_FLASH_ADDR,
+		0x06020000,
+		0,
+		0,
+		0,
+		"",
+		0 }, /* For Fact Uboot */
+
+	{ UBOOT_IDENTIFIER,
+		FIELD_UBOOT_FLASH_ADDR,
+		0x06020000,
+		0,
+		0,
+		1,
+		"",
+		0 } /* For Field uboot */
+
+};
+
+extern int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+
+enum {
+	encrypt,
+	decrypt
+} CryptoType;
+
+enum {
+	keyA,
+	keyB
+} CryptoKeyType;
+
+
+/*
+ * Decrypt aSrcAddr Image to
+ * 		crypto DECRYPT_AES128_CIPlus chl1 0x5000000 0x7000000 0x1600000
+ *
+ * 	Encrypt aSrcAddr Image to
+ * 		crypto ENCRYPT_AES128_CIPlus chl1 0x5000000 0x7000000 0x1600000
+ */
+int Sec1800l_crypto(uint32_t aSrcAddr, uint32_t alen, uint32_t aDstAddr, uint8_t key_flag, uint8_t crypto_type)
+{
+	char* pCmd[] = {"crypto", NULL, NULL, NULL, NULL, NULL, NULL};
+	char TempCmd1[32];
+	char TempCmd2[16];
+	char TempCmd3[16];
+	char TempCmd4[16];
+	char TempCmd5[16];
+	char TempCmd6[16];
+
+	int status=0;
+
+	if (crypto_type == 0) { // aes-128-cbc encryption
+
+		sprintf(TempCmd1 , "ENCRYPT_AES128_CIPlus");
+		sprintf(TempCmd2 , "chl2");
+	} else if (crypto_type == 1) { // decryption
+
+		sprintf(TempCmd1 , "DECRYPT_AES128_CIPlus");
+		sprintf(TempCmd2 , "chl1");
+	} else {
+
+		printf (" Invalid crypto_type .. exiting \n");
+		return -1;
+	}
+
+	sprintf(TempCmd3 , "0x%x", aSrcAddr);
+	sprintf(TempCmd4 , "0x%x", aDstAddr);
+	sprintf(TempCmd5 , "0x%x", alen); // $(filesize)
+	sprintf(TempCmd6 , "0x%x", key_flag);
+
+	debug (" Crypto : Crypto_Type : %s Channel : %s Src_Addr : %s, Dst_Addr : %s, Img_Len : %s, key_flag : %s\n", \
+			TempCmd1, TempCmd2, TempCmd3, TempCmd4, TempCmd5, TempCmd6);
+
+	pCmd[1] =  TempCmd1; pCmd[2] =  TempCmd2; pCmd[3] =  TempCmd3; pCmd[4] = TempCmd4; pCmd[5] = TempCmd5;
+	pCmd[6] = TempCmd6;
+
+	status = do_crypto(NULL, 0, 7, pCmd);
+
+	if ( 0 != status )
+	{
+		printf("ERROR: fail to Decrypt! (%d)\n", status);
+	}
+
+	return status;
+}
+
+void Sec1800l_BootM(uint32_t abootAddress)
+{
+	char* pCmd[] = {"bootm", NULL, NULL};
+	char TempCmd1[16];
+
+	sprintf(TempCmd1 , "0x%x", abootAddress);
+
+	pCmd[1] =  TempCmd1;
+
+	debug (" bootm addr : %s :: %s\n", pCmd[1], TempCmd1);
+
+	do_bootm(NULL, 0,2, pCmd); //FIXME : do_bootm 3rd arg- takes val 1 .. not working, Works fine for 2
+
+	return;
+}
+
+
+
+static int nandWriteError = 0;
+
+
+#include <u-boot/md5.h>
+
+static int sec1800l_md5sum(uint32_t aImgDramAddr,  uint32_t aImgLen, char *cmp_md5sum)
+{
+	int status = 0;
+	//unsigned char output[16];
+	unsigned char output[16];
+	uint32_t md5_offset = aImgLen;
+	register int j;
+
+	unsigned char *temp_md5buf = (unsigned char *) aImgDramAddr;
+
+	md5(temp_md5buf, md5_offset, output);
+
+#if 0
+	printf (" %s : MD5SUM ... \n", __FUNCTION__);
+	int i;
+	for (i=0; i<16; i++) {
+
+		if (i%8 == 0)
+			printf ("\n");
+
+		printf (" %02x", (unsigned char)output[i]);
+	}
+#endif
+
+	if (memcmp (output, cmp_md5sum, 16) != 0) {
+
+		status = -1;
+		printf(" Invalid Md5sum:\n\texpected");
+		for (j = 0; j < 16; ++j) { printf(" %02X", cmp_md5sum[j]); }
+		printf("\n\tcomputed");
+		for (j = 0; j < 16; ++j) { printf(" %02X", output[j]); }
+		printf("\n on %u bytes of data at memory address 0x%08x\n", aImgLen, aImgDramAddr);
+	}
+
+	return status;
+}
+
+#if defined(CONFIG_CMD_BOOTD)
+
+static int Crypto_Command(uint32_t source, uint32_t dest, uint32_t leng)
+{
+	char sa[16], da[16], le[16], *c[5];
+	sprintf(sa, "0x%08x", source);
+	sprintf(da, "0x%08x", dest);
+	sprintf(le, "0x%08x", leng);
+	c[0] = "read_decrypt"; c[1] = &sa[0]; c[2] = &da[0]; c[3] = &le[0]; c[4] = NULL;
+	return do_crypto(NULL, 0, 4, &c[0]);
+}
+
+static int do_crypto_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char *cmdptr[5];
+
+	if ( argc != 4) {
+		return cmd_usage(cmdtp);
+	}
+
+	cmdptr[0] = "read_decrypt";
+	cmdptr[1] = argv[1];
+	cmdptr[2] = argv[2];
+	cmdptr[3] = argv[3];
+	cmdptr[4] = NULL;
+	return do_crypto(NULL, 0, 4, &cmdptr[0]);
+}
+
+U_BOOT_CMD (
+		cryptotest ,        4,      1,      do_crypto_test,
+		"execute decrypt/encrypt cycle on memory\n",
+		"\tcryptotest source-address dest-address amount\n"
+	   );
+
+/*
+ * Do Image Decryption on crypto channel: stream mode, algo : aes-128-cbc
+ */
+int Img_Crypto ( uint32_t crypto_inLoc, uint32_t len, uint32_t crypto_outLoc, uint8_t key_flag, uint8_t crypto_type)
+{
+	/* Img Decryption */
+	if( Sec1800l_crypto(crypto_inLoc, len, crypto_outLoc, key_flag, crypto_type) != 0) {
+
+		printf (" decryption failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void hex_print (uint8_t *buff, uint32_t len)
+{
+	uint32_t cnt = 0;
+	for (cnt = 0; cnt < len; cnt++)
+		debug (" %02x", buff[cnt]);
+	debug ("\n");
+}
+
+
+/*
+ *	Decrypt and Authenticate an image for Kernel (Factory only) or blob.
+ */
+int Img_Authenticate (FlashImageInfo_t *hdr_p, int distImgType)
+{
+	char *ImgName = NULL;
+
+	uint32_t chk_crc32;
+	uint32_t crypto_outLoc;
+	uint8_t hash[32];
+	uint8_t inhash[32];
+	uint32_t Img_Len;
+	uint32_t Hash_Buf_Offset;
+	int val;
+
+	if (distImgType == 0) { // App Img
+
+		ImgName = "Blob";
+		crypto_outLoc = CRYPTO_OUT_BLOB_LINUX_ADDR;
+	} else {
+
+		ImgName = "Application";
+		crypto_outLoc = CRYPTO_OUT_KERNEL_DRAM_ADDR;
+	}
+#if 0
+	debug (" %s Hdr info : \n", ImgName);
+	debug (" mHdrType : 0x%x mSourceAddressInFlash : 0x%x mDestinationAddressInDram : 0x%x \
+			image mLength : %d siglen : %d ActiveImage flag : %d 		\
+			mVersion : %s Crc32 : 0x%x \n", hdr_p->mHdrType, hdr_p->mSourceAddressInFlash,
+			hdr_p->mDestinationAddressInDram, hdr_p->mLength,
+			hdr_p->mSignLen, hdr_p->mActiveImage,
+			hdr_p->mVersionNo, hdr_p->mCrc32);
+#endif
+
+	if (hdr_p->mHdrType == BLOB_IDENTIFIER ||
+			hdr_p->mHdrType == KERNEL_IDENTIFIER) {
+
+		debug (" Valid : %s Hdr Identifier \n", ImgName);
+
+		debug (" %s Header crc ...\n", ImgName);
+
+		chk_crc32 = crc32 (0, (unsigned char *)hdr_p, sizeof (FlashImageInfo_t) - 4);
+
+		if (chk_crc32 == hdr_p->mCrc32) {
+
+			printf (" Processing %s image.\n", ImgName);
+
+			unsigned int TotalLen = hdr_p->mLength + hdr_p->mSignLen;
+			TotalLen = SECTOR_SIZE * ( (TotalLen + SECTOR_SIZE -1) / SECTOR_SIZE ) ;
+
+			debug (" %s aligned len : %d\n", ImgName, TotalLen);
+
+			/* step 4. netHDImg2 from Nand block to 0x0240_0000 */
+			if ( cnc_NandRead(hdr_p->mSourceAddressInFlash,
+									hdr_p->mDestinationAddressInDram,						
+									TotalLen) != 0 
+				)
+			{
+				printf (" Failed to read %s!\n", ImgName);
+				return -1;
+			}
+
+
+			/* remove 32 byte Hash offset from mLength : use Img_Len for actual Img enc/dec now onwards */
+			Img_Len =  hdr_p->mLength-32;
+			debug (" Img_Len : %d\n", Img_Len);
+
+			/* back_up the 32 byte of i/p hash */
+			memcpy (inhash, (uint8_t *)(hdr_p->mDestinationAddressInDram + Img_Len), 32);
+			debug ("\n input hash dump: "); hex_print (inhash, 32);
+
+			/* 2nd pass decryption for keyB :: o/p : plain_text Img */
+			if (Img_Crypto (hdr_p->mDestinationAddressInDram, Img_Len , crypto_outLoc, keyB, decrypt) != 0) {
+				/* Flush out decryted Kernel/Blob Image with zero */
+				memset ((uint8_t *)crypto_outLoc, 0x0, hdr_p->mLength);
+				return -1;
+			}
+
+			/* loop-back output as input;
+			   do encryption to retrieve 1st pass hash of 16 byte; using keyA */
+			if (Img_Crypto (crypto_outLoc, Img_Len , hdr_p->mDestinationAddressInDram, keyA, encrypt) != 0) {
+				/* Flush out decryted Kernel/Blob Image with zero */
+				memset ((uint8_t *)crypto_outLoc, 0x0, hdr_p->mLength);
+				return -1;
+			}
+
+			/* flush hash buf */
+			memset (hash, 0x0, sizeof (hash));
+
+			/* jump to last 16 byte offset for 1st pass Hash record */
+			Hash_Buf_Offset = (hdr_p->mDestinationAddressInDram + (Img_Len -16) );
+
+			/* copy last 16byte hash store in local hash bufffer */
+			memcpy (hash, (uint8_t *)( Hash_Buf_Offset), 16);
+			debug ("\n 1st pass hash dump (16byte): "); hex_print (hash, 16);
+
+			/* copy inhash's last 26 byte (keyB) into hash last 16 byte index */
+			memcpy (hash+16, (inhash + 16), 16);
+
+			debug ("\n 2nd Encryption pass hash dump (16byte): "); hex_print (hash+16, 16);
+
+			debug ("\n 1st/2nd encryption pass hash dump (32 byte): "); hex_print (hash, 32);
+
+			/* compare 32 byte has with input Image */
+			if (memcmp(hash, inhash, 32) != 0) {
+
+				printf ("Error : Hashing failure!\n");
+
+				/* Flush out decryted Kernel/Blob Image with zero */
+				memset ((uint8_t *)crypto_outLoc, 0x0, hdr_p->mLength);
+				return -1;
+			}
+
+			/* rsa verify i/p : hash (32 byte :: keyA enc hash(16 byte)| keyB enc hash(16 byte) )
+			   i/p : 256 byte Image signature
+			   */
+			if (hdr_p->mHdrType == BLOB_IDENTIFIER) {
+				val = Cnc_ImgHybRsa_Verify (hash, (hdr_p->mDestinationAddressInDram + hdr_p->mLength), blob_pkey);
+			} else  {
+				val = Cnc_ImgHybRsa_Verify (hash, (hdr_p->mDestinationAddressInDram + hdr_p->mLength), pkey);
+			}
+
+			if (val != 0) {
+
+				/* Flush out decryted Kernel/Blob Image with zero */
+				memset ((uint8_t *)crypto_outLoc, 0x0, hdr_p->mLength);
+				return -1;
+			}
+
+		} else {
+
+			printf (" Invalid %s header CRC! Header corrupt! \n", ImgName);
+			return -1;
+		}
+
+	} else {
+
+		printf (" Invalid %s header signature!\n", ImgName);
+		return -1;
+	}
+
+#ifdef DEBUG_BLOB_FAIL
+	if (distImgType == 0)
+		return -1;
+#endif
+
+	return 0;
+}
+
+uint64_t read_free_running_clock(void)
+{
+	uint64_t ret;
+	uint32_t lo1, hi1, lo2, hi2;
+
+	/* Read twice so we can check for rollover between low and
+	   high reads. */
+	lo1 = *((volatile uint32_t *)0x80270020);
+	hi1 = *((volatile uint32_t *)0x80270024);
+	lo2 = *((volatile uint32_t *)0x80270020);
+	hi2 = *((volatile uint32_t *)0x80270024);
+
+	ret = (uint64_t) ((lo2 >= lo1)? hi1 : hi2);
+	ret <<= 32;
+	ret |= lo2;
+	return ret;
+}
+
+unsigned measure_time_ms(uint64_t *marker)
+{
+	uint64_t prev, delta, q; unsigned ret = 0u;
+	prev = *marker; *marker = read_free_running_clock();
+	delta = *marker - prev;
+	/* Free running clock ticks at 94.5 MHz = 10.6 ns */
+	q = (delta*10ull + 477ull)/954ull;
+	ret = (unsigned)q;
+	return ret;
+}
+
+static int do_timexfer(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t SA, DA, LNG, count, elapsed = 0, rate;
+	uint64_t marker = 0ull, scratch, scratch2;
+	uint32_t *d;
+	const uint32_t *s;
+
+	/* Usage: timexfer source dest count */
+	if ( argc != 4) {
+		return cmd_usage(cmdtp);
+	}
+
+	SA = simple_strtoul(argv[1], NULL, 16);
+	DA = simple_strtoul(argv[2], NULL, 16);
+	LNG = simple_strtoul(argv[3], NULL, 16);
+
+	if ( (SA <= DA && DA < SA + LNG) || (DA <= SA && SA < DA + LNG) ) {
+		printf("Overlapping regions not allowed.\n");
+		return 1;
+	}
+
+	if ( (SA & 3) != 0 || (DA & 3) != 0 || (LNG & 3) != 0 ) {
+		printf("Addresses and lengths must be 32-bit aligned\n");
+		return 1;
+	}
+
+	s = (const uint32_t *)SA;
+	d = (uint32_t *)DA;
+	count = LNG >> 2;
+
+	elapsed = measure_time_ms(&marker);
+	while (count != 0) {
+		*d++ = *s++;
+		--count;
+	}
+	elapsed = measure_time_ms(&marker);
+	if (elapsed == 0u) {
+		printf("cannot determine elapsed time!\n");
+		return 1;
+	}
+	scratch = (uint64_t)elapsed;
+	scratch2 = (uint64_t)LNG;
+	scratch2 *= 1000000ull;
+	scratch2 /= scratch;
+	rate = (uint32_t)scratch2;
+
+	printf("Time to xfer %u bytes: %u usec (%u bytes/sec)\n", LNG, elapsed, rate);
+
+	return 0;
+}
+
+U_BOOT_CMD (
+		timexfer ,        4,      1,      do_timexfer,
+		"time memory transfer\n",
+		"\ttimexfer source-address dest-address amount\n"
+	   );
+
+static void filter_bootargs(void)
+{
+	char *cmdline = NULL;
+	char *temp = NULL;
+	char newCmdLine[256];
+
+	newCmdLine[0] = '\0';
+
+	if ((cmdline = getenv("bootargs")) != NULL) {
+		debug (" %s : %d\n", cmdline, strlen(cmdline));
+
+		/* Check for valid arguments */
+		temp = strstr(cmdline, "console=ttyS0,115200");
+		if (temp) {
+			strncat(newCmdLine, temp, strlen("console=ttyS0,115200"));
+			strcat(newCmdLine, " ");
+		}
+		temp = strstr(cmdline, "nousb");
+		if (temp) {
+			strncat(newCmdLine, temp, strlen("nousb"));
+			strcat(newCmdLine, " ");
+		}
+		temp = strstr(cmdline, "quiet");
+		if (temp) {
+			strncat(newCmdLine, temp, strlen("quiet"));
+			strcat(newCmdLine, " ");
+		}
+		temp = strstr(cmdline, "outputmode=");
+		if (temp) {
+			strncat(newCmdLine, temp, strlen("outputmode=xx"));
+			if ((temp[12] < '0') || (temp[12] > '9'))
+				newCmdLine[strlen(newCmdLine)-1] = '\0'; /* single digit outputmode */
+			strcat(newCmdLine, " ");
+		}
+		temp = strstr(cmdline, "colorformat=");
+		if (temp) {
+			strncat(newCmdLine, temp, strlen("colorformat=x"));
+			strcat(newCmdLine, " ");
+		}
+
+		/* set bootargs with the filtered cmdline */
+		setenv("bootargs", newCmdLine);
+
+		debug (" filtered command line [%s]\n", newCmdLine);
+	}
+}
+
+/*
+ * Boots, does image authentication for kernel / secure blob Image,
+ * accordingly boots kernel.
+ * */
+static int do_boots (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	FlashImageInfo_t *kernelImgHdr;
+	FlashImageInfo_t *fact_kernelImgHdr;
+	FlashImageInfo_t *blobImgHdr;
+	char *ImgName = "Application";
+	//uint32_t RegVal = 0;
+	uint32_t fail_safe_flag = 0;
+
+	uint8_t hash[32];
+	uint8_t inhash[32];
+	uint32_t Img_Len;
+	uint32_t Hash_Buf_Offset;
+	int val, retry_count=2;
+
+	uint32_t mtd_part = 0;
+#ifdef MEASURE_CRYPTO
+	uint64_t total_time_marker = 0ull, crypto_marker = 0ull;
+	i	unsigned total_elapsed = 0, crypto_elapsed = 0, dontcare = 0 /* , part1_elapsed = 0, part2_elapsed = 0 */ ;
+#endif
+
+	if( argc > 1 )
+		return cmd_usage(cmdtp);
+
+	/* Check it SCS_ActivationBit is set before proceeding */
+	if (!SecHWGetRSAEnable()) {
+		printf (" Invalid chip for Secure boot mode.\n");
+#ifdef CHECK_SECURE_CHIP
+		return -1;
+#endif
+	} else {
+		debug (" Boot operational state : Secure Mode \n");
+	}
+
+	/*
+	 * 	Field Img2 Hdr parsing...
+	 *	1. Nand read frm 0x057c_0000 to Ram addr 0x0400_0000
+	 */
+
+	/* step 1.1 copy field hdr from flash to Dram */
+	if ( cnc_NandRead(CAVM18_FIELD_KENREL_HDR_FLSH_ADDR,
+							CAVM18_FIELD_HDR_DRAM_ADDR,				
+							CAVM18_FIELD_HDR_LEN) != 0 
+		)
+	{
+		printf (" Failed to read image 2 header! Jump to image1 Hdr\n");
+		goto FAIL_SAFE_HDR;
+	}
+
+	/*
+	 *	step 2.1 populate ImgHdr.mCavmUbootImage2 & ImgHdr.mCavmNetHDImage2
+	 *	Copy Field Hdrs i.e Uboot2/netHD2_Img from DRAM location 0x0400_0000 into ImgHdr
+	 */
+	kernelImgHdr = (FlashImageInfo_t *)CAVM18_FIELD_HDR_DRAM_ADDR;
+
+	/* step 2.1.1 Dump content of RXVD netHD2 Img */
+	debug (" Field Hdr info ....\n\n");
+
+	debug (" netHDImage \n");
+	debug (" mHdrType : 0x%x mSourceAddressInFlash : 0x%x mDestinationAddressInDram : 0x%x \
+			Field image mLength : %d siglen : %d ActiveImage flag : %d          \
+			mVersion : %s Crc32 : 0x%x \n", kernelImgHdr->mHdrType,
+			kernelImgHdr->mSourceAddressInFlash ,
+			kernelImgHdr->mDestinationAddressInDram,
+			kernelImgHdr->mLength,
+			kernelImgHdr->mSignLen, kernelImgHdr->mActiveImage,
+			kernelImgHdr->mVersionNo, kernelImgHdr->mCrc32);
+
+FAIL_SAFE_HDR:
+	/*
+	   step 1.2 copy fact hdr from flash to Dram !!! Optional .. can be changed ...
+	   Only used while Fact Img parsing ....
+	   */
+	if ( cnc_NandRead(CAVM18_FACT_HDR_FLSH_ADDR,
+				CAVM18_FACT_HDR_DRAM_ADDR,				
+				CAVM18_FACT_HDR_LEN) != 0 )
+	{
+
+		printf (" Failed to read image 1 Header! .. exiting!!\n");
+		return -1;
+	}
+
+	/*
+	 *	step 1.2 copy blob hdr from flash to Dram !!!
+	 *
+	 */
+	if ( cnc_NandRead(CAVM18_BLOB_HDR_FLSH_ADDR,
+				CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_BLOB_OFFSET,				
+				CAVM18_BLOB_HDR_LEN) != 0 )
+	{
+
+		printf (" Failed to read blob Header! .. exiting!!\n");
+		return -1;
+	}
+
+	/*
+	 *	step 2.2 populate ImgHdr.mCavmUbootImage2 & ImgHdr.mCavmNetHDImage2
+	 *	Copy Field Hdrs i.e Uboot2/netHD2_Img from DRAM location 0x0400_0000 into ImgHdr
+	 */
+
+	/* skip uboot header at offset 0x0000 */
+
+	/* point to Factory hdr offset */
+	fact_kernelImgHdr = (FlashImageInfo_t *)(CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_KERNEL_OFFSET);
+
+	unsigned int chk_crc32;
+
+	char *s = getenv ("pingpong_boot");
+	int pingpong_boot = (s && (*s == 'y')) ? 1 : 0;
+
+	if (pingpong_boot == 1) {
+
+		debug (" Skloading Type : ping-pong ...\n");
+		/*    Chk factory Img Hdr is next bootable kernel ; then FLIP the order such that
+		      field img Hdr (kernelImgHdr) take hdr info for Factory hdr(next bootable one)
+		      and factory hdr has field ImageInfo.
+
+		      Else skloader flow is as is i.e...
+		      */
+		if (fact_kernelImgHdr->mActiveImage == 1) {
+
+			debug (" Flip order for field to factory Img \n");
+
+			/* point field header at factory header */
+			kernelImgHdr = (FlashImageInfo_t *)(CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_KERNEL_OFFSET);
+
+			/* and vice versa */
+			fact_kernelImgHdr = (FlashImageInfo_t *)CAVM18_FIELD_HDR_DRAM_ADDR;
+		}
+
+	} else {
+
+		debug (" Skloading Type : default ...\n");
+	}
+
+
+	/* step 3. Do Parsing of field Img hdr */
+	if (kernelImgHdr->mHdrType == KERNEL_IDENTIFIER) { // Field Img
+
+		debug (" Valid : Field Hdr netHDImg identifier \n");
+
+		debug (" Field Header netHDImg crc ...");
+
+		chk_crc32 = crc32 (0, (unsigned char *)kernelImgHdr, sizeof (FlashImageInfo_t) - 4);
+
+		if (chk_crc32 == kernelImgHdr->mCrc32) {
+
+			printf (" Processing %s image.\n", ImgName);
+
+			unsigned int TotalLen = kernelImgHdr->mLength + kernelImgHdr->mSignLen;
+			TotalLen = SECTOR_SIZE * ( (TotalLen + SECTOR_SIZE -1) / SECTOR_SIZE );
+
+			/* debug (" netHDImg aligned len : %d\n", TotalLen); */
+
+			debug (" processing of image about to start .. \n");
+
+			/* step 4. netHDImg2 from Nand block to 0x0240_0000 */
+#ifdef MEASURE_CRYPTO
+			dontcare = measure_time_ms(&total_time_marker);
+			accum_busy_wait_time = 0;
+			accum_page_read_time = 0;
+			accum_pgrd = 0;
+			accum_ecccalc = 0;
+			accum_correct = 0;
+#endif
+			if ( cnc_NandRead(kernelImgHdr->mSourceAddressInFlash,
+						kernelImgHdr->mDestinationAddressInDram,						
+						TotalLen) != 0 )
+			{
+
+				printf (" Failed to read %s image!\n", ImgName);
+				fail_safe_flag = 1;
+				goto FAIL_SAFE;
+			}
+
+			/* remove 32 byte Hash offset from mLength : use Img_Len for actual Img enc/dec now onwards */
+			Img_Len =  kernelImgHdr->mLength-32;
+			debug (" Img_Len : %d\n", Img_Len);
+
+			if (Img_Len > MAX_KERNEL_IMAGE_SIZE) {
+				fail_safe_flag = 1;
+				goto FAIL_SAFE;
+			}
+
+			/* back_up the 32 byte of i/p hash */
+			memset (inhash, 0x0, sizeof (inhash));
+			memcpy (inhash, (uint8_t *)(kernelImgHdr->mDestinationAddressInDram + Img_Len), 32);
+			debug ("\n input Img hash dump: "); hex_print (inhash, 32);
+
+#ifdef MEASURE_CRYPTO
+			i			dontcare = measure_time_ms(&crypto_marker);
+			/* 2nd pass decryption for keyB :: o/p : plain_text Img */
+			if (Img_Crypto (kernelImgHdr->mDestinationAddressInDram, Img_Len , CRYPTO_OUT_KERNEL_DRAM_ADDR, keyB, decrypt) != 0) {
+				fail_safe_flag = 1;
+				goto FAIL_SAFE;
+			}
+			part1_elapsed = measure_time_ms(&crypto_marker);
+			crypto_elapsed += part1_elapsed;
+
+			/* loop-back output as input;
+			   do encryption to retrieve 1st pass hash of 16 byte; using keyA*/
+			if (Img_Crypto (CRYPTO_OUT_KERNEL_DRAM_ADDR, Img_Len , kernelImgHdr->mDestinationAddressInDram, keyA, encrypt) != 0) {
+				fail_safe_flag = 1;
+				goto FAIL_SAFE;
+			}
+#else
+			if (Crypto_Command(kernelImgHdr->mDestinationAddressInDram, CRYPTO_OUT_KERNEL_DRAM_ADDR, Img_Len) != 0) {
+				fail_safe_flag = 1;
+				goto FAIL_SAFE;
+			}
+#endif
+
+#ifdef MEASURE_CRYPTO
+			// part2_elapsed = measure_time_ms(&crypto_marker);
+			// crypto_elapsed += part2_elapsed;
+			crypto_elapsed = measure_time_ms(&crypto_marker);
+			total_elapsed = measure_time_ms(&total_time_marker);
+
+			printf("\n\n\n*** total elapsed time = %u usec\n", total_elapsed);
+			printf("*** time spent in crypto = %u usec\n", crypto_elapsed);
+			// printf("*** time spent in decrypt = %u usec\n", part1_elapsed);
+			// printf("*** time spent in encrypt = %u usec\n", part2_elapsed);
+			printf("*** time spent waiting for NAND ready = %u usec\n", accum_busy_wait_time);
+			printf("*** time spent waiting to read page = %u usec\n", accum_page_read_time);
+			printf("*** time spent       reading page   = %u usec\n", accum_pgrd);
+			printf("*** time spent       doing   ecc    = %u usec\n", accum_ecccalc);
+			printf("*** time spent     error correcting = %u usec\n", accum_correct);
+#endif
+
+			/* flush hash buf */
+			memset (hash, 0x0, sizeof (hash));
+
+			/* jump to last 16 byte offset for 1st pass Hash record */
+			Hash_Buf_Offset = (kernelImgHdr->mDestinationAddressInDram + (Img_Len -16));
+
+			/* copy last 16byte hash store in local hash bufffer */
+			memcpy (hash, (uint8_t *)( Hash_Buf_Offset), 16);
+			debug ("\n 1st encryption pass hash dump (16 byte): "); hex_print (hash, 16);
+
+			/* copy inhash's last 26 byte (keyB) into hash last 16 byte index */
+			memcpy (hash+16, (inhash + 16), 16);
+
+			debug ("\n 2nd Encryption pass hash dump (16byte): "); hex_print (hash+16, 16);
+
+			debug ("\n 1st/2nd encryption pass hash dump (32 byte): "); hex_print (hash, 32);
+
+			/* compare 32 byte hash with input Image */
+			val = memcmp(hash, inhash, 32);
+			if (val != 0) {
+
+				fail_safe_flag = 1;
+				printf ("Error : Hybrid hashing comparison failed ! Field Img\n");
+				debug ("inhash (%p)(32 bytes): ", inhash); hex_print(inhash, 32);
+				debug ("hash (%p)(32 bytes): ", hash); hex_print(hash, 32);
+
+			} else {
+
+				/* Hybrid RSA Verify input : hash & signature 2048 bit size */
+				val = Cnc_ImgHybRsa_Verify (hash, (kernelImgHdr->mDestinationAddressInDram + kernelImgHdr->mLength), pkey);
+				if (val != 0 ) {
+					fail_safe_flag = 1;
+					printf ("Error : Hybrid rsa_verify failed ! Field Img\n");
+				}
+
+				/* collect MTD (flash) address for bootargs cmdline option : Image upgrade condition
+				   of ping-pong scheme */
+				if (pingpong_boot == 1)
+					mtd_part =  kernelImgHdr->mSourceAddressInFlash;
+			}
+
+		} else {
+			fail_safe_flag = 1;
+			printf (" Invalid image 2 CRC. Header corrupt!\n");
+		}
+
+	} else {
+		fail_safe_flag = 1;
+		printf (" Invalid image 2 header signature !!!\n");
+	}
+
+FAIL_SAFE:
+	/* condition to check for switch to Factory Image */
+	if (fail_safe_flag == 1) {
+
+		/* Flush out decryted Kernel Image with zero */
+		memset ((uint8_t *)CRYPTO_OUT_KERNEL_DRAM_ADDR, 0x0, MAX_KERNEL_IMAGE_SIZE);
+
+		printf (" Field Img Authentication failed ... Look for Factory Img \n");
+
+		debug (" Factory Hdr info ....\n\n");
+		debug (" netHDImage \n");
+		debug (" mHdrType : 0x%x mSourceAddressInFlash : 0x%x mDestinationAddressInDram : 0x%x \
+				Fail-safe image mLength : %d siglen : %d ActiveImage flag : %d          \
+				mVersion : %s Crc32 : 0x%x \n", fact_kernelImgHdr->mHdrType,
+				fact_kernelImgHdr->mSourceAddressInFlash ,
+				fact_kernelImgHdr->mDestinationAddressInDram,
+				fact_kernelImgHdr->mLength,
+				fact_kernelImgHdr->mSignLen, fact_kernelImgHdr->mActiveImage,
+				fact_kernelImgHdr->mVersionNo, fact_kernelImgHdr->mCrc32);
+
+		val = Img_Authenticate(fact_kernelImgHdr, 1); // 1 : Factory kernel Img
+		if (val != 0) {
+
+			printf (" Fail-safe Img corrupt .. exiting Skloader !!!\n");
+			return -1;
+		}
+
+		printf (" Factory Img Authentication passed \n");
+
+		/* collect MTD (flash) address for bootargs cmdline option : fail-safe condition
+		   of ping-pong scheme */
+		if (pingpong_boot == 1)
+			mtd_part =  fact_kernelImgHdr->mSourceAddressInFlash;
+
+	} else {
+
+		printf (" Field Img Authentication passed \n");
+	}
+
+	printf (" Check for Blob image... ");
+
+	/* point to secure Blob header */
+	blobImgHdr = (FlashImageInfo_t *)(CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_BLOB_OFFSET);
+	debug("Blob hdr (FlashImageInfo_t *) @ 0x%08x + 0x%08x = 0x%08x\n",
+			CAVM18_FACT_HDR_DRAM_ADDR, CAVM18_FACT_HDR_BLOB_OFFSET,
+			CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_BLOB_OFFSET);
+
+	/*      On old systems the header was in a separate sector than the blob data, so if the
+	 *      header is bad try reading it from the old address.
+	 */
+	chk_crc32 = crc32 (0, (unsigned char *)blobImgHdr, sizeof (FlashImageInfo_t) - 4);
+	debug("act crc = 0x%08x, expected = 0x%08x\n", chk_crc32, blobImgHdr->mCrc32);
+
+	if (chk_crc32 != blobImgHdr->mCrc32) {
+
+		debug("Memory is garbage. Reading blob from NAND @ offset 0x%08x\n", CAVM18_BLOB_HDR_FLSH_ADDR);
+
+		printf("(old header)\n");
+
+		if (cnc_NandRead(CAVM18_BLOB_HDR_FLSH_ADDR, 
+					CAVM18_FACT_HDR_DRAM_ADDR + CAVM18_FACT_HDR_BLOB_OFFSET,
+					CAVM18_BLOB_HDR_LEN) != 0 ) {
+			printf (" Failed to read blob Header! .. exiting!!\n");
+			return -1;
+		}
+		chk_crc32 = crc32 (0, (unsigned char *)blobImgHdr, sizeof (FlashImageInfo_t) - 4);
+		debug("act crc = 0x%08x, expected = 0x%08x\n", chk_crc32, blobImgHdr->mCrc32);
+		if (chk_crc32 != blobImgHdr->mCrc32) {
+			printf("Blob is corrupt! Sorry...\n");
+			return -1;
+		}
+
+	} else {
+		printf("\n");
+	}
+
+	debug (" Secure Blob Image(HDCP/DTCP) Hdr info : \n");
+	debug (" HdrType : 0x%x SrcAddrFlash : 0x%x DestAddrDram : 0x%x\n",
+			blobImgHdr->mHdrType, blobImgHdr->mSourceAddressInFlash, blobImgHdr->mDestinationAddressInDram);
+	debug (" App Img Leng: %d siglen: %d, active: %d\n", blobImgHdr->mLength, blobImgHdr->mSignLen, blobImgHdr->mActiveImage);
+	debug (" Vers: %s Crc32: 0x%x\n", blobImgHdr->mVersionNo, blobImgHdr->mCrc32);
+
+	{
+		char *s = getenv("BOOTS_RETRY_COUNT");
+
+		if (s)
+			retry_count = (int)simple_strtoul (s, NULL, 10);
+	}
+
+	while ((val = Img_Authenticate(blobImgHdr, 0 /* Blob image */)) && (retry_count)) {
+		printf (" WARNING : App Blob corrupt \n");
+		retry_count--;
+	}
+
+	if (retry_count) {
+		printf (" AppImg (Blob) authenticated and copied to RAM addr : 0x%x\n", \
+				CRYPTO_OUT_BLOB_LINUX_ADDR);
+	} else {
+		/* FATAL ERROR. Could not authenticate blob */
+
+		char *s = getenv("BOOTS_NO_RESET");
+
+		if (!s || (*s == 'n'))  {
+			do_reset (NULL, 0, 0, NULL);
+		}
+	}
+
+	/* Only allow bootargs that we recognize */
+	filter_bootargs();
+
+	/*Set setenv u-boot args for Linux f/w upgrade application : In case of ping-pong Scheme only */
+	if (pingpong_boot == 1) {
+
+		char *cmdline = NULL;
+		char *temp = NULL;
+		char newCmdLine[256]; /* should be big enough after it is filtered */
+
+		if (mtd_part == FlashImgHdr[1].mSourceAddressInFlash)
+			temp = " mtd_skboot=14,16";
+		else
+			temp = " mtd_skboot=20,17";
+
+		if ((cmdline = getenv("bootargs")) != NULL) {
+			debug (" %s : %d\n", cmdline, strlen(cmdline));
+
+			strcpy (newCmdLine, cmdline);
+			strcat (newCmdLine, temp);
+			setenv("bootargs", newCmdLine);
+		} else {
+
+			debug ("WARNING : bootargs is NULL.. Filling hard-coded content .. \n");
+			cmdline = "console=ttyS0,115200";
+
+			strcpy (newCmdLine, cmdline);
+			strcat (newCmdLine, temp);
+			setenv("bootargs", newCmdLine);
+		}
+
+		debug ("bootargs::  %s : %d\n", newCmdLine, strlen(newCmdLine));
+	}
+
+	printf ("\n\n ... OK to boot \n");
+
+	Sec1800l_BootM(CRYPTO_OUT_KERNEL_DRAM_ADDR);
+
+	return 0;
+}
+
+U_BOOT_CMD (
+		boots,        1,      1,      do_boots,
+		"Boot Secure Kernel\n",
+		"\t Load, authenticate and run secure images (field, then factory) from NAND.\n"
+	   );
+
+#endif
+
+
+#if defined(CONFIG_CMD_ESP1800L_FLASH_UTIL)
+
+/************* esp1800l_flash_util ********************************/
+
+#define UPGRADE_MODE_GREATER    0x00000001   // 0=Upgrade on version mismatch, 1=Upgrade on greater
+#define UPGRADE_MODE_FORCE      0x00000002   // 0=Upgrade based on version, 1=Force
+#define UPGRADE_MODE_FACTORY    0x00000004   // 0=Upgrade field images 1=Upgrade Factory images
+#define UPGRADE_MODE_NO_KERNEL  0x00000008   // 0=Upgrade kernel 1=Don't upgrade kernel
+#define UPGRADE_MODE_NO_UBOOT   0x00000010   // 0=Upgrade uboot 1=Don't upgrade uboot
+
+// Header check signatures
+typedef struct __ImageInfo_t
+{
+	uint32_t mHdrId;                   // Sanity check of image before processing!
+	/*
+#define UBOOT_IDENTIFIER  (0x11223344)    // fail-safe/factory uboot
+#define KERNEL_IDENTIFIER (0x87543223)    // Fail-safe/factory kernel
+#define BLOB_IDENTIFIER   (0x22113344)    // APP_SIG :: HDCP + DTCP + ...
+*/
+	uint32_t mLength;                  // image len + image_signature len
+	uint32_t mSignLen;                 // size of signature len (stored at end of image)
+
+	char mVersionNo[256];              // svn revision for Linux/u-boot
+
+	char md5sum[16];                   // md5sum of image
+	uint32_t mCrc32;                   // crc of ImageInfo_t header
+
+} ImageInfo_t;
+
+typedef struct __ActFlashImage_t
+{
+	uint32_t numImages;
+	uint32_t reserved[3];
+	ImageInfo_t mCavm_ubootImage;	   // u-boot image
+	ImageInfo_t mCavm18_kernelImage;   // kernel image (ubootpImage)
+
+} ActFlashImage_t;
+
+ActFlashImage_t actImage;
+
+typedef struct __DistFlashImage_t
+{
+	uint32_t numImages;
+	uint32_t reserved[3];
+
+	// Up to three ImageInfo_t+Image data follow here:
+	ImageInfo_t image;	// mLength = total image_len + signature len
+} DistFlashImage_t;
+
+DistFlashImage_t distImage;
+
+
+static void print_Flashhdr (void* Hdr)
+{
+	uint32_t *hdr_p = (uint32_t *)Hdr;
+	hdr_p=hdr_p;
+	/* Dump data of all three for ananlysis */
+	debug (" Flash Hdr ... \n");
+	debug ("numImages : 0x%02x, reserved[0:1:2] : 0x%02x 0x%02x 0x%02x \n", \
+			*(hdr_p + 0), *(hdr_p + 1), *(hdr_p + 2),
+			*(hdr_p + 3));
+}
+
+static void print_ImageInfo (ImageInfo_t *hdr_p, char *ImageBin)
+{
+	int i;
+
+	printf (" %s ImageInfo_t ... \n", ImageBin);
+	printf (" mHdrType : 0x%x mLength : %d siglen : %d mVersion : %s Crc32 : 0x%x \n", \
+			hdr_p->mHdrId, hdr_p->mLength,
+			hdr_p->mSignLen, hdr_p->mVersionNo,
+			hdr_p->mCrc32);
+
+	printf (" MD5SUM ... \n");
+	for (i=0; i<16; i++) {
+
+		printf (" %02x", (unsigned char)hdr_p->md5sum[i]);
+	}
+
+	printf ("\n\n");
+}
+
+enum {
+	Factory,
+	Field
+}eActImgType;
+
+// check image version of with what is in NAND with what is passed.
+// If matching, return 0
+// If new is less than existing return -1
+// If new is greater than existing return 1
+static int checkImageVersion (uint32_t dstFlashAddr, unsigned long newVersion)
+{
+	int status = -1;
+	FlashImageInfo_t tmpImgHeader;
+	FlashImageInfo_t *Img = &tmpImgHeader;
+	char *endp;
+	unsigned long oldVersion;
+
+	// read whole header
+
+	if ( cnc_NandRead( dstFlashAddr, (uint32_t)Img,	sizeof(FlashImageInfo_t)) != 0 )
+	{
+		printf (" Failed to read NAND header location 0x%x\n", dstFlashAddr);
+		status = -2;
+		goto Error1 ;
+	}
+
+	// cmp version string of format svn_rev_x.x. FIXME this is broken for incrementing from 9 to 10.
+	oldVersion = simple_strtoul(&Img->mVersionNo[0], &endp, 10);
+
+	if (oldVersion == newVersion) {
+
+		printf (" Version Match \n");
+		status = 0;
+	} else if (oldVersion > newVersion) {
+
+		printf (" Version Mismatch : less \n");
+		status = -1;
+	} else {
+
+		printf (" Version Mismatch : greater \n");
+		status = 1;
+	}
+
+Error1:
+	return status;
+}
+
+/*
+ * Function to parse Image headers and flash onto respective loaction.
+ * Data is verified with a md5sum verification on the image read back from NAND.
+ */
+static int parse_and_flashImg ( uint32_t SrcImgLoc,
+		ImageInfo_t *SrcImgHdr,
+		const FlashImageInfo_t *TemplateDstImgHdr,
+		uint32_t flashHeaderAddr,
+		uint32_t modeFlag,
+		uint32_t actImgType)
+{
+	int status = -1;
+	uint32_t chk_crc32 = 0;
+	int versionDiff;
+	uint32_t ImgLen;
+	uint32_t hdrAddr = HEADER_DRAM_ADDR;
+
+	FlashImageInfo_t *tmpDstImgHdr;
+
+	if ( !( (SrcImgHdr->mHdrId == UBOOT_IDENTIFIER) ||
+				(SrcImgHdr->mHdrId == BLOB_IDENTIFIER) ||
+				(SrcImgHdr->mHdrId == KERNEL_IDENTIFIER) ) ) {
+		printf (" Invalid input header Identifier (0x%08x)... exiting.\n", SrcImgHdr->mHdrId);
+		goto Error1;
+	}
+
+
+	/* Validate Crc and Md5sum  */
+	debug (" Valid : %s header id\n", SrcImgHdr->mHdrId == UBOOT_IDENTIFIER ? "uboot" :
+			SrcImgHdr->mHdrId == BLOB_IDENTIFIER ? "blob" :"kernel");
+
+	chk_crc32 = crc32 (0, (unsigned char *)SrcImgHdr, sizeof (ImageInfo_t) - 4);
+	if (chk_crc32 != SrcImgHdr->mCrc32) {
+
+		printf (" Invalid Crc.. ImageInfo_t hdr corrupt .. exiting ! \n");
+		goto Error1;
+	}
+
+	printf(" Valid header CRC. Processing %s image. Checking md5sum... ",
+			(SrcImgHdr->mHdrId == UBOOT_IDENTIFIER) ? "uboot" :
+			(SrcImgHdr->mHdrId == KERNEL_IDENTIFIER) ? "kernel" :
+			"blob");
+
+
+	ImgLen = SrcImgHdr->mLength + SrcImgHdr->mSignLen;
+
+	/* calc md5sum */
+	if (sec1800l_md5sum(SrcImgLoc,  ImgLen, &SrcImgHdr->md5sum[0]) != 0) {
+
+		printf (" md5sum check failed for header... exiting\n");
+		goto Error1;
+	}
+
+
+	printf("done.\n");
+
+	if (flashHeaderAddr) {
+		debug ("preparing Blob/kernel Hdr \n");
+		/* read destination nand sector and copy sector size; check versioning;
+		   based on modeFlag flash accordingly */
+		unsigned long newVersion = simple_strtoul(&SrcImgHdr->mVersionNo[0], NULL, 10);
+
+		versionDiff = checkImageVersion ( flashHeaderAddr, newVersion);
+		if (versionDiff == -2) {
+			goto Error1;
+		}
+
+		if (SrcImgHdr->mHdrId == BLOB_IDENTIFIER)
+			modeFlag |= UPGRADE_MODE_FORCE; // Always force blob updates
+
+		if (!(modeFlag & UPGRADE_MODE_FORCE) && (versionDiff == 0)) { // Default Img flash mode
+
+			printf ("Version up to date.\n");
+			goto Error1;
+		} else if ((modeFlag & UPGRADE_MODE_GREATER) && (versionDiff == 1)) { // Upgrade mode
+
+			printf ("Version in flash is newer. Use --force to force the upgrade.\n");
+			goto Error1;
+		} else { // force mode ; flash directly
+
+			printf ("Forcing flash update.\n");
+		}
+
+		// Put the header into a DRAM area. The factory header is stored at an offset.
+		memset ( (unsigned char *)hdrAddr, 0xff, HEADER_DRAM_SIZE);
+
+		if ((SrcImgHdr->mHdrId == KERNEL_IDENTIFIER) &&
+				(flashHeaderAddr == CAVM18_FACT_HDR_FLSH_ADDR)) 	{
+			tmpDstImgHdr = (FlashImageInfo_t *)(hdrAddr + CAVM18_FACT_HDR_KERNEL_OFFSET);
+		} else {
+			tmpDstImgHdr = (FlashImageInfo_t *)hdrAddr;
+		}
+
+		// populate FlashImageInfo_t[x], which will be written into the flash.
+		tmpDstImgHdr->mHdrType                  = TemplateDstImgHdr->mHdrType;
+		tmpDstImgHdr->mSourceAddressInFlash     = TemplateDstImgHdr->mSourceAddressInFlash;
+		tmpDstImgHdr->mDestinationAddressInDram = TemplateDstImgHdr->mDestinationAddressInDram;
+		tmpDstImgHdr->mLength                   = SrcImgHdr->mLength;
+		tmpDstImgHdr->mSignLen                  = SrcImgHdr->mSignLen;
+		tmpDstImgHdr->mActiveImage              = actImgType; // 1 : field ;; 0 Factory
+		memcpy(tmpDstImgHdr->mVersionNo, SrcImgHdr->mVersionNo, 256);
+		tmpDstImgHdr->mCrc32 = crc32 (0, (unsigned char *)tmpDstImgHdr, sizeof (FlashImageInfo_t) - 4);
+
+		if (SrcImgHdr->mHdrId == KERNEL_IDENTIFIER) {
+			/* Flash ImgHdr to Nand sector. This is a separate sector for kernel images.
+			*/
+			if (cnc_NandErase(flashHeaderAddr, SECTOR_SIZE, 1) != 0) {
+
+				printf (" Error.. NAND erase failed for header!\n");
+				goto Error1;
+			}
+
+			if (cnc_NandWrite(hdrAddr, flashHeaderAddr, HEADER_DRAM_SIZE, KERNEL) != 0) {
+
+				printf (" Error .. NAND write failed for header!\n");
+				goto Error1;
+			}
+		}
+	}
+
+
+	uint32_t flashImageAddr = TemplateDstImgHdr->mSourceAddressInFlash;
+
+	if (SrcImgHdr->mHdrId == BLOB_IDENTIFIER) {
+		// Copy the blob to after the blob header and use that area to copy to NAND
+		memcpy((unsigned char *)(hdrAddr + CAVM18_BLOB_HDR_LEN), (unsigned char *)SrcImgLoc, ImgLen);
+		SrcImgLoc = hdrAddr;
+
+		// Adjust the flashImageAddr to reflect blob header preceding the data.
+		flashImageAddr -= CAVM18_BLOB_HDR_LEN;
+		ImgLen += CAVM18_BLOB_HDR_LEN;
+	}
+
+	// work on Image alignment; should be multiple of 128KByte
+	uint32_t ImgLen_aligned = SECTOR_SIZE * ( (ImgLen + SECTOR_SIZE -1) / SECTOR_SIZE ) ;
+
+	debug ("aligned 128K boundry ImgLen : %x\n", ImgLen_aligned);
+
+	// condition check for memory boundary so that ImgLen shouldn't be greater than 32 MB
+	if (ImgLen_aligned >= (32*1024*1024)) {
+
+		printf (" Image Size greater than 32 MByte.. Exiting \n");
+		goto Error1;
+	}
+
+	// jump to SrcImgLoc offset, make alignment to 128K (SECTOR_SIZE)
+	// flash to Nand
+	if (cnc_NandErase(flashImageAddr, ImgLen_aligned, 1) != 0) {
+
+		printf (" Error .. NAND Erase failed for header.\n");
+		goto Error1;
+	}
+
+	if (cnc_NandWrite((uint32_t)SrcImgLoc, flashImageAddr, ImgLen_aligned, RAW) != 0) {
+
+		printf (" Error .. NAND write failed for header\n");
+		goto Error1;
+	}
+
+	debug ("Reading back : Nand : %x\n", flashImageAddr);
+
+	if (SrcImgHdr->mHdrId == BLOB_IDENTIFIER) {
+		// Adjust the flashImageAddr to reflect blob header preceding the data.
+		flashImageAddr += CAVM18_BLOB_HDR_LEN;
+		ImgLen -= CAVM18_BLOB_HDR_LEN;
+		ImgLen_aligned -= CAVM18_BLOB_HDR_LEN;
+	}
+
+	// Read back same image len, verify md5sum with ImageInfo *SrcImgHdr
+	if ( cnc_NandRead( flashImageAddr, READ_BACK_IMAGE_RAM_ADDR, ImgLen_aligned) != 0 )
+	{
+		printf (" Failed to read NAND header location 0x%x\n", flashImageAddr);
+		goto Error1 ;
+	}
+
+	// calc md5sum
+	if (sec1800l_md5sum(READ_BACK_IMAGE_RAM_ADDR,  ImgLen, &SrcImgHdr->md5sum[0]) != 0) {
+
+		printf (" md5sum check failed for Image\n");
+		goto Error1;
+	}
+
+	printf (" \n\n Valid md5sum .. NAND read back Successful\n");
+
+	status = 0;
+
+Error1 :
+	return status;
+}
+
+static int find_needle_in_haystack (const unsigned char *needle, int len, const unsigned char *haystack, int limit)
+{
+	int i;
+	unsigned char c;
+	int state = 0;
+
+	for (i = 0; i < limit; i++) {
+		c = haystack[i];
+
+		if (c == needle[state]) {
+			state++;
+			if (state == len) {
+				return i+1; /* found needle */
+			}
+		} else {
+			state = 0;
+		}
+	}
+
+	return -1; /* did not find needle */
+}
+
+static void show_failed_search_results(const char *fmtstrg, const unsigned char *haystack, const unsigned char *needle, int needle_length)
+{
+	int i = 0, cols = 0;
+	printf(fmtstrg, haystack, needle, needle_length);
+	for (i = 0; i < 256; ++i) {
+		if (cols == 0) {
+			printf("\t");
+		}
+		printf(" %02x", needle[i]);
+		if (++cols == 16) {
+			printf("\n");
+			cols = 0;
+		}
+	}
+	if (cols != 0) {
+		printf("\n");
+	}
+	return;
+}
+
+static int public_key_does_not_match_mine (unsigned long addr)
+{
+	unsigned char *needle, *haystack;
+	int nBytesToCompare = 256, pos = 0, pos2 = 0;
+	/* int i = 0, cols = 0; */
+
+	printf("pkey @ %p, blob_pkey @ %p\n", pkey, blob_pkey);
+	haystack = (unsigned char *)(addr+0x250);
+	needle = pkey;
+	pos = find_needle_in_haystack(needle, 256, haystack, 524288);
+	if (pos != -1) {
+
+		/* pkey was found. Look for matching blob pkey. */
+		printf("pkey found @ %p\n", haystack + (pos - 256));
+
+		if (memcmp(pkey, blob_pkey, 256) == 0) {
+			pos2 = find_needle_in_haystack(needle, 256, haystack + pos, 524288 - pos);
+			if (pos2 != -1) {
+				printf("blob_pkey found @ %p\n", haystack + (pos + pos2 - 256));
+				return 0;   /* Both key and blob pkey matched. */
+			} else {
+				show_failed_search_results("memory area begins @ %p (512K-256 bytes), blob_pkey @ %p, key length: %d, target blob_pkey:\n",
+						haystack + pos, needle, 256);
+				printf("mismatch because blob_pkey wasn't found in image\n");
+				return 1;   /* Public key did not match. */
+			}
+		} else {
+			printf("pkey and blob_pkey are not the same. Look for blob_pkey now\n");
+			needle = blob_pkey;
+			pos2 = find_needle_in_haystack(needle, 256, haystack, 524288);
+			if (pos2 != -1) {
+				printf("blob_pkey found @ %p\n", haystack + (pos - 256));
+				return 0;   /* Both key and blob pkey matched. */
+			} else {
+				show_failed_search_results("memory area begins @ %p (512K bytes), blob_pkey @ %p, key length: %d, target blob_pkey:\n",
+						haystack, needle, 256);
+				printf("mismatch because blob_pkey wasn't found in image\n");
+				return 1;   /* Public key did not match. */
+			}
+		}
+	} else {
+		show_failed_search_results("memory area begins @ %p (512K bytes), pkey @ %p, key length: %d, target pkey:\n",
+				haystack, needle, 256);
+		printf("mismatch because pkey wasn't found in image\n");
+		return 1;   /* Public key did not match. */
+	}
+#if 0
+	if (memcmp(pkey, blob_pkey, 256) == 0) {
+		/* pkey and blob_pkey are identical */
+
+		if (pkey > blob_pkey)
+			needle = blob_pkey;
+		else
+			needle = pkey;
+
+		nBytesToCompare = 512;
+
+	} else {
+		/* pkey is not the same as blob_pkey.  Do not bother to scan for
+		   blob_pkey because all boards share the same blob_pkey.  Not
+		   all boards share the same pkey. */
+
+		needle = pkey;
+		nBytesToCompare = 256;
+	}
+
+	haystack = (unsigned char *)(addr+0x250);
+
+	if (find_needle_in_haystack(needle, nBytesToCompare, haystack, 524288) == -1) {
+		printf("memory area begins @ %p (search 512K bytes), pkey @ %p, key length: %d, target pkey:\n",
+				haystack, needle, nBytesToCompare);
+		for (i = 0; i < nBytesToCompare; ++i) {
+			if (cols == 0) {
+				printf("\t");
+			}
+			printf(" %02x", needle[i]);
+			if (++cols == 16) {
+				printf("\n");
+				cols = 0;
+			}
+		}
+		if (cols != 0) {
+			printf("\n");
+		}
+		return 1; /* public keys do not match mine */
+	} else {
+		return 0; /* public keys match mine */
+	}
+#endif
+}
+
+/*
+ * esp1800l_flash_util : Programm to flash distribution / Active Image in Nand Sectors
+ */
+
+int do_esp1800l_flash_util (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+	int status = -1;
+	int i;
+	int ActImgType = Field;
+	int modeFlag = 0;
+	unsigned long addr;
+
+	if (argc<2 || argc>6) {
+
+		return cmd_usage(cmdtp);
+	}
+
+	for(i=1; i<argc-1; i++)
+	{
+		if (!strcmp("--upgrade", argv[i])) {
+			modeFlag |= UPGRADE_MODE_GREATER;
+			continue;
+		}
+
+		if (!strcmp("--force", argv[i])) {
+			modeFlag |= UPGRADE_MODE_FORCE;
+			continue;
+		}
+
+		if (!strcmp("--factory", argv[i])) {
+			modeFlag |= UPGRADE_MODE_FACTORY;
+			ActImgType = Factory;
+			continue;
+		}
+
+		if (!strcmp("--kernel", argv[i])) {
+			modeFlag |= UPGRADE_MODE_NO_UBOOT;
+			continue;
+		}
+
+		if (!strcmp("--uboot", argv[i])) {
+			modeFlag |= UPGRADE_MODE_NO_KERNEL;
+			continue;
+		}
+
+		printf("Unexpected argument: %s\n", argv[i]);
+		return cmd_usage(cmdtp);
+	}
+
+	// If both --uboot and --kernel were indicated clear the previously set flags
+	if ((modeFlag & UPGRADE_MODE_NO_UBOOT) && (modeFlag & UPGRADE_MODE_NO_KERNEL))
+		modeFlag &= ~(UPGRADE_MODE_NO_UBOOT | UPGRADE_MODE_NO_KERNEL);
+
+	addr = simple_strtoul(argv[argc-1], NULL, 16);
+
+	if (addr == 0) {
+		printf("Unexpected image load address\n");
+		return cmd_usage(cmdtp);
+	}
+
+	// Arguments good
+	printf(" %s %s %s.\n",
+			modeFlag & UPGRADE_MODE_FORCE ? "Force update to" :
+			modeFlag & UPGRADE_MODE_GREATER ? "Checking version is greater to update" :
+			"Checking version is different to update",
+			modeFlag & UPGRADE_MODE_FACTORY ? "factory" : "field",
+			modeFlag & UPGRADE_MODE_NO_UBOOT ? "kernel image" :
+			modeFlag & UPGRADE_MODE_NO_KERNEL ? "uboot image" :
+			"uboot/kernel/blob images");
+
+	/* Rd mnumImage ; =1 then copy hdr of size distFlashImage OR > 1 then copy to hdr type
+	   actFlashImage */
+
+	/* Note that the following statement works only when the size of a pointer is the same
+	   as the size of an unsigned. */
+	unsigned char *Img = (unsigned char *) addr;
+
+	debug ("Image hdr Ram addr : %p \n", Img);
+
+	memcpy ( (unsigned char *)&distImage, Img, sizeof(distImage));
+
+	if (distImage.image.mHdrId == BLOB_IDENTIFIER) {
+		/* Sanity check. */
+		if (distImage.numImages != 1) {
+			printf("Number of images is %u, but only one is expected. No blob downloaded!\n", distImage.numImages);
+			goto Error1;
+		}
+
+		/* These flags aren't allowed for a blob program. They don't make sense. */
+		if ((modeFlag & UPGRADE_MODE_NO_UBOOT) ||
+				(modeFlag & UPGRADE_MODE_NO_KERNEL)) {
+			printf("Unexpected %s argument for blob image.\n",
+					modeFlag & UPGRADE_MODE_NO_UBOOT ? "--kernel" : "--uboot");
+			goto Error1;
+		}
+
+		debug ("Dist-specific Image Hdr dump... \n");
+
+		print_Flashhdr ( &distImage );
+		print_ImageInfo ( &distImage.image, "Secure Blob Image" );
+
+		// jump to real Image
+		/* Note that for a blob, distImage.numImages will be 1, so it's safe to assume that
+		   the image starts following the first image header. */
+		Img += sizeof (distImage);
+
+		debug (" Img offset : %p\n", Img);
+
+		if ( parse_and_flashImg ((uint32_t)Img,
+					&distImage.image,
+					&FlashImgHdr[0],
+					CAVM18_BLOB_HDR_FLSH_ADDR,
+					modeFlag,
+					ActImgType) != 0)
+		{
+			goto Error1;
+		}
+
+	} else if (distImage.numImages == 2) { /* Contains both u-boot and kernel */
+
+		if (public_key_does_not_match_mine(addr)) {
+			printf("\nERROR: The RSA public key inside the U-Boot image inside your SBIN file does\n");
+			printf("       not match mine.  I don't like your SBIN file!\n\n");
+
+			if (modeFlag & UPGRADE_MODE_FORCE) {
+				/* user typed the "--force" command line option */
+				int tmp;
+				printf("If you know what you're doing, you can ignore the error and still proceed.\n");
+				printf("Do you want to ignore the error and still proceed?  (y/N)  ");
+				tmp = getc();
+
+				switch (tmp) {
+					case 'y':
+					case 'Y':
+						printf("Yes\n\n");
+						break;
+					default:
+						printf("No\n\n");
+						goto Error1;
+						break;
+				}
+			} else goto Error1;
+		}
+
+		memset ( (unsigned char *)&actImage, 0x00, sizeof (actImage));
+		memcpy ( (unsigned char *)&actImage, Img, sizeof(actImage));
+
+		debug ("Active Image Hdr dump... \n");
+		print_Flashhdr ( &actImage );
+		print_ImageInfo ( &actImage.mCavm_ubootImage, "U-boot image" );
+		print_ImageInfo ( &actImage.mCavm18_kernelImage, "Kernel image" );
+
+		void *pkernelHdr = NULL;
+		void *pUbootHdr = NULL;
+		uint32_t DstKernelHdrLoc; // kernel Img hdr flash Loc
+
+		// Decode for Field/Fact; populate src Flash addr accordingly.
+		if (ActImgType == Factory) {
+			pkernelHdr = (FlashImageInfo_t *) (&FlashImgHdr[1]);
+			pUbootHdr  = (FlashImageInfo_t *) (&FlashImgHdr[3]);
+			DstKernelHdrLoc = CAVM18_FACT_HDR_FLSH_ADDR;
+		} else {
+			pkernelHdr = (FlashImageInfo_t *) (&FlashImgHdr[2]);
+			pUbootHdr  = (FlashImageInfo_t *) (&FlashImgHdr[4]);
+			DstKernelHdrLoc = CAVM18_FIELD_KENREL_HDR_FLSH_ADDR;
+		}
+
+		debug (" Img offset : %p, sizeof actFlashImage : %d\n", Img, sizeof (actImage));
+
+		// jump to real image of uboot, following the header
+		Img += sizeof (actImage);
+
+		if (!(modeFlag & UPGRADE_MODE_NO_UBOOT) &&
+				(parse_and_flashImg ((uint32_t)Img,
+						     &actImage.mCavm_ubootImage,
+						     (FlashImageInfo_t *)pUbootHdr,
+						     0,
+						     modeFlag,
+						     ActImgType) != 0) )
+		{
+
+			goto Error1;
+		}
+
+		// jump to Image real Image of kernel
+		Img += (actImage.mCavm_ubootImage.mLength + actImage.mCavm_ubootImage.mSignLen);
+
+		if (!(modeFlag & UPGRADE_MODE_NO_KERNEL) &&
+				(parse_and_flashImg ((uint32_t)Img,
+						     &actImage.mCavm18_kernelImage,
+						     (FlashImageInfo_t *)pkernelHdr,
+						     DstKernelHdrLoc,
+						     modeFlag,
+						     ActImgType) != 0))
+		{
+
+			goto Error1;
+		}
+
+	} else {
+
+		printf (" Invalid numImages value (%d) in flash image header, expected 1 or 2.\n",
+				distImage.numImages);
+		goto Error1;
+	}
+
+	status = 0;
+
+Error1:
+
+	if (nandWriteError) {
+		status = -EIO;
+		nandWriteError = 0;
+	}
+	return status;
+
+}
+
+U_BOOT_CMD (
+		esp1800l_flash_util ,        6,      0,      do_esp1800l_flash_util,
+		"Utility to flash signed_encrypted Image on Nand \n",
+		"\t [--factory] [--upgrade|--force] [--kernel|--uboot] image_load_addr \n"
+		"\t [--factory] Image type ; applicable for kernel/secureblob\n"
+		"\t [--upgrade] Upgrade nand sector with new Image provided that new Image has greater svn version \
+		compare with flashed Image\n"
+		"\t [--force]   Forceably flash Image: no version checking\n"
+		"\t [--kernel]  Only upgrade kernel\n"
+		"\t [--uboot]  Only upgrade uboot\n"
+		"\t [Image_load_addr] load addr of Image; should be 0x2000000 \n"
+	   );
+
+#endif
+
+#if defined(CONFIG_CMD_XRSA_VERIFY)
+/*
+   do_xrsa_verify - Program to rsa verify signed Image.
+   This program capable of doing rsa verify for PKCS15. key format 2048.
+   */
+static int do_xrsa_verify (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+	if (argc < 2 || argc > 4)
+		return cmd_usage(cmdtp);
+
+	/* signed Image address */
+	unsigned long aImgAddress = simple_strtoul(argv[1], NULL, 16);
+
+	/* image len excludes */
+	unsigned long aLen = simple_strtoul(argv[2], NULL, 16);
+
+	/* image len excludes */
+	unsigned long asignAddress = simple_strtoul(argv[3], NULL, 16);
+
+	printf ("Signed image: %x, Len: %x, signature addr: %x \n",(unsigned int) aImgAddress,(unsigned int) aLen,(unsigned int) asignAddress);
+
+	int val = ImgRsa_Verify (aImgAddress, aLen, asignAddress);
+
+	if (val != 0)
+		return -1;
+
+	return 0;
+}
+
+U_BOOT_CMD (
+		xrsa_verify ,        4,      1,      do_xrsa_verify,
+		"Verify rsa signed Image using s/w hashing \n",
+		"\t Test Image address \n"
+		"\t Test image length \n"
+		"\t Test Image signature address \n"
+		"\t RSA verify of signed image, algo -pkcs15, 2048-bit Key format, signature len : 256 ; function uses s/w hashing \n"
+		"\t argc 1 : signed Img len \n"
+		"\t argc 2 : Image len (with out signature) \n"
+		"\t argc 3 : Imaged Signature address ( 256 byte len as per algo) \n"
+	   );
+#endif
+
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+/*
+   Protect write access to ddr memory region for relocated uboot code (from gd->relocaddr to top
+   of memory.
+
+DISABLE_SEC_PROTECT : 0 : MEM PROTECT ON
+1 : MEM PROTECT OFF
+*/
+
+int check_write_to_code_area ( unsigned long addr, unsigned long size)
+{
+	int disable_protect_flag;	/* 0 : No mem protect for secure region
+					 *  1 : mem protect
+					 */
+	/* Handle out of range case */
+	addr &= (PHYS_SDRAM_1_SIZE-1);
+
+#if ( DISABLE_SEC_PROTECT == 1)
+
+	disable_protect_flag = 1;
+#else
+	disable_protect_flag = 0;
+#endif
+
+	if (disable_protect_flag == 1) {
+
+		printf ("WARNING:  No memory protection for code area..\n");
+		return 0;
+	} else {
+
+		debug (" addr : %x\n", (unsigned int)addr);
+		debug (" gd->relocaddr-0x%08x\n", (unsigned int)gd->relocaddr);
+
+		/* mem check for code area */
+
+		if ((addr >= gd->relocaddr && addr <= PHYS_SDRAM_1_SIZE) ||
+				(addr + size > gd->relocaddr))	{
+
+			printf (" Write access on code area denied 0x%08x - 0x%08x\n",
+					(unsigned)gd->relocaddr, (unsigned)(PHYS_SDRAM_1_SIZE - 1));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+#endif
+
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_burnotp.c u-boot-2011.06/common/cmd_burnotp.c
--- u-boot-2011.06_original/common/cmd_burnotp.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_burnotp.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,236 @@
+#include "cnc_util.h"
+
+#define DEBUG_BURNOTP 0
+//#define debug printf
+#define AUTO_LOCK_OTP 1
+
+#pragma pack(1)
+typedef struct Otp_t
+{
+	UInt32 mOtpBankNo;
+	UInt32 mOtpIndex;
+	UInt32 mOtpData;
+}Otp_t;
+
+#pragma pack(1)
+typedef struct OtpInfo_t
+{
+	UInt32 mNoOfOtpObjectInList;
+	Otp_t mOtpList[1];
+}OtpInfo_t;
+
+static int SkipLockOtpConfirmation;
+
+extern int do_lockotp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_load_serial_bin(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+Int32 Do_Dvu(UInt32 aOtpBufferInputAddress, UInt32 aInputBufferLength, UInt32 aOtpBufferOutputAddress)
+{
+	int Status = Cnc_InPlaceDecryptOnlyImage(aOtpBufferInputAddress,aInputBufferLength);
+	return Status;
+}
+
+int DecryptAndVerifyOtpData(UInt32 aInputAddress, UInt32 aOutputAddress , int aLength)
+{
+	int Status=0;
+	UInt8 SourceHash[32 +256];	
+	UInt8 ComputedHashBuffer[32 + 256];
+	//UInt8 TempBuf[512]; //Backup buffer
+	Status=Status;
+	debug("---------------\n");		
+	memcpy(SourceHash, (void*) (aInputAddress + aLength - 32), 16 );			
+	debug("-----  SourceHash ----------\n");
+	//Cnc_DumpMemory(SourceHash, 8);
+	debug("---------------\n");
+	Status = Cnc_DecryptImageGetHash(aInputAddress, aOutputAddress, aLength-32, ComputedHashBuffer, 16 );
+
+	debug("-----  SourceHash ----------\n");
+	//Cnc_DumpMemory(SourceHash, 8);
+	debug("------  ComputedHashBuffer --------\n");
+	//Cnc_DumpMemory(ComputedHashBuffer, 8);			
+	debug("---------------\n");
+	//Check hash signature 
+	if ( 0 == memcmp( SourceHash, ComputedHashBuffer, 16 ) )
+	{
+		return 0;				
+	}
+	return -1;		
+}
+
+int do_burnotp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	UInt32 i=0;
+	OtpInfo_t *p;
+	int status = 0;
+	char TempBuf0[16]={0};
+	char TempBuf1[16]={0};
+	char TempBuf2[16]={0};
+	char TempBuf3[16]={0};
+	UInt32 OtpBufferInputAddress =0x02000000;
+	UInt32 OtpBufferOutputAddress=0x02000000;
+	UInt32 cnt;
+
+	const char* pStep2[]     = { "otp"   , "write" , TempBuf1, TempBuf2 , TempBuf3 };
+	const char* kermit_cmd[] = { "loadb" , TempBuf0 };
+	const char* pLockOtp[]     = { "lockotp" };
+	UInt32 FileSize;
+
+	//burnotp kermit
+	//burnotp mem  <memoryaddress>
+	//burnotp usb <file_name>
+
+	memset( (void*)OtpBufferInputAddress , 0xFF, 64*1024);
+	memset( (void*)OtpBufferOutputAddress, 0xFF, 64*1024);
+
+
+	if ( (0 ==  strcmp( argv[1],"kermit" ) ) && (argc == 4) )
+	{
+		sprintf(TempBuf0, "%x", OtpBufferInputAddress);
+		status = do_load_serial_bin(NULL,0, 2 ,(char** const ) kermit_cmd);
+		if ( 0 != status )
+		{
+			printf("%sERROR: kermit failed, try again\n%s", ColorRed, ColorNormal);
+			goto error_exit;
+		}
+	}
+	else if ( ( 0 == strcmp ( argv[1], "mem" ) ) && (argc == 4) )
+	{
+		OtpBufferInputAddress = simple_strtol(argv[2],NULL,16);
+		OtpBufferOutputAddress=OtpBufferInputAddress;
+		FileSize = simple_strtol(argv[3],NULL,16);
+		if (FileSize<1)
+		{
+			printf("%sERROR: filesize too small\n%s", ColorRed, ColorNormal);
+			return -1;
+		}
+
+	}
+	else if ( ( 0 == strcmp( argv[1], "usb" ) ) && (argc == 3 ) )
+	{
+		status = cnc_LoadFileFromUsb(argv[2],  OtpBufferInputAddress , & FileSize);
+		if (status != 0 )
+		{
+			printf("%sERROR: unable to load file from usb\n%s" , ColorRed, ColorNormal );
+			return -1;
+		}
+	}
+	else
+	{
+		cmd_usage(cmdtp);
+		goto error_exit;
+	}
+
+	status = DecryptAndVerifyOtpData(OtpBufferInputAddress, OtpBufferOutputAddress, FileSize);
+	
+	if ( 0 != status )
+	{
+		printf("%sERROR: Fail to verify OTP data, please try again\n%s", ColorRed, ColorNormal );
+		return -1;
+	}	
+	else
+	{
+		printf("%sOTP data verified successfully\n%s", ColorGreen, ColorNormal );
+	}
+
+#if (DEBUG_BURNOTP)
+	Cnc_DumpMemory ( OtpBufferOutputAddress, FileSize/sizeof(UInt32) );
+#endif
+	p = (OtpInfo_t*) OtpBufferOutputAddress;
+	cnt = min( p->mNoOfOtpObjectInList,128);
+	for(i=0 ; i < cnt ; i++)
+	{
+		sprintf(TempBuf1, "0x%X" , p->mOtpList[i].mOtpBankNo);
+		sprintf(TempBuf2, "0x%X" , p->mOtpList[i].mOtpIndex);
+		sprintf(TempBuf3, "0x%08X" , p->mOtpList[i].mOtpData);
+#if (DEBUG_BURNOTP)
+		printf("%s %s %s %s %s\n", pStep2[0], pStep2[1], pStep2[2], pStep2[3], pStep2[4] );
+		status =0;
+#else
+		status = do_otp(NULL, 0, 5, (char** const )pStep2);
+#endif
+
+		if ( status != 0 )
+		{
+#if (DEBUG_BURNOTP)
+			Cnc_DumpMemory ( OtpBufferOutputAddress, FileSize/sizeof(UInt32) );
+#else
+			//wipe out memory before exit
+			memset( (void*) OtpBufferOutputAddress, 0, FileSize);
+#endif
+			printf("%sERROR: OTP programming failed, please contact vendor\n%s" , ColorRed, ColorNormal);
+			return -1;
+		}
+	}
+	//wipe out memory
+	memset( (void*) OtpBufferOutputAddress, 0, FileSize);
+	printf("%sOTP programmed successfully\n%s", ColorGreen, ColorNormal);
+
+#if (AUTO_LOCK_OTP)	
+	SkipLockOtpConfirmation=1;
+	status = do_lockotp(NULL, 0, 1, (char** const )pLockOtp);
+	SkipLockOtpConfirmation=0;
+#endif	
+	
+	return status;
+
+error_exit:
+	return -1;
+}
+
+U_BOOT_CMD(
+		burnotp, 4, 0 , do_burnotp,
+		"burn otp - from file (file can be downloaded via kermit or preloaded from meory or usb",
+		"burnotp kermit\n"
+		"burnotp mem  <memoryaddress> <length>\n"
+		"burnotp usb <file_name>\n"
+	  );
+	  
+	  
+int do_lockotp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int status = 0;
+	char temp='N';
+	const char* pStep2[]     = { "otp"   , "write" , "0" , "0x0", "0x00208108"  };
+
+	if ( 0  == SkipLockOtpConfirmation )
+	{
+		printf("%sWARNING:lockotp operation irreversible, Are you sure?, Do you want to continue? (N/Y)\n%s", ColorYellow, ColorNormal);
+		temp = getc();
+	}
+	else
+	{
+		temp = 'Y';
+	}
+	
+	if ((temp == 'Y' ) || (temp == 'y') )
+	{
+		#if (DEBUG_BURNOTP)
+			printf("%s %s %s %s %s\n", pStep2[0], pStep2[1], pStep2[2], pStep2[3], pStep2[4] );
+			status =0;
+		#else
+			status = do_otp(NULL, 0, 5, (char** const) pStep2);
+		#endif
+
+		if ( status != 0 )
+		{
+			printf("%sERROR: Fail to lock OTP. Please contact vedor\n%s", ColorRed, ColorNormal);
+			return -1;
+		}
+		
+		printf("%sOTP is locked successfully\n%s", ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf("%slockotp operation aborted\n%s", ColorMagenta, ColorNormal);
+	}
+
+	return status;
+}
+	  
+	  
+U_BOOT_CMD(
+		lockotp, 1, 0 , do_lockotp,
+		"lockotp",
+		"lockotp"
+	  );
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_cache.c u-boot-2011.06/common/cmd_cache.c
--- u-boot-2011.06_original/common/cmd_cache.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_cache.c	2014-07-29 17:28:38.819972000 +0800
@@ -2,23 +2,7 @@
  * (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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 /*
@@ -26,73 +10,97 @@
  */
 #include <common.h>
 #include <command.h>
+#include <linux/compiler.h>
+
+static int parse_argv(const char *);
 
-static int on_off (const char *);
+void __weak invalidate_icache_all(void)
+{
+	/* please define arch specific invalidate_icache_all */
+	puts("No arch specific invalidate_icache_all available!\n");
+}
 
-int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_icache(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	switch (argc) {
 	case 2:			/* on / off	*/
-		switch (on_off(argv[1])) {
-		case 0:	icache_disable();
+		switch (parse_argv(argv[1])) {
+		case 0:
+			icache_disable();
 			break;
-		case 1:	icache_enable ();
+		case 1:
+			icache_enable();
+			break;
+		case 2:
+			invalidate_icache_all();
 			break;
 		}
-		/* FALL TROUGH */
+		break;
 	case 1:			/* get status */
-		printf ("Instruction Cache is %s\n",
+		printf("Instruction Cache is %s\n",
 			icache_status() ? "ON" : "OFF");
 		return 0;
 	default:
-		return cmd_usage(cmdtp);
+		return CMD_RET_USAGE;
 	}
 	return 0;
 }
 
-int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+void __weak flush_dcache_all(void)
+{
+	puts("No arch specific flush_dcache_all available!\n");
+	/* please define arch specific flush_dcache_all */
+}
+
+int do_dcache(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	switch (argc) {
-	case 2:			/* on / off	*/
-		switch (on_off(argv[1])) {
-		case 0:	dcache_disable();
+	case 2:			/* on / off */
+		switch (parse_argv(argv[1])) {
+		case 0:
+			dcache_disable();
+			break;
+		case 1:
+			dcache_enable();
 			break;
-		case 1:	dcache_enable ();
+		case 2:
+			flush_dcache_all();
 			break;
 		}
-		/* FALL TROUGH */
+		break;
 	case 1:			/* get status */
-		printf ("Data (writethrough) Cache is %s\n",
+		printf("Data (writethrough) Cache is %s\n",
 			dcache_status() ? "ON" : "OFF");
 		return 0;
 	default:
-		return cmd_usage(cmdtp);
+		return CMD_RET_USAGE;
 	}
 	return 0;
-
 }
 
-static int on_off (const char *s)
+static int parse_argv(const char *s)
 {
-	if (strcmp(s, "on") == 0) {
-		return (1);
-	} else if (strcmp(s, "off") == 0) {
-		return (0);
-	}
-	return (-1);
+	if (strcmp(s, "flush") == 0)
+		return 2;
+	else if (strcmp(s, "on") == 0)
+		return 1;
+	else if (strcmp(s, "off") == 0)
+		return 0;
+
+	return -1;
 }
 
 
 U_BOOT_CMD(
 	icache,   2,   1,     do_icache,
 	"enable or disable instruction cache",
-	"[on, off]\n"
-	"    - enable or disable instruction cache"
+	"[on, off, flush]\n"
+	"    - enable, disable, or flush instruction cache"
 );
 
 U_BOOT_CMD(
 	dcache,   2,   1,     do_dcache,
 	"enable or disable data cache",
-	"[on, off]\n"
-	"    - enable or disable data (writethrough) cache"
+	"[on, off, flush]\n"
+	"    - enable, disable, or flush data (writethrough) cache"
 );
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_call_external_proc.c u-boot-2011.06/common/cmd_call_external_proc.c
--- u-boot-2011.06_original/common/cmd_call_external_proc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_call_external_proc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,199 @@
+#include <common.h>
+#include <command.h>
+
+#define EXTERNAL_PIC_PROCESSES_GET_KEY_WORD_CMD 'K'
+#define EXTERNAL_PIC_PROCESSES_GET_FILE_SIZE_CMD 'F'
+#define EXTERNAL_PIC_PROCESSES_GET_CONTEXT_SIZE_CMD 'C'
+
+#define EXTERNAL_PROCS_MAX_ARGC 9
+DECLARE_GLOBAL_DATA_PTR;
+
+struct external_code_attr{
+	unsigned int key_word;
+	unsigned char *addr;
+	unsigned int file_size;
+	unsigned int file_crc;
+	unsigned int context_size;  
+};
+
+int do_call_external_proc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+#define PIC_PROC_HAS_SEPERATE_SPACE
+	extern unsigned long do_go_exec (unsigned long (*entry)(int, char * const []), int argc, char * const argv[]);
+	static unsigned int magic[] = {0xe1a00000, 0xe1a00000};
+	unsigned int *app;
+	int ret=0;
+	struct external_code_attr this_code_attr[16]={{0}};
+	int i;
+	int found=0;
+	char *p=NULL;
+	unsigned int file_crc;
+	unsigned char *app_aligned_buf=(unsigned char*)CONFIG_ALIGNED_PIC_PROC_MEM_BASE;
+	unsigned int *q;
+
+	if(argc > EXTERNAL_PROCS_MAX_ARGC)
+	{
+		printf("The count of arguments should be less than %d.\n",EXTERNAL_PROCS_MAX_ARGC);
+		return -1;
+	}
+
+	if(1 == argc)
+	{
+		printf("%s",cmdtp->help);
+		return -1;
+	}
+
+	app = (unsigned int *)(gd->relocaddr+(unsigned long)_bss_end_ofs);
+
+	for(i=0;i<sizeof(this_code_attr)/sizeof(struct external_code_attr);i++)
+	{
+		char *argument[1];
+		char argv_0[2]={0};
+		argument[0]=argv_0;
+
+		memcpy(app_aligned_buf,app,0x300);
+		q=(unsigned int *)app_aligned_buf;	
+
+		if(q[0] == magic[0] && q[1] == magic[1]) 
+		{	  
+			argv_0[0]=EXTERNAL_PIC_PROCESSES_GET_KEY_WORD_CMD;
+			ret = do_go_exec((void*)app_aligned_buf, 1, argument);
+			if(ret>0)
+			{
+				this_code_attr[i].key_word=ret;
+			}
+			argv_0[0]=EXTERNAL_PIC_PROCESSES_GET_FILE_SIZE_CMD;
+			ret = do_go_exec((void*)app_aligned_buf, 1, argument);
+			if(ret>0)
+			{
+				this_code_attr[i].file_size=ret;
+			}
+			argv_0[0]=EXTERNAL_PIC_PROCESSES_GET_CONTEXT_SIZE_CMD;
+			ret = do_go_exec((void*)app_aligned_buf, 1, argument);
+			if(ret>0)
+			{
+				this_code_attr[i].context_size=ret;
+			}
+			this_code_attr[i].addr=(unsigned char *)app;
+			file_crc=crc32 (0, (uchar *)this_code_attr[i].addr, this_code_attr[i].file_size);
+			this_code_attr[i].file_crc=file_crc;
+			app=(unsigned int *)((unsigned int)app+this_code_attr[i].file_size); //try to get the next PIC processes.
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	if(q[0] == magic[0] && q[1] == magic[1])
+	{
+		printf("Too many PIC processes! We only contains %d proecesses.\n",sizeof(this_code_attr)/sizeof(struct external_code_attr));
+	}
+
+	//skip the "call_external_proc" command.
+	argc-=1;
+	argv++;  
+
+	if(0==strcmp(argv[0],"list"))
+	{
+		for(i=0;i<sizeof(this_code_attr)/sizeof(struct external_code_attr);i++)
+		{
+			if(0!=this_code_attr[i].key_word)
+			{
+				p=(char *)(&this_code_attr[i].key_word);
+				printf("%d:key_word=[%c%c%c%c],addr=[0x%X],file_crc=[0x%X],file_size=[0x%X],context_size=[0x%X].\n",
+						i,p[3],p[2],p[1],p[0],(unsigned int)this_code_attr[i].addr,this_code_attr[i].file_crc,this_code_attr[i].file_size,this_code_attr[i].context_size);
+			}
+			else
+			{
+				break;
+			}
+		}
+	}
+	else
+	{
+		int key_num=(argv[0][0]<<24|argv[0][1]<<16|argv[0][2]<<8|argv[0][3]);
+		int icache_flag=0;
+
+		for(i=0;i<sizeof(this_code_attr)/sizeof(struct external_code_attr);i++)
+		{
+			if(key_num == this_code_attr[i].key_word)
+			{
+#ifndef PIC_PROC_HAS_SEPERATE_SPACE	  	
+				unsigned char *app_ori_buf=NULL;
+#endif		
+				found=1;
+
+				if(CONFIG_UBOOT_EXTERNAL_PROC_LEN<this_code_attr[i].context_size)
+				{
+					printf("ERROR:The context exceed CONFIG_UBOOT_EXTERNAL_PROC_LEN bytes, it's too big to execute in PIC proc buffer.\n");
+					break;
+				}
+
+#ifndef PIC_PROC_HAS_SEPERATE_SPACE        
+				app_ori_buf=(unsigned char *)malloc(((this_code_attr[i].context_size+(sizeof(unsigned int)-1)))&(~(sizeof(unsigned int)-1)));
+				if(NULL==app_ori_buf)
+				{
+					printf("%s:malloc failed,size is 0x%X bytes.\n",__FUNCTION__,this_code_attr[i].context_size);
+					break;    
+				}
+				app_aligned_buf=(unsigned char *)(((int)(app_ori_buf+(sizeof(unsigned int)-1)))&(~(sizeof(unsigned int)-1)));
+#else        
+				app_aligned_buf=(unsigned char*)CONFIG_ALIGNED_PIC_PROC_MEM_BASE;
+#endif
+				memcpy(app_aligned_buf,this_code_attr[i].addr,this_code_attr[i].file_size);
+				//disable icache
+				if(0!=icache_status())
+				{
+					icache_flag=1;
+					icache_disable();
+				}
+				if(0!=dcache_status())
+				{
+					//flush dcache.
+					dcache_disable();
+					dcache_enable();
+				}
+				ret = do_go_exec((void*)app_aligned_buf, argc, argv);
+				//enable icache if needed.
+				if(1==icache_flag)
+				{
+					icache_enable();
+				}
+
+#ifndef PIC_PROC_HAS_SEPERATE_SPACE        
+				if(NULL != app_ori_buf)
+				{
+					free(app_ori_buf);
+					app_ori_buf=NULL;
+				}        
+#endif    
+				break;
+			}	  
+		}  
+
+		if(0 == found)
+		{
+			printf("Can not find any PIC processes whose key word is [%s].\n",argv[0]);
+		}
+	}
+
+#ifndef PIC_PROC_HAS_SEPERATE_SPACE
+	if(NULL != ori_buf)
+	{
+		free(ori_buf);
+		ori_buf=NULL;
+	}
+#endif
+
+	return 0;
+
+}
+
+U_BOOT_CMD(
+		call_external_proc, EXTERNAL_PROCS_MAX_ARGC, 0, do_call_external_proc,
+		"call external PIC process.\n",
+		"list - list attribute of all the PIC processes\n"
+		"call_external_proc key_word [args..] - call the process whose key word is \"key_word\".\n"		
+	  );
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_cnc1900_audio.c u-boot-2011.06/common/cmd_cnc1900_audio.c
--- u-boot-2011.06_original/common/cmd_cnc1900_audio.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_cnc1900_audio.c	2015-08-20 19:25:54.678159000 +0800
@@ -0,0 +1,356 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include <cnc1900_clock_reg.h>
+#include <cnc1900_audio_reg.h>
+
+#define power_clk_write(a,v) *((volatile unsigned int *)(a)) = v
+#define power_clk_read(a)    (*((volatile unsigned int *)(a)))
+
+#define write_ahb32(a,v) *((volatile unsigned int *)(a)) = v
+#define read_ahb32(a)    (*((volatile unsigned int *)(a)))
+
+//Audio
+typedef enum _AUDIO_CLOCK_MODE_e_
+{
+	_AUDIO_192KHz       ,
+	_AUDIO_176KHZ		,
+	_AUDIO_128KHZ		,
+	_AUDIO_96KHz 		,
+	_AUDIO_88_2KHz		,
+	_AUDIO_64KHz		,
+	_AUDIO_48KHz		,
+	_AUDIO_44_1KHz		,
+	_AUDIO_32KHz		,
+	_AUDIO_24KHz		,
+	_AUDIO_22_05KHz		,
+	_AUDIO_16KHz		,
+	_AUDIO_12KHz		,
+	_AUDIO_11_025KHz	,
+	_AUDIO_8KHz	        ,
+}AUDIO_CLOCK_MODE;
+
+enum aud_pll_postdiv {
+    aud_target_freq      ,
+	audpll_div_F         ,
+	audpll_div_Q         ,
+	audclk_postdiv
+};
+
+
+static const unsigned int aud_pll_cfg[16][4] =
+{   //target_freq  audpll_div_F  audpll_div_Q  audclk_postdiv 
+	{  192000,      32768000,      8,                  2     },   
+	{  176400,      35665850,      8,                  2     }, 
+	{  128000,      32768000,      8,                  3     }, 
+	{   96000,      32768000,     17,                  2     },   
+	{   88200,      64198531,     19,                  2     },            
+	{   64000,      32768000,     26,                  2     },       
+	{   48000,      32768000,     23,                  3     },       
+	{   44100,      33349886,     10,                  7     },       
+	{   32000,      32768000,     26,                  4     }, 
+	{   24000,      62086737,     18,                  8     },       
+	{   22050,      64198531,     19,                  8     },       
+	{   16000,      32768000,     26,                  8     }, 
+	{   12000,      62086737,     18,                 16     },       
+	{   11025,      64198531,     19,                 16     },       
+	{    8000,      63195429,     27,                 16     }      
+};
+
+typedef unsigned int U32;
+typedef unsigned short U16;
+typedef unsigned char U8;
+
+typedef enum
+{
+    I2S_SUCCESS = 0,
+    I2S_FAILED,
+}I2S_RETURN_VALUE;
+
+
+typedef enum
+{
+    I2S_0 = 0,
+    I2S_1,        
+    I2S_2,        
+    I2S_3,        
+}I2S_ID;
+
+typedef struct i2s_element_s
+{
+    I2S_ID i2s_id;
+    U32 UP0;
+    U32 LOW0;
+    U32 SCAL0; // Q24
+    U32 UP1;
+    U32 LOW1;
+    U32 SCAL1; // Q24
+    U8 mixing;
+    U8 todac;
+    U8 tohdmi;    
+    U8 unify;
+    U8 mix_sync;
+    
+}I2S_ELEMENT_t;
+
+typedef union _I2S_CONTROL
+{
+	U32 audio_i2s_control;
+	struct _bits_t
+	{
+		U32 invert_WS					:1	;
+		U32 lsb_first   				:1	;
+		U32 philip_std  				:1	;
+		U32 ws_16b                      :1	;
+		U32 i2s0_to_dac                 :1	;
+		U32 i2s1_to_dac                 :1	;
+		U32 i2s2_to_dac                 :1	;
+		U32 i2s3_to_dac                 :1	;
+		U32 i2s0_to_hdmi                :1	;
+		U32 i2s1_to_hdmi                :1	;
+		U32 i2s2_to_hdmi                :1	;
+		U32 i2s3_to_hdmi                :1	;
+        U32 i2s0_flush                  :1  ;
+        U32 i2s1_flush                  :1  ;
+        U32 i2s2_flush                  :1  ;
+        U32 i2s3_flush                  :1  ;
+        U32 mixer0_enable               :1  ;
+        U32 mixer1_enable               :1  ;
+        U32 mixer2_enable               :1  ;
+        U32 mixer3_enable               :1  ;
+        U32 i2s0_unify                   :1  ;
+        U32 i2s1_unify                   :1  ;
+        U32 i2s2_unify                   :1  ;
+        U32 i2s3_unify                   :1  ;
+		U32 i2s0_mixer_sync				:1   ;
+		U32 i2s1_mixer_sync				:1   ;
+		U32 i2s2_mixer_sync				:1   ;
+		U32 i2s3_mixer_sync				:1   ;
+		U32 i2s_hbr						:1  ;
+        U32 reserved                    :3 ;
+	}bit;
+}I2S_CONTROL, *PI2S_CONTROL;
+
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE audclk_rate);
+I2S_RETURN_VALUE i2s_channel_set(I2S_ELEMENT_t *i2s_element);
+
+static int do_audio (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+	I2S_ELEMENT_t i2s_element;
+	int sample_rate;
+	unsigned int start, size;
+	int i;
+	
+	if (argc < 4)
+		return cmd_usage(cmdtp);
+	
+	sample_rate = simple_strtoul(argv[1], NULL, 10);
+	start = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+	if(sample_rate < 0 || sample_rate > _AUDIO_8KHz){
+		printf("Invalid sample rate specified. Valid sample rates are:\n");
+		for(i = 0; i <= _AUDIO_8KHz; i++){
+			printf("\t%d: %d Hz\n", i, aud_pll_cfg[i][aud_target_freq]);
+		}
+		return -1;
+	}
+	if(start & 0x7 || size & 0x7){
+		printf("Start address and size must be aligned to 8 bytes\n");
+		return -1;
+	}
+
+	power_clk_write(CLOCK_PLL_CLK_EN, power_clk_read(CLOCK_PLL_CLK_EN) | (1 << 22));
+	printf("[CLOCK_PLL_CLK_EN] = %08x\n", power_clk_read(CLOCK_PLL_CLK_EN));
+
+	printf("Setting audio clock to %d Hz\n", aud_pll_cfg[sample_rate][aud_target_freq]);
+	clock_audio_setclock(sample_rate);
+	
+    i2s_element.i2s_id = I2S_0;
+    i2s_element.UP0 = start + size;
+    i2s_element.LOW0 = start;
+    i2s_element.SCAL0 = 0x1000000;
+    i2s_element.UP1 = i2s_element.UP0;
+    i2s_element.LOW1 = i2s_element.LOW0;
+    i2s_element.SCAL1 = i2s_element.SCAL0;
+    i2s_element.mixing = 0;
+    i2s_element.todac = 0;
+    i2s_element.tohdmi = 1;
+    i2s_element.unify = 0;
+    i2s_element.mix_sync = 0;
+
+	printf("Setting up I2S channel 0\n");
+	if(i2s_channel_set(&i2s_element) != I2S_SUCCESS){
+		printf("Setup failed\n");
+		return -1;
+	}
+
+	printf("[CSM1300_AUD_I2S_CNTL] = 0x%08x\n", read_ahb32(CSM1300_AUD_I2S_CNTL));
+	printf("Setting up I2S DMA from 0x%08x to 0x%08x\n", start, start + size - 8);
+	write_ahb32(CSM1300_AUD_I2S_WP0 + 0x100 * 0, start + size - 8);
+
+	return 0;
+}
+
+I2S_RETURN_VALUE i2s_channel_set(I2S_ELEMENT_t *i2s_element)
+{
+	U32 i2s_offset;
+	U32 I2S_RP_reg, I2S_WP_reg, I2S_UP_reg, I2S_LOW_reg, I2S_SCAL_reg;
+	U32 control_status = 0;
+
+	if (i2s_element->i2s_id > I2S_3|| 
+		(i2s_element->UP0 & 0x7) ||
+		(i2s_element->LOW0 & 0x7) ||
+		(i2s_element->UP1 & 0x7) ||
+		(i2s_element->LOW1 & 0x7) ||
+		(i2s_element->LOW0 > i2s_element->UP0) ||
+		(i2s_element->LOW1 > i2s_element->UP1)
+		)
+	{
+		return I2S_FAILED; 
+	}
+
+	i2s_offset = i2s_element->i2s_id;
+
+	I2S_RP_reg = CSM1300_AUD_I2S_RP0 + 0x100*i2s_offset;
+	I2S_WP_reg = CSM1300_AUD_I2S_WP0 + 0x100*i2s_offset; 
+	I2S_UP_reg = CSM1300_AUD_I2S_UP0 + 0x100*i2s_offset;
+	I2S_LOW_reg = CSM1300_AUD_I2S_LOW0 + 0x100*i2s_offset;
+	I2S_SCAL_reg = CSM1300_AUD_I2S_SCAL0 + 0x100*i2s_offset;
+	write_ahb32(I2S_RP_reg, i2s_element->LOW0);
+	write_ahb32(I2S_WP_reg, i2s_element->LOW0);
+	write_ahb32(I2S_UP_reg, i2s_element->UP0);
+	write_ahb32(I2S_LOW_reg, i2s_element->LOW0);
+	write_ahb32(I2S_SCAL_reg, i2s_element->SCAL0);
+
+	I2S_RP_reg = CSM1300_AUD_I2S_RP1 + 0x100*i2s_offset;
+	I2S_WP_reg = CSM1300_AUD_I2S_WP1 + 0x100*i2s_offset; 
+	I2S_UP_reg = CSM1300_AUD_I2S_UP1 + 0x100*i2s_offset;
+	I2S_LOW_reg = CSM1300_AUD_I2S_LOW1 + 0x100*i2s_offset;
+	I2S_SCAL_reg = CSM1300_AUD_I2S_SCAL1 + 0x100*i2s_offset;
+	write_ahb32(I2S_RP_reg, i2s_element->LOW1);
+	write_ahb32(I2S_WP_reg, i2s_element->LOW1);
+	write_ahb32(I2S_UP_reg, i2s_element->UP1);
+	write_ahb32(I2S_LOW_reg, i2s_element->LOW1);
+	write_ahb32(I2S_SCAL_reg, i2s_element->SCAL1);
+
+	control_status = read_ahb32(CSM1300_AUD_I2S_CNTL);
+
+	if (i2s_element->mixing == 1)
+		control_status |= 1<<(i2s_offset + 16);
+	else
+		control_status &= ~(1<<(i2s_offset + 16));
+
+	if (i2s_element->tohdmi == 1)
+		control_status |= 1<<(i2s_offset + 8);
+	else
+		control_status &= ~(1<<(i2s_offset + 8));
+
+	if (i2s_element->todac == 1)
+		control_status |= 1<<(i2s_offset + 4);
+	else
+		control_status &= ~(1<<(i2s_offset + 4));
+
+	if (i2s_element->unify == 1)
+		control_status |= 1<<(i2s_offset + 20);
+	else
+		control_status &= ~(1<<(i2s_offset + 20));
+
+	if (i2s_element->mix_sync == 1)
+		control_status |= 1<<(i2s_offset + 24);
+	else
+		control_status &= ~(1<<(i2s_offset + 24));
+
+	write_ahb32(CSM1300_AUD_I2S_CNTL, control_status);
+
+	return I2S_SUCCESS;    
+}
+
+I2S_RETURN_VALUE i2s_flush_simple(I2S_ID i2s_id)
+{
+    
+    U32 i2s_offset;
+    
+    U32 control_status;
+
+    i2s_offset = i2s_id;
+    if (i2s_offset > I2S_3)
+    {
+        return I2S_FAILED;
+    }
+
+    control_status = read_ahb32(CSM1300_AUD_I2S_CNTL);
+
+    /* set flush bit */
+    control_status |= 1<<(i2s_offset + 12);
+    write_ahb32(CSM1300_AUD_I2S_CNTL, control_status);
+
+    /* clear flush bit */
+    control_status &= ~(1<<(i2s_offset + 12));
+    write_ahb32(CSM1300_AUD_I2S_CNTL, control_status);
+
+    return I2S_SUCCESS;
+}
+
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE audclk_rate)
+{
+    unsigned int   data;
+
+   // printk("CNC1900 Audio Target freq = %d\n", aud_pll_cfg[audclk_rate][aud_target_freq]);
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFF7FF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable audio pcm clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFCF;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //aud pll & divider reset
+
+    power_clk_write(PLL_AUD_PARA_Q, aud_pll_cfg[audclk_rate][audpll_div_Q]);
+    power_clk_write(PLL_AUD_PARA_F, aud_pll_cfg[audclk_rate][audpll_div_F]);
+    power_clk_write(CLOCK_AUD_DIV, aud_pll_cfg[audclk_rate][audclk_postdiv]);
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000010;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000030;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000800;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable audio pcm clock
+
+}
+
+U_BOOT_CMD(
+	audio, 4, 1, do_audio,
+	"output PCM samples to I2S0",
+	"sample_rate address size_in_byte"
+);
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_cnc1900_otp.c u-boot-2011.06/common/cmd_cnc1900_otp.c
--- u-boot-2011.06_original/common/cmd_cnc1900_otp.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_cnc1900_otp.c	2014-11-19 00:41:17.367468000 +0800
@@ -0,0 +1,673 @@
+#include <common.h>
+#ifndef STANDALONE_OTP
+#include <exports.h>
+#else
+#include <command.h>
+#endif
+
+/* Secure Core register space */
+#define SECURE_BASE             0xfffff800
+#define SECURE_MAILBOX0         (SECURE_BASE + 0x00)
+#define SECURE_MAILBOX1         (SECURE_BASE + 0x04)
+#define SECURE_MAILBOX2         (SECURE_BASE + 0x08)
+#define SECURE_MAILBOX3         (SECURE_BASE + 0x0c)
+#define SECURE_MAILBOX4         (SECURE_BASE + 0x10)
+#define SECURE_MAILBOX5         (SECURE_BASE + 0x14)
+#define SECURE_MAILBOX6         (SECURE_BASE + 0x18)
+#define SECURE_MAILBOX7         (SECURE_BASE + 0x1c)
+
+#define OTP_REG_WRITE(addr, val) (*((volatile unsigned int *)(addr)) = (val))
+#define OTP_REG_READ(addr)       (*((volatile unsigned int *)(addr)))
+
+/* Generic Error code */
+#define OTP_GEN_INVALID_CMD	-1
+#define OTP_GEN_LAST_TIMEOUT	-2
+#define OTP_GEN_CMD_TIMEOUT	-3
+
+/* Error code for cmd 0x12, 0x13 */
+#define OTP_PV_SUCCESS	0
+#define OTP_PV_INVALID_IDX	1
+#define OTP_PV_ACCESS_DENIED	2
+#define OTP_PV_PROGRAM_DENIED_FACTORY	3
+#define OTP_PV_PROGRAM_DENIED_LOCKED	4
+#define OTP_PV_PROGRAM_DENIED_ONEWAY	5
+#define OTP_PV_PROGRAM_FAILURE	6
+#define OTP_PV_MAX_ERROR	6
+
+/* Error code for cmd 0x14, 0x15 */
+#define OTP_RW_SUCCESS	0
+#define OTP_RW_INVALID_ADDR	1
+#define OTP_RW_ACCESS_DENIED	2
+#define OTP_RW_ACCESS_FAILED	3
+#define OTP_RW_MAX_ERROR	3
+
+const char *otp_err_generic[] = {
+	"No error",
+	"Invalid command",
+	"Last command not fetched",
+	"Command timeout",
+};
+
+const char *otp_err_pv[] = {
+	"No error",
+	"Invalid PV index",
+	"Access denied for secret PV",
+	"Program denied for factory-programmed PV",
+	"Program denied for lockable PV",
+	"Program denied for one-way PV",
+	"Program failure",
+};
+
+const char *otp_err[] = {
+	"No error",
+	"Invalid address",
+	"Access denied",
+	"Program failure"
+};
+
+#ifdef STANDALONE_OTP
+int do_otp(int argc, char *const argv[]);
+
+int main_proc(int argc, char *const argv[])
+{
+	app_startup(argv);
+	do_otp(argc, argv);
+}
+#endif
+const char *otp_error(int pv, char status)
+{
+	if(status <= 0){
+		return otp_err_generic[-status];
+	}
+	if(pv && status <= OTP_PV_MAX_ERROR){
+		return otp_err_pv[(int)status];
+	}else if(status <= OTP_RW_MAX_ERROR){
+		return otp_err[(int)status];
+	}else{
+		return "Unknown error";
+	}
+
+}
+
+/* Read OTP interface */
+/* Valid len = 1, 2, 4 or 5 */
+char __otp_read(unsigned int cmd, const unsigned int idx, unsigned int *data, int len)
+{
+	unsigned int RegVal = 0;
+	unsigned int timeout;
+
+	/* 1.0 check last command reponded */
+	RegVal = OTP_REG_READ(SECURE_MAILBOX0);
+	timeout = 0;
+	while(RegVal & 0x80000000)
+	{
+		if(timeout++ > 100000){
+			return OTP_GEN_LAST_TIMEOUT;
+		}
+		RegVal = OTP_REG_READ(SECURE_MAILBOX0);
+	}
+
+	/* 2.0 Write index of PV value */
+	OTP_REG_WRITE(SECURE_MAILBOX1, idx);
+
+	/* 3.0 clear status register */
+	OTP_REG_WRITE(SECURE_MAILBOX7, 0x0);
+
+	/* 4.0 send OTP Read command */
+	OTP_REG_WRITE(SECURE_MAILBOX0, 0x80000000 | cmd);
+
+	/* 5.0 Check status register */
+	RegVal = OTP_REG_READ(SECURE_MAILBOX7);
+	timeout = 0;
+	while (!(RegVal & 0x80000000))
+	{
+		if(timeout++ > 100000){
+			return OTP_GEN_CMD_TIMEOUT;
+		}
+		RegVal = OTP_REG_READ(SECURE_MAILBOX7);
+	}
+
+	/* 6.0 Check core status */
+	if(RegVal & 0xffff){
+		return (char)(RegVal & 0xff);
+	}
+
+	/* 7.0 Read PV out */
+	data[0] = OTP_REG_READ(SECURE_MAILBOX2);
+	if(len >= 2){
+		data[1] = OTP_REG_READ(SECURE_MAILBOX3);
+	}
+	if(len >= 3){
+		data[2] = OTP_REG_READ(SECURE_MAILBOX4);
+	}
+	if(len >= 4){
+		data[3] = OTP_REG_READ(SECURE_MAILBOX5);
+	}
+	if(len >= 5){
+		data[4] = OTP_REG_READ(SECURE_MAILBOX6);
+	}
+	/* 8.0 Clear status register to 0 */
+	OTP_REG_WRITE(SECURE_MAILBOX7, 0x0);
+
+	return (char)(RegVal & 0xff);
+}
+
+/* Write OTP using PV interface */
+/* Valid len = 1, 2 or 4 */
+char __otp_write(unsigned int cmd, const unsigned int idx, unsigned int *data, int len)
+{
+	unsigned int RegVal = 0;
+	unsigned int timeout;
+
+	/* 1.0 check last command reponded */
+	RegVal = OTP_REG_READ(SECURE_MAILBOX0);
+	timeout = 0;
+	while(RegVal & 0x80000000)
+	{
+		if(timeout++ > 100000){
+			return OTP_GEN_LAST_TIMEOUT;
+		}
+		RegVal = OTP_REG_READ(SECURE_MAILBOX0);
+	}
+
+	/* 2.0 Write index of PV value */
+	OTP_REG_WRITE(SECURE_MAILBOX1, idx);
+
+	/* 3.0 clear status register */
+	OTP_REG_WRITE(SECURE_MAILBOX7, 0x0);
+
+	/* 7.0 Write PV in */
+	OTP_REG_WRITE(SECURE_MAILBOX2, data[0]);
+	if(len >= 2){
+		OTP_REG_WRITE(SECURE_MAILBOX3, data[1]);
+	}
+	if(len >= 3){
+		OTP_REG_WRITE(SECURE_MAILBOX4, data[2]);
+	}
+	if(len >= 4){
+		OTP_REG_WRITE(SECURE_MAILBOX5, data[3]);
+	}
+	/* 4.0 send OTP Read command */
+	OTP_REG_WRITE(SECURE_MAILBOX0, 0x80000000 | cmd);
+
+	/* 5.0 Check status register */
+	RegVal = OTP_REG_READ(SECURE_MAILBOX7);
+	timeout = 0;
+	while (!(RegVal & 0x80000000))
+	{
+		if(timeout++ > 100000){
+			return OTP_GEN_CMD_TIMEOUT;
+		}
+		RegVal = OTP_REG_READ(SECURE_MAILBOX7);
+	}
+
+	/* 8.0 Clear status register to 0 */
+	OTP_REG_WRITE(SECURE_MAILBOX7, 0x0);
+
+	return (char)(RegVal & 0xff);
+}
+
+
+char otp_read_pv(const unsigned int idx, unsigned int *data, int len)
+{
+	return __otp_read(0x12, idx, data, len);
+}
+
+char otp_write_pv(const unsigned int idx, unsigned int *data, int len)
+{
+	return __otp_write(0x13, idx, data, len);
+}
+
+char otp_read(int area, unsigned int addr, unsigned int *data)
+{
+	return __otp_read(0x14, addr + (area << 16), data, 1);
+}
+
+char otp_write(int area, unsigned int addr, unsigned int data)
+{
+	return __otp_write(0x15, addr + (area << 16), &data, 1);
+}
+
+#ifdef STANDALONE_OTP
+int do_otp(int argc, char *const argv[])
+#else
+int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+#endif
+{
+	char *cmd;
+	int area, idx;
+	int len=0;
+	int i;
+	int status=-1;
+	unsigned int data[4], data_v[4], sha1[5];
+	unsigned int *hdcp_addr;
+
+	if (argc < 3)goto usage;
+	cmd = argv[1];
+
+	if(argv[2][0] == '0' || argv[2][0] == '1'){
+		area = argv[2][0] - '0';
+	}else if(strcmp(argv[2], "pv") == 0){
+		area = -1;
+	}else{
+		goto usage;
+	}
+
+	if(argc < 4){
+		idx = -1;
+	}else{
+		idx = simple_strtoul(argv[3], NULL, 16);
+	}
+
+	if(area == -1){
+		if(argc < 5){
+			len = -1;
+		}else{
+			len = simple_strtoul(argv[4], NULL, 16);
+			if(len < 1 || len > 4)goto usage;
+		}
+	}
+
+	if(strcmp(cmd, "read") == 0){
+		if(area == -1 && idx >= 0 && len > 0){
+			status = otp_read_pv(idx, data, len);
+			if(!status){
+				printf("OTP_PV[0x%x] = ", idx);
+				for(i = 0; i < len; i++){
+					printf("0x%08x, ", data[i]);
+				}
+				printf("\n");
+			}else{
+				printf("Failed reading OTP_PV[0x%x], status = %s (%d)\n", idx, otp_error(1, status), status);
+			}
+		}else if(area != -1 && idx >=0){
+			status = otp_read(area, idx, &data[0]);
+			if(!status){
+				printf("OTP%d[0x%x] = 0x%08x\n", area, idx, data[0]);
+			}else{
+				printf("Failed reading OTP[0x%x], status = %s (%d)\n", idx, otp_error(0, status), status);
+			}
+		}else{
+			goto usage;
+		}
+	}
+	if(strcmp(cmd, "write") == 0){
+		if(area == -1 && idx >= 0 && len > 0){
+			if(argc < 5 + len) goto usage;
+			for(i = 0; i < len; i++){
+				data[i] = simple_strtoul(argv[5 + i], NULL, 16);
+#ifdef DEBUG
+				printf("data[%d] = 0x%08x\n", i, data[i]);
+#endif
+			}
+			status = otp_write_pv(idx, data, len);
+			if(status){
+				printf("Failed write status = %s (%d)\n", otp_error(1, status), status);
+				return status;
+			}
+			status = otp_read_pv(idx, data_v, len);
+			if(!status){
+				for(i = 0; i < len; i++){
+					if(data[i] != data_v[i]){
+#ifdef DEBUG
+						printf("Verification failed at OTP_PV[0x%x][%d], expect = 0x%08x, read = 0x%08x\n",
+								idx, i, data[i], data_v[i]);
+#else
+						printf("Verification failed at OTP_PV[0x%x][%d]\n",	idx, i);
+#endif
+					}
+				}
+			}else{
+				printf("Failed reading OTP_PV[0x%x], status = %s (%d)\n", idx, otp_error(1, status), status);
+			}
+
+		}else if(idx >= 0 && argc >= 5){
+			data[0] = simple_strtoul(argv[4], NULL, 16);
+			status = otp_write(area, idx, data[0]);
+			if(status){
+				printf("Failed write status = %s (%d)\n", otp_error(0, status), status);
+				return status;
+			}
+			status = otp_read(area, idx, &data_v[0]);
+			if(!status){
+				if(data[0] != data_v[0]){
+#ifdef DEBUG
+					printf("Verification failed at OTP%d[0x%x], expect = 0x%08x, read = 0x%08x\n", area, idx, data[0], data_v[0]);
+#else
+					printf("Verification failed at OTP%d[0x%x]\n", area, idx);
+#endif
+				}
+			}else{
+				printf("Failed reading OTP%d[0x%x], status = %s (%d)\n", area, idx, otp_error(0, status), status);
+			}
+		}else{
+			goto usage;
+		}
+	}
+	if(strcmp(cmd, "hdcp") == 0){
+		hdcp_addr = (unsigned int *)simple_strtoul(argv[2], NULL, 16);
+		for(i = 0; i < 80; i++){
+			printf("Writing HDCP[%d] = %08x\n", i, hdcp_addr[i]);
+
+			status = otp_write(1, i, hdcp_addr[i]);
+			printf("write status = %s (%d)\n", otp_error(0, status), status);
+			status = otp_read(1, i, &data_v[0]);
+			if(!status){
+				if(hdcp_addr[i] != data_v[0]){
+#ifdef DEBUG
+					printf("Verification failed at OTP%d[0x%x], expect = 0x%08x, read = 0x%08x\n", 1, i, hdcp_addr[i], data_v[0]);
+#else
+					printf("Verification failed at OTP%d[0x%x]\n", 1, i);
+#endif
+				}
+			}else{
+				printf("Failed reading OTP%d[0x%x], status = %s (%d)\n", 1, i, otp_error(0, status), status);
+			}
+
+		}
+	}
+	if(strcmp(cmd, "dump") == 0){
+		if(area == -1){
+			for(i = 0; i <= 0x1a; i++){
+				status = otp_read_pv(i, data, 4);
+				if(!status){
+					printf("OTP_PV[0x%x] = {0x%08x, 0x%08x, 0x%08x, 0x%08x}\n", i, data[0], data[1], data[2], data[3]);
+				}else{
+					printf("Failed reading OTP_PV[0x%x], status = %s (%d)\n", i, otp_error(1, status), status);
+				}
+			}
+		}else{
+			for(i = 0; i < 128 ; i++){
+				status = otp_read(area, i, &data[0]);
+				if(!status){
+					printf("OTP%d[0x%x] = 0x%08x\n", area, i, data[0]);
+				}else{
+					printf("Failed reading OTP[0x%x], status = %s (%d)\n", i, otp_error(0, status), status);
+				}
+			}
+			__otp_read(0x28, area, sha1, 5);
+			printf("SHA1[OTP%d] = ", area);
+			for(i = 0; i < 20; i++){
+				printf("%02x", ((unsigned char *)sha1)[i] );
+			}
+			printf("\n");
+		}
+	}
+	return status;
+usage:
+	printf("Syntax error\n");
+	return 1;
+}
+
+int do_uid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned int uid[4];
+	unsigned int lock;
+
+	otp_read_pv(7, &lock, 1);
+
+	if (lock == 1) {
+		otp_read(0, 0, &uid[0]);
+		otp_read(0, 1, &uid[1]);
+		otp_read(0, 2, &uid[2]);
+		otp_read(0, 3, &uid[3]);
+	} else
 {
+		otp_read(0, 0x11, &uid[0]);
+		otp_read(0, 0x12, &uid[1]);
+		otp_read(0, 0x13, &uid[2]);
+		otp_read(0, 0x14, &uid[3]);
+	}
+
+	printf("0x%08X%08X%08X%08X\n", uid[0], uid[1], uid[2], uid[3]);
+
+	return 1;
+}
+
+int otp_read_sha256(unsigned int *sha256)
+{
+	unsigned int lock;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		otp_read(0, 4, &sha256[0]);
+		otp_read(0, 5, &sha256[1]);
+		otp_read(0, 6, &sha256[2]);
+		otp_read(0, 7, &sha256[3]);
+		otp_read(0, 8, &sha256[4]);
+		otp_read(0, 9, &sha256[5]);
+		otp_read(0, 10, &sha256[6]);
+		otp_read(0, 11, &sha256[7]);
+		return 0;
+	}
+
+	return -1;
+}
+
+int otp_read_version(unsigned short *version)
+{
+	unsigned int lock, found = 0;
+	unsigned int version_tmp;
+	int i, j;
+
+	*version = 0;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		for (i=12; i<20; i++)
+		{
+			otp_read(0, i, &version_tmp);
+			for (j=0; j<32; j++)
+			{
+				if (version_tmp & ( 1 << j ))
+				{
+					if ( found == 0 )
+						(*version) += 1;
+					else
+						return -1;
+				}
+				else
+					found = 1;
+			}
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+int otp_read_version_uboot(unsigned char *version)
+{
+	unsigned int lock, found = 0;
+	unsigned int version_tmp;
+	int i, j;
+
+	*version = 0;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		for (i=20; i<24; i++)
+		{
+			otp_read(0, i, &version_tmp);
+			for (j=0; j<32; j++)
+			{
+				if (version_tmp & ( 1 << j ))
+				{
+					if ( found == 0 )
+						(*version) += 1;
+					else
+						return -1;
+				}
+				else
+					found = 1;
+			}
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+int otp_write_version(unsigned short version)
+{
+	unsigned int lock;
+	unsigned int index, offset;
+
+	if (version > 256)
+		return -1;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		index = version / 32;
+		offset = version % 32;
+		if (offset == 0)
+		{
+			index--;
+			offset = 32;
+		}
+		otp_write(0, 12+index, 1<<(offset-1));
+		return 0;
+	}
+
+	return -1;
+}
+
+int otp_write_version_uboot(unsigned char version)
+{
+	unsigned int lock;
+	unsigned int index, offset;
+
+	if (version > 128)
+		return -1;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		index = version / 32;
+		offset = version % 32;
+		if (offset == 0)
+		{
+			index--;
+			offset = 32;
+		}
+		otp_write(0, 20+index, 1<<(offset-1));
+		return 0;
+	}
+
+	return -1;
+}
+
+int do_otp_ver(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned short ver;
+
+	otp_read_version(&ver);
+	printf("%d\n", (int)ver);
+
+	return 1;
+}
+
+
+int otp_check_uart_lock(void)
+{
+	unsigned int lock, data = 0;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		otp_read(0, 24, &data);
+		return data;
+	}else{
+		return 0;
+	}
+}
+
+int do_otp_uart_lock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned int lock;
+
+	otp_read_pv(7, &lock, 1);
+	if (lock == 1) {
+		printf("UART LOCKED\n");
+		otp_write(0, 24, 1);
+	}else{
+		printf("Cannot lock UART without secured OTP\n");
+	}
+	return 0;
+}
+
+int do_otp_ver_uboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned char ver;
+
+	otp_read_version_uboot(&ver);
+	printf("%d\n", (int)ver);
+
+	return 1;
+}
+
+int do_otp_ver_set(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned short ver;
+	if(argc < 2) return -1;
+	ver = simple_strtoul(argv[1], NULL, 10);
+	printf("Setting OTP version to %d\n", (int)ver);
+	otp_write_version(ver);
+
+	return 1;
+}
+
+int do_otp_ver_uboot_set(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned short ver;
+	if(argc < 2) return -1;
+	ver = simple_strtoul(argv[1], NULL, 10);
+	printf("Setting OTP U-Boot version to %d\n", (int)ver);
+	otp_write_version_uboot(ver);
+
+	return 1;
+}
+
+#ifndef STANDALONE_OTP
+U_BOOT_CMD(
+		otp, 10, 0,	do_otp,
+		"otp operation",
+		""
+	  );
+
+U_BOOT_CMD(
+		uid, 1, 0,	do_uid,
+		"read uid from chip.\n",
+		""
+	  );
+
+U_BOOT_CMD(
+		otp_ver, 1, 0,	do_otp_ver,
+		"read OTP version from chip.\n",
+		""
+	  );
+
+U_BOOT_CMD(
+		otp_ver_uboot, 1, 0,	do_otp_ver_uboot,
+		"read OTP U-Boot version from chip.\n",
+		""
+	  );
+
+U_BOOT_CMD(
+		otp_ver_set, 2, 0,	do_otp_ver_set,
+		"set OTP version from chip.\n",
+		""
+	  );
+
+U_BOOT_CMD(
+		otp_uart_lock, 2, 0,	do_otp_uart_lock,
+		"set OTP UART Lock.\n",
+		""
+	  );
+
+
+U_BOOT_CMD(
+		otp_ver_set_uboot, 2, 0,	do_otp_ver_uboot_set,
+		"set OTP U-Boot  version from chip.\n",
+		""
+	  );
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_cncflash.c u-boot-2011.06/common/cmd_cncflash.c
--- u-boot-2011.06_original/common/cmd_cncflash.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_cncflash.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,657 @@
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#include <usb.h>
+#include <jffs2/jffs2.h>
+#include <nand.h>
+#include "cnc_util.h"
+
+typedef enum FLASH_MODE
+{
+	FLASH_MODE_READ=0,
+	FLASH_MODE_WRITE,
+	FLASH_MODE_ERASE,
+	FALSH_MODE_VERFIFY,
+	FLASH_MODE_INVALID=-1
+}FLASH_MODE;
+
+typedef enum MTD_ID
+{
+	MTD_ID_NAND_FLASH=0,
+	MTD_ID_SPI_FLASH,
+	MTD_ID_NOR_FLASH,
+	MTD_ID_EMMC_FLASH,
+	MTD_ID_INVALID=-1
+}MTD_ID;
+
+const char* CncValidMtdIdList[] = 
+{
+	"cnc-nand",
+	"s25f",
+	"cnc-spi"
+	"cnc-nor",
+	"emmc",
+	NULL
+};
+
+const char* FlashModeList[] =
+{
+	"read",
+	"write",
+	"erase",
+	"verify",
+	NULL,
+};
+
+extern int GetSizeAndOffset(const char* pBuf, int* apSize, int *apOffset);
+extern int GenerateImagePartitionListFromBootArgs(const char* apBootArgs, ImagePartitionList_t *apImagePartitionList);
+
+int GetSizeAndOffset(const char* pBuf, int* apSize, int *apOffset)
+{
+    //xx@yy
+    char TempBuf[16]={0};
+    char* p1;
+    //char* p2;
+    int multiplier=1;
+    
+    //printf("GetSizeAndOffset%s\n", pBuf);
+
+    strncpy(TempBuf, pBuf, sizeof(TempBuf) );
+
+    p1 = strstr(TempBuf, "@" );
+    if (p1 == NULL) return -1;
+
+    TempBuf[p1-TempBuf]='\0';
+    switch ( TempBuf [ strlen(TempBuf )-1] )
+    {
+        case 'k':
+            multiplier = 1024;
+            break;
+        case 'm':
+            multiplier = 1024*1024;
+            break;
+        case 'g':
+            multiplier=1024*1024*1024;
+            break;
+    }
+    *apSize = simple_strtol(TempBuf,NULL,10 )* multiplier ;   
+
+    p1++;
+    multiplier=1;
+    switch ( *(p1 + strlen(p1)-1 ) )
+    {
+        case 'k':
+            multiplier = 1024;
+            break;
+        case 'm':
+            multiplier = 1024*1024;
+            break;
+        case 'g':
+            multiplier=1024*1024*1024;
+            break;
+    }
+    *apOffset = simple_strtol(p1,NULL,10 )* multiplier ;  
+    return 0;
+
+}
+
+
+//bootargs="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200 mtdparts=s25f:56k@0k(miniloader),8k@56k(env);cnc-nand:1m@0m(free1),2m@1m(logo),6m@3m(failsafekernel),1m@9m(uboot2),4m@10m(kernel),100m@14m(rootfs),100m@114m(update),42m@214m(user)" --image1 "name=miniloader, secure=1, nand=0, erase_write=1, version=r45345, image=./test1.bin" --image2 "name=kernel, secure=1, nand=1, erase_write=1, version=r99, image=./test2.bin"
+//bootargs="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200
+//         mtdparts=s25f:56k@0k(miniloader),8k@56k(env);cnc-nand:1m@0m(free1),2m@1m(logo),6m@3m(failsafekernel),1m@9m(uboot2),4m@10m(kernel),100m@14m(rootfs),100m@114m(update),42m@214m(user)" --image1 "name=miniloader, secure=1, nand=0, erase_write=1, version=r45345, image=./test1.bin" --image2 "name=kernel, secure=1, nand=1, erase_write=1, version=r99, image=./test2.bin"
+int GenerateImagePartitionListFromBootArgs(const char* apBootArgs, ImagePartitionList_t *apImagePartitionList)
+{
+	int Status = -1;
+    const char* p1 = apBootArgs;
+    int pos = 0;
+    const char* p2 ;
+    char TempBuf[512];
+    int size;
+    int offset;
+
+    int i=0;
+    int j=0;
+
+
+    p2 = strstr(p1, SPI_TOKEN );
+    if (p2 != NULL )
+    {
+        //spi parition info exist...
+        p2 = strstr(p2,":");
+        if ( NULL == p2)
+        {
+            return Status;
+        }
+        p2 = p2 + strlen( ":" );
+
+        i=0;
+        j=0;
+	TempBuf[0]='\0';
+	strncpy(TempBuf,p2,512);
+	p2=strtok(TempBuf," ");
+        while(  (  *(p2+i) != ';') && 
+                ( *(p2+i) != '\0' ) && 
+                ( *(p2+i) != ' ' ) &&
+                ( *(p2+i) != '\"' )
+             )
+        {
+			if ( j >= sizeof(TempBuf) )
+			{
+				return -1;
+			}
+			
+            TempBuf[j] = * (p2+i);
+            i++;
+
+            if (TempBuf[j] == '(' )
+            {
+                TempBuf[j]='\0';
+                Status = GetSizeAndOffset(TempBuf,& size, & offset);
+                if (Status == -1 )
+                {
+                    return -1;
+                }
+                apImagePartitionList->mImagePartitionList[pos].mFlashAddress = offset;
+                apImagePartitionList->mImagePartitionList[pos].mLength  = size    ;
+                j=0;
+                continue;
+            }
+            else if (TempBuf[j] == ')' )
+            {
+                TempBuf[j]='\0';
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mPartionName , TempBuf);
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mMtdId , SPI_TOKEN );
+                j=0;
+                continue;
+            }
+            else if ( TempBuf[j] == ',' )
+            {
+                j=0;
+                pos++;
+                continue;
+            }
+            j++;
+        }
+    }
+
+	if (p2 != NULL )
+	{
+		if ( *(p2+i) == ';')
+		{
+			pos++;
+		}
+	}
+
+	i=0;
+    j=0;
+    p2 = strstr(p1, "emmc" );
+    if (p2 != NULL )
+    {
+        //emmc parition info exist...
+        p2 = strstr(p2,":");
+        if ( NULL == p2)
+        {
+            return Status;
+        }
+        p2 = p2 + strlen( ":" );
+
+        i=0;
+        j=0;
+	TempBuf[0]='\0';
+	strncpy(TempBuf,p2,512);
+	p2=strtok(TempBuf," ");
+        while(  (  *(p2+i) != ';') && 
+                ( *(p2+i) != '\0' ) && 
+                ( *(p2+i) != ' ' ) &&
+                ( *(p2+i) != '\"' )
+             )
+        {
+			if ( j >= sizeof(TempBuf) )
+			{
+				return -1;
+			}
+			
+            TempBuf[j] = * (p2+i);
+            i++;
+
+            if (TempBuf[j] == '(' )
+            {
+                TempBuf[j]='\0';
+                Status = GetSizeAndOffset(TempBuf,& size, & offset);
+                if (Status == -1 )
+                {
+                    return -1;
+                }
+                apImagePartitionList->mImagePartitionList[pos].mFlashAddress = offset;
+                apImagePartitionList->mImagePartitionList[pos].mLength  = size    ;
+                j=0;
+                continue;
+            }
+            else if (TempBuf[j] == ')' )
+            {
+                TempBuf[j]='\0';
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mPartionName , TempBuf);
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mMtdId , "emmc" );
+                if( *(p2+i) == '\0' )
+                {
+                	pos++;
+                }
+                j=0;
+                continue;
+            }
+            else if (TempBuf[j] == ',' )
+            {
+                j=0;
+                pos++;
+                continue;
+            }
+            j++;
+        }
+    }
+	if (p2 != NULL )
+	{
+		if ( *(p2+i) == ';')
+		{
+			pos++;
+		}
+	} 
+
+	i=0;
+    j=0;
+    p2 = strstr(p1, "cnc-nand" );
+    if (p2 != NULL )
+    {
+        //cnc-nand parition info exist...
+        p2 = strstr(p2,":");
+        if ( NULL == p2)
+        {
+            return Status;
+        }
+        p2 = p2 + strlen( ":" );
+
+        i=0;
+        j=0;
+	TempBuf[0]='\0';
+	strncpy(TempBuf,p2,512);
+	p2=strtok(TempBuf," ");
+        while(  (  *(p2+i) != ';') && 
+                ( *(p2+i) != '\0' ) && 
+                ( *(p2+i) != ' ' ) &&
+                ( *(p2+i) != '\"' )
+             )
+        {
+			if ( j >= sizeof(TempBuf) )
+			{
+				return -1;
+			}
+			
+            TempBuf[j] = * (p2+i);
+            i++;
+
+            if (TempBuf[j] == '(' )
+            {
+                TempBuf[j]='\0';
+                Status = GetSizeAndOffset(TempBuf,& size, & offset);
+                if (Status == -1 )
+                {
+                    return -1;
+                }
+                apImagePartitionList->mImagePartitionList[pos].mFlashAddress = offset;
+                apImagePartitionList->mImagePartitionList[pos].mLength  = size    ;
+                j=0;
+                continue;
+            }
+            else if (TempBuf[j] == ')' )
+            {
+                TempBuf[j]='\0';
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mPartionName , TempBuf);
+                strcpy(apImagePartitionList->mImagePartitionList[pos].mMtdId , "cnc-nand" );
+                if( *(p2+i) == '\0' )
+                {
+                	pos++;
+                }
+                j=0;
+                continue;
+            }
+            else if (TempBuf[j] == ',' )
+            {
+                j=0;
+                pos++;
+                continue;
+            }
+            j++;
+        }
+    }
+	if (p2 != NULL )
+	{
+		if ( *(p2+i) == '\"')
+		{
+			pos++;
+		}
+	}
+    apImagePartitionList->mNoOfPartition = pos;
+	return Status;	
+}
+
+
+int SearchExactStringInList(const char* pBuffer, const char* aList[])
+{
+	int i;
+
+	i=0;
+	
+	while ( aList[i] != NULL)
+	{		
+		if ( 0 == strcmp( pBuffer, aList[i] ) )
+		{
+			return i;
+		}		
+		i++;
+	}	
+	return -1;
+}
+
+int GetPartiotioIndex(  ImagePartitionList_t * apImagePartitionList, const char* apMtdId, const char* apPartitionName )
+{
+	int i;
+	for(i=0;i <	apImagePartitionList->mNoOfPartition; i++)
+	{
+		if( ( 0 == strcmp( apImagePartitionList->mImagePartitionList[i].mMtdId , apMtdId ) ) &&
+		    ( 0 == strcmp( apImagePartitionList->mImagePartitionList[i].mPartionName, apPartitionName ) )
+		  )
+		{
+			return i;
+		}
+	}
+	return -1;
+}
+
+void PrintUsage(cmd_tbl_t *cmdtp)
+{
+	cmd_usage(cmdtp);
+}
+
+
+int CncFlashTask( FLASH_MODE aFlashMode, MTD_ID  aMtdId , ImagePartition_t *apImagePartition , UInt32 aDdrAddress)
+{
+	int Status=-1;
+	switch (aFlashMode)
+	{
+		case FLASH_MODE_INVALID:
+		{
+			printf("%sERROR: Invalid FLASH_MODE supplied%s\n", ColorRed, ColorNormal);
+			return -1;
+		}
+		break;
+		
+		case FLASH_MODE_READ:
+		{
+			switch ( aMtdId)
+			{
+				case MTD_ID_NAND_FLASH:
+				{
+					Status = cnc_NandRead(apImagePartition->mFlashAddress ,
+								apImagePartition->mDdrAddress , 								 
+								apImagePartition->mLength);
+					
+				}
+				break;
+				case MTD_ID_SPI_FLASH:
+				{
+					Status = cnc_SpiRead(apImagePartition->mFlashAddress , 
+								apImagePartition->mDdrAddress ,								
+								apImagePartition->mLength);
+				}
+				break;
+				case MTD_ID_NOR_FLASH:
+				{
+					Status = cnc_NorRead(apImagePartition->mFlashAddress , 
+								apImagePartition->mDdrAddress ,								
+								apImagePartition->mLength);
+				}
+				break;
+				case MTD_ID_EMMC_FLASH:
+				{
+					Status = cnc_EMMCRead(apImagePartition->mFlashAddress , 
+								apImagePartition->mDdrAddress ,								
+								apImagePartition->mLength);
+				}
+				break;
+				case MTD_ID_INVALID:
+				{
+					printf("%sERROR: Invalid MTD_ID supplied%s\n", ColorRed, ColorNormal);
+					return -1;
+				}
+				break;
+			}
+		}
+		break;
+		
+		case FLASH_MODE_WRITE:
+		{
+			switch ( aMtdId)
+			{
+				case MTD_ID_NAND_FLASH:
+				{	
+					Status = cnc_NandWrite( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength,
+								0 /* do no spread , because we are erasing entire mtd region*/
+							);
+				}
+				break;
+				case MTD_ID_SPI_FLASH:
+				{
+					Status = cnc_SpiWrite( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_NOR_FLASH:
+				{
+					Status = cnc_NorWrite( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_EMMC_FLASH:
+				{
+					Status = cnc_EMMCWrite( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength, 0
+							);
+				}
+				break;
+				case MTD_ID_INVALID:
+				{
+					printf("%sERROR: Invalid MTD_ID supplied%s\n", ColorRed, ColorNormal);
+					return -1;
+				}
+				break;
+				
+			}
+		}
+		break;
+		case FLASH_MODE_ERASE:
+		{
+			switch ( aMtdId)
+			{
+				case MTD_ID_NAND_FLASH:
+				{
+					Status = cnc_NandErase( apImagePartition->mFlashAddress , apImagePartition->mLength, 0	);//use nand erase only. don't use erase.spread
+				}
+				break;
+				case MTD_ID_SPI_FLASH:
+				{
+					Status = cnc_SpiErase( apImagePartition->mFlashAddress , apImagePartition->mLength	);
+				}
+				break;
+				case MTD_ID_NOR_FLASH:
+				{
+					Status = cnc_NorErase( apImagePartition->mFlashAddress , apImagePartition->mLength	);
+				}
+				break;
+				case MTD_ID_EMMC_FLASH:
+				{
+//					Status = cnc_NorErase( apImagePartition->mFlashAddress , apImagePartition->mLength	);
+					printf("eMMC does not need to erase\n");
+					Status = 0;
+				}
+				break;
+				case MTD_ID_INVALID:
+				{
+					printf("%sERROR: Invalid MTD_ID supplied%s\n", ColorRed, ColorNormal);
+					return -1;
+				}
+				break;
+				
+			}
+		}
+		break;
+		case FALSH_MODE_VERFIFY:
+		{
+			switch ( aMtdId)
+			{
+				case MTD_ID_NAND_FLASH:
+				{
+					Status = cnc_NandVerify( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_SPI_FLASH:
+				{
+					Status = cnc_SpiVerify( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_NOR_FLASH:
+				{
+					Status = cnc_NorVerify( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_EMMC_FLASH:
+				{
+					Status = cnc_EMMCVerify( apImagePartition->mDdrAddress , 
+								apImagePartition->mFlashAddress , 
+								apImagePartition->mLength
+							);
+				}
+				break;
+				case MTD_ID_INVALID:
+				{
+					printf("%sERROR: Invalid MTD_ID supplied%s\n", ColorRed, ColorNormal);
+					return -1;
+				}
+				break;
+				
+			}
+		}
+		break;		
+	}
+	return Status;
+}
+
+int do_cncflash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	UInt32 DdrAddress = 0;
+	int Status=0;
+	int i;
+	FLASH_MODE FlashMode = FLASH_MODE_INVALID;
+	MTD_ID MtdId = MTD_ID_INVALID;
+	ImagePartitionList_t mImagePartitionInfoList;
+	int ExpectedArgc = 5;
+
+	if (argc == 1)
+	{
+		PrintUsage(cmdtp);
+		return 0;
+	}
+	
+	memset( &mImagePartitionInfoList, 0, sizeof(mImagePartitionInfoList) );
+	Status = GenerateImagePartitionListFromBootArgs(getenv("bootargs"), & mImagePartitionInfoList);
+	if (Status == -1)
+	{
+		printf("%sERROR: error occured while parsing bootargs, please contact vendor\n%s", ColorRed, ColorNormal);
+		return -1;
+	}
+	
+	FlashMode = SearchExactStringInList( argv[1] , FlashModeList);
+	MtdId     = SearchExactStringInList( argv[2] , CncValidMtdIdList);
+
+	if( (FlashMode == FLASH_MODE_INVALID) || (  MtdId == MTD_ID_INVALID) )
+	{
+		printf("%sERROR: invalid operation or mtdid is specified\n%s", ColorRed, ColorNormal);
+		PrintUsage(cmdtp);
+		return -1;
+	}
+	
+	i= GetPartiotioIndex( & mImagePartitionInfoList , argv[2] , argv[3] );
+
+	if ( i== -1)
+	{
+		printf("%sERROR: invalid partition name or mtdid is specified\n%s", ColorRed, ColorNormal);
+		PrintUsage(cmdtp);
+		return -1;
+	}
+	
+	if (FlashMode == FLASH_MODE_ERASE)
+	{
+		ExpectedArgc--;
+	}
+	
+	if (argc < ExpectedArgc)
+	{
+		printf("%sERROR: please supply all argument\n%s", ColorRed, ColorNormal);
+		PrintUsage(cmdtp);
+		return -1;
+	}
+	
+	if ( FlashMode != FLASH_MODE_ERASE)
+	{
+		DdrAddress = simple_strtol(argv[4] , NULL,16);
+	}
+
+	mImagePartitionInfoList.mImagePartitionList[i].mDdrAddress = DdrAddress;
+
+	debug("%s ",  mImagePartitionInfoList.mImagePartitionList[i].mMtdId);
+	debug("%s ",  mImagePartitionInfoList.mImagePartitionList[i].mPartionName);
+	debug("%08x ",  mImagePartitionInfoList.mImagePartitionList[i].mFlashAddress);
+	debug("%08x ",  mImagePartitionInfoList.mImagePartitionList[i].mDdrAddress);
+	debug("%08x\n",  mImagePartitionInfoList.mImagePartitionList[i].mLength );
+	
+	if (argc == 6 )
+	{
+		if ( FlashMode == FLASH_MODE_ERASE)
+		{
+			printf("%sLength can not be changed to requested size, becuase cncflash operates on mtd partition so we can not use erase.spread%s\n", ColorYellow, ColorNormal );
+		}
+		else
+		{
+			mImagePartitionInfoList.mImagePartitionList[i].mLength = simple_strtol(argv[5], NULL, 16);
+			debug("Length is changed to %08x\n",  mImagePartitionInfoList.mImagePartitionList[i].mLength );
+		}
+	}
+
+	
+	Status = CncFlashTask( FlashMode, MtdId , & mImagePartitionInfoList.mImagePartitionList[i] , DdrAddress );
+	
+	return Status;
+}
+
+U_BOOT_CMD(
+	cncflash, 6, 0, do_cncflash,
+	"[read|write|erase] [cnc-nand|s25f|cnc-spi|cnc-nor|emmc] [partition_name] [DdrAddress]\n",
+	"[read|write|erase] [cnc-nand|s25f|cnc-spi|cnc-nor|emmc] [partition_name] [DdrAddress]\n"
+);
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_ColorOnOff.c u-boot-2011.06/common/cmd_ColorOnOff.c
--- u-boot-2011.06_original/common/cmd_ColorOnOff.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_ColorOnOff.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2009
+ * 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 <common.h>
+#include <command.h>
+#include <cnc_util.h>
+
+extern char version_string[];
+extern void ColorOn(void);
+extern void ColorOff(void);
+
+int do_coloron(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	ColorOn();
+	puts("OK\n");
+	return 0;
+}
+int do_coloroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	ColorOff();
+	puts("OK\n");
+	return 0;
+}
+
+U_BOOT_CMD(
+	coloron,	1,		1,	do_coloron,
+	"uboot with color",
+	""
+);
+U_BOOT_CMD(
+	coloroff,	1,		1,	do_coloroff,
+	"uboot nocolor",
+	""
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_cslogo.c u-boot-2011.06/common/cmd_cslogo.c
--- u-boot-2011.06_original/common/cmd_cslogo.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_cslogo.c	2016-03-02 15:58:51.137133000 +0800
@@ -0,0 +1,488 @@
+/****************************************************************************
+ * Copyright (C) 2011 Cavium Inc.
+ * All rights reserved
+ *
+ * [RELEASE HISTORY]
+ * VERSION  DATE       AUTHOR                  DESCRIPTION
+ * 0.1      11-10-11       Jia Ma           		Original
+ ****************************************************************************
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/byteorder.h>
+#include <malloc.h>
+#include "cnc_util.h"
+#include "../drivers/cnc1900/df/df.h"
+#include "../drivers/cnc1900/cncedid/cnc_edid.h"
+
+/*#define SPLASH_BUFFER 					0x01000000
+#define TEMP_SPLASH_BUFFER 				0x02000000
+*/
+#define SPLASH_BUFFER                                   0x0f000000
+#define TEMP_SPLASH_BUFFER                              0x0f800000
+#define MAX_TEMP_SPLASH_BUFFER_SIZE		(8*1024*1024)
+
+unsigned int screen_w,screen_h,picture_color_mode,pixel_width,GFXLINEPITCHSIZE;
+
+
+/*COLOR_FORMAT_RGB565    = 2
+  COLOR_FORMAT_ARGB4444  = 3
+  COLOR_FORMAT_ARGB1555  = 5
+  COLOR_FORMAT_ARGB8888  = 6*/
+/*
+   PixelOutputFormat=TVOUT_MODE
+   PictureColorMode=DF_GFX_COLOR_FORMAT
+   */
+static void DISP_SET_FLAG(unsigned int flag)
+{
+	unsigned int *ctl_cfg;
+	ctl_cfg = (unsigned int *)0xfff0000;
+	*ctl_cfg=flag;
+}
+
+extern int disp_init(TVOUT_MODE mode, int pic_w, int pic_h, int dst_x, int dst_y,unsigned char * pData,int hdcp_status, int colorspace_mode);
+static int DrawPicture(unsigned int aImageWidth, unsigned int aImageHeight, unsigned int aOffsetTop, unsigned int aOffsetLeft,
+		unsigned int PixelOutputFormat ,
+		unsigned int PictureColorMode , unsigned char* apData,int hdcp_status, int colorspace_mode
+		)
+{
+#if 1
+	picture_color_mode =PictureColorMode;
+
+	switch(PixelOutputFormat){
+		case 0:
+		case 2:
+		case 8:
+		case 10:
+		case 11:
+			screen_w = 720;
+			screen_h = 576;
+			GFXLINEPITCHSIZE = 720*2;
+			break;
+		case 1:
+		case 3:
+		case 9:
+			screen_w = 720;
+			screen_h = 480;
+			GFXLINEPITCHSIZE = 720*2;
+			break;
+		case 4:
+		case 5:
+		case 20:
+			screen_w = 1280;
+			screen_h = 720;
+			GFXLINEPITCHSIZE = 1280*2;
+			break;
+		case 6:
+		case 7:
+		case 12:
+		case 13:
+		case 14:
+		case 15:
+		case 16:
+			screen_w = 1920;
+			screen_h = 1080;
+			GFXLINEPITCHSIZE = 1920*2;
+			break;
+		case 17:
+			screen_w = 640;
+			screen_h = 480;
+			GFXLINEPITCHSIZE = 640*2;
+			break;
+		case 18:
+			screen_w = 800;
+			screen_h = 600;
+			GFXLINEPITCHSIZE = 800*2;
+			break;
+		case 19:
+			screen_w = 1024;
+			screen_h = 768;
+			GFXLINEPITCHSIZE = 1024*2;
+			break;
+		case 53:
+			screen_w = 1366;
+			screen_h = 768;
+			GFXLINEPITCHSIZE = 1366*2;
+			break;
+		default:
+			screen_w = 720;
+			screen_h = 576;
+			GFXLINEPITCHSIZE = 720*2;
+			break;
+	}
+
+	pixel_width = 2;
+
+	/*df of 1900 support scale*/
+	GFXLINEPITCHSIZE=aImageWidth*2;
+
+	if(picture_color_mode == 6){
+		GFXLINEPITCHSIZE = GFXLINEPITCHSIZE*2;
+		pixel_width = 4;
+	}
+
+	printf("GFXLINEPITCHSIZE = %d, screen_h = %d\n",GFXLINEPITCHSIZE,screen_h);
+	/* clear screen */
+	//memset((void*)GFXBASEADDRESS, 0, GFXLINEPITCHSIZE * screen_h);
+
+	printf("pixel_width = %d\n",pixel_width);
+
+	disp_init(PixelOutputFormat, aImageWidth, aImageHeight, aOffsetLeft, aOffsetTop,apData,hdcp_status,colorspace_mode);
+
+	/*psrcbuf = (unsigned char*)pic_buf;
+	  pdstbuf = (unsigned char*)(GFXBASEADDRESS + (dst_y * GFXLINEPITCHSIZE) + dst_x * pixel_width);
+
+	  for(i = 0; i < pic_h; i++){
+	  memcpy(pdstbuf, psrcbuf, pic_w * pixel_width);
+	  psrcbuf += (pic_w*pixel_width);
+	  pdstbuf += GFXLINEPITCHSIZE;
+	  }*/
+
+	//	write_hd2sd_cmd(mode);
+#endif
+
+	return 0;
+}
+
+UInt8* UnzipIfReguired(UInt8* apSrcBuffer, UInt8* apDestinationBuffer)
+{
+	int Status;
+	if( ( *(apSrcBuffer + 0 ) == 0x1F) && ( *(apSrcBuffer + 1 ) == 0x8B )  )
+	{
+		printf("%slogo is in zip format\n%s", ColorYellow, ColorNormal);
+		//It is in zip format - run through unzip
+		unsigned long src=0;
+		unsigned long dst=0;
+		unsigned long src_len = ~0UL;
+		unsigned long dst_len = ~0UL;
+
+		src=src;
+		dst=dst;
+		src_len=src_len;
+		dst_len=dst_len;
+
+		Status =  gunzip( (void *) apDestinationBuffer, MAX_TEMP_SPLASH_BUFFER_SIZE , (void *) apSrcBuffer, &src_len);
+		if (Status != 0 )
+		{
+			return NULL;
+		}
+		printf("%sUnzip of logo is done successfully%s\n", ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf("%slogo is raw mode\n%s" , ColorYellow, ColorNormal);
+		//It is in raw mode. just cp the pointer.
+		apDestinationBuffer = apSrcBuffer;
+	}
+	return apDestinationBuffer;
+}
+#define GET_FROM_FLASH
+int do_cslogo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned int ImageWidth=0;
+	unsigned int ImageHeight=0;
+	unsigned int OffsetTop=0;
+	unsigned int OffsetLeft=0;
+	unsigned int PixelOutputFormat = 0;
+	unsigned int PictureColorMode = 0;
+	unsigned int DdrAddress = SPLASH_BUFFER;
+#ifdef GET_FROM_FLASH
+	unsigned int FlashAddress = 0;
+#endif
+	int Status=0;
+	int hdcp_status = 0 ;
+	int colorspace_mode = 0xff;
+
+	Status=Status;
+	ImageWidth=ImageWidth;
+	ImageHeight=ImageHeight;
+	OffsetTop=OffsetTop;
+	OffsetLeft=OffsetLeft;
+	PixelOutputFormat = PixelOutputFormat;
+	PictureColorMode = PictureColorMode;
+
+	printf("argc =%d\n",argc);
+	if( ! ( (argc == 7) ||  (argc == 8) || (argc == 9) || (argc == 10) ) ){
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return -1;
+	}
+
+	PixelOutputFormat = simple_strtoul(argv[1], NULL, 0);
+	PictureColorMode = simple_strtoul(argv[2], NULL, 0);
+	ImageWidth = simple_strtoul(argv[3], NULL, 0);
+	ImageHeight = simple_strtoul(argv[4], NULL, 0);
+	OffsetTop = simple_strtoul(argv[5], NULL, 0);
+	OffsetLeft = simple_strtoul(argv[6], NULL, 0);
+	if(((PixelOutputFormat<0)||(PixelOutputFormat>TVOUT_RGB_1366X768_60FPS))||((PictureColorMode<0)||(PictureColorMode>DF_GFX_XRGB8888))){
+		printf("Error input param!\n");
+		return -1;
+	}
+
+	
+	printf("PixelOutputFormat = %d, PictureColorMode = %d\n", (int)PixelOutputFormat ,(int) PictureColorMode );
+	printf("ImageWidth = %d ImageHeight = %d\n",(int) ImageWidth , (int)ImageHeight );
+	printf("OffsetTop = %d OffsetLeft = %d\n", (int)OffsetTop , (int)OffsetLeft );
+
+#ifdef GET_FROM_FLASH
+	if (argc == 8 ){
+		FlashAddress = simple_strtoul(argv[7], NULL, 16);
+		if(0xffffffff != FlashAddress){
+			Status = cnc_NandRead(FlashAddress,   TEMP_SPLASH_BUFFER,  MAX_TEMP_SPLASH_BUFFER_SIZE);
+			if (Status != 0 ){
+				printf("%sERROR: NAND read failed\n%s", ColorRed, ColorNormal );
+				return -1;
+			}
+		}
+	}
+	else{
+		//more preferred way
+		Status =  cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "splash" , TEMP_SPLASH_BUFFER,  0xFFFFFFFF );
+		if (Status != 0 ){
+			printf("%sERROR: NAND read failed for partiotion name \"splash\"\n%s", ColorRed, ColorNormal );
+			return -1;
+		}
+	}
+#endif
+
+	if(argc == 9){
+		hdcp_status=simple_strtoul(argv[8], NULL, 0);
+		printf("hdcp_status = %d\n", hdcp_status);
+	}
+	if(argc == 10){
+		hdcp_status=simple_strtoul(argv[8], NULL, 0);
+		printf("hdcp_status = %d\n", hdcp_status);
+		colorspace_mode=simple_strtoul(argv[9], NULL, 0);
+		printf("colorspace_mode = %d\n",colorspace_mode);
+	}
+
+	if(!dcache_status()){
+		dcache_enable();
+	}
+	DdrAddress = (unsigned int) UnzipIfReguired( (unsigned char*) TEMP_SPLASH_BUFFER, (unsigned char*) SPLASH_BUFFER);
+	dcache_disable();
+
+	if (0 == DdrAddress ){
+		printf("%sUnable to process logo data\n%s" , ColorRed, ColorNormal);
+		return -1;
+	}
+
+	Status = DrawPicture(ImageWidth, ImageHeight, OffsetTop, OffsetLeft, PixelOutputFormat , PictureColorMode , (unsigned char*) DdrAddress ,hdcp_status, colorspace_mode);
+	return 0;
+}
+
+
+extern unsigned int gfxid;
+extern unsigned int UiStarted(void);
+extern void DFGfxSetAlpha(int GfxId, unsigned short DefaultAlpha, unsigned short ARGB1555Alpha0, unsigned short ARGB1555Alpha1);
+int do_csupgrade_logo(void)
+{
+	unsigned int DdrAddress = SPLASH_BUFFER;
+	int Status=0;
+
+	if(!UiStarted()){
+		printf("UI does not start!!!\n");
+		return -1;
+	}
+
+#ifdef GET_FROM_FLASH
+	Status =  cnc_Read_MtdPartition(CONFIG_CNC_BOOTM_MTDID, "update_splash" , TEMP_SPLASH_BUFFER,  0xFFFFFFFF );
+	if (Status != 0 ){
+		printf("%sERROR: NAND read failed for partiotion name \"update_splash\"\n%s", ColorRed, ColorNormal );
+		return -1;
+	}
+#endif
+	DFGfxSetAlpha(gfxid, 0, 0, 0);
+	if(!dcache_status()){
+		dcache_enable();
+	}
+	DdrAddress = (unsigned int) UnzipIfReguired( (unsigned char*) TEMP_SPLASH_BUFFER, (unsigned char*) SPLASH_BUFFER);
+	dcache_disable();
+
+	if (0 == DdrAddress ){
+		printf("%sUnable to process logo data\n%s" , ColorRed, ColorNormal);
+		return -1;
+	}
+
+	DFGfxSetAlpha(gfxid, 0xff, 0, 0);
+	printf("show upgrade splash logo\n");
+
+	return 0;
+}
+
+cnc_edid_t edid_storage;
+int tvoutmode_supported_res[TVOUT_MODE_MAX] = {0};
+int audmode_supported[CSAUD_HDMI_MAX] = {0};
+extern int do_call_external_proc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+
+int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	int* ret_val = (int *)0xf000000;
+	char *hdmi_argv[5]={0};
+	int res = -1;
+	char* temp_char = NULL;
+	char* bootargs = NULL;
+	cnc_edid_t *edid = &edid_storage;
+
+	hdmi_argv[0]="call_external_proc";
+	hdmi_argv[1]="HDMI";
+	hdmi_argv[2]="0xff";
+
+	do_call_external_proc(NULL, 0, 4, hdmi_argv);
+	if(0xffffffff == *ret_val){
+		printf("HDMI not plug in or Read EDID info failed!\n");
+		return 1;
+	}
+
+	cnc_edid_init(edid);
+	memcpy(edid->edid_bin, (int *)0xf000004, ret_val[0]);
+	edid->edid_bin_valid = EDID_BIN_VALID;
+	edid->edid_bin_length = ret_val[0];
+
+	cnc_edid_parse(edid);
+	temp_char = getenv("PRINT_EDID");
+	if(NULL != temp_char){
+		printf("Original EDID:\n");
+		cnc_edid_print(edid);
+	}
+	res = cnc_edid_filter(edid, tvoutmode_supported_res, audmode_supported);
+	if(NULL != temp_char){
+		printf("Filtered EDID:\n");
+		cnc_edid_print(edid);
+	}
+	temp_char = NULL;
+	cnc_edid_clear_bin(edid);
+	printf("best res = %d\n", res);
+
+	if(-1 == res) {
+		printf("Unsupported format!\n");
+		return 1;
+	} else {
+		temp_char = NULL;
+		// set bootargs outputmode parameter
+		bootargs = getenv("bootargs");
+		//		printf("bootargs = %s\n", bootargs);
+		temp_char = strstr(bootargs,"outputmode=");
+		//		printf("temp_char = %s\n",temp_char);
+		if(NULL == temp_char){
+			temp_char = malloc(strlen(bootargs) + 20);
+			if(0 == temp_char){
+				printf("Not enough memory!\n");
+				return 1;
+			}
+			memcpy(temp_char, bootargs, strlen(bootargs));
+			sprintf(temp_char+strlen(bootargs)," outputmode=%d",res);
+			setenv("bootargs", temp_char);
+		}
+		else{
+			int num1 = 0;
+			int num2 = 0;
+			char* aaa = strchr(temp_char, '=');
+			char* bbb = strchr(temp_char, ' ');
+
+			num1 = aaa - bootargs;
+			//	printf("num1 = %d\n",num1);
+			//			printf("%s\n",aaa+1);
+			if(NULL == bbb){
+				temp_char = malloc(strlen(bootargs) + 20);
+				if(0 == temp_char){
+					printf("Not enough memory!\n");
+					return 1;
+				}
+				memcpy(temp_char, bootargs, num1+1);
+				sprintf(temp_char+num1+1,"%d",res);
+			}
+			else{
+				num2 = bbb - bootargs;
+				//	printf("num2 = %d\n",num2);
+				temp_char = malloc(strlen(bootargs) + 20);
+				if(0 == temp_char){
+					printf("Not enough memory!\n");
+					return 1;
+				}
+				strncpy(temp_char, bootargs, num1+1);
+				sprintf(temp_char+num1+1,"%d",res);
+				//				printf("strlen(temp_char) = %d\n",strlen(temp_char));
+				strncat(temp_char+strlen(temp_char), bbb,strlen(bbb));
+			}
+		}
+		setenv("bootargs", temp_char);
+		sprintf(temp_char, "%d", res);
+		setenv("OUTPUTMODE",temp_char);
+	}
+
+	return 0;
+}
+
+int do_aksv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	int* ret_val = (int *)0xf000000;
+	char *hdmi_argv[5]={0};
+
+	hdmi_argv[0]="call_external_proc";
+	hdmi_argv[1]="HDMI";
+	hdmi_argv[2]="0xfe";
+
+	do_call_external_proc(NULL, 0, 4, hdmi_argv);
+	if(0xffffffff == *ret_val){
+		printf("Read AKSV failed!\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+
+int do_dump_tpi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	int* ret_val = (int *)0xf000000;
+	char *hdmi_argv[5]={0};
+
+	hdmi_argv[0]="call_external_proc";
+	hdmi_argv[1]="HDMI";
+	hdmi_argv[2]="0xfd";
+
+	do_call_external_proc(NULL, 0, 4, hdmi_argv);
+	if(0xffffffff == *ret_val){
+		printf("Dump TPI failed!\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+		logo,	10,	1,	do_cslogo,
+		"display logo picture on TV Screen",
+		"    - output mode(TVOUT_MODE): refer to the struct CSTVOUT_MODE in cstvout.h\n"
+		"    - color mode(DF_GFX_COLOR_FORMAT): refer to th struct CSOSD_COLOR_FORMAT in csosd.h\n"
+		"    - width(decimal): 	picture width\n"
+		"    - height(decimal): picture height\n"
+		"    - dstX(decimal): 	the top-left X coordinate of screen\n"
+		"    - dstY(decimal): 	the top-left Y coordinate of screen\n"
+		"    - Flash Address(hex): 	Flash address where splash is stored in flash\n"
+		"    - hdcp status: 	enable:1 disable:0(default)  \n"
+		"    - colorspace mode: override colorspace(0:RGB, 1:YUV444, 2:YUV422) \n"
+		"e.g.- logo output_mode color_mode 720 576 0 0 (optional Flash Address where image is stored, by default it will try to read from mtd partition name - splash)"
+		);
+
+U_BOOT_CMD(
+		edid,   1,  1,  do_edid,
+		"parse EDID to find the best resolution and set OUTPUTMODE.\n",
+		"parse EDID to find the best resolution and set OUTPUTMODE.\n"
+		);
+
+
+U_BOOT_CMD(
+		aksv,   1,  1,  do_aksv,
+		"output corresponding AKSV value.\n",
+		"output corresponding AKSV value.\n"
+		);
+
+U_BOOT_CMD(
+		dumptpi,   1,  1,  do_dump_tpi,
+		"output HDMI register value.\n",
+		"output HDMI register value.\n"
+		);
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_fpc.c u-boot-2011.06/common/cmd_fpc.c
--- u-boot-2011.06_original/common/cmd_fpc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_fpc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,164 @@
+/*
+ * Description:
+ * 		Fronpannel led show implementation, reference to
+ * 		kernel driver.
+ *
+ * Author: Celestial
+ */
+#include <common.h>
+#include <command.h>
+
+/*************************************************************
+ FPC_INIT
+ Description: Boot with a default sign on fpc led.
+ 	      For a better interaction.
+*************************************************************/
+
+/* Register Map */
+#define ORION_FPC_BASE          0x80172000
+
+#define FPC_INTS                (0x00  >> 1) /* Interrupt Status Register */
+#define FPC_INTM                (0x04  >> 1) /* Interrupt Mask Register */
+#define FPC_RC_CTL_L            (0x08  >> 1) /* Remote Control Register */
+#define FPC_RC_CMD_L            (0x100 >> 1) /* RC5 Command Register */
+#define FPC_NEC_CMD_L           (0x104 >> 1) /* NEC Command Register */
+#define FPC_LED_DATA_L          (0x200 >> 1) /* Led Display Data Register */
+#define FPC_LED_CNTL_L          (0x204 >> 1) /* Led Display Control Register */
+#define FPC_KSCAN_DATA_L        (0x300 >> 1) /* Key Scan Data Register */
+#define FPC_KSCAN_CNTL_L        (0x304 >> 1) /* Key Scan Control Register */
+#define FPC_ARBCNTL_L           (0x308 >> 1) /* Led & Key Scan Arbiter Control Register */
+#define FPC_RC_CTL_H            (0x0a  >> 1) /* Remote Control Register */
+#define FPC_RC_CMD_H            (0x102 >> 1) /* RC5 Command Register */
+#define FPC_NEC_CMD_H           (0x106 >> 1) /* NEC Command Register */
+#define FPC_LED_DATA_H          (0x202 >> 1) /* Led Display Data Register */
+#define FPC_LED_CNTL_H          (0x206 >> 1) /* Led Display Control Register */
+#define FPC_KSCAN_DATA_H        (0x302 >> 1) /* Key Scan Data Register */
+#define FPC_KSCAN_CNTL_H        (0x306 >> 1) /* Key Scan Control Register */
+#define FPC_ARBCNTL_H           (0x30a >> 1) /* Led & Key Scan Arbiter Control Register */
+
+
+#define fpc_writew(v,a)         do { *((volatile unsigned short *)ORION_FPC_BASE + (a)) = v; }while(0)
+#define fpc_readw(a)            *((volatile unsigned short  *)ORION_FPC_BASE + (a))
+
+static unsigned char num_tab[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x00 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x10 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	/* */ /*!*/ /*"*/ /*#*/ /*$*/ /*%*/ /*&*/ /*'*/
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x20 */
+	/*(*/ /*)*/ /***/ /*+*/ /*,*/  /*-*/ /*.*/ /*/*/
+	0x63, 0x0F, 0xff, 0xff, 0xff, 0xfd, 0xFE, 0xff,
+	/*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
+	0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, /* 0x30 */
+	/*8*/ /*9*/ /* */ /* */ /* */ /* */ /* */ /* */
+	0x01, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	/* */ /*A*/ /*B*/ /*C*/ /*D*/ /*E*/ /*F*/ /*G*/
+	0xff, 0x11, 0x01, 0x63, 0x85, 0x61, 0x71, 0x09, /* 0x40 */
+	/*H*/ /*I*/ /*J*/ /*K*/ /*L*/ /*M*/ /*N*/ /*O*/
+	0x91, 0x9f, 0x87, 0xff, 0xe3, 0xff, 0x13, 0x03,
+	/*P*/ /*Q*/ /*R*/ /*S*/ /*T*/ /*U*/ /*V*/ /*W*/
+	0x31, 0x19, 0xF5, 0x49, 0xE1, 0x83, 0xff, 0xff, /* 0x50 */
+	/*X*/ /*Y*/ /*Z*/ /*[*/ /*\*/ /*]*/ /*^*/ /*_*/
+	0xff, 0x89, 0xff, 0x63, 0xff, 0x0F, 0xff, 0xEF,
+	/*`*/ /*a*/ /*b*/ /*c*/ /*d*/ /*e*/ /*f*/ /*g*/
+	0xff, 0x11, 0xC1, 0xE5, 0x85, 0x61, 0x71, 0x09, /* 0x60 */
+	/*h*/ /*i*/  /*j*/ /*k*/ /*l*/ /*m*/ /*n*/ /*o*/
+	0xD1, 0x9f, 0x87, 0xff, 0xe3, 0xff, 0xD5, 0xC5,
+	/*p*/ /*q*/ /*r*/ /*s*/ /*t*/ /*u*/ /*v*/ /*w*/
+	0x31, 0x19, 0xF5, 0x49, 0xE1, 0xC7, 0xff, 0xff, /* 0x70 */
+	/*x*/ /*y*/ /*z*/ /*{*/ /*|*/ /*}*/ /*~*/ /* */
+	0xff, 0x89, 0xff, 0xff, 0x9F, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xe0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xf0 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+
+void fpc_led_enable(int cmd)
+{
+	fpc_writew(0x8000, FPC_LED_CNTL_H);
+	fpc_writew(0 != cmd ? 0x1000 : 0x0000, FPC_LED_CNTL_L);
+}
+
+void fpc_led_disp(int arg)
+{
+	fpc_writew((arg >> 16) & 0xffff, FPC_LED_DATA_H);
+	fpc_writew(arg & 0xffff, FPC_LED_DATA_L);
+}
+
+void fpc_init_show(const char *string)
+{
+	int i, val;
+	char  str[5] = { 0 };
+
+	sprintf(str,"%-4s", string);
+
+	for (val = 0, i = 0; i<4 ; i++)
+		val |= num_tab[(int)str[i]] << (8 * i);
+
+	fpc_led_disp(val);
+	fpc_led_enable(1);
+}
+
+#define GPIO_PINMUX() do {}while(0)
+
+int do_fpc_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	 GPIO_PINMUX();
+	 fpc_init_show(argv[1]);
+
+	 return 0;
+}
+
+U_BOOT_CMD(
+	fpcd,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_fpc_led,
+	"Display data on frontpanel led",
+	"<data>"
+	);
+
+int do_fpcraw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	u32 val;
+
+	val = simple_strtoul(argv[1], NULL, 16);
+
+	GPIO_PINMUX();
+
+	fpc_led_disp(val);
+	fpc_led_enable(1);
+
+	return 0;
+}
+int do_enagpio2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	fpc_writew(0x4000, FPC_LED_CNTL_H);
+	fpc_writew(0x0000, FPC_LED_CNTL_L);
+	return 0;
+}
+
+U_BOOT_CMD(
+	fpcraw,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_fpcraw,
+	"Display raw data on frontpanel led",
+	"<data>"
+	);
+
+U_BOOT_CMD(
+	disled,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_enagpio2,
+	"Disable LED display and enable GPIO2",
+	""
+	);
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_gpio.c u-boot-2011.06/common/cmd_gpio.c
--- u-boot-2011.06_original/common/cmd_gpio.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_gpio.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,89 +1,78 @@
 /*
- * Control GPIO pins on the fly
+ * Basic GPIO functions
  *
- * Copyright (c) 2008-2011 Analog Devices Inc.
+ * Copyright (c) 2008 Celestial Semiconductor
+ *
+ * This package is free software;  you can redistribute it and/or
+ * modify it under the terms of the license found in the file
+ * named COPYING that should have accompanied this file.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Tu BaoZhao bz.tu@celestialsemi.com, Celestial Semiconductor
+ *
+ * Copyright (c) 2007 Celestial Semiconductor
  *
- * Licensed under the GPL-2 or later.
  */
 
 #include <common.h>
 #include <command.h>
 
-#include <asm/gpio.h>
+extern void 		 gpio_hw_set_direct(int gpio_id, int data);
+extern unsigned int  gpio_hw_read(int gpio_id);
+extern void          gpio_hw_write(int gpio_id, int data);
 
-#ifndef name_to_gpio
-#define name_to_gpio(name) simple_strtoul(name, NULL, 10)
-#endif
-
-enum gpio_cmd {
-	GPIO_INPUT,
-	GPIO_SET,
-	GPIO_CLEAR,
-	GPIO_TOGGLE,
-};
 
-static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	int gpio;
-	enum gpio_cmd sub_cmd;
-	ulong value;
-	const char *str_cmd, *str_gpio;
-
-#ifdef gpio_status
-	if (argc == 2 && !strcmp(argv[1], "status")) {
-		gpio_status();
-		return 0;
-	}
-#endif
+	int gpio_id;
+	unsigned short data;
 
-	if (argc != 3)
- show_usage:
-		return cmd_usage(cmdtp);
-	str_cmd = argv[1];
-	str_gpio = argv[2];
-
-	/* parse the behavior */
-	switch (*str_cmd) {
-		case 'i': sub_cmd = GPIO_INPUT;  break;
-		case 's': sub_cmd = GPIO_SET;    break;
-		case 'c': sub_cmd = GPIO_CLEAR;  break;
-		case 't': sub_cmd = GPIO_TOGGLE; break;
-		default:  goto show_usage;
+	if (argc < 3 || argc > 4) {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
 	}
 
-	/* turn the gpio name into a gpio number */
-	gpio = name_to_gpio(str_gpio);
-	if (gpio < 0)
-		goto show_usage;
-
-	/* grab the pin before we tweak it */
-	if (gpio_request(gpio, "cmd_gpio")) {
-		printf("gpio: requesting pin %u failed\n", gpio);
+	gpio_id = simple_strtoul(argv[2], NULL, 0);
+	if (gpio_id < 0 || gpio_id >41) {
+		printf("%s: invalid parameters! at line: %d\n",
+			__FUNCTION__, __LINE__);
 		return -1;
 	}
 
-	/* finally, let's do it: set direction and exec command */
-	if (sub_cmd == GPIO_INPUT) {
-		gpio_direction_input(gpio);
-		value = gpio_get_value(gpio);
-	} else {
-		switch (sub_cmd) {
-			case GPIO_SET:    value = 1; break;
-			case GPIO_CLEAR:  value = 0; break;
-			case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
-			default:          goto show_usage;
+	if (strcmp(argv[1], "read") == 0) {
+		if (argc > 3) {
+			printf("Usage: %s\n", cmdtp->help);
+			return -1;
 		}
-		gpio_direction_output(gpio, value);
-	}
-	printf("gpio: pin %s (gpio %i) value is %lu\n",
-		str_gpio, gpio, value);
 
-	gpio_free(gpio);
+		gpio_hw_set_direct(gpio_id, 0);
+		data = gpio_hw_read(gpio_id);
+		printf("gpio[%d] = %u\n", gpio_id, data);
+	} else if (strcmp(argv[1], "write") == 0) {
+		if (argc < 4) {
+			printf("Usage: %s\n", cmdtp->help);
+			return -1;
+		}
 
-	return value;
+		data = simple_strtoul(argv[3], NULL, 0);
+		gpio_hw_set_direct(gpio_id, 1);
+		gpio_hw_write(gpio_id, data);
+		printf("Write ok!\n");
+	} else {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
+	}
+
+	return 0;
 }
 
-U_BOOT_CMD(gpio, 3, 0, do_gpio,
-	"input/set/clear/toggle gpio pins",
-	"<input|set|clear|toggle> <pin>\n"
-	"    - input/set/clear/toggle the specified pin");
+U_BOOT_CMD(
+	gpio,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_gpio,
+	"gpio    - gpio read/write bit\n",
+	"\ngpio <read>  <gpio_id>\n"
+	"gpio <write> <gpio_id> <data>\n"
+	);
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_gpio.c_2011.06 u-boot-2011.06/common/cmd_gpio.c_2011.06
--- u-boot-2011.06_original/common/cmd_gpio.c_2011.06	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_gpio.c_2011.06	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,89 @@
+/*
+ * Control GPIO pins on the fly
+ *
+ * Copyright (c) 2008-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include <asm/gpio.h>
+
+#ifndef name_to_gpio
+#define name_to_gpio(name) simple_strtoul(name, NULL, 10)
+#endif
+
+enum gpio_cmd {
+	GPIO_INPUT,
+	GPIO_SET,
+	GPIO_CLEAR,
+	GPIO_TOGGLE,
+};
+
+static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int gpio;
+	enum gpio_cmd sub_cmd;
+	ulong value;
+	const char *str_cmd, *str_gpio;
+
+#ifdef gpio_status
+	if (argc == 2 && !strcmp(argv[1], "status")) {
+		gpio_status();
+		return 0;
+	}
+#endif
+
+	if (argc != 3)
+ show_usage:
+		return cmd_usage(cmdtp);
+	str_cmd = argv[1];
+	str_gpio = argv[2];
+
+	/* parse the behavior */
+	switch (*str_cmd) {
+		case 'i': sub_cmd = GPIO_INPUT;  break;
+		case 's': sub_cmd = GPIO_SET;    break;
+		case 'c': sub_cmd = GPIO_CLEAR;  break;
+		case 't': sub_cmd = GPIO_TOGGLE; break;
+		default:  goto show_usage;
+	}
+
+	/* turn the gpio name into a gpio number */
+	gpio = name_to_gpio(str_gpio);
+	if (gpio < 0)
+		goto show_usage;
+
+	/* grab the pin before we tweak it */
+	if (gpio_request(gpio, "cmd_gpio")) {
+		printf("gpio: requesting pin %u failed\n", gpio);
+		return -1;
+	}
+
+	/* finally, let's do it: set direction and exec command */
+	if (sub_cmd == GPIO_INPUT) {
+		gpio_direction_input(gpio);
+		value = gpio_get_value(gpio);
+	} else {
+		switch (sub_cmd) {
+			case GPIO_SET:    value = 1; break;
+			case GPIO_CLEAR:  value = 0; break;
+			case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
+			default:          goto show_usage;
+		}
+		gpio_direction_output(gpio, value);
+	}
+	printf("gpio: pin %s (gpio %i) value is %lu\n",
+		str_gpio, gpio, value);
+
+	gpio_free(gpio);
+
+	return value;
+}
+
+U_BOOT_CMD(gpio, 3, 0, do_gpio,
+	"input/set/clear/toggle gpio pins",
+	"<input|set|clear|toggle> <pin>\n"
+	"    - input/set/clear/toggle the specified pin");
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_gpt.c u-boot-2011.06/common/cmd_gpt.c
--- u-boot-2011.06_original/common/cmd_gpt.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_gpt.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,336 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ * author: Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <mmc.h>
+#include <part_efi.h>
+#include <exports.h>
+#include <linux/ctype.h>
+#include <div64.h>
+
+#ifndef CONFIG_PARTITION_UUIDS
+#error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_GPT to be enabled
+#endif
+
+/**
+ * extract_env(): Expand env name from string format '&{env_name}'
+ *                and return pointer to the env (if the env is set)
+ *
+ * @param str - pointer to string
+ * @param env - pointer to pointer to extracted env
+ *
+ * @return - zero on successful expand and env is set
+ */
+static char extract_env(const char *str, char **env)
+{
+	char *e, *s;
+
+	if (!str || strlen(str) < 4)
+		return -1;
+
+	if ((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')) {
+		s = strdup(str);
+		if (s == NULL)
+			return -1;
+		memset(s + strlen(s) - 1, '\0', 1);
+		memmove(s, s + 2, strlen(s) - 1);
+		e = getenv(s);
+		free(s);
+		if (e == NULL) {
+			printf("Environmental '%s' not set\n", str);
+			return -1; /* env not set */
+		}
+		*env = e;
+		return 0;
+	}
+
+	return -1;
+}
+
+/**
+ * extract_val(): Extract value from a key=value pair list (comma separated).
+ *                Only value for the given key is returend.
+ *                Function allocates memory for the value, remember to free!
+ *
+ * @param str - pointer to string with key=values pairs
+ * @param key - pointer to the key to search for
+ *
+ * @return - pointer to allocated string with the value
+ */
+static char *extract_val(const char *str, const char *key)
+{
+	char *v, *k;
+	char *s, *strcopy;
+	char *new = NULL;
+
+	strcopy = strdup(str);
+	if (strcopy == NULL)
+		return NULL;
+
+	s = strcopy;
+	while (s) {
+		v = strsep(&s, ",");
+		if (!v)
+			break;
+		k = strsep(&v, "=");
+		if (!k)
+			break;
+		if  (strcmp(k, key) == 0) {
+			new = strdup(v);
+			break;
+		}
+	}
+
+	free(strcopy);
+
+	return new;
+}
+
+/**
+ * set_gpt_info(): Fill partition information from string
+ *		function allocates memory, remember to free!
+ *
+ * @param dev_desc - pointer block device descriptor
+ * @param str_part - pointer to string with partition information
+ * @param str_disk_guid - pointer to pointer to allocated string with disk guid
+ * @param partitions - pointer to pointer to allocated partitions array
+ * @param parts_count - number of partitions
+ *
+ * @return - zero on success, otherwise error
+ *
+ */
+static int set_gpt_info(block_dev_desc_t *dev_desc,
+			const char *str_part,
+			char **str_disk_guid,
+			disk_partition_t **partitions,
+			u8 *parts_count)
+{
+	char *tok, *str, *s;
+	int i;
+	char *val, *p;
+	int p_count;
+	disk_partition_t *parts;
+	int errno = 0;
+	uint64_t size_ll, start_ll;
+
+	debug("%s: MMC lba num: 0x%x %d\n", __func__,
+	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+
+	if (str_part == NULL)
+		return -1;
+
+	str = strdup(str_part);
+
+	/* extract disk guid */
+	s = str;
+	tok = strsep(&s, ";");
+	val = extract_val(tok, "uuid_disk");
+	debug("val = %s\n",val);
+	if (!val) {
+		free(str);
+		return -2;
+	}
+	if (extract_env(val, &p)){
+		p = val;
+	}
+	*str_disk_guid = strdup(p);
+	free(val);
+
+	if (strlen(s) == 0)
+		return -3;
+
+	i = strlen(s) - 1;
+	if (s[i] == ';')
+		s[i] = '\0';
+
+	/* calculate expected number of partitions */
+	p_count = 1;
+	p = s;
+	while (*p) {
+		if (*p++ == ';')
+			p_count++;
+	}
+	debug("p_count = %d\n", p_count);
+	/* allocate memory for partitions */
+	parts = calloc(sizeof(disk_partition_t), p_count);
+
+	/* retrieve partitions data from string */
+	for (i = 0; i < p_count; i++) {
+		tok = strsep(&s, ";");
+		debug("tok = %s\n", tok);
+		if (tok == NULL)
+			break;
+
+		/* uuid */
+		val = extract_val(tok, "uuid");
+		debug("uid = %s\n", val);
+		if (!val) { /* 'uuid' is mandatory */
+			errno = -4;
+			goto err;
+		}
+		if (extract_env(val, &p)){
+			p = val;
+		}
+		if (strlen(p) >= sizeof(parts[i].uuid)) {
+			debug("Wrong uuid format for partition %d\n", i);
+			errno = -4;
+			goto err;
+		}
+		strcpy((char *)parts[i].uuid, p);
+		free(val);
+
+		/* name */
+		val = extract_val(tok, "name");
+		debug("name = %s\n",val);
+		if (!val) { /* name is mandatory */
+			errno = -4;
+			goto err;
+		}
+		if (extract_env(val, &p)){
+			p = val;
+		}
+		if (strlen(p) >= sizeof(parts[i].name)) {
+			errno = -4;
+			goto err;
+		}
+		strcpy((char *)parts[i].name, p);
+		free(val);
+
+		/* size */
+		val = extract_val(tok, "size");
+		debug("size = %s\n", val);
+		if (!val) { /* 'size' is mandatory */
+			errno = -4;
+			goto err;
+		}
+		if (extract_env(val, &p)){
+			p = val;
+		}
+		size_ll = ustrtoull(p, &p, 0);
+		debug("size_ll = 0x%llx, dev_desc->blksz = 0x%lx\n",size_ll, dev_desc->blksz);
+		parts[i].size = lldiv(size_ll, dev_desc->blksz);
+		debug("parts[%d].size = 0x%lx\n",i,parts[i].size);
+		free(val);
+
+		/* start address */
+		val = extract_val(tok, "start");
+		debug("val = %s\n",val);
+		if (val) { /* start address is optional */
+			if (extract_env(val, &p))
+				p = val;
+			start_ll = ustrtoull(p, &p, 0);
+			debug("wwwsize_ll = 0x%llx, dev_desc->blksz = 0x%lx\n",size_ll, dev_desc->blksz);
+			parts[i].start = lldiv(start_ll, dev_desc->blksz);
+			debug("wwwparts[%d].size = 0x%lx\n",i,parts[i].size);
+			free(val);
+		}
+	}
+
+	*parts_count = p_count;
+	*partitions = parts;
+	free(str);
+
+	return 0;
+err:
+	free(str);
+	free(*str_disk_guid);
+	free(parts);
+
+	return errno;
+}
+
+static int gpt_mmc_default(int dev, const char *str_part)
+{
+	int ret;
+	char *str_disk_guid;
+	u8 part_count = 0;
+	disk_partition_t *partitions = NULL;
+
+	struct mmc *mmc = find_mmc_device(dev);
+
+	if (mmc == NULL) {
+		printf("%s: mmc dev %d NOT available\n", __func__, dev);
+		return CMD_RET_FAILURE;
+	}
+
+	if (!str_part)
+		return -1;
+
+	/* fill partitions */
+	ret = set_gpt_info(&mmc->block_dev, str_part,
+			&str_disk_guid, &partitions, &part_count);
+	if (ret) {
+		if (ret == -1)
+			printf("No partition list provided\n");
+		if (ret == -2)
+			printf("Missing disk guid\n");
+		if ((ret == -3) || (ret == -4))
+			printf("Partition list incomplete\n");
+		return -1;
+	}
+
+	/* save partitions layout to disk */
+	gpt_restore(&mmc->block_dev, str_disk_guid, partitions, part_count);
+	free(str_disk_guid);
+	free(partitions);
+
+	return 0;
+}
+
+/**
+ * do_gpt(): Perform GPT operations
+ *
+ * @param cmdtp - command name
+ * @param flag
+ * @param argc
+ * @param argv
+ *
+ * @return zero on success; otherwise error
+ */
+int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+	int dev = 0;
+	char *pstr;
+
+	if (argc < 5)
+		return CMD_RET_USAGE;
+
+	/* command: 'write' */
+	if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
+		/* device: 'mmc' */
+		if (strcmp(argv[2], "mmc") == 0) {
+			/* check if 'dev' is a number */
+			for (pstr = argv[3]; *pstr != '\0'; pstr++)
+				if (!isdigit(*pstr)) {
+					printf("'%s' is not a number\n",
+						argv[3]);
+					return CMD_RET_USAGE;
+				}
+			dev = (int)simple_strtoul(argv[3], NULL, 10);
+			/* write to mmc */
+			if (gpt_mmc_default(dev, argv[4]))
+				return CMD_RET_FAILURE;
+		}
+	} else {
+		return CMD_RET_USAGE;
+	}
+	return ret;
+}
+
+U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
+	"GUID Partition Table",
+	"<command> <interface> <dev> <partitions_list>\n"
+	" - GUID partition table restoration\n"
+	" Restore GPT information on a device connected\n"
+	" to interface\n"
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_mem.c u-boot-2011.06/common/cmd_mem.c
--- u-boot-2011.06_original/common/cmd_mem.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_mem.c	2014-07-29 17:28:38.819972000 +0800
@@ -42,6 +42,11 @@
 
 static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+extern int check_write_to_code_area (unsigned long addr, unsigned long size);
+#endif
+
+
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
@@ -180,6 +185,10 @@
 	addr = simple_strtoul(argv[1], NULL, 16);
 	addr += base_address;
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+	if (check_write_to_code_area (addr, size))
+		return -1;
+#endif
 	/* Get the value to write.
 	*/
 	writeval = simple_strtoul(argv[2], NULL, 16);
@@ -410,6 +419,11 @@
 		return 0;
 	}
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+	if (check_write_to_code_area (dest, count*size))
+		return -1;
+#endif
+
 	/* Check if we are copying from DataFlash to RAM */
 	if (addr_dataflash(addr) && !addr_dataflash(dest)
 #ifndef CONFIG_SYS_NO_FLASH
@@ -471,12 +485,12 @@
 
 int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	ulong	addr, length, i, junk;
+	ulong	addr, length, i, junk=0;
 	int	size;
 	volatile uint	*longp;
 	volatile ushort *shortp;
 	volatile u_char	*cp;
-
+	junk=junk;
 	if (argc < 3)
 		return cmd_usage(cmdtp);
 
@@ -535,11 +549,18 @@
 		while (i-- > 0)
 			junk = *cp++;
 	}
+	return 0;
 }
-
+#undef CONFIG_LOOPW
 #ifdef CONFIG_LOOPW
 int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+	struct pattern{
+		unsigned int burst[4];
+	};
+	const struct pattern pp = {
+		{0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
+	};
 	ulong	addr, length, i, data;
 	int	size;
 	volatile uint	*longp;
@@ -562,7 +583,7 @@
 	/* Length is the number of objects, not number of bytes.
 	*/
 	length = simple_strtoul(argv[2], NULL, 16);
-
+#if 0
 	/* data to write */
 	data = simple_strtoul(argv[3], NULL, 16);
 
@@ -607,6 +628,14 @@
 		while (i-- > 0)
 			*cp++ = data;
 	}
+#endif
+	for(;;){
+		*(struct pattern *)(addr+0x0000000) = pp;
+		*(struct pattern *)(addr+0x0000010) = pp;
+		*(struct pattern *)(addr+0x0000020) = pp;
+		*(struct pattern *)(addr+0x0000030) = pp;
+	}
+
 }
 #endif /* CONFIG_LOOPW */
 
@@ -619,7 +648,7 @@
 {
 	vu_long	*addr, *start, *end;
 	ulong	val;
-	ulong	readback;
+//	ulong	readback;
 	ulong	errs = 0;
 	int iterations = 1;
 	int iteration_limit;
@@ -650,8 +679,9 @@
 		0xaaaaaaaa,	/* alternating 1/0 */
 	};
 #else
-	ulong	incr;
+	ulong	incr=0;
 	ulong	pattern;
+	incr=incr;
 #endif
 
 	if (argc > 1)
@@ -926,9 +956,9 @@
 		for (addr=start,val=pattern; addr<end; addr++) {
 			WATCHDOG_RESET();
 			*addr = val;
-			val  += incr;
+//			val  += incr;
 		}
-
+#if 0
 		puts ("Reading...");
 
 		for (addr=start,val=pattern; addr<end; addr++) {
@@ -944,22 +974,23 @@
 					return 1;
 				}
 			}
-			val += incr;
+		//	val += incr;
 		}
-
+#endif
 		/*
 		 * Flip the pattern each time to make lots of zeros and
 		 * then, the next time, lots of ones.  We decrement
 		 * the "negative" patterns and increment the "positive"
 		 * patterns to preserve this feature.
 		 */
-		if(pattern & 0x80000000) {
-			pattern = -pattern;	/* complement & increment */
-		}
-		else {
+//		if(pattern & 0x80000000) {
+//			pattern = -pattern;	/* complement & increment */
+//		}
+
+//		else{
 			pattern = ~pattern;
-		}
-		incr = -incr;
+//		}
+		//incr = -incr;
 	}
 #endif
 	return 0;	/* not reached */
@@ -1022,6 +1053,10 @@
 	 * the next value.  A non-converted value exits.
 	 */
 	do {
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+	        if (check_write_to_code_area (addr, size))
+	        	return -1;
+#endif
 		printf("%08lx:", addr);
 		if (size == 4)
 			printf(" %08x", *((uint   *)addr));
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_mmc.c u-boot-2011.06/common/cmd_mmc.c
--- u-boot-2011.06_original/common/cmd_mmc.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_mmc.c	2014-07-29 17:28:38.819972000 +0800
@@ -53,7 +53,8 @@
 
 		curr_device = dev;
 		printf("mmc%d is available\n", curr_device);
-	} else if (strcmp(argv[1], "device") == 0) {
+	} 
+	else if (strcmp(argv[1], "device") == 0) {
 		if (argc == 2) {
 			if (curr_device < 0) {
 				puts("No MMC device available\n");
@@ -87,6 +88,12 @@
 );
 #else /* !CONFIG_GENERIC_MMC */
 
+enum mmc_state {
+	MMC_INVALID,
+	MMC_READ,
+	MMC_WRITE,
+	MMC_ERASE,
+};
 static void print_mmcinfo(struct mmc *mmc)
 {
 	printf("Device: %s\n", mmc->name);
@@ -100,7 +107,7 @@
 	printf("Rd Block Len: %d\n", mmc->read_bl_len);
 
 	printf("%s version %d.%d\n", IS_SD(mmc) ? "SD" : "MMC",
-			(mmc->version >> 4) & 0xf, mmc->version & 0xf);
+			(mmc->version >> 8) & 0xf, mmc->version & 0xff);
 
 	printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
 	puts("Capacity: ");
@@ -138,12 +145,14 @@
 U_BOOT_CMD(
 	mmcinfo, 1, 0, do_mmcinfo,
 	"display MMC info",
-	"    - device number of the device to dislay info of\n"
+	"    - device number of the device to display info of\n"
 	""
 );
 
 int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+	enum mmc_state state;
+
 	if (argc < 2)
 		return cmd_usage(cmdtp);
 
@@ -165,9 +174,11 @@
 		}
 
 		mmc->has_init = 0;
-		mmc_init(mmc);
 
-		return 0;
+		if (mmc_init(mmc))
+			return 1;
+		else
+			return 0;
 	} else if (strncmp(argv[1], "part", 4) == 0) {
 		block_dev_desc_t *mmc_dev;
 		struct mmc *mmc = find_mmc_device(curr_device);
@@ -227,7 +238,7 @@
 				if (!ret)
 					mmc->part_num = part;
 
-				printf("switch to partions #%d, %s\n",
+				printf("switch to partitions #%d, %s\n",
 						part, (!ret) ? "OK" : "ERROR");
 			}
 		}
@@ -239,53 +250,61 @@
 				curr_device, mmc->part_num);
 
 		return 0;
-	} else if (strcmp(argv[1], "read") == 0) {
-		void *addr = (void *)simple_strtoul(argv[2], NULL, 16);
-		u32 cnt = simple_strtoul(argv[4], NULL, 16);
-		u32 n;
-		u32 blk = simple_strtoul(argv[3], NULL, 16);
-		struct mmc *mmc = find_mmc_device(curr_device);
-
-		if (!mmc) {
-			printf("no mmc device at slot %x\n", curr_device);
-			return 1;
-		}
-
-		printf("\nMMC read: dev # %d, block # %d, count %d ... ",
-				curr_device, blk, cnt);
-
-		mmc_init(mmc);
-
-		n = mmc->block_dev.block_read(curr_device, blk, cnt, addr);
+	}
 
-		/* flush cache after read */
-		flush_cache((ulong)addr, cnt * 512); /* FIXME */
+	if (strcmp(argv[1], "read") == 0)
+		state = MMC_READ;
+	else if (strcmp(argv[1], "write") == 0)
+		state = MMC_WRITE;
+	else if (strcmp(argv[1], "erase") == 0)
+		state = MMC_ERASE;
+	else
+		state = MMC_INVALID;
 
-		printf("%d blocks read: %s\n",
-				n, (n==cnt) ? "OK" : "ERROR");
-		return (n == cnt) ? 0 : 1;
-	} else if (strcmp(argv[1], "write") == 0) {
-		void *addr = (void *)simple_strtoul(argv[2], NULL, 16);
-		u32 cnt = simple_strtoul(argv[4], NULL, 16);
-		u32 n;
+	if (state != MMC_INVALID) {
 		struct mmc *mmc = find_mmc_device(curr_device);
-
-		int blk = simple_strtoul(argv[3], NULL, 16);
+		int idx = 2;
+		u32 blk, cnt, n;
+		void *addr;
+
+		if (state != MMC_ERASE) {
+			addr = (void *)simple_strtoul(argv[idx], NULL, 16);
+			++idx;
+		} else
+			addr = 0;
+		blk = simple_strtoul(argv[idx], NULL, 16);
+		cnt = simple_strtoul(argv[idx + 1], NULL, 16);
 
 		if (!mmc) {
 			printf("no mmc device at slot %x\n", curr_device);
 			return 1;
 		}
 
-		printf("\nMMC write: dev # %d, block # %d, count %d ... ",
-				curr_device, blk, cnt);
+		printf("\nMMC %s: dev # %d, block # %d, count %d ... ",
+				argv[1], curr_device, blk, cnt);
 
 		mmc_init(mmc);
 
-		n = mmc->block_dev.block_write(curr_device, blk, cnt, addr);
+		switch (state) {
+		case MMC_READ:
+			n = mmc->block_dev.block_read(curr_device, blk,
+						      cnt, addr);
+			/* flush cache after read */
+			flush_cache((ulong)addr, cnt * 512); /* FIXME */
+			break;
+		case MMC_WRITE:
+			n = mmc->block_dev.block_write(curr_device, blk,
+						      cnt, addr);
+			break;
+		case MMC_ERASE:
+			n = mmc->block_dev.block_erase(curr_device, blk, cnt);
+			break;
+		default:
+			BUG();
+		}
 
-		printf("%d blocks written: %s\n",
-				n, (n == cnt) ? "OK" : "ERROR");
+		printf("%d blocks %s: %s\n",
+				n, argv[1], (n == cnt) ? "OK" : "ERROR");
 		return (n == cnt) ? 0 : 1;
 	}
 
@@ -297,6 +316,7 @@
 	"MMC sub system",
 	"read addr blk# cnt\n"
 	"mmc write addr blk# cnt\n"
+	"mmc erase blk# cnt\n"
 	"mmc rescan\n"
 	"mmc part - lists available partition on current mmc device\n"
 	"mmc dev [dev] [part] - show or set current mmc device [partition]\n"
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_nand.c u-boot-2011.06/common/cmd_nand.c
--- u-boot-2011.06_original/common/cmd_nand.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_nand.c	2014-07-29 17:28:38.819972000 +0800
@@ -470,7 +470,8 @@
 		int chip = 0;
 		int spread = 0;
 		int args = 2;
-
+		chip=chip;
+		part=part;
 		if (cmd[5] != 0) {
 			if (!strcmp(&cmd[5], ".spread")) {
 				spread = 1;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_nvedit.c u-boot-2011.06/common/cmd_nvedit.c
--- u-boot-2011.06_original/common/cmd_nvedit.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_nvedit.c	2014-07-29 17:28:38.819972000 +0800
@@ -459,8 +459,8 @@
 {
 	char buffer[CONFIG_SYS_CBSIZE];
 	char *init_val;
-	int len;
-
+	int len=0;
+	len=len;
 	if (argc < 2)
 		return cmd_usage(cmdtp);
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_sec_env.c u-boot-2011.06/common/cmd_sec_env.c
--- u-boot-2011.06_original/common/cmd_sec_env.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_sec_env.c	2015-01-27 18:37:47.257516000 +0800
@@ -0,0 +1,645 @@
+#include <common.h>
+#include <command.h>
+#include <mmc.h>
+#include <spi_flash.h>
+#include <environment.h>
+#include <watchdog.h>
+#include <serial.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+// #include <asm/global_data.h>
+#if defined(CONFIG_CMD_NET)
+#include <net.h>
+#endif
+
+#include <search.h>
+#include <errno.h>
+#include <malloc.h>
+#include <nand.h>
+
+#ifndef CONFIG_ENV_SPI_BUS
+# define CONFIG_ENV_SPI_BUS	0
+#endif
+#ifndef CONFIG_ENV_SPI_CS
+# define CONFIG_ENV_SPI_CS		0
+#endif
+#ifndef CONFIG_ENV_SPI_MAX_HZ
+# define CONFIG_ENV_SPI_MAX_HZ	1000000
+#endif
+#ifndef CONFIG_ENV_SPI_MODE
+# define CONFIG_ENV_SPI_MODE	SPI_MODE_3
+#endif
+
+typedef int (*UBootCommandFunction)(cmd_tbl_t *, int, int, char * const[]);
+
+static int readenv2(size_t offset, u_char *buf, size_t env_length, size_t env_range);
+static int env_import2(const char *buf, int check, struct hsearch_data *env_hash_table, size_t env_size);
+static void set_default_env2(const char *s, struct hsearch_data *environ_hash_table, char *def_env, size_t def_env_size);
+static int env_print2(char *name, struct hsearch_data *env_hash_table);
+extern int do_nand( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int env_import(const char *buf, int check);
+static int writeenv(size_t offset, u_char *buf);
+
+void dispsecenv(void);
+
+// DECLARE_GLOBAL_DATA_PTR;
+
+#define SECURED_PARAMETER_SIZE      ( CONFIG_ENV_F_SIZE - ENV_HEADER_SIZE  )
+#define SECURED_PARAMETER_IN_FLASH  ( CONFIG_ENV_F_OFFSET )
+#define SECURED_PARAMETER_SIGNATURE ( 0xCA98CADE )
+#define EXTRA_BLOCKS_IN_FLASH       ( 1 )
+
+/* Hash table for secure environment variables. */
+struct hsearch_data sec_env_htbl;
+env_t secure_environment;
+
+
+#define FACTORY_PASSWORD   ( "cavium_secret" )
+#ifndef CONFIG_SEC_ENV_IS_IN_MMC
+#define FLASH_SECTOR_SIZE (CONFIG_ENV_F_SECT_SIZE)
+#endif
+
+static int AllowEdit = 0;
+
+//-----------------------------------------------------------------------------------------
+
+#ifdef CONFIG_SEC_ENV_IS_IN_MMC
+static int writeenv(size_t offset, u_char *buf)
+{
+	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_SEC_ENV_DEV);
+	uint blk_start, blk_cnt, n;
+
+	blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len;
+	blk_cnt   = ALIGN(CONFIG_ENV_F_SIZE, mmc->write_bl_len) / mmc->write_bl_len;
+
+	n = mmc->block_dev.block_write(CONFIG_SYS_MMC_SEC_ENV_DEV, blk_start,
+			blk_cnt, buf);
+
+	return (n == blk_cnt) ? 0 : 1;
+}
+#else
+/*
+ * The legacy NAND code saved the environment in the first NAND device i.e.,
+ * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
+ */
+static int writeenv(size_t offset, u_char *buf)
+{
+	size_t end = offset + CONFIG_ENV_F_SIZE;
+	size_t amount_saved = 0;
+	size_t blocksize, len;
+
+	u_char *char_ptr;
+
+	blocksize = nand_info[0].erasesize;
+	len = min(blocksize, CONFIG_ENV_F_SIZE);
+	end += (blocksize * EXTRA_BLOCKS_IN_FLASH);
+
+	while (amount_saved < CONFIG_ENV_F_SIZE && offset < end) {
+		if (nand_block_isbad(&nand_info[0], offset)) {
+			printf("%s: ***** block at offset 0x%07x is bad, skipping.\n", __func__, offset);
+			offset += blocksize;
+		} else {
+			char_ptr = &buf[amount_saved];
+			if (nand_write(&nand_info[0], offset, &len,
+						char_ptr))
+				return 1;
+			printf("%s: wrote 0x%07x bytes of data to offset 0x%07x\n", __func__, len, offset);
+			offset += blocksize;
+			amount_saved += len;
+		}
+	}
+	printf("%s: 0x%07x/0x%07x saved\n", __func__, amount_saved, CONFIG_ENV_F_SIZE);
+	if (amount_saved != CONFIG_ENV_F_SIZE)
+		return 1;
+
+	return 0;
+}
+#endif
+
+/*
+ * Command interface: print one or all environment variables
+ *
+ * Returns 0 in case of error, or length of printed string
+ */
+static int env_print2(char *name, struct hsearch_data *env_hash_table)
+{
+	char *res = NULL;
+	size_t len;
+
+	if (name) {		/* print a single name */
+		ENTRY e, *ep;
+
+		e.key = name;
+		e.data = NULL;
+		hsearch_r(e, FIND, &ep, env_hash_table);
+		if (ep == NULL)
+			return 0;
+		len = printf("%s=%s\n", ep->key, ep->data);
+		return len;
+	}
+
+	/* print whole list */
+	len = hexport_r(env_hash_table, '\n', &res, 0);
+
+	if (len > 0) {
+		puts(res);
+		free(res);
+		return len;
+	}
+
+	/* should never happen */
+	return 0;
+}
+
+static void set_default_env2(const char *s, struct hsearch_data *environ_hash_table, char *def_env, size_t def_env_size)
+{
+	if (def_env_size > ENV_SIZE) {
+		puts("*** Error - default environment is too large\n\n");
+		return;
+	}
+
+	if (s) {
+		if (*s == '!') {
+			printf("*** Warning - %s, "
+					"using default environment\n\n",
+					s+1);
+		} else {
+			puts(s);
+		}
+	} else {
+		puts("Using default environment\n\n");
+	}
+
+	if (himport_r(environ_hash_table, def_env, def_env_size, '\0', 0) == 0) {
+		error("Environment import failed: errno = %d\n", errno);
+	}
+	return;
+}
+
+#ifdef CONFIG_SEC_ENV_IS_IN_MMC
+static int readenv2(size_t offset, u_char *buf, size_t env_length, size_t env_range)
+{
+	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_SEC_ENV_DEV);
+	uint blk_start, blk_cnt, n;
+
+	blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
+	blk_cnt   = ALIGN(env_length, mmc->read_bl_len) / mmc->read_bl_len;
+
+	n = mmc->block_dev.block_read(CONFIG_SYS_MMC_SEC_ENV_DEV, blk_start,
+			blk_cnt, buf);
+
+	return (n == blk_cnt) ? 0 : 1;
+}
+#else
+static int readenv2(size_t offset, u_char *buf, size_t env_length, size_t env_range)
+{
+	size_t end = offset + env_range;
+	size_t amount_loaded = 0;
+	size_t blocksize, len;
+
+	u_char *char_ptr;
+
+	blocksize = nand_info[0].erasesize;
+	if (!blocksize)
+		return 1;
+	len = min(blocksize, env_length);
+	end += (blocksize * EXTRA_BLOCKS_IN_FLASH);
+
+	while (amount_loaded < env_length && offset < end) {
+		if (nand_block_isbad(&nand_info[0], offset)) {
+			offset += blocksize;
+		} else {
+			char_ptr = &buf[amount_loaded];
+			if (nand_read_skip_bad(&nand_info[0], offset, &len, char_ptr))
+				return 1;
+			offset += blocksize;
+			amount_loaded += len;
+		}
+	}
+	if (amount_loaded != env_length)
+		return 1;
+
+	return 0;
+}
+#endif
+
+static uint32_t Sec_GetCrc32(void)
+{
+	return crc32(0, &(secure_environment.data[0]), SECURED_PARAMETER_SIZE);
+}
+
+void sec_set_default_env(const char *s)
+{
+	char defenv[4];
+
+	memset(&defenv[0], 0, sizeof(defenv));
+	set_default_env2(s, &sec_env_htbl, defenv, sizeof(defenv));
+}
+
+/*
+ * Check if CRC is valid and (if yes) import the environment.
+ * Note that "buf" may or may not be aligned.
+ */
+static int env_import2(const char *buf, int check, struct hsearch_data *env_hash_table, size_t env_size)
+{
+	env_t *ep = (env_t *)buf;
+
+	if (check) {
+		uint32_t exp_crc, act_crc;
+
+		memcpy(&exp_crc, &ep->crc, sizeof(exp_crc));
+
+		act_crc = crc32(0, ep->data, env_size);
+		if (act_crc != exp_crc)
+			return 0;
+	}
+
+	if (himport_r(env_hash_table, (char *)ep->data, env_size, '\0', 0)) {
+		return 1;
+	}
+
+	error("Cannot import environment: errno = %d\n", errno);
+
+	sec_set_default_env("!secure import failed");
+
+	return 0;
+}
+
+void sec_env_relocate(void)
+{
+	int rv; uint32_t actual_crc;
+	printf("initializing secure environment\n");
+
+#ifdef CONFIG_SEC_ENV_IS_IN_MMC
+	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_SEC_ENV_DEV);
+
+	if (!mmc) {
+		sec_set_default_env("!No MMC card found\n");
+		return;
+	}
+
+	if (mmc_init(mmc)) {
+		sec_set_default_env("!MMC init failed\n");
+		return;
+	}
+#endif
+
+	/* Create a 67-element empty hash table. */
+	sec_env_htbl.table = NULL;
+	if (hcreate_r(67, &sec_env_htbl)) {
+		memset(&secure_environment, 0xff, sizeof(secure_environment));
+		rv = readenv2(SECURED_PARAMETER_IN_FLASH,
+				(u_char *)&secure_environment,
+				CONFIG_ENV_SIZE, CONFIG_ENV_SIZE);
+		/* dispsecenv(); */
+		if (rv == 0) {
+			actual_crc = Sec_GetCrc32();
+			if (actual_crc != secure_environment.crc) {
+				printf("bad factory default area CRC: 0x%08x (actual) vs 0x%08x (expected)\n",
+						actual_crc, secure_environment.crc);
+				sec_set_default_env("!bad factory default environment CRC");
+			} else {
+				env_import2((const char *)(&secure_environment), 0, &sec_env_htbl, SECURED_PARAMETER_SIZE);
+			}
+		} else {
+			printf("there was a problem reading the factory default environment!\n");
+		}
+	} else {
+		printf("ERROR! could not create a new hash table for factory default environment!\n");
+	}
+	return;
+}
+
+#ifdef CONFIG_SYS_FLASH_PROTECTION
+static int SecChangeFlashProtection(int protect)
+{
+	int status = 0;
+	char TempCmd2_1[16], TempCmd2_2[16];
+	char *pCmd3[4] = { "protect", "off", NULL, NULL };
+	uint32_t aDestinationAddressInFlash = SECURED_PARAMETER_IN_FLASH;
+	uint32_t aLength = ((sizeof(gSecNvRam) + FLASH_SECTOR_SIZE - 1)/FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE;
+
+	if (protect) pCmd3[1] = "on";
+	sprintf(TempCmd2_1, "0x%x", aDestinationAddressInFlash);
+	sprintf(TempCmd2_2, "0x%x", aDestinationAddressInFlash + aLength - 1);
+	pCmd3[2] = TempCmd2_1;
+	pCmd3[3] = TempCmd2_2;
+	if (do_protect(NULL, 0, 4, (char** const) pCmd3) != 0)
+	{
+		status = -1;
+		if (protect)
+			printf("ERROR: fail to protect secure parameter sector\n");
+		else
+			printf("ERROR: fail to un-protect secure parameter sector\n");
+	}
+	return status;
+}
+#endif
+
+void dispsecenv(void)
+{
+	register int k, j; char c;
+	printf("secure environment CRC = 0x%08x\n", secure_environment.crc);
+	printf("first 512 bytes:\n");
+	for (k = 0; k < 32; ++k) {
+		printf("0x%03x:", k*16);
+		for (j = 0; j < 8; ++j) printf(" %02x", secure_environment.data[k*16+j]);
+		printf("  ");
+		for (j = 8; j < 16; ++j) printf(" %02x", secure_environment.data[k*16+j]);
+		printf("    ");
+		for (j = 0; j < 8; ++j) {
+			c = secure_environment.data[k*16+j];
+			if (c >= ' ' && c <= '~')
+				putc(c);
+			else
+				putc('.');
+		}
+		printf("  ");
+		for (j = 8; j < 16; ++j) {
+			c = secure_environment.data[k*16+j];
+			if (c >= ' ' && c <= '~')
+				putc(c);
+			else
+				putc('.');
+		}
+		printf("\n");
+	}
+	return;
+}
+
+static int Sec_SaveNvramToFlash(void)
+{
+	int status = -1;
+	nand_erase_options_t nand_erase_options;
+	unsigned char *buffer;
+
+	memset(&secure_environment, 0xff, sizeof(secure_environment));
+	buffer = &(secure_environment.data[0]);
+	if (hexport_r(&sec_env_htbl, '\0', (char **)&buffer, SECURED_PARAMETER_SIZE) != -1) {
+
+		secure_environment.crc = Sec_GetCrc32();
+		memset(&nand_erase_options, 0, sizeof(nand_erase_options));
+
+		nand_erase_options.length = SECURED_PARAMETER_SIZE + (nand_info[0].erasesize*EXTRA_BLOCKS_IN_FLASH);
+		nand_erase_options.offset = SECURED_PARAMETER_IN_FLASH;
+
+#ifdef CONFIG_SEC_ENV_IS_IN_MMC
+		puts("Writing to MMC... ");
+#else
+		puts("Erasing NAND...\n");
+		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
+			return status;
+
+		/* dispsecenv(); */
+		puts("Writing to NAND... ");
+#endif
+		if (writeenv(SECURED_PARAMETER_IN_FLASH, (u_char *)&secure_environment)) {
+			puts("FAILED!\n");
+		} else {
+			puts("done\n");
+			status = 0;
+		}
+	} else {
+		error("Cannot export environment: errno = %d\n", errno);
+	}
+
+	return status;
+
+}
+
+//-----------------------------------------------------------------------------------------
+
+void Sec_NvramPrint(char* apTag)
+{
+	env_print2(apTag, &sec_env_htbl);
+	return;
+}
+
+int Sec_SetNvRam (char *name, char *value)
+{
+	ENTRY e, *ep;
+
+	if (strchr(name, '=')) {
+		printf("## Error: illegal character '=' in variable name \"%s\"\n", name);
+		return -1;
+	}
+
+	/* Delete only ? */
+	if (value == NULL) {
+		printf("Deleting secure environment key \"%s\"\n", name);
+		return hdelete_r(name, &sec_env_htbl)? 0 : -1;
+	}
+
+	/*
+	 * Insert / replace new value
+	 */
+	e.key  = name;
+	e.data = value;
+	hsearch_r(e, ENTER, &ep, &sec_env_htbl);
+	if (!ep)
+	{
+		printf("## Error inserting \"%s\" variable, errno=%d\n",name, errno);
+		return -1;
+	}
+
+	return 0;
+}
+
+#if 0
+int Sec_Init(void)
+{
+	int status = -1;
+	memset( & gSecNvRam , 0, sizeof (SecNvRam_t) );
+	status = Sec_LoadNvramFromFlash();
+	if (0 == status )
+	{
+		printf("Secured parameter OK...\n");
+	}
+	else
+	{
+		printf("ERROR: Invalid Secured parameter found, OR it looks like secured parameter was never programmed on this board.\n");
+		memset( & gSecNvRam , 0, sizeof (SecNvRam_t) );
+		//Sec_SaveNvramToFlash();
+	}
+	Sec_ProtectSector();
+	return status;
+}
+#endif
+
+
+int do_printsecenv(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i;
+	int status = 0;
+	if ( argc == 1 )
+	{
+		Sec_NvramPrint(NULL);
+	}
+	else
+	{
+		for (i = 1; i < argc; i++)
+		{
+			Sec_NvramPrint(argv[i]);
+		}
+	}
+	return status;
+}
+
+#define TEMPBUF_SIZE (512)
+int do_setsecenv(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i, status = -1, overflowed = 0, remaining;
+	char *dst, *src, TempBuf[TEMPBUF_SIZE] = {0};
+	if (argc == 2 )
+	{
+		Sec_SetNvRam( argv[1], NULL );
+		status = 0;
+	}
+	else
+	{
+		dst = &TempBuf[0]; remaining = TEMPBUF_SIZE; src = &argv[2][0];
+		while (--remaining > 0 && *src != '\0')
+			*dst++ = *src++;
+		if (*src == '\0' && remaining > 0)
+		{
+			for (i = 3; i < argc; ++i)
+			{
+				*dst++ = ' ';
+				src = &argv[i][0];
+				while (--remaining > 0 && *src != '\0')
+					*dst++ = *src++;
+				if (*src != '\0') { overflowed = 1; break; }
+			}
+			if (!overflowed)
+			{
+				*dst = '\0';
+				Sec_SetNvRam( argv[1], TempBuf );
+				status = 0;
+			}
+		}
+	}
+	return status;
+}
+
+int Sec_SaveToFlash(void)
+{
+	int status = 0;
+
+
+	if ( 0 == AllowEdit  )
+	{
+		printf("ERROR: Sorry, you need password to save secured parameter\n");
+		return -1;
+	}
+
+	status = Sec_SaveNvramToFlash();
+	if ( 0 != status )
+	{
+		printf("ERROR: failed to store Secured paramter, please check hardware or contact vendor\n");
+	}
+	return status;
+}
+
+int do_savesecenv(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return Sec_SaveToFlash();
+}
+
+int do_pswdsec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int status = -1;
+	if ( 0 == strcmp(argv[1] , FACTORY_PASSWORD ) )
+	{
+		AllowEdit = 1;
+		printf("Password OK, now you can save factory parameters.\n");
+		status = 0;
+	}
+	else
+	{
+		printf("ERROR: wrong password entered, please contact Cavium.\n");
+	}
+	return status;
+}
+
+int do_set_sec_defaults(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int status = -1, rv;
+	u_char *buffer = NULL;
+	uint32_t exp_crc, act_crc;
+
+	/* Verify CRC on factory area */
+	printf("Read factory default environment and verify CRC.\n");
+	buffer = (u_char *)malloc(CONFIG_ENV_SIZE);
+	if (buffer == NULL) {
+		printf("ERROR: not enough memory to execute command!\n");
+		goto done;
+	}
+	rv = readenv2(SECURED_PARAMETER_IN_FLASH, buffer, CONFIG_ENV_SIZE, CONFIG_ENV_SIZE);
+	if (rv != 0) {
+		printf("ERROR: could not read factory default environment!\n");
+		goto free_then_done;
+	}
+	act_crc = crc32(0, buffer + (CONFIG_ENV_SIZE-SECURED_PARAMETER_SIZE), SECURED_PARAMETER_SIZE);
+	exp_crc = *(uint32_t *)buffer;
+	if (act_crc != exp_crc) {
+		printf("ERROR: actual CRC of 0x%08x does not match expected CRC of 0x%08x in secure NVRAM area!\n",
+				act_crc, exp_crc);
+		goto free_then_done;
+	}
+
+	/* Re-load environment hash table */
+	env_import((char *)buffer, 0);
+	saveenv();
+	printf("Sync memory with new environment.\n");
+
+	/* We're done! */
+	status = 0;
+
+free_then_done:
+	free(buffer);
+done:
+	return status;
+}
+
+/**************************************************/
+U_BOOT_CMD(
+		printsecenv, CONFIG_SYS_MAXARGS, 1, (UBootCommandFunction)do_printsecenv,
+		"printsecenv- print secured environment variables\n",
+		"\n    - print values of all secured environment variables\n"
+		"printenv name ...\n"
+		"    - print value of environment variable 'name'\n"
+	  );
+
+U_BOOT_CMD(
+		setsecenv, CONFIG_SYS_MAXARGS, 0, (UBootCommandFunction)do_setsecenv,
+		"setsecenv  - set environment variables\n",
+		"name value ...\n"
+		"    - set secured environment variable 'name' to 'value ...'\n"
+		"setsecenv name\n"
+		"    - delete environment variable 'name'\n"
+	  );
+
+U_BOOT_CMD(
+		savesecenv, 1+0, 0,	(UBootCommandFunction)do_savesecenv,
+		"savesecenv - save secured environment variables to storage\n",
+		NULL
+	  );
+
+U_BOOT_CMD(
+		pswdsec, 1+1, 0,	(UBootCommandFunction)do_pswdsec,
+		"pswdsec - to save secured parameter enter password\n",
+		NULL
+	  );
+
+U_BOOT_CMD(
+		secinit, CONFIG_SYS_MAXARGS, 0,	(UBootCommandFunction)sec_env_relocate,
+		"secinit- initialize secure environment stuff\n"
+		" (for testing purposes only)\n",
+		NULL
+	  );
+
+U_BOOT_CMD(
+		nvram_set_defaults, 1, 0, (UBootCommandFunction)do_set_sec_defaults,
+		"nvram_set_defaults - reset environment to factory defaults\n",
+		NULL
+	  );
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_sf.c u-boot-2011.06/common/cmd_sf.c
--- u-boot-2011.06_original/common/cmd_sf.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_sf.c	2014-07-29 17:28:38.819972000 +0800
@@ -147,6 +147,8 @@
 	if (ret) {
 		printf("SPI flash %s failed\n", argv[0]);
 		return 1;
+	} else {
+		printf("Successfully r/w %d bytes of data\n", (unsigned int)len);
 	}
 
 	return 0;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_sf_legacy.c u-boot-2011.06/common/cmd_sf_legacy.c
--- u-boot-2011.06_original/common/cmd_sf_legacy.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_sf_legacy.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,398 @@
+/*
+ * (C) Copyright 2002
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.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
+ */
+
+/*
+ * SPI Read/Write Utilities
+ */
+
+#include <common.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int do_sflashre(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned char *maddr;
+	unsigned int caddr;
+	unsigned int size;
+
+	if (argc != 4) {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
+	}
+
+	maddr = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
+	caddr = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	SDEBUG("caddr: 0x%x, maddr: 0x%x, size: 0x%x\n",  caddr, (unsigned int) maddr, size);
+
+	seeprom_read(caddr, maddr, size);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfre,	CONFIG_SYS_MAXARGS/*5*/,	0,	do_sflashre,
+	"sfre    - spi flash read byte.\n",
+	"\nsfre <maddr> <offset> <len>\n"
+	);
+
+int do_sflashwr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned char *maddr;
+	unsigned int caddr;
+	int size;
+
+	if (argc != 4) {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
+	}
+
+	maddr = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
+	caddr = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	SDEBUG("caddr: 0x%x, maddr: 0x%x, size: 0x%x\n",  caddr, (unsigned int) maddr, size);
+
+	seeprom_write(caddr, maddr, size);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfwr,	CONFIG_SYS_MAXARGS/*5*/,	0,	do_sflashwr,
+	"sfwr    - spi flash write byte\n",
+	"\nsfwr <maddr> <offset> <len>\n"
+	);
+
+int do_sflasher(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	//volatile unsigned char *maddr;
+	unsigned int caddr, eaddr;
+	unsigned char *arg = (unsigned char *) argv[2];
+	int size;
+
+	if (argc < 2) {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
+	}
+
+	if (strcmp(argv[1], "all") == 0) {
+		seeprom_erase(CMD_CE, 0, 0);
+		return 0;
+	}
+
+	caddr = simple_strtoul(argv[1], NULL, 16);
+
+	if (*argv[2] == '+'){
+		size = simple_strtoul((char*) ++arg, NULL, 16);
+	} else {
+		eaddr = simple_strtoul(argv[2], NULL, 16);
+		size = eaddr - caddr;
+	}
+
+	//SDEBUG("caddr: 0x%x, maddr: 0x%x, size: 0x%x\n",  caddr, maddr, size);
+    SDEBUG("caddr: 0x%x, size: 0x%x\n",  caddr, size);
+
+	seeprom_erase(CMD_SE, caddr, size);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfer,	CONFIG_SYS_MAXARGS/*5*/,	0,	do_sflasher,
+	"sfer    - spi flash erase\n",
+	"\nsfer <from> <to>\n"
+	"sfer <from> <+size>\n"
+	);
+
+static void print_num(const char *name, ulong value)
+{
+	printf ("%-12s= 0x%08lX\n", name, value);
+}
+static void print_str(const char *name, const char *str)
+{
+	printf ("%-12s= %6s\n", name, str);
+}
+
+int do_sfinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+	print_str ("chipname",	    gd->sf_inf->name	   );
+	print_num ("chipid",	    gd->sf_inf->jedec_id   );
+	print_num ("extid",	    	gd->sf_inf->ext_id	   );
+	print_num ("secsize",       gd->sf_inf->sector_size);
+	print_num ("secnum",	    gd->sf_inf->n_sectors  );
+	print_num ("chipsize",	    gd->sf_size 	   );
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfinfo,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_sfinfo,
+	"sfinfo  - display spi flash informations.\n",
+	NULL
+	);
+
+#if 0
+void spi_rx_flash(void)
+{
+	/* write data */
+	spi_write(rDR, 0x3);
+	/* write addr */
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+	/* read 3 byte */
+	spi_write(rDR, 0x0);	/* for receive only */
+	spi_write(rDR, 0x0);	/* for reveive only */
+	spi_write(rDR, 0x0);	/* for reveive only */
+
+	/* polling for finish */
+	while (spi_read(rSR) & 0x1);
+	while (spi_read(rTXFLR) & 0x1);
+	while (! (spi_read(rSR) & 0x8));
+	udelay(10000);	/* important */
+
+	/* read dummy data */
+	spi_read(rDR);
+	spi_read(rDR);
+	spi_read(rDR);
+	spi_read(rDR);
+
+	printf("read data 1: 	0x%x\n", spi_read(rDR));
+	printf("read data 2: 	0x%x\n", spi_read(rDR));
+	printf("read data 3: 	0x%x\n", spi_read(rDR));
+}
+
+void spi_flash_erase(void)
+{
+	/* write data */
+	spi_write(rDR, 0xd8);
+	/* write addr */
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+
+	/* polling for finish */
+	while (spi_read(rSR) & 0x1);
+	while (spi_read(rTXFLR) & 0x1);
+	while (! (spi_read(rSR) & 0x8));
+	udelay(10000);	/* important */
+}
+void spi_tx_flash(void)
+{
+	//spi_flash_erase();
+
+	/* write data */
+	spi_write(rDR, 0x2);
+	/* write addr */
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+	spi_write(rDR, 0x0);
+	/* read 3 byte */
+#if 0
+	spi_write(rDR, 0x1);	/* for receive only */
+	spi_write(rDR, 0x2);	/* for reveive only */
+	spi_write(rDR, 0x3);	/* for reveive only */
+#else
+	spi_write(rDR, 0x3);	/* for receive only */
+	spi_write(rDR, 0x2);	/* for reveive only */
+	spi_write(rDR, 0x1);	/* for reveive only */
+#endif
+
+	/* polling for finish */
+	while (spi_read(rSR) & 0x1);
+	while (spi_read(rTXFLR) & 0x1);
+	while (! (spi_read(rSR) & 0x8));
+	udelay(10000);	/* important */
+}
+
+int do_sflashr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+/*    spi_rxtx_mode();*/
+/*    spi_timing_mode3();*/
+	*(volatile unsigned short *)(0x10150008) = 0;
+	*(volatile unsigned short *)(0x10150000) = 0x0c7;
+	*(volatile unsigned short *)(0x10150008) = 1;
+
+	spi_rx_flash();
+}
+
+U_BOOT_CMD(
+	sfr,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_sflashr,
+	"sfr     - flash read test\n",
+	NULL
+	);
+
+int do_sflashw(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+/*    spi_rxtx_mode();*/
+/*    spi_timing_mode3();*/
+
+/*    spi_timing_mode0();*/
+	*(volatile unsigned short *)(0x10150008) = 0;
+	*(volatile unsigned short *)(0x10150000) = 0x007;
+	*(volatile unsigned short *)(0x10150008) = 1;
+	spi_write(rDR, 0x06);
+	mdelay(1);
+/*    spi_timing_mode3();*/
+	*(volatile unsigned short *)(0x10150008) = 0;
+	*(volatile unsigned short *)(0x10150000) = 0x0c7;
+	*(volatile unsigned short *)(0x10150008) = 1;
+
+	spi_tx_flash();
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfw,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_sflashw,
+	"sfw     - flash write test\n",
+	NULL
+	);
+
+int do_sflashe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+/*    spi_rxtx_mode();*/
+/*    spi_timing_mode0();*/
+	*(volatile unsigned short *)(0x10150008) = 0;
+	*(volatile unsigned short *)(0x10150000) = 0x007;
+	*(volatile unsigned short *)(0x10150008) = 1;
+	spi_write(rDR, 0x06);
+	mdelay(1);
+/*    spi_timing_mode3();*/
+	*(volatile unsigned short *)(0x10150008) = 0;
+	*(volatile unsigned short *)(0x10150000) = 0x0c7;
+	*(volatile unsigned short *)(0x10150008) = 1;
+
+	spi_flash_erase();
+
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfe,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_sflashe,
+	"sfe     - flash erase test\n",
+	NULL
+	);
+
+#endif
+
+#if 0
+
+/*===================================================================
+ * Two interface to write data bus.
+ */
+
+int do_spiw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc < 2) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+	spi_write(rDR, simple_strtoul(argv[1], NULL, 16));
+
+	return 0;
+}
+
+int do_spir(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc > 1) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	printf("%x\n", spi_read(rDR));
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	spiw,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_spiw,
+	"spiw    - wirte to spi bus(32)\n",
+	NULL
+	);
+U_BOOT_CMD(
+	spir,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_spir,
+	"spir    - read to spi bus(32)\n",
+	NULL
+	);
+#endif
+
+/* Do test */
+#if 0
+int do_spi_read1K(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned saddr, maddr, size;
+	int i;
+
+
+	saddr = simple_strtoul(argv[1], NULL, 16);
+	maddr = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	for (i = 0; i < size; i++) {
+		asm_spi_read_1k(saddr, maddr);
+		saddr += 1024;
+		maddr += 1024;
+	}
+
+	return 0;
+}
+U_BOOT_CMD(
+	spir1k,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_spi_read1K,
+	"spir1k    - read 1k use asmbly method\n",
+	NULL
+	);
+
+int do_nand_read(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	unsigned caddr, maddr, size;
+	int i;
+
+
+	caddr = simple_strtoul(argv[1], NULL, 16);
+	maddr = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	NANDOpen();
+	NANDRead_1K(maddr,caddr);
+	for (i = 0; i <= size/1024; i++) {
+		NANDRead_1K(maddr,caddr);
+		caddr += 1024;
+		maddr += 1024;
+	}
+	NANDClose();
+
+	return 0;
+}
+U_BOOT_CMD(
+	nandr,	CONFIG_SYS_MAXARGS/*5*/,	1,	do_nand_read,
+	"nandr    - read 1k from nand\n",
+	NULL
+	);
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_simg.c u-boot-2011.06/common/cmd_simg.c
--- u-boot-2011.06_original/common/cmd_simg.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_simg.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include <mmc.h>
+#include <malloc.h>
+#include <linux/ctype.h>
+
+typedef struct sparse_header {
+  __le32	magic;		/* 0xed26ff3a */
+  __le16	major_version;	/* (0x1) - reject images with higher major versions */
+  __le16	minor_version;	/* (0x0) - allow images with higer minor versions */
+  __le16	file_hdr_sz;	/* 28 bytes for first revision of the file format */
+  __le16	chunk_hdr_sz;	/* 12 bytes for first revision of the file format */
+  __le32	blk_sz;		/* block size in bytes, must be a multiple of 4 (4096) */
+  __le32	total_blks;	/* total blocks in the non-sparse output image */
+  __le32	total_chunks;	/* total chunks in the sparse input image */
+  __le32	image_checksum; /* CRC32 checksum of the original data, counting "don't care" */
+				/* as 0. Standard 802.3 polynomial, use a Public Domain */
+				/* table implementation */
+} sparse_header_t;
+
+#define SPARSE_HEADER_MAGIC	0xed26ff3a
+
+#define CHUNK_TYPE_RAW		0xCAC1
+#define CHUNK_TYPE_FILL		0xCAC2
+#define CHUNK_TYPE_DONT_CARE	0xCAC3
+#define CHUNK_TYPE_CRC32    0xCAC4
+
+typedef struct chunk_header {
+  __le16	chunk_type;	/* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
+  __le16	reserved1;
+  __le32	chunk_sz;	/* in blocks in output image */
+  __le32	total_sz;	/* in bytes of chunk input file including chunk header and data */
+} chunk_header_t;
+
+/* Following a Raw or Fill or CRC32 chunk is data.
+ *  For a Raw chunk, it's the data in chunk_sz * blk_sz.
+ *  For a Fill chunk, it's 4 bytes of the fill data.
+ *  For a CRC32 chunk, it's 4 bytes of CRC32
+ */
+
+#define SPARSE_HEADER_MAJOR_VER 1
+
+static u32 mem_addr;
+static u32 mmc_addr;
+
+static block_dev_desc_t *mmc_desc;
+
+#define COPY_BUF_SIZE (1024*1024)
+static u8 *copybuf;
+
+/*
+ * A function that calculates the CRC-32 based on the table above is
+ * given below for documentation purposes. An equivalent implementation
+ * of this function that's actually used in the kernel can be found
+ * in sys/libkern.h, where it can be inlined.
+ */
+
+static u32 sparse_crc32(u32 crc_in, const void *buf, int size)
+{
+	return crc32(crc_in, buf, size);
+}
+
+static int read_all(void *buf, size_t len)
+{
+	memcpy(buf, (void *)mem_addr, len);
+	mem_addr += len;
+	return len;
+}
+
+static int write_all(void *buf, size_t len)
+{
+	u32 start = mmc_addr / mmc_desc->blksz;
+	u32 blksz = len / mmc_desc->blksz;
+
+	mmc_desc->block_write(mmc_desc->dev, start, blksz, buf);
+	mmc_addr += len;
+	return len;
+}
+
+static void lseek_mem(u32 offset)
+{
+	mem_addr += offset;
+}
+
+static void lseek_mmc(u32 offset)
+{
+	mmc_addr += offset;
+}
+
+int process_raw_chunk(u32 blocks, u32 blk_sz, u32 *crc32)
+{
+	u64 len = blocks * blk_sz;
+	int ret;
+	int chunk;
+
+	while (len) {
+		chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len;
+		ret = read_all(copybuf, chunk);
+		if (ret != chunk) {
+			fprintf(stderr, "read returned an error copying a raw chunk: %d %d\n",
+					ret, chunk);
+			return(-1);
+		}
+		*crc32 = sparse_crc32(*crc32, copybuf, chunk);
+		ret = write_all(copybuf, chunk);
+		if (ret != chunk) {
+			fprintf(stderr, "write returned an error copying a raw chunk\n");
+			return(-1);
+		}
+		len -= chunk;
+	}
+
+	return blocks;
+}
+
+
+int process_fill_chunk(u32 blocks, u32 blk_sz, u32 *crc32)
+{
+	u64 len = blocks * blk_sz;
+	int ret;
+	int chunk;
+	u32 fill_val = 0;
+	u32 *fillbuf;
+	unsigned int i;
+
+	/* Fill copy_buf with the fill value */
+	ret = read_all(&fill_val, sizeof(fill_val));
+	fillbuf = (u32 *)copybuf;
+	for (i = 0; i < (COPY_BUF_SIZE / sizeof(fill_val)); i++) {
+		fillbuf[i] = fill_val;
+	}
+
+	while (len) {
+		chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len;
+		*crc32 = sparse_crc32(*crc32, copybuf, chunk);
+		ret = write_all(copybuf, chunk);
+		if (ret != chunk) {
+			fprintf(stderr, "write returned an error copying a raw chunk\n");
+			return(-1);
+		}
+		len -= chunk;
+	}
+
+	return blocks;
+}
+
+int process_skip_chunk(u32 blocks, u32 blk_sz, u32 *crc32)
+{
+	/* len needs to be 64 bits, as the sparse file specifies the skip amount
+	 * as a 32 bit value of blocks.
+	 */
+	u32 len = blocks * blk_sz;
+	lseek_mmc(len);
+
+	return blocks;
+}
+
+int process_crc32_chunk(u32 crc32)
+{
+	u32 file_crc32;
+	int ret;
+
+	ret = read_all(&file_crc32, 4);
+	if (ret != 4) {
+		fprintf(stderr, "read returned an error copying a crc32 chunk\n");
+		return(-1);
+	}
+
+	if (file_crc32 != crc32) {
+		fprintf(stderr, "computed crc32 of 0x%8.8x, expected 0x%8.8x\n",
+			 crc32, file_crc32);
+		return(-1);
+	}
+
+	return 0;
+}
+
+static int simg_mmc_write(int dev, char *memstr, char *mmcstr)
+{
+	unsigned int i;
+	struct mmc *mmc = find_mmc_device(dev);
+	sparse_header_t sparse_header;
+	chunk_header_t chunk_header;
+	u32 crc32 = 0;
+	u32 total_blocks = 0;
+	int ret;
+
+	mmc_desc = &mmc->block_dev;
+	mem_addr = simple_strtoul(memstr, NULL, 16);
+	mmc_addr = simple_strtoul(mmcstr, NULL, 16) * mmc_desc->blksz;
+
+	copybuf = malloc(COPY_BUF_SIZE);
+	if (!copybuf) {
+		fprintf(stderr, "Error mallocing buffer\n");
+		return(-1);
+	}
+
+	ret = read_all(&sparse_header, sizeof(sparse_header));
+	if (ret != sizeof(sparse_header)) {
+		fprintf(stderr, "Error reading sparse file header\n");
+		return(-1);
+	}
+
+	if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
+		fprintf(stderr, "Bad magic\n");
+		return(-1);
+	}
+
+	if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
+		fprintf(stderr, "Unknown major version number\n");
+		return(-1);
+	}
+
+	if (sparse_header.file_hdr_sz > sizeof(sparse_header_t)) {
+		/* Skip the remaining bytes in a header that is longer than
+		 * we expected.
+		 */
+		lseek_mem(sparse_header.file_hdr_sz - sizeof(sparse_header_t));
+	}
+
+	for (i=0; i<sparse_header.total_chunks; i++) {
+		ret = read_all(&chunk_header, sizeof(chunk_header));
+		if (ret != sizeof(chunk_header)) {
+			fprintf(stderr, "Error reading chunk header\n");
+			return(-1);
+		}
+
+		if (sparse_header.chunk_hdr_sz > sizeof(chunk_header_t)) {
+			/* Skip the remaining bytes in a header that is longer than
+			 * we expected.
+			 */
+			lseek_mem(sparse_header.chunk_hdr_sz - sizeof(chunk_header_t));
+		}
+
+		switch (chunk_header.chunk_type) {
+		    case CHUNK_TYPE_RAW:
+			if (chunk_header.total_sz != (sparse_header.chunk_hdr_sz +
+				 (chunk_header.chunk_sz * sparse_header.blk_sz)) ) {
+				fprintf(stderr, "Bogus chunk size for chunk %d, type Raw\n", i);
+				return(-1);
+			}
+			total_blocks += process_raw_chunk(chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
+			break;
+		    case CHUNK_TYPE_FILL:
+			if (chunk_header.total_sz != (sparse_header.chunk_hdr_sz + sizeof(u32)) ) {
+				fprintf(stderr, "Bogus chunk size for chunk %d, type Fill\n", i);
+				return(-1);
+			}
+			total_blocks += process_fill_chunk(chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
+			break;
+		    case CHUNK_TYPE_DONT_CARE:
+			if (chunk_header.total_sz != sparse_header.chunk_hdr_sz) {
+				fprintf(stderr, "Bogus chunk size for chunk %d, type Dont Care\n", i);
+				return(-1);
+			}
+			total_blocks += process_skip_chunk(chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
+			break;
+		    case CHUNK_TYPE_CRC32:
+			process_crc32_chunk(crc32);
+			break;
+		    default:
+			fprintf(stderr, "Unknown chunk type 0x%4.4x\n", chunk_header.chunk_type);
+		}
+
+	}
+
+	if (sparse_header.total_blks != total_blocks) {
+		fprintf(stderr, "Wrote %d blocks, expected to write %d blocks\n",
+			 total_blocks, sparse_header.total_blks);
+		return(-1);
+	}
+
+	return(0);
+}
+
+int do_simg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+	int dev = 0;
+	char *pstr;
+
+	if (argc < 6)
+		return CMD_RET_USAGE;
+
+	/* command: 'write' */
+	if ((strcmp(argv[1], "write") == 0) && (argc == 6)) {
+		/* device: 'mmc' */
+		if (strcmp(argv[2], "mmc") == 0) {
+			/* check if 'dev' is a number */
+			for (pstr = argv[3]; *pstr != '\0'; pstr++)
+				if (!isdigit(*pstr)) {
+					printf("'%s' is not a number\n",
+						argv[3]);
+					return CMD_RET_USAGE;
+				}
+			dev = (int)simple_strtoul(argv[3], NULL, 10);
+			/* write to mmc */
+			if (simg_mmc_write(dev, argv[4], argv[5]))
+				return CMD_RET_FAILURE;
+		}
+	} else {
+		return CMD_RET_USAGE;
+	}
+	return ret;
+}
+
+U_BOOT_CMD(simg, CONFIG_SYS_MAXARGS, 1, do_simg,
+	"Write Simg Image",
+	"<command> <interface> <simg addr> <mmc addr>\n"
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_update.c u-boot-2011.06/common/cmd_update.c
--- u-boot-2011.06_original/common/cmd_update.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_update.c	2015-06-18 16:19:05.254106000 +0800
@@ -0,0 +1,1322 @@
+#include "cnc_util.h"
+#include <net.h>
+
+//"update force splash,kernel,rootfs tftp://192.168.300.100/zcnc83xxS.bin";
+//"update force splash,kernel,rootfs usb://zcnc83xxS.bin";
+//"update miniloader,uboot  usb://zcnc83xxS.bin";
+//"update force";
+
+/* Update command usage - 
+ * update [CSV_LIST_OF_MTD_PARTITION_NAME] [force] [filename-url]
+ *
+ * e.g.:
+ * 
+ * 1) update                                                 -  update all partion available in cnc83xxS.bin from USB drive (except miniloader and uboot) you can only upgrade, if newer version is not greater
+ *                                                              compare to current working one, it will be skipped. (upgrade only)
+ * 2) update force                                           -  update all partion available in cnc83xxS.bin from USB drive - ignore version checking so user can do downgrade, upgrade.
+ * 3) update uboot,miniloader                                -  update uboot and miniloader if it is available in cnc83xxS.bin from USB drive (upgrade only)
+ * 4) update miniloader                                      -  update miniloader if it is available in cnc83xxS.bin from USB drive - (upgrade only)
+ * 5) update splash,kernel,jffs2                             -  update splash, kernel and jffs2 - if it is available in cnc83xxS.bin from USB drive - (upgrade only)
+ * 6) update force splash,kernel,jffs2 usb://cnc83xxS.bin    -  update splash, kernel and jffs2 - if it is available in MyCnc83xxS.bin from USB drive and ignore version checking
+
+ * 7) update tftp://192.168.1.2                              -  update all partion available in cnc83xxS.bin from tftp server (except miniloader and uboot) you can only upgrade, if newer version is not greater
+ *                                                              compare to current working one, it will be skipped. (upgrade only)
+ * 8) update force tftp://192.168.1.2                        -  update all partion available in cnc83xxS.bin from tftp server - ignore version checking so user can do downgrade, upgrade.
+ * 9) update uboot,miniloader tftp://192.168.1.2             -  update uboot and miniloader if it is available in cnc83xxS.bin from tftp server (upgrade only)
+ * 10) update miniloader tftp://192.168.1.2                  -  update miniloader if it is available in cnc83xxS.bin from tftp server - (upgrade only)
+ * 11) update splash,kernel,jffs2 tftp://192.168.1.2         -  update splash, kernel and jffs2 - if it is available in cnc83xxS.bin from tftp server - (upgrade only)
+ * 12) update force splash,kernel,jffs2 tftp://192.168.1.2/cnc83xxS.bin  -  update splash, kernel and jffs2 - if it is available in imaeg from tftp server - file name is MyCnc83xxS.bin and ignore version checking
+ * 
+ * 13) update help                                           -  help, usage, print valid aprtition name availale in bootargs.
+ */
+
+#if defined(CONFIG_AUTO_UPDATE) && defined(CONFIG_USB_STORAGE)
+
+int gpio_num_for_blink = -1;
+int rate_in_ms = -1;
+extern void disable_and_unregister_wd_timer_irq(void);
+extern void register_and_enable_wd_timer_irq(unsigned int rate_in_ms);
+
+//#define DEBUG_UPDATE
+#ifdef	DEBUG_UPDATE
+#define debug_update(fmt,args...)	printf (fmt ,##args)
+#else
+#define debug_update(fmt,args...)
+#endif	/* DEBUG_UPDATE */
+
+//---------------------------------------------------------------------------------------------------------------------------------------------------
+
+//#undef debug
+//#define debug printf
+
+#define member_size(type, member) sizeof(((type *)0)->member)
+
+#define FILE_VERSION        (0x00000100)
+#define SIGNATURE           (0x00001900)
+#define DEFAULT_CNC83XX_FILE_NAME ("cnc83xx.bin")
+#define DEFAULT_CNC83XXU_FILE_NAME ("cnc83xxU.bin")
+#define member_size(type, member) sizeof(((type *)0)->member)
+#define DEFAULT_VENDOR_ID   (0xCA000000)
+#define DEFAULT_PRODUCT_ID  (0x19000000)
+
+#define DDR_LOAD_ADDRESS    0x10000000
+
+
+#undef PAGE_SIZE
+#undef MTD_WRITEABLE
+
+
+#define PAGE_SIZE           (4*1024)
+#define MTD_WRITEABLE		(0x40)
+#define MTD_POWERUP_LOCK	(0x80)
+#define UINT_MAX            0xffffffff    /* maximum unsigned int value */
+
+#define VERSION_NO_LENGTH     256
+#define NVRAM_PARAM_TEXT_SIZE 4096 /* 4K */
+
+
+#define  UPDATE_MAX_PARTITION_SUPPORT   10 
+
+const char* ImageTypeByName[] = {
+	"KERNEL",
+	"RAMDISK",
+	"JFFS2",
+	"RAW"
+};
+
+const char* SkipParitionCheckingForUpgrade[]=
+{
+	"env",
+	"logo",
+	"update",
+	"user",
+	"free",
+
+	"miniloader",
+	"env_f",
+	"env1",
+	"rootfs_info_f",
+	"env2",
+	"rootfs_info",
+	"uboot1",
+	"uboot2",
+	"rootfs1",
+	"rootfs2",
+	"blob",
+	"kernel",
+	"logo",
+	"datafs",
+	"jffs2",
+	"conf",
+	NULL
+};
+
+typedef struct UpdateObject_t
+{
+	char   			mMtdId[16];
+	char   			mPartitionName[16];
+	UInt32 			mPartitionPositionInFlash;
+	UInt32          mImagePositionInFile;
+	UInt32 			mImageLength;
+	UInt32 			mPartitionSizeInFlash; 
+	UInt32       	mExtraInfo;
+}UpdateObject_t;
+
+typedef struct UpdateCommandObject_t
+{
+	int  mForce;
+	int  mUsb; //0-tftp, 1-usb, 2-mmc0, 3-mmc1
+	char mFileName[256];
+	char mIpAddress[15+1];
+	int  mNoOfValidParition;
+	UpdateObject_t mUpdateObjectList[MAXIUM_NO_OF_IMAGE];
+}UpdateCommandObject_t;
+
+typedef struct UpdateCommandParameterListObject_t
+{
+#define MAX_ARG_COUNT 5
+	int mNoOfParameter;
+	char mParameterList[MAX_ARG_COUNT][256];
+}UpdateCommandParameterListObject_t;
+
+typedef int (*Ptr2FuncParameter)(char* pBuf , UpdateCommandParameterListObject_t * apObject);
+typedef int (*Ptr2FuncPartition)(char* pBuf , UpdateCommandObject_t * apObject);
+
+//--------------------------------------------------------------------------------------------
+
+static int LookForUnsignedImage=0;
+
+//--------------------------------------------------------------------------------------------
+#pragma pack(1)
+typedef struct Header2_t
+{
+	UInt32 mValid;
+	char   mMtdId[16];
+	char   mPartitionName[64];
+	char   mVersionNo[256];
+	UInt32 mExtraInfo;					//d0 - 0 = encrypted (default)   , 1 = unencrypted
+	//d1 - 0 = nand (default)        , 1 = spi
+	//d2 - 0 = erase & write(default), 1 = preserved old content
+	UInt32 mImageLength;
+	UInt32 mImagePositionInFile;
+	UInt32 mPartitionSizeInFlash; 
+	UInt32 mPartitionPositionInFlash;
+}Header2_t;
+
+#pragma pack(1)
+typedef struct Header1_t
+{
+	int  mSignature;
+	int  mFileFormatVersionNo;
+	int  mVendorId;
+	int  mProductId;
+	char mCustomerName[32];
+	char mBootCmd[512];
+	char mBootArgs[512];
+	char mNvRamParamText[ NVRAM_PARAM_TEXT_SIZE];
+	int  mNoOfValidParition;
+	Header2_t mImageList[MAXIUM_NO_OF_IMAGE];		//images can be stored
+	UInt32 mHeaderCrc;
+	char mRsaSignature[256];
+}Header1_t;
+//--------------------------------------------------------------------------------------------
+extern int cnc_NorErase(UInt32 aFlashStartAddress, UInt32 aLength);
+extern int cnc_NorVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+extern int cnc_NorRead(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+extern int cnc_NorWrite(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+
+
+/* externals */
+extern int fat_register_device(block_dev_desc_t *, int);
+extern int file_fat_detectfs(void);
+extern long file_fat_read(const char *, void *, unsigned long);
+//extern int i2c_read (unsigned char, unsigned int, int , unsigned char* , int);
+extern int flash_sect_erase(ulong, ulong);
+extern int flash_sect_protect (int, ulong, ulong);
+extern int flash_write (char *, ulong, ulong);
+/* change char* to void* to shutup the compiler */
+extern block_dev_desc_t *get_dev (const char*, int);
+
+extern int GetSizeAndOffset(const char* pBuf, int* apSize, int *apOffset);
+extern int GenerateImagePartitionListFromBootArgs(const char* apBootArgs, ImagePartitionList_t *apImagePartitionList);
+
+
+/*
+ * The format for the command line is as follows:
+ *
+ * mtdparts=<mtddef>[;<mtddef]
+ * <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
+ *              where <mtd-id> is the name from the "cat /proc/mtd" command
+ * <partdef> := <size>[@offset][<name>][ro][lk]
+ * <mtd-id>  := unique name used in mapping driver/device (mtd->name)
+ * <size>    := standard linux memsize OR "-" to denote all remaining space
+ * <name>    := '(' NAME ')'
+ *
+ * Examples:
+ *
+ * 1 NOR Flash, with 1 single writable partition:
+ * edb7312-nor:-
+ *
+ * 1 NOR Flash with 2 partitions, 1 NAND with one
+ * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
+ */
+
+int SearchStringInAList(const char* pBuffer, const char* aList[])
+{
+	int i;
+	char* p1;
+	i=0;
+
+	while ( aList[i] != NULL)
+	{		
+		p1 = strstr(pBuffer, aList[i] );
+		if ( NULL !=  p1 )
+		{
+			return 0;
+		}		
+		i++;
+	}
+
+	return -1;
+}
+
+int VerifyAllPartitionPresentInImage(const Header1_t * apHeader1 , const ImagePartitionList_t *apImagePartitionList)
+{
+	int Status = 0;
+
+	int i=0;
+	int j=0;
+	char * p1;
+	int found=-1;
+
+	for(i=0; i < apImagePartitionList->mNoOfPartition ; i++)
+	{
+		p1 = (char*) (apImagePartitionList->mImagePartitionList[i].mPartionName );
+		found = -1;
+		printf("Searching for %s partition in supplied imaged...", p1);
+		if ( 0 == SearchStringInAList((const char*) p1, SkipParitionCheckingForUpgrade) )
+		{
+			printf("Skipping %s paritition\n", p1);
+			continue;
+		}
+
+		for ( j=0; j < apHeader1->mNoOfValidParition ; j++)
+		{
+			if ( 0 == strcmp ( apHeader1->mImageList[j].mPartitionName , p1 ) )
+			{
+				printf(" found it, %sPASS\n%s",  ColorGreen , ColorNormal );
+				found =1;
+				break;
+			}
+		}
+
+		if ( -1 == found)
+		{
+			printf(" not found, %sFAIL\n%s", ColorRed, ColorNormal );
+			return -1;
+		}
+	}
+	return Status;	
+}
+
+int isspace(int c) 
+{
+	/* first check gives quick exit in most cases */
+	return(c<=' ' && (c==' ' || (c<=13 && c>=9)));
+}
+
+static int CSV_Callback(char* pBuf, UpdateCommandObject_t * apObject)
+{
+	printf("Partition(%d) - %s\n", apObject->mNoOfValidParition , pBuf);
+	if (apObject->mNoOfValidParition < MAXIUM_NO_OF_IMAGE )
+	{
+		strncpy( apObject->mUpdateObjectList[apObject->mNoOfValidParition].mPartitionName, 
+				pBuf, 
+				sizeof (apObject->mUpdateObjectList[apObject->mNoOfValidParition].mPartitionName)
+			   );
+		apObject->mNoOfValidParition++;   
+	}
+	else
+	{
+		printf("ERROR: Parameter list overflow\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int SSV_Callback(char*pBuf , UpdateCommandParameterListObject_t * apObject)
+{
+	printf("Parameter(%d) - %s\n", apObject->mNoOfParameter, pBuf);
+	if (apObject->mNoOfParameter < MAX_ARG_COUNT )
+	{
+		strncpy ( apObject->mParameterList[apObject->mNoOfParameter] , pBuf , sizeof(apObject->mParameterList[0]) );
+		apObject->mNoOfParameter++;    
+	}
+	else
+	{
+		printf("ERROR: Parameter list overflow\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int trim(char** pStr)
+{
+	char *end;
+	char* str = *pStr;
+	while( isspace(*str)) 
+	{
+		(*pStr)++;
+		str++;
+	}
+
+	if(*str == 0) 
+	{
+		return 0;
+	}
+
+	end = str + strlen(str) - 1;
+	while(end > str && isspace(*end))
+	{
+		end--;
+	}
+	*(end+1) = 0;
+	return 0;
+}
+
+static void CSV(const char* str, UpdateCommandObject_t * apObject , Ptr2FuncPartition  pPtr2Func )
+{	
+	const char s[] = ",";
+	char *token;
+
+	token = strtok((char*) str, s);
+
+	while( token != NULL ) 
+	{
+		trim( & token);
+		if ( NULL != pPtr2Func  )
+		{
+			pPtr2Func(token , apObject);
+		}
+		token = strtok(NULL, s);
+	}   
+}
+
+static void SSV(const char* str, UpdateCommandParameterListObject_t * apObject , Ptr2FuncParameter  pPtr2Func )
+{	
+	const char s[] = " ";
+	char *token;
+
+	token = strtok((char*) str, s);
+
+	while( token != NULL ) 
+	{
+		trim( & token);   
+		if ( NULL != pPtr2Func  )
+		{
+			pPtr2Func(token , apObject);
+		}
+		token = strtok(NULL, s);
+	}   
+}
+
+static int ParseUpdateCommand(const char* apBuffer, UpdateCommandParameterListObject_t * apParameterObj,  UpdateCommandObject_t * apUpdateCommandObject )
+{
+	char* TempP2=NULL;
+	char* TempP3;
+	char* TempP4;
+	char* TempP5;
+	char* TempP6;
+	char TempBuf2[256]={0};
+
+	int i;
+	TempP2=TempP2;
+
+	if ( 0 == LookForUnsignedImage ){
+		strncpy(apUpdateCommandObject->mFileName, DEFAULT_CNC83XX_FILE_NAME , sizeof (apUpdateCommandObject->mFileName));
+	}
+	else{
+		strncpy(apUpdateCommandObject->mFileName, DEFAULT_CNC83XXU_FILE_NAME , sizeof (apUpdateCommandObject->mFileName));
+	}
+
+	strncpy(TempBuf2, apBuffer, sizeof(TempBuf2) );
+
+	//get all param first
+	SSV(TempBuf2, apParameterObj, SSV_Callback);
+	printf("%s\n", TempBuf2);
+	//get parition names.
+	for(i=0 ; i < MAX_ARG_COUNT ; i++){
+		TempP2 = strstr( apParameterObj->mParameterList[i] , ",");
+		TempP3 = strstr( apParameterObj->mParameterList[i] , "usb://");
+		TempP4 = strstr( apParameterObj->mParameterList[i] , "tftp://");
+		TempP5 = strstr( apParameterObj->mParameterList[i] , "mmc0://");
+		TempP6 = strstr( apParameterObj->mParameterList[i] , "mmc1://");
+
+
+		if ( 0 == strcmp(apParameterObj->mParameterList[i], "update" ) ){
+			continue;
+		}
+		if ( 0 == strcmp(apParameterObj->mParameterList[i], "force" ) ){
+			apUpdateCommandObject->mForce=1;
+			continue;
+		}
+		if ( 0 == strcmp(apParameterObj->mParameterList[i], "blink" ) ){
+			printf("blink case\n");
+			gpio_num_for_blink = simple_strtoul(apParameterObj->mParameterList[2], NULL, 0);
+			rate_in_ms = simple_strtoul(apParameterObj->mParameterList[3], NULL, 0);
+			printf("gpio_num_for_blink = %d, rate_in_ms = %d\n",gpio_num_for_blink,rate_in_ms);
+			continue;
+		}
+		if ( NULL != TempP3 ){
+			//mUsb - file name
+			apUpdateCommandObject->mUsb=1;
+			strncpy(apUpdateCommandObject->mFileName , TempP3 + strlen("usb://") , sizeof(apUpdateCommandObject->mFileName) );
+			continue;
+		}
+		if ( NULL != TempP5 ){
+			//mUsb - file name
+			apUpdateCommandObject->mUsb=2;
+			strncpy(apUpdateCommandObject->mFileName , TempP3 + strlen("mmc0://") , sizeof(apUpdateCommandObject->mFileName) );
+			continue;
+		}
+		if ( NULL != TempP6 ){
+			//mUsb - file name
+			apUpdateCommandObject->mUsb=3;
+			strncpy(apUpdateCommandObject->mFileName , TempP3 + strlen("mmc1://") , sizeof(apUpdateCommandObject->mFileName) );
+			continue;
+		}
+		if ( NULL != TempP4 ){
+			//tftp - file name
+			apUpdateCommandObject->mUsb=0;
+			TempP4 = TempP4 + strlen("tftp://");
+			TempP3 = strstr(TempP4, "/" );
+			if (TempP3 == NULL ){
+				strncpy(apUpdateCommandObject->mFileName , TempP4 , sizeof(apUpdateCommandObject->mFileName) );
+			}
+			else{
+				strncpy(apUpdateCommandObject->mFileName , TempP3+1 , sizeof(apUpdateCommandObject->mFileName) );
+				strncpy(apUpdateCommandObject->mIpAddress , TempP4 , TempP3-TempP4 );
+			}	
+			continue;
+		}
+		//else may be partition...
+		if((-1 == gpio_num_for_blink) && (-1 == rate_in_ms))
+			CSV(apParameterObj->mParameterList[i], apUpdateCommandObject , CSV_Callback);
+	}
+	return 0;
+}
+
+
+
+int UsbStart(void)
+{
+	block_dev_desc_t *stor_dev;
+	int au_usb_stor_curr_dev = -1;
+	/* start USB */
+	if (usb_stop() < 0)
+	{
+		printf ("usb_stop failed\n");
+		return -1;
+	}
+	if (usb_init() < 0)
+	{
+		printf ("usb_init failed\n");
+		return -1;
+	}
+
+	/*
+	 * check whether a storage device is attached (assume that it's
+	 * a USB memory stick, since nothing else should be attached).
+	 */
+	au_usb_stor_curr_dev = usb_stor_scan(1);
+	if (au_usb_stor_curr_dev == -1)
+	{
+		printf ("No device found. Not initialized?\n");
+		return -1;
+	}
+
+	/* check whether it has a partition table */
+	stor_dev = get_dev("usb", 0);
+	if (stor_dev == NULL)
+	{
+		printf ("uknown device type\n");
+		return -1;
+	}
+
+	int partition_index = 1 ;
+	int partition_available = 0 ;
+	for(;partition_index <= UPDATE_MAX_PARTITION_SUPPORT ; partition_index++  )
+	{	
+		if (fat_register_device(stor_dev, partition_index) == 0)
+		{
+			partition_available = 1 ;	
+			//		stor_dev->dev = partition_index ;
+			printf ("USB %d:%d is availble for fatls\n", au_usb_stor_curr_dev, partition_index);
+			break;
+		}
+		else
+		{	
+			printf ("Unable to use USB %d:%d for fatls\n", au_usb_stor_curr_dev, partition_index);
+		}	
+	}
+
+	if(partition_available == 0)
+		return -1 ;
+
+	if (file_fat_detectfs() != 0)
+	{
+		printf ("file_fat_detectfs failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int MMCStart(int index)
+{
+	block_dev_desc_t *stor_dev;
+
+	/* check whether it has a partition table */
+	stor_dev = get_dev("mmc", index);
+	if (stor_dev == NULL)
+	{
+		printf ("uknown device type\n");
+		return -1;
+	}
+
+	int partition_index = 1 ;
+	int partition_available = 0 ;
+	for(;partition_index <= UPDATE_MAX_PARTITION_SUPPORT ; partition_index++  )
+	{	
+		if (fat_register_device(stor_dev, partition_index) == 0)
+		{
+			partition_available = 1 ;	
+			//		stor_dev->dev = partition_index ;
+			printf ("MMC %d:%d is availble for fatls\n", index, partition_index);
+			break;
+		}
+		else
+		{	
+			printf ("Unable to use MMC %d:%d for fatls\n", index, partition_index);
+		}	
+	}
+
+	if(partition_available == 0)
+		return -1 ;
+
+	if (file_fat_detectfs() != 0)
+	{
+		printf ("file_fat_detectfs failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int FatLoadUsb(const char* apFileName, unsigned char* aDestinationAddress, unsigned int aSize, unsigned int * apDataRead)
+{
+	unsigned int sz = file_fat_read(apFileName, (void*) aDestinationAddress, aSize);
+	if (sz == 0xFFFFFFFF) 
+	{
+		debug ("file %s not found\n", apFileName);
+		return -1;
+	}
+	debug_update("Image Size is %d\n", sz);
+	* apDataRead = sz ;
+	return 0;
+}
+
+UInt32 GetUInt32(UInt8* pBuffer)
+{
+	return (UInt32) ( ( * (pBuffer+0) << 0 ) | ( * (pBuffer+1) << 8 ) | ( * (pBuffer+2) << 16 ) | ( * (pBuffer+3) << 24 )  ); 
+}
+
+int ProgramFlash( 	const char* apMtdId, const char* apPartitionName ,
+		UInt32 aOffset,	UInt8* apBuffer, 
+		UInt32 aLength , cnc_ImageType aImageType,
+		UInt32 aPartitionSize )
+{
+	int Status=-1;	
+	image_header_t* hdr = (image_header_t *)apBuffer;
+	//UInt32 addr,off,nbytes;
+	if ( 0 == strcmp ( apMtdId , "cnc-nand" ) )
+	{	
+		printf( "Programming NAND flash MTD_ID=%s PartitionName=%s FlashStartAddress=%08x Length=%d (0x%08x) ImageType=%s\n",
+				apMtdId,
+				apPartitionName , 
+				aOffset ,
+				aLength ,
+				aLength ,ImageTypeByName [aImageType] );
+
+		//Irrespective of type of partition always perform nand erase (don't use erase.spread)				
+		Status = cnc_NandErase( aOffset, aPartitionSize, 0);
+		if (0 != Status ) return Status;				
+
+		if ( aImageType == JFFS2)
+		{
+			printf("Removing Header\n");
+			apBuffer = (UInt8 *)((UInt8 *)hdr + sizeof(*hdr));
+			aLength = aLength - sizeof(*hdr) ;
+			printf("After removing header - %08x %08x\n", (UInt32) apBuffer , aLength);
+			//printf("For JFFS2 erasing complete MTD region, changeing size for erase from %x to %x, (erasing without spread)", aLength, aPartitionSize);
+			//Status = cnc_NandErase( aOffset, aPartitionSize, 0);
+		}
+		else
+		{
+			//Status = cnc_NandErase( aOffset, aLength, 1);
+		}
+		Status = cnc_NandWrite( (UInt32) apBuffer , aOffset, aLength, aImageType );
+		if ( 0 != Status ) return Status;	
+	}
+	else if ( 0 == strcmp ( apMtdId , "emmc" ) )
+	{	
+		printf( "Programming eMMC flash MTD_ID=%s PartitionName=%s FlashStartAddress=%08x Length=%d (0x%08x) ImageType=%s\n",
+				apMtdId,
+				apPartitionName , 
+				aOffset ,
+				aLength ,
+				aLength ,ImageTypeByName [aImageType] );
+#if 0
+		Status = cnc_EMMCErase( aOffset, aPartitionSize);
+		if (0 != Status ) return Status;				
+#endif
+		if ( aImageType == JFFS2)
+		{
+			printf("Removing Header\n");
+			apBuffer = (UInt8 *)((UInt8 *)hdr + sizeof(*hdr));
+			aLength = aLength - sizeof(*hdr) ;
+			printf("After removing header - %08x %08x\n", (UInt32) apBuffer , aLength);
+			//printf("For JFFS2 erasing complete MTD region, changeing size for erase from %x to %x, (erasing without spread)", aLength, aPartitionSize);
+			//Status = cnc_NandErase( aOffset, aPartitionSize, 0);
+		}
+		else
+		{
+			//Status = cnc_NandErase( aOffset, aLength, 1);
+		}
+#ifndef MMC_WRITE_VERIFY
+		Status = cnc_EMMCWrite( (UInt32) apBuffer , aOffset, aLength, aImageType );
+		if ( 0 != Status ) {
+			printf("ERROR: cnc_EMMCWrite\n");
+			return Status;
+		}
+#else
+		while(Status == -1){
+			Status = cnc_EMMCWrite( (UInt32) apBuffer , aOffset, aLength, aImageType );
+			if ( 0 != Status ) {
+				printf("ERROR: cnc_EMMCWrite\n");
+				return Status;
+			}
+			Status = cnc_EMMCVerify2((UInt32) apBuffer, aOffset, aLength);
+			if ( 0 == Status)
+			{
+				printf("%seMMC is verified successfully\n%s", ColorGreen, ColorNormal);
+			}
+			else
+			{
+				printf("%sERROR:Fail to verify eMMC, please check your hardware\n%s", ColorRed, ColorNormal);
+			}
+		}
+#endif
+	}	
+	else if ( 0 == strcmp ( apMtdId , SPI_TOKEN ) )
+	{
+		//SPI flash write
+		printf( "Programming SPI flash MTD_ID=%s PartitionName=%s FlashStartAddress=%08x Length=%d (0x%08x)\n",
+				apMtdId,
+				apPartitionName , 
+				aOffset ,
+				aLength ,
+				aLength);
+		Status = cnc_SpiErase( aOffset, aLength);
+		Status = cnc_SpiWrite( (UInt32) apBuffer , aOffset, aLength);
+	}
+	else if ( 0 == strcmp ( apMtdId , "cnc-nor" ) )
+	{
+		//SPI flash write
+		printf( "Programming SPI flash MTD_ID=%s PartitionName=%s FlashStartAddress=%08x Length=%d (0x%08x)\n",
+				apMtdId,
+				apPartitionName , 
+				aOffset ,
+				aLength ,
+				aLength);
+		Status = cnc_NorErase( aOffset, aLength);
+		Status = cnc_NorWrite( (UInt32) apBuffer , aOffset, aLength);
+	}
+	else
+	{
+		printf("ERROR: Unsupported MTD_ID %s\n, Aborting...\n" , apMtdId );
+	}
+
+	return Status;
+}
+void PrintLongAsciiString(const char* apBuf)
+{
+	while ( *(apBuf) != '\0')
+	{
+		printf("%c", *(apBuf));
+		apBuf++;
+	}
+	printf("\n");
+}
+
+int CompareCurrentBootArgsMtdPartsWithNewOne(const char* apCurrentBootArgs, const char* apNewBootArgs)
+{
+	int Status=0;
+	const char* p1 ;
+	const char* p2 ;
+	int i,j;
+	//printf("Comparing bootargs...\n");
+	p1 = strstr(apCurrentBootArgs, "mtdparts=");
+	if (NULL != p1 )
+	{
+		p1 = p1 + strlen("mtdparts=");
+		p2 = strstr(apNewBootArgs, "mtdparts=");
+		if (NULL != p2 )
+		{
+			p2 = p2 + strlen("mtdparts=");
+			i=0;j=0;
+
+			while(
+					(*(p1+i) != '\0') && (*(p1+i) != ' ') &&
+					(*(p2+j) != '\0') && (*(p2+j) != ' ') 
+				 )
+			{		
+				if ( *(p1+i) == *(p2+j) )
+				{
+					i++;
+					j++;
+				}
+				else
+				{
+					Status = -1;
+					break;
+				}
+				//printf("%d %d %c %c\n", i,j, *(p1+i) , *(p2+j) );
+			}
+		}
+	}
+
+	if ( Status != 0 )
+	{
+		printf("%s\n", ColorYellow);
+		printf("WARNING: bootargs differ...\nrunning system has bootargs=" );
+		PrintLongAsciiString (apCurrentBootArgs);
+		printf("while supplied in image, bootargs=");
+		PrintLongAsciiString(apNewBootArgs);
+		printf("%s\n", ColorNormal);
+	}
+	else
+	{
+		printf(" %sPASS\n%s",  ColorGreen , ColorNormal);
+	}
+
+	Status = 0; // force Status = 0. We don't care if bootargs changes or not durning update image.
+	return Status;
+}
+
+int VerifyImageCrc32(Header1_t * apHeader1, UInt8* pBuffer, UInt32 aLength, int aVerifyImageCrcAlso)
+{
+	int Status = -1;	
+	int i;	
+	int j;
+	char* p1 ;
+	int pos;
+	int cnt;
+	char TempBuf[512];        
+
+	UInt32 ComputedCrc32;
+	UInt32 Crc32InImage;
+
+	debug_update("Signature            = %08X\n", apHeader1->mSignature);
+	debug_update("File format version  = %08X\n", apHeader1->mFileFormatVersionNo);
+	debug_update("Vendor ID            = %08X\n", apHeader1->mVendorId);
+	debug_update("Product ID           = %08X\n", apHeader1->mProductId);
+	debug_update("BootCmd              = %s\n",   apHeader1->mBootCmd  );
+	debug_update("BootArgs             = " );  PrintLongAsciiString(apHeader1->mBootArgs );
+	debug_update("NVRAM\n");
+
+	p1 = apHeader1->mNvRamParamText;
+	pos=0;
+	cnt=0;
+	while (1){
+		cnt =  *( (int*)(p1 + pos) );
+		if (cnt == 0 ){
+			break;
+		}
+		pos=pos+sizeof(int);           
+		memcpy(TempBuf,  p1+pos, cnt);
+		TempBuf[cnt]='\0';
+		pos = pos + cnt;
+		debug_update("%s\n", TempBuf);            
+	}
+
+	debug_update("No.of Image Packaged = %d\n",   apHeader1->mNoOfValidParition);
+	debug_update("CRC                  = %08X\n", apHeader1->mHeaderCrc);    
+	ComputedCrc32 = crc32(0, (void*) apHeader1 , (UInt32) ( (UInt32) & apHeader1->mHeaderCrc - (UInt32) apHeader1 ) ) ;
+	if ( ComputedCrc32 != apHeader1->mHeaderCrc ){
+		debug_update("ERROR: CRC error1\n");
+		return Status;
+	}
+
+	debug_update("RSA Header Signature\n");
+	for(i=0;i<16;i++){
+		for(j=0;j<16;j++){
+			debug_update("%02x ", (UInt8) apHeader1->mRsaSignature[ (i*16) + j ] );
+		}
+		debug_update("\n");
+	}
+
+	for(i=0;i< apHeader1->mNoOfValidParition;i++){
+		debug_update("Valid                    = %d\n", apHeader1->mImageList[i].mValid );
+		debug_update("MtdId                    = %s\n", apHeader1->mImageList[i].mMtdId );
+		debug_update("PartitionName            = %s \n", apHeader1->mImageList[i].mPartitionName );
+		debug_update("VersionNo                = %s\n", apHeader1->mImageList[i].mVersionNo);
+		debug_update("ExtraInfo                = %08X\n", apHeader1->mImageList[i].mExtraInfo);	
+		debug_update("  Image is               = %s\n", (0 == (apHeader1->mImageList[i].mExtraInfo & (1<<0)) ) ? "encrypted" : "unencrypted" );				//d0 - 0 = encrypted (default)   , 1 = unencrypted
+		debug_update("  Image goes to          = %s\n", (0 == (apHeader1->mImageList[i].mExtraInfo & (1<<1)) ) ? "NAND" : "SPI" );								//d1 - 0 = nand (default)        , 1 = spi
+		debug_update("  Image wiriting mode    = %s\n", (0 == (apHeader1->mImageList[i].mExtraInfo & (1<<2)) ) ? "Erase & Write" : "Preserved Old Content" );	//d2 - 0 = erase & write(default), 1 = preserved old content
+		debug_update("  Image Type             = %s\n", ImageTypeByName[ (apHeader1->mImageList[i].mExtraInfo >> 3) & 3 ] );			
+		debug_update("ImageLength              = %d\n" ,apHeader1->mImageList[i].mImageLength );
+		debug_update("ImagePositionInFile      = %08X\n" , apHeader1->mImageList[i].mImagePositionInFile );
+		debug_update("PartitionSizeInFlash     = %08X\n", apHeader1->mImageList[i].mPartitionSizeInFlash ); 
+		debug_update("PartitionPositionInFlash = %08X\n", apHeader1->mImageList[i].mPartitionPositionInFlash);
+		debug_update("CRC32 %08x %08x\n", (UInt32)( pBuffer + apHeader1->mImageList[i].mImagePositionInFile) , apHeader1->mImageList[i].mImageLength );
+
+		if ( 1 == aVerifyImageCrcAlso){
+			if(!dcache_status()){
+				dcache_enable();
+			}
+			ComputedCrc32 = crc32(0, pBuffer + apHeader1->mImageList[i].mImagePositionInFile, apHeader1->mImageList[i].mImageLength );
+			dcache_disable();
+			Crc32InImage = * ( (UInt32*)( pBuffer + apHeader1->mImageList[i].mImagePositionInFile + apHeader1->mImageList[i].mImageLength) );
+			if ( ComputedCrc32 != Crc32InImage ){
+				printf("ERROR: CRC error3\n");
+				return Status;
+			}
+		}
+	}
+	Status=0;
+	return Status;	
+}
+
+int ProgramNvRamParameter(Header1_t* apHeader1)
+{
+	char TempBuf[512]={0};
+	int Status;
+	//First unset 
+	setenv("kernel_load_addr", ""); 
+	setenv("rootfs_load_addr", "");
+	setenv("blob_load_addr", "");	
+	//SetCustomerName
+	memset(TempBuf, 0, sizeof(TempBuf) );
+	strncpy(TempBuf, apHeader1->mCustomerName, strlen(apHeader1->mCustomerName) );
+	Status = setenv( "CUSTOMER_NAME" , TempBuf);
+	if (Status != 0 )
+	{
+		return -1;
+	}
+	//Now program new bootargs and bootcmd
+	memset(TempBuf, 0, sizeof(TempBuf) );
+	strncpy(TempBuf, apHeader1->mBootCmd, strlen(apHeader1->mBootCmd)  ); //skip ""
+	Status = setenv( "bootcmd" , TempBuf);
+	if (Status != 0 )
+	{
+		return -1;
+	}
+	memset(TempBuf, 0, sizeof(TempBuf));
+	strncpy(TempBuf, apHeader1->mBootArgs, strlen(apHeader1->mBootArgs) ); //skip ""
+	Status = setenv( "bootargs" , TempBuf);
+	if (Status != 0 )
+	{
+		return -1;
+	}
+	Status = saveenv();
+	if (Status != 0 )
+	{
+		return -1;
+	}
+	return 0;
+}
+
+int Update_UpdateObjectFromHeader1(UpdateCommandObject_t  * apUpdateObject, Header1_t * apHeader1)
+{
+	int i = 0;
+	int j = 0;
+
+	int found = -1;
+	for (i = 0; i < apUpdateObject->mNoOfValidParition; i++)
+	{
+		found = -1;
+		for (j = 0; j < apHeader1->mNoOfValidParition; j++)
+		{
+			if (0 == strcmp(apUpdateObject->mUpdateObjectList[i].mPartitionName, apHeader1->mImageList[j].mPartitionName))
+			{
+				strncpy(apUpdateObject->mUpdateObjectList[i].mMtdId, apHeader1->mImageList[j].mMtdId, sizeof(apUpdateObject->mUpdateObjectList[i].mMtdId));
+				strncpy(apUpdateObject->mUpdateObjectList[i].mPartitionName, apHeader1->mImageList[j].mPartitionName, sizeof(apUpdateObject->mUpdateObjectList[i].mPartitionName));
+				apUpdateObject->mUpdateObjectList[i].mPartitionPositionInFlash = apHeader1->mImageList[j].mPartitionPositionInFlash;
+				apUpdateObject->mUpdateObjectList[i].mImagePositionInFile = apHeader1->mImageList[j].mImagePositionInFile;
+				apUpdateObject->mUpdateObjectList[i].mImageLength = apHeader1->mImageList[j].mImageLength;
+				apUpdateObject->mUpdateObjectList[i].mExtraInfo = apHeader1->mImageList[j].mExtraInfo;
+				apUpdateObject->mUpdateObjectList[i].mPartitionSizeInFlash = apHeader1->mImageList[j].mPartitionSizeInFlash;
+				found = 0;
+				break;
+			}
+		}
+
+		if (-1 == found)
+		{
+			printf("%sERROR: Invalid patition name \"%s\"specfied to upgrade%s\n", ColorRed, apUpdateObject->mUpdateObjectList[i].mPartitionName, ColorNormal);
+			return -1;
+		}
+	}	
+	return 0;
+}
+
+extern int do_csupgrade_logo(void);
+int do_updatex (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char CmdBuf[512]={0};
+	char TempBuf[512]={0};
+	Header1_t mHeader1;
+	UpdateCommandObject_t  UpdateObject;
+	UpdateCommandParameterListObject_t  ParameterObject;
+	ImagePartitionList_t ImagePartitionList;
+	char* event_ptr, *bootsrc;    
+
+	int i;
+	int Status=-1;
+	char* p1;
+	int MtdPartsAreMatchingOktoProgram=0;
+	unsigned char *pStorageBuffer = (unsigned char *)DDR_LOAD_ADDRESS;
+	UInt32 mDataRead=0;	
+	char* xp1;    
+	int usb_read_try_time = 5;
+
+	for(i=0;i<argc;i++){
+		strncat(CmdBuf, argv[i], sizeof(CmdBuf)-strlen(CmdBuf) );
+		strncat(CmdBuf, " ", sizeof(CmdBuf)-strlen(CmdBuf) );
+	}
+	p1 = CmdBuf;
+
+	memset(&UpdateObject , 0, sizeof(UpdateObject) );
+	memset(&ParameterObject , 0, sizeof(ParameterObject) );
+
+	bootsrc = getenv("updatesrc");
+	if(bootsrc != NULL){
+		UpdateObject.mUsb = simple_strtoul(bootsrc, NULL, 10);
+	}else{
+		UpdateObject.mUsb = CONFIG_CMD_UPDATE_SOURCE;
+	}
+
+	Status = ParseUpdateCommand(p1, & ParameterObject,  & UpdateObject);
+	if ( 0 != Status  ){
+		printf("%sERROR: while parsing update command error occured%s\n", ColorRed, ColorNormal);
+	}
+	if(-1 != gpio_num_for_blink)
+		register_and_enable_wd_timer_irq(usec_to_tick(rate_in_ms*1000));
+
+	event_ptr = getenv("pre_update_event");
+	if (NULL != event_ptr ){
+		run_command(event_ptr,0);
+	}
+
+#if 0	
+	printf("Usb=%d\n",UpdateObject.mUsb); 
+	printf("Force=%d\n",UpdateObject.mForce); 
+	if ( UpdateObject.mUsb == 0 )
+	{
+		printf("IpAddress=%s\n", UpdateObject.mIpAddress);
+	}    
+	printf("FileName=%s\n",UpdateObject.mFileName);
+	for (i=0;i<UpdateObject.mNoOfValidParition;i++)
+	{
+		printf("%s\n", UpdateObject.mPartitionNameList[i]);
+	}
+#endif
+
+	if (1 == UpdateObject.mUsb )
+	{
+		printf("Starting USB...\n");
+		Status = UsbStart();
+		if (-1 == Status)
+		{			
+			goto boot_cmd_error_file_usb;
+		}
+	}
+	if (2 == UpdateObject.mUsb || 3 == UpdateObject.mUsb)
+	{
+		printf("Scanning MMC...\n");
+		Status = MMCStart(UpdateObject.mUsb - 2);
+		if (-1 == Status)
+		{			
+			goto boot_cmd_error_file_usb;
+		}
+	}
+
+	if (UpdateObject.mUsb == 1 || UpdateObject.mUsb == 2 || UpdateObject.mUsb == 3)
+	{
+		Status = FatLoadUsb(UpdateObject.mFileName, pStorageBuffer, sizeof(mHeader1) , &mDataRead ); //First load header only
+		if( (-1 == Status) || ( sizeof(mHeader1) != mDataRead ) )
+		{
+			printf("%sCould not found %s file\n%s" ,ColorYellow, UpdateObject.mFileName, ColorNormal);
+			//May be cnc83xxU.bin might be present - try that one.
+			strncpy(UpdateObject.mFileName, DEFAULT_CNC83XXU_FILE_NAME , sizeof (UpdateObject.mFileName));
+			printf("%strying to load %s file\n%s" ,ColorYellow, UpdateObject.mFileName, ColorNormal);
+			Status = FatLoadUsb(UpdateObject.mFileName, pStorageBuffer, sizeof(mHeader1) , &mDataRead ); //First load header only
+			if( (-1 == Status) || ( sizeof(mHeader1) != mDataRead ) )
+			{
+				//both image are failed.
+				goto boot_cmd_error_file_usb;
+			}
+		}
+
+		do_csupgrade_logo();
+#if 1		
+		//Validate header
+		memcpy( & mHeader1 , pStorageBuffer , sizeof(mHeader1) );	
+		printf("Verifying image header...");	
+		Status = VerifyImageCrc32( & mHeader1 , pStorageBuffer, mDataRead,0);//verify header only(do not verify image crc)
+		if (-1 == Status)
+		{
+			printf(" FAIL\n");
+			goto  boot_cmd_error_crc;
+		}
+		printf(" %sPASS\n%s",  ColorGreen , ColorNormal);
+#endif		
+boot_cmd_read_usb_image:
+		//Now load complete image
+		printf("Loading complete image\n");
+		Status = FatLoadUsb(UpdateObject.mFileName, pStorageBuffer, 0, &mDataRead ); 
+		if (-1 == Status)
+		{
+			goto boot_cmd_error_file_usb;
+		}
+		printf("\nChecking image integrity ...");
+		Status = VerifyImageCrc32( & mHeader1 , pStorageBuffer, mDataRead,1);//now verify image crc also.
+		if (-1 == Status)
+		{
+			printf(" %sFAIL%s\n", ColorRed, ColorNormal);
+			if(usb_read_try_time){
+				usb_read_try_time --;
+				printf("try to ");
+				goto boot_cmd_read_usb_image;
+			}
+			else{
+				printf("Already try 5 times, still got error, exit!\n");
+				goto  boot_cmd_error_crc;
+			}
+		}
+		printf(" %sPASS%s\n", ColorGreen, ColorNormal);
+
+	}
+	else
+	{
+		printf("updating from tftp\n");
+		int size= 0 ;
+		load_addr = DDR_LOAD_ADDRESS;
+		copy_filename (BootFile,  UpdateObject.mFileName , sizeof(BootFile));
+		if ((size = NetLoop(TFTP)) < 0) {
+			show_boot_progress (-81);
+			return 1;
+		}
+
+		memcpy( & mHeader1 , pStorageBuffer , sizeof(mHeader1) );
+		//verify header only.
+		Status = VerifyImageCrc32( & mHeader1 , pStorageBuffer, mDataRead,0);
+		if (-1 == Status)
+		{
+			goto  boot_cmd_error_crc;
+		}
+
+		printf("\nChecking image integrity ...");
+		Status = VerifyImageCrc32( & mHeader1 , pStorageBuffer, mDataRead,1);//now verify image crc also.
+		if (-1 == Status)
+		{
+			printf(" FAIL\n");
+			goto  boot_cmd_error_crc;
+		}
+		printf(" OK\n");	
+	}
+
+
+	memcpy( & mHeader1 , pStorageBuffer , sizeof(mHeader1) );
+
+	Status = -1;
+	xp1 = getenv("bootargs");
+	if (xp1 != NULL )
+	{
+		Status = CompareCurrentBootArgsMtdPartsWithNewOne(xp1 ,  mHeader1.mBootArgs );
+	}	
+
+	if (Status == 0)
+	{
+		//mtdparts are matching
+		MtdPartsAreMatchingOktoProgram=1;				
+	}
+	else
+	{
+		if( 1 == UpdateObject.mForce) // "force"
+		{
+			if ( 0 == ProgramNvRamParameter( & mHeader1 ) )
+			{
+				MtdPartsAreMatchingOktoProgram=1;
+			}
+		}
+		else
+		{
+			MtdPartsAreMatchingOktoProgram = 0;
+		}
+	}
+
+	//---------------------------------------
+	Status = GenerateImagePartitionListFromBootArgs(mHeader1.mBootArgs, & ImagePartitionList);
+	if (Status == -1)
+	{
+		puts(ColorRed);printf("ERROR: error occured while parsing bootargs, please contact vendor\n");puts(ColorNormal);
+		return -1;
+	}
+	//---------------------------------------
+	if (0 == MtdPartsAreMatchingOktoProgram )
+	{
+		puts(ColorYellow);
+		printf("MTD parition information was not matching with existing image\n");
+		printf("Before porgramming image, we want to make sure, in supplied image file %s all parition are defined\n" , UpdateObject.mFileName);
+		printf("In such cases, partial upgrade is not allowed. \n");
+		printf("OR\nYou can try \nupdate force usb://cnc83xx.bin\n");
+
+		puts(ColorNormal);
+		Status = VerifyAllPartitionPresentInImage( & mHeader1 , & ImagePartitionList);
+		if ( UpdateObject.mForce ==1 )
+		{
+			//goto force_continue;
+		}
+		else if (-1 == Status)
+		{
+			puts(ColorRed);
+			printf("ERROR: please contact vendor and try to get image which has all paritions defined\n");
+			printf("       aborting firmware upgrade\n");
+			puts(ColorNormal);
+			return -1;
+		}
+	}
+	//--------------------------------------------------------------------------------
+	Status = Update_UpdateObjectFromHeader1(& UpdateObject, & mHeader1);
+	if (-1 == Status)
+	{
+		return Status;
+	}
+	//--------------------------------------------------------------------------------
+	if ( 0 != UpdateObject.mNoOfValidParition )
+	{
+		i=0;
+		for( i = 0 ; i < UpdateObject.mNoOfValidParition ; i++ )
+		{
+			Status = ProgramFlash(  UpdateObject.mUpdateObjectList[i].mMtdId,
+					UpdateObject.mUpdateObjectList[i].mPartitionName,
+					UpdateObject.mUpdateObjectList[i].mPartitionPositionInFlash,
+					pStorageBuffer + UpdateObject.mUpdateObjectList[i].mImagePositionInFile,
+					UpdateObject.mUpdateObjectList[i].mImageLength,
+					(cnc_ImageType)( (UpdateObject.mUpdateObjectList[i].mExtraInfo >> 3) & 3) ,
+					UpdateObject.mUpdateObjectList[i].mPartitionSizeInFlash
+					);
+		}
+	}
+	else
+	{
+		i=0;
+		for(i=0;i< mHeader1.mNoOfValidParition;i++)
+		{
+			Status = ProgramFlash( 	mHeader1.mImageList[i].mMtdId, 
+					mHeader1.mImageList[i].mPartitionName,
+					mHeader1.mImageList[i].mPartitionPositionInFlash,
+					pStorageBuffer + mHeader1.mImageList[i].mImagePositionInFile ,
+					mHeader1.mImageList[i].mImageLength ,
+					(cnc_ImageType)( (mHeader1.mImageList[i].mExtraInfo >> 3) & 3),
+					mHeader1.mImageList[i].mPartitionSizeInFlash
+					);
+			if (-1 == Status )
+			{
+				goto boot_cmd_error_nand_programming;
+			}		
+		}
+	}
+
+	//First unset 
+	setenv("kernel_load_addr", ""); 
+	setenv("rootfs_load_addr", "");
+	setenv("blob_load_addr", "");	
+	//SetCustomerName
+	memset(TempBuf, 0, sizeof(TempBuf) );
+	strncpy(TempBuf, mHeader1.mCustomerName, strlen(mHeader1.mCustomerName) );
+	Status = setenv( "CUSTOMER_NAME" , TempBuf);
+	if (Status != 0 )
+	{
+		goto boot_cmd_error_write2nvram_fail;
+	}
+	//Now program new bootargs and bootcmd
+	memset(TempBuf, 0, sizeof(TempBuf) );
+	strncpy(TempBuf, mHeader1.mBootCmd, strlen(mHeader1.mBootCmd) ); //skip ""
+	Status = setenv( "bootcmd" , TempBuf);
+	if (Status != 0 )
+	{
+		goto boot_cmd_error_write2nvram_fail;
+	}
+	memset(TempBuf, 0, sizeof(TempBuf));
+	strncpy(TempBuf, mHeader1.mBootArgs, strlen(mHeader1.mBootArgs) ); //skip ""
+	Status = setenv( "bootargs" , TempBuf);
+	if (Status != 0 )
+	{
+		goto boot_cmd_error_write2nvram_fail;
+	}
+	Status = saveenv();
+	if (Status != 0 )
+	{
+		goto boot_cmd_error_write2nvram_fail;
+	}
+#if (CONFIG_TARGET_NAME == CNW83XX_OTT_EMMC) || (CONFIG_TARGET_NAME == CNW83XX_SONY_VEDETT)
+	{
+		cnc_EMMCRescan();
+		cnc_CreatGPTPartitionTable(&ImagePartitionList);
+	}
+#endif
+	goto boot_cmd_ok;   	
+
+
+boot_cmd_error_nand_programming:
+	Status = -1;
+	printf("%sERROR: Nand programming failed for partition %s %s\n%s", 
+			ColorRed, mHeader1.mImageList[i].mMtdId, mHeader1.mImageList[i].mPartitionName, ColorNormal );
+	goto boot_cmd_exit;
+
+boot_cmd_error_crc:
+	Status = -1;
+	printf("%sERROR: Image file %s is corrupted\n%s" ,ColorRed, UpdateObject.mFileName, ColorNormal);
+	goto boot_cmd_exit;
+
+boot_cmd_error_file_usb:
+	Status = -1;
+	printf("%sERROR: Unable to open file %s\n%s" ,ColorRed, UpdateObject.mFileName, ColorNormal);
+	goto boot_cmd_exit;
+
+
+boot_cmd_error_write2nvram_fail:
+	Status = -1;
+	printf("%sERROR: Unable to update nvram bootargs / bootcmd parameters%s" , ColorRed , ColorNormal );
+	goto boot_cmd_exit;
+
+boot_cmd_ok:
+	Status = 0;
+	printf("%s%s is updated successfully\n%s", ColorGreen, UpdateObject.mFileName , ColorNormal);
+	printf("%sPlease reset your sytem\n%s" , ColorGreen, ColorNormal);
+
+	event_ptr = getenv("post_update_event");
+	if (NULL != event_ptr )
+	{
+		run_command(event_ptr,0);
+	}
+
+boot_cmd_exit:
+	if(-1 != gpio_num_for_blink)
+		disable_and_unregister_wd_timer_irq();
+
+	return Status;
+}
+
+int test_emmc1 (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	//	char mBootArgs[512];
+	ImagePartitionList_t ImagePartitionList;
+	int Status = 1;
+
+	cnc_EMMCRescan();
+	Status = GenerateImagePartitionListFromBootArgs(getenv("bootargs"), & ImagePartitionList);
+	if (Status == -1)
+	{
+		puts(ColorRed);printf("ERROR: error occured while parsing bootargs, please contact vendor\n");puts(ColorNormal);
+		return -1;
+	}
+	cnc_CreatGPTPartitionTable(&ImagePartitionList);
+	return 0;
+}
+//-----------------------------------------------------------------------------------------------------------------------------------------------------
+
+U_BOOT_CMD(
+		update, 10, 0, do_updatex,
+		"update various partitions in flash from a file\n",
+		"[CSV_LIST_OF_MTD_PARTITION_NAMES] [force] [filename-url]\n"
+		"  [CSV_LIST_OF_MTD_PARTITION_NAMES] - from mtd-parts in bootargs (splash,uboot,kernel,jffs2,...)\n"
+		"  [force] - ignore mtd partition information and version checks\n"
+		"  [filename-url] - usb://filename, tftp://filename. If not included, use USB cnc83xx.bin, then cnc83xxU.bin.\n"
+		"  [blink] <gpio_num> <rate_in_ms>\n"
+		);
+U_BOOT_CMD(
+		test_emmc, 10, 0, test_emmc1,
+		"update various partitions in flash from a file\n",
+		"[CSV_LIST_OF_MTD_PARTITION_NAMES] [force] [filename-url]\n"
+		"  [CSV_LIST_OF_MTD_PARTITION_NAMES] - from mtd-parts in bootargs (splash,uboot,kernel,jffs2,...)\n"
+		"  [force] - ignore mtd partition information and version checks\n"
+		"  [filename-url] - usb://filename, tftp://filename. If not included, use USB cnc83xx.bin, then cnc83xxU.bin.\n"
+		"  [blink] <gpio_num> <rate_in_ms>\n"
+		);
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_update_misc.c u-boot-2011.06/common/cmd_update_misc.c
--- u-boot-2011.06_original/common/cmd_update_misc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_update_misc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,69 @@
+#include "cnc_util.h"
+
+#if defined(CONFIG_AUTO_UPDATE) && defined(CONFIG_USB_STORAGE)
+
+int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_auto_update(unsigned int size);
+//---------------------------------------------------------------------------------------------------------------------------------------------------
+int do_update (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char *pCmd[5] = { "nand", "read", NULL, NULL, NULL};
+	char TempCmd1[16], TempCmd2[16], TempCmd3[16];
+
+	pCmd[2] = TempCmd1;
+	pCmd[3] = TempCmd2;
+	pCmd[4] = TempCmd3;
+
+	unsigned int *ptr, size;
+	int i;
+
+	if(argc == 1)
+	{
+		do_auto_update(0);
+	}
+	else if(argc == 2)
+	{
+		if(*argv[1] == '*')
+		{
+			ptr = (unsigned int*) simple_strtoul(argv[1] + 1, NULL, 16);
+			return do_auto_update(*ptr);
+		}
+		else
+		{
+			return do_auto_update(simple_strtoul(argv[1], NULL, 16));
+		}
+	}
+	else if(argc == 3)
+	{
+		sprintf(TempCmd1, "0x%x", CONFIG_USB_UPGRADE_DATA_ADDR);
+		sprintf(TempCmd2, "%s", argv[1]);
+		if(*argv[2] == '*')
+		{
+			ptr =  (unsigned int*) simple_strtoul(argv[2] + 1, NULL, 16);
+			size = *ptr;			
+		}
+		else
+		{
+			size = simple_strtoul(argv[2], NULL, 16);
+		}
+		sprintf(TempCmd3, "0x%x", size);
+		printf("nand read %s %s %s\n", pCmd[2], pCmd[3], pCmd[4]);
+		i = do_nand(NULL, 0, 5, pCmd);
+		if(i)
+		{
+			return i;
+		}
+		return do_auto_update(size);
+	}
+    return 0;
+}
+
+U_BOOT_CMD(
+	update_misc, 3, 0, do_update,
+	"update_misc - update your u-boot.bin / uImage / ramdiskg.img by USB storage device. \n",
+	"update_misc [CSV_LIST_OF_MTD_PARTITION_NAME] [force] [filename-url]\n"
+	"update_misc force splash,kernel,jffs2 usb://cnc83xxS.bin - update splash, kernel and jffs2. If it is available in cnc83xxS.bin from USB drive and also ignore version checking\n"
+	"update_misc force splash,kernel,jffs2 tftp://192.168.1.2/cnc83xxS.bin - update splash, kernel and jffs2. If it is available in image cnc83xxS.bin from tftp server and also ignore version checking\n"
+);
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_upgrade.c u-boot-2011.06/common/cmd_upgrade.c
--- u-boot-2011.06_original/common/cmd_upgrade.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_upgrade.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,449 @@
+#if 0
+#include <common.h>
+#include <command.h>
+#include <asm/errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+//upgrade spiuboot force cavm18_bootloader.bin
+//upgrade nethd // filename defaults to cavm18_netHD.sbin
+
+
+//usb start
+//fatload usb 0 0x2000000 su-boot.bin
+//sfer 0 +${filesize}
+//sfwr 0x2000000 0 ${filesize}
+
+//usb start
+//fatload usb 0x0 0x02100000 ubootpImage
+//saveenv
+//nand erase 0x02400000 ${filesize}
+//nand write 0x02100000 0x02400000 ${filesize}
+//reset
+
+//#define MAX_UBOOT_SIZE (0x80000)
+#define MAX_SPI_UBOOT_SIZE_STRING ("0x60000")
+#define MAX_UBOOT_SIZE_STRING ("0x80000")
+
+#define FILE_MEM_ADDR_STRING          ("0x02100000")
+#define FILE_MEM_ADDR                 (0x02100000)
+#define TMP_UBOOT_ADDR_STRING         ("0x0200000c")
+#define TMP_UBOOT_ADDR                (0x0200000c)
+#define SECURE_IMAGE_FILENAME         "cavm18_netHD.sbin"
+#define SECURE_IMAGE_EXTENSION        "sbin"
+#define INSECURE_UBOOT_IMAGE_FILENAME "cavm18_bootloader.bin"
+#define INSECURE_IMAGE_FILENAME       "cavm18_nethd.bin"
+#define UPGRADE_SPIUBOOT              0
+#define UPGRADE_UBOOT       	      1
+#define UPGRADE_NETHD	              2
+
+extern int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_sflashwr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_sflasher(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_sflashre(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_esp1800l_flash_util (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/* return the extension of a filename. returns filename if no extension */
+char *get_extension(char *filename)
+{
+	char *ext = filename;
+	
+	if (ext == NULL)
+		return ext;
+
+	// Work backwards from end of the name to the '.'
+	ext = filename + strlen(filename);
+
+	while ((*(ext-1) != '.') && (ext != filename)) {
+		ext--;
+	}
+
+	return ext;
+}
+
+
+int ReadNetHdBinFile(char *filename)
+{
+	int status;
+	char* cmd1[] = { "fatload" , "usb", "0" , FILE_MEM_ADDR_STRING, filename  };
+	status = do_fat_fsload(NULL, 0, 5 , cmd1);
+	if ( 0 == status)
+	{		
+		saveenv();
+	}
+	else
+	{
+		printf("ERROR: failed to load %s\n", filename);
+	}
+	return status;
+}
+
+int EraseNetHdRegion(void)
+{
+	 int status;
+	//nand erase 0x02400000 ${filesize}
+	//char filesize[16]={0};
+	//char* cmd1[] = { "nand" , "erase", "0x02400000" , & filesize[0] };
+	//strncpy(filesize , getenv("filesize") , sizeof(filesize) ) ;
+	char* cmd1[] = { "nand" , "erase", "0x02400000" , "0x02000000" };
+	status = do_nand(NULL, 0, 4 , cmd1);
+	if ( 0 == status)
+	{		
+		
+	}
+	else
+	{
+		printf("ERROR: unable to erase NAND flash for cavm18_nethd.bin\n");
+	}
+	return status;
+}
+
+int ProgramNetHdToNandFlash(char *filename)
+{
+	int status = 0;;
+	char *ext = get_extension(filename);
+	int retries = 3;
+
+	do {
+		if (0 == strcmp(ext, SECURE_IMAGE_EXTENSION)) {
+			// esp1800l_flash_util
+			char* cmd1[] = { "esp1800l_flash_util" , "--kernel", "--force", FILE_MEM_ADDR_STRING};
+
+			status = do_esp1800l_flash_util(NULL, 0 , 4 , cmd1 ) ;
+			// status will be -EIO on nand error
+		} else {
+			char filesize[16]={0};
+			char* cmd1[] = { "nand" , "write" , FILE_MEM_ADDR_STRING , "0x02400000",  & filesize[0] };
+			strncpy(filesize , getenv("filesize") , sizeof(filesize) ) ;
+
+			status = EraseNetHdRegion();
+			if (0 != status ) {
+				printf("ERROR: fail to erase NAND flash nethd region\n");
+			} else {
+				//nand write 0x02100000 0x02400000 ${filesize}
+				status = do_nand(NULL, 0, 5 , cmd1);
+				if ( 0 != status)
+				{
+					printf("ERROR: unable to write %s to NAND flash\n", filename);
+					status = -EIO;
+				}
+			}
+		}
+	} while ((--retries > 0) && (status == -EIO));
+
+	return status;
+}
+
+// returns 0 if it found valid boot addresses in SPI
+int ubootBootAddrs(int *bootaddr1, int *bootaddr2)
+{
+	int status;
+	char spi_addr[16]={0};
+	char* cmd1[] = { "sfre" , TMP_UBOOT_ADDR_STRING, &spi_addr[0] ,  "4"  };
+	*bootaddr1 = *bootaddr2 = -1;
+
+	strcpy(spi_addr, "0x208");
+
+	// read from 0x0208 from SPI and if it is 0x2c00 it boots from SPI (insecure board). 
+	status = do_sflashre(NULL, 0 , 4 , cmd1 ) ;
+	if (0 != status) {
+		printf("ERROR: fail to read SPI flash\n");
+	} else {
+		*bootaddr1 = (int)*(int *)(TMP_UBOOT_ADDR);
+
+		strcpy(spi_addr, "0xb504");
+
+		// read from 0x0b500 from SPI and to get primary NAND uboot address
+		status = do_sflashre(NULL, 0 , 4 , cmd1 ) ;
+		if (0 != status) {
+			printf("ERROR: fail to read SPI flash\n");
+		} else {
+			*bootaddr2 = (int)*(int *)(TMP_UBOOT_ADDR);
+		}
+	}
+	
+	return status;
+}
+
+int ReadBootLoaderBinFile(char *filename)
+{
+	int status;
+	char* cmd1[] = { "fatload" , "usb", "0" , FILE_MEM_ADDR_STRING, filename  };
+
+	memset((void*) FILE_MEM_ADDR , 0xFF , simple_strtoul ( MAX_UBOOT_SIZE_STRING , NULL, 16 ));
+	status = do_fat_fsload(NULL, 0, 5 , cmd1);
+	if ( 0 == status)
+	{		
+	}
+	else
+	{
+		printf("ERROR: failed to load %s\n", filename);
+	}
+
+	return status;
+}
+
+int EraseSPIUBootRegion(void)
+{
+	int status;
+	char* cmd2[] = { "sfer" , "0", MAX_SPI_UBOOT_SIZE_STRING }; //erase 512K.
+
+	status =  do_sflasher(NULL, 0,3,  cmd2) ;	
+	printf("status = %d\n" , status );
+
+	return status;
+}
+
+int EraseNANDUBootRegion(char *addr)
+{
+	int status;
+	char* cmd1[] = { "nand" , "erase.spread", addr, MAX_UBOOT_SIZE_STRING }; //erase 512K.
+	status = do_nand(NULL, 0, 4 , cmd1);
+	if ( 0 != status)
+	{
+		printf("ERROR: unable to erase NAND flash at address %s\n", addr);
+	}
+
+	return status;
+}
+
+int ProgramUBootToSPIFlash(void)
+{
+	int status;
+	char* cmd1[] = { "sfwr" , FILE_MEM_ADDR_STRING, "0" ,  MAX_SPI_UBOOT_SIZE_STRING  };
+	int bootaddr1, bootaddr2;
+
+	status = ubootBootAddrs(&bootaddr1, &bootaddr2);
+
+	if (status != 0)  {
+	} else if (bootaddr1 != 0x2c00) {
+		printf("ERROR: miniloader in SPI flash does not boot uboot from SPI flash!\n");
+		status = -1;
+	} else {
+		status = EraseSPIUBootRegion();
+		if (status != 0 ) {
+			printf("ERROR: fail to erase SPI flash\n");
+		} else {
+			status = do_sflashwr(NULL, 0 , 4 , cmd1 ) ;
+		}
+	}
+	return status;
+}
+
+int ProgramUBootToNANDFlash(char *filename)
+{
+	int status = 0;
+	int bootaddr1, bootaddr2;
+	char *ext = get_extension(filename);
+	int retries = 3;
+
+	status = ubootBootAddrs(&bootaddr1, &bootaddr2);
+
+	do {
+		if (status != 0)  {
+		} else if (bootaddr1 == 0x2c00) {
+			printf("ERROR: miniloader in SPI flash boots from SPI not NAND!\n");
+			status = -1;
+		} else if (0 == strcmp(ext, SECURE_IMAGE_EXTENSION)) {
+			// esp1800l_flash_util
+			char* cmd1[] = { "esp1800l_flash_util" , "--uboot", "--force", FILE_MEM_ADDR_STRING};
+
+			status = do_esp1800l_flash_util(NULL, 0 , 4 , cmd1 ) ;
+			// status will be -EIO on nand error
+
+		} else {
+			char nand_addr[16]={0};
+			char* cmd1[] = { "nand" , "write", FILE_MEM_ADDR_STRING, &nand_addr[0] ,  MAX_UBOOT_SIZE_STRING  };
+			sprintf(nand_addr, "0x%x", bootaddr2);
+
+			status = EraseNANDUBootRegion(nand_addr);
+			if (status == 0 ) {
+				status = do_nand(NULL, 0 , 5 , cmd1 ) ;
+				if ( 0 != status )
+				{
+					status = -EIO;
+					printf("ERROR: fail to write to nand\n");
+				}
+			}
+		}
+	} while ((--retries > 0) && (status == -EIO));
+
+	return status;
+}
+
+int StartUsbService(void)
+{
+	extern int usb_stor_curr_dev;
+	int status;
+	char* usb_start[] = { "usb" , "start" };
+
+	//printf("Going for UpgradeAllIfRequired\n");
+	status = do_usb(NULL, 0, 2, usb_start );
+	if ( usb_stor_curr_dev < 0)
+	{
+		status = -1;
+	}
+
+	return status;
+}
+//--------------------------------------------------------------------------------------------------
+int StopUsbService(void)
+{
+	int status;
+	char* usb_stop[] = { "usb" , "stop" };
+
+	printf("Usb service is stopped now\n");
+	status = do_usb(NULL, 0, 2, usb_stop );
+
+	return status;
+}
+//--------------------------------------------------------------------------------------------------
+
+void stoupper(char *s)
+{
+	for(; *s; s++)
+	{
+		if(('a' <= *s) && (*s <= 'z'))
+		{
+			*s = 'A' + (*s - 'a');
+		}
+	}
+}
+
+void stolower(char *s)
+{
+	for(; *s; s++)
+	{
+		if(('A' <= *s) && (*s <= 'Z'))
+		{
+			*s = 'a' + (*s - 'A');
+		}
+	}
+}
+
+int do_upgrade(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int status;
+	int what_to_upgrade = -1 ;
+	int force = 0;
+	char *filename = SECURE_IMAGE_FILENAME;
+
+	if ((argc < 2) || (argc > 4))
+	{
+		return cmd_usage(cmdtp);
+	}
+
+	stolower((char*) argv[1] );
+	stolower((char*) argv[2] );
+
+	if( 0 == strcmp( argv[1] , "spiuboot" ) )
+	{
+		what_to_upgrade=UPGRADE_SPIUBOOT;
+		filename = INSECURE_UBOOT_IMAGE_FILENAME;
+	}
+	else if( 0 == strcmp( argv[1] , "uboot" ) )
+	{
+		what_to_upgrade=UPGRADE_UBOOT;
+	}
+	else if( 0 == strcmp( argv[1] , "nethd" ) )
+	{
+		what_to_upgrade=UPGRADE_NETHD;
+	}
+	else
+	{
+		return cmd_usage(cmdtp);
+	}
+
+	if( 0 == strcmp( argv[2] , "force" ) )
+	{
+		force=1;
+	}
+
+	if (((force)  && (argc == 4)) ||
+	   ((!force) && (argc == 3)))
+		filename = argv[argc-1];
+
+	status = StartUsbService();
+	if (status != 0 ) {
+		printf("ERROR: fail to start usb service\n");
+		goto exit2;
+	}
+
+	if ( UPGRADE_SPIUBOOT == what_to_upgrade )
+	{
+		if ( 1 == force ) {
+			status = ReadBootLoaderBinFile(filename);
+			if (status == 0 ) {
+				status = ProgramUBootToSPIFlash();
+				if (status != 0 ) {
+					printf("ERROR: fail to program SPI flash\n");
+				}
+			}
+		} else {
+			printf("Expected force option when updating SPI uboot\n");
+		}
+	}
+	else if ( UPGRADE_UBOOT == what_to_upgrade )
+	{
+		if ( 1 == force ) {
+			status = ReadNetHdBinFile(filename);
+			if (status == 0 ) {
+				status = ProgramUBootToNANDFlash(filename);
+				if (status != 0 ) {
+					printf("ERROR: fail to program SPI flash\n");
+				}
+			}
+		} else {
+			printf("Expected force option when updating uboot\n");
+		}
+	}
+	else // kernel image
+	{
+		status = ReadNetHdBinFile(filename);
+		if (status != 0 ) {
+			printf("WARNING: failed to read %s file, trying %s\n",
+					filename, INSECURE_IMAGE_FILENAME);
+			filename = INSECURE_IMAGE_FILENAME;
+			status = ReadNetHdBinFile(filename);
+			if (status != 0 ) {
+				printf("ERROR: failed to read %s.\n", filename);
+			}
+		}
+		if (status == 0) {
+			status = ProgramNetHdToNandFlash(filename);
+			if (status != 0 ) {
+				printf("ERROR: fail to program NAND flash\n");
+			}
+		}
+	}
+
+	status = StopUsbService();
+	if (status != 0 ) {
+		printf("ERROR: fail to stop usb service\n");
+	}
+
+exit2:	
+	return status;
+}
+
+
+
+int AutoFirmwareUpgrade(void)
+{
+	printf("Performing USB_UPDATES2=1\n");
+	return 0;
+}
+
+U_BOOT_CMD(
+	upgrade,	4,	0,	do_upgrade,
+	"Utility to upgrade uboot or nethd image\n",
+	"\tupgrade spiuboot|uboot|nethd [force] [filename]\n"
+	"\t  spiuboot indicates that uboot in SPI flash should be updated with cavm18_bootloader.bin\n"
+	"\t  uboot indicates that uboot image in NAND flash should be updated with cavm18_netHD.sbin or file specified\n"
+	"\t  nethd indicates that nethd image in NAND flash should be updated with cavm18_netHD.sbin or file specified\n"
+	"\n"
+	"\t  force indicates that the upgrade should be done regardless of version or whether uboot was specified\n"
+	);
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_usb2nand.c u-boot-2011.06/common/cmd_usb2nand.c
--- u-boot-2011.06_original/common/cmd_usb2nand.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_usb2nand.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2009
+ * 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 <common.h>
+#include <command.h>
+#include "cnc_util.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+
+//usb2nand filename address spread
+int do_usb2nand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	#define MAX_RETRY_COUNT 3
+	int status;
+	int ReTryCount=3;
+	//char* flash_address = argv[2];
+	//char filesize[12]={0};
+	UInt32 FlashAddress=0;
+	UInt32 DdrStorageAddress=0;
+	UInt32 DdrVerifyAddress=0;
+
+	int skip_verify=0;
+
+	unsigned int uFileSize;
+	unsigned int MaxFileSize ;
+	
+	FlashAddress = simple_strtol( argv[2], NULL,16);	
+	
+	MaxFileSize = ( (gd->reloc_off -16) & 0xFFFFFFFC) / 2 ;
+
+	DdrStorageAddress=0;	
+	DdrVerifyAddress = MaxFileSize;
+
+	if (argc < 3)
+	{
+		cmd_usage(cmdtp);
+		return -1;
+	}
+
+	if ( 0 == strcmp( argv[3] , "0"))
+	{
+		skip_verify=1;
+		MaxFileSize = ( (gd->reloc_off -16) & 0xFFFFFFFC);
+	}
+
+	printf("NOTE:This command can handle maxiumum file size of %d bytes\n", MaxFileSize);
+	
+	status = cnc_LoadFileFromUsb(argv[1],  DdrStorageAddress, & uFileSize);
+	
+	if (uFileSize < 1 )
+	{
+		printf("ERROR: File Error, count < 1, aborting...\n");
+		return -3;
+	}
+	if (uFileSize > MaxFileSize ) 
+	{
+		printf("ERROR: Input file size too big, please program image manually\n");
+		return -2;
+	}
+	
+	do
+	{				
+		status = cnc_NandErase(FlashAddress ,uFileSize , 1);//erase.spread
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+		
+		status = cnc_NandWrite(DdrStorageAddress ,FlashAddress ,uFileSize, RAW );
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+
+		if (skip_verify == 1)
+		{
+			printf("skipping memory verify\n");
+			ReTryCount=MAX_RETRY_COUNT;
+			break;
+		}
+
+		status = cnc_NandRead(FlashAddress ,DdrVerifyAddress ,uFileSize );
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+		status = memcmp( (void*) DdrStorageAddress , (void*) DdrVerifyAddress ,uFileSize );
+		if (status == 0 )
+		{
+			ReTryCount=MAX_RETRY_COUNT;
+			break;
+		}
+		else
+		{
+			printf("Memory compare fail, trying to reprogram image. Retry count=%d\n", MAX_RETRY_COUNT-ReTryCount);
+		}
+	}while(ReTryCount--);
+
+exit1:
+	if (ReTryCount == 0 )
+	{
+		printf("ERROR: Fail to program Image, please contact vendor\n");
+	}
+	else
+	{
+		if ( 1 == skip_verify )
+		{
+			printf("Image is programmed successfully (but it was not verified)\n");
+		}
+		else
+		{
+			printf("Image is programmed and verified successfully\n");
+		}
+	}
+    return 0;
+}
+
+
+U_BOOT_CMD(
+	usb2nand, 4, 1, do_usb2nand,
+	"filename flash_address",
+	"filename flash_address"
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_usb2spi.c u-boot-2011.06/common/cmd_usb2spi.c
--- u-boot-2011.06_original/common/cmd_usb2spi.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cmd_usb2spi.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2009
+ * 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 <common.h>
+#include <command.h>
+#include "cnc_util.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+//usb2spi filename address
+int do_usb2spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	#define MAX_RETRY_COUNT 3
+	int status;
+	int ReTryCount=3;
+	//char* flash_address = argv[2];
+	//char filesize[12]={0};
+	UInt32 FlashAddress=0;
+	UInt32 DdrStorageAddress=0;
+	UInt32 DdrVerifyAddress=0;
+
+	int skip_verify=0;
+
+	unsigned int uFileSize;
+	unsigned int MaxFileSize ;
+	
+	FlashAddress = simple_strtol( argv[2], NULL,16);	
+	
+	MaxFileSize = ( (gd->reloc_off -16) & 0xFFFFFFFC) / 2 ;
+
+	DdrStorageAddress=0;	
+	DdrVerifyAddress = MaxFileSize;
+
+	if (argc < 3)
+	{
+		cmd_usage(cmdtp);
+		return -1;
+	}
+
+	if ( 0 == strcmp( argv[3] , "0"))
+	{
+		skip_verify=1;
+		MaxFileSize = ( (gd->reloc_off -16) & 0xFFFFFFFC);
+	}
+
+	printf("NOTE:This command can handle maxiumum file size of %d bytes\n", MaxFileSize);
+	
+	status = cnc_LoadFileFromUsb(argv[1],  DdrStorageAddress, & uFileSize);
+	
+	if (uFileSize < 1 )
+	{
+		printf("ERROR: File Error, count < 1, aborting...\n");
+		return -3;
+	}
+	if (uFileSize > MaxFileSize ) 
+	{
+		printf("ERROR: Input file size too big, please program image manually\n");
+		return -2;
+	}
+	
+	do
+	{				
+		status = cnc_SpiErase(FlashAddress ,uFileSize);
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+		
+		status = cnc_SpiWrite(DdrStorageAddress ,FlashAddress ,uFileSize );
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+
+		if (skip_verify == 1)
+		{
+			printf("skipping memory verify\n");
+			ReTryCount=MAX_RETRY_COUNT;
+			break;
+		}
+
+		status = cnc_SpiRead(FlashAddress ,DdrVerifyAddress ,uFileSize );
+		if (status != 0 )
+		{
+			ReTryCount=0;
+			goto exit1;
+			return -1;
+		}
+		status = memcmp( (void*) DdrStorageAddress , (void*) DdrVerifyAddress ,uFileSize );
+		if (status == 0 )
+		{
+			ReTryCount=MAX_RETRY_COUNT;
+			break;
+		}
+		else
+		{
+			printf("Memory compare fail, trying to reprogram image. Retry count=%d\n", MAX_RETRY_COUNT-ReTryCount);
+		}
+	}while(ReTryCount--);
+
+exit1:
+	if (ReTryCount == 0 )
+	{
+		printf("ERROR: Fail to program Image, please contact vendor\n");
+	}
+	else
+	{
+		if ( 1 == skip_verify )
+		{
+			printf("Image is programmed successfully (but it was not verified)\n");
+		}
+		else
+		{
+			printf("Image is programmed and verified successfully\n");
+		}
+	}
+    return 0;
+}
+
+
+U_BOOT_CMD(
+	usb2spi, 3, 1, do_usb2spi,
+	"filename flash_address",
+	"filename flash_address"
+);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_usb.c u-boot-2011.06/common/cmd_usb.c
--- u-boot-2011.06_original/common/cmd_usb.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_usb.c	2014-07-29 17:28:38.819972000 +0800
@@ -5,29 +5,13 @@
  * Most of this source has been derived from the Linux USB
  * project.
  *
- * 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
- *
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
 #include <command.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <part.h>
 #include <usb.h>
 
@@ -39,7 +23,7 @@
 #endif
 
 /* some display routines (info command) */
-char *usb_get_class_desc(unsigned char dclass)
+static char *usb_get_class_desc(unsigned char dclass)
 {
 	switch (dclass) {
 	case USB_CLASS_PER_INTERFACE:
@@ -65,8 +49,8 @@
 	}
 }
 
-void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
-			   unsigned char proto)
+static void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
+				  unsigned char proto)
 {
 	switch (dclass) {
 	case USB_CLASS_PER_INTERFACE:
@@ -147,16 +131,17 @@
 	}
 }
 
-void usb_display_string(struct usb_device *dev, int index)
+static void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
 	}
 }
 
-void usb_display_desc(struct usb_device *dev)
+static void usb_display_desc(struct usb_device *dev)
 {
 	if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) {
 		printf("%d: %s,  USB Revision %x.%x\n", dev->devnum,
@@ -190,8 +175,8 @@
 
 }
 
-void usb_display_conf_desc(struct usb_configuration_descriptor *config,
-			   struct usb_device *dev)
+static void usb_display_conf_desc(struct usb_config_descriptor *config,
+				  struct usb_device *dev)
 {
 	printf("   Configuration: %d\n", config->bConfigurationValue);
 	printf("   - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces,
@@ -205,8 +190,8 @@
 	}
 }
 
-void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,
-			 struct usb_device *dev)
+static void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,
+				struct usb_device *dev)
 {
 	printf("     Interface: %d\n", ifdesc->bInterfaceNumber);
 	printf("     - Alternate Setting %d, Endpoints: %d\n",
@@ -222,7 +207,7 @@
 	}
 }
 
-void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
+static void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
 {
 	printf("     - Endpoint %d %s ", epdesc->bEndpointAddress & 0xf,
 		(epdesc->bEndpointAddress & 0x80) ? "In" : "Out");
@@ -240,14 +225,14 @@
 		printf("Interrupt");
 		break;
 	}
-	printf(" MaxPacket %d", epdesc->wMaxPacketSize);
+	printf(" MaxPacket %d", get_unaligned(&epdesc->wMaxPacketSize));
 	if ((epdesc->bmAttributes & 0x03) == 0x3)
 		printf(" Interval %dms", epdesc->bInterval);
 	printf("\n");
 }
 
 /* main routine to diasplay the configs, interfaces and endpoints */
-void usb_display_config(struct usb_device *dev)
+static void usb_display_config(struct usb_device *dev)
 {
 	struct usb_config *config;
 	struct usb_interface *ifdesc;
@@ -267,21 +252,49 @@
 	printf("\n");
 }
 
+static struct usb_device *usb_find_device(int devnum)
+{
+	struct usb_device *dev;
+	int d;
+
+	for (d = 0; d < USB_MAX_DEVICE; d++) {
+		dev = usb_get_dev_index(d);
+		if (dev == NULL)
+			return NULL;
+		if (dev->devnum == devnum)
+			return dev;
+	}
+
+	return NULL;
+}
+
 static inline char *portspeed(int speed)
 {
-	if (speed == USB_SPEED_HIGH)
-		return "480 Mb/s";
-	else if (speed == USB_SPEED_LOW)
-		return "1.5 Mb/s";
-	else
-		return "12 Mb/s";
+	char *speed_str;
+
+	switch (speed) {
+	case USB_SPEED_SUPER:
+		speed_str = "5 Gb/s";
+		break;
+	case USB_SPEED_HIGH:
+		speed_str = "480 Mb/s";
+		break;
+	case USB_SPEED_LOW:
+		speed_str = "1.5 Mb/s";
+		break;
+	default:
+		speed_str = "12 Mb/s";
+		break;
+	}
+
+	return speed_str;
 }
 
 /* shows the device tree recursively */
-void usb_show_tree_graph(struct usb_device *dev, char *pre)
+static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 {
 	int i, index;
-	int has_child, last_child, port;
+	int has_child, last_child;
 
 	index = strlen(pre);
 	printf(" %s", pre);
@@ -300,7 +313,6 @@
 				/* found our pointer, see if we have a
 				 * little sister
 				 */
-				port = i;
 				while (i++ < dev->parent->maxchild) {
 					if (dev->parent->children[i] != NULL) {
 						/* found a sister */
@@ -339,7 +351,7 @@
 }
 
 /* main routine for the tree command */
-void usb_show_tree(struct usb_device *dev)
+static void usb_show_tree(struct usb_device *dev)
 {
 	char preamble[32];
 
@@ -347,159 +359,74 @@
 	usb_show_tree_graph(dev, &preamble[0]);
 }
 
-
-/******************************************************************************
- * usb boot command intepreter. Derived from diskboot
- */
-#ifdef CONFIG_USB_STORAGE
-int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int usb_test(struct usb_device *dev, int port, char* arg)
 {
-	char *boot_device = NULL;
-	char *ep;
-	int dev, part = 1, rcode;
-	ulong addr, cnt;
-	disk_partition_t info;
-	image_header_t *hdr;
-	block_dev_desc_t *stor_dev;
-#if defined(CONFIG_FIT)
-	const void *fit_hdr = NULL;
-#endif
-
-	switch (argc) {
-	case 1:
-		addr = CONFIG_SYS_LOAD_ADDR;
-		boot_device = getenv("bootdevice");
-		break;
-	case 2:
-		addr = simple_strtoul(argv[1], NULL, 16);
-		boot_device = getenv("bootdevice");
-		break;
-	case 3:
-		addr = simple_strtoul(argv[1], NULL, 16);
-		boot_device = argv[2];
-		break;
-	default:
-		return cmd_usage(cmdtp);
-	}
-
-	if (!boot_device) {
-		puts("\n** No boot device **\n");
-		return 1;
-	}
-
-	dev = simple_strtoul(boot_device, &ep, 16);
-	stor_dev = usb_stor_get_dev(dev);
-	if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) {
-		printf("\n** Device %d not available\n", dev);
-		return 1;
-	}
-	if (stor_dev->block_read == NULL) {
-		printf("storage device not initialized. Use usb scan\n");
-		return 1;
-	}
-	if (*ep) {
-		if (*ep != ':') {
-			puts("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = simple_strtoul(++ep, NULL, 16);
-	}
-
-	if (get_partition_info(stor_dev, part, &info)) {
-		/* try to boot raw .... */
-		strncpy((char *)&info.type[0], BOOT_PART_TYPE,
-			sizeof(BOOT_PART_TYPE));
-		strncpy((char *)&info.name[0], "Raw", 4);
-		info.start = 0;
-		info.blksz = 0x200;
-		info.size = 2880;
-		printf("error reading partinfo...try to boot raw\n");
-	}
-	if ((strncmp((char *)info.type, BOOT_PART_TYPE,
-	    sizeof(info.type)) != 0) &&
-	    (strncmp((char *)info.type, BOOT_PART_COMP,
-	    sizeof(info.type)) != 0)) {
-		printf("\n** Invalid partition type \"%.32s\""
-			" (expect \"" BOOT_PART_TYPE "\")\n",
-			info.type);
-		return 1;
-	}
-	printf("\nLoading from USB device %d, partition %d: "
-		"Name: %.32s  Type: %.32s\n",
-		dev, part, info.name, info.type);
-
-	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
-		info.start, info.size, info.blksz);
+	int mode;
 
-	if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) {
-		printf("** Read error on %d:%d\n", dev, part);
+	if (port > dev->maxchild) {
+		printf("Device is no hub or does not have %d ports.\n", port);
 		return 1;
 	}
 
-	switch (genimg_get_format((void *)addr)) {
-	case IMAGE_FORMAT_LEGACY:
-		hdr = (image_header_t *)addr;
-
-		if (!image_check_hcrc(hdr)) {
-			puts("\n** Bad Header Checksum **\n");
-			return 1;
-		}
-
-		image_print_contents(hdr);
-
-		cnt = image_get_image_size(hdr);
+	switch (arg[0]) {
+	case 'J':
+	case 'j':
+		printf("Setting Test_J mode");
+		mode = USB_TEST_MODE_J;
+		break;
+	case 'K':
+	case 'k':
+		printf("Setting Test_K mode");
+		mode = USB_TEST_MODE_K;
+		break;
+	case 'S':
+	case 's':
+		printf("Setting Test_SE0_NAK mode");
+		mode = USB_TEST_MODE_SE0_NAK;
+		break;
+	case 'P':
+	case 'p':
+		printf("Setting Test_Packet mode");
+		mode = USB_TEST_MODE_PACKET;
+		break;
+	case 'F':
+	case 'f':
+		printf("Setting Test_Force_Enable mode");
+		mode = USB_TEST_MODE_FORCE_ENABLE;
 		break;
-#if defined(CONFIG_FIT)
-	case IMAGE_FORMAT_FIT:
-		fit_hdr = (const void *)addr;
-		puts("Fit image detected...\n");
-
-		cnt = fit_get_size(fit_hdr);
-		break;
-#endif
 	default:
-		puts("** Unknown image type\n");
+		printf("Unrecognized test mode: %s\nAvailable modes: "
+		       "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg);
 		return 1;
 	}
 
-	cnt += info.blksz - 1;
-	cnt /= info.blksz;
-	cnt -= 1;
-
-	if (stor_dev->block_read(dev, info.start+1, cnt,
-		      (ulong *)(addr+info.blksz)) != cnt) {
-		printf("\n** Read error on %d:%d\n", dev, part);
-		return 1;
-	}
+	if (port)
+		printf(" on downstream facing port %d...\n", port);
+	else
+		printf(" on upstream facing port...\n");
 
-#if defined(CONFIG_FIT)
-	/* This cannot be done earlier, we need complete FIT image in RAM
-	 * first
-	 */
-	if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) {
-		if (!fit_check_format(fit_hdr)) {
-			puts("** Bad FIT image format\n");
-			return 1;
-		}
-		fit_print_contents(fit_hdr);
+	if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,
+			    port ? USB_RT_PORT : USB_RECIP_DEVICE,
+			    port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST,
+			    (mode << 8) | port,
+			    NULL, 0, USB_CNTL_TIMEOUT) == -1) {
+		printf("Error during SET_FEATURE.\n");
+		return 1;
+	} else {
+		printf("Test mode successfully set. Use 'usb start' "
+		       "to return to normal operation.\n");
+		return 0;
 	}
-#endif
-
-	/* Loading ok, update default load address */
-	load_addr = addr;
+}
 
-	flush_cache(addr, (cnt+1)*info.blksz);
 
-	/* Check if we should attempt an auto-start */
-	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
-		char *local_args[2];
-		local_args[0] = argv[0];
-		local_args[1] = NULL;
-		printf("Automatic boot of image at addr 0x%08lX ...\n", addr);
-		rcode = do_bootm(cmdtp, 0, 1, local_args);
-		return rcode;
-	}
-	return 0;
+/******************************************************************************
+ * usb boot command intepreter. Derived from diskboot
+ */
+#ifdef CONFIG_USB_STORAGE_USBBOOT
+static int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return common_diskboot(cmdtp, "usb", argc, argv);
 }
 #endif /* CONFIG_USB_STORAGE */
 
@@ -518,14 +445,16 @@
 #endif
 
 	if (argc < 2)
-		return cmd_usage(cmdtp);
+		return CMD_RET_USAGE;
 
 	if ((strncmp(argv[1], "reset", 5) == 0) ||
 		 (strncmp(argv[1], "start", 5) == 0)) {
+#if 0
+		bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+#endif
 		usb_stop();
 		printf("(Re)start USB...\n");
-		i = usb_init();
-		if (i >= 0) {
+		if (usb_init() >= 0) {
 #ifdef CONFIG_USB_STORAGE
 			/* try to recognize storage devices immediately */
 			usb_stor_curr_dev = usb_stor_scan(1);
@@ -534,6 +463,9 @@
 			/* try to recognize ethernet devices immediately */
 			usb_ether_curr_dev = usb_host_eth_scan(1);
 #endif
+#ifdef CONFIG_USB_KEYBOARD
+			drv_usb_kbd_init();
+#endif
 		}
 		return 0;
 	}
@@ -560,8 +492,14 @@
 		return 1;
 	}
 	if (strncmp(argv[1], "tree", 4) == 0) {
-		printf("\nDevice Tree:\n");
-		usb_show_tree(usb_get_dev_index(0));
+		puts("USB device tree:\n");
+		for (i = 0; i < USB_MAX_DEVICE; i++) {
+			dev = usb_get_dev_index(i);
+			if (dev == NULL)
+				break;
+			if (dev->parent == NULL)
+				usb_show_tree(dev);
+		}
 		return 0;
 	}
 	if (strncmp(argv[1], "inf", 3) == 0) {
@@ -576,17 +514,9 @@
 			}
 			return 0;
 		} else {
-			int d;
-
-			i = simple_strtoul(argv[2], NULL, 16);
+			i = simple_strtoul(argv[2], NULL, 10);
 			printf("config for device %d\n", i);
-			for (d = 0; d < USB_MAX_DEVICE; d++) {
-				dev = usb_get_dev_index(d);
-				if (dev == NULL)
-					break;
-				if (dev->devnum == i)
-					break;
-			}
+			dev = usb_find_device(i);
 			if (dev == NULL) {
 				printf("*** No device available ***\n");
 				return 0;
@@ -597,6 +527,18 @@
 		}
 		return 0;
 	}
+	if (strncmp(argv[1], "test", 4) == 0) {
+		if (argc < 5)
+			return CMD_RET_USAGE;
+		i = simple_strtoul(argv[2], NULL, 10);
+		dev = usb_find_device(i);
+		if (dev == NULL) {
+			printf("Device %d does not exist.\n", i);
+			return 1;
+		}
+		i = simple_strtoul(argv[3], NULL, 10);
+		return usb_test(dev, i, argv[4]);
+	}
 #ifdef CONFIG_USB_STORAGE
 	if (strncmp(argv[1], "stor", 4) == 0)
 		return usb_stor_info();
@@ -703,40 +645,37 @@
 		return 0;
 	}
 #endif /* CONFIG_USB_STORAGE */
-	return cmd_usage(cmdtp);
+	return CMD_RET_USAGE;
 }
 
-#ifdef CONFIG_USB_STORAGE
 U_BOOT_CMD(
 	usb,	5,	1,	do_usb,
 	"USB sub-system",
-	"reset - reset (rescan) USB controller\n"
-	"usb stop [f]  - stop USB [f]=force stop\n"
-	"usb tree  - show USB device tree\n"
+	"start - start (scan) USB controller\n"
+	"usb reset - reset (rescan) USB controller\n"
+	"usb stop [f] - stop USB [f]=force stop\n"
+	"usb tree - show USB device tree\n"
 	"usb info [dev] - show available USB devices\n"
-	"usb storage  - show details of USB storage devices\n"
+	"usb test [dev] [port] [mode] - set USB 2.0 test mode\n"
+	"    (specify port 0 to indicate the device's upstream port)\n"
+	"    Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n"
+#ifdef CONFIG_USB_STORAGE
+	"usb storage - show details of USB storage devices\n"
 	"usb dev [dev] - show or set current USB storage device\n"
 	"usb part [dev] - print partition table of one or all USB storage"
-	" devices\n"
+	"    devices\n"
 	"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
 	"    to memory address `addr'\n"
 	"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
 	"    from memory address `addr'"
+#endif /* CONFIG_USB_STORAGE */
 );
 
 
+#ifdef CONFIG_USB_STORAGE_USBBOOT
 U_BOOT_CMD(
 	usbboot,	3,	1,	do_usbboot,
 	"boot from USB device",
 	"loadAddr dev:part"
 );
-
-#else
-U_BOOT_CMD(
-	usb,	5,	1,	do_usb,
-	"USB sub-system",
-	"reset - reset (rescan) USB controller\n"
-	"usb  tree  - show USB device tree\n"
-	"usb  info [dev] - show available USB devices"
-);
-#endif
+#endif /* CONFIG_USB_STORAGE */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cmd_version.c u-boot-2011.06/common/cmd_version.c
--- u-boot-2011.06_original/common/cmd_version.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/cmd_version.c	2014-07-29 17:28:38.819972000 +0800
@@ -24,17 +24,18 @@
 #include <common.h>
 #include <command.h>
 #include <version.h>
+#include "cnc_util.h"
 
 extern char version_string[];
 
 int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	printf("\n%s\n", version_string);
+	printf("\n%s%s%s\n", ColorMagenta , version_string, ColorNormal);
 #ifdef CC_VERSION_STRING
-	puts(CC_VERSION_STRING "\n");
+	//puts(CC_VERSION_STRING "\n");
 #endif
 #ifdef LD_VERSION_STRING
-	puts(LD_VERSION_STRING "\n");
+	//puts(LD_VERSION_STRING "\n");
 #endif
 
 	return 0;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/cnc_util.c u-boot-2011.06/common/cnc_util.c
--- u-boot-2011.06_original/common/cnc_util.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/cnc_util.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1024 @@
+#include <rsa.h>
+#include "cnc_util.h"
+/*
+//\e[attr;3x;4ym
+#define RESET		0
+#define BRIGHT 		1
+#define DIM		    2
+#define UNDERLINE 	4
+#define BLINK		5
+#define REVERSE		7
+#define HIDDEN		8
+
+#define BLACK 		0
+#define RED		    1
+#define GREEN		2
+#define YELLOW		3
+#define BLUE		4
+#define MAGENTA		5
+#define CYAN		6
+#define	WHITE		7
+{ESC}[1m	High intensity.
+{ESC}[1;5m	High intensity and blink.
+{ESC}[30;46m	Black foreground, cyan background.
+{ESC}[m	Turn off all attributes.
+{ESC}[0m	Turn off all attributes.
+{ESC}[0;1;36m	Turn off all attributes, then turn on high-intensity cyan foreground.
+*/
+
+static struct spi_flash *cnc_spi_flash = NULL;
+
+char ColorBlack[sizeof xColorBlack] = xColorBlack;
+char ColorRed[sizeof  xColorRed ] = xColorRed ;
+char ColorGreen[sizeof xColorGreen  ] =  xColorGreen ;
+char ColorYellow[sizeof xColorYellow  ] =  xColorYellow ;
+char ColorBlue[sizeof xColorBlue  ] = xColorBlue  ;
+char ColorMagenta[sizeof xColorMagenta  ] = xColorMagenta  ;
+char ColorCyan[sizeof xColorCyan  ] =  xColorCyan ;
+char ColorWhite[sizeof xColorWhite  ] = xColorWhite  ;
+char ColorLightBlack[sizeof xColorLightBlack  ] = xColorLightBlack   ;
+char ColorLightRed[sizeof xColorLightRed  ] = xColorLightRed  ;
+char ColorLightGreen[sizeof  xColorLightGreen ] =  xColorLightGreen ;
+char ColorLightYellow[sizeof xColorLightYellow  ] = xColorLightYellow  ;
+char ColorLightBlue[sizeof xColorLightBlue  ] = xColorLightBlue  ;
+char ColorLightMagenta[sizeof xColorLightMagenta  ] = xColorLightMagenta  ;
+char ColorLightCyan[sizeof xColorLightCyan  ] = xColorLightCyan   ;
+char ColorLightWhite[sizeof  xColorLightWhite ] = xColorLightWhite  ;
+char ColorNormal[sizeof  xColorNormal ] = xColorNormal  ;
+char BlinkOn[sizeof xBlinkOn  ] = xBlinkOn  ;
+
+static int kluge_flag_to_fix_bug3394;
+
+extern int do_sflasher(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_sflashre(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_usb(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_fat_fsload(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_call_external_proc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_cncflash(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_sflashwr(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_mmcops(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_mem_md(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_flerase(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_mem_cmp(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_mem_cp(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+extern int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+void ColorOff(void)
+{
+	ColorBlack[0]='\0';
+	ColorRed[0]='\0';
+	ColorGreen[0]='\0';
+	ColorYellow[0]='\0';
+	ColorBlue[0]='\0';
+	ColorMagenta[0]='\0';
+	ColorCyan[0]='\0';
+	ColorWhite[0]='\0';
+	ColorLightBlack[0]='\0';
+	ColorLightRed[0]='\0';
+	ColorLightGreen[0]='\0';
+	ColorLightYellow[0]='\0';
+	ColorLightBlue[0]='\0';
+	ColorLightMagenta[0]='\0';
+	ColorLightCyan[0]='\0';
+	ColorLightWhite[0]='\0';
+	ColorNormal[0]='\0';
+	BlinkOn[0]='\0';
+}
+
+void ColorOn(void)
+{
+	strcpy(ColorBlack,xColorBlack);
+	strcpy(ColorRed, xColorRed );
+	strcpy(ColorGreen,  xColorGreen );
+	strcpy(ColorYellow, xColorYellow );
+	strcpy(ColorBlue, xColorBlue  );
+	strcpy(ColorMagenta, xColorMagenta  );
+	strcpy(ColorCyan,xColorCyan );
+	strcpy(ColorWhite, xColorWhite)  ;
+	strcpy(ColorLightBlack, xColorLightBlack   );
+	strcpy(ColorLightRed, xColorLightRed  );
+	strcpy(ColorLightGreen, xColorLightGreen );
+	strcpy(ColorLightYellow, xColorLightYellow  );
+	strcpy(ColorLightBlue, xColorLightBlue  );
+	strcpy(ColorLightMagenta, xColorLightMagenta  );
+	strcpy(ColorLightCyan, xColorLightCyan   );
+	strcpy(ColorLightWhite, xColorLightWhite  );
+	strcpy(ColorNormal, xColorNormal  );
+	strcpy(BlinkOn,xBlinkOn  );
+}
+
+void Cnc_DumpMemory(UInt32 aStartAddress, UInt32 aCount)
+{
+	/* 	md.l 0x1000 0x100*/
+	char* pCmd[] = {  "md.l" , NULL ,  NULL  };
+	char TempCmd1[16];
+	char TempCmd2[16];
+
+	int status=0;
+	pCmd[1] =  TempCmd1; pCmd[2] =  TempCmd2;
+
+	sprintf(TempCmd1 , "0x%x", aStartAddress);
+	sprintf(TempCmd2 , "0x%x", aCount);
+	status = do_mem_md (NULL, 0, 3 , (char** const )pCmd );
+	status = status;
+}
+
+int cnc_NandRead(uint32_t aSrcAddressInFlash,  uint32_t aDstAddressInDram,  uint32_t alen)
+{
+	/* 		    nand     read   4000000 ${WORK_IMG} ${filesize}*/
+	char* pCmd[5] = {  "nand" , "read" ,  NULL ,  NULL     , NULL };
+	char TempCmd1[16];
+	char TempCmd2[16];
+	char TempCmd3[16];
+
+	int status=0;
+
+	sprintf(TempCmd1 , "0x%x", aDstAddressInDram); // Work_IMG : Flash address
+	sprintf(TempCmd2 , "0x%x", aSrcAddressInFlash); // DDR Ram address
+	sprintf(TempCmd3 , "0x%x", alen); // $(filesize)
+
+	debug (" NandRd : SrcFlashAddr : %x DstAddressDram : %x len : %x\n",
+			aSrcAddressInFlash, aDstAddressInDram, alen);
+
+	pCmd[2] =  TempCmd1; pCmd[3] =  TempCmd2; pCmd[4] =  TempCmd3;
+
+	if (aSrcAddressInFlash & 0x1FFFF)
+	{
+		/* NAND offset is not a multiple of the block size, do the kluge */
+		kluge_flag_to_fix_bug3394 = 1;
+	}
+
+	status = do_nand(NULL, 0, 5, pCmd);
+	kluge_flag_to_fix_bug3394 = 0;
+	if ( 0 != status )
+	{
+		status = -1;
+		printf("ERROR: fail to read nand secure sector\n");
+	}
+	return status;
+}
+
+int cnc_EMMCRead(uint32_t aSrcAddressInFlash,  uint32_t aDstAddressInDram,  uint32_t alen)
+{
+	/* 		    nand     read   4000000 ${WORK_IMG} ${filesize}*/
+	char* pCmd[5] = {  "mmc" , "read" ,  NULL ,  NULL     , NULL };
+	char TempCmd1[16];
+	char TempCmd2[16];
+	char TempCmd3[16];
+
+	int status=0;
+
+	sprintf(TempCmd1 , "0x%x", aDstAddressInDram); // Work_IMG : Flash address
+	sprintf(TempCmd2 , "0x%x", aSrcAddressInFlash >> 9); // DDR Ram address
+	sprintf(TempCmd3 , "0x%x", ((alen + 511) >> 9)); // $(filesize)
+
+	debug (" eMMCRd : SrcFlashAddr : %x DstAddressDram : %x len : %x\n",
+			aSrcAddressInFlash, aDstAddressInDram, alen);
+
+	pCmd[2] =  TempCmd1; pCmd[3] =  TempCmd2; pCmd[4] =  TempCmd3;
+
+	if (aSrcAddressInFlash & 0x1FF)
+	{
+		/* eMMC offset is not a multiple of the block size, do the kluge?? */
+		//		kluge_flag_to_fix_bug3394 = 1;
+	}
+
+	status = do_mmcops(NULL, 0, 5, pCmd);
+	//	kluge_flag_to_fix_bug3394 = 0;
+	if ( 0 != status )
+	{
+		status = -1;
+		printf("ERROR: fail to read eMMC secure sector\n");
+	}
+	return status;
+}
+int cnc_NorErase(UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	return 0;
+	/*
+	   int status=0;
+	   char argv0[20];
+	   char argv1[20];
+	   char argv2[20];
+	   char *argv[] = { argv0,
+	   argv1,
+	   argv2
+	   };
+
+	   sprintf( argv0, "%s", "erase" );
+	   sprintf( argv1, "%X", aFlashStartAddress );
+	   sprintf( argv2, "%X", aFlashStartAddress + aLength  );
+
+	//printf("running:%s %s %s\n", argv0, argv1, argv2);
+	//status=do_flerase(NULL, 0,sizeof(argv)/sizeof(char *), argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+	*/
+}
+int cnc_NorVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	int status;
+	char argv0[20];
+	char argv1[20];
+	char argv2[20];
+	char argv3[20];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3
+	};
+
+	sprintf( argv0, "%s", "cmp.b" );
+	sprintf( argv1, "%X", aDdrStartAddress );
+	sprintf( argv2, "%X", aFlashStartAddress);
+	sprintf( argv3, "%X", aLength);
+
+	//printf("running:%s %s %s %s\n", argv0, argv1, argv2,argv3);
+	status=do_mem_cmp(NULL, 0,sizeof(argv)/sizeof(char *), argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+int cnc_NorRead(UInt32 aFlashSourceAddress, UInt32 aDdrDestinationAddress,  UInt32 aLength)
+{
+	int status;
+	char argv0[20];
+	char argv1[20];
+	char argv2[20];
+	char argv3[20];
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3
+	};
+
+	sprintf( argv0, "%s", "cp.b" );
+	sprintf( argv1, "%X", aFlashSourceAddress );
+	sprintf( argv2, "%X", aDdrDestinationAddress );
+	sprintf( argv3, "%X", aLength );
+
+	//printf("running:%s %s %s %s\n", argv0, argv1, argv2, argv3);
+	status = do_mem_cp(NULL, 0,sizeof(argv)/sizeof(char *), argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+int cnc_NorWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength)
+{
+	int status;
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char argv2[20]={0};
+	char argv3[20]={0};
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3
+	};
+	sprintf( argv0, "%s", "cp.b" );
+	sprintf( argv1, "%X", aDdrSourceAddress );
+	sprintf( argv2, "%X", aFlashDestinationAddress );
+	sprintf( argv3, "%X", aLength );
+
+	//printf("running:%s %s %s %s\n", argv0, argv1, argv2, argv3);
+	status = do_mem_cp(NULL, 0,sizeof(argv)/sizeof(char *), argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+int cnc_NandErase(UInt32 aFlashStartAddress, UInt32 aLength , UInt32 aEraseSpread)
+{
+	int status;
+	char argv0[20];
+	char argv1[20];
+	char argv2[20];
+	char argv3[20];
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3
+	};
+
+	sprintf( argv0, "%s", "nand" );
+	sprintf( argv1, "%s",  (aEraseSpread==1) ? "erase.spread" : "erase" );
+	sprintf( argv2, "%X", aFlashStartAddress );
+	sprintf( argv3, "%X", aLength );
+
+	//printf("running:%s %s %s %s\n", argv0, argv1, argv2, argv3);
+	status = do_nand( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+
+int cnc_EMMCRescan(void)
+{
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char *argv[] = { argv0,argv1};
+	int status;
+
+	sprintf( argv0, "%s", "mmc" );
+	sprintf( argv1, "%s", "rescan" );
+
+	printf("running:%s %s\n", argv0, argv1);
+	status = do_mmcops( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	return status;
+}
+
+int cnc_CreatGPTPartitionTable(ImagePartitionList_t *pt_list)
+{
+	int cur_pt_num = 0;
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char argv2[20]={0};
+	char argv3[20]={0};
+	char argv4[1024]={0};
+	char temp_argv[1024]={0};
+	char temp_uuid[40]={0};
+	char *argv[] = { argv0,argv1,argv2,argv3,argv4};
+	int status;
+	int first_emmc_pt = 1;
+	setenv("emmc0", "10000000-0000-0000-1310-000000000000");
+	sprintf( argv4, "%s", "uuid_disk=10000000-0000-0000-1310-000000000000;");
+	for(cur_pt_num = 0; cur_pt_num < pt_list->mNoOfPartition; cur_pt_num++){
+		if(0 == strcmp(pt_list->mImagePartitionList[cur_pt_num].mMtdId, "emmc")){
+			//			printf("index = %d, %s, 0x%x\n",cur_pt_num, pt_list->mImagePartitionList[cur_pt_num].mPartionName, pt_list->mImagePartitionList[cur_pt_num].mLength);
+			sprintf(temp_uuid, "10000000-0000-0000-1310-0000000000%2.2d", cur_pt_num+1);
+			setenv(pt_list->mImagePartitionList[cur_pt_num].mPartionName, temp_uuid);
+			if(first_emmc_pt){
+				sprintf(temp_argv,"uuid=%s,name=%s,size=%dMiB,start=1MiB;", temp_uuid, pt_list->mImagePartitionList[cur_pt_num].mPartionName, pt_list->mImagePartitionList[cur_pt_num].mLength/0x100000);
+				first_emmc_pt =0;
+			}
+			else{
+				sprintf(temp_argv,"uuid=%s,name=%s,size=%dMiB;", temp_uuid, pt_list->mImagePartitionList[cur_pt_num].mPartionName, pt_list->mImagePartitionList[cur_pt_num].mLength/0x100000);
+			}
+			strcat(argv4,temp_argv);
+			memset(temp_uuid,0,sizeof(temp_uuid));
+		}
+	}
+
+	sprintf( argv0, "%s", "gpt" );
+	sprintf( argv1, "%s", "write" );
+	sprintf( argv2, "%s", "mmc" );
+	sprintf( argv3, "%s", "0" );
+	//	sprintf( argv4, "%s", "uuid_disk=${emmc0};uuid=${blob},name=blob,size=1MiB,start=1MiB;uuid=${splash},name=splash,size=16MiB;uuid=${uboot_f},name=uboot_f,size=1MiB;uuid=${uboot},name=uboot,size=1MiB;uuid=${kernel_f},name=kernel_f,size=3MiB;uuid=${kernel},name=kernel,size=3MiB;uuid=${rootfs_f},name=rootfs_f,size=80MiB;uuid=${rootfs},name=rootfs,size=80MiB;uuid=${conf},name=conf,size=20MiB;uuid=${datafs},name=datafs,size=80MiB");
+	//	printf("running:%s %s %s,%s,%s\n", argv0, argv1,argv2,argv3,argv4);
+	status = do_gpt( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	return status;
+}
+
+int cnc_EMMCWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength,
+		cnc_ImageType aImageType )
+{
+	//image_header_t *hdr;
+	int status;
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char argv2[20]={0};
+	char argv3[20]={0};
+	char argv4[20]={0};
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4
+	};
+	sprintf( argv0, "%s", "mmc" );
+	sprintf( argv1, "%s", "write" );
+
+#if 0
+	hdr = (image_header_t *) aDdrSourceAddress;
+	switch (hdr->ih_type)
+	{
+		//------------------
+		case IH_TYPE_KERNEL:
+		case IH_TYPE_RAMDISK:
+			{
+				sprintf(argv1, "%s", "write.jffs2" );
+			}
+			break;
+			//-----------------
+		case IH_TYPE_FIRMWARE:
+		default:
+			{
+				sprintf( argv1, "%s", "write" );
+			}
+			//------------------
+	}
+#endif
+
+	sprintf( argv2, "%X", aDdrSourceAddress );
+	sprintf( argv3, "%X", aFlashDestinationAddress >> 9 );
+	sprintf( argv4, "%X", ((aLength + 511) >> 9) );
+
+	printf("running:%s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4 );
+	status = do_mmcops( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+
+int cnc_EMMCWrite2(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength,
+		cnc_ImageType aImageType )
+{
+	//image_header_t *hdr;
+	int status = -1;
+	int count = 0, offset = 0;
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char argv2[20]={0};
+	char argv3[20]={0};
+	char argv4[20]={0};
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4
+	};
+	sprintf( argv0, "%s", "mmc" );
+	sprintf( argv1, "%s", "write" );
+	aLength += 511;
+	while (aLength > 0 )
+	{
+		count = min(aLength,128*1024 );
+		sprintf( argv2, "%X", aDdrSourceAddress + offset);
+		sprintf( argv3, "%X", (aFlashDestinationAddress + offset)>> 9 );
+		if(count>>9)
+			sprintf( argv4, "%X", (count >> 9) );
+
+		printf("running:%s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4 );
+		status = do_mmcops( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+		if(-1 == status)
+			break;
+
+		aLength -= count;
+		offset +=count;
+	}
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+int cnc_NandWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength,
+		cnc_ImageType aImageType )
+{
+	//image_header_t *hdr;
+	int status;
+	char argv0[20]={0};
+	char argv1[20]={0};
+	char argv2[20]={0};
+	char argv3[20]={0};
+	char argv4[20]={0};
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4
+	};
+	sprintf( argv0, "%s", "nand" );
+	sprintf( argv1, "%s", "write" );
+
+#if 0
+	hdr = (image_header_t *) aDdrSourceAddress;
+	switch (hdr->ih_type)
+	{
+		//------------------
+		case IH_TYPE_KERNEL:
+		case IH_TYPE_RAMDISK:
+			{
+				sprintf(argv1, "%s", "write.jffs2" );
+			}
+			break;
+			//-----------------
+		case IH_TYPE_FIRMWARE:
+		default:
+			{
+				sprintf( argv1, "%s", "write" );
+			}
+			//------------------
+	}
+#endif
+
+	switch (aImageType)
+	{
+		case KERNEL:sprintf(argv1, "%s", "write" );break;
+		case RAMDISK:sprintf(argv1, "%s", "write" );break;
+		case JFFS2:sprintf(argv1, "%s", "write.jffs2" );break;
+		default:
+		case RAW:sprintf( argv1, "%s", "write" ); break;
+	}
+
+	sprintf( argv2, "%X", aDdrSourceAddress );
+	sprintf( argv3, "%X", aFlashDestinationAddress );
+	sprintf( argv4, "%X", aLength );
+
+	//printf("running:%s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4 );
+	status = do_nand( NULL, 0, sizeof(argv)/sizeof(char *), argv );
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+int cnc_EMMCVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	int status=-1;
+	char TempBuf[128*1024];
+	UInt32 Offset=0;
+	UInt32 Count;
+	while (aLength > 0 )
+	{
+		Count = min(aLength,sizeof(TempBuf) );
+		status =  cnc_EMMCRead( aFlashStartAddress + Offset,(UInt32) TempBuf, Count);
+		if ( 0 == memcmp((UInt8*)TempBuf, (UInt8*)(aDdrStartAddress + Offset), Count) )
+		{
+			Offset = Offset + Count;
+			aLength = aLength - Count;
+		}
+		else
+		{
+			int i=0;
+			for(i=0;i<Count;i++)
+			{
+				if (TempBuf[i] != * ((UInt8*)(aDdrStartAddress)) )
+				{
+					break;
+				}
+			}
+			printf("%sERROR: eMMC verify fails at address %08x\n%s", ColorRed , aFlashStartAddress + i, ColorNormal );
+			status=-1;
+			return status;
+		}
+	}
+	return status;
+}
+
+int cnc_EMMCVerify2(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	int status=-1;
+	UInt32 Offset=0;
+
+	status =  cnc_EMMCRead( aFlashStartAddress + Offset,(UInt32) (0x18000000), aLength);
+	if ( 0 == memcmp((UInt8*)(0x18000000), (UInt8*)(aDdrStartAddress + Offset), aLength) )
+	{
+		status = 0;
+	}
+
+	return status;
+}
+
+int cnc_NandVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	int status=-1;
+	char TempBuf[128*1024];
+	UInt32 Offset=0;
+	UInt32 Count;
+	while (aLength > 0 )
+	{
+		Count = min(aLength,sizeof(TempBuf) );
+		status =  cnc_NandRead( aFlashStartAddress + Offset,(UInt32) TempBuf, Count);
+		if ( 0 == memcmp((UInt8*)TempBuf, (UInt8*)(aDdrStartAddress + Offset), Count) )
+		{
+			Offset = Offset + Count;
+			aLength = aLength - Count;
+		}
+		else
+		{
+			int i=0;
+			for(i=0;i<Count;i++)
+			{
+				if (TempBuf[i] != * ((UInt8*)(aDdrStartAddress)) )
+				{
+					break;
+				}
+			}
+			printf("%sERROR: NAND verify fails at address %08x\n%s", ColorRed , aFlashStartAddress + i, ColorNormal );
+			status=-1;
+			return status;
+		}
+	}
+	return status;
+}
+int cnc_SpiVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	int status=-1;
+	char TempBuf[128*1024];
+	UInt32 Offset=0;
+	UInt32 Count;
+	while (aLength > 0 )
+	{
+		Count = min(aLength,sizeof(TempBuf) );
+		status =  cnc_SpiRead( aFlashStartAddress + Offset,(UInt32) TempBuf, Count);
+		if ( 0 == memcmp((UInt8*)TempBuf, (UInt8*)(aDdrStartAddress +Offset), Count) )
+		{
+			Offset = Offset + Count;
+			aLength = aLength - Count;
+		}
+		else
+		{
+			int i=0;
+			for(i=0;i<Count;i++)
+			{
+				if (TempBuf[i] != * ((UInt8*)(aDdrStartAddress)) )
+				{
+					break;
+				}
+			}
+			printf( "%sERROR: SPI verify fails at address %08x\n%s" , ColorRed , aFlashStartAddress + i, ColorNormal );
+			status=-1;
+			return status;
+		}
+	}
+	return status;
+}
+int cnc_SpiWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength)
+{
+	if(!cnc_spi_flash){
+		cnc_spi_flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_3);
+		if(!cnc_spi_flash) return 1;
+	}
+	return spi_flash_write(cnc_spi_flash, aFlashDestinationAddress, aLength, (const void *)aDdrSourceAddress);
+}
+int cnc_SpiErase(UInt32 aFlashStartAddress, UInt32 aLength)
+{
+	if(!cnc_spi_flash){
+		cnc_spi_flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_3);
+		if(!cnc_spi_flash) return 1;
+	}
+	return spi_flash_erase(cnc_spi_flash, aFlashStartAddress, aLength);
+}
+int cnc_SpiRead(UInt32 aFlashSourceAddress, UInt32 aDdrDestinationAddress,  UInt32 aLength)
+{
+	if(!cnc_spi_flash){
+		cnc_spi_flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_3);
+		if(!cnc_spi_flash) return 1;
+	}
+	return spi_flash_read(cnc_spi_flash, aFlashSourceAddress, aLength, (void *)aDdrDestinationAddress);
+}
+//-------------------------------------------------------------------------------
+int cnc_UsbStart(void)
+{
+	const char *pStep1[] = { "usb", "start"};
+	return do_usb ( NULL, 0, sizeof(pStep1)/sizeof(const char*) ,(char** const ) pStep1);
+}
+int cnc_UsbStop(void)
+{
+	const char *pStep7[] = { "usb", "stop"};
+	return do_usb ( NULL, 0, sizeof(pStep7)/sizeof(const char*) , (char** const )pStep7);
+}
+int cnc_LoadFileFromUsb(const char* pFileName, UInt32 aAddress, UInt32 * apFileSize)
+{
+	int status;
+	char DDR_STORAGE_ADDRESS[12]={0};
+	char filesize[12]={0};
+	const char *pStep2[] = { "fatload", "usb" , "0", DDR_STORAGE_ADDRESS , pFileName };
+
+	sprintf(DDR_STORAGE_ADDRESS,"%x", aAddress);
+
+	status = cnc_UsbStart();
+	if (status != 0 )
+	{
+		printf("ERROR: fail to mount USB drive, aborting...\n");
+		return -4;
+	}
+
+	status = do_fat_fsload( NULL, 0, sizeof(pStep2)/sizeof(const char*) ,(char** const ) pStep2);
+	if (status != 0 )
+	{
+		return -1;
+	}
+	strncpy(filesize, getenv("filesize"), sizeof(filesize) );
+	*apFileSize = simple_strtol( filesize, NULL,16);
+	if (*apFileSize < 1 )
+	{
+		printf("ERROR: File Error, count < 1, aborting...\n");
+		return -3;
+	}
+
+	status = cnc_UsbStop();
+	return status;
+}
+
+
+int Cnc_InPlaceDecryptOnlyImage(UInt32 aSrcDstAddress, UInt32 aLength)
+{
+	//"call_external_proc" , "DVU_" , "crypto" , "0x00000000", "0x00000000", "0x00000000" "deconly""
+	int status;
+
+	char argv0[20];
+	char argv1[8];
+	char argv2[8];
+	char argv3[16];
+	char argv4[16];
+	char argv5[16];
+	char argv6[16];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4,
+		argv5,
+		argv6
+	};
+
+	sprintf( argv0, "%s", "call_external_proc" );
+	sprintf( argv1, "%s", "DVU_" );
+	sprintf( argv2, "%s", "crypto" );
+	sprintf( argv3, "%08X", aSrcDstAddress );
+	sprintf( argv4, "%08X", aSrcDstAddress  );
+	sprintf( argv5, "%08X", aLength  );
+	sprintf( argv6, "%s", "deconly"  );
+
+	//printf("running:%s %s %s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4, argv5,argv6);
+	status=do_call_external_proc(NULL, 0,sizeof(argv)/sizeof(char *),(char** const ) argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+
+int Cnc_InPlaceDecryptOnlyImage_AES(UInt8 *KeyLadder, UInt32 aSrcDstAddress, UInt32 aLength)
+{
+	int status;
+
+	char argv0[20];
+	char argv1[8];
+	char argv2[8];
+	char argv3[16];
+	char argv4[16];
+	char argv5[16];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4,
+		argv5,
+	};
+
+	sprintf( argv0, "%s", "call_external_proc" );
+	sprintf( argv1, "%s", "DVU_" );
+	sprintf( argv2, "%s", "dec_aes" );
+	sprintf( argv3, "%08X", (unsigned int)KeyLadder );
+	sprintf( argv4, "%08X", aSrcDstAddress  );
+	sprintf( argv5, "%08X", aLength  );
+
+	//printf("running:%s %s %s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4, argv5,argv6);
+	status=do_call_external_proc(NULL, 0,sizeof(argv)/sizeof(char *),(char** const ) argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+	return status;
+}
+
+int Cnc_DecryptImage(UInt32 aSourceAddress, UInt32 aDestinationAddress, UInt32 aLength)
+{
+	//"call_external_proc" , "DVU_" , "crypto" , "0x00000000", "0x00000000", "0x00000000""
+	int status;
+
+	char argv0[20];
+	char argv1[8];
+	char argv2[8];
+	char argv3[16];
+	char argv4[16];
+	char argv5[16];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4,
+		argv5
+	};
+
+	sprintf( argv0, "%s", "call_external_proc" );
+	sprintf( argv1, "%s", "DVU_" );
+	sprintf( argv2, "%s", "crypto" );
+	sprintf( argv3, "%08X", aSourceAddress );
+	sprintf( argv4, "%08X", aDestinationAddress  );
+	sprintf( argv5, "%08X", aLength  );
+
+	//printf("running:%s %s %s %s %s %s\n", argv0, argv1, argv2, argv3, argv4, argv5);
+	status=do_call_external_proc(NULL, 0,sizeof(argv)/sizeof(char *), (char** const )argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+
+	return status;
+}
+int Cnc_DecryptImageGetHash(UInt32 aSourceAddress, UInt32 aDestinationAddress, UInt32 aLength,
+		UInt8* apHashBuf, int aHasBufLength)
+{
+	int status;
+
+	char argv0[20];
+	char argv1[8];
+	char argv2[8];
+	char argv3[16];
+	char argv4[16];
+	char argv5[16];
+	char argv6[16];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4,
+		argv5,
+		argv6
+	};
+
+	sprintf( argv0, "%s", "call_external_proc" );
+	sprintf( argv1, "%s", "DVU_" );
+	sprintf( argv2, "%s", "crypto" );
+	sprintf( argv3, "%08X", aSourceAddress );
+	sprintf( argv4, "%08X", aDestinationAddress  );
+	sprintf( argv5, "%08X", aLength  );
+	sprintf( argv6, "%08X", (UInt32) apHashBuf  );
+
+
+	//debug(ColorRed "running:%s %s %s %s %s %s %s\n" ColorNormal , argv0, argv1, argv2, argv3, argv4, argv5, argv6);
+	status=do_call_external_proc(NULL, 0,sizeof(argv)/sizeof(char *),(char** const ) argv);
+	//printf("Status - %s\n", (status ==0) ? "OK" : "Error");
+
+	//Cnc_DumpMemory(apHashBuf, aHasBufLength/sizeof(int) );
+
+	return status;
+}
+
+int cnc_Read_MtdPartition(const char *apMtdID, const char* apMtdPartitionName, UInt32 aDestinationAddress, UInt32 aLength /* 0xFFFFFFFF - to read comple region */ )
+{
+	int status;
+
+	char argv0[16];
+	char argv1[16];
+	char argv2[16];
+	char argv3[16];
+	char argv4[16];
+	char argv5[16];
+
+	char *argv[] = { argv0,
+		argv1,
+		argv2,
+		argv3,
+		argv4,
+		argv5
+	};
+
+	sprintf( argv0, "%s", "cncflash" );
+	sprintf( argv1, "%s", "read" );
+	sprintf( argv2, "%s", apMtdID );
+	sprintf( argv3, "%s", apMtdPartitionName );
+	sprintf( argv4, "%08X", aDestinationAddress  );
+	sprintf( argv5, "%08X", aLength  );
+
+	if ( 0xFFFFFFFF == aLength)
+	{
+		status = do_cncflash(NULL, 0, 5,(char** const ) argv);
+	}
+	else
+	{
+		status = do_cncflash(NULL, 0, 6, (char** const )argv);
+	}
+	return status;
+}
+
+/*
+ * Perform RSA verification on an image using a hybrid hashing input, No SW hashing here.
+ */
+int Cnc_ImgHybRsa_Verify (UInt8 hash[32], UInt32 asignAddress, UInt8 *publicKey)
+{
+	debug (" Uploading Public key ... \n");
+
+	/* Do hash of i/p Image */
+	UpdateExternalRSAKey(publicKey) ; // considered 2048 will generate 256 byte of public key only
+
+	printf ( "%s Verifying Image RSA signature... %s",ColorYellow, ColorNormal);
+
+	// debug only
+	debug ("sign buf addr %x\n", asignAddress);
+
+	int rt = HybridSignatureVerify( hash, (unsigned char *)asignAddress, RSA_PKCS_V15);
+
+	if (rt == 0)
+	{
+		printf ( "%s OK.\n%s" , ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf ( "%sFailed! Invalid Image.\n%s" , ColorRed, ColorNormal);
+		return -1;
+	}
+
+	return 0;
+}
+
+extern int otp_read_sha256(unsigned int *sha256);
+
+/*
+ *  Perform RSA verification on an image (deprecated)
+ */
+int ImgRsa_Verify (uint32_t aImgAddress, uint32_t aLen, uint32_t asignAddress, cnc_ImageType imageType)
+{
+	unsigned char Hash[32];
+	unsigned char OTP_Hash[32];
+
+	debug (" Uploading Public key ... \n");
+
+	/* Do hash of i/p Image */
+	if (imageType == RAW)
+	{
+		UpdateExternalRSAKey(blob_pkey) ;
+	}
+	else
+	{
+		UpdateExternalRSAKey(pkey) ; // considered 2048 will generate 256 byte of public key only
+	}
+
+	printf ( "%s Verifying Image RSA signature... %s",ColorYellow, ColorNormal);
+
+	// debug only
+	debug ("Img buf addr %x :: Img len : %x :: sign buf addr %x\n", aImgAddress, aLen, asignAddress);
+
+	int rt = SignatureVerify((unsigned char *)aImgAddress, aLen,
+			(unsigned char *)asignAddress, Hash, RSA_PKCS_V21);
+	if (rt == 0)
+	{
+		if (imageType == RAW)
+		{
+			otp_read_sha256((unsigned int*)OTP_Hash);
+			if (!memcmp(Hash, OTP_Hash, 32))
+			{
+				printf ( "%s OK.\n%s" , ColorGreen, ColorNormal);
+			}
+			else
+			{
+				printf ( "%sFailed! Hash mismatch, Invalid Blob.\n%s" , ColorRed, ColorNormal);
+				return -1;
+			}
+		}
+		else
+		{
+			printf ( "%s OK.\n%s" , ColorGreen, ColorNormal);
+		}
+	}
+	else
+	{
+		printf ( "%sFailed! Invalid Image.\n%s" , ColorRed, ColorNormal);
+		return -1;
+	}
+
+	return 0;
+}
+
+#define HW_REG_READ(addr)           (*((volatile unsigned int *)(addr)))
+#define SECURITY_CFG_ADDR           0xfffff010
+
+//returns 1 - if it is enabled.
+//returns 0 - if it is not enabled.
+unsigned int SecHWGetRSAEnable(void)
+{
+	unsigned int ret;
+	ret = HW_REG_READ(SECURITY_CFG_ADDR);
+	ret = (ret >> 3) & 0x1;
+	return ret ^ 0x1;
+}
+
+int ProgramAndVerify2Spi(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength )
+{
+	int Status = cnc_SpiErase(aFlashAddress, aLength); if( 0 != Status) return Status;
+	Status = cnc_SpiWrite(aDdrAddress , aFlashAddress, aLength); if( 0 != Status) return Status;
+	Status = cnc_SpiVerify(aDdrAddress, aFlashAddress, aLength);
+	if ( 0 == Status)
+	{
+		printf("%sSPI is programmed and verified successfully\n%s", ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf("%sERROR:Fail to verify SPI with programmed data, please check your hardware\n%s", ColorRed, ColorNormal);
+	}
+	return Status;
+}
+
+int ProgramAndVerify2Nand(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength)
+{
+	int Status = cnc_NandErase(aFlashAddress, aLength, 1); if( 0 != Status) return Status;
+	Status = cnc_NandWrite(aDdrAddress, aFlashAddress, aLength, RAW ); if( 0 != Status) return Status;
+	Status = cnc_NandVerify(aDdrAddress, aFlashAddress, aLength);
+	if ( 0 == Status)
+	{
+		printf("%sNAND is programmed and verified successfully\n%s", ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf("%sERROR:Fail to verify NAND with programmed data, please check your hardware\n%s", ColorRed, ColorNormal);
+	}
+	return Status;
+}
+
+int ProgramAndVerify2EMMC(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength)
+{
+	int Status;
+	//	Status = cnc_EMMCErase(aFlashAddress, aLength, 1); if( 0 != Status) return Status;
+	Status = cnc_EMMCWrite(aDdrAddress, aFlashAddress, aLength, RAW ); if( 0 != Status) return Status;
+	Status = cnc_EMMCVerify(aDdrAddress, aFlashAddress, aLength);
+	if ( 0 == Status)
+	{
+		printf("%seMMC is programmed and verified successfully\n%s", ColorGreen, ColorNormal);
+	}
+	else
+	{
+		printf("%sERROR:Fail to verify eMMC with programmed data, please check your hardware\n%s", ColorRed, ColorNormal);
+	}
+	return Status;
+}
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/command.c u-boot-2011.06/common/command.c
--- u-boot-2011.06_original/common/command.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/command.c	2014-07-29 17:28:38.819972000 +0800
@@ -142,6 +142,8 @@
 
 int cmd_usage(cmd_tbl_t *cmdtp)
 {
+	if (cmdtp == NULL ) return -1;
+	
 	printf("%s - %s\n\n", cmdtp->name, cmdtp->usage);
 
 #ifdef	CONFIG_SYS_LONGHELP
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/exports.c u-boot-2011.06/common/exports.c
--- u-boot-2011.06_original/common/exports.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/exports.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,5 +1,6 @@
 #include <common.h>
 #include <exports.h>
+#include <cnc_util.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/hush.c u-boot-2011.06/common/hush.c
--- u-boot-2011.06_original/common/hush.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/hush.c	2014-09-05 13:44:03.861705000 +0800
@@ -1091,6 +1091,11 @@
 
 /* This is the magic location that prints prompts
  * and gets data back from the user */
+#ifdef CONFIG_INPUT_WHITELIST
+
+CONFIG_INPUT_WHITELIST
+
+#endif
 static int file_get(struct in_str *i)
 {
 	int ch;
@@ -1108,7 +1113,24 @@
 #else
 			while(! i->p  || strlen(i->p)==0 ) {
 #endif
+#ifdef CONFIG_INPUT_WHITELIST
+				do{
+					char **ptr, *whitelist_env;
+					get_user_input(i);
+					whitelist_env = getenv("WHITELIST");
+					if(whitelist_env != NULL && simple_strtoul(whitelist_env, NULL, 10)){
+						for(ptr = &input_whitelist[0];*ptr; ptr++){
+							if(!strncmp(i->p, *ptr, min(strlen(i->p), strlen(*ptr)))) break;
+						}
+
+						if(*ptr) break;
+					}else{
+						break;
+					}
+				}while(1);
+#else
 				get_user_input(i);
+#endif
 			}
 			i->promptmode=2;
 #ifndef __U_BOOT__
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/image.c u-boot-2011.06/common/image.c
--- u-boot-2011.06_original/common/image.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/image.c	2014-10-30 20:54:29.112101000 +0800
@@ -181,8 +181,14 @@
 {
 	ulong data = image_get_data (hdr);
 	ulong len = image_get_data_size (hdr);
+#ifndef USE_HOSTCC
+	int dc = dcache_status();
+	dcache_enable();
+#endif
 	ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
-
+#ifndef USE_HOSTCC
+	if(!dc)dcache_disable();
+#endif
 	return (dcrc == image_get_dcrc (hdr));
 }
 
@@ -308,6 +314,7 @@
 	printf ("%sCreated:      ", p);
 	genimg_print_time ((time_t)image_get_time (hdr));
 #endif
+    printf ("%sImage Ver:    %d\n", p, image_get_ver (hdr));
 	printf ("%sImage Type:   ", p);
 	image_print_type (hdr);
 	printf ("%sData Size:    ", p);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/main.c u-boot-2011.06/common/main.c
--- u-boot-2011.06_original/common/main.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/main.c	2014-07-29 17:28:38.819972000 +0800
@@ -278,9 +278,11 @@
 	char *s;
 	int bootdelay;
 #endif
+
 #ifdef CONFIG_PREBOOT
 	char *p;
 #endif
+
 #ifdef CONFIG_BOOTCOUNT_LIMIT
 	unsigned long bootcount = 0;
 	unsigned long bootlimit = 0;
@@ -288,6 +290,9 @@
 	char bcs_set[16];
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
 
+	int AutoRunBootCmd=1;
+	char* AutoRunBootCmdNvram=NULL;
+
 #ifdef CONFIG_BOOTCOUNT_LIMIT
 	bootcount = bootcount_load();
 	bootcount++;
@@ -374,6 +379,12 @@
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
 		s = getenv ("bootcmd");
 
+	AutoRunBootCmdNvram = getenv("AUTORUN_BOOTCMD");
+	if (NULL != AutoRunBootCmdNvram )
+	{
+		AutoRunBootCmd = simple_strtol (AutoRunBootCmdNvram, NULL,0);
+	}
+	
 	debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
 
 	if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
@@ -384,8 +395,10 @@
 # ifndef CONFIG_SYS_HUSH_PARSER
 		run_command (s, 0);
 # else
-		parse_string_outer(s, FLAG_PARSE_SEMICOLON |
-				    FLAG_EXIT_FROM_LOOP);
+		if (1 == AutoRunBootCmd )
+		{
+			parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+		}
 # endif
 
 # ifdef CONFIG_AUTOBOOT_KEYED
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/Makefile u-boot-2011.06/common/Makefile
--- u-boot-2011.06_original/common/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/Makefile	2015-10-12 12:39:26.973494000 +0800
@@ -26,6 +26,7 @@
 LIB	= $(obj)libcommon.o
 
 # core
+COBJS-$(CONFIG_CNC1800L_TEST) += test.o
 COBJS-y += main.o
 COBJS-y += console.o
 COBJS-y += command.o
@@ -39,6 +40,19 @@
 COBJS-y += stdio.o
 COBJS-y += xyzModem.o
 
+COBJS-y += pkey.o
+COBJS-y += blob_pkey.o
+COBJS-y += cmd_cncflash.o
+COBJS-y += cmd_usb2nand.o
+COBJS-y += cmd_usb2spi.o
+COBJS-y += cmd_burnotp.o
+COBJS-y += cmd_ColorOnOff.o
+
+COBJS-y += cnc_util.o
+#COBJS-y += cmd_update_misc.o
+COBJS-$(CONFIG_CMD_SEC_NVEDIT) += cmd_sec_env.o
+
+
 # core command
 COBJS-y += cmd_boot.o
 COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
@@ -140,8 +154,10 @@
 COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
 COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o
 COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
+COBJS-$(CONFIG_CMD_SF_LEGACY) += cmd_sf_legacy.o
 COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o
 COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o
+COBJS-$(CONFIG_CMD_BOOTS) += cmd_boots.o
 COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o
 COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o
 COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o
@@ -151,14 +167,19 @@
 COBJS-$(CONFIG_CMD_TSI148) += cmd_tsi148.o
 COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o
 COBJS-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o
+COBJS-$(CONFIG_CMD_ANDR_BOOT) += cmd_andrboot.o
+COBJS-$(CONFIG_CMD_AUTO_BOOT) += cmd_autoboot.o
 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
 ifdef CONFIG_CMD_USB
 COBJS-y += cmd_usb.o
-COBJS-y += usb.o
+COBJS-y += usb.o usb_hub.o
 COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
+COBJS-$(CONFIG_AUTO_UPDATE) += cmd_update.o
+COBJS-$(CONFIG_CMD_UPGRADE) += cmd_upgrade.o
 endif
 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
+COBJS-$(CONFIG_CMD_SIMG) += cmd_simg.o
 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
 
 # others
@@ -173,6 +194,13 @@
 COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
+
+COBJS-$(CONFIG_CMD_CSLOGO) += cmd_cslogo.o
+COBJS-$(CONFIG_CMD_FPC) += cmd_fpc.o
+COBJS-$(CONFIG_CMD_CALL_EXTERNAL_PROC) += cmd_call_external_proc.o
+COBJS-$(CONFIG_CMD_CNC1900_OTP) += cmd_cnc1900_otp.o
+COBJS-$(CONFIG_CMD_CNC1900_AUDIO) += cmd_cnc1900_audio.o
 
 
 COBJS	:= $(sort $(COBJS-y))
@@ -189,12 +217,12 @@
 	$(call cmd_link_o_target, $(OBJS))
 
 $(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc
-	$(CC) $(AFLAGS) -Wa,--no-warn \
+	@$(CC) $(AFLAGS) -Wa,--no-warn \
 		-DENV_CRC=$(shell $(obj)../tools/envcrc) \
 		-c -o $@ $(src)env_embedded.c
 
 $(obj)../tools/envcrc:
-	$(MAKE) -C ../tools
+	@$(MAKE) -C ../tools
 
 #########################################################################
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/usb.c u-boot-2011.06/common/usb.c
--- u-boot-2011.06_original/common/usb.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/usb.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,5 +1,4 @@
 /*
- *
  * Most of this source has been derived from the Linux USB
  * project:
  * (C) Copyright Linus Torvalds 1999
@@ -15,24 +14,7 @@
  * Adapted for U-Boot:
  * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
  *
- * 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
- *
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 /*
@@ -47,83 +29,86 @@
 #include <common.h>
 #include <command.h>
 #include <asm/processor.h>
+#include <linux/compiler.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 #include <usb.h>
 #ifdef CONFIG_4xx
 #include <asm/4xx_pci.h>
 #endif
 
-#ifdef DEBUG
-#define USB_DEBUG
-#define USB_HUB_DEBUG
-#endif
-
-#ifdef	USB_DEBUG
-#define	USB_PRINTF(fmt, args...)	printf(fmt , ##args)
-#else
-#define USB_PRINTF(fmt, args...)
-#endif
-
 #define USB_BUFSIZ	512
 
 static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
-static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
-/**********************************************************************
- * some forward declerations...
- */
-void usb_scan_devices(void);
-
-int usb_hub_probe(struct usb_device *dev, int ifnum);
-void usb_hub_reset(void);
-static int hub_port_reset(struct usb_device *dev, int port,
-			  unsigned short *portstat);
-
-/***********************************************************************
- * wait_ms
- */
-
-inline void wait_ms(unsigned long ms)
-{
-	while (ms-- > 0)
-		udelay(1000);
-}
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#endif
 
 /***************************************************************************
  * Init USB Device
  */
-
 int usb_init(void)
 {
-	int result;
+	void *ctrl;
+	struct usb_device *dev;
+	int i, start_index = 0;
 
-	running = 0;
 	dev_index = 0;
 	asynch_allowed = 1;
 	usb_hub_reset();
+
+	/* first make all devices unknown */
+	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		memset(&usb_dev[i], 0, sizeof(struct usb_device));
+		usb_dev[i].devnum = -1;
+	}
+
 	/* init low_level USB */
-	printf("USB:   ");
-	result = usb_lowlevel_init();
-	/* if lowlevel init is OK, scan the bus for devices
-	 * i.e. search HUBs and configure them */
-	if (result == 0) {
-		printf("scanning bus for devices... ");
-		running = 1;
-		usb_scan_devices();
+	for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+		/* init low_level USB */
+		printf("USB%d:   ", i);
+		if (usb_lowlevel_init(i, &ctrl)) {
+			puts("lowlevel init failed\n");
+			continue;
+		}
+		/*
+		 * lowlevel init is OK, now scan the bus for devices
+		 * i.e. search HUBs and configure them
+		 */
+		start_index = dev_index;
+		printf("scanning bus %d for devices... ", i);
+		dev = usb_alloc_new_device(ctrl);
+		/*
+		 * device 0 is always present
+		 * (root hub, so let it analyze)
+		 */
+		if (dev)
+			usb_new_device(dev);
+
+		if (start_index == dev_index)
+			puts("No USB Device found\n");
+		else
+			printf("%d USB Device(s) found\n",
+				dev_index - start_index);
+
 		usb_started = 1;
-		return 0;
-	} else {
-		printf("Error, couldn't init Lowlevel part\n");
-		usb_started = 0;
+	}
+
+	debug("scan end\n");
+	/* if we were not able to find at least one working bus, bail out */
+	if (!usb_started) {
+		puts("USB error: all controllers failed lowlevel init\n");
 		return -1;
 	}
+
+	return 0;
 }
 
 /******************************************************************************
@@ -131,15 +116,20 @@
  */
 int usb_stop(void)
 {
-	int res = 0;
+	int i;
 
 	if (usb_started) {
 		asynch_allowed = 1;
 		usb_started = 0;
 		usb_hub_reset();
-		res = usb_lowlevel_stop();
+
+		for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+			if (usb_lowlevel_stop(i))
+				printf("failed to stop USB controller %d\n", i);
+		}
 	}
-	return res;
+
+	return 0;
 }
 
 /*
@@ -184,23 +174,26 @@
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1);
+
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
-	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
-		   "value 0x%X index 0x%X length 0x%X\n",
-		   request, requesttype, value, index, size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
+	debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
+	      "value 0x%X index 0x%X length 0x%X\n",
+	      request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0)
+		return -1;
 	if (timeout == 0)
 		return (int)size;
 
@@ -212,7 +205,7 @@
 	while (timeout--) {
 		if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
 			break;
-		wait_ms(1);
+		mdelay(1);
 	}
 	if (dev->status)
 		return -1;
@@ -232,11 +225,12 @@
 	if (len < 0)
 		return -1;
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
-	submit_bulk_msg(dev, pipe, data, len);
+	if (submit_bulk_msg(dev, pipe, data, len) < 0)
+		return -1;
 	while (timeout--) {
 		if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
 			break;
-		wait_ms(1);
+		mdelay(1);
 	}
 	*actual_length = dev->act_len;
 	if (dev->status == 0)
@@ -263,42 +257,50 @@
 		return dev->epmaxpacketin[((pipe>>15) & 0xf)];
 }
 
-/* The routine usb_set_maxpacket_ep() is extracted from the loop of routine
+/*
+ * The routine usb_set_maxpacket_ep() is extracted from the loop of routine
  * usb_set_maxpacket(), because the optimizer of GCC 4.x chokes on this routine
  * when it is inlined in 1 single routine. What happens is that the register r3
  * is used as loop-count 'i', but gets overwritten later on.
  * This is clearly a compiler bug, but it is easier to workaround it here than
  * to update the compiler (Occurs with at least several GCC 4.{1,2},x
  * CodeSourcery compilers like e.g. 2007q3, 2008q1, 2008q3 lite editions on ARM)
+ *
+ * NOTE: Similar behaviour was observed with GCC4.6 on ARMv5.
  */
-static void  __attribute__((noinline))
-usb_set_maxpacket_ep(struct usb_device *dev, struct usb_endpoint_descriptor *ep)
+static void noinline
+usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
 {
 	int b;
+	struct usb_endpoint_descriptor *ep;
+	u16 ep_wMaxPacketSize;
+
+	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
 
 	b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
 
 	if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 						USB_ENDPOINT_XFER_CONTROL) {
 		/* Control => bidirectional */
-		dev->epmaxpacketout[b] = ep->wMaxPacketSize;
-		dev->epmaxpacketin[b] = ep->wMaxPacketSize;
-		USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",
-			   b, dev->epmaxpacketin[b]);
+		dev->epmaxpacketout[b] = ep_wMaxPacketSize;
+		dev->epmaxpacketin[b] = ep_wMaxPacketSize;
+		debug("##Control EP epmaxpacketout/in[%d] = %d\n",
+		      b, dev->epmaxpacketin[b]);
 	} else {
 		if ((ep->bEndpointAddress & 0x80) == 0) {
 			/* OUT Endpoint */
-			if (ep->wMaxPacketSize > dev->epmaxpacketout[b]) {
-				dev->epmaxpacketout[b] = ep->wMaxPacketSize;
-				USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",
-					   b, dev->epmaxpacketout[b]);
+			if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
+				dev->epmaxpacketout[b] = ep_wMaxPacketSize;
+				debug("##EP epmaxpacketout[%d] = %d\n",
+				      b, dev->epmaxpacketout[b]);
 			}
 		} else {
 			/* IN Endpoint */
-			if (ep->wMaxPacketSize > dev->epmaxpacketin[b]) {
-				dev->epmaxpacketin[b] = ep->wMaxPacketSize;
-				USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",
-					   b, dev->epmaxpacketin[b]);
+			if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
+				dev->epmaxpacketin[b] = ep_wMaxPacketSize;
+				debug("##EP epmaxpacketin[%d] = %d\n",
+				      b, dev->epmaxpacketin[b]);
 			}
 		} /* if out */
 	} /* if control */
@@ -307,14 +309,13 @@
 /*
  * set the max packed value of all endpoints in the given configuration
  */
-int usb_set_maxpacket(struct usb_device *dev)
+static int usb_set_maxpacket(struct usb_device *dev)
 {
 	int i, ii;
 
 	for (i = 0; i < dev->config.desc.bNumInterfaces; i++)
 		for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++)
-			usb_set_maxpacket_ep(dev,
-					  &dev->config.if_desc[i].ep_desc[ii]);
+			usb_set_maxpacket_ep(dev, i, ii);
 
 	return 0;
 }
@@ -323,12 +324,13 @@
  * Parse the config, located in buffer, and fills the dev->config structure.
  * Note that all little/big endian swapping are done automatically.
  */
-int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
+static int usb_parse_config(struct usb_device *dev,
+			unsigned char *buffer, int cfgno)
 {
 	struct usb_descriptor_header *head;
 	int index, ifno, epno, curr_if_num;
-	int i;
-	unsigned char *ch;
+	u16 ep_wMaxPacketSize;
+	struct usb_interface *if_desc = NULL;
 
 	ifno = -1;
 	epno = -1;
@@ -356,41 +358,61 @@
 			     &buffer[index])->bInterfaceNumber != curr_if_num) {
 				/* this is a new interface, copy new desc */
 				ifno = dev->config.no_of_if;
+				if_desc = &dev->config.if_desc[ifno];
 				dev->config.no_of_if++;
-				memcpy(&dev->config.if_desc[ifno],
-					&buffer[index], buffer[index]);
-				dev->config.if_desc[ifno].no_of_ep = 0;
-				dev->config.if_desc[ifno].num_altsetting = 1;
+				memcpy(if_desc,	&buffer[index], buffer[index]);
+				if_desc->no_of_ep = 0;
+				if_desc->num_altsetting = 1;
 				curr_if_num =
-				     dev->config.if_desc[ifno].desc.bInterfaceNumber;
+				     if_desc->desc.bInterfaceNumber;
 			} else {
 				/* found alternate setting for the interface */
-				dev->config.if_desc[ifno].num_altsetting++;
+				if (ifno >= 0) {
+					if_desc = &dev->config.if_desc[ifno];
+					if_desc->num_altsetting++;
+				}
 			}
 			break;
 		case USB_DT_ENDPOINT:
 			epno = dev->config.if_desc[ifno].no_of_ep;
+			if_desc = &dev->config.if_desc[ifno];
 			/* found an endpoint */
-			dev->config.if_desc[ifno].no_of_ep++;
-			memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
+			if_desc->no_of_ep++;
+			memcpy(&if_desc->ep_desc[epno],
+				&buffer[index], buffer[index]);
+			ep_wMaxPacketSize = get_unaligned(&dev->config.\
+							if_desc[ifno].\
+							ep_desc[epno].\
+							wMaxPacketSize);
+			put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
+					&dev->config.\
+					if_desc[ifno].\
+					ep_desc[epno].\
+					wMaxPacketSize);
+			debug("if %d, ep %d\n", ifno, epno);
+			break;
+		case USB_DT_SS_ENDPOINT_COMP:
+			if_desc = &dev->config.if_desc[ifno];
+			memcpy(&if_desc->ss_ep_comp_desc[epno],
 				&buffer[index], buffer[index]);
-			le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].\
-							       wMaxPacketSize));
-			USB_PRINTF("if %d, ep %d\n", ifno, epno);
 			break;
 		default:
 			if (head->bLength == 0)
 				return 1;
 
-			USB_PRINTF("unknown Description Type : %x\n",
-				   head->bDescriptorType);
+			debug("unknown Description Type : %x\n",
+			      head->bDescriptorType);
 
+#ifdef DEBUG
 			{
-				ch = (unsigned char *)head;
+				unsigned char *ch = (unsigned char *)head;
+				int i;
+
 				for (i = 0; i < head->bLength; i++)
-					USB_PRINTF("%02X ", *ch++);
-				USB_PRINTF("\n\n\n");
+					debug("%02X ", *ch++);
+				debug("\n\n\n");
 			}
+#endif
 			break;
 		}
 		index += head->bLength;
@@ -433,7 +455,7 @@
 /**********************************************************************
  * get_descriptor type
  */
-int usb_get_descriptor(struct usb_device *dev, unsigned char type,
+static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
 			unsigned char index, void *buf, int size)
 {
 	int res;
@@ -452,9 +474,9 @@
 {
 	int result;
 	unsigned int tmp;
-	struct usb_configuration_descriptor *config;
+	struct usb_config_descriptor *config;
 
-	config = (struct usb_configuration_descriptor *)&buffer[0];
+	config = (struct usb_config_descriptor *)&buffer[0];
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
 	if (result < 9) {
 		if (result < 0)
@@ -468,14 +490,13 @@
 	tmp = le16_to_cpu(config->wTotalLength);
 
 	if (tmp > USB_BUFSIZ) {
-		USB_PRINTF("usb_get_configuration_no: failed to get " \
-			   "descriptor - too long: %d\n", tmp);
+		printf("usb_get_configuration_no: failed to get " \
+		       "descriptor - too long: %d\n", tmp);
 		return -1;
 	}
 
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
-	USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",
-		   cfgno, result, tmp);
+	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, tmp);
 	return result;
 }
 
@@ -483,11 +504,11 @@
  * set address of a device to the value in dev->devnum.
  * This can only be done by addressing the device via the default address (0)
  */
-int usb_set_address(struct usb_device *dev)
+static int usb_set_address(struct usb_device *dev)
 {
 	int res;
 
-	USB_PRINTF("set address %d\n", dev->devnum);
+	debug("set address %d\n", dev->devnum);
 	res = usb_control_msg(dev, usb_snddefctrl(dev),
 				USB_REQ_SET_ADDRESS, 0,
 				(dev->devnum), 0,
@@ -536,10 +557,10 @@
 /********************************************************************
  * set configuration number to configuration
  */
-int usb_set_configuration(struct usb_device *dev, int configuration)
+static int usb_set_configuration(struct usb_device *dev, int configuration)
 {
 	int res;
-	USB_PRINTF("set configuration %d\n", configuration);
+	debug("set configuration %d\n", configuration);
 	/* set setup command */
 	res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 				USB_REQ_SET_CONFIGURATION, 0,
@@ -599,7 +620,7 @@
 /********************************************************************
  * get string index in buffer
  */
-int usb_get_string(struct usb_device *dev, unsigned short langid,
+static int usb_get_string(struct usb_device *dev, unsigned short langid,
 		   unsigned char index, void *buf, int size)
 {
 	int i;
@@ -677,7 +698,7 @@
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -691,19 +712,19 @@
 	if (!dev->have_langid) {
 		err = usb_string_sub(dev, 0, 0, tbuf);
 		if (err < 0) {
-			USB_PRINTF("error getting string descriptor 0 " \
-				   "(error=%lx)\n", dev->status);
+			debug("error getting string descriptor 0 " \
+			      "(error=%lx)\n", dev->status);
 			return -1;
 		} else if (tbuf[0] < 4) {
-			USB_PRINTF("string descriptor 0 too short\n");
+			debug("string descriptor 0 too short\n");
 			return -1;
 		} else {
 			dev->have_langid = -1;
 			dev->string_langid = tbuf[2] | (tbuf[3] << 8);
 				/* always use the first langid listed */
-			USB_PRINTF("USB device number %d default " \
-				   "language ID 0x%x\n",
-				   dev->devnum, dev->string_langid);
+			debug("USB device number %d default " \
+			      "language ID 0x%x\n",
+			      dev->devnum, dev->string_langid);
 		}
 	}
 
@@ -743,14 +764,13 @@
 		return &usb_dev[index];
 }
 
-
 /* returns a pointer of a new device structure or NULL, if
  * no device struct is available
  */
-struct usb_device *usb_alloc_new_device(void)
+struct usb_device *usb_alloc_new_device(void *controller)
 {
 	int i;
-	USB_PRINTF("New Device %d\n", dev_index);
+	debug("New Device %d\n", dev_index);
 	if (dev_index == USB_MAX_DEVICE) {
 		printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
 		return NULL;
@@ -761,10 +781,23 @@
 	for (i = 0; i < USB_MAXCHILDREN; i++)
 		usb_dev[dev_index].children[i] = NULL;
 	usb_dev[dev_index].parent = NULL;
+	usb_dev[dev_index].controller = controller;
 	dev_index++;
 	return &usb_dev[dev_index - 1];
 }
 
+/*
+ * Free the newly created device node.
+ * Called in error cases where configuring a newly attached
+ * device fails for some reason.
+ */
+void usb_free_device(void)
+{
+	dev_index--;
+	debug("Freeing device node: %d\n", dev_index);
+	memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
+	usb_dev[dev_index].devnum = -1;
+}
 
 /*
  * By the time we get here, the device has gotten a new device ID
@@ -777,7 +810,7 @@
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -794,12 +827,13 @@
 	dev->epmaxpacketin[0] = 8;
 	dev->epmaxpacketout[0] = 8;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
+	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8);
 	if (err < 8) {
 		printf("\n      USB device not responding, " \
 		       "giving up (status=%lX)\n", dev->status);
 		return 1;
 	}
+	memcpy(&dev->descriptor, tmpbuf, 8);
 #else
 	/* This is a Windows scheme of initialization sequence, with double
 	 * reset of the device (Linux uses the same sequence)
@@ -827,11 +861,16 @@
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
 	if (err < 0) {
-		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
+		debug("usb_new_device: usb_get_descriptor() failed\n");
 		return 1;
 	}
 
 	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
+	/*
+	 * Fetch the device class, driver can use this info
+	 * to differentiate between HUB and DEVICE.
+	 */
+	dev->descriptor.bDeviceClass = desc->bDeviceClass;
 
 	/* find the port number we're at */
 	if (parent) {
@@ -883,12 +922,12 @@
 		return 1;
 	}
 
-	wait_ms(10);	/* Let the SET_ADDRESS settle */
+	mdelay(10);	/* Let the SET_ADDRESS settle */
 
 	tmp = sizeof(dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 &dev->descriptor, sizeof(dev->descriptor));
+				 tmpbuf, sizeof(dev->descriptor));
 	if (err < tmp) {
 		if (err < 0)
 			printf("unable to get device descriptor (error=%d)\n",
@@ -898,14 +937,21 @@
 				"(expected %i, got %i)\n", tmp, err);
 		return 1;
 	}
+	memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	err = usb_get_configuration_no(dev, tmpbuf, 0);
+	if (err < 0) {
+		printf("usb_new_device: Cannot read configuration, " \
+		       "skipping device %04x:%04x\n",
+		       dev->descriptor.idVendor, dev->descriptor.idProduct);
+		return -1;
+	}
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -913,9 +959,9 @@
 			"len %d, status %lX\n", dev->act_len, dev->status);
 		return -1;
 	}
-	USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
-		   dev->descriptor.iManufacturer, dev->descriptor.iProduct,
-		   dev->descriptor.iSerialNumber);
+	debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
+	      dev->descriptor.iManufacturer, dev->descriptor.iProduct,
+	      dev->descriptor.iSerialNumber);
 	memset(dev->mf, 0, sizeof(dev->mf));
 	memset(dev->prod, 0, sizeof(dev->prod));
 	memset(dev->serial, 0, sizeof(dev->serial));
@@ -928,461 +974,12 @@
 	if (dev->descriptor.iSerialNumber)
 		usb_string(dev, dev->descriptor.iSerialNumber,
 			   dev->serial, sizeof(dev->serial));
-	USB_PRINTF("Manufacturer %s\n", dev->mf);
-	USB_PRINTF("Product      %s\n", dev->prod);
-	USB_PRINTF("SerialNumber %s\n", dev->serial);
+	debug("Manufacturer %s\n", dev->mf);
+	debug("Product      %s\n", dev->prod);
+	debug("SerialNumber %s\n", dev->serial);
 	/* now prode if the device is a hub */
 	usb_hub_probe(dev, 0);
 	return 0;
 }
 
-/* build device Tree  */
-void usb_scan_devices(void)
-{
-	int i;
-	struct usb_device *dev;
-
-	/* first make all devices unknown */
-	for (i = 0; i < USB_MAX_DEVICE; i++) {
-		memset(&usb_dev[i], 0, sizeof(struct usb_device));
-		usb_dev[i].devnum = -1;
-	}
-	dev_index = 0;
-	/* device 0 is always present (root hub, so let it analyze) */
-	dev = usb_alloc_new_device();
-	if (usb_new_device(dev))
-		printf("No USB Device found\n");
-	else
-		printf("%d USB Device(s) found\n", dev_index);
-	/* insert "driver" if possible */
-#ifdef CONFIG_USB_KEYBOARD
-	drv_usb_kbd_init();
-	USB_PRINTF("scan end\n");
-#endif
-}
-
-
-/****************************************************************************
- * HUB "Driver"
- * Probes device for being a hub and configurate it
- */
-
-#ifdef	USB_HUB_DEBUG
-#define	USB_HUB_PRINTF(fmt, args...)	printf(fmt , ##args)
-#else
-#define USB_HUB_PRINTF(fmt, args...)
-#endif
-
-
-static struct usb_hub_device hub_dev[USB_MAX_HUB];
-static int usb_hub_index;
-
-
-int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
-{
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-		USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
-}
-
-int usb_clear_hub_feature(struct usb_device *dev, int feature)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-				USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature,
-				0, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-				USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
-				port, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_set_port_feature(struct usb_device *dev, int port, int feature)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-				USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
-				port, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_get_hub_status(struct usb_device *dev, void *data)
-{
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
-			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
-}
-
-int usb_get_port_status(struct usb_device *dev, int port, void *data)
-{
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
-			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
-}
-
-
-static void usb_hub_power_on(struct usb_hub_device *hub)
-{
-	int i;
-	struct usb_device *dev;
-
-	dev = hub->pusb_dev;
-	/* Enable power to the ports */
-	USB_HUB_PRINTF("enabling power on all ports\n");
-	for (i = 0; i < dev->maxchild; i++) {
-		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
-		USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status);
-		wait_ms(hub->desc.bPwrOn2PwrGood * 2);
-	}
-}
-
-void usb_hub_reset(void)
-{
-	usb_hub_index = 0;
-}
-
-struct usb_hub_device *usb_hub_allocate(void)
-{
-	if (usb_hub_index < USB_MAX_HUB)
-		return &hub_dev[usb_hub_index++];
-
-	printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
-	return NULL;
-}
-
-#define MAX_TRIES 5
-
-static inline char *portspeed(int portstatus)
-{
-	if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
-		return "480 Mb/s";
-	else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
-		return "1.5 Mb/s";
-	else
-		return "12 Mb/s";
-}
-
-static int hub_port_reset(struct usb_device *dev, int port,
-			unsigned short *portstat)
-{
-	int tries;
-	struct usb_port_status portsts;
-	unsigned short portstatus, portchange;
-
-	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
-	for (tries = 0; tries < MAX_TRIES; tries++) {
-
-		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
-		wait_ms(200);
-
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
-			USB_HUB_PRINTF("get_port_status failed status %lX\n",
-					dev->status);
-			return -1;
-		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
-
-		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
-				portstatus, portchange,
-				portspeed(portstatus));
-
-		USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \
-			       "  USB_PORT_STAT_ENABLE %d\n",
-			(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
-			(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
-			(portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
-
-		if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
-		    !(portstatus & USB_PORT_STAT_CONNECTION))
-			return -1;
-
-		if (portstatus & USB_PORT_STAT_ENABLE)
-			break;
-
-		wait_ms(200);
-	}
-
-	if (tries == MAX_TRIES) {
-		USB_HUB_PRINTF("Cannot enable port %i after %i retries, " \
-				"disabling port.\n", port + 1, MAX_TRIES);
-		USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
-		return -1;
-	}
-
-	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
-	*portstat = portstatus;
-	return 0;
-}
-
-
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
-{
-	struct usb_device *usb;
-	struct usb_port_status portsts;
-	unsigned short portstatus, portchange;
-
-	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
-		USB_HUB_PRINTF("get_port_status failed\n");
-		return;
-	}
-
-	portstatus = le16_to_cpu(portsts.wPortStatus);
-	portchange = le16_to_cpu(portsts.wPortChange);
-	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
-			portstatus, portchange, portspeed(portstatus));
-
-	/* Clear the connection change status */
-	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
-
-	/* Disconnect any existing devices under this port */
-	if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
-	     (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
-		USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n");
-		/* Return now if nothing is connected */
-		if (!(portstatus & USB_PORT_STAT_CONNECTION))
-			return;
-	}
-	wait_ms(200);
-
-	/* Reset the port */
-	if (hub_port_reset(dev, port, &portstatus) < 0) {
-		printf("cannot reset port %i!?\n", port + 1);
-		return;
-	}
-
-	wait_ms(200);
-
-	/* Allocate a new device struct for it */
-	usb = usb_alloc_new_device();
-
-	if (portstatus & USB_PORT_STAT_HIGH_SPEED)
-		usb->speed = USB_SPEED_HIGH;
-	else if (portstatus & USB_PORT_STAT_LOW_SPEED)
-		usb->speed = USB_SPEED_LOW;
-	else
-		usb->speed = USB_SPEED_FULL;
-
-	dev->children[port] = usb;
-	usb->parent = dev;
-	/* Run it through the hoops (find a driver, etc) */
-	if (usb_new_device(usb)) {
-		/* Woops, disable the port */
-		USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
-		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
-	}
-}
-
-
-int usb_hub_configure(struct usb_device *dev)
-{
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
-	struct usb_hub_descriptor *descriptor;
-	struct usb_hub_status *hubsts;
-	int i;
-	struct usb_hub_device *hub;
-
-	/* "allocate" Hub device */
-	hub = usb_hub_allocate();
-	if (hub == NULL)
-		return -1;
-	hub->pusb_dev = dev;
-	/* Get the the hub descriptor */
-	if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
-		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
-				   "descriptor, giving up %lX\n", dev->status);
-		return -1;
-	}
-	descriptor = (struct usb_hub_descriptor *)buffer;
-
-	/* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */
-	i = descriptor->bLength;
-	if (i > USB_BUFSIZ) {
-		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
-				"descriptor - too long: %d\n",
-				descriptor->bLength);
-		return -1;
-	}
-
-	if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) {
-		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
-				"descriptor 2nd giving up %lX\n", dev->status);
-		return -1;
-	}
-	memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength);
-	/* adjust 16bit values */
-	hub->desc.wHubCharacteristics =
-				le16_to_cpu(descriptor->wHubCharacteristics);
-	/* set the bitmap */
-	bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
-	/* devices not removable by default */
-	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
-	bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
-	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
-
-	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-		hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
-
-	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-		hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
-
-	dev->maxchild = descriptor->bNbrPorts;
-	USB_HUB_PRINTF("%d ports detected\n", dev->maxchild);
-
-	switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) {
-	case 0x00:
-		USB_HUB_PRINTF("ganged power switching\n");
-		break;
-	case 0x01:
-		USB_HUB_PRINTF("individual port power switching\n");
-		break;
-	case 0x02:
-	case 0x03:
-		USB_HUB_PRINTF("unknown reserved power switching mode\n");
-		break;
-	}
-
-	if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND)
-		USB_HUB_PRINTF("part of a compound device\n");
-	else
-		USB_HUB_PRINTF("standalone hub\n");
-
-	switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) {
-	case 0x00:
-		USB_HUB_PRINTF("global over-current protection\n");
-		break;
-	case 0x08:
-		USB_HUB_PRINTF("individual port over-current protection\n");
-		break;
-	case 0x10:
-	case 0x18:
-		USB_HUB_PRINTF("no over-current protection\n");
-		break;
-	}
-
-	USB_HUB_PRINTF("power on to power good time: %dms\n",
-			descriptor->bPwrOn2PwrGood * 2);
-	USB_HUB_PRINTF("hub controller current requirement: %dmA\n",
-			descriptor->bHubContrCurrent);
-
-	for (i = 0; i < dev->maxchild; i++)
-		USB_HUB_PRINTF("port %d is%s removable\n", i + 1,
-			hub->desc.DeviceRemovable[(i + 1) / 8] & \
-					   (1 << ((i + 1) % 8)) ? " not" : "");
-
-	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
-		USB_HUB_PRINTF("usb_hub_configure: failed to get Status - " \
-				"too long: %d\n", descriptor->bLength);
-		return -1;
-	}
-
-	if (usb_get_hub_status(dev, buffer) < 0) {
-		USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
-				dev->status);
-		return -1;
-	}
-
-	hubsts = (struct usb_hub_status *)buffer;
-	USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n",
-			le16_to_cpu(hubsts->wHubStatus),
-			le16_to_cpu(hubsts->wHubChange));
-	USB_HUB_PRINTF("local power source is %s\n",
-		(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \
-		"lost (inactive)" : "good");
-	USB_HUB_PRINTF("%sover-current condition exists\n",
-		(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
-		"" : "no ");
-	usb_hub_power_on(hub);
-
-	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
-		unsigned short portstatus, portchange;
-
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
-			USB_HUB_PRINTF("get_port_status failed\n");
-			continue;
-		}
-
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
-		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
-				i + 1, portstatus, portchange);
-
-		if (portchange & USB_PORT_STAT_C_CONNECTION) {
-			USB_HUB_PRINTF("port %d connection change\n", i + 1);
-			usb_hub_port_connect_change(dev, i);
-		}
-		if (portchange & USB_PORT_STAT_C_ENABLE) {
-			USB_HUB_PRINTF("port %d enable change, status %x\n",
-					i + 1, portstatus);
-			usb_clear_port_feature(dev, i + 1,
-						USB_PORT_FEAT_C_ENABLE);
-
-			/* EM interference sometimes causes bad shielded USB
-			 * devices to be shutdown by the hub, this hack enables
-			 * them again. Works at least with mouse driver */
-			if (!(portstatus & USB_PORT_STAT_ENABLE) &&
-			     (portstatus & USB_PORT_STAT_CONNECTION) &&
-			     ((dev->children[i]))) {
-				USB_HUB_PRINTF("already running port %i "  \
-						"disabled by hub (EMI?), " \
-						"re-enabling...\n", i + 1);
-					usb_hub_port_connect_change(dev, i);
-			}
-		}
-		if (portstatus & USB_PORT_STAT_SUSPEND) {
-			USB_HUB_PRINTF("port %d suspend change\n", i + 1);
-			usb_clear_port_feature(dev, i + 1,
-						USB_PORT_FEAT_SUSPEND);
-		}
-
-		if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
-			USB_HUB_PRINTF("port %d over-current change\n", i + 1);
-			usb_clear_port_feature(dev, i + 1,
-						USB_PORT_FEAT_C_OVER_CURRENT);
-			usb_hub_power_on(hub);
-		}
-
-		if (portchange & USB_PORT_STAT_C_RESET) {
-			USB_HUB_PRINTF("port %d reset change\n", i + 1);
-			usb_clear_port_feature(dev, i + 1,
-						USB_PORT_FEAT_C_RESET);
-		}
-	} /* end for i all ports */
-
-	return 0;
-}
-
-int usb_hub_probe(struct usb_device *dev, int ifnum)
-{
-	struct usb_interface *iface;
-	struct usb_endpoint_descriptor *ep;
-	int ret;
-
-	iface = &dev->config.if_desc[ifnum];
-	/* Is it a hub? */
-	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
-		return 0;
-	/* Some hubs have a subclass of 1, which AFAICT according to the */
-	/*  specs is not defined, but it works */
-	if ((iface->desc.bInterfaceSubClass != 0) &&
-	    (iface->desc.bInterfaceSubClass != 1))
-		return 0;
-	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (iface->desc.bNumEndpoints != 1)
-		return 0;
-	ep = &iface->ep_desc[0];
-	/* Output endpoint? Curiousier and curiousier.. */
-	if (!(ep->bEndpointAddress & USB_DIR_IN))
-		return 0;
-	/* If it's not an interrupt endpoint, we'd better punt! */
-	if ((ep->bmAttributes & 3) != 3)
-		return 0;
-	/* We found a hub */
-	USB_HUB_PRINTF("USB hub found\n");
-	ret = usb_hub_configure(dev);
-	return ret;
-}
-
 /* EOF */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/usb_hub.c u-boot-2011.06/common/usb_hub.c
--- u-boot-2011.06_original/common/usb_hub.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/common/usb_hub.c	2014-08-28 18:12:18.974057000 +0800
@@ -0,0 +1,549 @@
+/*
+ * Most of this source has been derived from the Linux USB
+ * project:
+ * (C) Copyright Linus Torvalds 1999
+ * (C) Copyright Johannes Erdfelt 1999-2001
+ * (C) Copyright Andreas Gal 1999
+ * (C) Copyright Gregory P. Smith 1999
+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
+ * (C) Copyright Randy Dunlap 2000
+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
+ * (C) Copyright Yggdrasil Computing, Inc. 2000
+ *     (usb_device_id matching changes by Adam J. Richter)
+ *
+ * Adapted for U-Boot:
+ * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/****************************************************************************
+ * HUB "Driver"
+ * Probes device for being a hub and configurate it
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <asm/unaligned.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#include <usb.h>
+#ifdef CONFIG_4xx
+#include <asm/4xx_pci.h>
+#endif
+
+#define USB_BUFSIZ	512
+
+static struct usb_hub_device hub_dev[USB_MAX_HUB];
+static int usb_hub_index;
+
+__weak void usb_hub_reset_devices(int port)
+{
+	return;
+}
+
+static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
+		USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+}
+
+static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+				USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
+				port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+				USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
+				port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+static int usb_get_hub_status(struct usb_device *dev, void *data)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
+			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+static int usb_get_port_status(struct usb_device *dev, int port, void *data)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
+			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+
+static void usb_hub_power_on(struct usb_hub_device *hub)
+{
+	int i;
+	struct usb_device *dev;
+	unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
+	unsigned short portstatus;
+	int ret;
+
+	dev = hub->pusb_dev;
+
+	/*
+	 * Enable power to the ports:
+	 * Here we Power-cycle the ports: aka,
+	 * turning them off and turning on again.
+	 */
+	debug("enabling power on all ports\n");
+	for (i = 0; i < dev->maxchild; i++) {
+		usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+		debug("port %d returns %lX\n", i + 1, dev->status);
+	}
+
+	/* Wait at least 2*bPwrOn2PwrGood for PP to change */
+	mdelay(pgood_delay);
+
+	for (i = 0; i < dev->maxchild; i++) {
+		ret = usb_get_port_status(dev, i + 1, portsts);
+		if (ret < 0) {
+			debug("port %d: get_port_status failed\n", i + 1);
+			continue;
+		}
+
+		/*
+		 * Check to confirm the state of Port Power:
+		 * xHCI says "After modifying PP, s/w shall read
+		 * PP and confirm that it has reached the desired state
+		 * before modifying it again, undefined behavior may occur
+		 * if this procedure is not followed".
+		 * EHCI doesn't say anything like this, but no harm in keeping
+		 * this.
+		 */
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		if (portstatus & (USB_PORT_STAT_POWER << 1)) {
+			debug("port %d: Port power change failed\n", i + 1);
+			continue;
+		}
+	}
+
+	for (i = 0; i < dev->maxchild; i++) {
+		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+		debug("port %d returns %lX\n", i + 1, dev->status);
+	}
+
+	/*
+	 * Wait for power to become stable,
+	 * plus spec-defined max time for device to connect
+	 */
+	mdelay(pgood_delay + 1000);
+}
+
+void usb_hub_reset(void)
+{
+	usb_hub_index = 0;
+}
+
+static struct usb_hub_device *usb_hub_allocate(void)
+{
+	if (usb_hub_index < USB_MAX_HUB)
+		return &hub_dev[usb_hub_index++];
+
+	printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
+	return NULL;
+}
+
+#define MAX_TRIES 5
+
+static inline char *portspeed(int portstatus)
+{
+	char *speed_str;
+
+	switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
+	case USB_PORT_STAT_SUPER_SPEED:
+		speed_str = "5 Gb/s";
+		break;
+	case USB_PORT_STAT_HIGH_SPEED:
+		speed_str = "480 Mb/s";
+		break;
+	case USB_PORT_STAT_LOW_SPEED:
+		speed_str = "1.5 Mb/s";
+		break;
+	default:
+		speed_str = "12 Mb/s";
+		break;
+	}
+
+	return speed_str;
+}
+
+int hub_port_reset(struct usb_device *dev, int port,
+			unsigned short *portstat)
+{
+	int tries;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
+	unsigned short portstatus, portchange;
+
+	debug("hub_port_reset: resetting port %d...\n", port);
+	for (tries = 0; tries < MAX_TRIES; tries++) {
+
+		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
+		mdelay(200);
+
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
+			debug("get_port_status failed status %lX\n",
+			      dev->status);
+			return -1;
+		}
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
+
+		debug("portstatus %x, change %x, %s\n", portstatus, portchange,
+							portspeed(portstatus));
+
+		debug("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \
+		      "  USB_PORT_STAT_ENABLE %d\n",
+		      (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
+		      (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
+		      (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
+
+		if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
+		    !(portstatus & USB_PORT_STAT_CONNECTION))
+			return -1;
+
+		if (portstatus & USB_PORT_STAT_ENABLE)
+			break;
+
+		mdelay(200);
+	}
+
+	if (tries == MAX_TRIES) {
+		debug("Cannot enable port %i after %i retries, " \
+		      "disabling port.\n", port + 1, MAX_TRIES);
+		debug("Maybe the USB cable is bad?\n");
+		return -1;
+	}
+
+	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
+	*portstat = portstatus;
+	return 0;
+}
+
+
+void usb_hub_port_connect_change(struct usb_device *dev, int port)
+{
+	struct usb_device *usb;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
+	unsigned short portstatus;
+
+	/* Check status */
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
+		debug("get_port_status failed\n");
+		return;
+	}
+
+	portstatus = le16_to_cpu(portsts->wPortStatus);
+	debug("portstatus %x, change %x, %s\n",
+	      portstatus,
+	      le16_to_cpu(portsts->wPortChange),
+	      portspeed(portstatus));
+
+	/* Clear the connection change status */
+	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
+
+	/* Disconnect any existing devices under this port */
+	if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
+	     (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
+		debug("usb_disconnect(&hub->children[port]);\n");
+		/* Return now if nothing is connected */
+		if (!(portstatus & USB_PORT_STAT_CONNECTION))
+			return;
+	}
+	mdelay(200);
+
+	/* Reset the port */
+	if (hub_port_reset(dev, port, &portstatus) < 0) {
+		printf("cannot reset port %i!?\n", port + 1);
+		return;
+	}
+
+	mdelay(200);
+
+	/* Allocate a new device struct for it */
+	usb = usb_alloc_new_device(dev->controller);
+
+	switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
+	case USB_PORT_STAT_SUPER_SPEED:
+		usb->speed = USB_SPEED_SUPER;
+		break;
+	case USB_PORT_STAT_HIGH_SPEED:
+		usb->speed = USB_SPEED_HIGH;
+		break;
+	case USB_PORT_STAT_LOW_SPEED:
+		usb->speed = USB_SPEED_LOW;
+		break;
+	default:
+		usb->speed = USB_SPEED_FULL;
+		break;
+	}
+
+	dev->children[port] = usb;
+	usb->parent = dev;
+	usb->portnr = port + 1;
+	/* Run it through the hoops (find a driver, etc) */
+	if (usb_new_device(usb)) {
+		/* Woops, disable the port */
+		usb_free_device();
+		dev->children[port] = NULL;
+		debug("hub: disabling port %d\n", port + 1);
+		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
+	}
+}
+
+
+static int usb_hub_configure(struct usb_device *dev)
+{
+	int i, length;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
+	short hubCharacteristics;
+	struct usb_hub_descriptor *descriptor;
+	struct usb_hub_device *hub;
+	__maybe_unused struct usb_hub_status *hubsts;
+
+	/* "allocate" Hub device */
+	hub = usb_hub_allocate();
+	if (hub == NULL)
+		return -1;
+	hub->pusb_dev = dev;
+	/* Get the the hub descriptor */
+	if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+		debug("usb_hub_configure: failed to get hub " \
+		      "descriptor, giving up %lX\n", dev->status);
+		return -1;
+	}
+	descriptor = (struct usb_hub_descriptor *)buffer;
+
+	length = min(descriptor->bLength, sizeof(struct usb_hub_descriptor));
+
+	if (usb_get_hub_descriptor(dev, buffer, length) < 0) {
+		debug("usb_hub_configure: failed to get hub " \
+		      "descriptor 2nd giving up %lX\n", dev->status);
+		return -1;
+	}
+	memcpy((unsigned char *)&hub->desc, buffer, length);
+	/* adjust 16bit values */
+	put_unaligned(le16_to_cpu(get_unaligned(
+			&descriptor->wHubCharacteristics)),
+			&hub->desc.wHubCharacteristics);
+	/* set the bitmap */
+	bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
+	/* devices not removable by default */
+	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
+	bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
+	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
+
+	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
+		hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
+
+	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
+		hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
+
+	dev->maxchild = descriptor->bNbrPorts;
+	debug("%d ports detected\n", dev->maxchild);
+
+	hubCharacteristics = get_unaligned(&hub->desc.wHubCharacteristics);
+	switch (hubCharacteristics & HUB_CHAR_LPSM) {
+	case 0x00:
+		debug("ganged power switching\n");
+		break;
+	case 0x01:
+		debug("individual port power switching\n");
+		break;
+	case 0x02:
+	case 0x03:
+		debug("unknown reserved power switching mode\n");
+		break;
+	}
+
+	if (hubCharacteristics & HUB_CHAR_COMPOUND)
+		debug("part of a compound device\n");
+	else
+		debug("standalone hub\n");
+
+	switch (hubCharacteristics & HUB_CHAR_OCPM) {
+	case 0x00:
+		debug("global over-current protection\n");
+		break;
+	case 0x08:
+		debug("individual port over-current protection\n");
+		break;
+	case 0x10:
+	case 0x18:
+		debug("no over-current protection\n");
+		break;
+	}
+
+	debug("power on to power good time: %dms\n",
+	      descriptor->bPwrOn2PwrGood * 2);
+	debug("hub controller current requirement: %dmA\n",
+	      descriptor->bHubContrCurrent);
+
+	for (i = 0; i < dev->maxchild; i++)
+		debug("port %d is%s removable\n", i + 1,
+		      hub->desc.DeviceRemovable[(i + 1) / 8] & \
+		      (1 << ((i + 1) % 8)) ? " not" : "");
+
+	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
+		debug("usb_hub_configure: failed to get Status - " \
+		      "too long: %d\n", descriptor->bLength);
+		return -1;
+	}
+
+	if (usb_get_hub_status(dev, buffer) < 0) {
+		debug("usb_hub_configure: failed to get Status %lX\n",
+		      dev->status);
+		return -1;
+	}
+
+#ifdef DEBUG
+	hubsts = (struct usb_hub_status *)buffer;
+#endif
+
+	debug("get_hub_status returned status %X, change %X\n",
+	      le16_to_cpu(hubsts->wHubStatus),
+	      le16_to_cpu(hubsts->wHubChange));
+	debug("local power source is %s\n",
+	      (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \
+	      "lost (inactive)" : "good");
+	debug("%sover-current condition exists\n",
+	      (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
+	      "" : "no ");
+	usb_hub_power_on(hub);
+
+	/*
+	 * Reset any devices that may be in a bad state when applying
+	 * the power.  This is a __weak function.  Resetting of the devices
+	 * should occur in the board file of the device.
+	 */
+	for (i = 0; i < dev->maxchild; i++)
+		usb_hub_reset_devices(i + 1);
+
+	for (i = 0; i < dev->maxchild; i++) {
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
+		unsigned short portstatus, portchange;
+		int ret;
+		ulong start = get_timer(0);
+
+		/*
+		 * Wait for (whichever finishes first)
+		 *  - A maximum of 10 seconds
+		 *    This is a purely observational value driven by connecting
+		 *    a few broken pen drives and taking the max * 1.5 approach
+		 *  - connection_change and connection state to report same
+		 *    state
+		 */
+		do {
+			ret = usb_get_port_status(dev, i + 1, portsts);
+			if (ret < 0) {
+				debug("get_port_status failed\n");
+				break;
+			}
+
+			portstatus = le16_to_cpu(portsts->wPortStatus);
+			portchange = le16_to_cpu(portsts->wPortChange);
+
+			if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
+				(portstatus & USB_PORT_STAT_CONNECTION))
+				break;
+
+		} while (get_timer(start) < CONFIG_SYS_HZ * 10);
+
+		if (ret < 0)
+			continue;
+
+		debug("Port %d Status %X Change %X\n",
+		      i + 1, portstatus, portchange);
+
+		if (portchange & USB_PORT_STAT_C_CONNECTION) {
+			debug("port %d connection change\n", i + 1);
+			usb_hub_port_connect_change(dev, i);
+		}
+		if (portchange & USB_PORT_STAT_C_ENABLE) {
+			debug("port %d enable change, status %x\n",
+			      i + 1, portstatus);
+			usb_clear_port_feature(dev, i + 1,
+						USB_PORT_FEAT_C_ENABLE);
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
+			/* EM interference sometimes causes bad shielded USB
+			 * devices to be shutdown by the hub, this hack enables
+			 * them again. Works at least with mouse driver */
+			if (!(portstatus & USB_PORT_STAT_ENABLE) &&
+			     (portstatus & USB_PORT_STAT_CONNECTION) &&
+			     ((dev->children[i]))) {
+				debug("already running port %i "  \
+				      "disabled by hub (EMI?), " \
+				      "re-enabling...\n", i + 1);
+				      usb_hub_port_connect_change(dev, i);
+			}
+#endif
+		}
+		if (portstatus & USB_PORT_STAT_SUSPEND) {
+			debug("port %d suspend change\n", i + 1);
+			usb_clear_port_feature(dev, i + 1,
+						USB_PORT_FEAT_SUSPEND);
+		}
+
+		if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
+			debug("port %d over-current change\n", i + 1);
+			usb_clear_port_feature(dev, i + 1,
+						USB_PORT_FEAT_C_OVER_CURRENT);
+			usb_hub_power_on(hub);
+		}
+
+		if (portchange & USB_PORT_STAT_C_RESET) {
+			debug("port %d reset change\n", i + 1);
+			usb_clear_port_feature(dev, i + 1,
+						USB_PORT_FEAT_C_RESET);
+		}
+	} /* end for i all ports */
+
+	return 0;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+	struct usb_interface *iface;
+	struct usb_endpoint_descriptor *ep;
+	int ret;
+
+	iface = &dev->config.if_desc[ifnum];
+	/* Is it a hub? */
+	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
+		return 0;
+	/* Some hubs have a subclass of 1, which AFAICT according to the */
+	/*  specs is not defined, but it works */
+	if ((iface->desc.bInterfaceSubClass != 0) &&
+	    (iface->desc.bInterfaceSubClass != 1))
+		return 0;
+	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
+	if (iface->desc.bNumEndpoints != 1)
+		return 0;
+	ep = &iface->ep_desc[0];
+	/* Output endpoint? Curiousier and curiousier.. */
+	if (!(ep->bEndpointAddress & USB_DIR_IN))
+		return 0;
+	/* If it's not an interrupt endpoint, we'd better punt! */
+	if ((ep->bmAttributes & 3) != 3)
+		return 0;
+	/* We found a hub */
+	debug("USB hub found\n");
+	ret = usb_hub_configure(dev);
+	return ret;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/usb_storage.c u-boot-2011.06/common/usb_storage.c
--- u-boot-2011.06_original/common/usb_storage.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/usb_storage.c	2014-08-28 12:42:22.909123000 +0800
@@ -16,24 +16,7 @@
  * BBB support based on /sys/dev/usb/umass.c from
  * FreeBSD.
  *
- * 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
- *
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 /* Note:
@@ -56,16 +39,9 @@
 #include <part.h>
 #include <usb.h>
 
-#undef USB_STOR_DEBUG
 #undef BBB_COMDAT_TRACE
 #undef BBB_XPORT_TRACE
 
-#ifdef	USB_STOR_DEBUG
-#define USB_STOR_PRINTF(fmt, args...)	printf(fmt , ##args)
-#else
-#define USB_STOR_PRINTF(fmt, args...)
-#endif
-
 #include <scsi.h>
 /* direction table -- this indicates the direction of the data
  * transfer for each command code -- a 1 indicates input
@@ -78,8 +54,7 @@
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -136,6 +111,7 @@
 	struct usb_device *pusb_dev;	 /* this usb_device */
 
 	unsigned int	flags;			/* from filter initially */
+#	define USB_READY	(1 << 0)
 	unsigned char	ifnum;			/* interface number */
 	unsigned char	ep_in;			/* in endpoint */
 	unsigned char	ep_out;			/* out ....... */
@@ -155,6 +131,17 @@
 	trans_cmnd	transport;		/* transport routine */
 };
 
+#ifdef CONFIG_USB_EHCI
+/*
+ * The U-Boot EHCI driver can handle any transfer length as long as there is
+ * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are
+ * limited to 65535 blocks.
+ */
+#define USB_MAX_XFER_BLK	10240
+#else
+#define USB_MAX_XFER_BLK	20
+#endif
+
 static struct us_data usb_stor[USB_MAX_STOR_DEV];
 
 
@@ -166,20 +153,21 @@
 		      block_dev_desc_t *dev_desc);
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss);
-unsigned long usb_stor_read(int device, unsigned long blknr,
-			    unsigned long blkcnt, void *buffer);
-unsigned long usb_stor_write(int device, unsigned long blknr,
-			     unsigned long blkcnt, const void *buffer);
+unsigned long usb_stor_read(int device, lbaint_t blknr,
+			    lbaint_t blkcnt, void *buffer);
+unsigned long usb_stor_write(int device, lbaint_t blknr,
+			     lbaint_t blkcnt, const void *buffer);
 struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
 
+#ifdef CONFIG_PARTITIONS
 block_dev_desc_t *usb_stor_get_dev(int index)
 {
 	return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
 }
+#endif
 
-
-void usb_show_progress(void)
+static void usb_show_progress(void)
 {
 	debug(".");
 }
@@ -207,17 +195,16 @@
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
-	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+	debug("Get Max LUN -> len = %i, result = %i\n", len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -230,11 +217,8 @@
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
-		printf("       scanning bus for storage devices... ");
+		printf("       scanning usb for storage devices... ");
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 
@@ -252,7 +236,7 @@
 	usb_max_devs = 0;
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
 		dev = usb_get_dev_index(i); /* get device */
-		USB_STOR_PRINTF("i=%d\n", i);
+		debug("i=%d\n", i);
 		if (dev == NULL)
 			break; /* no more devices available */
 
@@ -268,9 +252,9 @@
 			     lun++) {
 				usb_dev_desc[usb_max_devs].lun = lun;
 				if (usb_stor_get_info(dev, &usb_stor[start],
-						      &usb_dev_desc[usb_max_devs]) == 1) {
-				usb_max_devs++;
-		}
+				    &usb_dev_desc[usb_max_devs]) == 1) {
+					usb_max_devs++;
+				}
 			}
 		}
 		/* if storage device */
@@ -299,7 +283,7 @@
 }
 
 
-#ifdef	USB_STOR_DEBUG
+#ifdef	DEBUG
 
 static void usb_show_srb(ccb *pccb)
 {
@@ -351,45 +335,49 @@
 		/* set up the transfer loop */
 		do {
 			/* transfer the data */
-			USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
-				  (unsigned int)buf, this_xfer, 11 - maxtry);
+			debug("Bulk xfer 0x%x(%d) try #%d\n",
+			      (unsigned int)buf, this_xfer, 11 - maxtry);
 			result = usb_bulk_msg(us->pusb_dev, pipe, buf,
 					      this_xfer, &partial,
 					      USB_CNTL_TIMEOUT * 5);
-			USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
-				  result, partial, this_xfer);
+			debug("bulk_msg returned %d xferred %d/%d\n",
+			      result, partial, this_xfer);
 			if (us->pusb_dev->status != 0) {
 				/* if we stall, we need to clear it before
 				 * we go on
 				 */
-#ifdef USB_STOR_DEBUG
+#ifdef DEBUG
 				display_int_status(us->pusb_dev->status);
 #endif
 				if (us->pusb_dev->status & USB_ST_STALLED) {
-					USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
+					debug("stalled ->clearing endpoint" \
+					      "halt for pipe 0x%x\n", pipe);
 					stat = us->pusb_dev->status;
 					usb_clear_halt(us->pusb_dev, pipe);
 					us->pusb_dev->status = stat;
 					if (this_xfer == partial) {
-						USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n", us->pusb_dev->status);
+						debug("bulk transferred" \
+						      "with error %lX," \
+						      " but data ok\n",
+						      us->pusb_dev->status);
 						return 0;
 					}
 					else
 						return result;
 				}
 				if (us->pusb_dev->status & USB_ST_NAK_REC) {
-					USB_STOR_PRINTF("Device NAKed bulk_msg\n");
+					debug("Device NAKed bulk_msg\n");
 					return result;
 				}
-				USB_STOR_PRINTF("bulk transferred with error");
+				debug("bulk transferred with error");
 				if (this_xfer == partial) {
-					USB_STOR_PRINTF(" %d, but data ok\n",
-							us->pusb_dev->status);
+					debug(" %ld, but data ok\n",
+					      us->pusb_dev->status);
 					return 0;
 				}
 				/* if our try counter reaches 0, bail out */
-					USB_STOR_PRINTF(" %d, data %d\n",
-						us->pusb_dev->status, partial);
+					debug(" %ld, data %d\n",
+					      us->pusb_dev->status, partial);
 				if (!maxtry--)
 						return result;
 			}
@@ -423,35 +411,34 @@
 	 *
 	 * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
 	 */
-	USB_STOR_PRINTF("BBB_reset\n");
+	debug("BBB_reset\n");
 	result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
 				 US_BBB_RESET,
 				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-				 0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT * 5);
+				 0, us->ifnum, NULL, 0, USB_CNTL_TIMEOUT * 5);
 
 	if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
-		USB_STOR_PRINTF("RESET:stall\n");
+		debug("RESET:stall\n");
 		return -1;
 	}
 
 	/* long wait for reset */
-	wait_ms(150);
-	USB_STOR_PRINTF("BBB_reset result %d: status %X reset\n", result,
-			us->pusb_dev->status);
+	mdelay(150);
+	debug("BBB_reset result %d: status %lX reset\n",
+	      result, us->pusb_dev->status);
 	pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
 	result = usb_clear_halt(us->pusb_dev, pipe);
 	/* long wait for reset */
-	wait_ms(150);
-	USB_STOR_PRINTF("BBB_reset result %d: status %X clearing IN endpoint\n",
-			result, us->pusb_dev->status);
+	mdelay(150);
+	debug("BBB_reset result %d: status %lX clearing IN endpoint\n",
+	      result, us->pusb_dev->status);
 	/* long wait for reset */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 	result = usb_clear_halt(us->pusb_dev, pipe);
-	wait_ms(150);
-	USB_STOR_PRINTF("BBB_reset result %d: status %X"
-			" clearing OUT endpoint\n", result,
-			us->pusb_dev->status);
-	USB_STOR_PRINTF("BBB_reset done\n");
+	mdelay(150);
+	debug("BBB_reset result %d: status %lX clearing OUT endpoint\n",
+	      result, us->pusb_dev->status);
+	debug("BBB_reset done\n");
 	return 0;
 }
 
@@ -464,7 +451,7 @@
 	unsigned char cmd[12];
 	int result;
 
-	USB_STOR_PRINTF("CB_reset\n");
+	debug("CB_reset\n");
 	memset(cmd, 0xff, sizeof(cmd));
 	cmd[0] = SCSI_SEND_DIAG;
 	cmd[1] = 4;
@@ -475,14 +462,13 @@
 				 USB_CNTL_TIMEOUT * 5);
 
 	/* long wait for reset */
-	wait_ms(1500);
-	USB_STOR_PRINTF("CB_reset result %d: status %X"
-			" clearing endpoint halt\n", result,
-			us->pusb_dev->status);
+	mdelay(1500);
+	debug("CB_reset result %d: status %lX clearing endpoint halt\n",
+	      result, us->pusb_dev->status);
 	usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
 	usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
 
-	USB_STOR_PRINTF("CB_reset done\n");
+	debug("CB_reset done\n");
 	return 0;
 }
 
@@ -490,18 +476,18 @@
  * Set up the command for a BBB device. Note that the actual SCSI
  * command is copied into cbw.CBWCDB.
  */
-int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
+static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 {
 	int result;
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
 #ifdef BBB_COMDAT_TRACE
-	printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n",
+	printf("dir %d lun %d cmdlen %d cmd %p datalen %lu pdata %p\n",
 		dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
 		srb->pdata);
 	if (srb->cmdlen) {
@@ -512,33 +498,33 @@
 #endif
 	/* sanity checks */
 	if (!(srb->cmdlen <= CBWCDBLENGTH)) {
-		USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n");
+		debug("usb_stor_BBB_comdat:cmdlen too large\n");
 		return -1;
 	}
 
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	cbw->bCDBLength = srb->cmdlen;
 	/* copy the command data into the CBW command data buffer */
 	/* DST SRC LEN!!! */
-	memcpy(cbw.CBWCDB, srb->cmd, srb->cmdlen);
-	result = usb_bulk_msg(us->pusb_dev, pipe, &cbw, UMASS_BBB_CBW_SIZE,
+	memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
+	result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
 			      &actlen, USB_CNTL_TIMEOUT * 5);
 	if (result < 0)
-		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
+		debug("usb_stor_BBB_comdat:usb_bulk_msg error\n");
 	return result;
 }
 
 /* FIXME: we also need a CBI_command which sets up the completion
  * interrupt, and waits for it
  */
-int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
+static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
 {
 	int result = 0;
 	int dir_in, retry;
@@ -554,8 +540,8 @@
 		pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
 	while (retry--) {
-		USB_STOR_PRINTF("CBI gets a command: Try %d\n", 5 - retry);
-#ifdef USB_STOR_DEBUG
+		debug("CBI gets a command: Try %d\n", 5 - retry);
+#ifdef DEBUG
 		usb_show_srb(srb);
 #endif
 		/* let's send the command via the control pipe */
@@ -566,35 +552,35 @@
 					 0, us->ifnum,
 					 srb->cmd, srb->cmdlen,
 					 USB_CNTL_TIMEOUT * 5);
-		USB_STOR_PRINTF("CB_transport: control msg returned %d,"
-				" status %X\n", result, us->pusb_dev->status);
+		debug("CB_transport: control msg returned %d, status %lX\n",
+		      result, us->pusb_dev->status);
 		/* check the return code for the command */
 		if (result < 0) {
 			if (us->pusb_dev->status & USB_ST_STALLED) {
 				status = us->pusb_dev->status;
-				USB_STOR_PRINTF(" stall during command found,"
-						" clear pipe\n");
+				debug(" stall during command found," \
+				      " clear pipe\n");
 				usb_clear_halt(us->pusb_dev,
 					      usb_sndctrlpipe(us->pusb_dev, 0));
 				us->pusb_dev->status = status;
 			}
-			USB_STOR_PRINTF(" error during command %02X"
-					" Stat = %X\n", srb->cmd[0],
-					us->pusb_dev->status);
+			debug(" error during command %02X" \
+			      " Stat = %lX\n", srb->cmd[0],
+			      us->pusb_dev->status);
 			return result;
 		}
 		/* transfer the data payload for this command, if one exists*/
 
-		USB_STOR_PRINTF("CB_transport: control msg returned %d,"
-				" direction is %s to go 0x%lx\n", result,
-				dir_in ? "IN" : "OUT", srb->datalen);
+		debug("CB_transport: control msg returned %d," \
+		      " direction is %s to go 0x%lx\n", result,
+		      dir_in ? "IN" : "OUT", srb->datalen);
 		if (srb->datalen) {
 			result = us_one_transfer(us, pipe, (char *)srb->pdata,
 						 srb->datalen);
-			USB_STOR_PRINTF("CBI attempted to transfer data,"
-					" result is %d status %lX, len %d\n",
-					result, us->pusb_dev->status,
-					us->pusb_dev->act_len);
+			debug("CBI attempted to transfer data," \
+			      " result is %d status %lX, len %d\n",
+			      result, us->pusb_dev->status,
+				us->pusb_dev->act_len);
 			if (!(us->pusb_dev->status & USB_ST_NAK_REC))
 				break;
 		} /* if (srb->datalen) */
@@ -607,7 +593,7 @@
 }
 
 
-int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
+static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
 {
 	int timeout;
 
@@ -616,19 +602,18 @@
 			(void *) &us->ip_data, us->irqmaxp, us->irqinterval);
 	timeout = 1000;
 	while (timeout--) {
-		if ((volatile int *) us->ip_wanted == 0)
+		if ((volatile int *) us->ip_wanted == NULL)
 			break;
-		wait_ms(10);
+		mdelay(10);
 	}
 	if (us->ip_wanted) {
 		printf("	Did not get interrupt on CBI\n");
 		us->ip_wanted = 0;
 		return USB_STOR_TRANSPORT_ERROR;
 	}
-	USB_STOR_PRINTF
-		("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
-		 us->ip_data, us->pusb_dev->irq_act_len,
-		 us->pusb_dev->irq_status);
+	debug("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
+	      us->ip_data, us->pusb_dev->irq_act_len,
+	      us->pusb_dev->irq_status);
 	/* UFI gives us ASC and ASCQ, like a request sense */
 	if (us->subclass == US_SC_UFI) {
 		if (srb->cmd[0] == SCSI_REQ_SENSE ||
@@ -655,24 +640,24 @@
 #define USB_TRANSPORT_NOT_READY_RETRY 10
 
 /* clear a stall on an endpoint - special for BBB devices */
-int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
+static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
 {
 	int result;
 
 	/* ENDPOINT_HALT = 0, so set value to 0 */
 	result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
 				USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
-				0, endpt, 0, 0, USB_CNTL_TIMEOUT * 5);
+				0, endpt, NULL, 0, USB_CNTL_TIMEOUT * 5);
 	return result;
 }
 
-int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
+static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 {
 	int result, retry;
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -681,15 +666,16 @@
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
 	/* COMMAND phase */
-	USB_STOR_PRINTF("COMMAND phase\n");
+	debug("COMMAND phase\n");
 	result = usb_stor_BBB_comdat(srb, us);
 	if (result < 0) {
-		USB_STOR_PRINTF("failed to send CBW status %ld\n",
-			us->pusb_dev->status);
+		debug("failed to send CBW status %ld\n",
+		      us->pusb_dev->status);
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
 	}
-	wait_ms(5);
+	if (!(us->flags & USB_READY))
+		mdelay(5);
 	pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
 	pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 	/* DATA phase + error handling */
@@ -697,7 +683,7 @@
 	/* no data, go immediately to the STATUS phase */
 	if (srb->datalen == 0)
 		goto st;
-	USB_STOR_PRINTF("DATA phase\n");
+	debug("DATA phase\n");
 	if (dir_in)
 		pipe = pipein;
 	else
@@ -706,7 +692,7 @@
 			      &data_actlen, USB_CNTL_TIMEOUT * 5);
 	/* special handling of STALL in DATA phase */
 	if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
-		USB_STOR_PRINTF("DATA:stall\n");
+		debug("DATA:stall\n");
 		/* clear the STALL on the endpoint */
 		result = usb_stor_BBB_clear_endpt_stall(us,
 					dir_in ? us->ep_in : us->ep_out);
@@ -715,8 +701,8 @@
 			goto st;
 	}
 	if (result < 0) {
-		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
-			us->pusb_dev->status);
+		debug("usb_bulk_msg error status %ld\n",
+		      us->pusb_dev->status);
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -729,14 +715,14 @@
 st:
 	retry = 0;
 again:
-	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	debug("STATUS phase\n");
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
 	if ((result < 0) && (retry < 1) &&
 	    (us->pusb_dev->status & USB_ST_STALLED)) {
-		USB_STOR_PRINTF("STATUS:stall\n");
+		debug("STATUS:stall\n");
 		/* clear the STALL on the endpoint */
 		result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
 		if (result >= 0 && (retry++ < 1))
@@ -744,50 +730,50 @@
 			goto again;
 	}
 	if (result < 0) {
-		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
-			us->pusb_dev->status);
+		debug("usb_bulk_msg error status %ld\n",
+		      us->pusb_dev->status);
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
-		USB_STOR_PRINTF("!CSWSIGNATURE\n");
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
+		debug("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
-		USB_STOR_PRINTF("!Tag\n");
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
+		debug("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
-		USB_STOR_PRINTF(">PHASE\n");
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
+		debug(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
-		USB_STOR_PRINTF("=PHASE\n");
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
+		debug("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
 	} else if (data_actlen > srb->datalen) {
-		USB_STOR_PRINTF("transferred %dB instead of %dB\n",
-			data_actlen, srb->datalen);
+		debug("transferred %dB instead of %ldB\n",
+		      data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
-		USB_STOR_PRINTF("FAILED\n");
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
+		debug("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 
 	return result;
 }
 
-int usb_stor_CB_transport(ccb *srb, struct us_data *us)
+static int usb_stor_CB_transport(ccb *srb, struct us_data *us)
 {
 	int result, status;
 	ccb *psrb;
@@ -801,14 +787,14 @@
 	/* issue the command */
 do_retry:
 	result = usb_stor_CB_comdat(srb, us);
-	USB_STOR_PRINTF("command / Data returned %d, status %X\n",
-			result, us->pusb_dev->status);
+	debug("command / Data returned %d, status %lX\n",
+	      result, us->pusb_dev->status);
 	/* if this is an CBI Protocol, get IRQ */
 	if (us->protocol == US_PR_CBI) {
 		status = usb_stor_CBI_get_status(srb, us);
 		/* if the status is error, report it */
 		if (status == USB_STOR_TRANSPORT_ERROR) {
-			USB_STOR_PRINTF(" USB CBI Command Error\n");
+			debug(" USB CBI Command Error\n");
 			return status;
 		}
 		srb->sense_buf[12] = (unsigned char)(us->ip_data >> 8);
@@ -816,7 +802,7 @@
 		if (!us->ip_data) {
 			/* if the status is good, report it */
 			if (status == USB_STOR_TRANSPORT_GOOD) {
-				USB_STOR_PRINTF(" USB CBI Command Good\n");
+				debug(" USB CBI Command Good\n");
 				return status;
 			}
 		}
@@ -824,7 +810,7 @@
 	/* do we have to issue an auto request? */
 	/* HERE we have to check the result */
 	if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
-		USB_STOR_PRINTF("ERROR %X\n", us->pusb_dev->status);
+		debug("ERROR %lX\n", us->pusb_dev->status);
 		us->transport_reset(us);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
@@ -832,7 +818,7 @@
 	    ((srb->cmd[0] == SCSI_REQ_SENSE) ||
 	    (srb->cmd[0] == SCSI_INQUIRY))) {
 		/* do not issue an autorequest after request sense */
-		USB_STOR_PRINTF("No auto request and good\n");
+		debug("No auto request and good\n");
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 	/* issue an request_sense */
@@ -845,19 +831,19 @@
 	psrb->cmdlen = 12;
 	/* issue the command */
 	result = usb_stor_CB_comdat(psrb, us);
-	USB_STOR_PRINTF("auto request returned %d\n", result);
+	debug("auto request returned %d\n", result);
 	/* if this is an CBI Protocol, get IRQ */
 	if (us->protocol == US_PR_CBI)
 		status = usb_stor_CBI_get_status(psrb, us);
 
 	if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
-		USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",
-				us->pusb_dev->status);
+		debug(" AUTO REQUEST ERROR %ld\n",
+		      us->pusb_dev->status);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
-	USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
-			srb->sense_buf[0], srb->sense_buf[2],
-			srb->sense_buf[12], srb->sense_buf[13]);
+	debug("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
+	      srb->sense_buf[0], srb->sense_buf[2],
+	      srb->sense_buf[12], srb->sense_buf[13]);
 	/* Check the auto request result */
 	if ((srb->sense_buf[2] == 0) &&
 	    (srb->sense_buf[12] == 0) &&
@@ -881,7 +867,7 @@
 				srb->sense_buf[12], srb->sense_buf[13]);
 			return USB_STOR_TRANSPORT_FAILED;
 		} else {
-			wait_ms(100);
+			mdelay(100);
 			goto do_retry;
 		}
 		break;
@@ -912,7 +898,7 @@
 		srb->datalen = 36;
 		srb->cmdlen = 12;
 		i = ss->transport(srb, ss);
-		USB_STOR_PRINTF("inquiry returns %d\n", i);
+		debug("inquiry returns %d\n", i);
 		if (i == 0)
 			break;
 	} while (--retry);
@@ -937,9 +923,9 @@
 	srb->pdata = &srb->sense_buf[0];
 	srb->cmdlen = 12;
 	ss->transport(srb, ss);
-	USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",
-			srb->sense_buf[2], srb->sense_buf[12],
-			srb->sense_buf[13]);
+	debug("Request Sense returned %02X %02X %02X\n",
+	      srb->sense_buf[2], srb->sense_buf[12],
+	      srb->sense_buf[13]);
 	srb->pdata = (uchar *)ptr;
 	return 0;
 }
@@ -954,10 +940,22 @@
 		srb->cmd[1] = srb->lun << 5;
 		srb->datalen = 0;
 		srb->cmdlen = 12;
-		if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
+		if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) {
+			ss->flags |= USB_READY;
 			return 0;
+		}
 		usb_request_sense(srb, ss);
-		wait_ms(100);
+		/*
+		 * Check the Key Code Qualifier, if it matches
+		 * "Not Ready - medium not present"
+		 * (the sense Key equals 0x2 and the ASC is 0x3a)
+		 * return immediately as the medium being absent won't change
+		 * unless there is a user action.
+		 */
+		if ((srb->sense_buf[2] == 0x02) &&
+		    (srb->sense_buf[12] == 0x3a))
+			return -1;
+		mdelay(100);
 	} while (retries--);
 
 	return -1;
@@ -994,7 +992,7 @@
 	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
 	srb->cmd[8] = (unsigned char) blocks & 0xff;
 	srb->cmdlen = 12;
-	USB_STOR_PRINTF("read10: start %lx blocks %x\n", start, blocks);
+	debug("read10: start %lx blocks %x\n", start, blocks);
 	return ss->transport(srb, ss);
 }
 
@@ -1011,7 +1009,7 @@
 	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
 	srb->cmd[8] = (unsigned char) blocks & 0xff;
 	srb->cmdlen = 12;
-	USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks);
+	debug("write10: start %lx blocks %x\n", start, blocks);
 	return ss->transport(srb, ss);
 }
 
@@ -1039,14 +1037,14 @@
 }
 #endif /* CONFIG_USB_BIN_FIXUP */
 
-#define USB_MAX_READ_BLK 20
-
-unsigned long usb_stor_read(int device, unsigned long blknr,
-			    unsigned long blkcnt, void *buffer)
+unsigned long usb_stor_read(int device, lbaint_t blknr,
+			    lbaint_t blkcnt, void *buffer)
 {
-	unsigned long start, blks, buf_addr;
+	lbaint_t start, blks;
+	uintptr_t buf_addr;
 	unsigned short smallblks;
 	struct usb_device *dev;
+	struct us_data *ss;
 	int retry, i;
 	ccb *srb = &usb_ccb;
 
@@ -1055,7 +1053,7 @@
 
 	device &= 0xff;
 	/* Setup  device */
-	USB_STOR_PRINTF("\nusb_read: dev %d \n", device);
+	debug("\nusb_read: dev %d \n", device);
 	dev = NULL;
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
 		dev = usb_get_dev_index(i);
@@ -1064,39 +1062,33 @@
 		if (dev->devnum == usb_dev_desc[device].target)
 			break;
 	}
+	ss = (struct us_data *)dev->privptr;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 	srb->lun = usb_dev_desc[device].lun;
 	buf_addr = (unsigned long)buffer;
 	start = blknr;
 	blks = blkcnt;
-	if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
-		printf("Device NOT ready\n   Request Sense returned %02X %02X"
-		       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
-		       srb->sense_buf[13]);
-		return 0;
-	}
 
-	USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx"
-			" buffer %lx\n", device, start, blks, buf_addr);
+	debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF
+	      " buffer %x\n", device, start, blks, (unsigned int)buf_addr);
 
 	do {
 		/* XXX need some comment here */
 		retry = 2;
 		srb->pdata = (unsigned char *)buf_addr;
-		if (blks > USB_MAX_READ_BLK)
-			smallblks = USB_MAX_READ_BLK;
+		if (blks > USB_MAX_XFER_BLK)
+			smallblks = USB_MAX_XFER_BLK;
 		else
 			smallblks = (unsigned short) blks;
 retry_it:
-		if (smallblks == USB_MAX_READ_BLK)
+		if (smallblks == USB_MAX_XFER_BLK)
 			usb_show_progress();
 		srb->datalen = usb_dev_desc[device].blksz * smallblks;
 		srb->pdata = (unsigned char *)buf_addr;
-		if (usb_read_10(srb, (struct us_data *)dev->privptr, start,
-		    smallblks)) {
-			USB_STOR_PRINTF("Read ERROR\n");
-			usb_request_sense(srb, (struct us_data *)dev->privptr);
+		if (usb_read_10(srb, ss, start, smallblks)) {
+			printf("Read ERROR\n");
+			usb_request_sense(srb, ss);
 			if (retry--)
 				goto retry_it;
 			blkcnt -= blks;
@@ -1106,24 +1098,26 @@
 		blks -= smallblks;
 		buf_addr += srb->datalen;
 	} while (blks != 0);
+	ss->flags &= ~USB_READY;
 
-	USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",
-			start, smallblks, buf_addr);
+	debug("usb_read: end startblk " LBAF
+	      ", blccnt %x buffer %x\n",
+	      start, smallblks, (unsigned int)buf_addr);
 
 	usb_disable_asynch(0); /* asynch transfer allowed */
-	if (blkcnt >= USB_MAX_READ_BLK)
+	if (blkcnt >= USB_MAX_XFER_BLK)
 		debug("\n");
 	return blkcnt;
 }
 
-#define USB_MAX_WRITE_BLK 20
-
-unsigned long usb_stor_write(int device, unsigned long blknr,
-				unsigned long blkcnt, const void *buffer)
+unsigned long usb_stor_write(int device, lbaint_t blknr,
+				lbaint_t blkcnt, const void *buffer)
 {
-	unsigned long start, blks, buf_addr;
+	lbaint_t start, blks;
+	uintptr_t buf_addr;
 	unsigned short smallblks;
 	struct usb_device *dev;
+	struct us_data *ss;
 	int retry, i;
 	ccb *srb = &usb_ccb;
 
@@ -1132,7 +1126,7 @@
 
 	device &= 0xff;
 	/* Setup  device */
-	USB_STOR_PRINTF("\nusb_write: dev %d \n", device);
+	debug("\nusb_write: dev %d \n", device);
 	dev = NULL;
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
 		dev = usb_get_dev_index(i);
@@ -1141,6 +1135,7 @@
 		if (dev->devnum == usb_dev_desc[device].target)
 			break;
 	}
+	ss = (struct us_data *)dev->privptr;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 
@@ -1148,15 +1143,9 @@
 	buf_addr = (unsigned long)buffer;
 	start = blknr;
 	blks = blkcnt;
-	if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
-		printf("Device NOT ready\n   Request Sense returned %02X %02X"
-		       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
-			srb->sense_buf[13]);
-		return 0;
-	}
 
-	USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx"
-			" buffer %lx\n", device, start, blks, buf_addr);
+	debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF
+	      " buffer %lx\n", device, start, blks, buf_addr);
 
 	do {
 		/* If write fails retry for max retry count else
@@ -1164,19 +1153,18 @@
 		 */
 		retry = 2;
 		srb->pdata = (unsigned char *)buf_addr;
-		if (blks > USB_MAX_WRITE_BLK)
-			smallblks = USB_MAX_WRITE_BLK;
+		if (blks > USB_MAX_XFER_BLK)
+			smallblks = USB_MAX_XFER_BLK;
 		else
 			smallblks = (unsigned short) blks;
 retry_it:
-		if (smallblks == USB_MAX_WRITE_BLK)
+		if (smallblks == USB_MAX_XFER_BLK)
 			usb_show_progress();
 		srb->datalen = usb_dev_desc[device].blksz * smallblks;
 		srb->pdata = (unsigned char *)buf_addr;
-		if (usb_write_10(srb, (struct us_data *)dev->privptr, start,
-		    smallblks)) {
-			USB_STOR_PRINTF("Write ERROR\n");
-			usb_request_sense(srb, (struct us_data *)dev->privptr);
+		if (usb_write_10(srb, ss, start, smallblks)) {
+			debug("Write ERROR\n");
+			usb_request_sense(srb, ss);
 			if (retry--)
 				goto retry_it;
 			blkcnt -= blks;
@@ -1186,12 +1174,13 @@
 		blks -= smallblks;
 		buf_addr += srb->datalen;
 	} while (blks != 0);
+	ss->flags &= ~USB_READY;
 
-	USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n",
-			start, smallblks, buf_addr);
+	debug("usb_write: end startblk " LBAF ", blccnt %x buffer %lx\n",
+	      start, smallblks, buf_addr);
 
 	usb_disable_asynch(0); /* asynch transfer allowed */
-	if (blkcnt >= USB_MAX_WRITE_BLK)
+	if (blkcnt >= USB_MAX_XFER_BLK)
 		debug("\n");
 	return blkcnt;
 
@@ -1203,6 +1192,7 @@
 {
 	struct usb_interface *iface;
 	int i;
+	struct usb_endpoint_descriptor *ep_desc;
 	unsigned int flags = 0;
 
 	int protocol = 0;
@@ -1213,12 +1203,12 @@
 
 #if 0
 	/* this is the place to patch some storage devices */
-	USB_STOR_PRINTF("iVendor %X iProduct %X\n", dev->descriptor.idVendor,
+	debug("iVendor %X iProduct %X\n", dev->descriptor.idVendor,
 			dev->descriptor.idProduct);
 
 	if ((dev->descriptor.idVendor) == 0x066b &&
 	    (dev->descriptor.idProduct) == 0x0103) {
-		USB_STOR_PRINTF("patched for E-USB\n");
+		debug("patched for E-USB\n");
 		protocol = US_PR_CB;
 		subclass = US_SC_UFI;	    /* an assumption */
 	}
@@ -1235,7 +1225,7 @@
 	memset(ss, 0, sizeof(struct us_data));
 
 	/* At this point, we know we've got a live one */
-	USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
+	debug("\n\nUSB Mass Storage device detected\n");
 
 	/* Initialize the us_data structure with some useful info */
 	ss->flags = flags;
@@ -1255,21 +1245,21 @@
 	}
 
 	/* set the handler pointers based on the protocol */
-	USB_STOR_PRINTF("Transport: ");
+	debug("Transport: ");
 	switch (ss->protocol) {
 	case US_PR_CB:
-		USB_STOR_PRINTF("Control/Bulk\n");
+		debug("Control/Bulk\n");
 		ss->transport = usb_stor_CB_transport;
 		ss->transport_reset = usb_stor_CB_reset;
 		break;
 
 	case US_PR_CBI:
-		USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
+		debug("Control/Bulk/Interrupt\n");
 		ss->transport = usb_stor_CB_transport;
 		ss->transport_reset = usb_stor_CB_reset;
 		break;
 	case US_PR_BULK:
-		USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");
+		debug("Bulk/Bulk/Bulk\n");
 		ss->transport = usb_stor_BBB_transport;
 		ss->transport_reset = usb_stor_BBB_reset;
 		break;
@@ -1285,34 +1275,35 @@
 	 * We will ignore any others.
 	 */
 	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
+		ep_desc = &iface->ep_desc[i];
 		/* is it an BULK endpoint? */
-		if ((iface->ep_desc[i].bmAttributes &
+		if ((ep_desc->bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
-			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
-				ss->ep_in = iface->ep_desc[i].bEndpointAddress &
-					USB_ENDPOINT_NUMBER_MASK;
+			if (ep_desc->bEndpointAddress & USB_DIR_IN)
+				ss->ep_in = ep_desc->bEndpointAddress &
+						USB_ENDPOINT_NUMBER_MASK;
 			else
 				ss->ep_out =
-					iface->ep_desc[i].bEndpointAddress &
+					ep_desc->bEndpointAddress &
 					USB_ENDPOINT_NUMBER_MASK;
 		}
 
 		/* is it an interrupt endpoint? */
-		if ((iface->ep_desc[i].bmAttributes &
-		    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
-			ss->ep_int = iface->ep_desc[i].bEndpointAddress &
-				USB_ENDPOINT_NUMBER_MASK;
-			ss->irqinterval = iface->ep_desc[i].bInterval;
+		if ((ep_desc->bmAttributes &
+		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
+			ss->ep_int = ep_desc->bEndpointAddress &
+						USB_ENDPOINT_NUMBER_MASK;
+			ss->irqinterval = ep_desc->bInterval;
 		}
 	}
-	USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
-		  ss->ep_in, ss->ep_out, ss->ep_int);
+	debug("Endpoints In %d Out %d Int %d\n",
+	      ss->ep_in, ss->ep_out, ss->ep_int);
 
 	/* Do some basic sanity checks, and bail if we find a problem */
 	if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
 	    !ss->ep_in || !ss->ep_out ||
 	    (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
-		USB_STOR_PRINTF("Problems with device\n");
+		debug("Problems with device\n");
 		return 0;
 	}
 	/* set class specific stuff */
@@ -1342,7 +1333,8 @@
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1350,7 +1342,7 @@
 
 	dev_desc->target = dev->devnum;
 	pccb->lun = dev_desc->lun;
-	USB_STOR_PRINTF(" address %d\n", dev_desc->target);
+	debug(" address %d\n", dev_desc->target);
 
 	if (usb_inquiry(pccb, ss))
 		return -1;
@@ -1366,9 +1358,9 @@
 		/* drive is removable */
 		dev_desc->removable = 1;
 	}
-	memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	memcpy(&dev_desc->vendor[0], (const void *) &usb_stor_buf[8], 8);
+	memcpy(&dev_desc->product[0], (const void *) &usb_stor_buf[16], 16);
+	memcpy(&dev_desc->revision[0], (const void *) &usb_stor_buf[32], 4);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
@@ -1376,8 +1368,8 @@
 	usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
 		      (uchar *)dev_desc->product);
 #endif /* CONFIG_USB_BIN_FIXUP */
-	USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
-			usb_stor_buf[3]);
+	debug("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
+	      usb_stor_buf[3]);
 	if (usb_test_unit_ready(pccb, ss)) {
 		printf("Device NOT ready\n"
 		       "   Request Sense returned %02X %02X %02X\n",
@@ -1396,8 +1388,8 @@
 		cap[0] = 2880;
 		cap[1] = 0x200;
 	}
-	USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0],
-			cap[1]);
+	ss->flags &= ~USB_READY;
+	debug("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]);
 #if 0
 	if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
 		cap[0] >>= 16;
@@ -1409,16 +1401,16 @@
 	cap[0] += 1;
 	capacity = &cap[0];
 	blksz = &cap[1];
-	USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",
-			*capacity, *blksz);
+	debug("Capacity = 0x%lx, blocksz = 0x%lx\n", *capacity, *blksz);
 	dev_desc->lba = *capacity;
 	dev_desc->blksz = *blksz;
+	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->type = perq;
-	USB_STOR_PRINTF(" address %d\n", dev_desc->target);
-	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
+	debug(" address %d\n", dev_desc->target);
+	debug("partype: %d\n", dev_desc->part_type);
 
 	init_part(dev_desc);
 
-	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
+	debug("partype: %d\n", dev_desc->part_type);
 	return 1;
 }
diff '--exclude=.svn' -Naur u-boot-2011.06_original/common/xyzModem.c u-boot-2011.06/common/xyzModem.c
--- u-boot-2011.06_original/common/xyzModem.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/common/xyzModem.c	2014-07-29 17:28:38.819972000 +0800
@@ -93,7 +93,7 @@
 } xyz;
 
 #define xyzModem_CHAR_TIMEOUT            2000	/* 2 seconds */
-#define xyzModem_MAX_RETRIES             20
+#define xyzModem_MAX_RETRIES             200
 #define xyzModem_MAX_RETRIES_WITH_CRC    10
 #define xyzModem_CAN_COUNT                3	/* Wait for 3 CAN before quitting */
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/config.mk u-boot-2011.06/config.mk
--- u-boot-2011.06_original/config.mk	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/config.mk	2014-11-19 00:41:17.367468000 +0800
@@ -152,7 +152,7 @@
 endif
 RELFLAGS= $(PLATFORM_RELFLAGS)
 DBGFLAGS= -g # -DDEBUG
-OPTFLAGS= -Os #-fomit-frame-pointer
+OPTFLAGS= -O2 #-fomit-frame-pointer
 
 OBJCFLAGS += --gap-fill=0xff
 
@@ -183,6 +183,7 @@
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
 endif
 
+
 CFLAGS += $(call cc-option,-fno-stack-protector)
 
 # $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
@@ -197,6 +198,12 @@
 endif
 
 AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
+UBOOT_VERSIONTAG ?= 0
+AFLAGS += -DUBOOT_VERSIONTAG=$(UBOOT_VERSIONTAG)
+
+ifeq ($(UART_LOCK),1)
+CFLAGS += -DCONFIG_UART_LOCK
+endif
 
 LDFLAGS += $(PLATFORM_LDFLAGS)
 LDFLAGS_FINAL += -Bstatic
@@ -237,20 +244,23 @@
 
 #########################################################################
 
+CFLAGS += -Werror -Wno-unused-but-set-variable 
+CFLAGS += -Wno-unused-function
+
 # Allow boards to use custom optimize flags on a per dir/file basis
 BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))
 ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))
 ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))
 $(obj)%.s:	%.S
-	$(CPP) $(ALL_AFLAGS) -o $@ $<
+	$(Q)$(CPP) $(ALL_AFLAGS) -o $@ $<
 $(obj)%.o:	%.S
-	$(CC)  $(ALL_AFLAGS) -o $@ $< -c
+	$(Q)$(CC)  $(ALL_AFLAGS) -o $@ $< -c
 $(obj)%.o:	%.c
-	$(CC)  $(ALL_CFLAGS) -o $@ $< -c
+	$(Q)$(CC)  $(ALL_CFLAGS) -o $@ $< -c
 $(obj)%.i:	%.c
-	$(CPP) $(ALL_CFLAGS) -o $@ $< -c
+	$(Q)$(CPP) $(ALL_CFLAGS) -o $@ $< -c
 $(obj)%.s:	%.c
-	$(CC)  $(ALL_CFLAGS) -o $@ $< -c -S
+	$(Q)$(CC)  $(ALL_CFLAGS) -o $@ $< -c -S
 
 #########################################################################
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/disk/part.c u-boot-2011.06/disk/part.c
--- u-boot-2011.06_original/disk/part.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/disk/part.c	2014-07-29 17:28:38.819972000 +0800
@@ -74,7 +74,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-block_dev_desc_t *get_dev(char* ifname, int dev)
+block_dev_desc_t *get_dev(const char* ifname, int dev)
 {
 	const struct block_drvr *drvr = block_drvr;
 	block_dev_desc_t* (*reloc_get_dev)(int dev);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/disk/part_dos.c u-boot-2011.06/disk/part_dos.c
--- u-boot-2011.06_original/disk/part_dos.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/disk/part_dos.c	2014-08-28 18:12:18.974057000 +0800
@@ -73,13 +73,26 @@
 
 static int test_block_type(unsigned char *buffer)
 {
+	int slot;
+	struct dos_partition *p;
+
 	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
 		return (-1);
 	} /* no DOS Signature at all */
-	if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 ||
-	    strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) {
-		return DOS_PBR; /* is PBR */
+	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
+	for (slot = 0; slot < 3; slot++) {
+		if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+			if (!slot &&
+			    (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
+				     "FAT", 3) == 0 ||
+			     strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
+				     "FAT32", 5) == 0)) {
+				return DOS_PBR; /* is PBR */
+			} else {
+				return -1;
+			}
+		}
 	}
 	return DOS_MBR;	    /* Is MBR */
 }
@@ -87,7 +100,7 @@
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[DEFAULT_SECTOR_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, DEFAULT_SECTOR_SIZE);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
@@ -102,7 +115,7 @@
 static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative,
 							   int part_num)
 {
-	unsigned char buffer[DEFAULT_SECTOR_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, DEFAULT_SECTOR_SIZE);
 	dos_partition_t *pt;
 	int i;
 
@@ -118,11 +131,12 @@
 			buffer[DOS_PART_MAGIC_OFFSET + 1]);
 		return;
 	}
+	/*
 	if(i==DOS_PBR) {
 		printf ("    1\t\t         0\t%10ld\t%2x\n",
 			dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]);
 		return;
-	}
+	}*/
 	/* Print all primary/logical partitions */
 	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 	for (i = 0; i < 4; i++, pt++) {
@@ -166,7 +180,7 @@
 				 int relative, int part_num,
 				 int which_part, disk_partition_t *info)
 {
-	unsigned char buffer[DEFAULT_SECTOR_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, DEFAULT_SECTOR_SIZE);
 	dos_partition_t *pt;
 	int i;
 
@@ -195,8 +209,9 @@
 		    (part_num == which_part) &&
 		    (is_extended(pt->sys_ind) == 0)) {
 			info->blksz = 512;
-			info->start = ext_part_sector + le32_to_int (pt->start4);
-			info->size  = le32_to_int (pt->size4);
+			info->start = (lbaint_t)(ext_part_sector +
+					le32_to_int(pt->start4));
+			info->size  = (lbaint_t)le32_to_int(pt->size4);
 			switch(dev_desc->if_type) {
 				case IF_TYPE_IDE:
 				case IF_TYPE_SATA:
diff '--exclude=.svn' -Naur u-boot-2011.06_original/disk/part_efi.c u-boot-2011.06/disk/part_efi.c
--- u-boot-2011.06_original/disk/part_efi.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/disk/part_efi.c	2014-07-29 17:28:38.819972000 +0800
@@ -2,23 +2,7 @@
  * Copyright (C) 2008 RuggedCom, Inc.
  * Richard Retanubun <RichardRetanubun@RuggedCom.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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 /*
@@ -30,48 +14,17 @@
  *
  * This limits the maximum size of addressable storage to < 2 Terra Bytes
  */
+#include <asm/unaligned.h>
 #include <common.h>
 #include <command.h>
 #include <ide.h>
 #include <malloc.h>
-#include "part_efi.h"
-
-#if defined(CONFIG_CMD_IDE) || \
-    defined(CONFIG_CMD_MG_DISK) || \
-    defined(CONFIG_CMD_SATA) || \
-    defined(CONFIG_CMD_SCSI) || \
-    defined(CONFIG_CMD_USB) || \
-    defined(CONFIG_MMC) || \
-    defined(CONFIG_SYSTEMACE)
+#include <part_efi.h>
+#include <linux/ctype.h>
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-	return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-	return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-	return (((unsigned long long)le64[7] << 56) +
-		((unsigned long long)le64[6] << 48) +
-		((unsigned long long)le64[5] << 40) +
-		((unsigned long long)le64[4] << 32) +
-		((unsigned long long)le64[3] << 24) +
-		((unsigned long long)le64[2] << 16) +
-		((unsigned long long)le64[1] << 8) +
-		(unsigned long long)le64[0]);
-}
+DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef HAVE_BLOCK_DEVICE
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +32,7 @@
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
 	return crc32(0, buf, len);
 }
@@ -90,111 +43,452 @@
 
 static int pmbr_part_valid(struct partition *part);
 static int is_pmbr_valid(legacy_mbr * mbr);
-
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 				gpt_header * pgpt_head, gpt_entry ** pgpt_pte);
-
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 				gpt_header * pgpt_head);
-
 static int is_pte_valid(gpt_entry * pte);
 
+static char *print_efiname(gpt_entry *pte)
+{
+	static char name[PARTNAME_SZ + 1];
+	int i;
+	for (i = 0; i < PARTNAME_SZ; i++) {
+		u8 c;
+		c = pte->partition_name[i] & 0xff;
+		c = (c && !isprint(c)) ? '.' : c;
+		name[i] = c;
+	}
+	name[PARTNAME_SZ] = 0;
+	return name;
+}
+
+static void uuid_string(unsigned char *uuid, char *str)
+{
+	static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11,
+				  12, 13, 14, 15};
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(str, "%02x", uuid[le[i]]);
+		str += 2;
+		switch (i) {
+		case 3:
+		case 5:
+		case 7:
+		case 9:
+			*str++ = '-';
+			break;
+		}
+	}
+}
+
+static efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
+
+static inline int is_bootable(gpt_entry *p)
+{
+	return p->attributes.fields.legacy_bios_bootable ||
+		!memcmp(&(p->partition_type_guid), &system_guid,
+			sizeof(efi_guid_t));
+}
+
+#ifdef CONFIG_EFI_PARTITION
 /*
  * Public Functions (include/part.h)
  */
 
 void print_part_efi(block_dev_desc_t * dev_desc)
 {
-	gpt_header gpt_head;
-	gpt_entry **pgpt_pte = NULL;
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
+	gpt_entry *gpt_pte = NULL;
 	int i = 0;
+	char uuid[37];
 
 	if (!dev_desc) {
-		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+		printf("%s: Invalid Argument(s)\n", __func__);
 		return;
 	}
 	/* This function validates AND fills in the GPT header and PTE */
 	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
-			 &(gpt_head), pgpt_pte) != 1) {
-		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
+			 gpt_head, &gpt_pte) != 1) {
+		printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
 		return;
 	}
 
-	debug("%s: gpt-entry at 0x%08X\n", __FUNCTION__, (unsigned int)*pgpt_pte);
-
-	printf("Part  Start LBA  End LBA\n");
-	for (i = 0; i < le32_to_int(gpt_head.num_partition_entries); i++) {
+	debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
 
-		if (is_pte_valid(&(*pgpt_pte)[i])) {
-			printf("%s%d  0x%llX    0x%llX\n", GPT_ENTRY_NAME,
-				(i + 1),
-				le64_to_int((*pgpt_pte)[i].starting_lba),
-				le64_to_int((*pgpt_pte)[i].ending_lba));
-		} else {
-			break;	/* Stop at the first non valid PTE */
-		}
+	printf("Part\tStart LBA\tEnd LBA\t\tName\n");
+	printf("\tAttributes\n");
+	printf("\tType UUID\n");
+	printf("\tPartition UUID\n");
+
+	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
+		/* Stop at the first non valid PTE */
+		if (!is_pte_valid(&gpt_pte[i]))
+			break;
+
+		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
+			le64_to_cpu(gpt_pte[i].starting_lba),
+			le64_to_cpu(gpt_pte[i].ending_lba),
+			print_efiname(&gpt_pte[i]));
+		printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
+		uuid_string(gpt_pte[i].partition_type_guid.b, uuid);
+		printf("\ttype:\t%s\n", uuid);
+		uuid_string(gpt_pte[i].unique_partition_guid.b, uuid);
+		printf("\tuuid:\t%s\n", uuid);
 	}
 
 	/* Remember to free pte */
-	if (*pgpt_pte != NULL) {
-		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
-		free(*pgpt_pte);
-	}
+	free(gpt_pte);
 	return;
 }
 
 int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 				disk_partition_t * info)
 {
-	gpt_header gpt_head;
-	gpt_entry **pgpt_pte = NULL;
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
+	gpt_entry *gpt_pte = NULL;
 
 	/* "part" argument must be at least 1 */
 	if (!dev_desc || !info || part < 1) {
-		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+		printf("%s: Invalid Argument(s)\n", __func__);
 		return -1;
 	}
 
 	/* This function validates AND fills in the GPT header and PTE */
 	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
-			&(gpt_head), pgpt_pte) != 1) {
-		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
+			gpt_head, &gpt_pte) != 1) {
+		printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
+		return -1;
+	}
+
+	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
+	    !is_pte_valid(&gpt_pte[part - 1])) {
+		debug("%s: *** ERROR: Invalid partition number %d ***\n",
+			__func__, part);
+		free(gpt_pte);
 		return -1;
 	}
 
 	/* The ulong casting limits the maximum disk size to 2 TB */
-	info->start = (ulong) le64_to_int((*pgpt_pte)[part - 1].starting_lba);
+	info->start = (u64)le64_to_cpu(gpt_pte[part - 1].starting_lba);
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
-	info->size = ((ulong)le64_to_int((*pgpt_pte)[part - 1].ending_lba) + 1)
+	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
-	info->blksz = GPT_BLOCK_SIZE;
+	info->blksz = dev_desc->blksz;
 
-	sprintf((char *)info->name, "%s%d", GPT_ENTRY_NAME, part);
+	sprintf((char *)info->name, "%s",
+			print_efiname(&gpt_pte[part - 1]));
 	sprintf((char *)info->type, "U-Boot");
+	info->bootable = is_bootable(&gpt_pte[part - 1]);
+#ifdef CONFIG_PARTITION_UUIDS
+	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
+#endif
 
-	debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
-		info->start, info->size, info->name);
+	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
+	      info->start, info->size, info->name);
 
 	/* Remember to free pte */
-	if (*pgpt_pte != NULL) {
-		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
-		free(*pgpt_pte);
-	}
+	free(gpt_pte);
 	return 0;
 }
 
 int test_part_efi(block_dev_desc_t * dev_desc)
 {
-	legacy_mbr legacymbr;
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
 
 	/* Read legacy MBR from block 0 and validate it */
-	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) & legacymbr) != 1)
-		|| (is_pmbr_valid(&legacymbr) != 1)) {
+	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
+		|| (is_pmbr_valid(legacymbr) != 1)) {
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+	legacy_mbr *p_mbr;
+
+	/* Setup the Protective MBR */
+	p_mbr = calloc(1, sizeof(p_mbr));
+	if (p_mbr == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	/* Append signature */
+	p_mbr->signature = MSDOS_MBR_SIGNATURE;
+	p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
+	p_mbr->partition_record[0].start_sect = 1;
+	p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba;
+
+	/* Write MBR sector to the MMC device */
+	if (dev_desc->block_write(dev_desc->dev, 0, 1, p_mbr) != 1) {
+		printf("** Can't write to device %d **\n",
+			dev_desc->dev);
+		free(p_mbr);
+		return -1;
+	}
+
+	free(p_mbr);
+	return 0;
+}
+
+/**
+ * string_uuid(); Convert UUID stored as string to bytes
+ *
+ * @param uuid - UUID represented as string
+ * @param dst - GUID buffer
+ *
+ * @return return 0 on successful conversion
+ */
+static int string_uuid(char *uuid, u8 *dst)
+{
+	efi_guid_t guid;
+	u16 b, c, d;
+	u64 e;
+	u32 a;
+	u8 *p;
+	u8 i;
+
+	const u8 uuid_str_len = 36;
+
+	/* The UUID is written in text: */
+	/* 1        9    14   19   24 */
+	/* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx */
+
+	debug("%s: uuid: %s\n", __func__, uuid);
+
+	if (strlen(uuid) != uuid_str_len)
 		return -1;
+
+	for (i = 0; i < uuid_str_len; i++) {
+		if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+			if (uuid[i] != '-')
+				return -1;
+		} else {
+			if (!isxdigit(uuid[i]))
+				return -1;
+		}
+	}
+
+	a = (u32)simple_strtoul(uuid, NULL, 16);
+	b = (u16)simple_strtoul(uuid + 9, NULL, 16);
+	c = (u16)simple_strtoul(uuid + 14, NULL, 16);
+	d = (u16)simple_strtoul(uuid + 19, NULL, 16);
+	e = (u64)simple_strtoull(uuid + 24, NULL, 16);
+
+	p = (u8 *) &e;
+	guid = EFI_GUID(a, b, c, d >> 8, d & 0xFF,
+			*(p + 5), *(p + 4), *(p + 3),
+			*(p + 2), *(p + 1) , *p);
+
+	memcpy(dst, guid.b, sizeof(efi_guid_t));
+
+	return 0;
+}
+
+int write_gpt_table(block_dev_desc_t *dev_desc,
+		gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
+					   * sizeof(gpt_entry)), dev_desc);
+	u32 calc_crc32;
+	u64 val;
+
+	debug("max lba: %x\n", (u32) dev_desc->lba);
+	/* Setup the Protective MBR */
+	if (set_protective_mbr(dev_desc) < 0)
+		goto err;
+
+	/* Generate CRC for the Primary GPT Header */
+	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
+			      le32_to_cpu(gpt_h->num_partition_entries) *
+			      le32_to_cpu(gpt_h->sizeof_partition_entry));
+	gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
+
+	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+			      le32_to_cpu(gpt_h->header_size));
+	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+	/* Write the First GPT to the block right after the Legacy MBR */
+	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e)
+	    != pte_blk_cnt)
+		goto err;
+
+	/* recalculate the values for the Second GPT Header */
+	val = le64_to_cpu(gpt_h->my_lba);
+	gpt_h->my_lba = gpt_h->alternate_lba;
+	gpt_h->alternate_lba = cpu_to_le64(val);
+	gpt_h->header_crc32 = 0;
+
+	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+			      le32_to_cpu(gpt_h->header_size));
+	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->last_usable_lba + 1),
+				  pte_blk_cnt, gpt_e) != pte_blk_cnt)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1)
+		goto err;
+
+	debug("GPT successfully written to block device!\n");
+	return 0;
+
+ err:
+	printf("** Can't write to device %d **\n", dev_desc->dev);
+	return -1;
+}
+
+int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+		disk_partition_t *partitions, int parts)
+{
+	u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba);
+	ulong start;
+	int i, k;
+	size_t efiname_len, dosname_len;
+#ifdef CONFIG_PARTITION_UUIDS
+	char *str_uuid;
+#endif
+
+	for (i = 0; i < parts; i++) {
+		/* partition starting lba */
+		start = partitions[i].start;
+		if (start && (start < offset)) {
+			printf("Partition overlap\n");
+			return -1;
+		}
+		if (start) {
+			gpt_e[i].starting_lba = cpu_to_le64(start);
+			offset = start + partitions[i].size;
+		} else {
+			gpt_e[i].starting_lba = cpu_to_le64(offset);
+			offset += partitions[i].size;
+		}
+		if (offset >= gpt_h->last_usable_lba) {
+			printf("Partitions layout exceds disk size\n");
+			return -1;
+		}
+		/* partition ending lba */
+		if ((i == parts - 1) && (partitions[i].size == 0))
+			/* extend the last partition to maximuim */
+			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+		else
+			gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
+
+		/* partition type GUID */
+		memcpy(gpt_e[i].partition_type_guid.b,
+			&PARTITION_BASIC_DATA_GUID, 16);
+
+#ifdef CONFIG_PARTITION_UUIDS
+		str_uuid = partitions[i].uuid;
+		if (string_uuid(str_uuid, gpt_e[i].unique_partition_guid.b)) {
+			printf("Partition no. %d: invalid guid: %s\n",
+				i, str_uuid);
+			return -1;
+		}
+#endif
+
+		/* partition attributes */
+		memset(&gpt_e[i].attributes, 0,
+		       sizeof(gpt_entry_attributes));
+
+		/* partition name */
+		efiname_len = sizeof(gpt_e[i].partition_name)
+			/ sizeof(efi_char16_t);
+		dosname_len = sizeof(partitions[i].name);
+
+		memset(gpt_e[i].partition_name, 0,
+		       sizeof(gpt_e[i].partition_name));
+
+		for (k = 0; k < min(dosname_len, efiname_len); k++)
+			gpt_e[i].partition_name[k] =
+				(efi_char16_t)(partitions[i].name[k]);
+
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
+		      __func__, partitions[i].name, i,
+		      offset, i, partitions[i].size);
 	}
+
 	return 0;
 }
 
+int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+		char *str_guid, int parts_count)
+{
+	gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
+	gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
+	gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
+	gpt_h->my_lba = cpu_to_le64(1);
+	gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+	gpt_h->first_usable_lba = cpu_to_le64(34);
+	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+	gpt_h->partition_entry_lba = cpu_to_le64(2);
+	gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
+	gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
+	gpt_h->header_crc32 = 0;
+	gpt_h->partition_entry_array_crc32 = 0;
+
+	if (string_uuid(str_guid, gpt_h->disk_guid.b))
+		return -1;
+
+	return 0;
+}
+
+int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
+		disk_partition_t *partitions, int parts_count)
+{
+	int ret;
+
+	gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header),
+						       dev_desc));
+	gpt_entry *gpt_e;
+
+	if (gpt_h == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+
+	gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
+					       * sizeof(gpt_entry),
+					       dev_desc));
+	if (gpt_e == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		free(gpt_h);
+		return -1;
+	}
+
+	/* Generate Primary GPT header (LBA1) */
+	ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count);
+	if (ret)
+		goto err;
+
+	/* Generate partition entries */
+	ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count);
+	if (ret)
+		goto err;
+
+	/* Write GPT partition table */
+	ret = write_gpt_table(dev_desc, gpt_h, gpt_e);
+
+err:
+	free(gpt_e);
+	free(gpt_h);
+	return ret;
+}
+#endif
+
 /*
  * Private functions
  */
@@ -206,7 +500,7 @@
 static int pmbr_part_valid(struct partition *part)
 {
 	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-		le32_to_int(part->start_sect) == 1UL) {
+		get_unaligned_le32(&part->start_sect) == 1UL) {
 		return 1;
 	}
 
@@ -225,9 +519,8 @@
 {
 	int i = 0;
 
-	if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
 		return 0;
-	}
 
 	for (i = 0; i < 4; i++) {
 		if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -250,12 +543,12 @@
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-	unsigned char crc32_backup[4] = { 0 };
-	unsigned long calc_crc32;
+	u32 crc32_backup = 0;
+	u32 calc_crc32;
 	unsigned long long lastlba;
 
 	if (!dev_desc || !pgpt_head) {
-		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+		printf("%s: Invalid Argument(s)\n", __func__);
 		return 0;
 	}
 
@@ -266,54 +559,54 @@
 	}
 
 	/* Check the GPT header signature */
-	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
 		printf("GUID Partition Table Header signature is wrong:"
 			"0x%llX != 0x%llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->signature),
-			(unsigned long long)GPT_HEADER_SIGNATURE);
+			le64_to_cpu(pgpt_head->signature),
+			GPT_HEADER_SIGNATURE);
 		return 0;
 	}
 
 	/* Check the GUID Partition Table CRC */
-	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
 	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-		le32_to_int(pgpt_head->header_size));
+		le32_to_cpu(pgpt_head->header_size));
 
-	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-	if (calc_crc32 != le32_to_int(crc32_backup)) {
+	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
 		printf("GUID Partition Table Header CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(crc32_backup), calc_crc32);
+			"0x%x != 0x%x\n",
+		       le32_to_cpu(crc32_backup), calc_crc32);
 		return 0;
 	}
 
 	/* Check that the my_lba entry points to the LBA that contains the GPT */
-	if (le64_to_int(pgpt_head->my_lba) != lba) {
+	if (le64_to_cpu(pgpt_head->my_lba) != lba) {
 		printf("GPT: my_lba incorrect: %llX != %llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->my_lba),
-			(unsigned long long)lba);
+			le64_to_cpu(pgpt_head->my_lba),
+			lba);
 		return 0;
 	}
 
 	/* Check the first_usable_lba and last_usable_lba are within the disk. */
 	lastlba = (unsigned long long)dev_desc->lba;
-	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
 		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->first_usable_lba), lastlba);
+			le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
 		return 0;
 	}
-	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
 		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->last_usable_lba), lastlba);
+			(u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 		return 0;
 	}
 
 	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-		le64_to_int(pgpt_head->first_usable_lba),
-		le64_to_int(pgpt_head->last_usable_lba), lastlba);
+		le64_to_cpu(pgpt_head->first_usable_lba),
+		le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
 	/* Read and allocate Partition Table Entries */
 	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -324,18 +617,16 @@
 
 	/* Check the GUID Partition Table Entry Array CRC */
 	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-		le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry));
+		le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
 		printf("GUID Partition Table Entry Array CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(pgpt_head->partition_entry_array_crc32),
+			"0x%x != 0x%x\n",
+			le32_to_cpu(pgpt_head->partition_entry_array_crc32),
 			calc_crc32);
 
-		if (*pgpt_pte != NULL) {
-			free(*pgpt_pte);
-		}
+		free(*pgpt_pte);
 		return 0;
 	}
 
@@ -355,37 +646,40 @@
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 					 gpt_header * pgpt_head)
 {
-	size_t count = 0;
+	size_t count = 0, blk_cnt;
 	gpt_entry *pte = NULL;
 
 	if (!dev_desc || !pgpt_head) {
-		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+		printf("%s: Invalid Argument(s)\n", __func__);
 		return NULL;
 	}
 
-	count = le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry);
+	count = le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-	debug("%s: count = %lu * %lu = %u\n", __FUNCTION__,
-		le32_to_int(pgpt_head->num_partition_entries),
-		le32_to_int(pgpt_head->sizeof_partition_entry), count);
+	debug("%s: count = %u * %u = %zu\n", __func__,
+	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
-		pte = malloc(count);
+		pte = memalign(ARCH_DMA_MINALIGN,
+			       PAD_TO_BLOCKSIZE(count, dev_desc));
 	}
 
 	if (count == 0 || pte == NULL) {
-		printf("%s: ERROR: Can't allocate 0x%X bytes for GPT Entries\n",
-			__FUNCTION__, count);
+		printf("%s: ERROR: Can't allocate 0x%zX "
+		       "bytes for GPT Entries\n",
+			__func__, count);
 		return NULL;
 	}
 
 	/* Read GPT Entries from device */
+	blk_cnt = BLOCK_CNT(count, dev_desc);
 	if (dev_desc->block_read (dev_desc->dev,
-		(unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
-		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
-		!= (count / GPT_BLOCK_SIZE)) {
+		le64_to_cpu(pgpt_head->partition_entry_lba),
+		(lbaint_t) (blk_cnt), pte)
+		!= blk_cnt) {
 
 		printf("*** ERROR: Can't read GPT Entries ***\n");
 		free(pte);
@@ -405,7 +699,7 @@
 	efi_guid_t unused_guid;
 
 	if (!pte) {
-		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+		printf("%s: Invalid Argument(s)\n", __func__);
 		return 0;
 	}
 
@@ -417,8 +711,8 @@
 	if (memcmp(pte->partition_type_guid.b, unused_guid.b,
 		sizeof(unused_guid.b)) == 0) {
 
-		debug("%s: Found an unused PTE GUID at 0x%08X\n", __FUNCTION__,
-		(unsigned int)pte);
+		debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__,
+		      (unsigned int)(uintptr_t)pte);
 
 		return 0;
 	} else {
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_assemble.c u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_assemble.c
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_assemble.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_assemble.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2003-2011, Cavium Networks. All rights reserved.
+ *
+ * This Software is the property of Cavium Networks.  The Software and all
+ * accompanying documentation are copyrighted.  The Software made available
+ * here constitutes the proprietary information of Cavium Networks.  You
+ * agree to take reasonable steps to prevent the disclosure, unauthorized use
+ * or unauthorized distribution of the Software.  You shall use this Software
+ * solely with Cavium hardware.
+ *
+ * Except as expressly permitted in a separate Software License Agreement
+ * between You and Cavium Networks, you shall not modify, decompile,
+ * disassemble, extract, or otherwise reverse engineer this Software.  You
+ * shall not make any copy of the Software or its accompanying documentation,
+ * except for copying incident to the ordinary and intended use of the
+ * Software and the Underlying Program and except for the making of a single
+ * archival copy.
+ *
+ * This Software, including technical data, may be subject to U.S.  export
+ * control laws, including the U.S.  Export Administration Act and its
+ * associated regulations, and may be subject to export or import regulations
+ * in other countries.  You warrant that You will comply strictly in all
+ * respects with all such regulations and acknowledge that you have the
+ * responsibility to obtain licenses to export, re-export or import the
+ * Software.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
+ * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
+ * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
+ * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
+ * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
+ * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
+ * POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ *
+ */
+
+#include "common.h"
+#include "cnc_edid.h"
+
+// Not checking edid_valid anywhere in here yet.
+// Philosophical question: should bounds check here or in parser?  It's not here now.
+
+int cnc_edid_assemble_header(cnc_edid_t *edid) {
+    unsigned char header[EDID_HEADER_LENGTH] = EDID_HEADER_INITIALIZER;
+    memcpy(edid->edid_bin, header, EDID_HEADER_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_vendor_product_id(cnc_edid_t *edid) {
+    unsigned char byte0, byte1, tmp;
+    byte0 = (edid->id_mfg_name[0] - '@') << 2;
+    byte0 &= 0x7c;
+    tmp = edid->id_mfg_name[1] - '@';
+    byte0 |= (tmp & 0x18) >> 3;
+    byte1 = (tmp & 7) << 5;
+    byte1 |= edid->id_mfg_name[2] - '@';
+    edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+0] = byte0;
+    edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+1] = byte1;
+    EDID_ASSEMBLE_INT_TO_SHORT(edid->edid_bin+EDID_ID_PRODUCT_CODE_OFFSET, edid->id_product_code);
+    EDID_ASSEMBLE_INT_TO_LONG(edid->edid_bin+EDID_ID_SERIAL_NUMBER_OFFSET, edid->id_serial_number);
+    edid->edid_bin[EDID_WEEK_OF_MFG_OFFSET] = edid->week_of_mfg;
+    edid->edid_bin[EDID_YEAR_OF_MFG_OFFSET] = edid->year_of_mfg;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_version(cnc_edid_t *edid) {
+    edid->edid_bin[EDID_VERSION_OFFSET] = edid->version;
+    edid->edid_bin[EDID_REVISION_OFFSET] = edid->revision;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_display_params(cnc_edid_t *edid) {
+    if(edid->signal_interface == EDID_VIDEO_INPUT_DEF_SIGNAL_INT_DIGITAL) {
+        edid->edid_bin[EDID_VIDEO_INPUT_DEF_OFFSET] = EDID_VIDEO_INPUT_DEF_SIGNAL_INT_MASK |
+                (edid->color_bit_depth << EDID_VIDEO_INPUT_DEF_COLOR_DEPTH_SHIFT) |
+                edid->interface_std;
+    }
+    else {   // EDID_VIDEO_INPUT_DEF_SIGNAL_INT_ANALOG
+        edid->edid_bin[EDID_DISPLAY_PARAMS_OFFSET] = edid->video_input_def;
+    }
+    edid->edid_bin[EDID_VIDEO_INPUT_HORIZONTAL_OFFSET] = edid->horizontal;
+    edid->edid_bin[EDID_VIDEO_INPUT_VERTICAL_OFFSET] = edid->vertical;
+    edid->edid_bin[EDID_VIDEO_INPUT_GAMMA_OFFSET] = edid->gamma;
+    edid->edid_bin[EDID_VIDEO_INPUT_FEATURE_SUPPORT_OFFSET] = edid->feature_support;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_chromaticity(cnc_edid_t *edid) {
+    int lo_0, lo_1;
+    lo_0 = ((edid->chromaticity[EDID_CHROMATICITY_Rx_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_RxLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_Ry_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_RyLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_Gx_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_GxLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_Gy_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_GyLo_SHIFT);
+    lo_1 = ((edid->chromaticity[EDID_CHROMATICITY_Bx_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_BxLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_By_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_ByLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_Wx_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_WxLo_SHIFT) |
+           ((edid->chromaticity[EDID_CHROMATICITY_Wy_INDEX] & EDID_CHROMATICITY_LoByte_MASK) << EDID_CHROMATICITY_WyLo_SHIFT);
+    edid->edid_bin[EDID_CHROMATICITY_RxLo_OFFSET] = lo_0;
+    edid->edid_bin[EDID_CHROMATICITY_BxLo_OFFSET] = lo_1;
+    edid->edid_bin[EDID_CHROMATICITY_RxHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Rx_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_RyHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Ry_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_GxHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Gx_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_GyHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Gy_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_BxHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Bx_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_ByHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_By_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_WxHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Wx_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    edid->edid_bin[EDID_CHROMATICITY_WyHi_OFFSET] = edid->chromaticity[EDID_CHROMATICITY_Wy_INDEX] >> EDID_CHROMATICITY_HiByte_SHIFT;
+    return EDID_SUCCESS;
+}
+
+// return true if the resolution is found in the list
+int edid_search_established_timing(cnc_edid_t *edid, int h, int v, int hz, int interlaced) {
+    int i;
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if(edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+            cnc_edid_timing_t *timing = &(edid->timings[i]);
+            if(timing->h_active == h &&
+                    timing->v_active == v &&
+                    timing->v_frequency == hz) {
+                if(timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) {
+                    return interlaced ? 1 : 0;
+                }
+                else {
+                    return interlaced ? 0 : 1;
+                }
+            }
+        }
+    return 0;
+}
+
+int cnc_edid_assemble_established_timings(cnc_edid_t *edid) {
+    edid->edid_bin[EDID_ESTABLISHED_TIMINGS_I_OFFSET] =
+        (edid_search_established_timing(edid, 720, 400, 70, 0)   ? 0x80 : 0) |
+        (edid_search_established_timing(edid, 720, 400, 88, 0)   ? 0x40 : 0) |
+        (edid_search_established_timing(edid, 640, 480, 60, 0)   ? 0x20 : 0) |
+        (edid_search_established_timing(edid, 640, 480, 67, 0)   ? 0x10 : 0) |
+        (edid_search_established_timing(edid, 640, 480, 72, 0)   ? 8 : 0) |
+        (edid_search_established_timing(edid, 640, 480, 75, 0)   ? 4 : 0) |
+        (edid_search_established_timing(edid, 800, 600, 56, 0)   ? 2 : 0) |
+        (edid_search_established_timing(edid, 800, 600, 60, 0)   ? 1 : 0);
+    edid->edid_bin[EDID_ESTABLISHED_TIMINGS_II_OFFSET] =
+        (edid_search_established_timing(edid, 800, 600, 72, 0)   ? 0x80 : 0) |
+        (edid_search_established_timing(edid, 800, 600, 75, 0)   ? 0x40 : 0) |
+        (edid_search_established_timing(edid, 832, 624, 75, 0)   ? 0x20 : 0) |
+        (edid_search_established_timing(edid, 1024, 768, 87, 1)  ? 0x10 : 0) |
+        (edid_search_established_timing(edid, 1024, 768, 60, 0)  ? 8 : 0) |
+        (edid_search_established_timing(edid, 1024, 768, 70, 0)  ? 4 : 0) |
+        (edid_search_established_timing(edid, 1024, 768, 75, 0)  ? 2 : 0) |
+        (edid_search_established_timing(edid, 1280, 1024, 75, 0) ? 1 : 0);
+    edid->edid_bin[EDID_ESTABLISHED_TIMINGS_MFG_OFFSET] =
+        edid_search_established_timing(edid, 1152, 870, 75, 0)  ? 0x80 : 0;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_standard_timings(cnc_edid_t *edid) {
+    int i;
+    int std_timings_count=0;
+    unsigned char *b0 = edid->edid_bin+EDID_STANDARD_TIMINGS_OFFSET;
+    unsigned char *b1 = b0+1;
+    int flags = (EDID_TIMING_IFLAGS_ENTRY_VALID |
+                 EDID_TIMING_IFLAGS_AR_VALID |
+                 EDID_TIMING_IFLAGS_V_FREQ_VALID |
+                 EDID_TIMING_IFLAGS_LOCATION_STD);
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++) {
+        if((edid->timings[i].internal_flags & flags) == flags) {
+            int ar;
+            cnc_edid_timing_t *timing = &(edid->timings[i]);
+            if(timing->ar_numerator == 16 && timing->ar_denominator == 10) {
+                ar = 0;
+            }
+            else if(timing->ar_numerator == 4 && timing->ar_denominator == 3) {
+                ar = 0x40;
+            }
+            else if(timing->ar_numerator == 5 && timing->ar_denominator == 4) {
+                ar = 0x80;
+            }
+            else if(timing->ar_numerator == 16 && timing->ar_denominator == 9) {
+                ar = 0xc0;
+            }
+            else {
+                printf("%s: weird Aspect Ratio found (%d:%d), skipping\n", __FUNCTION__, timing->ar_numerator, timing->ar_denominator);
+                continue;
+            }
+            *b0 = (timing->h_active - 248) / 8; // VESA EEDID spec table 3.19
+            *b1 = ar | ((timing->v_frequency - 60) & EDID_STANDARD_TIMINGS_FIELD_REFRESH_MASK);
+            b0 += EDID_STANDARD_TIMINGS_LENGTH_EACH;
+            b1 += EDID_STANDARD_TIMINGS_LENGTH_EACH;
+            if(++std_timings_count >= EDID_STANDARD_TIMINGS_COUNT) {
+                break;
+            }
+        }
+    }
+    for(; std_timings_count < EDID_STANDARD_TIMINGS_COUNT; std_timings_count++) {
+        *b0 = *b1 = 1;
+        b0 += EDID_STANDARD_TIMINGS_LENGTH_EACH;
+        b1 += EDID_STANDARD_TIMINGS_LENGTH_EACH;
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_dtd(cnc_edid_t *edid, int offset, int timing_index) {
+    unsigned char *block = edid->edid_bin + offset;
+    cnc_edid_timing_t *timing = &(edid->timings[timing_index]);
+    int pixclk_scaled = timing->pixel_clock / EDID_DTD_PIXEL_CLOCK_MULTIPLIER;
+    block[EDID_DTD_PIXEL_CLOCK_LO_OFFSET] = pixclk_scaled & 0xff;
+    block[EDID_DTD_PIXEL_CLOCK_HI_OFFSET] = pixclk_scaled >> 8;
+    block[EDID_DTD_H_ACTIVE_LO_OFFSET] = timing->h_active & EDID_DTD_LO_MASK;
+    block[EDID_DTD_H_BLANK_LO_OFFSET] = timing->h_blank & EDID_DTD_LO_MASK;
+    block[EDID_DTD_H_ACTIVE_HI_OFFSET] =
+        ((timing->h_active >> EDID_DTD_H_ACTIVE_HI_SHIFT) & EDID_DTD_H_ACTIVE_HI_MASK) |
+        ((timing->h_blank  >> EDID_DTD_H_BLANK_HI_SHIFT) & EDID_DTD_H_BLANK_HI_MASK);
+    block[EDID_DTD_V_ACTIVE_LO_OFFSET] = timing->v_active & EDID_DTD_LO_MASK;
+    block[EDID_DTD_V_BLANK_LO_OFFSET] = timing->v_blank & EDID_DTD_LO_MASK;
+    block[EDID_DTD_V_ACTIVE_HI_OFFSET] =
+        ((timing->v_active >> EDID_DTD_V_ACTIVE_HI_SHIFT) & EDID_DTD_V_ACTIVE_HI_MASK) |
+        ((timing->v_blank >> EDID_DTD_V_BLANK_HI_SHIFT) & EDID_DTD_V_BLANK_HI_MASK);
+    block[EDID_DTD_H_FRONT_PORCH_LO_OFFSET] = timing->h_front_porch & EDID_DTD_LO_MASK;
+    block[EDID_DTD_H_SYNC_WIDTH_LO_OFFSET] = timing->h_sync_width & EDID_DTD_LO_MASK;
+    block[EDID_DTD_V_FRONT_PORCH_LO_OFFSET] =
+        ((timing->v_front_porch << EDID_DTD_V_FRONT_PORCH_LO_SHIFT) & EDID_DTD_V_FRONT_PORCH_LO_MASK) |
+        ((timing->v_sync_width << EDID_DTD_V_SYNC_WIDTH_LO_SHIFT) & EDID_DTD_V_SYNC_WIDTH_LO_MASK);
+    block[EDID_DTD_H_FRONT_PORCH_HI_OFFSET] =
+        ((timing->h_front_porch >> EDID_DTD_H_FRONT_PORCH_HI_SHIFT) & EDID_DTD_H_FRONT_PORCH_HI_MASK) |
+        ((timing->h_sync_width >> EDID_DTD_H_SYNC_WIDTH_HI_SHIFT) & EDID_DTD_H_SYNC_WIDTH_HI_MASK) |
+        ((timing->v_front_porch >> EDID_DTD_V_FRONT_PORCH_HI_SHIFT) & EDID_DTD_V_FRONT_PORCH_HI_MASK) |
+        ((timing->v_sync_width >> EDID_DTD_V_SYNC_WIDTH_HI_SHIFT) & EDID_DTD_V_SYNC_WIDTH_HI_MASK);
+    block[EDID_DTD_H_SIZE_MM_LO_OFFSET] = timing->h_size_mm & EDID_DTD_LO_MASK;
+    block[EDID_DTD_V_SIZE_MM_LO_OFFSET] = timing->v_size_mm & EDID_DTD_LO_MASK;
+    block[EDID_DTD_H_SIZE_MM_HI_OFFSET] =
+        ((timing->h_size_mm >> EDID_DTD_H_SIZE_MM_HI_SHIFT) & EDID_DTD_H_SIZE_MM_HI_MASK) |
+        ((timing->v_size_mm >> EDID_DTD_V_SIZE_MM_HI_SHIFT) & EDID_DTD_V_SIZE_MM_HI_MASK);
+    block[EDID_DTD_BORDER_WIDTH_OFFSET] = timing->border_width;
+    block[EDID_DTD_BORDER_HEIGHT_OFFSET] = timing->border_height;
+    block[EDID_DTD_FLAGS_OFFSET] = timing->timing_flags;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_display_descriptor(cnc_edid_t *edid, int block_offset, int display_desc_type) {
+    int i;
+    switch(display_desc_type) {
+    case EDID_DISPLAY_DESC_DUMMY: {
+        for(i=0; i<EDID_18B_BLOCK_LENGTH; i++) {
+            edid->edid_bin[block_offset++] = (i == 3) ? EDID_DISPLAY_DESC_DUMMY : 0;
+        }
+        break;
+    }
+    case EDID_DISPLAY_DESC_DISPLAY_PRODUCT_NAME: {
+        char *name = (char *)edid->edid_bin + block_offset + EDID_DISPLAY_DESC_STRING_OFFSET;
+        for(i=0; i<3; i++) {
+            edid->edid_bin[block_offset++] = 0;
+        }
+        edid->edid_bin[block_offset++] = EDID_DISPLAY_DESC_DISPLAY_PRODUCT_NAME;
+        strncpy(name, edid->display_product_name, EDID_DISPLAY_DESC_STRING_LENGTH);
+        break;
+    }
+    case EDID_DISPLAY_DESC_DISPLAY_RANGE_LIMITS: {
+        int rate_v_min, rate_v_max, rate_h_min, rate_h_max;
+        int rate_v_min_shift=0, rate_v_max_shift=0, rate_h_min_shift=0, rate_h_max_shift=0;
+        int offset = block_offset;
+        for(i=0; i<3; i++) {
+            edid->edid_bin[offset++] = 0;
+        }
+        edid->edid_bin[offset] = EDID_DISPLAY_DESC_DISPLAY_RANGE_LIMITS;
+        rate_v_min = edid->rate_v_min;
+        if(rate_v_min > 255) {
+            rate_v_min -= 255;
+            rate_v_min_shift = EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MIN;
+        }
+        rate_v_max = edid->rate_v_max;
+        if(rate_v_max > 255) {
+            rate_v_max -= 255;
+            rate_v_max_shift = EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MAX;
+        }
+        rate_h_min = edid->rate_h_min;
+        if(rate_h_min > 255) {
+            rate_h_min -= 255;
+            rate_h_min_shift = EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MIN;
+        }
+        rate_h_max = edid->rate_h_max;
+        if(rate_h_max > 255) {
+            rate_h_max -= 255;
+            rate_h_max_shift = EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MAX;
+        }
+        edid->edid_bin[block_offset + EDID_DISPLAY_RANGE_LIMITS_OFFSET] =
+            rate_v_min_shift | rate_v_max_shift | rate_h_min_shift | rate_h_max_shift;
+        edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_V_MIN_OFFSET] = rate_v_min;
+        edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_V_MAX_OFFSET] = rate_v_max;
+        edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_H_MIN_OFFSET] = rate_h_min;
+        edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_H_MAX_OFFSET] = rate_h_max;
+        edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MAX_OFFSET] =
+            edid->rate_pixel_clock_max / EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MULTIPLIER;
+        // FIXME: Byte 10 GTF support???
+        offset = EDID_DISPLAY_RANGE_LIMITS_GTF_OFFSET;
+        edid->edid_bin[block_offset+offset++] = 0;
+        edid->edid_bin[block_offset+offset++] = 0xa;
+        while(offset<EDID_18B_BLOCK_LENGTH) {
+            edid->edid_bin[block_offset+offset++] = 0x20;
+        }
+        break;
+    }
+    case EDID_DISPLAY_DESC_DISPLAY_SERIAL_NUMBER: {
+        char *name = (char *)edid->edid_bin + block_offset + EDID_DISPLAY_DESC_STRING_OFFSET;
+        for(i=0; i<3; i++) {
+            edid->edid_bin[block_offset++] = 0;
+        }
+        edid->edid_bin[block_offset++] = EDID_DISPLAY_DESC_DISPLAY_SERIAL_NUMBER;
+        strncpy(name, edid->display_serial_number, EDID_DISPLAY_DESC_STRING_LENGTH);
+        break;
+    }
+    default:
+        printf("%s: WARNING: Reserved or Mfg-specified display descriptor type 0x%02x\n", __FUNCTION__, display_desc_type);
+        return EDID_ERROR;
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_main_18_byte_blocks(cnc_edid_t *edid) {
+    int i, s=0; // s is a counter of 18 byte blocks that have been filled
+    int flags = (EDID_TIMING_IFLAGS_ENTRY_VALID |
+                 EDID_TIMING_IFLAGS_AR_VALID |
+                 EDID_TIMING_IFLAGS_V_FREQ_VALID |
+                 EDID_TIMING_IFLAGS_LOCATION_MAIN_18B);
+    int save_timing_indices[2];
+    unsigned char offset = EDID_MAIN_18B_OFFSET;
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if((edid->timings[i].internal_flags & flags) == flags) {
+            save_timing_indices[s++] = i;
+            if(s == 2) {
+                break;
+            }
+        }
+    for(i=0; i<s; i++) {
+        cnc_edid_assemble_dtd(edid, offset, save_timing_indices[i]);
+        offset += EDID_18B_BLOCK_LENGTH;
+    }
+    if(edid->edid_valid | EDID_VALID_DISPLAY_PRODUCT_NAME) {
+        cnc_edid_assemble_display_descriptor(edid, offset, EDID_DISPLAY_DESC_DISPLAY_PRODUCT_NAME);
+        offset += EDID_18B_BLOCK_LENGTH;
+        s++;
+    }
+    if(edid->edid_valid | EDID_VALID_DISPLAY_RANGE_LIMITS) {
+        cnc_edid_assemble_display_descriptor(edid, offset, EDID_DISPLAY_DESC_DISPLAY_RANGE_LIMITS);
+        offset += EDID_18B_BLOCK_LENGTH;
+        s++;
+    }
+    if(s < 4 && edid->edid_valid | EDID_VALID_DISPLAY_SERIAL_NUMBER) {
+        cnc_edid_assemble_display_descriptor(edid, offset, EDID_DISPLAY_DESC_DISPLAY_SERIAL_NUMBER);
+        offset += EDID_18B_BLOCK_LENGTH;
+        s++;
+    }
+    while(s<4) {
+        cnc_edid_assemble_display_descriptor(edid, offset, EDID_DISPLAY_DESC_DUMMY);
+        offset += EDID_18B_BLOCK_LENGTH;
+        s++;
+    }
+    return EDID_SUCCESS;
+}
+
+// responsible for setting edid->ext_blocks_count and setting its valid bit
+int cnc_edid_assemble_extension_blocks_count(cnc_edid_t *edid) {
+    edid->edid_bin[EDID_EXT_BLOCKS_COUNT] = edid->ext_blocks_count;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_checksum(cnc_edid_t *edid, int block_num) {
+    int i, checksum = 0;
+    unsigned char *block_p = edid->edid_bin+EDID_EXT_BLOCK_OFFSET(block_num);
+    block_p[EDID_CHECKSUM_OFFSET] = 0;
+    for(i=0; i<EDID_BLOCK_LENGTH; i++) {
+        checksum += block_p[i];
+    }
+    block_p[EDID_CHECKSUM_OFFSET] = 0x100-checksum;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_main(cnc_edid_t *edid) {
+    int ret;
+    ret  = cnc_edid_assemble_header(edid);
+    ret |= cnc_edid_assemble_vendor_product_id(edid);
+    ret |= cnc_edid_assemble_version(edid);
+    ret |= cnc_edid_assemble_display_params(edid);
+    ret |= cnc_edid_assemble_chromaticity(edid);
+    ret |= cnc_edid_assemble_established_timings(edid);
+    ret |= cnc_edid_assemble_standard_timings(edid);
+    ret |= cnc_edid_assemble_main_18_byte_blocks(edid);
+    ret |= cnc_edid_assemble_extension_blocks_count(edid);
+    ret |= cnc_edid_assemble_checksum(edid, 0); // block 0
+    if(ret == EDID_SUCCESS) {
+        ret = edid->ext_blocks_count;
+    }
+    return ret;
+}
+
+int cnc_edid_assemble_ext_video_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    int i;
+    int flags = (EDID_TIMING_IFLAGS_ENTRY_VALID |
+                 EDID_TIMING_IFLAGS_LOCATION_SVD);
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if((edid->timings[i].internal_flags & flags) == flags) {
+            *current_p++ = edid->timings[i].vic |
+                           ((edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_NATIVE) ?
+                            EDID_EXT_BLOCK_TYPE_VIDEO_NATIVE_MASK : 0);
+        }
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_VIDEO << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_audio_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    int i;
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    for(i=0; i<EDID_AUDIO_STORAGE_SIZE; i++)
+        if(edid->audio_formats[i].format != EDID_AUDIO_FORMAT_RESERVED) {
+            *current_p++ =
+                (edid->audio_formats[i].format << EDID_EXT_BLOCK_SAD_FORMAT_CODE_SHIFT) |
+                (edid->audio_formats[i].max_channels-1);
+            *current_p++ = edid->audio_formats[i].frequencies;
+            *current_p++ = edid->audio_formats[i].extra_data;
+        }
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_AUDIO << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_speaker_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    *current_p++ = edid->speaker_alloc & EDID_SPEAKER_BYTE1_MASK;
+    *current_p++ = edid->speaker_alloc >> EDID_SPEAKER_BYTE2_SHIFT;
+    *current_p++ = EDID_SPEAKER_BYTE3_VALUE;
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_SPEAKER << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_vendor_specific_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    int i;
+    for(i=0; i<edid->vendor_specific_length; i++) {
+        *current_p++ = edid->vendor_specific[i];
+    }
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_VENDOR_SPECIFIC << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_vidcap_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    *current_p++ = EDID_EXT_BLOCK_TYPE_EXTENDED_VIDCAP;
+    *current_p++ = edid->video_capability;
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_EXTENDED << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_colorimetry_block(cnc_edid_t *edid, unsigned char **assemble_p) {
+    unsigned char *block_p = *assemble_p;
+    unsigned char *current_p = block_p+1;
+    *current_p++ = EDID_EXT_BLOCK_TYPE_EXTENDED_COLORIMETRY;
+    *current_p++ = edid->colorimetry & EDID_COLORIMETRY_BYTE1_MASK;
+    *current_p++ = edid->colorimetry >> EDID_COLORIMETRY_BYTE2_SHIFT;
+    *block_p =
+        (EDID_EXT_BLOCK_TYPE_EXTENDED << EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT) |
+        ((current_p - block_p)-1);
+    *assemble_p = current_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_ext_18b_blocks(cnc_edid_t *edid, unsigned char **assemble_p) {
+    int i;
+    int flags = (EDID_TIMING_IFLAGS_ENTRY_VALID |
+                 EDID_TIMING_IFLAGS_LOCATION_EXT_18B);
+    unsigned char *block_p = *assemble_p;
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if((edid->timings[i].internal_flags & flags) == flags) {
+            cnc_edid_assemble_dtd(edid, block_p-edid->edid_bin, i);
+            block_p += EDID_18B_BLOCK_LENGTH;
+        }
+    *assemble_p = block_p;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_assemble_extensions(cnc_edid_t *edid) {
+    int ret=EDID_SUCCESS;
+    unsigned char *block_p = edid->edid_bin+EDID_EXT_BLOCK_OFFSET(1);
+    unsigned char *current_p = block_p+EDID_EXT_BLOCK_DATA_BLOCKS_OFFSET;
+    block_p[EDID_EXT_BLOCK_TAG_OFFSET] = EDID_EXT_BLOCK_TAG_EXPECTED_VALUE;
+    block_p[EDID_EXT_BLOCK_REVISION_OFFSET] = EDID_EXT_BLOCK_REVISION_EXPECTED_VALUE;
+    // FIXME: make sure the native-formats counter within this field is updated
+    block_p[EDID_EXT_BLOCK_FLAGS_OFFSET] = edid->eedid_flags;
+    if(edid->edid_valid & EDID_VALID_SVDS_PRESENT) {
+        cnc_edid_assemble_ext_video_block(edid, &current_p);
+    }
+    if(edid->edid_valid & EDID_VALID_AUDIO_FORMATS) {
+        cnc_edid_assemble_ext_audio_block(edid, &current_p);
+    }
+    if(edid->edid_valid & EDID_VALID_SPEAKER_ALLOC) {
+        cnc_edid_assemble_ext_speaker_block(edid, &current_p);
+    }
+    if(edid->edid_valid & EDID_VALID_VENDOR_SPECIFIC) {
+        cnc_edid_assemble_ext_vendor_specific_block(edid, &current_p);
+    }
+    if(edid->edid_valid & EDID_VALID_VIDEO_CAPABILITY) {
+        cnc_edid_assemble_ext_vidcap_block(edid, &current_p);
+    }
+    if(edid->edid_valid & EDID_VALID_COLORIMETRY) {
+        cnc_edid_assemble_ext_colorimetry_block(edid, &current_p);
+    }
+    block_p[EDID_EXT_BLOCK_18B_BLOCK_START_OFFSET] = current_p - block_p;
+    cnc_edid_assemble_ext_18b_blocks(edid, &current_p);
+    while((current_p - block_p) < EDID_EXT_BLOCK_SIZE) {
+        *current_p++ = 0;
+    }
+    ret |= cnc_edid_assemble_checksum(edid, 1); // block 1
+    return EDID_SUCCESS;
+}
+
+// creates the binary version of the edid from the data in the cnc_edid_t
+int cnc_edid_assemble(cnc_edid_t *edid) {
+    int ret;
+// This if 0 version would allow the assembler to determine the number of ext blocks
+//  necessary and pass that number to the main block for inclusion as the n_ext_blocks.
+// As it is now there is only ever zero or one, so the 2nd version is more manageable.
+#if 0
+    ret = cnc_edid_assemble_extensions(edid);
+    ret |= cnc_edid_assemble_main(edid);
+    if(ret == EDID_SUCCESS) {
+        edid->edid_bin_valid = EDID_BIN_VALID;
+    }
+#else
+    ret = cnc_edid_assemble_main(edid);
+    if(ret == EDID_ERROR) {
+        printf("%s: main block assembly failed, giving up\n", __FUNCTION__);
+        return ret;
+    }
+    if(ret) {
+        ret = cnc_edid_assemble_extensions(edid);
+    }
+    if(ret == EDID_SUCCESS) {
+        edid->edid_bin_valid = EDID_BIN_VALID;
+    }
+#endif
+    return ret;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid.h u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid.h
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,664 @@
+#ifndef __EDID_H
+#define __EDID_H
+
+typedef enum
+{
+	CSAUD_HDMI_PCM_DOWN_MIX = 0,
+	CSAUD_HDMI_PCM_MULTI_CHANNEL,
+	CSAUD_HDMI_DOLBY_DIGITAL,
+	CSAUD_HDMI_DOLBY_DIGITAL_PLUS,
+	CSAUD_HDMI_HBR,
+	CSAUD_HDMI_MAX
+}CSAUD_HDMI_MODE;
+
+#define EDID_TEST
+
+#define EDID_MAX_BIN_LENGTH                      1024
+
+#define EDID_BLOCK_LENGTH                        0x80
+
+#define EDID_HEADER_OFFSET                       0
+#define EDID_HEADER_LENGTH                       8
+
+#define EDID_VENDOR_PRODUCT_ID_OFFSET            0x8
+#define EDID_VENDOR_PRODUCT_ID_LENGTH            10
+#define EDID_ID_MFG_NAME_OFFSET                  EDID_VENDOR_PRODUCT_ID_OFFSET
+#define EDID_ID_MFG_NAME_LENGTH                  2
+#define EDID_ID_PRODUCT_CODE_OFFSET              \
+    (EDID_ID_MFG_NAME_OFFSET + EDID_ID_MFG_NAME_LENGTH)
+#define EDID_ID_PRODUCT_CODE_LENGTH              2
+#define EDID_ID_SERIAL_NUMBER_OFFSET             \
+    (EDID_ID_PRODUCT_CODE_OFFSET + EDID_ID_PRODUCT_CODE_LENGTH)
+#define EDID_ID_SERIAL_NUMBER_LENGTH             4
+#define EDID_WEEK_OF_MFG_OFFSET                  \
+    (EDID_ID_SERIAL_NUMBER_OFFSET + EDID_ID_SERIAL_NUMBER_LENGTH)
+#define EDID_WEEK_OF_MFG_LENGTH                  1
+#define EDID_YEAR_OF_MFG_OFFSET                  \
+    (EDID_WEEK_OF_MFG_OFFSET + EDID_WEEK_OF_MFG_LENGTH)
+#define EDID_YEAR_OF_MFG_LENGTH                  1
+
+#define EDID_VERSION_OFFSET                      0x12
+#define EDID_REVISION_OFFSET                     (EDID_VERSION_OFFSET+1)
+#define EDID_VERSION_LENGTH                      2
+
+#define EDID_DISPLAY_PARAMS_OFFSET               0x14
+#define EDID_DISPLAY_PARAMS_LENGTH               5
+#define EDID_VIDEO_INPUT_DEF_OFFSET              EDID_DISPLAY_PARAMS_OFFSET
+#define EDID_VIDEO_INPUT_DEF_SIGNAL_INT_MASK     0x80
+#define EDID_VIDEO_INPUT_DEF_SIGNAL_INT_DIGITAL  EDID_VIDEO_INPUT_DEF_SIGNAL_INT_MASK
+#define EDID_VIDEO_INPUT_DEF_SIGNAL_INT_ANALOG   0
+#define EDID_VIDEO_INPUT_DEF_COLOR_DEPTH_MASK    0x70
+#define EDID_VIDEO_INPUT_DEF_COLOR_DEPTH_SHIFT   4
+#define EDID_VIDEO_INPUT_DEF_INTERFACE_STD_MASK  0x0f
+#define EDID_VIDEO_INPUT_DEF_INTERFACE_STD_SHIFT 0
+#define EDID_VIDEO_INPUT_HORIZONTAL_OFFSET       \
+    (EDID_VIDEO_INPUT_DEF_OFFSET + 1)
+#define EDID_VIDEO_INPUT_VERTICAL_OFFSET         \
+    (EDID_VIDEO_INPUT_HORIZONTAL_OFFSET + 1)
+#define EDID_VIDEO_INPUT_GAMMA_OFFSET        \
+    (EDID_VIDEO_INPUT_VERTICAL_OFFSET + 1)
+#define EDID_VIDEO_INPUT_FEATURE_SUPPORT_OFFSET  \
+    (EDID_VIDEO_INPUT_GAMMA_OFFSET + 1)
+#define EDID_VIDEO_INPUT_STANDBY_MASK            0x80
+#define EDID_VIDEO_INPUT_SUSPEND_MASK            0x40
+#define EDID_VIDEO_INPUT_ACTIVE_OFF_MASK         0x20
+#define EDID_VIDEO_INPUT_COLOR_TYPE_MASK         0x18
+#define EDID_VIDEO_INPUT_COLOR_TYPE_SHIFT        3
+#define EDID_VIDEO_INPUT_SRGB_MASK               0x04
+#define EDID_VIDEO_INPUT_PREFERRED_MASK          0x02
+#define EDID_VIDEO_INPUT_CONTINUOUS_MASK         0x01
+
+#define EDID_CHROMATICITY_OFFSET                 0x19
+#define EDID_CHROMATICITY_LENGTH                 10
+#define EDID_CHROMATICITY_RxLo_OFFSET            EDID_CHROMATICITY_OFFSET
+#define EDID_CHROMATICITY_RxLo_MASK              0xc0
+#define EDID_CHROMATICITY_RxLo_SHIFT             6
+#define EDID_CHROMATICITY_RyLo_OFFSET            EDID_CHROMATICITY_OFFSET
+#define EDID_CHROMATICITY_RyLo_MASK              0x30
+#define EDID_CHROMATICITY_RyLo_SHIFT             4
+#define EDID_CHROMATICITY_GxLo_OFFSET            EDID_CHROMATICITY_OFFSET
+#define EDID_CHROMATICITY_GxLo_MASK              0x0c
+#define EDID_CHROMATICITY_GxLo_SHIFT             2
+#define EDID_CHROMATICITY_GyLo_OFFSET            EDID_CHROMATICITY_OFFSET
+#define EDID_CHROMATICITY_GyLo_MASK              0x03
+#define EDID_CHROMATICITY_GyLo_SHIFT             0
+#define EDID_CHROMATICITY_BxLo_OFFSET            (EDID_CHROMATICITY_OFFSET+1)
+#define EDID_CHROMATICITY_BxLo_MASK              0xc0
+#define EDID_CHROMATICITY_BxLo_SHIFT             6
+#define EDID_CHROMATICITY_ByLo_OFFSET            (EDID_CHROMATICITY_OFFSET+1)
+#define EDID_CHROMATICITY_ByLo_MASK              0x30
+#define EDID_CHROMATICITY_ByLo_SHIFT             4
+#define EDID_CHROMATICITY_WxLo_OFFSET            (EDID_CHROMATICITY_OFFSET+1)
+#define EDID_CHROMATICITY_WxLo_MASK              0x0c
+#define EDID_CHROMATICITY_WxLo_SHIFT             2
+#define EDID_CHROMATICITY_WyLo_OFFSET            (EDID_CHROMATICITY_OFFSET+1)
+#define EDID_CHROMATICITY_WyLo_MASK              0x03
+#define EDID_CHROMATICITY_WyLo_SHIFT             0
+
+#define EDID_CHROMATICITY_RxHi_OFFSET            (EDID_CHROMATICITY_OFFSET+2)
+#define EDID_CHROMATICITY_RyHi_OFFSET            (EDID_CHROMATICITY_OFFSET+3)
+#define EDID_CHROMATICITY_GxHi_OFFSET            (EDID_CHROMATICITY_OFFSET+4)
+#define EDID_CHROMATICITY_GyHi_OFFSET            (EDID_CHROMATICITY_OFFSET+5)
+#define EDID_CHROMATICITY_BxHi_OFFSET            (EDID_CHROMATICITY_OFFSET+6)
+#define EDID_CHROMATICITY_ByHi_OFFSET            (EDID_CHROMATICITY_OFFSET+7)
+#define EDID_CHROMATICITY_WxHi_OFFSET            (EDID_CHROMATICITY_OFFSET+8)
+#define EDID_CHROMATICITY_WyHi_OFFSET            (EDID_CHROMATICITY_OFFSET+9)
+#define EDID_CHROMATICITY_HiByte_SHIFT           2
+#define EDID_CHROMATICITY_LoByte_MASK            3
+
+#define EDID_CHROMATICITY_Rx_INDEX               0
+#define EDID_CHROMATICITY_Ry_INDEX               1
+#define EDID_CHROMATICITY_Gx_INDEX               2
+#define EDID_CHROMATICITY_Gy_INDEX               3
+#define EDID_CHROMATICITY_Bx_INDEX               4
+#define EDID_CHROMATICITY_By_INDEX               5
+#define EDID_CHROMATICITY_Wx_INDEX               6
+#define EDID_CHROMATICITY_Wy_INDEX               7
+
+#define EDID_CHROMATICITY_STORAGE_SIZE           8
+
+#define EDID_ESTABLISHED_TIMINGS_OFFSET          0x23
+#define EDID_ESTABLISHED_TIMINGS_LENGTH          3
+#define EDID_ESTABLISHED_TIMINGS_I_OFFSET        EDID_ESTABLISHED_TIMINGS_OFFSET
+#define EDID_ESTABLISHED_TIMINGS_II_OFFSET       (EDID_ESTABLISHED_TIMINGS_I_OFFSET+1)
+#define EDID_ESTABLISHED_TIMINGS_MFG_OFFSET      (EDID_ESTABLISHED_TIMINGS_II_OFFSET+1)
+
+#define EDID_ESTABLISHED_TIMINGS_I_INDEX         0
+#define EDID_ESTABLISHED_TIMINGS_II_INDEX        1
+#define EDID_ESTABLISHED_TIMINGS_MFG_INDEX       2
+
+#define EDID_STANDARD_TIMINGS_OFFSET             0x26
+#define EDID_STANDARD_TIMINGS_LENGTH             16
+#define EDID_STANDARD_TIMINGS_LENGTH_EACH        2
+#define EDID_STANDARD_TIMINGS_BLOCK_OFFSET(i)    \
+    (EDID_STANDARD_TIMINGS_OFFSET + i*EDID_STANDARD_TIMINGS_LENGTH_EACH)
+#define EDID_STANDARD_TIMINGS_COUNT              8
+
+#define EDID_STANDARD_TIMINGS_AR_MASK            0xc0
+#define EDID_STANDARD_TIMINGS_FIELD_REFRESH_MASK 0x3f
+
+#define EDID_MAIN_18B_OFFSET                     0x36
+#define EDID_18B_BLOCK_LENGTH                    18
+#define EDID_MAIN_18B_BLOCK_OFFSET(i) (EDID_MAIN_18B_OFFSET+(EDID_18B_BLOCK_LENGTH*i))
+
+#define EDID_DISPLAY_DESC_TAG_NUM_OFFSET         3 // offset from start of 18B block
+#define EDID_DISPLAY_DESC_DUMMY                  0x10
+#define EDID_DISPLAY_DESC_DISPLAY_SERIAL_NUMBER  0xff
+#define EDID_DISPLAY_DESC_ALPHANUM_STRING        0xfe
+#define EDID_DISPLAY_DESC_DISPLAY_RANGE_LIMITS   0xfd
+#define EDID_DISPLAY_DESC_DISPLAY_PRODUCT_NAME   0xfc
+#define EDID_DISPLAY_DESC_COLOR_POINT_DATA       0xfb
+#define EDID_DISPLAY_DESC_STD_TIMING_ID          0xfa
+#define EDID_DISPLAY_DESC_DCM_DATA               0xf9
+#define EDID_DISPLAY_DESC_CVT_3_BYTE_CODES       0xf8
+#define EDID_DISPLAY_DESC_EST_TIMINGS_III        0xf7
+// shared between serial number, data string and product name
+#define EDID_DISPLAY_DESC_STRING_OFFSET          5 // offset from start of 18B block
+#define EDID_DISPLAY_DESC_STRING_LENGTH          13 // 13 bytes of data
+#define EDID_DISPLAY_DESC_STRING_STORAGE_SIZE    16 // stored in 16 bytes       
+#define EDID_DISPLAY_DESC_STD_TIMINGS_OFFSET     5 // offset from start of 18B block
+#define EDID_DISPLAY_DESC_STD_TIMINGS_COUNT      6
+
+#define EDID_DISPLAY_RANGE_LIMITS_OFFSET         4
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MASK   3
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MASK   0xc0
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MIN    1
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MAX    2
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MIN    4
+#define EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MAX    8
+#define EDID_DISPLAY_RANGE_LIMITS_V_MIN_OFFSET   5
+#define EDID_DISPLAY_RANGE_LIMITS_V_MAX_OFFSET   6
+#define EDID_DISPLAY_RANGE_LIMITS_H_MIN_OFFSET   7
+#define EDID_DISPLAY_RANGE_LIMITS_H_MAX_OFFSET   8
+#define EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MAX_OFFSET 9
+#define EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MULTIPLIER 10
+#define EDID_DISPLAY_RANGE_LIMITS_GTF_OFFSET     10
+
+#define EDID_DTD_PIXEL_CLOCK_LO_OFFSET           0
+#define EDID_DTD_PIXEL_CLOCK_HI_OFFSET           1
+#define EDID_DTD_PIXEL_CLOCK_HI_SHIFT            8
+#define EDID_DTD_PIXEL_CLOCK_MULTIPLIER          10000
+
+#define EDID_DTD_H_ACTIVE_LO_OFFSET              2
+#define EDID_DTD_H_ACTIVE_HI_OFFSET              4
+#define EDID_DTD_H_ACTIVE_HI_MASK                0xf0
+#define EDID_DTD_H_ACTIVE_HI_SHIFT               4
+
+#define EDID_DTD_H_BLANK_LO_OFFSET               3
+#define EDID_DTD_H_BLANK_HI_OFFSET               4
+#define EDID_DTD_H_BLANK_HI_MASK                 0xf
+#define EDID_DTD_H_BLANK_HI_SHIFT                8
+
+#define EDID_DTD_V_ACTIVE_LO_OFFSET              5
+#define EDID_DTD_V_ACTIVE_HI_OFFSET              7
+#define EDID_DTD_V_ACTIVE_HI_MASK                0xf0
+#define EDID_DTD_V_ACTIVE_HI_SHIFT               4
+
+#define EDID_DTD_V_BLANK_LO_OFFSET               6
+#define EDID_DTD_V_BLANK_HI_OFFSET               7
+#define EDID_DTD_V_BLANK_HI_MASK                 0xf
+#define EDID_DTD_V_BLANK_HI_SHIFT                8
+
+#define EDID_DTD_H_FRONT_PORCH_LO_OFFSET         8
+#define EDID_DTD_H_FRONT_PORCH_HI_OFFSET         11
+#define EDID_DTD_H_FRONT_PORCH_HI_MASK           0xc0
+#define EDID_DTD_H_FRONT_PORCH_HI_SHIFT          2
+
+#define EDID_DTD_H_SYNC_WIDTH_LO_OFFSET          9
+#define EDID_DTD_H_SYNC_WIDTH_HI_OFFSET          11
+#define EDID_DTD_H_SYNC_WIDTH_HI_MASK            0x30
+#define EDID_DTD_H_SYNC_WIDTH_HI_SHIFT           4
+
+#define EDID_DTD_V_FRONT_PORCH_LO_OFFSET         10
+#define EDID_DTD_V_FRONT_PORCH_LO_MASK           0xf0
+#define EDID_DTD_V_FRONT_PORCH_LO_SHIFT          4
+#define EDID_DTD_V_FRONT_PORCH_HI_OFFSET         11
+#define EDID_DTD_V_FRONT_PORCH_HI_MASK           0xc
+#define EDID_DTD_V_FRONT_PORCH_HI_SHIFT          2
+
+#define EDID_DTD_V_SYNC_WIDTH_LO_OFFSET          10
+#define EDID_DTD_V_SYNC_WIDTH_LO_MASK            0xf
+#define EDID_DTD_V_SYNC_WIDTH_LO_SHIFT           0
+#define EDID_DTD_V_SYNC_WIDTH_HI_OFFSET          11
+#define EDID_DTD_V_SYNC_WIDTH_HI_MASK            0x3
+#define EDID_DTD_V_SYNC_WIDTH_HI_SHIFT           4
+
+#define EDID_DTD_H_SIZE_MM_LO_OFFSET             12
+#define EDID_DTD_H_SIZE_MM_HI_OFFSET             14
+#define EDID_DTD_H_SIZE_MM_HI_MASK               0xf0
+#define EDID_DTD_H_SIZE_MM_HI_SHIFT              4
+
+#define EDID_DTD_V_SIZE_MM_LO_OFFSET             13
+#define EDID_DTD_V_SIZE_MM_HI_OFFSET             14
+#define EDID_DTD_V_SIZE_MM_HI_MASK               0xf
+#define EDID_DTD_V_SIZE_MM_HI_SHIFT              8
+
+#define EDID_DTD_BORDER_WIDTH_OFFSET             15
+#define EDID_DTD_BORDER_HEIGHT_OFFSET            16
+
+#define EDID_DTD_LO_MASK                         0xff
+
+#define EDID_DTD_FLAGS_OFFSET                    17
+#define EDID_DTD_FLAGS_MASK                      0xff
+#define EDID_DTD_FLAGS_INTERLACED                0x80
+#define EDID_DTD_FLAGS_STEREO_MASK               ((3<<5)|1)
+#define EDID_DTD_FLAGS_STEREO_NORMAL0            0 // these two should be treated equally
+#define EDID_DTD_FLAGS_STEREO_NORMAL1            1
+#define EDID_DTD_FLAGS_STEREO_FS_RIGHT           (1<<5)
+#define EDID_DTD_FLAGS_STEREO_FS_LEFT            (2<<5)
+#define EDID_DTD_FLAGS_STEREO_2WAY_RIGHT         ((1<<5)|1)
+#define EDID_DTD_FLAGS_STEREO_2WAY_LEFT          ((2<<5)|1)
+#define EDID_DTD_FLAGS_STEREO_4WAY               (3<<5)
+#define EDID_DTD_FLAGS_STEREO_SIDE_BY_SIDE       ((3<<5)|1)
+#define EDID_DTD_FLAGS_SYNC_MASK                 0x1e
+#define EDID_DTD_FLAGS_SYNC_TYPE_MASK            0x18
+#define EDID_DTD_FLAGS_SYNC_SERRATIONS_MASK      4 // for analog and digital cpst sync
+#define EDID_DTD_FLAGS_SYNC_SYNC_ON_GREEN_MASK   2 // for analog sync only
+#define EDID_DTD_FLAGS_SYNC_VSYNC_POLARITY_MASK  4 // for digital separate sync
+#define EDID_DTD_FLAGS_SYNC_HSYNC_POLARITY_MASK  2 // for digital separate sync
+
+#define EDID_EXT_BLOCKS_COUNT                    0x7e
+#define EDID_CHECKSUM_OFFSET                     0x7f
+
+#define EDID_EXT_BLOCK_SIZE                      0x80
+// count from start of EDID, first EEDID block is block 1
+#define EDID_EXT_BLOCK_OFFSET(i)                 (i*EDID_EXT_BLOCK_SIZE)
+
+#define EDID_EXT_BLOCK_TAG_OFFSET                0 // offset from start of block
+#define EDID_EXT_BLOCK_TAG_EXPECTED_VALUE        2
+#define EDID_EXT_BLOCK_REVISION_OFFSET           1 // offset from start of block
+#define EDID_EXT_BLOCK_REVISION_EXPECTED_VALUE   3
+#define EDID_EXT_BLOCK_18B_BLOCK_START_OFFSET    2
+#define EDID_EXT_BLOCK_FLAGS_OFFSET              3
+#define EDID_EXT_BLOCK_FLAGS_UNDERSCAN_MASK      0x80
+#define EDID_EXT_BLOCK_FLAGS_AUDIO_MASK          0x40
+#define EDID_EXT_BLOCK_FLAGS_YCbCr_444_MASK      0x20
+#define EDID_EXT_BLOCK_FLAGS_YCbCr_422_MASK      0x10
+#define EDID_EXT_BLOCK_FLAGS_DTD_COUNT_MASK      0x0f
+#define EDID_EXT_BLOCK_DATA_BLOCKS_OFFSET        4
+
+#define EDID_EXT_BLOCK_DATA_BLOCK_TAG_MASK       0xe0
+#define EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT      5
+#define EDID_EXT_BLOCK_DATA_BLOCK_LEN_OFFSET     0
+#define EDID_EXT_BLOCK_DATA_BLOCK_LEN_MASK       0x1f
+
+#define EDID_EXT_BLOCK_TYPE_AUDIO                1
+#define EDID_EXT_BLOCK_TYPE_VIDEO                2
+#define EDID_EXT_BLOCK_TYPE_VENDOR_SPECIFIC      3
+#define EDID_EXT_BLOCK_TYPE_SPEAKER              4
+#define EDID_EXT_BLOCK_TYPE_VESA_DTC             5
+#define EDID_EXT_BLOCK_TYPE_EXTENDED             7
+#define EDID_EXT_BLOCK_TYPE_EXTENDED_VIDCAP      0
+#define EDID_EXT_BLOCK_TYPE_EXTENDED_COLORIMETRY 5
+
+#define EDID_EXT_BLOCK_TYPE_VIDEO_NATIVE_MASK    0x80
+#define EDID_EXT_BLOCK_TYPE_VIDEO_VIC_MASK       0x7f
+
+#define EDID_EXT_BLOCK_SAD_SIZE                  3
+#define EDID_EXT_BLOCK_SAD_FORMAT_CODE_MASK      0x78 // four bits
+#define EDID_EXT_BLOCK_SAD_FORMAT_CODE_SHIFT     3
+#define EDID_EXT_BLOCK_SAD_NUM_CHANNELS_MASK     0x7  // three bits, max num chan - 1
+
+#define EDID_EXT_BLOCK_SAD_FILTER_48khz_max      7
+
+#define EDID_AUDIO_STORAGE_SIZE                  16   // size is arbitrary
+#define EDID_AUDIO_FORMAT_RESERVED               0
+#define EDID_AUDIO_FORMAT_LPCM                   1
+#define EDID_AUDIO_FORMAT_AC3                    2
+#define EDID_AUDIO_FORMAT_MPEG1                  3
+#define EDID_AUDIO_FORMAT_MP3                    4
+#define EDID_AUDIO_FORMAT_MPEG2                  5
+#define EDID_AUDIO_FORMAT_AAC                    6
+#define EDID_AUDIO_FORMAT_DTS                    7
+#define EDID_AUDIO_FORMAT_ATRAC                  8
+#define EDID_AUDIO_FORMAT_DSD                    9
+#define EDID_AUDIO_FORMAT_E_AC3                  10
+#define EDID_AUDIO_FORMAT_DTS_HD                 11
+#define EDID_AUDIO_FORMAT_MLP                    12
+#define EDID_AUDIO_FORMAT_DST                    13
+#define EDID_AUDIO_FORMAT_WMA_PRO                14
+#define EDID_AUDIO_FORMAT_EXT                    15
+
+#define EDID_AUDIO_FORMAT_STRS_STORAGE_SIZE      16
+#define EDID_AUDIO_FREQ_STRS_STORAGE_SIZE        8
+
+#define EDID_AUDIO_FORMAT_STRS_INITIALIZER {"Reserved", "LPCM", "AC3", "MPEG1", "MP3", "MPEG2", "AAC", "DTS", "ATRAC", "DSD", "E-AC3", "DTS-HD", "MLP", "DST", "WMA Pro", "EXT"}
+#define EDID_AUDIO_EXT_FORMAT_STRS_INITIALIZER {"Reserved""HE-AAC", "HE-AACx2", "MPEG Surround")
+#define EDID_AUDIO_FREQUENCY_STRS_INITIALIZER {"32", "44.1", "48", "88.2", "96", "176.4", "192"}
+
+#define EDID_AUDIO_FORMAT_LPCM_16_BIT_MASK       1
+#define EDID_AUDIO_FORMAT_LPCM_20_BIT_MASK       2
+#define EDID_AUDIO_FORMAT_LPCM_24_BIT_MASK       4
+
+#define EDID_SPEAKER_BYTE1_MASK                  0xff
+#define EDID_SPEAKER_BYTE2_SHIFT                 8
+#define EDID_SPEAKER_BYTE3_VALUE                 0
+
+#define EDID_SPEAKER_FL_FR_MASK                  1
+#define EDID_SPEAKER_LFE_MASK                    2
+#define EDID_SPEAKER_FC_MASK                     4
+#define EDID_SPEAKER_RL_RR_MASK                  8
+#define EDID_SPEAKER_RC_MASK                     0x10
+#define EDID_SPEAKER_FLC_FRC_MASK                0x20
+#define EDID_SPEAKER_RLC_RRC_MASK                0x40
+#define EDID_SPEAKER_FLW_FRW_MASK                0x80
+#define EDID_SPEAKER_FLH_FRH_MASK                0x100
+#define EDID_SPEAKER_TC_MASK                     0x200
+#define EDID_SPEAKER_FCH_MASK                    0x400
+
+#define EDID_SPEAKER_STRS_STORAGE_SIZE           11
+
+#define EDID_SPEAKER_STRS_INITIALIZER {"Front Left and Front Right", "Low Frequency Effect", "Front Center", "Rear Left and Rear Right", "Rear Center", "Front Left Center and Front Right Center", "Rear Left Center and Rear Right Center", "Front Left Wide and Front Right Wide", "Front Left High and Front Right High", "Top Center", "Front Center High"}
+
+#define EDID_VENDOR_SPECIFIC_STORAGE_SIZE        32 // arbitrary
+#define EDID_VENDOR_SPECIFIC_FILTER_BYTE         5
+#define EDID_VENDOR_SPECIFIC_FILTER_DEEP_COLOR   0x87
+
+#define EDID_EXTENDED_TAG_CODE_VIDCAP            0
+#define EDID_EXTENDED_TAG_CODE_VENDOR_VDB        1
+#define EDID_EXTENDED_TAG_CODE_VESA_VDD_INFO     2
+#define EDID_EXTENDED_TAG_CODE_VESA_VDB          3
+#define EDID_EXTENDED_TAG_CODE_HDMI_VDB          4
+#define EDID_EXTENDED_TAG_CODE_COLORIMETRY       5
+#define EDID_EXTENDED_TAG_CODE_CEA_AUDIO         16
+#define EDID_EXTENDED_TAG_CODE_VENDOR_ADB        17
+#define EDID_EXTENDED_TAG_CODE_HDMI_ADB          18
+
+#define EDID_VIDCAP_S_CE_MASK                    0x03
+#define EDID_VIDCAP_S_IT_MASK                    0x0c
+#define EDID_VIDCAP_S_IT_SHIFT                   2
+#define EDID_VIDCAP_S_PT_MASK                    0x30
+#define EDID_VIDCAP_S_PT_SHIFT                   4
+#define EDID_VIDCAP_QS_MASK                      0x40
+#define EDID_VIDCAP_QY_MASK                      0x80
+
+#define EDID_VIDCAP_STRINGS_STORAGE_SIZE    4
+#define EDID_VIDCAP_STRS_INITIALIZER { "Not Supported", "Always Overscanned", "Always Underscanned", "Supports Over- and Underscan"}
+
+#define EDID_COLORIMETRY_BYTE1_MASK              0xff
+#define EDID_COLORIMETRY_BYTE2_MASK              0xf00
+#define EDID_COLORIMETRY_BYTE2_SHIFT             8
+
+#define EDID_COLORIMETRY_STRS_STORAGE_SIZE       6
+#define EDID_COLORIMETRY_STRS_INITIALIZER {"xvYCC601", "xvYCC709", "sYCC602", "AdobeYCC601", "AdobeYCCRGB", "Future Metadata Profile"};
+
+#define EDID_ID_STRING_LENGTH                    64
+
+// -1 if valid, 0 if invalid, bitfield of mismatched checksums otherwise
+#define EDID_BIN_INVALID                         0
+#define EDID_BIN_VALID                           (-1)
+
+#define EDID_ERROR                               (-1)
+#define EDID_SUCCESS                             0
+
+#define EDID_TRUE                                1
+#define EDID_FALSE                               0
+
+#define EDID_HEADER_INITIALIZER {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0}
+#define EDID_HEADER_LENGTH                       8
+
+// defs for field cnc_edid_t.edid_valid
+#define EDID_VALID_HEADER                        0x00001
+#define EDID_VALID_VENDOR_PRODUCT_ID             0x00002
+#define EDID_VALID_VERSION                       0x00004
+#define EDID_VALID_DISPLAY_PARAMS                0x00008
+#define EDID_VALID_CHROMATICITY                  0x00010
+#define EDID_VALID_EST_TIMINGS                   0x00020
+#define EDID_VALID_STD_TIMINGS                   0x00040
+#define EDID_VALID_DISPLAY_SERIAL_NUMBER         0x00080
+#define EDID_VALID_DISPLAY_DATA_STR              0x00100
+#define EDID_VALID_DISPLAY_PRODUCT_NAME          0x00200
+#define EDID_VALID_EXT_BLOCKS_COUNT              0x00400
+#define EDID_VALID_DISPLAY_RANGE_LIMITS          0x00800
+#define EDID_VALID_EEDID                         0x01000
+#define EDID_VALID_SVDS_PRESENT                  0x02000
+#define EDID_VALID_AUDIO_FORMATS                 0x04000
+#define EDID_VALID_SPEAKER_ALLOC                 0x08000
+#define EDID_VALID_VENDOR_SPECIFIC               0x10000
+#define EDID_VALID_VIDEO_CAPABILITY              0x20000
+#define EDID_VALID_COLORIMETRY                   0x40000
+#define EDID_VALID_CHECKSUM                      0x80000
+
+// defs for field cnc_edid_timing_t.internal_flags
+#define EDID_TIMING_IFLAGS_LOCATION_EST          0x00001
+#define EDID_TIMING_IFLAGS_LOCATION_STD          0x00002
+#define EDID_TIMING_IFLAGS_LOCATION_MAIN_18B     0x00004
+#define EDID_TIMING_IFLAGS_LOCATION_SVD          0x00008
+#define EDID_TIMING_IFLAGS_LOCATION_EXT_18B      0x00010
+#define EDID_TIMING_IFLAGS_LOCATION_EXT_18B_STD  0x00020 // a type 0xfa disp desc blk
+#define EDID_TIMING_IFLAGS_LOCATION_MASK         0x0003f
+#define EDID_TIMING_IFLAGS_AR_VALID              0x00100
+#define EDID_TIMING_IFLAGS_PIXEL_CLOCK_VALID     0x00200
+#define EDID_TIMING_IFLAGS_V_FREQ_VALID          0x00400
+#define EDID_TIMING_IFLAGS_VIC_VALID             0x00800
+#define EDID_TIMING_IFLAGS_PREFERRED             0x01000
+#define EDID_TIMING_IFLAGS_PIXEL_DOUBLED         0x02000
+#define EDID_TIMING_IFLAGS_NATIVE                0x04000
+#define EDID_TIMING_IFLAGS_ENTRY_VALID           0x10000
+
+// 17 Est, 8 Std, 4 18B block in the main edid
+// 25 timings is the most in any ext edid
+// so 17+8+4+25=54 should be enough, use 64 for now
+#define EDID_TIMINGS_STORAGE_SIZE       64
+
+typedef struct {
+    int vic;
+    int h_active;
+    int v_active;
+    int pixel_clock;
+    int v_frequency;
+    int ar_numerator;
+    int ar_denominator;
+    int timing_flags;
+    int h_total;
+    int v_total;
+    int h_blank;
+    int v_blank;
+    int h_front_porch;
+    int v_front_porch;
+    int h_sync_width;
+    int v_sync_width;
+    int h_size_mm;
+    int v_size_mm;
+    int border_width;
+    int border_height;
+    int internal_flags;
+} cnc_edid_timing_t;
+
+// basically the three bytes of a SAD, masked; byte 0 is separated
+typedef struct {
+    int format;
+    int max_channels;
+    int frequencies; // 8 bit vector as defined in tables 45-49 of CEA 861-E
+    int extra_data;
+} cnc_edid_audio_t;
+
+// used in edid_util.c and edid_ops.c
+typedef struct {
+    int vic;
+    int h_active;
+    int v_active;
+    char interlaced;
+    int v_frequency;
+    int ar_numerator;
+    int ar_denominator;
+    int pixel_doubled;
+} cnc_edid_vic_struct_t;
+
+#define EDID_MIN_VIC 1
+#define EDID_MAX_VIC 64
+
+typedef struct {
+    // user-specified name of this edid
+    char id_string[EDID_ID_STRING_LENGTH];
+
+    // binary version of edid and related info
+    unsigned char edid_bin[EDID_MAX_BIN_LENGTH];
+
+    // -1 if valid, 0 if invalid, bitfield of mismatched checksums otherwise
+    // 0 bit is invalid in bitfield, start with all valid, clear if invalid
+    int edid_bin_valid;
+    int edid_bin_length;
+
+    // bitfield used to mark which parts of canonical format are valid
+    // typically written by parser functions, used by assembler
+    int edid_valid;
+
+    // EDID_VENDOR_PRODUCT_ID fields
+    unsigned char id_mfg_name[4];
+    int id_product_code;
+    int id_serial_number;
+    int week_of_mfg;
+    int year_of_mfg;
+
+    // EDID_VERSION fields
+    int version;
+    int revision;
+
+    // EDID_DISPLAY_PARAMS fields
+    int signal_interface; // analog or digital
+    int color_bit_depth;
+    int interface_std;
+    int video_input_def; // FIXME: analog case not parsed
+    int horizontal;
+    int vertical;
+    int gamma;
+    int feature_support;
+
+    // EDID_CHROMATICITY fields
+    int chromaticity[EDID_CHROMATICITY_STORAGE_SIZE];
+
+    // EDID_18B fields
+    char display_serial_number[EDID_DISPLAY_DESC_STRING_STORAGE_SIZE];
+    char display_data_string[EDID_DISPLAY_DESC_STRING_STORAGE_SIZE];
+    char display_product_name[EDID_DISPLAY_DESC_STRING_STORAGE_SIZE];
+
+    // Display Range Limits (also from an 18B field)
+    int rate_v_min, rate_v_max;
+    int rate_h_min, rate_h_max;
+    int rate_pixel_clock_max;
+
+    int ext_blocks_count;
+
+    // EEDID fields
+    int eedid_flags;
+    int speaker_alloc;
+    int video_capability;
+    int colorimetry;
+    cnc_edid_audio_t audio_formats[EDID_AUDIO_STORAGE_SIZE];
+    // hurry-up option, needs to be parsed and dealt with better
+    unsigned char vendor_specific[EDID_VENDOR_SPECIFIC_STORAGE_SIZE];
+    int vendor_specific_length;
+
+    cnc_edid_timing_t timings[EDID_TIMINGS_STORAGE_SIZE];
+} cnc_edid_t;
+
+#define EDID_INVALIDATE_BINARY(edid)                              \
+    edid->edid_bin_valid = EDID_BIN_INVALID
+
+#define EDID_VALIDATE_BINARY(edid, block)                 \
+    do {                                                          \
+    if (!(edid->edid_bin_valid & (1<<block))) {   \
+        printf("%s: EDID binary is not valid, block %d (%x)\n",    \
+           __FUNCTION__, block, edid->edid_bin_valid);                \
+        edid_retval = EDID_ERROR;                 \
+    } else                                \
+        edid_retval = EDID_SUCCESS;               \
+    } while (0)
+
+#define EDID_MARK_BAD_CHECKSUM(edid, block)               \
+    do {                                                          \
+    if (edid->edid_bin_valid == EDID_BIN_VALID)           \
+        edid->edid_bin_valid = (1<<block);                \
+    else                                                      \
+        edid->edid_bin_valid |= (1<<block);               \
+    } while (0)
+
+#ifdef  EDID_DEBUG
+#define EDID_DEBUG_DUMP(edid, offset, length)                 \
+    do {                                                          \
+    int i, off=offset;                                        \
+    printe("%s:\n\t0x%02x:%2db: ", __FUNCTION__+11, offset, length); \
+    for (i=0; i<length; i++)                                  \
+        printe("%02x ", edid->edid_bin[off++]);           \
+        printe("\n");                             \
+    } while (0);
+#else
+#define EDID_DEBUG_DUMP(edid, offset, length)
+#endif
+
+#ifdef  EDID_BIG_ENDIAN
+
+#define EDID_PARSE_SHORT_TO_INT(d, s) \
+    d = ( ((*(s))<<8) | (*((s)+1)) )
+#define EDID_PARSE_LONG_TO_INT(d, s)                \
+    d = ( ((*(s))<<24) | (*((s)+1)<<16) | (*((s)+2)<<8) | (*((s)+3)) )
+
+#error NEED MORE MACROS HERE
+
+#else /* else if EDID_LITTLE_ENDIAN */
+
+// d is dst is an integer variable
+// s is a pointer to the edid_bin
+#define EDID_PARSE_SHORT_TO_INT(d, s) \
+    d = ( ((*((s)+1))<<8) | (*(s)) )
+#define EDID_PARSE_LONG_TO_INT(d, s)                \
+    d = ( ((*( (s)+3))<<24) | (*((s)+2)<<16) | (*((s)+1)<<8) | (*(s)) )
+
+// d is a pointer to the edid_bin
+// s is an integer variable
+#define EDID_ASSEMBLE_INT_TO_SHORT(d, s) \
+    do {                                 \
+    *(d) = s & 0xff;         \
+    *(d+1) = (s & 0xff00) >> 8;  \
+    } while (0)
+#define EDID_ASSEMBLE_INT_TO_LONG(d, s)  \
+    do {                                 \
+    *(d) = s & 0xff;         \
+    *(d+1) = (s & 0xff00) >> 8;  \
+    *(d+2) = (s & 0xff0000) >> 16;   \
+    *(d+3) = (s & 0xff000000) >> 24; \
+    } while (0)
+
+#endif /* EDID_BIG_ENDIAN */
+
+// declarations for functions from cnc_edid_parse.c
+int cnc_edid_parse(cnc_edid_t *edid);
+
+// declarations for functions from edid_util.c
+void cnc_edid_set_id_string(cnc_edid_t *edid, char *edid_id_string);
+int cnc_edid_read_hex(cnc_edid_t *edid);
+int cnc_edid_int_to_color_bit_depth(int color_bit_depth);
+int cnc_edid_vic_to_edid_timing(cnc_edid_timing_t *timing, int vic);
+cnc_edid_timing_t *cnc_edid_get_free_timing_struct(cnc_edid_t *edid);
+cnc_edid_audio_t *cnc_edid_get_free_audio_struct(cnc_edid_t *edid);
+char *cnc_edid_color_bit_depth_ascii(cnc_edid_t *edid);
+char *cnc_edid_interface_std_ascii(cnc_edid_t *edid);
+char *cnc_edid_display_color_type_to_ascii(cnc_edid_t *edid);
+char *cnc_edid_timing_iflags_location_to_ascii(cnc_edid_timing_t *timing);
+
+#ifdef EDID_FLOATING_POINT_AVAILABLE
+float cnc_edid_gamma_to_f(cnc_edid_t *edid);
+float cnc_edid_chromaticity_to_f(int chromaticity_val);
+int cnc_edid_gamme_from_f(float gamma);
+int cnc_edid_chromaticity_from_f(float chromaticity_val);
+#else
+int cnc_edid_chromaticity_fract(int chromaticity_val);
+int cnc_edid_gamma_int(cnc_edid_t *edid);
+int cnc_edid_gamma_fract(cnc_edid_t *edid);
+#endif
+
+// declarations for functions from edid_ops.c
+int cnc_edid_copy(cnc_edid_t *src, cnc_edid_t *dst);
+int cnc_edid_clear_bin(cnc_edid_t *edid);
+int cnc_edid_clear_canonical(cnc_edid_t *edid);
+void cnc_edid_init(cnc_edid_t *edid);
+int cnc_edid_filter(cnc_edid_t *edid, int* tvoutmode_supported_res, int* audmode_supported);
+
+// declarations for functions from cnc_edid_filter.c
+int cnc_edid_print(cnc_edid_t *edid);
+int cnc_edid_print_hex(cnc_edid_t *edid);
+
+// declarations for functions from cnc_edid_assemble.c
+int cnc_edid_assemble(cnc_edid_t *edid);
+#endif /* __EDID_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_ops.c u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_ops.c
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_ops.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_ops.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2003-2011, Cavium Networks. All rights reserved.
+ *
+ * This Software is the property of Cavium Networks.  The Software and all
+ * accompanying documentation are copyrighted.  The Software made available
+ * here constitutes the proprietary information of Cavium Networks.  You
+ * agree to take reasonable steps to prevent the disclosure, unauthorized use
+ * or unauthorized distribution of the Software.  You shall use this Software
+ * solely with Cavium hardware.
+ *
+ * Except as expressly permitted in a separate Software License Agreement
+ * between You and Cavium Networks, you shall not modify, decompile,
+ * disassemble, extract, or otherwise reverse engineer this Software.  You
+ * shall not make any copy of the Software or its accompanying documentation,
+ * except for copying incident to the ordinary and intended use of the
+ * Software and the Underlying Program and except for the making of a single
+ * archival copy.
+ *
+ * This Software, including technical data, may be subject to U.S.  export
+ * control laws, including the U.S.  Export Administration Act and its
+ * associated regulations, and may be subject to export or import regulations
+ * in other countries.  You warrant that You will comply strictly in all
+ * respects with all such regulations and acknowledge that you have the
+ * responsibility to obtain licenses to export, re-export or import the
+ * Software.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
+ * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
+ * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
+ * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
+ * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
+ * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
+ * POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ *
+ */
+
+#include "common.h"
+#include "cnc_edid.h"
+#include "../df/df.h"
+#ifdef EDID_TEST
+int cnc_edid_bin_cmp(cnc_edid_t *edid1, cnc_edid_t *edid2) {
+    int i, retval=EDID_SUCCESS;
+    for(i=0; i<EDID_MAX_BIN_LENGTH; i++) {
+        if(edid1->edid_bin[i] == edid2->edid_bin[i]) {
+            continue;
+        }
+        if(i==0x23 && ((edid1->edid_bin[i] | edid2->edid_bin[i]) == 0x20)) {
+            printf("%s: warning, original EDID didn't include 640x480 in EST timings\n", __FUNCTION__);
+            continue;
+        }
+        printf("%s: difference found at byte 0x%x:%02x vs %02x\n", __FUNCTION__, i, edid1->edid_bin[i], edid2->edid_bin[i]);
+        retval = EDID_ERROR;
+        if(i<0x7f) {
+            i = 0x7e;
+        }
+        else if(i<0xff) {
+            i = 0xfe;
+        }
+    }
+    if(retval) {
+        cnc_edid_print_hex(edid1);
+        printf("\n");
+        cnc_edid_print_hex(edid2);
+    }
+    return retval;
+}
+#endif
+
+int cnc_edid_copy(cnc_edid_t *src, cnc_edid_t *dst) {
+    memcpy(dst, src, sizeof(cnc_edid_t));
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_clear_bin(cnc_edid_t *edid) {
+  //  bzero(edid->edid_bin, EDID_MAX_BIN_LENGTH * sizeof(unsigned char));
+    memset(edid->edid_bin, 0, EDID_MAX_BIN_LENGTH * sizeof(unsigned char));
+    EDID_INVALIDATE_BINARY(edid);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_clear_canonical(cnc_edid_t *edid) {
+    int valid, length, edid_size, edid_bin_size;
+    if(edid->edid_bin_valid != EDID_BIN_VALID) {
+        printf("%s: warning: edid bin not valid, why clear only canonical?\n", __FUNCTION__);
+    }
+    valid = edid->edid_bin_valid;
+    length = edid->edid_bin_length;
+    edid_size = sizeof(cnc_edid_t);
+    edid_bin_size = EDID_MAX_BIN_LENGTH * sizeof(unsigned char);
+//    bzero((void*)(((unsigned int)edid)+edid_bin_size), edid_size-edid_bin_size);
+    memset((void*)(((unsigned int)edid)+edid_bin_size), 0, edid_size-edid_bin_size);
+    edid->edid_bin_valid = valid;
+    edid->edid_bin_length = length;
+    return EDID_SUCCESS;
+}
+
+void cnc_edid_init(cnc_edid_t *edid) {
+//    bzero(edid, sizeof(cnc_edid_t));
+    memset(edid, 0, sizeof(cnc_edid_t));
+}
+
+//#define NETHD_SUPPORT_TIMINGS_COUNT 20
+// convenient struct to use for these compares, though the vic and AR info is not used
+// sorted by ascending h_active!!!!
+/*
+static cnc_edid_vic_struct_t supported_res[NETHD_SUPPORT_TIMINGS_COUNT]= {
+    { 1,   640,480,'p',       60,  4, 3, 0},
+    { 2,   720,480,'p',       60,  4, 3, 0},
+    { 6,   720,480,'i',       60,  4, 3, 1},
+    {17,   720,576,'p',       50,  4, 3, 0},
+    {21,   720,576,'i',       50,  4, 3, 1},
+    { 0,   800,600,'p',       60,  4, 3, 0},
+    { 0,  1024,768,'p',       60,  4, 3, 0},
+    { 0,  1280,1024,'p',      60,  4, 3, 0},
+    { 0,  1280,768,'p',       60,  5, 3, 0},
+    { 0,  1280,960,'p',       60,  5, 3, 0},
+    { 0,  1600,1200,'p',      60,  4, 3, 0},
+
+    {60,  1280,720,'p',       24, 16, 9, 0},
+    {62,  1280,720,'p',       30, 16, 9, 0},
+
+    {32,  1920,1080,'p',      24, 16, 9, 0},
+    {34,  1920,1080,'p',      30, 16, 9, 0},
+
+    { 5,  1920,1080,'i',      60, 16, 9, 0}, // svds go through vic table in edid_util.c
+    {19,  1280,720,'p',       50, 16, 9, 0},
+    {31,  1920,1080,'p',      50, 16, 9, 0},
+    { 4,  1280,720,'p',       60, 16, 9, 0},
+    {16,  1920,1080,'p',      60, 16, 9, 0},
+#if 0
+    {39,  1920,1080,'i',      50, 16, 9, 0},
+    { 0,  1920,1200,'p',      50, 16,10, 0},
+    { 5,  1920,540,'i',       60, 16, 9, 0}, // dtds have field v_active
+    {39,  1920,540,'i',       50, 16, 9, 0},
+#endif
+};
+static int tvoutmode[NETHD_SUPPORT_TIMINGS_COUNT]= {
+    TVOUT_RGB_640X480_60FPS,
+    TVOUT_MODE_480P,
+    TVOUT_MODE_480I,
+    TVOUT_MODE_576P,
+    0,
+    TVOUT_RGB_800X600_60FPS,
+    TVOUT_RGB_1024X768_60FPS,
+    TVOUT_RGB_1280X1024_60FPS,
+    0,
+    0,
+    0,
+    0,
+    0,
+    TVOUT_MODE_1080P24,
+    TVOUT_MODE_1080P30,
+    TVOUT_MODE_1080I30,
+    TVOUT_MODE_720P50,
+    TVOUT_MODE_1080P50,
+    TVOUT_MODE_720P60,
+    TVOUT_MODE_1080P60
+}
+*/
+
+static cnc_edid_vic_struct_t supported_res[]= {
+
+    {21,   720,576,'i',       60,  4, 3, 1}, //TVOUT_MODE_576I,
+    {39,  1920,1080,'i',      50, 16, 9, 0}, //TVOUT_MODE_1080I25,+
+    { 0,   800,480,'p',       60,  5, 3, 0},//	TVOUT_RGB_800X480_60FPS,
+    { 0,  1360,768,'p',       60, 16, 9, 0},//	TVOUT_RGB_1360X768_60FPS,
+    { 0,  1366,768,'p',       60, 16, 9, 0},//	TVOUT_RGB_1366X768_60FPS,
+    { 0,  1920,1080,'p',      25, 16, 9, 0}, //TVOUT_MODE_1080P25,
+    { 6,   720,480,'i',       60,  4, 3, 1}, //TVOUT_MODE_480I,
+	{ 5,  1920,1080,'i',      60, 16, 9, 0}, //TVOUT_MODE_1080I30,
+	{ 1,   640,480,'p',       60,  4, 3, 0}, //TVOUT_RGB_640X480_60FPS,
+	{ 2,   720,480,'p',       60,  4, 3, 0}, //TVOUT_MODE_480P,
+	{17,   720,576,'p',       50,  4, 3, 0}, //TVOUT_MODE_576P,
+	{ 0,   800,600,'p',       60,  4, 3, 0}, //TVOUT_RGB_800X600_60FPS,
+	{ 0,  1024,768,'p',       60,  4, 3, 0}, //TVOUT_RGB_1024X768_60FPS,
+	{ 0,  1280,1024,'p',      60,  4, 3, 0}, //TVOUT_RGB_1280X1024_60FPS,
+    { 0,  1440,900,'p',       60,  8, 5, 0},//	TVOUT_RGB_1440X900_60FPS,
+	{19,  1280,720,'p',       50, 16, 9, 0}, //TVOUT_MODE_720P50,
+	{ 4,  1280,720,'p',       60, 16, 9, 0}, //TVOUT_MODE_720P60,
+	{32,  1920,1080,'p',      24, 16, 9, 0}, //TVOUT_MODE_1080P24,
+	{34,  1920,1080,'p',      30, 16, 9, 0}, //TVOUT_MODE_1080P30,
+	{31,  1920,1080,'p',      50, 16, 9, 0}, //TVOUT_MODE_1080P50,
+	{16,  1920,1080,'p',      60, 16, 9, 0} //TVOUT_MODE_1080P60,///<Define the timing mode is 1080P@60Hz( only for HDMI interface)  /* id = 16 */
+};
+
+/* Commented out resolutions were not being used before, so I have left them out also
+ * but I see not real reason for doing that.
+ * will investigate and decide if it makes sense to add them or not.
+ */
+static int tvoutmode[]= {
+    TVOUT_MODE_576I,///<Define the timing mode is 576i. /* id = 0 */
+    TVOUT_MODE_1080I25,///<Define the timing mode is 1080i@25hz.  /* id = 6 */
+	TVOUT_RGB_800X480_60FPS,
+	TVOUT_RGB_1360X768_60FPS,
+	TVOUT_RGB_1366X768_60FPS,
+	TVOUT_MODE_1080P25,
+    TVOUT_MODE_480I,///<Define the timing mode is 480i.     /* id = 1 */
+	TVOUT_MODE_1080I30,///<Define the timing mode is 1080i@30hz.  /* id = 7 */
+	TVOUT_RGB_640X480_60FPS,///<Define the timing mode is 640*480@60fps(only for VGA interface) /* id = 17 */
+	TVOUT_MODE_480P,///<Define the timing mode is 480p.     /* id = 3 */
+	TVOUT_MODE_576P,///<Define the timing mode is 576p.     /* id = 2 */
+	TVOUT_RGB_800X600_60FPS,///<Define the timing mode is 800*600@60fps(only for VGA interface) /* id = 18 */
+	TVOUT_RGB_1024X768_60FPS,///<Define the timing mode is 1024*768@60fps(only for VGA interface) /* id = 19 */
+	TVOUT_RGB_1280X1024_60FPS,///<Define the timing mode is 1280*1024@60fps(only for VGA interface) /* id = 23 */
+	TVOUT_RGB_1440X900_60FPS,
+	TVOUT_MODE_720P50,///<Define the timing mode is 720p@50hz.   /* id = 4 */
+	TVOUT_MODE_720P60,///<Define the timing mode is 720p@60hz.   /* id = 5 */
+	TVOUT_MODE_1080P24,///<Define the timing mode is 1080P@24Hz( only for HDMI interface)  /* id = 12 */
+	TVOUT_MODE_1080P30,///<Define the timing mode is 1080P@30Hz( only for HDMI interface)  /* id = 14 */
+	TVOUT_MODE_1080P50,///<Define the timing mode is 1080P@50Hz( only for HDMI interface)  /* id = 15 */
+	TVOUT_MODE_1080P60,///<Define the timing mode is 1080P@60Hz( only for HDMI interface)  /* id = 16 */
+};
+
+static int maxindex=0;
+static int maxres=0;
+static int edid_timing_is_supported(cnc_edid_t *edid, int timing_index, int* tvoutmode_supported_res) {
+    int NETHD_SUPPORT_TIMINGS_COUNT = sizeof(supported_res)/sizeof(cnc_edid_vic_struct_t);
+    cnc_edid_timing_t *timing = edid->timings+timing_index;
+    int i, v_freq = (timing->v_frequency == 59) ? 60 : timing->v_frequency;
+    for(i=0; i<NETHD_SUPPORT_TIMINGS_COUNT; i++) {
+//        printf("edid: %d x %d @ %d %d\n", timing->h_active, timing->v_active, v_freq, (timing->timing_flags & EDID_DTD_FLAGS_INTERLACED));
+//        printf("res:  %d x %d @ %d %d\n", supported_res[i].h_active, supported_res[i].v_active, supported_res[i].v_frequency, (supported_res[i].interlaced == 'i'));
+
+        if(supported_res[i].h_active == timing->h_active &&
+                supported_res[i].v_active == timing->v_active &&
+                supported_res[i].v_frequency == v_freq &&
+                ((supported_res[i].interlaced == 'i') ==
+                 ((timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) != 0))) {
+            int tvout_index = tvoutmode[i];
+            if(tvout_index !=0) {
+                tvoutmode_supported_res[tvout_index] = 1;
+            }
+            if(i > maxindex) {
+                maxindex=i;
+                maxres=tvoutmode[i];
+            }
+            //        printf("EDID_SUCCESS(%d): %d x %d %c @ %dHz != %d x %d %c @ %dHz\n",i, timing->h_active, timing->v_active, (timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) ? 'i' : 'p', timing->v_frequency, supported_res[i].h_active, supported_res[i].v_active, supported_res[i].interlaced, supported_res[i].v_frequency);
+            return EDID_SUCCESS;
+        }
+#if 0
+        else {
+            printf("IN ELSE(%d): %d x %d %c @ %dHz != %d x %d %c @ %dHz\n",i, timing->h_active, timing->v_active, (timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) ? 'i' : 'p', timing->v_frequency, supported_res[i].h_active, supported_res[i].v_active, supported_res[i].interlaced, supported_res[i].v_frequency);
+        }
+#endif
+        /*
+            if (supported_res[i].h_active > timing->h_active)
+                break;
+        */
+    }
+    return EDID_ERROR;
+}
+
+int cnc_edid_filter(cnc_edid_t *edid, int* tvoutmode_supported_res, int* audmode_supported) {
+    int i;
+    maxres = 0;
+    maxindex = 0;
+    memset(tvoutmode_supported_res, 0, TVOUT_MODE_MAX*sizeof(int));
+    memset(audmode_supported, 0, 32*sizeof(int));
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++) {
+        if(edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+            if(edid_timing_is_supported(edid, i, tvoutmode_supported_res) != EDID_SUCCESS) {
+                edid->timings[i].internal_flags &= ~EDID_TIMING_IFLAGS_ENTRY_VALID;
+            }
+        }
+    }
+    for(i=0; i<EDID_AUDIO_STORAGE_SIZE; i++)
+        if(edid->audio_formats[i].format != EDID_AUDIO_FORMAT_RESERVED) {
+            if(edid->audio_formats[i].format == EDID_AUDIO_FORMAT_E_AC3) {
+                audmode_supported[CSAUD_HDMI_DOLBY_DIGITAL_PLUS] = 1;
+            }
+            else if(edid->audio_formats[i].format == EDID_AUDIO_FORMAT_AC3) {
+                audmode_supported[CSAUD_HDMI_DOLBY_DIGITAL] = 1;
+            }
+            else if(edid->audio_formats[i].format == EDID_AUDIO_FORMAT_LPCM) {
+                audmode_supported[CSAUD_HDMI_PCM_DOWN_MIX] = 1;
+                if(edid->audio_formats[i].max_channels>=2) {
+                    audmode_supported[CSAUD_HDMI_PCM_MULTI_CHANNEL] = 1;
+                }
+            }
+
+            // invalidate non-LPCM formats
+            if(edid->audio_formats[i].format != EDID_AUDIO_FORMAT_LPCM) {
+                edid->audio_formats[i].format = EDID_AUDIO_FORMAT_RESERVED;
+                continue;
+            }
+            // max of two channels for LPCM
+            //edid->audio_formats[i].max_channels = 2;
+            // disallow > 48khz formats
+            edid->audio_formats[i].frequencies &= EDID_EXT_BLOCK_SAD_FILTER_48khz_max;
+        }
+    if(edid->edid_valid & EDID_VALID_VENDOR_SPECIFIC &&
+            edid->vendor_specific_length > EDID_VENDOR_SPECIFIC_FILTER_BYTE) {
+        //printk("%s: vs: 0x%02x", __FUNCTION__, edid->vendor_specific[EDID_VENDOR_SPECIFIC_FILTER_BYTE]);
+        edid->vendor_specific[EDID_VENDOR_SPECIFIC_FILTER_BYTE] &=
+            EDID_VENDOR_SPECIFIC_FILTER_DEEP_COLOR;
+        //printk(" after filter: 0x%02x\n", edid->vendor_specific[EDID_VENDOR_SPECIFIC_FILTER_BYTE]);
+    }
+    return(maxres);
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_parse.c u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_parse.c
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_parse.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_parse.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,722 @@
+/*
+ * Copyright (c) 2003-2011, Cavium Networks. All rights reserved.
+ *
+ * This Software is the property of Cavium Networks.  The Software and all
+ * accompanying documentation are copyrighted.  The Software made available
+ * here constitutes the proprietary information of Cavium Networks.  You
+ * agree to take reasonable steps to prevent the disclosure, unauthorized use
+ * or unauthorized distribution of the Software.  You shall use this Software
+ * solely with Cavium hardware.
+ *
+ * Except as expressly permitted in a separate Software License Agreement
+ * between You and Cavium Networks, you shall not modify, decompile,
+ * disassemble, extract, or otherwise reverse engineer this Software.  You
+ * shall not make any copy of the Software or its accompanying documentation,
+ * except for copying incident to the ordinary and intended use of the
+ * Software and the Underlying Program and except for the making of a single
+ * archival copy.
+ *
+ * This Software, including technical data, may be subject to U.S.  export
+ * control laws, including the U.S.  Export Administration Act and its
+ * associated regulations, and may be subject to export or import regulations
+ * in other countries.  You warrant that You will comply strictly in all
+ * respects with all such regulations and acknowledge that you have the
+ * responsibility to obtain licenses to export, re-export or import the
+ * Software.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
+ * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
+ * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
+ * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
+ * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
+ * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
+ * POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ *
+ */
+
+#include "common.h"
+#include "cnc_edid.h"
+
+// return checksum, which will be 0 if successful
+int cnc_edid_check_sum(cnc_edid_t *edid, int which_block) {
+    int i, sum=0;
+    int offset=which_block*EDID_BLOCK_LENGTH;
+    for(i=0; i<EDID_BLOCK_LENGTH; i++) {
+        sum += edid->edid_bin[offset++];
+    }
+    sum &= 0xff;
+    if(sum != 0) {
+        printf("%s: failed for block %d, sum=0x%02x\n", __FUNCTION__, which_block, sum);
+        EDID_MARK_BAD_CHECKSUM(edid, which_block);
+    }
+#ifdef EDID_DEBUG
+    else {
+        printf("%s: checksum ok for block %d\n", __FUNCTION__, which_block);
+    }
+#endif
+    return sum;
+}
+
+int cnc_edid_parse_header(cnc_edid_t *edid) {
+    unsigned char header[EDID_HEADER_LENGTH] = EDID_HEADER_INITIALIZER;
+    int i;
+    for(i=0; i<EDID_HEADER_LENGTH; i++)
+        if(edid->edid_bin[i] != header[i]) {
+            printf("%s: header byte mismatch at byte %d, wanted 0x%02x, got 0x%02x\n",
+                   __FUNCTION__, i, header[i], edid->edid_bin[i]);
+            return EDID_ERROR;
+        }
+    edid->edid_valid |= EDID_VALID_HEADER;
+    EDID_DEBUG_DUMP(edid, EDID_HEADER_OFFSET, EDID_HEADER_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_vendor_product_id(cnc_edid_t *edid) {
+    // MFG Name, 5 bit ascii from base of 'A', so 0='A'
+    edid->id_mfg_name[0] = '@'+((edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+0] & 0x7c) >> 2);
+    edid->id_mfg_name[1] = '@'+
+                           (((edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+0] & 0x03) << 3) |
+                            ((edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+1] & 0xe0) >> 5));
+    edid->id_mfg_name[2] = '@'+(edid->edid_bin[EDID_ID_MFG_NAME_OFFSET+1] & 0x1f);
+    edid->id_mfg_name[3] = '\0';
+    EDID_PARSE_SHORT_TO_INT(edid->id_product_code, edid->edid_bin+EDID_ID_PRODUCT_CODE_OFFSET);
+    EDID_PARSE_LONG_TO_INT(edid->id_serial_number, edid->edid_bin+EDID_ID_SERIAL_NUMBER_OFFSET);
+    edid->week_of_mfg = edid->edid_bin[EDID_WEEK_OF_MFG_OFFSET];
+    edid->year_of_mfg = edid->edid_bin[EDID_YEAR_OF_MFG_OFFSET];
+    edid->edid_valid |= EDID_VALID_VENDOR_PRODUCT_ID;
+    EDID_DEBUG_DUMP(edid, EDID_VENDOR_PRODUCT_ID_OFFSET, EDID_VENDOR_PRODUCT_ID_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_version(cnc_edid_t *edid) {
+    edid->version = edid->edid_bin[EDID_VERSION_OFFSET];
+    edid->revision = edid->edid_bin[EDID_REVISION_OFFSET];
+    edid->edid_valid |= EDID_VALID_VERSION;
+    EDID_DEBUG_DUMP(edid, EDID_VERSION_OFFSET, EDID_VERSION_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_display_params(cnc_edid_t *edid) {
+    edid->signal_interface = edid->edid_bin[EDID_VIDEO_INPUT_DEF_OFFSET] &
+                             EDID_VIDEO_INPUT_DEF_SIGNAL_INT_MASK;
+    if(edid->signal_interface == EDID_VIDEO_INPUT_DEF_SIGNAL_INT_DIGITAL) {
+        edid->color_bit_depth =
+            (edid->edid_bin[EDID_VIDEO_INPUT_DEF_OFFSET] &
+             EDID_VIDEO_INPUT_DEF_COLOR_DEPTH_MASK) >>
+            EDID_VIDEO_INPUT_DEF_COLOR_DEPTH_SHIFT;
+        edid->interface_std =
+            (edid->edid_bin[EDID_VIDEO_INPUT_DEF_OFFSET] &
+             EDID_VIDEO_INPUT_DEF_INTERFACE_STD_MASK) >>
+            EDID_VIDEO_INPUT_DEF_INTERFACE_STD_SHIFT;
+    }
+    else {   // EDID_VIDEO_INPUT_DEF_SIGNAL_INT_ANALOG
+        edid->video_input_def = edid->edid_bin[EDID_DISPLAY_PARAMS_OFFSET];
+    }
+    edid->horizontal = edid->edid_bin[EDID_VIDEO_INPUT_HORIZONTAL_OFFSET];
+    edid->vertical = edid->edid_bin[EDID_VIDEO_INPUT_VERTICAL_OFFSET];
+    edid->gamma = edid->edid_bin[EDID_VIDEO_INPUT_GAMMA_OFFSET];
+    edid->feature_support = edid->edid_bin[EDID_VIDEO_INPUT_FEATURE_SUPPORT_OFFSET];
+    edid->edid_valid |= EDID_VALID_DISPLAY_PARAMS;
+    EDID_DEBUG_DUMP(edid, EDID_DISPLAY_PARAMS_OFFSET, EDID_DISPLAY_PARAMS_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_chromaticity(cnc_edid_t *edid) {
+    edid->chromaticity[EDID_CHROMATICITY_Rx_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_RxLo_OFFSET] & EDID_CHROMATICITY_RxLo_MASK) >>
+         EDID_CHROMATICITY_RxLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_RxHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Ry_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_RyLo_OFFSET] & EDID_CHROMATICITY_RyLo_MASK) >>
+         EDID_CHROMATICITY_RyLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_RyHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Gx_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_GxLo_OFFSET] & EDID_CHROMATICITY_GxLo_MASK) >>
+         EDID_CHROMATICITY_GxLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_GxHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Gy_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_GyLo_OFFSET] & EDID_CHROMATICITY_GyLo_MASK) >>
+         EDID_CHROMATICITY_GyLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_GyHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Bx_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_BxLo_OFFSET] & EDID_CHROMATICITY_BxLo_MASK) >>
+         EDID_CHROMATICITY_BxLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_BxHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_By_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_ByLo_OFFSET] & EDID_CHROMATICITY_ByLo_MASK) >>
+         EDID_CHROMATICITY_ByLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_ByHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Wx_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_WxLo_OFFSET] & EDID_CHROMATICITY_WxLo_MASK) >>
+         EDID_CHROMATICITY_WxLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_WxHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->chromaticity[EDID_CHROMATICITY_Wy_INDEX] =
+        ((edid->edid_bin[EDID_CHROMATICITY_WyLo_OFFSET] & EDID_CHROMATICITY_WyLo_MASK) >>
+         EDID_CHROMATICITY_WyLo_SHIFT) |
+        (edid->edid_bin[EDID_CHROMATICITY_WyHi_OFFSET] << EDID_CHROMATICITY_HiByte_SHIFT);
+    edid->edid_valid |= EDID_VALID_CHROMATICITY;
+    EDID_DEBUG_DUMP(edid, EDID_CHROMATICITY_OFFSET, EDID_CHROMATICITY_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_save_established_timing(cnc_edid_t *edid, int h, int v, int hz, int interlaced) {
+    cnc_edid_timing_t *timing = cnc_edid_get_free_timing_struct(edid);
+    if(timing == NULL) {
+        return EDID_ERROR;
+    }
+    timing->h_active = h;
+    timing->v_active = v;
+    timing->v_frequency = hz;
+    timing->timing_flags = interlaced ? EDID_DTD_FLAGS_INTERLACED : 0;
+    timing->internal_flags =
+        EDID_TIMING_IFLAGS_LOCATION_EST |
+        EDID_TIMING_IFLAGS_V_FREQ_VALID |
+        EDID_TIMING_IFLAGS_ENTRY_VALID;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_established_timings(cnc_edid_t *edid) {
+    unsigned char et1=edid->edid_bin[EDID_ESTABLISHED_TIMINGS_I_OFFSET];
+    unsigned char et2=edid->edid_bin[EDID_ESTABLISHED_TIMINGS_II_OFFSET];
+    unsigned char mt =edid->edid_bin[EDID_ESTABLISHED_TIMINGS_MFG_OFFSET];
+    if(et1 & 0x80) {
+        cnc_edid_save_established_timing(edid, 720, 400, 70, 0);
+    }
+    if(et1 & 0x40) {
+        cnc_edid_save_established_timing(edid, 720, 400, 88, 0);
+    }
+    if(et1 & 0x20) {
+        cnc_edid_save_established_timing(edid, 640, 480, 60, 0);
+    }
+    if(et1 & 0x10) {
+        cnc_edid_save_established_timing(edid, 640, 480, 67, 0);
+    }
+    if(et1 & 8) {
+        cnc_edid_save_established_timing(edid, 640, 480, 72, 0);
+    }
+    if(et1 & 4) {
+        cnc_edid_save_established_timing(edid, 640, 480, 75, 0);
+    }
+    if(et1 & 2) {
+        cnc_edid_save_established_timing(edid, 800, 600, 56, 0);
+    }
+    if(et1 & 1) {
+        cnc_edid_save_established_timing(edid, 800, 600, 60, 0);
+    }
+    if(et2 & 0x80) {
+        cnc_edid_save_established_timing(edid, 800, 600, 72, 0);
+    }
+    if(et2 & 0x40) {
+        cnc_edid_save_established_timing(edid, 800, 600, 75, 0);
+    }
+    if(et2 & 0x20) {
+        cnc_edid_save_established_timing(edid, 832, 624, 75, 0);
+    }
+    if(et2 & 0x10) {
+        cnc_edid_save_established_timing(edid, 1024, 768, 87, 1);
+    }
+    if(et2 & 8) {
+        cnc_edid_save_established_timing(edid, 1024, 768, 60, 0);
+    }
+    if(et2 & 4) {
+        cnc_edid_save_established_timing(edid, 1024, 768, 70, 0);
+    }
+    if(et2 & 2) {
+        cnc_edid_save_established_timing(edid, 1024, 768, 75, 0);
+    }
+    if(et2 & 1) {
+        cnc_edid_save_established_timing(edid, 1280, 1024, 75, 0);
+    }
+    if(mt & 0x80) {
+        cnc_edid_save_established_timing(edid, 1152, 870, 75, 0);
+    }
+#ifdef EDID_DEPRECATED
+    memcpy(edid->edid_established_timings,
+           edid->edid_bin+EDID_ESTABLISHED_TIMINGS_OFFSET,
+           EDID_ESTABLISHED_TIMINGS_LENGTH);
+#endif
+    edid->edid_valid |= EDID_VALID_EST_TIMINGS;
+    EDID_DEBUG_DUMP(edid, EDID_ESTABLISHED_TIMINGS_OFFSET, EDID_ESTABLISHED_TIMINGS_LENGTH);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_and_store_standard_timing(cnc_edid_t *edid, int offset, cnc_edid_timing_t *timing) {
+    unsigned char b0 = edid->edid_bin[offset];
+    unsigned char b1 = edid->edid_bin[offset+1];
+    if(b0 == 1 && b1 == 1) { // this std timing block is unused
+        return EDID_SUCCESS;
+    }
+    if(b0 == 0) {
+        printf("%s: Reserved value in byte 0 of std timing offset 0x%x\n",
+               __FUNCTION__, offset);
+        return EDID_ERROR;
+    }
+    timing->h_active = b0*8+248; // VESA EEDID spec table 3.19
+    switch(b1 & EDID_STANDARD_TIMINGS_AR_MASK) {
+    case 0x00:
+        timing->ar_numerator = 16;
+        timing->ar_denominator = 10;
+        break;
+    case 0x40:
+        timing->ar_numerator =  4;
+        timing->ar_denominator =  3;
+        break;
+    case 0x80:
+        timing->ar_numerator =  5;
+        timing->ar_denominator =  4;
+        break;
+    case 0xc0:
+        timing->ar_numerator = 16;
+        timing->ar_denominator =  9;
+        break;
+    default:
+        printf("%s: Something not right about AR field calculation\n", __FUNCTION__);
+        return EDID_ERROR;
+    }
+    timing->v_active = timing->h_active * timing->ar_denominator / timing->ar_numerator;
+    timing->v_frequency = (b1 & EDID_STANDARD_TIMINGS_FIELD_REFRESH_MASK) + 60;
+    timing->internal_flags =
+        EDID_TIMING_IFLAGS_AR_VALID |
+        EDID_TIMING_IFLAGS_V_FREQ_VALID |
+        EDID_TIMING_IFLAGS_ENTRY_VALID;
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_standard_timings(cnc_edid_t *edid) {
+    int i, ret=EDID_SUCCESS;
+    cnc_edid_timing_t *timing;
+    for(i=0; i<EDID_STANDARD_TIMINGS_COUNT; i++) {
+        timing = cnc_edid_get_free_timing_struct(edid);
+        if(timing == NULL) {
+            return EDID_ERROR;
+        }
+        ret |= cnc_edid_parse_and_store_standard_timing(edid, EDID_STANDARD_TIMINGS_BLOCK_OFFSET(i), timing);
+        if(timing->internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+            timing->internal_flags |= EDID_TIMING_IFLAGS_LOCATION_STD;
+        }
+    }
+#ifdef EDID_DEPRECATED
+    memcpy(edid->edid_standard_timings,
+           edid->edid_bin+EDID_STANDARD_TIMINGS_OFFSET,
+           EDID_STANDARD_TIMINGS_LENGTH);
+#endif
+    edid->edid_valid |= EDID_VALID_STD_TIMINGS;
+    EDID_DEBUG_DUMP(edid, EDID_STANDARD_TIMINGS_OFFSET, EDID_STANDARD_TIMINGS_LENGTH);
+    return ret;
+}
+
+int cnc_edid_parse_display_descriptor(cnc_edid_t *edid, int block_offset) {
+    int display_desc_type = edid->edid_bin[block_offset + EDID_DISPLAY_DESC_TAG_NUM_OFFSET];
+    switch(display_desc_type) {
+    case EDID_DISPLAY_DESC_DUMMY:
+        break;
+    case EDID_DISPLAY_DESC_DISPLAY_SERIAL_NUMBER: {
+        char *name = (char *)edid->edid_bin + block_offset + EDID_DISPLAY_DESC_STRING_OFFSET;
+        strncpy(edid->display_serial_number, name, EDID_DISPLAY_DESC_STRING_LENGTH);
+        edid->display_serial_number[EDID_DISPLAY_DESC_STRING_LENGTH] = '\0';
+        edid->edid_valid |= EDID_VALID_DISPLAY_SERIAL_NUMBER;
+        break;
+    }
+    case EDID_DISPLAY_DESC_ALPHANUM_STRING: {
+        char *name = (char *)edid->edid_bin + block_offset + EDID_DISPLAY_DESC_STRING_OFFSET;
+        strncpy(edid->display_data_string, name, EDID_DISPLAY_DESC_STRING_LENGTH);
+        edid->display_data_string[EDID_DISPLAY_DESC_STRING_LENGTH] = '\0';
+        edid->edid_valid |= EDID_VALID_DISPLAY_DATA_STR;
+        break;
+    }
+    case EDID_DISPLAY_DESC_DISPLAY_RANGE_LIMITS: {
+        int flags = edid->edid_bin[block_offset + EDID_DISPLAY_RANGE_LIMITS_OFFSET];
+        int v_min_add, v_max_add, h_min_add, h_max_add;
+        switch(flags & EDID_DISPLAY_RANGE_LIMITS_FLAGS_V_MASK) {
+        case 0:
+            v_min_add = v_max_add = 0;
+            break;
+        case 2:
+            v_min_add = 0;
+            v_max_add = 255;
+            break;
+        case 3:
+            v_min_add = v_max_add = 255;
+            break;
+        default:
+            printf("%s: WARNING: reserved v_flags value in display range limits block at offset 0x%x\n", __FUNCTION__, block_offset);
+            v_min_add = v_max_add = 0;
+        }
+        switch(flags & EDID_DISPLAY_RANGE_LIMITS_FLAGS_H_MASK) {
+        case   0:
+            h_min_add =    h_max_add =   0;
+            break;
+        case   8:
+            h_min_add = 0;
+            h_max_add = 255;
+            break;
+        case 0xc:
+            h_min_add =    h_max_add = 255;
+            break;
+        default:
+            printf("%s: WARNING: reserved h_flags value in display range limits block at offset 0x%x\n", __FUNCTION__, block_offset);
+            h_min_add = h_max_add = 0;
+        }
+        edid->rate_v_min =
+            edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_V_MIN_OFFSET] + v_min_add;
+        edid->rate_v_max =
+            edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_V_MAX_OFFSET] + v_max_add;
+        edid->rate_h_min =
+            edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_H_MIN_OFFSET] + h_min_add;
+        edid->rate_h_max =
+            edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_H_MAX_OFFSET] + h_max_add;
+        edid->rate_pixel_clock_max =
+            edid->edid_bin[block_offset+EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MAX_OFFSET] *
+            EDID_DISPLAY_RANGE_LIMITS_PIXCLK_MULTIPLIER;
+        edid->edid_valid |= EDID_VALID_DISPLAY_RANGE_LIMITS;
+        // FIXME: Byte 10 GTF support???
+#ifdef EDID_DEPRECATED
+        memcpy(edid->display_range_limits,
+               edid->edid_bin + block_offset + EDID_DISPLAY_RANGE_LIMITS_OFFSET,
+               EDID_DISPLAY_RANGE_LIMITS_COUNT);
+#endif
+        break;
+    }
+    case EDID_DISPLAY_DESC_DISPLAY_PRODUCT_NAME: {
+        char *name = (char *)edid->edid_bin + block_offset + EDID_DISPLAY_DESC_STRING_OFFSET;
+        strncpy(edid->display_product_name, name, EDID_DISPLAY_DESC_STRING_LENGTH);
+        edid->display_product_name[EDID_DISPLAY_DESC_STRING_LENGTH] = '\0';
+        edid->edid_valid |= EDID_VALID_DISPLAY_PRODUCT_NAME;
+        break;
+    }
+    case EDID_DISPLAY_DESC_STD_TIMING_ID: {
+        int i, ret=EDID_SUCCESS;
+        cnc_edid_timing_t *timing;
+        for(i=0; i<EDID_DISPLAY_DESC_STD_TIMINGS_COUNT; i++) {
+            timing = cnc_edid_get_free_timing_struct(edid);
+            if(timing == NULL) {
+                return EDID_ERROR;
+            }
+            ret |= cnc_edid_parse_and_store_standard_timing(edid, EDID_STANDARD_TIMINGS_BLOCK_OFFSET(i), timing);
+            if(timing->internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+                timing->internal_flags |= EDID_TIMING_IFLAGS_LOCATION_EXT_18B_STD;
+            }
+        }
+        break;
+    }
+    case EDID_DISPLAY_DESC_COLOR_POINT_DATA:
+    case EDID_DISPLAY_DESC_DCM_DATA:
+    case EDID_DISPLAY_DESC_CVT_3_BYTE_CODES:
+    case EDID_DISPLAY_DESC_EST_TIMINGS_III:
+        printf("%s: WARNING: Unparsed block type 0x%x\n", __FUNCTION__, display_desc_type);
+        return EDID_ERROR;
+    case 0: {
+        int i, sum=0, bytes_remaining = (EDID_18B_BLOCK_LENGTH - EDID_DISPLAY_DESC_TAG_NUM_OFFSET);
+        unsigned char *block = edid->edid_bin+block_offset + EDID_DISPLAY_DESC_TAG_NUM_OFFSET;
+        for(i=1; i<bytes_remaining; i++) {
+            sum += block[i];
+        }
+        if(sum == 0) {
+            break;    // determined this 'block' is padding at the end of an extension block
+        }
+        // else fall through to the warning message in the default case
+    }
+    default:
+        printf("%s: WARNING: Reserved or Mfg-specified display descriptor type 0x%02x\n", __FUNCTION__, display_desc_type);
+        return EDID_ERROR;
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_dtd(cnc_edid_t *edid, int offset, cnc_edid_timing_t *timing) {
+    unsigned char *block = edid->edid_bin + offset;
+    if(timing == NULL) {
+        return EDID_ERROR;
+    }
+    timing->pixel_clock = (block[EDID_DTD_PIXEL_CLOCK_LO_OFFSET] |
+                           (block[EDID_DTD_PIXEL_CLOCK_HI_OFFSET] << EDID_DTD_PIXEL_CLOCK_HI_SHIFT)) *
+                          EDID_DTD_PIXEL_CLOCK_MULTIPLIER;
+    timing->h_active = block[EDID_DTD_H_ACTIVE_LO_OFFSET] |
+                       ((block[EDID_DTD_H_ACTIVE_HI_OFFSET] & EDID_DTD_H_ACTIVE_HI_MASK) << EDID_DTD_H_ACTIVE_HI_SHIFT);
+    timing->v_active = block[EDID_DTD_V_ACTIVE_LO_OFFSET] |
+                       ((block[EDID_DTD_V_ACTIVE_HI_OFFSET] & EDID_DTD_V_ACTIVE_HI_MASK) << EDID_DTD_V_ACTIVE_HI_SHIFT);
+    timing->h_blank = block[EDID_DTD_H_BLANK_LO_OFFSET] |
+                      ((block[EDID_DTD_H_BLANK_HI_OFFSET] & EDID_DTD_H_BLANK_HI_MASK) << EDID_DTD_H_BLANK_HI_SHIFT);
+    timing->v_blank = block[EDID_DTD_V_BLANK_LO_OFFSET] |
+                      ((block[EDID_DTD_V_BLANK_HI_OFFSET] & EDID_DTD_V_BLANK_HI_MASK) << EDID_DTD_V_BLANK_HI_SHIFT);
+    timing->h_front_porch = block[EDID_DTD_H_FRONT_PORCH_LO_OFFSET] |
+                            ((block[EDID_DTD_H_FRONT_PORCH_HI_OFFSET] & EDID_DTD_H_FRONT_PORCH_HI_MASK) << EDID_DTD_H_FRONT_PORCH_HI_SHIFT);
+    timing->v_front_porch =
+        ((block[EDID_DTD_V_FRONT_PORCH_LO_OFFSET] & EDID_DTD_V_FRONT_PORCH_LO_MASK) >> EDID_DTD_V_FRONT_PORCH_LO_SHIFT) |
+        ((block[EDID_DTD_V_FRONT_PORCH_HI_OFFSET] & EDID_DTD_V_FRONT_PORCH_HI_MASK) << EDID_DTD_V_FRONT_PORCH_HI_SHIFT);
+    timing->h_sync_width = block[EDID_DTD_H_SYNC_WIDTH_LO_OFFSET] |
+                           ((block[EDID_DTD_H_SYNC_WIDTH_HI_OFFSET] & EDID_DTD_H_SYNC_WIDTH_HI_MASK) << EDID_DTD_H_SYNC_WIDTH_HI_SHIFT);
+    timing->v_sync_width =
+        ((block[EDID_DTD_V_SYNC_WIDTH_LO_OFFSET] & EDID_DTD_V_SYNC_WIDTH_LO_MASK) >>EDID_DTD_V_SYNC_WIDTH_LO_SHIFT) |
+        ((block[EDID_DTD_V_SYNC_WIDTH_HI_OFFSET] & EDID_DTD_V_SYNC_WIDTH_HI_MASK) << EDID_DTD_V_SYNC_WIDTH_HI_SHIFT);
+    timing->h_size_mm = block[EDID_DTD_H_SIZE_MM_LO_OFFSET] |
+                        ((block[EDID_DTD_H_SIZE_MM_HI_OFFSET] & EDID_DTD_H_SIZE_MM_HI_MASK) << EDID_DTD_H_SIZE_MM_HI_SHIFT);
+    timing->v_size_mm = block[EDID_DTD_V_SIZE_MM_LO_OFFSET] |
+                        ((block[EDID_DTD_V_SIZE_MM_HI_OFFSET] & EDID_DTD_V_SIZE_MM_HI_MASK) << EDID_DTD_V_SIZE_MM_HI_SHIFT);
+    timing->border_width = block[EDID_DTD_BORDER_WIDTH_OFFSET];
+    timing->border_height = block[EDID_DTD_BORDER_HEIGHT_OFFSET];
+    timing->timing_flags = block[EDID_DTD_FLAGS_OFFSET];
+    timing->h_total = timing->h_active + timing->h_blank;
+    timing->v_total = timing->v_active + timing->v_blank;
+    timing->v_frequency = timing->pixel_clock / (timing->h_total * timing->v_total);
+    timing->internal_flags =
+        EDID_TIMING_IFLAGS_AR_VALID |
+        EDID_TIMING_IFLAGS_V_FREQ_VALID |
+        EDID_TIMING_IFLAGS_PIXEL_CLOCK_VALID |
+        EDID_TIMING_IFLAGS_ENTRY_VALID;
+    if((timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) != 0) {
+        timing->v_active <<= 1;
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_parse_18_byte_block(cnc_edid_t *edid, int block_offset, cnc_edid_timing_t *timing) {
+    int ret;
+    if(edid->edid_bin[block_offset] == 0 &&
+            edid->edid_bin[block_offset+1] == 0 &&
+            edid->edid_bin[block_offset+2] == 0) {
+        ret = cnc_edid_parse_display_descriptor(edid, block_offset);
+    }
+    else {
+        ret = cnc_edid_parse_dtd(edid, block_offset, timing);
+    }
+    EDID_DEBUG_DUMP(edid, block_offset, EDID_18B_BLOCK_LENGTH);
+    return ret;
+}
+
+// returns the number of extension blocks
+int cnc_edid_parse_extension_blocks_count(cnc_edid_t *edid) {
+    return edid->ext_blocks_count = edid->edid_bin[EDID_EXT_BLOCKS_COUNT];
+}
+
+
+int cnc_edid_parse_main_18_byte_blocks(cnc_edid_t *edid) {
+    int i, offset, ret=EDID_SUCCESS;
+    cnc_edid_timing_t *timing;
+    for(i=0; i<4; i++) {
+        offset = EDID_MAIN_18B_BLOCK_OFFSET(i);
+        timing = cnc_edid_get_free_timing_struct(edid);
+        if(timing == NULL) {
+            return EDID_ERROR;
+        }
+        ret |= cnc_edid_parse_18_byte_block(edid, offset, timing);
+        if(ret == EDID_SUCCESS && timing->internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+            timing->internal_flags |= EDID_TIMING_IFLAGS_LOCATION_MAIN_18B;
+            if(i == 0) {
+                timing->internal_flags |= EDID_TIMING_IFLAGS_PREFERRED;
+            }
+        }
+    }
+    return ret;
+}
+
+// returns EDID_ERROR if any part fails or the number of extension blocks if it succeeds
+int cnc_edid_parse_main(cnc_edid_t *edid) {
+    int i, edid_retval=EDID_SUCCESS;
+    EDID_VALIDATE_BINARY(edid, 0);
+    edid_retval |= cnc_edid_check_sum(edid, 0); // main edid is block 0
+    edid_retval |= cnc_edid_parse_header(edid);
+    edid_retval |= cnc_edid_parse_vendor_product_id(edid);
+    edid_retval |= cnc_edid_parse_version(edid);
+    edid_retval |= cnc_edid_parse_display_params(edid);
+    edid_retval |= cnc_edid_parse_chromaticity(edid);
+    edid_retval |= cnc_edid_parse_established_timings(edid);
+    edid_retval |= cnc_edid_parse_standard_timings(edid);
+    edid_retval |= cnc_edid_parse_main_18_byte_blocks(edid);
+    i = cnc_edid_parse_extension_blocks_count(edid);
+    return edid_retval ? EDID_ERROR : i;
+}
+
+int cnc_edid_parse_eedid_data_block(cnc_edid_t *edid, int offset) {
+    unsigned char *block = edid->edid_bin + offset;
+    int tag = (block[0] & EDID_EXT_BLOCK_DATA_BLOCK_TAG_MASK) >>
+              EDID_EXT_BLOCK_DATA_BLOCK_TAG_SHIFT;
+    int block_length = block[EDID_EXT_BLOCK_DATA_BLOCK_LEN_OFFSET] &
+                       EDID_EXT_BLOCK_DATA_BLOCK_LEN_MASK;
+    int ret=EDID_SUCCESS;
+    // tag types from Table 41 of CEA 861-E
+    switch(tag) {
+    case EDID_EXT_BLOCK_TYPE_AUDIO: {
+        int i, n_sads = block_length/EDID_EXT_BLOCK_SAD_SIZE;
+        cnc_edid_audio_t *audio_fmt;
+        unsigned char *sad;
+#ifdef EDID_DEBUG
+        printf("%s: Audio byte 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+        if(block_length % EDID_EXT_BLOCK_SAD_SIZE == 0) {
+            printf("\t%d SADs in this block\n", n_sads);
+        }
+#endif
+        if(block_length % EDID_EXT_BLOCK_SAD_SIZE) {
+            printf("\tweird Audio block len %d\n", block_length);
+            return EDID_ERROR;
+        }
+        for(i=0; i<n_sads; i++) {
+            int format, num_channels;
+            sad = block + 1 + (i*EDID_EXT_BLOCK_SAD_SIZE);
+            format = (sad[0] & EDID_EXT_BLOCK_SAD_FORMAT_CODE_MASK) >> EDID_EXT_BLOCK_SAD_FORMAT_CODE_SHIFT;
+            num_channels = sad[0] & EDID_EXT_BLOCK_SAD_NUM_CHANNELS_MASK;
+            if(format == EDID_AUDIO_FORMAT_RESERVED) {
+                printf("%s: Audio format in SAD %d is reserved value (0)\n", __FUNCTION__, i);
+                continue;
+            }
+            audio_fmt = cnc_edid_get_free_audio_struct(edid);
+            if(audio_fmt == NULL) {
+                return EDID_ERROR;
+            }
+            audio_fmt->format = format;
+            audio_fmt->max_channels = num_channels+1;
+            audio_fmt->frequencies = sad[1];
+            audio_fmt->extra_data = sad[2];
+#ifdef EDID_DEBUG
+            printf("\tformat %d, frequencies:0x%02x, extra:%02x\n", format, sad[1], sad[2]);
+#endif
+        }
+        edid->edid_valid |= EDID_VALID_AUDIO_FORMATS;
+        break;
+    }
+    case EDID_EXT_BLOCK_TYPE_VIDEO: {
+        cnc_edid_timing_t *timing;
+        int i;
+        for(i=1; i<=block_length; i++) {
+            timing = cnc_edid_get_free_timing_struct(edid);
+            if(timing == NULL) {
+                return EDID_ERROR;
+            }
+            ret |= cnc_edid_vic_to_edid_timing(timing,
+                                           block[i] & EDID_EXT_BLOCK_TYPE_VIDEO_VIC_MASK);
+            if(timing->internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+                if(block[i] & EDID_EXT_BLOCK_TYPE_VIDEO_NATIVE_MASK) {
+                    timing->internal_flags |= EDID_TIMING_IFLAGS_NATIVE;
+                }
+                timing->internal_flags |= EDID_TIMING_IFLAGS_LOCATION_SVD;
+            }
+        }
+#ifdef EDID_DEBUG
+        printf("%s: Video byte 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+#endif
+        edid->edid_valid |= EDID_VALID_SVDS_PRESENT;
+        break;
+    }
+    case EDID_EXT_BLOCK_TYPE_VENDOR_SPECIFIC: {
+        int i;
+        for(i=0; i<block_length; i++) {
+            edid->vendor_specific[i] = block[i+1];
+        }
+        edid->vendor_specific_length = block_length;
+#ifdef EDID_DEBUG
+        printf("%s: Vendor byte 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+#endif
+        edid->edid_valid |= EDID_VALID_VENDOR_SPECIFIC;
+        break;
+    }
+    case EDID_EXT_BLOCK_TYPE_SPEAKER:
+        if(block[0] != 0x83) {
+            printf("%s: Speaker Alloc header is weird: 0x%02x offset 0x%02x\n",  __FUNCTION__, block[0], offset);
+            break;
+        }
+        edid->speaker_alloc = block[1] | block[2]<<EDID_SPEAKER_BYTE2_SHIFT;
+#ifdef EDID_DEBUG
+        printf("%s: Speaker byte 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+#endif
+        edid->edid_valid |= EDID_VALID_SPEAKER_ALLOC;
+        break;
+    case EDID_EXT_BLOCK_TYPE_VESA_DTC:
+#ifdef EDID_DEBUG
+        printf("%s: VESA DTC byte 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+#endif
+        break;
+    case EDID_EXT_BLOCK_TYPE_EXTENDED: { // extended tag
+        int etag = block[1];
+        if(etag == EDID_EXTENDED_TAG_CODE_VIDCAP) {
+            edid->video_capability = block[2];
+            edid->edid_valid |= EDID_VALID_VIDEO_CAPABILITY;
+        }
+        else if(etag == EDID_EXTENDED_TAG_CODE_COLORIMETRY) {
+            edid->colorimetry = block[2] | (block[3] << EDID_COLORIMETRY_BYTE2_SHIFT);
+            edid->edid_valid |= EDID_VALID_COLORIMETRY;
+        }
+        else {
+            printf("%s: Unhandled Extended Type Tag 0x%02x offset 0x%x\n", __FUNCTION__, etag, offset);
+        }
+#ifdef EDID_DEBUG
+        if(etag == EDID_EXTENDED_TAG_CODE_VIDCAP) {
+            printf("%s: VidCap Extended Type Tag offset 0x%x\n", __FUNCTION__, offset);
+        }
+        else if(etag == EDID_EXTENDED_TAG_CODE_COLORIMETRY) {
+            printf("%s: Colorimetry Extended Type Tag offset 0x%x\n", __FUNCTION__, offset);
+        }
+#endif
+        break;
+    }
+    default:
+        printf("%s: Reserved Type Tag 0x%02x offset 0x%x\n", __FUNCTION__, block[0], offset);
+    }
+    return ret;
+}
+
+int cnc_edid_parse_extension(cnc_edid_t *edid, int which_block) {
+    int ret, offset, dtd_start_offset, dtd_count, parsed_block_len;
+    int block_offset = EDID_EXT_BLOCK_OFFSET(which_block);
+    unsigned char *block = edid->edid_bin + block_offset;
+    cnc_edid_timing_t *timing;
+    ret = cnc_edid_check_sum(edid, which_block);
+    if(block[EDID_EXT_BLOCK_TAG_OFFSET] != EDID_EXT_BLOCK_TAG_EXPECTED_VALUE) {
+        printf("%s: ERROR: EEDID Block Tag unexpected value 0x%02x, offset 0x%x\n",
+               __FUNCTION__,
+               block[EDID_EXT_BLOCK_TAG_OFFSET], EDID_EXT_BLOCK_OFFSET(which_block));
+        return EDID_ERROR;
+    }
+    if(block[EDID_EXT_BLOCK_REVISION_OFFSET] != EDID_EXT_BLOCK_REVISION_EXPECTED_VALUE) {
+        printf("%s: WARNING: EEDID Block Revision unexpected value 0x%02x, offset 0x%x\n",
+               __FUNCTION__,
+               block[EDID_EXT_BLOCK_TAG_OFFSET], EDID_EXT_BLOCK_OFFSET(which_block));
+    }
+    // dtd_start_offset and the loop control variable offset are relative to this block
+    dtd_start_offset = block[EDID_EXT_BLOCK_18B_BLOCK_START_OFFSET];
+    edid->eedid_flags = block[EDID_EXT_BLOCK_FLAGS_OFFSET];
+    dtd_count = edid->eedid_flags & EDID_EXT_BLOCK_FLAGS_DTD_COUNT_MASK;
+    for(offset = EDID_EXT_BLOCK_DATA_BLOCKS_OFFSET;
+            offset < dtd_start_offset;
+            offset += parsed_block_len) {
+        ret |= cnc_edid_parse_eedid_data_block(edid, EDID_EXT_BLOCK_OFFSET(which_block) + offset);
+        parsed_block_len = (block[offset] & EDID_EXT_BLOCK_DATA_BLOCK_LEN_MASK) + 1;
+    }
+    // This should maybe be fatal.  Bad juju would occur if alignment was off.
+    if(offset != dtd_start_offset)
+        printf("%s: WARNING: end of data blocks != start of 18B blocks (0x%x != 0x%x)\n",
+               __FUNCTION__, offset, dtd_start_offset);
+    for(; offset<(EDID_EXT_BLOCK_SIZE-EDID_18B_BLOCK_LENGTH); offset+=EDID_18B_BLOCK_LENGTH) {
+        timing = cnc_edid_get_free_timing_struct(edid);
+        if(timing == NULL) {
+            return EDID_ERROR;
+        }
+        ret |= cnc_edid_parse_18_byte_block(edid, block_offset + offset, timing);
+        if(timing->internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) {
+            timing->internal_flags |= EDID_TIMING_IFLAGS_LOCATION_EXT_18B;
+        }
+    }
+    for(; offset<EDID_CHECKSUM_OFFSET; offset++) {
+        if(block[offset] != 0) {
+            printf("%s: WARNING: wanted padding, found non-zero data at offset 0x%x, eedid blcok %d\n", __FUNCTION__, offset, which_block);
+        }
+    }
+    edid->edid_valid |= EDID_VALID_EEDID; // sufficient?
+    return ret;
+}
+
+int cnc_edid_parse(cnc_edid_t *edid) {
+    int i, n_ext_blocks, ret=EDID_SUCCESS;
+    n_ext_blocks = cnc_edid_parse_main(edid);
+    if(n_ext_blocks <= 0) {
+        printf("%s: not parsing eedid %d\n", __FUNCTION__, n_ext_blocks);
+        return n_ext_blocks; // failed or no ext blocks
+    }
+    for(i=1; i<=n_ext_blocks; i++) {
+        ret |= cnc_edid_parse_extension(edid, i);
+    }
+    return ret;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_print.c u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_print.c
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_print.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_print.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2003-2011, Cavium Networks. All rights reserved.
+ *
+ * This Software is the property of Cavium Networks.  The Software and all
+ * accompanying documentation are copyrighted.  The Software made available
+ * here constitutes the proprietary information of Cavium Networks.  You
+ * agree to take reasonable steps to prevent the disclosure, unauthorized use
+ * or unauthorized distribution of the Software.  You shall use this Software
+ * solely with Cavium hardware.
+ *
+ * Except as expressly permitted in a separate Software License Agreement
+ * between You and Cavium Networks, you shall not modify, decompile,
+ * disassemble, extract, or otherwise reverse engineer this Software.  You
+ * shall not make any copy of the Software or its accompanying documentation,
+ * except for copying incident to the ordinary and intended use of the
+ * Software and the Underlying Program and except for the making of a single
+ * archival copy.
+ *
+ * This Software, including technical data, may be subject to U.S.  export
+ * control laws, including the U.S.  Export Administration Act and its
+ * associated regulations, and may be subject to export or import regulations
+ * in other countries.  You warrant that You will comply strictly in all
+ * respects with all such regulations and acknowledge that you have the
+ * responsibility to obtain licenses to export, re-export or import the
+ * Software.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
+ * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
+ * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
+ * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
+ * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
+ * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
+ * POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ *
+ */
+
+#include "common.h"
+#include "cnc_edid.h"
+
+int cnc_edid_print_hex(cnc_edid_t *edid) {
+    int i=0, edid_retval=EDID_SUCCESS;
+    EDID_VALIDATE_BINARY(edid, 0);
+    printf("\n");
+    for(i=0; i<edid->edid_bin_length; i++) {
+        if((i & 0xf) == 0) {
+            printf("0x%02x:", i);
+        }
+        printf(" %02x", edid->edid_bin[i]);
+        if((i & 0xf) == 0xf) {
+            printf("\n");
+        }
+    }
+    printf("\n");
+    return edid_retval;
+}
+
+int cnc_edid_print_vendor_product_id(cnc_edid_t *edid) {
+    if(edid->edid_valid & EDID_VALID_VENDOR_PRODUCT_ID) {
+        printf("\t   Manufacturer: %s\n", edid->id_mfg_name);
+        printf("\t   Product Code: 0x%04x\n", edid->id_product_code);
+        printf("\t  Serial Number: 0x%08x\n", edid->id_serial_number);
+        printf("\t    Week of Mfg: %d\n", edid->week_of_mfg);
+        printf("\t    Year of Mfg: %d\n", edid->year_of_mfg+1990);
+    }
+    // for debugging id mfg name parsing
+    //printf("%02x %02x %02x %02x\n", edid->id_mfg_name[0], edid->id_mfg_name[1], edid->id_mfg_name[2], edid->id_mfg_name[3]);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_version(cnc_edid_t *edid) {
+    if(edid->edid_valid & EDID_VALID_VERSION) {
+        printf("\t        Version: %d\n", edid->version);
+        printf("\t       Revision: %d\n", edid->revision);
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_display_params(cnc_edid_t *edid) {
+    if(edid->edid_valid & EDID_VALID_DISPLAY_PARAMS) {
+        if(edid->signal_interface == EDID_VIDEO_INPUT_DEF_SIGNAL_INT_DIGITAL) {
+            printf("\t      Interface: Digital\n");
+            printf("\tColor Bit Depth: %s\n", cnc_edid_color_bit_depth_ascii(edid));
+            printf("\t  Interface Std: %s\n", cnc_edid_interface_std_ascii(edid));
+        }
+        else {
+            printf("\t      Interface: Analog\n");
+            printf("\t    Field Value: 0x%02x (should parse)\n", edid->video_input_def);
+        }
+        if(edid->horizontal != 0 && edid->vertical != 0) {
+            printf("\t      Horzontal: %3dcm %d.%02din\n", edid->horizontal, (edid->horizontal*100)/254, edid->horizontal%254);
+            printf("\t       Vertical: %3dcm %d.%02din\n", edid->vertical, (edid->vertical*100)/254, edid->vertical%254);
+        }
+        else {
+            printf("\t     H/V Fields: 0x%02x 0x%02x\n", edid->horizontal, edid->vertical);
+        }
+        if(edid->gamma != 0xff) {
+            printf("\t          Gamma: %d.%02d\n", cnc_edid_gamma_int(edid), cnc_edid_gamma_fract(edid));
+        }
+        else {
+            printf("\t          Gamma: Undefined\n");
+        }
+        printf("\t        Standby: %supported\n",
+               edid->feature_support & EDID_VIDEO_INPUT_STANDBY_MASK ? "S" : "Uns");
+        printf("\t        Suspend: %supported\n",
+               edid->feature_support & EDID_VIDEO_INPUT_SUSPEND_MASK ? "S" : "Uns");
+        printf("\t     Active Off: %supported\n",
+               edid->feature_support & EDID_VIDEO_INPUT_ACTIVE_OFF_MASK ? "S" : "Uns");
+        printf("\t     Color Type: %s\n", cnc_edid_display_color_type_to_ascii(edid));
+        printf("\t       sRGB Std: is %sthe default color space\n", (edid->feature_support & EDID_VIDEO_INPUT_SRGB_MASK) ? "" : "not ");
+        printf("\t Preferred Mode: %s the native pixel format and preferred refresh rate\n", (edid->feature_support & EDID_VIDEO_INPUT_PREFERRED_MASK) ? "includes" : "does not include");
+        printf("\t Continous Freq: Display is %scontinuous frequency %s\n", (edid->feature_support & EDID_VIDEO_INPUT_CONTINUOUS_MASK) ? "" : "non-", (edid->feature_support & EDID_VIDEO_INPUT_CONTINUOUS_MASK) ? "" : "(multi-mode)");
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_chromaticity(cnc_edid_t *edid) {
+    if(edid->edid_valid & EDID_VALID_CHROMATICITY) {
+        printf("\t Chromaticity R: x 0.%03d, y 0.%03d\n",
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Rx_INDEX]),
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Ry_INDEX]));
+        printf("\t              G: x 0.%03d, y 0.%03d\n",
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Gx_INDEX]),
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Gy_INDEX]));
+        printf("\t              B: x 0.%03d, y 0.%03d\n",
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Bx_INDEX]),
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_By_INDEX]));
+        printf("\t              W: x 0.%03d, y 0.%03d\n",
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Wx_INDEX]),
+               cnc_edid_chromaticity_fract(edid->chromaticity[EDID_CHROMATICITY_Wy_INDEX]));
+    }
+    return EDID_SUCCESS;
+}
+
+void cnc_edid_print_timing(cnc_edid_timing_t *timing, char *prefix) {
+    printf("%s %4dx%d%c @ %dHz\n", prefix,
+           timing->h_active,
+           timing->v_active,
+           (timing->timing_flags & EDID_DTD_FLAGS_INTERLACED) ? 'i' : 'p',
+           timing->v_frequency);
+}
+
+int cnc_edid_print_established_timings(cnc_edid_t *edid) {
+    char *prefix_on ="\t    Est Timings: ";
+    char *prefix_off="\t               : ";
+    char *prefix=prefix_on;
+    int i;
+    if(!(edid->edid_valid & EDID_VALID_EST_TIMINGS)) {
+        return EDID_ERROR;
+    }
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if((edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) &&
+                (edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_LOCATION_EST)) {
+            cnc_edid_print_timing(&(edid->timings[i]), prefix);
+            prefix = prefix_off;
+        }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_standard_timings(cnc_edid_t *edid) {
+    char *prefix_on ="\t    Std Timings: ";
+    char *prefix_off="\t               : ";
+    char *prefix=prefix_on;
+    int i;
+    if(!(edid->edid_valid & EDID_VALID_STD_TIMINGS)) {
+        return EDID_ERROR;
+    }
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if((edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID) &&
+                (edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_LOCATION_STD)) {
+            cnc_edid_print_timing(&(edid->timings[i]), prefix);
+            prefix = prefix_off;
+        }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_display_desc_string(char *stored_str) {
+    char print_str[EDID_DISPLAY_DESC_STRING_STORAGE_SIZE];
+    //char *newline;
+    strncpy(print_str, stored_str, EDID_DISPLAY_DESC_STRING_LENGTH);
+    // supposed to be terminated by a newline and padded with spaces
+    // check anyway and remove the spaces
+#if 0
+	newline = index(print_str, '\n');
+    if(newline == -1) {
+        print_str[EDID_DISPLAY_DESC_STRING_LENGTH] = '\0';
+    }
+    else {
+        *newline = '\0';
+    }
+#endif
+    printf("%s\n", print_str);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_display_serial_number(cnc_edid_t *edid) {
+    if(!(edid->edid_valid & EDID_VALID_DISPLAY_SERIAL_NUMBER)) {
+        return EDID_ERROR;
+    }
+    printf("\t  Serial Number: ");
+    return cnc_edid_print_display_desc_string(edid->display_serial_number);
+}
+
+int cnc_edid_print_display_data_string(cnc_edid_t *edid) {
+    if(!(edid->edid_valid & EDID_VALID_DISPLAY_DATA_STR)) {
+        return EDID_ERROR;
+    }
+    printf("\t    Data String: ");
+    return cnc_edid_print_display_desc_string(edid->display_data_string);
+}
+
+int cnc_edid_print_display_product_name(cnc_edid_t *edid) {
+    if(!(edid->edid_valid & EDID_VALID_DISPLAY_PRODUCT_NAME)) {
+        return EDID_ERROR;
+    }
+    printf("\t   Product Name: ");
+    return cnc_edid_print_display_desc_string(edid->display_product_name);
+}
+
+int cnc_edid_print_display_range_limits(cnc_edid_t *edid) {
+    if(!(edid->edid_valid & EDID_VALID_DISPLAY_RANGE_LIMITS)) {
+        return EDID_ERROR;
+    }
+    printf("\t Disp Range Lim: V min %2d Hz,  max %3d Hz\n",
+           edid->rate_v_min, edid->rate_v_max);
+    printf("\t               : H min %2d kHz, max %3d kHz\n",
+           edid->rate_h_min, edid->rate_h_max);
+    printf("\t               : pixel clock   max %3d MHz\n", edid->rate_pixel_clock_max);
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_audio_formats(cnc_edid_t *edid) {
+    char *freq_strs[EDID_AUDIO_FREQ_STRS_STORAGE_SIZE] = EDID_AUDIO_FREQUENCY_STRS_INITIALIZER;
+    char *format_strs[EDID_AUDIO_FORMAT_STRS_STORAGE_SIZE] = EDID_AUDIO_FORMAT_STRS_INITIALIZER;
+    cnc_edid_audio_t *audio_fmt;
+    int i, f, need_comma, need_hdr=1;
+    if(!(edid->edid_valid & EDID_VALID_AUDIO_FORMATS)) {
+        return EDID_ERROR;
+    }
+    for(i=0; i<EDID_AUDIO_STORAGE_SIZE; i++) {
+        audio_fmt = &(edid->audio_formats[i]);
+        if(audio_fmt->format == EDID_AUDIO_FORMAT_RESERVED) {
+            continue;
+        }
+        printf("\t  %s: %d channels of %s at\n", need_hdr?"Audio Formats":"             ", audio_fmt->max_channels, format_strs[audio_fmt->format]);
+        need_hdr = 0;
+        printf("\t               :     ");
+        if(audio_fmt->frequencies == 0) {
+            printf("Refer to data for frequency range\n");
+        }
+        else {
+            need_comma = 0;
+            for(f=0; f<EDID_AUDIO_FREQ_STRS_STORAGE_SIZE; f++) {
+                if(audio_fmt->frequencies & (1<<f)) {
+                    printf("%s%s", need_comma?", ":"", freq_strs[f]);
+                    need_comma = 1;
+                }
+            }
+            printf(" kHz\n");
+        }
+        if(audio_fmt->format == EDID_AUDIO_FORMAT_LPCM) {
+            printf("\t               :     ");
+            if(audio_fmt->extra_data & EDID_AUDIO_FORMAT_LPCM_16_BIT_MASK) {
+                printf("16");
+                need_comma = 1;
+            }
+            else {
+                need_comma = 0;
+            }
+            if(audio_fmt->extra_data & EDID_AUDIO_FORMAT_LPCM_20_BIT_MASK) {
+                printf("%s20", need_comma?", ":"");
+                need_comma = 1;
+            }
+            if(audio_fmt->extra_data & EDID_AUDIO_FORMAT_LPCM_24_BIT_MASK) {
+                printf("%s24", need_comma?", ":"");
+            }
+            printf(" bits/sample\n");
+        }
+        //printf("\t   Audio Format: %s\n", format_strs[audio_fmt->format]);
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_video_capability(cnc_edid_t *edid) {
+    char *vidcap_strs[EDID_VIDCAP_STRINGS_STORAGE_SIZE] = EDID_VIDCAP_STRS_INITIALIZER;
+    if(!(edid->edid_valid & EDID_VALID_VIDEO_CAPABILITY)) {
+        return EDID_ERROR;
+    }
+    printf("\tVideoCapability: CE Formats: %s\n", vidcap_strs[edid->video_capability & EDID_VIDCAP_S_CE_MASK]);
+    printf("\t               : IT Formats: %s\n", vidcap_strs[(edid->video_capability & EDID_VIDCAP_S_IT_MASK)>>EDID_VIDCAP_S_IT_SHIFT]);
+    if(edid->video_capability & EDID_VIDCAP_S_PT_MASK) {
+        printf("\t               : Preferred Format: %s\n", vidcap_strs[(edid->video_capability & EDID_VIDCAP_S_PT_MASK)>>EDID_VIDCAP_S_PT_SHIFT]);
+    }
+    if(edid->video_capability & EDID_VIDCAP_QS_MASK) {
+        printf("\t               : RGB Quant Range is Selectable via AVI Q\n");
+    }
+    if(edid->video_capability & EDID_VIDCAP_QY_MASK) {
+        printf("\t               : YCC Quant Range is Selectable via AVI YQ\n");
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_vendor_specific(cnc_edid_t *edid) {
+    int i;
+    if(!(edid->edid_valid & EDID_VALID_VENDOR_SPECIFIC)) {
+        return EDID_ERROR;
+    }
+    printf("\tVendor Specific: ");
+    for(i=0; i<edid->vendor_specific_length; i++) {
+        printf("%02x ", edid->vendor_specific[i]);
+    }
+    printf("\n");
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_colorimetry(cnc_edid_t *edid) {
+    int i, need_hdr=1;
+    char *colorimetry_strs[EDID_COLORIMETRY_STRS_STORAGE_SIZE] = EDID_COLORIMETRY_STRS_INITIALIZER;
+    if(!(edid->edid_valid & EDID_VALID_COLORIMETRY)) {
+        return EDID_ERROR;
+    }
+    for(i=0; i<EDID_COLORIMETRY_STRS_STORAGE_SIZE-1; i++)
+        if(edid->colorimetry & (1<<i)) {
+            printf("\t    %s: %s\n", need_hdr?"Colorimetry":"           ", colorimetry_strs[i]);
+            need_hdr = 0;
+        }
+    if(edid->colorimetry & EDID_COLORIMETRY_BYTE2_MASK) {
+        printf("\t    %s: %s\n", need_hdr?"Colorimetry":"           ", colorimetry_strs[i]);
+    }
+    return EDID_SUCCESS;
+}
+
+int cnc_edid_print_speaker_alloc(cnc_edid_t *edid) {
+    char *speaker_strs[EDID_SPEAKER_STRS_STORAGE_SIZE] = EDID_SPEAKER_STRS_INITIALIZER;
+    int i, need_hdr=1;
+    if(!(edid->edid_valid & EDID_VALID_SPEAKER_ALLOC)) {
+        return EDID_ERROR;
+    }
+    for(i=0; i<EDID_SPEAKER_STRS_STORAGE_SIZE; i++) {
+        if(edid->speaker_alloc & (1<<i)) {
+            printf("\t       %s: %s\n", need_hdr?"Speakers":"        ", speaker_strs[i]);
+            need_hdr=0;
+        }
+    }
+    return EDID_SUCCESS;
+}
+
+/*
+    edid->eedid_audio =
+    block[EDID_EXT_BLOCK_FLAGS_OFFSET] & EDID_EXT_BLOCK_FLAGS_AUDIO_MASK;
+    edid->eedid_YCbCr444 =
+    block[EDID_EXT_BLOCK_FLAGS_OFFSET] & EDID_EXT_BLOCK_FLAGS_YCbCr_444_MASK;
+    edid->eedid_YCbCr422 =
+    block[EDID_EXT_BLOCK_FLAGS_OFFSET] & EDID_EXT_BLOCK_FLAGS_YCbCr_422_MASK;
+    edid->eedid_num_dtds =
+    block[EDID_EXT_BLOCK_FLAGS_OFFSET] & EDID_EXT_BLOCK_FLAGS_DTD_COUNT_MASK;
+*/
+
+// debug function
+void cnc_edid_print_timings(cnc_edid_t *edid) {
+    int i;
+    printf("\n");
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if(edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID)
+#if 1
+            printf("%2d: %4d x %4d %c %dhz%c(%s) %d %d\n", i,
+                   edid->timings[i].h_active,
+                   edid->timings[i].v_active,
+                   (edid->timings[i].timing_flags & EDID_DTD_FLAGS_INTERLACED)? 'i' : 'p',
+                   (edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_V_FREQ_VALID) ?
+                   edid->timings[i].v_frequency : edid->timings[i].pixel_clock,
+                   (edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_PREFERRED)?'*':' ',
+                   cnc_edid_timing_iflags_location_to_ascii(&(edid->timings[i])),
+                   edid->timings[i].ar_numerator,
+                   edid->timings[i].ar_denominator
+                  );
+#else
+            printf("T %4d x %4d %c %dhz\n",
+                   edid->timings[i].h_active,
+                   edid->timings[i].v_active,
+                   (edid->timings[i].timing_flags & EDID_DTD_FLAGS_INTERLACED)? 'i' : 'p',
+                   (edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_V_FREQ_VALID) ?
+                   edid->timings[i].v_frequency : edid->timings[i].pixel_clock);
+#endif
+    printf("\n");
+}
+
+int cnc_edid_print(cnc_edid_t *edid) {
+    printf("\n");
+    cnc_edid_print_vendor_product_id(edid);
+    cnc_edid_print_version(edid);
+    cnc_edid_print_display_params(edid);
+    cnc_edid_print_chromaticity(edid);
+    cnc_edid_print_established_timings(edid);
+    cnc_edid_print_standard_timings(edid);
+    cnc_edid_print_display_serial_number(edid);
+    cnc_edid_print_display_data_string(edid);
+    cnc_edid_print_display_product_name(edid);
+    cnc_edid_print_display_range_limits(edid);
+    cnc_edid_print_audio_formats(edid);
+    cnc_edid_print_speaker_alloc(edid);
+    cnc_edid_print_video_capability(edid);
+    cnc_edid_print_vendor_specific(edid);
+    cnc_edid_print_colorimetry(edid);
+    cnc_edid_print_timings(edid);
+    return EDID_SUCCESS;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_util.c u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_util.c
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_edid_util.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_edid_util.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2003-2011, Cavium Networks. All rights reserved.
+ *
+ * This Software is the property of Cavium Networks.  The Software and all
+ * accompanying documentation are copyrighted.  The Software made available
+ * here constitutes the proprietary information of Cavium Networks.  You
+ * agree to take reasonable steps to prevent the disclosure, unauthorized use
+ * or unauthorized distribution of the Software.  You shall use this Software
+ * solely with Cavium hardware.
+ *
+ * Except as expressly permitted in a separate Software License Agreement
+ * between You and Cavium Networks, you shall not modify, decompile,
+ * disassemble, extract, or otherwise reverse engineer this Software.  You
+ * shall not make any copy of the Software or its accompanying documentation,
+ * except for copying incident to the ordinary and intended use of the
+ * Software and the Underlying Program and except for the making of a single
+ * archival copy.
+ *
+ * This Software, including technical data, may be subject to U.S.  export
+ * control laws, including the U.S.  Export Administration Act and its
+ * associated regulations, and may be subject to export or import regulations
+ * in other countries.  You warrant that You will comply strictly in all
+ * respects with all such regulations and acknowledge that you have the
+ * responsibility to obtain licenses to export, re-export or import the
+ * Software.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
+ * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
+ * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
+ * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
+ * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
+ * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
+ * POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ *
+ */
+
+#include "common.h"
+#include "cnc_edid.h"
+
+void cnc_edid_set_id_string(cnc_edid_t *edid, char *edid_id_string) {
+    strncpy(edid->id_string, edid_id_string, EDID_ID_STRING_LENGTH);
+    if(strlen(edid_id_string) >= EDID_ID_STRING_LENGTH) {
+        edid->id_string[EDID_ID_STRING_LENGTH-1] = '\0';
+    }
+}
+#if 0
+int cnc_edid_read_hex(cnc_edid_t *edid) {
+    int i=0, tmp;
+    while(scanf("%x ", &tmp) == 1) {
+        edid->edid_bin[i++] = tmp & 0xff;
+        if(i >= EDID_MAX_BIN_LENGTH) {
+            printf("%s: edid length limited to %d bytes\n", __FUNCTION__, EDID_MAX_BIN_LENGTH);
+            return EDID_ERROR;
+        }
+    }
+    edid->edid_bin_valid = EDID_BIN_VALID;
+    edid->edid_bin_length = i;
+#ifdef EDID_DEBUG
+    printf("%s: read %d bytes\n", __FUNCTION__, i);
+#endif
+    return EDID_SUCCESS;
+}
+#endif
+char *cnc_edid_color_bit_depth_ascii(cnc_edid_t *edid) {
+    switch(edid->color_bit_depth) {
+    case 0:
+        return "Undefined";
+    case 1:
+        return "6 bits per primary color";
+    case 2:
+        return "8 bits per primary color";
+    case 3:
+        return "10 bits per primary color";
+    case 4:
+        return "12 bits per primary color";
+    case 5:
+        return "14 bits per primary color";
+    case 6:
+        return "16 bits per primary color";
+    case 7:
+        return "Reserved (should not be used)";
+    default:
+        return "WARNING: color_bit_depth variable corrupt";
+    }
+}
+
+int cnc_edid_int_to_color_bit_depth(int color_bit_depth) {
+    switch(color_bit_depth) {
+    case 0:
+        return 0;
+    case 6:
+        return 1;
+    case 8:
+        return 2;
+    case 10:
+        return 3;
+    case 12:
+        return 4;
+    case 14:
+        return 5;
+    case 16:
+        return 6;
+    default:
+        printf("%s: WARNING: color_bit_depth value out of range\n", __FUNCTION__);
+    }
+    return EDID_ERROR;
+}
+
+char *cnc_edid_interface_std_ascii(cnc_edid_t *edid) {
+    switch(edid->interface_std) {
+    case 0:
+        return "Digital Interface Std is not defined";
+    case 1:
+        return "DVI is supported";
+    case 2:
+        return "HDMI-a is supported";
+    case 3:
+        return "HDMI-b is supported";
+    case 4:
+        return "HDMI-c is supported";
+    case 5:
+        return "Display Port is supported";
+    default:
+        return "Reserved (should not be used)";
+    }
+}
+
+// even though I didn't save the code that used this in cnc_edid_filter.c
+#ifdef EDID_FLOATING_POINT_AVAILABLE
+float cnc_edid_gamma_to_f(cnc_edid_t *edid) {
+    return (edid->gamma+100.0)/100.0;
+}
+
+int cnc_edid_gamme_from_f(float gamma) {
+    if(gamma < 1.0 || gamma > 3.54) {
+        return EDID_ERROR;
+    }
+    return (int)(gamma * 100) - 100;
+}
+#else
+int cnc_edid_gamma_int(cnc_edid_t *edid) {
+    return (edid->gamma + 100) / 100;
+}
+int cnc_edid_gamma_fract(cnc_edid_t *edid) {
+    return (edid->gamma + 100) % 100;
+}
+#endif
+
+
+char *cnc_edid_display_color_type_to_ascii(cnc_edid_t *edid) {
+    int color_type;
+    color_type = (edid->feature_support & EDID_VIDEO_INPUT_COLOR_TYPE_MASK);
+    color_type >>= EDID_VIDEO_INPUT_COLOR_TYPE_SHIFT;
+    if(edid->signal_interface == EDID_VIDEO_INPUT_DEF_SIGNAL_INT_ANALOG) {
+        switch(color_type) {
+        case 0:
+            return "Monochrome or Grayscale display";
+        case 1:
+            return "RGB display";
+        case 2:
+            return "Non-RGB display";
+        case 3:
+            return "Display Color Type is Undefined";
+        }
+    }
+    else {
+        switch(color_type) {
+        case 0:
+            return "RGB 4:4:4";
+        case 1:
+            return "RGB 4:4:4 & YCbCr 4:4:4";
+        case 2:
+            return "RGB 4:4:4 & YCbCr 4:2:2";
+        case 3:
+            return "RGB 4:4:4 & YCbCr 4:4:4 & YCbCr 4:2:2";
+        }
+    }
+    return "bug in cnc_edid_display_color_type_to_ascii()";
+}
+
+// even though I didn't save the code that used this in cnc_edid_filter.c
+#ifdef EDID_FLOATING_POINT_AVAILABLE
+float cnc_edid_chromaticity_to_f(int chromaticity_val) {
+    return chromaticity_val/1024.0;
+}
+
+int cnc_edid_chromaticity_from_f(float chromaticity_val) {
+    return (int)(chromaticity_val * 1024);
+}
+#else
+int cnc_edid_chromaticity_fract(int chromaticity_val) {
+    return (chromaticity_val * 1000) / 1024;
+}
+#endif
+
+//    cnc_edid_timing_t *timing = cnc_edid_get_free_timing_struct(edid);
+cnc_edid_timing_t *cnc_edid_get_free_timing_struct(cnc_edid_t *edid) {
+    int i;
+    for(i=0; i<EDID_TIMINGS_STORAGE_SIZE; i++)
+        if(!(edid->timings[i].internal_flags & EDID_TIMING_IFLAGS_ENTRY_VALID)) {
+            //printf("%s: %d\n", __FUNCTION__, i);
+            return &(edid->timings[i]);
+        }
+    printf("%s: failed to allocate a timing struct\n", __FUNCTION__);
+    return NULL;
+}
+
+//    cnc_edid_audio_t *audio_fmt = cnc_edid_get_free_audio_struct(edid);
+cnc_edid_audio_t *cnc_edid_get_free_audio_struct(cnc_edid_t *edid) {
+    int i;
+    for(i=0; i<EDID_AUDIO_STORAGE_SIZE; i++)
+        if(edid->audio_formats[i].format == EDID_AUDIO_FORMAT_RESERVED) {
+            //printf("%s: %d\n", __FUNCTION__, i);
+            return &(edid->audio_formats[i]);
+        }
+    printf("%s: failed to allocate an audio struct\n", __FUNCTION__);
+    return NULL;
+}
+
+char *cnc_edid_timing_iflags_location_to_ascii(cnc_edid_timing_t *timing) {
+    int loc = timing->internal_flags & EDID_TIMING_IFLAGS_LOCATION_MASK;
+    switch(loc) {
+    case 0x01:
+        return "EST";
+    case 0x02:
+        return "STD";
+    case 0x04:
+        return "EDID DTD";
+    case 0x08:
+        return "EXT SVD";
+    case 0x10:
+        return "EXT DTD";
+    case 0x20:
+        return "EDID 18B STD";
+    default:
+        printf("%s: WARNING! location field not understood or corrupt (0x%x)\n", __FUNCTION__, loc);
+        return "???";
+    }
+}
+
+/* CEA 861 Table 4 Video FormatsVideo ID Code and Aspect Ratios
+VIC Resolution     V Rate       AR   Pixel AR
+1   640x480p       59.94Hz/60Hz 4:3  1:1
+2   720x480p       59.94Hz/60Hz 4:3  8:9
+3   720x480p       59.94Hz/60Hz 16:9 32:27
+4   1280x720p      59.94Hz/60Hz 16:9 1:1
+5   1920x1080i     59.94Hz/60Hz 16:9 1:1
+6   720(1440)x480i 59.94Hz/60Hz 4:3  8:9
+7   720(1440)x480i 59.94Hz/60Hz 16:9 32:27
+8   720(1440)x240p 59.94Hz/60Hz 4:3  4:9
+9   720(1440)x240p 59.94Hz/60Hz 16:9 16:27
+10  2880x480i      59.94Hz/60Hz 4:3  2:9  20:92
+11  2880x480i      59.94Hz/60Hz 16:9 8:27 -80:272
+12  2880x240p      59.94Hz/60Hz 4:3  1:9  10:92
+13  2880x240p      59.94Hz/60Hz 16:9 4:27  40:272
+14  1440x480p      59.94Hz/60Hz 4:3  4:9 or 8:93
+15  1440x480p      59.94Hz/60Hz 16:9 16:27 or 32:273
+16  1920x1080p     59.94Hz/60Hz 16:9 1:1
+17  720x576p       50Hz         4:3  16:15
+18  720x576p       50Hz         16:9 64:45
+19  1280x720p      50Hz         16:9 1:1
+20  1920x1080i     50Hz         16:9 1:1
+21  720(1440)x576i 50Hz         4:3  16:15
+22  720(1440)x576i 50Hz         16:9 64:45
+23  720(1440)x288p 50Hz         4:3  8:15
+24  720(1440)x288p 50Hz         16:9 32:45
+25  2880x576i      50Hz         4:3  2:15  20:152
+26  2880x576i      50Hz         16:9 16:45-160:452
+27  2880x288p      50Hz         4:3  1:15  10:152
+28  2880x288p      50Hz         16:9 8:45  80:452
+29  1440x576p      50Hz         4:3  8:15 or 16:153
+30  1440x576p      50Hz         16:9 32:45 or 64:453
+31  1920x1080p     50Hz         16:9 1:1
+32  1920x1080p     23.97Hz/24Hz 16:9 1:1
+33  1920x1080p     25Hz         16:9 1:1
+34  1920x1080p     29.97Hz/30Hz 16:9 1:1
+35  2880x480p      59.94Hz/60Hz 4:3  2:9, 4:9, or 8:94
+36  2880x480p      59.94Hz/60Hz 16:9 8:27, 16:27, or 32:274
+37  2880x576p      50Hz         4:3  4:15, 8:15, or 16:154
+38  2880x576p      50Hz         16:9 16:45, 32:45, or 64:454
+39  1920x1080i     50Hz         16:9 1:1
+40  1920x1080i     100Hz        16:9 1:1
+41  1280x720p      100Hz        16:9 1:1
+42  720x576p       100Hz        4:3  16:15
+43  720x576p       100Hz        16:9 64:45
+44  720(1440)x576i 100Hz        4:3  16:15
+45  720(1440)x576i 100Hz        16:9 64:45
+46  1920x1080i     119.88/120Hz 16:9 1:1
+47  1280x720p      119.88/120Hz 16:9 1:1
+48  720x480p       119.88/120Hz 4:3  8:9
+49  720x480p       119.88/120Hz 16:9 32:27
+50  720(1440)x480i 119.88/120Hz 4:3  8:9
+51  720(1440)x480i 119.88/120Hz 16:9 32:27
+52  720x576p       200Hz        4:3  16:15
+53  720x576p       200Hz        16:9 64:45
+54  720(1440)x576i 200Hz        4:3  16:15
+55  720(1440)x576i 200Hz        16:9 64:45
+56  720x480p       239.76/240Hz 4:3  8:9
+57  720x480p       239.76/240Hz 16:9 32:27
+58  720(1440)x480i 239.76/240Hz 4:3  8:9
+59  720(1440)x480i 239.76/240Hz 16:9 32:27
+60  1280x720p      23.97Hz/24Hz 16:9 1:1
+61  1280x720p      25Hz         16:9 1:1
+62  1280x720p      29.97Hz/30Hz 16:9 1:1
+63  1920x1080p     119.88/120Hz 16:9 1:1
+64  1920x1080p     100Hz        16:9 1:1
+*/
+
+
+static cnc_edid_vic_struct_t edid_vic[EDID_MAX_VIC+1]= {
+    { 0,   0,0,'p',            0,  0, 0, 0},
+    { 1,   640,480,'p',       60,  4, 3, 0},
+    { 2,   720,480,'p',       60,  4, 3, 0},
+    { 3,   720,480,'p',       60, 16, 9, 0},
+    { 4,   1280,720,'p',      60, 16, 9, 0},
+    { 5,   1920,1080,'i',     60, 16, 9, 0},
+    { 6,   720,480,'i',       60,  4, 3, 1},
+    { 7,   720,480,'i',       60, 16, 9, 1},
+    { 8,   720,240,'p',       60,  4, 3, 1},
+    { 9,   720,240,'p',       60, 16, 9, 1},
+    {10,  2880,480,'i',       60,  4, 3, 0},
+    {11,  2880,480,'i',       60, 16, 9, 0},
+    {12,  2880,240,'p',       60,  4, 3, 0},
+    {13,  2880,240,'p',       60, 16, 9, 0},
+    {14,  1440,480,'p',       60,  4, 3, 0},
+    {15,  1440,480,'p',       60, 16, 9, 0},
+    {16,  1920,1080,'p',      60, 16, 9, 0},
+    {17,  720,576,'p',        50,  4, 3, 0},
+    {18,  720,576,'p',        50, 16, 9, 0},
+    {19,  1280,720,'p',       50, 16, 9, 0},
+    {20,  1920,1080,'i',      50, 16, 9, 0},
+    {21,  720,576,'i',        50,  4, 3, 1},
+    {22,  720,576,'i',        50, 16, 9, 1},
+    {23,  720,288,'p',        50,  4, 3, 1},
+    {24,  720,288,'p',        50, 16, 9, 1},
+    {25,  2880,576,'i',       50,  4, 3, 0},
+    {26,  2880,576,'i',       50, 16, 9, 0},
+    {27,  2880,288,'p',       50,  4, 3, 0},
+    {28,  2880,288,'p',       50, 16, 9, 0},
+    {29,  1440,576,'p',       50,  4, 3, 0},
+    {30,  1440,576,'p',       50, 16, 9, 0},
+    {31,  1920,1080,'p',      50, 16, 9, 0},
+    {32,  1920,1080,'p',      24, 16, 9, 0},
+    {33,  1920,1080,'p',      25, 16, 9, 0},
+    {34,  1920,1080,'p',      30, 16, 9, 0},
+    {35,  2880,480,'p',       60,  4, 3, 0},
+    {36,  2880,480,'p',       60, 16, 9, 0},
+    {37,  2880,576,'p',       50,  4, 3, 0},
+    {38,  2880,576,'p',       50, 16, 9, 0},
+    {39,  1920,1080,'i',      50, 16, 9, 0},
+    {40,  1920,1080,'i',     100, 16, 9, 0},
+    {41,  1280,720,'p',      100, 16, 9, 0},
+    {42,  720,576,'p',       100,  4, 3, 0},
+    {43,  720,576,'p',       100, 16, 9, 0},
+    {44,  720,576,'i',       100,  4, 3, 1},
+    {45,  720,576,'i',       100, 16, 9, 1},
+    {46,  1920,1080,'i',     120, 16, 9, 0},
+    {47,  1280,720,'p',      120, 16, 9, 0},
+    {48,  720,480,'p',       120,  4, 3, 0},
+    {49,  720,480,'p',       120, 16, 9, 0},
+    {50,  720,480,'i',       120,  4, 3, 1},
+    {51,  720,480,'i',       120, 16, 9, 1},
+    {52,  720,576,'p',       200,  4, 3, 0},
+    {53,  720,576,'p',       200, 16, 9, 0},
+    {54,  720,576,'i',       200,  4, 3, 1},
+    {55,  720,576,'i',       200, 16, 9, 1},
+    {56,  720,480,'p',       240,  4, 3, 0},
+    {57,  720,480,'p',       240, 16, 9, 0},
+    {58,  720,480,'i',       240,  4, 3, 1},
+    {59,  720,480,'i',       240, 16, 9, 1},
+    {60,  1280,720,'p',       24, 16, 9, 0},
+    {61,  1280,720,'p',       25, 16, 9, 0},
+    {62,  1280,720,'p',       30, 16, 9, 0},
+    {63,  1920,1080,'p',     120, 16, 9, 0},
+    {64,  1920,1080,'p',     100, 16, 9, 0}
+};
+
+int cnc_edid_vic_to_edid_timing(cnc_edid_timing_t *timing, int vic) {
+    if(vic == 0) { // have seen this; LGFlatron EDID; ignore silently
+        return EDID_SUCCESS;
+    }
+    if(vic < EDID_MIN_VIC || vic > EDID_MAX_VIC) {
+        printf("%s: WARNING, VIC out of range (%d)\n", __FUNCTION__, vic);
+        return EDID_ERROR;
+    }
+    if(edid_vic[vic].vic != vic) {
+        printf("%s: WARNING, problem with VIC table\n", __FUNCTION__);
+        return EDID_ERROR;
+    }
+    timing->vic            = vic;
+    timing->h_active       = edid_vic[vic].h_active;
+    timing->v_active       = edid_vic[vic].v_active;
+    if(edid_vic[vic].interlaced == 'i') {
+        timing->timing_flags |= EDID_DTD_FLAGS_INTERLACED;
+    }
+    timing->v_frequency    = edid_vic[vic].v_frequency;
+    timing->ar_numerator   = edid_vic[vic].ar_numerator;
+    timing->ar_denominator = edid_vic[vic].ar_denominator;
+    if(edid_vic[vic].pixel_doubled) {
+        timing->internal_flags |= EDID_TIMING_IFLAGS_PIXEL_DOUBLED;
+    }
+    timing->internal_flags |=
+        (EDID_TIMING_IFLAGS_LOCATION_SVD |
+         EDID_TIMING_IFLAGS_AR_VALID |
+         EDID_TIMING_IFLAGS_V_FREQ_VALID |
+         EDID_TIMING_IFLAGS_VIC_VALID |
+         EDID_TIMING_IFLAGS_ENTRY_VALID);
+    return EDID_SUCCESS;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_sample_edid.h u-boot-2011.06/drivers/cnc1900/cncedid/cnc_sample_edid.h
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/cnc_sample_edid.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/cnc_sample_edid.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,27 @@
+/*
+ * sample_edid.h
+ */
+
+#ifndef _SAMPLE_EDID_H_
+#define _SAMPLE_EDID_H_
+
+static unsigned char cnc_sample_edid[256] = {
+ 0x00 ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0x00 ,0x4c ,0x2d ,0x80 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 
+,0x18 ,0x0f ,0x01 ,0x03 ,0x80 ,0x59 ,0x32 ,0x8c ,0x0a ,0xe2 ,0xbd ,0xa1 ,0x5b ,0x4a ,0x98 ,0x24 
+,0x15 ,0x47 ,0x4a ,0x20 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 
+,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x1d ,0x00 ,0x72 ,0x51 ,0xd0 ,0x1e ,0x20 ,0x6e ,0x28 
+,0x55 ,0x00 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 ,0x1e ,0x01 ,0x1d ,0x00 ,0xbc ,0x52 ,0xd0 ,0x1e ,0x20 
+,0xb8 ,0x28 ,0x55 ,0x40 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 ,0x1e ,0x00 ,0x00 ,0x00 ,0xfd ,0x00 ,0x32 
+,0x3d ,0x0f ,0x2e ,0x08 ,0x00 ,0x0a ,0x20 ,0x20 ,0x20 ,0x20 ,0x20 ,0x20 ,0x00 ,0x00 ,0x00 ,0xfc 
+,0x00 ,0x53 ,0x41 ,0x4d ,0x53 ,0x55 ,0x4e ,0x47 ,0x0a ,0x20 ,0x20 ,0x20 ,0x20 ,0x20 ,0x01 ,0x94
+,0x02 ,0x03 ,0x19 ,0x71 ,0x46 ,0x84 ,0x13 ,0x05 ,0x14 ,0x03 ,0x12 ,0x23 ,0x09 ,0x07 ,0x07 ,0x83 
+,0x01 ,0x00 ,0x00 ,0x65 ,0x03 ,0x0c ,0x00 ,0x10 ,0x00 ,0x01 ,0x1d ,0x80 ,0x18 ,0x71 ,0x1c ,0x16 
+,0x20 ,0x58 ,0x2c ,0x25 ,0x00 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 ,0x9e ,0x01 ,0x1d ,0x80 ,0xd0 ,0x72 
+,0x1c ,0x16 ,0x20 ,0x10 ,0x2c ,0x25 ,0x80 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 ,0x9e ,0x8c ,0x0a ,0xd0 
+,0x8a ,0x20 ,0xe0 ,0x2d ,0x10 ,0x10 ,0x3e ,0x96 ,0x00 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 ,0x18 ,0x8c 
+,0x0a ,0xd0 ,0x90 ,0x20 ,0x40 ,0x31 ,0x20 ,0x0c ,0x40 ,0x55 ,0x00 ,0x75 ,0xf2 ,0x31 ,0x00 ,0x00 
+,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
+,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xca 
+};
+
+#endif /* _SAMPLE_EDID_H_ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/cncedid/Makefile u-boot-2011.06/drivers/cnc1900/cncedid/Makefile
--- u-boot-2011.06_original/drivers/cnc1900/cncedid/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/cncedid/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,21 @@
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libedid.o
+
+COBJS-$(CONFIG_CNC1900_DF) += cnc_edid_ops.o cnc_edid_parse.o cnc_edid_assemble.o cnc_edid_print.o cnc_edid_util.o      
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+all:	$(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS) $(HDMIOBJ))
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/crypto/cmd_crypto.c u-boot-2011.06/drivers/cnc1900/crypto/cmd_crypto.c
--- u-boot-2011.06_original/drivers/cnc1900/crypto/cmd_crypto.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/crypto/cmd_crypto.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,29 @@
+#include <command.h>
+#include <command.h>
+
+extern int do_call_external_proc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
+
+extern int printf(const char* fmt, ...);
+
+int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+    int i;
+    char *dvu_argv[9]={0};
+
+    if (argc > 7)
+    {
+        printf("Too many arguments for DVU.\n");
+        return -1;
+    }
+
+    dvu_argv[0]="call_external_proc";
+    dvu_argv[1]="DVU_";
+
+    for (i=0; i<argc; i++)
+    {
+        dvu_argv[i+2] = argv[i];
+    }
+
+    return do_call_external_proc(NULL, 0, argc+2, dvu_argv);
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/crypto/crypto_drv.c u-boot-2011.06/drivers/cnc1900/crypto/crypto_drv.c
--- u-boot-2011.06_original/drivers/cnc1900/crypto/crypto_drv.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/crypto/crypto_drv.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,947 @@
+/**
+ * @file   crypto_drv.c
+ * @author Fan Xiaodong <xiaodong.fan@caviumnetworks.com>
+ * @date   Nov 2011
+ * 
+ * @brief  Secrity driver on U-boot
+ * 
+ * 
+ */
+
+#include <common.h>
+#include "sec_define.h"
+#include "crypto_drv.h"
+
+
+extern SEC_CHANNEL_INFO channel_info[CRYPTO_CHANNEL_MAX_NUM];
+
+
+//#define DEBUG_PRINTF    printf
+#define DEBUG_PRINTF(fmt, args...)
+
+#define TIMEOUT_MAX 200000
+#define CHECK_WITH_TMO(condition) ({            \
+            int timeout = 0;                    \
+            while (condition) {                 \
+                if (timeout++ > TIMEOUT_MAX)    \
+                    return SEC_CORE_ERROR;      \
+                else                            \
+                    udelay(1);                  \
+            }                                   \
+        })
+
+#define SEC_ASSERT(x)   {                                           \
+        SEC_ERROR_CODE code;                                        \
+        code = (x);                                                 \
+        if (code != SEC_CORE_SUCCESS)                               \
+            {                                                       \
+                printf("--func:%s line:%d error:%d --  \n", \
+                       __FUNCTION__,__LINE__,code);                 \
+                return code;                                        \
+            }                                                       \
+    }
+
+SEC_CHANNEL_INFO channel_info[CRYPTO_CHANNEL_MAX_NUM];
+
+void CHL_Dump_Regs(unsigned int chl)
+{	unsigned int addr;
+	unsigned int val;
+
+    printf("Interrupt: \n");
+    for (addr = (unsigned int)CNC_CRYPTO_BASE; addr <=(unsigned int)CNC_CRYPTO_BASE + 0xc; addr += 4) {
+        val = scread32(addr);
+        printf(" crypto_read[0x%03x] = 0x%08x \n", addr, val);
+    }
+    if (chl == 0) {
+        printf("\nCHL 0: \n");
+        for (addr = (unsigned int)CNC_CRYPTO_BASE +0x10; addr <= (unsigned int)CNC_CRYPTO_BASE +0x4c; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr, val);
+        }
+        for (addr = (unsigned int)CNC_CRYPTO_BASE +0x60; addr <= (unsigned int)CNC_CRYPTO_BASE +0x68; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr, val);
+        }
+    } else if (chl == 1){
+        printf("\nCHL 1: \n");
+        for (addr = (unsigned int)CNC_CRYPTO_BASE +0x110; addr <= (unsigned int)CNC_CRYPTO_BASE +0x14c; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr , val);
+        }
+        for (addr = (unsigned int)CNC_CRYPTO_BASE +0x160; addr <= (unsigned int)CNC_CRYPTO_BASE +0x188; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr , val);
+        }
+    }else if (chl == 2) {
+        printf("\nCHL 2: \n");
+        for (addr = (unsigned int)CNC_CRYPTO_BASE +0x210; addr <= (unsigned int)CNC_CRYPTO_BASE +0x24c; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr, val);
+        }
+        for (addr = (unsigned int)CNC_CRYPTO_BASE + 0x260; addr <= (unsigned int)CNC_CRYPTO_BASE +0x288; addr += 4) {
+            val = scread32(addr);
+            printf(" crypto_read[0x%03x] = 0x%08x \n", addr, val);
+        }
+    }
+}
+
+
+SEC_ERROR_CODE SEC_Reset(void)
+{
+    unsigned int status;
+    status =scread32(0xB2100200);
+    scwrite32(0xB2100200, status & (~(1<<5)));
+    scwrite32(0xB2100200, status | (1<<5));
+    scwrite32(TDES_INT_CLS_ADDR, 0xFFFFFFFF);
+    //    scwrite32(TDES_INT_ENB_ADDR, 0xffffffff);
+    scwrite32(TDES_INT_RAW_REG_ADDR, 0);
+    return SEC_CORE_SUCCESS;
+}
+ 
+SEC_ERROR_CODE SEC_init(void)
+{
+    unsigned int i;
+
+	for(i = 0 ; i < CRYPTO_CHANNEL_MAX_NUM; i++){
+        channel_info[i].p_chl_mem_base = CRYPTO_MEM_REGION + i * CRYPTO_MEM_SIZE /3;
+        channel_info[i].chl_mem_size = CRYPTO_MEM_SIZE / 3;
+        channel_info[i].p_in_buffer_base = channel_info[i].p_chl_mem_base;
+
+        channel_info[i].in_buffer_size = channel_info[i].chl_mem_size / 2;
+
+        channel_info[i].p_out_buffer_base = channel_info[i].p_in_buffer_base + channel_info[i].in_buffer_size;
+
+        channel_info[i].out_buffer_size = channel_info[i].chl_mem_size - channel_info[i].in_buffer_size;
+
+
+        if (i == 0){ 
+            channel_info[i].mode = BLOCK_DMA_MODE; 
+        }
+        else {
+            channel_info[i].mode = STREAMING_MODE; 
+        }
+        channel_info[i].input_buffer.r_pointer = channel_info[i].p_in_buffer_base;
+        channel_info[i].input_buffer.w_pointer = channel_info[i].p_in_buffer_base;
+        channel_info[i].output_buffer.r_pointer = channel_info[i].p_out_buffer_base;
+        channel_info[i].output_buffer.w_pointer = channel_info[i].p_out_buffer_base;
+
+        channel_info[i].emi = NO_SET;
+        channel_info[i].count = 0;
+    }
+
+    
+    DEBUG_PRINTF("SEC Init\n");
+    return SEC_CORE_SUCCESS;
+}
+
+
+
+SEC_ERROR_CODE SEC_term(void)
+{
+    scwrite32(TDES_INT_CLS_ADDR, 0xFFFFFFFF);
+    scwrite32(TDES_INT_ENB_ADDR, 0);
+    scwrite32(TDES_DATA_SIZE(0), 0);
+
+
+    return SEC_CORE_SUCCESS;
+}
+
+
+SEC_ERROR_CODE PV_read(unsigned int cmd, unsigned int *value)
+{
+
+    CHECK_WITH_TMO(scread32(MAILBOX0) & 0x80000000);
+	scwrite32(MAILBOX1, cmd);
+	scwrite32(MAILBOX7, 0x0);
+	scwrite32(MAILBOX0, 0x80000012);
+    CHECK_WITH_TMO(!(scread32(MAILBOX7) & 0x80000000));
+	if (scread32(MAILBOX7) & 0xffff)
+		return SEC_CORE_ERROR;
+
+	*value = scread32(MAILBOX2);
+	scwrite32(MAILBOX7, 0x0);
+	return SEC_CORE_SUCCESS;
+}
+
+
+static SEC_ERROR_CODE Key_write(unsigned int         cmd, 
+                                unsigned int         type,
+                                const unsigned char* key,
+                                int                  size)
+{
+    unsigned int * val = (unsigned int *)key;
+    int i;
+
+    if (size & 0x3)
+        return SEC_CORE_ERROR;  
+   
+
+    CHECK_WITH_TMO(scread32(MAILBOX0) & 0x80000000);
+	scwrite32(MAILBOX1, type);
+    for(i = 0; i < size; i += 4)
+    	scwrite32(MAILBOX2 + i, *val++);
+
+	scwrite32(MAILBOX7, 0x0);
+	scwrite32(MAILBOX0, cmd);
+    CHECK_WITH_TMO(!(scread32(MAILBOX7) & 0x80000000));
+	if (scread32(MAILBOX7) & 0xffff)
+		return SEC_CORE_ERROR;
+	scwrite32(MAILBOX7, 0x0);
+	return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Init(unsigned int chl)
+{
+    if (channel_info[chl].mode == BLOCK_DMA_MODE) {
+        scwrite32(SAR_TS(chl), channel_info[chl].p_in_buffer_base);
+        scwrite32(DAR_TS0(chl), channel_info[chl].p_out_buffer_base);
+        scwrite32(TDES_CONT(chl), 0);
+    } else if (channel_info[chl].mode == STREAMING_MODE) {
+        scwrite32(SRC_LOW_ADDR_TS(chl), channel_info[chl].p_in_buffer_base);
+        scwrite32(SRC_UP_ADDR_TS(chl), channel_info[chl].p_in_buffer_base + channel_info[chl].in_buffer_size);
+
+        scwrite32(SRC_WR_PT_TS(chl), channel_info[chl].input_buffer.w_pointer);
+        scwrite32(SRC_RD_PT_TS(chl), channel_info[chl].input_buffer.r_pointer);
+
+        scwrite32(DES_LOW_ADDR_TS(chl), channel_info[chl].p_out_buffer_base);
+        scwrite32(DES_UP_ADDR_TS(chl), channel_info[chl].p_out_buffer_base + channel_info[chl].out_buffer_size);
+
+        scwrite32(DES_WR_PT_TS(chl), channel_info[chl].output_buffer.w_pointer);
+        scwrite32(DES_RD_PT_TS(chl), channel_info[chl].output_buffer.r_pointer);
+
+        scwrite32(TDES_CONT(chl), 0);
+    }
+    channel_info[chl].write_count = 0;
+    channel_info[chl].read_count = 0;
+    DEBUG_PRINTF("CHL Init\n");
+    
+	return SEC_CORE_SUCCESS;
+}
+
+
+SEC_ERROR_CODE SetHostKey(unsigned int chl, SEC_EMI emi, unsigned char * hostkey, int size)
+{
+    unsigned int kldf;
+
+    if ((IS_DVB(emi) && (size != 8))   || 
+        (IS_TDES(emi) && (size != 16)) ||
+        (IS_AES(emi) && (size != 16))  ||
+        (chl >= CRYPTO_CHANNEL_MAX_NUM))
+        {
+            printf("--func:%s line:%d invalid input parameters\n", __FUNCTION__,__LINE__);
+            return SEC_CORE_ERROR;
+        }
+    
+    /* get kld status */
+    SEC_ASSERT(PV_read(0x2, &kldf));
+
+    if (!kldf) { /* Default mode */
+        if (IS_TDES(emi))
+            {
+                SEC_ASSERT(Key_write(0x80000004, 0x80000100 | chl, hostkey, size));
+            }
+        else if (IS_AES(emi))
+            {
+                SEC_ASSERT(Key_write(0x80000004, 0x80000000 | chl, hostkey, size));
+            }
+        else 
+            {
+                printf("unsupported emi = 0x%08x\n", emi);
+                return SEC_CORE_ERROR;
+            }
+    } else { /* In Restricted mode */
+        if (IS_TDES(emi))
+            {
+                unsigned int Key0 = 0;
+                unsigned int Key1 = 0;
+                unsigned int Key2 = 0;
+                unsigned int Key3 = 0;
+                unsigned int KeyReg0;
+                unsigned int KeyReg1;
+
+                Key0 = *(unsigned int *)(hostkey+0x0);
+                Key1 = *(unsigned int *)(hostkey+0x4);
+                Key2 = *(unsigned int *)(hostkey+0x8);
+                Key3 = *(unsigned int *)(hostkey+0xc);
+
+                KeyReg0 = KeyReg1 = 0;
+                KeyReg0 = ((Key1 & 0xfe000000) >> (32-7)) |
+                    ((Key1 & 0x00fe0000) >> (24-14)) |
+                    ((Key1 & 0x0000fe00) << (14-9)) |
+                    ((Key1 & 0x000000fe) << (21-1)) |
+                    ((Key0 & 0x1e000000) << (3));
+
+                KeyReg1 = ((Key0 & 0xe0000000) >> 29) |
+                    ((Key0 & 0x00fe0000) >> 14) |
+                    ((Key0 & 0x0000fe00) << 1) |
+                    ((Key0 & 0x000000fe) << 16);
+
+                scwrite32(TDES_KEY0(chl), KeyReg0);
+                scwrite32(TDES_KEY1(chl), KeyReg1);
+                scwrite32(TDES_KEY4(chl), KeyReg0);
+                scwrite32(TDES_KEY5(chl), KeyReg1);
+
+                KeyReg0 = KeyReg1 = 0;
+                KeyReg0 = ((Key3 & 0xfe000000) >> (32-7)) |
+                    ((Key3 & 0x00fe0000) >> (24-14)) |
+                    ((Key3 & 0x0000fe00) << (14-9)) |
+                    ((Key3 & 0x000000fe) << (21-1)) |
+                    ((Key2 & 0x1e000000) << (3));
+
+                KeyReg1 = ((Key2 & 0xe0000000) >> 29) |
+                    ((Key2 & 0x00fe0000) >> 14) |
+                    ((Key2 & 0x0000fe00) << 1) |
+                    ((Key2 & 0x000000fe) << 16);
+
+                scwrite32(TDES_KEY2(chl), KeyReg0);
+                scwrite32(TDES_KEY3(chl), KeyReg1);
+            }
+        else if (IS_AES(emi)){
+            scwrite32(TDES_KEY3(chl), scSWAP(*(unsigned int *)(hostkey+0x0)));
+            scwrite32(TDES_KEY2(chl), scSWAP(*(unsigned int *)(hostkey+0x4)));
+            scwrite32(TDES_KEY1(chl), scSWAP(*(unsigned int *)(hostkey+0x8)));
+            scwrite32(TDES_KEY0(chl), scSWAP(*(unsigned int *)(hostkey+0xc)));
+        }  else 
+            {
+                printf("unsupported emi = 0x%08x\n", emi);
+                return SEC_CORE_ERROR;
+            }
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE SetCryptoMode(unsigned int          chl,
+                             SEC_EMI               emi,
+                             unsigned char *       Ivector,
+                             int                   size)
+{    
+    //    unsigned char crm, cim, sbm = 0, ivf = 0, enc = 0;
+    unsigned int  temp;
+    unsigned int refreshIv =1;
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM) {
+        printf( "invalid channel number!\n");
+        return SEC_CORE_INVALID_PARAM;
+    }
+    
+    if (!IS_ECB(emi) && refreshIv &&
+        ( (Ivector == NULL) ||
+          (IS_AES(emi) && (size != 16)) ||
+          (IS_TDES(emi) && (size != 8)) ) )
+        {
+            printf("invalid input IV size or vector:emi=0x%x, size=%d \n", emi, size);
+            return SEC_CORE_INVALID_PARAM;
+        }
+    scwrite32(TDES_COM(chl), 0 );    
+
+	/* Step 2: set IV vector */
+	if (!IS_ECB(emi) && refreshIv) { /* CBC */
+        if (size == 8){ 
+            scwrite32(TDES_IV1(chl), scSWAP(*(unsigned int *)(Ivector)));
+			scwrite32(TDES_IV0(chl), scSWAP(*(unsigned int *)(Ivector+4)));
+			scwrite32(TDES_IV2(chl), 0);
+			scwrite32(TDES_IV3(chl), 0);
+
+        }
+        else // size == 16
+        {
+    		scwrite32(TDES_IV3(chl), scSWAP(*(unsigned int *)(Ivector)));
+			scwrite32(TDES_IV2(chl), scSWAP(*(unsigned int *)(Ivector+4)));
+			scwrite32(TDES_IV1(chl), scSWAP(*(unsigned int *)(Ivector+8)));
+			scwrite32(TDES_IV0(chl), scSWAP(*(unsigned int *)(Ivector+12)));
+            
+        }
+	}
+    //    temp = scread32(TDES_COM(chl)) & (~0x7ff);
+
+
+    temp = ((emi & 0xff) <<9) | 
+        (((emi & 0x700) >>8) << 6) | 
+        (((emi & 0xf0000) >> 16) <<2) |
+        ((emi & 0x80000000)>> 30) |
+        (refreshIv & 0x1);
+
+    scwrite32(TDES_COM(chl), temp);    
+
+    DEBUG_PRINTF("SEC Set Mode:emi=0x%x, temp=0x%x\n",emi, temp);
+    DEBUG_PRINTF("SEC Mode:0x%x\n",scread32(TDES_COM(chl)));
+    return SEC_CORE_SUCCESS;  
+}
+
+SEC_ERROR_CODE GetCryptoIV(unsigned int          chl,
+                           SEC_EMI               emi,
+                           unsigned char *       Ivector,
+                           int *                 size)
+{
+    if (size == NULL || *size == 0)
+        return SEC_CORE_INVALID_PARAM;
+    if (IS_ECB(emi) && ((Ivector == NULL) ||
+                        (IS_AES(emi) && (*size < 16)) ||
+                        (IS_TDES(emi) && (*size < 8)) ) )    
+        {
+            return SEC_CORE_INVALID_PARAM;
+        }
+
+    if (IS_AES(emi))
+        *size = 16;
+    else if (IS_TDES(emi))
+        *size =8;
+
+	if (!IS_ECB(emi)){ /* CBC */
+            if (IS_TDES(emi)){
+                *size = 8; 
+                (*(unsigned int *)(Ivector)) = scSWAP(scread32(TDES_IV1(chl)));
+                (*(unsigned int *)(Ivector+4)) = scSWAP(scread32(TDES_IV0(chl)));
+
+            }
+            else if (IS_AES(emi)){// size == 16
+ 
+            *size = 16;
+    		(*(unsigned int *)(Ivector))= scSWAP(scread32(TDES_IV3(chl)));
+    		(*(unsigned int *)(Ivector+4))= scSWAP(scread32(TDES_IV2(chl)));
+    		(*(unsigned int *)(Ivector+8))= scSWAP(scread32(TDES_IV1(chl)));
+    		(*(unsigned int *)(Ivector+12))= scSWAP(scread32(TDES_IV0(chl)));
+
+        }
+	}    
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Start(unsigned int chl)
+{
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM) {
+        printf( "invalid channel number!\n");
+        return SEC_CORE_INVALID_PARAM;
+    }
+
+    //    scwrite32(TDES_CONT(chl), 0);    
+    while (((scread32(TDES_COM(chl)) >> 30) & 0x1) == 0x1 ){
+       printf("Not Stop!\n");
+    }
+
+    DEBUG_PRINTF("TDES_COM(%d) = 0x%x\n", chl, scread32(TDES_COM(chl)));
+    scwrite32(TDES_COM(chl), (scread32(TDES_COM(chl)) | 0x80000000));
+    channel_info[chl].write_count = 0;
+    channel_info[chl].read_count = 0;
+    channel_info[chl].term_last_flag = 0;
+    channel_info[chl].input_buffer.r_pointer = channel_info[chl].p_in_buffer_base;
+    channel_info[chl].input_buffer.w_pointer = channel_info[chl].p_in_buffer_base;
+    channel_info[chl].output_buffer.r_pointer = channel_info[chl].p_out_buffer_base;
+    channel_info[chl].output_buffer.w_pointer = channel_info[chl].p_out_buffer_base;
+
+
+    scwrite32(SRC_WR_PT_TS(chl), channel_info[chl].input_buffer.w_pointer);
+    scwrite32(SRC_RD_PT_TS(chl), channel_info[chl].input_buffer.r_pointer);
+
+    scwrite32(DES_WR_PT_TS(chl), channel_info[chl].output_buffer.w_pointer);
+    scwrite32(DES_RD_PT_TS(chl), channel_info[chl].output_buffer.r_pointer);
+    DEBUG_PRINTF("SEC Chl %d start\n", chl);
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Stop(unsigned int chl)
+{
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM) {
+        printf( "invalid channel number!\n");
+        return SEC_CORE_INVALID_PARAM;
+    }    
+    scwrite32(TDES_COM(chl), (scread32(TDES_COM(chl)) & ~0x80000000));
+
+    scwrite32(TDES_CONT(chl), 0);
+    channel_info[chl].write_count = 0;
+    channel_info[chl].read_count = 0;
+    channel_info[chl].term_last_flag = 0;
+    DEBUG_PRINTF("SEC Chl %d stop\n", chl);
+    return SEC_CORE_SUCCESS;
+
+}
+
+SEC_ERROR_CODE CHL_Enable_In_Interrupt(unsigned int chl)
+{
+    unsigned int value;
+    if (channel_info[chl].mode == STREAMING_MODE){
+        value = scread32(TDES_INT_ENB_ADDR);
+        value |= (1 << (4 * chl));
+        scwrite32(TDES_INT_ENB_ADDR, value);
+    }
+
+    DEBUG_PRINTF("SEC Chl %d Interrupt enable\n", chl);
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Set_In_Threshold(unsigned int chl, unsigned int in_threshold)
+{
+    if (channel_info[chl].mode == STREAMING_MODE){
+        scwrite32(SRC_THRESHOLD_TS(chl), in_threshold);
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Set_Out_Threshold(unsigned int chl, unsigned int out_threshold)
+{
+
+    if (channel_info[chl].mode == STREAMING_MODE){
+        scwrite32(SRC_THRESHOLD_TS(chl), out_threshold);
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Enable_Out_Interrupt(unsigned int chl)
+{
+    unsigned int vale;
+    if (channel_info[chl].mode == STREAMING_MODE){
+       vale = scread32(TDES_INT_ENB_ADDR);
+       vale |= (1 << (4 * chl + 1));
+        scwrite32(TDES_INT_ENB_ADDR, vale);
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+
+SEC_ERROR_CODE CHL_Enable_End_Interrupt(unsigned int chl)
+{
+    unsigned int vale;
+    vale = scread32(TDES_INT_ENB_ADDR);
+    if (chl == 0) 
+        vale |= 0x1;
+    else 
+        vale |= (1 << (4 * chl + 2));
+    scwrite32(TDES_INT_ENB_ADDR, vale);
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Disable_In_Interrupt(unsigned int chl)
+{
+    unsigned int vale;
+    if (channel_info[chl].mode == STREAMING_MODE){
+        vale = scread32(TDES_INT_ENB_ADDR);
+        vale &=~( 1 << 4 * chl);
+        scwrite32(TDES_INT_ENB_ADDR, vale);
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+SEC_ERROR_CODE CHL_Disable_Out_Interrupt(unsigned int chl)
+{
+    unsigned int vale;
+    if (channel_info[chl].mode == STREAMING_MODE){
+        vale = scread32(TDES_INT_ENB_ADDR);
+        vale &=~( 1 << (4 * chl +1) );
+        scwrite32(TDES_INT_ENB_ADDR, vale);
+    }
+    return SEC_CORE_SUCCESS;
+}
+
+
+SEC_ERROR_CODE CHL_Disable_End_Interrupt(unsigned int chl)
+{
+   unsigned int vale;
+    vale = scread32(TDES_INT_ENB_ADDR);
+    if (chl == 1) 
+        vale &= ~0x1;
+    else 
+        vale &= ~(1 << (4 * chl + 2));
+    scwrite32(TDES_INT_ENB_ADDR, vale);
+    return SEC_CORE_SUCCESS;
+}
+
+
+/** 
+ * Flush the rest data for streaming mode
+ * 
+ * @param chl: channel number 
+ * 
+ * @return 
+ */
+
+SEC_ERROR_CODE CHL_Flush(unsigned int chl)
+{
+    unsigned int in_wp;
+    unsigned int free_size;
+    unsigned int term_data;
+    unsigned int written_size;
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM) {
+        printf( "invalid channel number!\n");
+        return SEC_CORE_INVALID_PARAM;
+    }    
+    if (channel_info[chl].mode != STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+    in_wp = (channel_info[chl].input_buffer.w_pointer) & 0x7FFFFFFF;
+
+    /* workaround for bug */
+    if (((in_wp % 64) != 0) || channel_info[chl].write_count < 64){
+        scwrite32(TDES_CONT(chl), 1); 
+    } else {
+        do{
+            free_size =CHL_Check_InBuffer_FreeSize(chl);
+            DEBUG_PRINTF("Flush: free data =%d\n",free_size);
+        }while( free_size <4 );
+        term_data = 0xbeefbeef;
+
+        written_size = Stream_CHL_Write_Data(chl,(char *) &term_data, 4);
+        channel_info[chl].write_count -= written_size;
+        scwrite32(TDES_CONT(chl), 1); 
+    }
+
+    DEBUG_PRINTF("SEC Chl %d Flush\n", chl);
+    return SEC_CORE_SUCCESS;
+}
+
+
+/** Set Block Mode channel access mode: DMA/HOST
+ *  Only for Block mode channel
+ * 
+ * @param chl: channel number: now only support channel 0 
+ * @param mode: DMA or HOST
+ * 
+ * @return 
+ */
+SEC_ERROR_CODE SetBlockCHLMode(unsigned int chl, SEC_CHANNEL_MODE mode)
+{
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM) {
+        printf( "invalid channel number!\n");
+        return SEC_CORE_INVALID_PARAM;
+    }    
+    if (channel_info[chl].mode == STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    } else if (mode == BLOCK_DMA_MODE) {
+        scwrite32(TDES_CONT(chl), 0);
+    } else {
+        scwrite32(TDES_CONT(chl), 1);
+    } 
+    channel_info[chl].mode = mode;
+    DEBUG_PRINTF("SEC Chl %d Mode to %d\n", chl, mode);
+    return SEC_CORE_SUCCESS;
+
+}
+
+/** 
+ * 
+ * 
+ * @param chl : chl number
+ * @param status:  0: for stopped  1: in processing 
+ * 
+ * @return 
+ */
+SEC_ERROR_CODE GetCryptoDone(unsigned int chl, unsigned char* status)
+{
+    unsigned int raw_int_value;
+    unsigned int int_value=0;
+    int_value=int_value;
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || status == NULL) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+    raw_int_value =scread32(TDES_INT_RAW_REG_ADDR);
+    int_value = scread32(TDES_INT_REG_ADDR);
+
+
+
+    if (chl == 0) 
+        *status = (~raw_int_value) & 0x1;
+    else 
+        *status = ((~raw_int_value) >> (4 * chl + 2)) & 0x1;
+
+    DEBUG_PRINTF("COM=0x%x, CON=0x%x\n", scread32(TDES_COM(chl)), scread32(TDES_CONT(chl))); 
+    DEBUG_PRINTF("raw=0x%x, status=%d\n", raw_int_value, *status);     
+    if (*status == 0){
+        
+        scwrite32(TDES_CONT(chl), 0);
+        
+        if (chl == 0) 
+            raw_int_value = (raw_int_value) & (~0x1);
+        else 
+            raw_int_value = (raw_int_value) & (~(1 << (4 * chl + 2)));
+
+        scwrite32(TDES_INT_RAW_REG_ADDR, raw_int_value);
+    }
+    
+
+    return SEC_CORE_SUCCESS;    
+
+}
+
+SEC_ERROR_CODE Update_CHL_InWr_Pointer(unsigned int chl)
+{
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || channel_info[chl].mode != STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+    scwrite32(SRC_WR_PT_TS(chl),channel_info[chl].input_buffer.w_pointer);
+    DEBUG_PRINTF("SEC Chl %d update In write Pointer to 0x%x\n", chl, channel_info[chl].input_buffer.w_pointer);
+    return SEC_CORE_SUCCESS;    
+}
+
+SEC_ERROR_CODE Get_CHL_InRe_Pointer(unsigned int chl) //b
+{ 
+   if (chl >= CRYPTO_CHANNEL_MAX_NUM || channel_info[chl].mode != STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+   channel_info[chl].input_buffer.r_pointer = scread32(SRC_RD_PT_TS(chl));
+   return SEC_CORE_SUCCESS;    
+}
+
+SEC_ERROR_CODE Update_CHL_OutRe_Pointer(unsigned int chl)
+{
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || channel_info[chl].mode != STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+    scwrite32(DES_RD_PT_TS(chl),channel_info[chl].output_buffer.r_pointer);
+    DEBUG_PRINTF("SEC Chl %d update out read Pointer to 0x%x \n", chl, channel_info[chl].output_buffer.r_pointer);
+    return SEC_CORE_SUCCESS;    
+}
+
+SEC_ERROR_CODE Get_CHL_OutWr_Pointer(unsigned int chl)
+{
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || channel_info[chl].mode != STREAMING_MODE) {
+        return SEC_CORE_INVALID_PARAM;
+    }
+
+    channel_info[chl].output_buffer.w_pointer = scread32(DES_WR_PT_TS(chl));
+    return SEC_CORE_SUCCESS;    
+}
+
+int CHL_Check_OutBuffer_DataSize(unsigned int chl)
+{
+    int len;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+    unsigned int diff;
+
+    if (channel_info[chl].mode != STREAMING_MODE) {
+        len = (int)scread32(TDES_DATA_SIZE(chl));
+        if (len == 0) return channel_info[chl].count;
+        else return 0;
+    }
+
+    Get_CHL_OutWr_Pointer(chl);
+    
+	wp = channel_info[chl].output_buffer.w_pointer;
+	rp = channel_info[chl].output_buffer.r_pointer;
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+
+	if (wp_tog == rp_tog) {
+		len = wp - rp;
+	}
+	else {
+		len = channel_info[chl].out_buffer_size + wp - rp;
+	}
+    diff = (unsigned int)(channel_info[chl].write_count - channel_info[chl].read_count);
+    if (len > diff) 
+        len = diff;
+    DEBUG_PRINTF("SEC Chl %d check output data size: %d(wp=0x%x,rp=0x%x )\n", chl, len,wp,rp);
+	return len;
+
+}
+
+int CHL_Check_InBuffer_FreeSize(unsigned int chl)
+{
+
+    int len;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+    Get_CHL_InRe_Pointer(chl);
+    
+	wp = channel_info[chl].input_buffer.w_pointer;
+	rp = channel_info[chl].input_buffer.r_pointer;
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+
+	if (wp_tog == rp_tog) {
+		len = channel_info[chl].in_buffer_size + rp - wp;
+	}
+	else {
+		len = rp - wp;
+	}
+
+	return len;
+
+}
+
+int Block_CHL_Read_Data(unsigned int chl, char* buf, unsigned int len)
+{
+    unsigned int read_addr;
+
+    if (len > channel_info[chl].out_buffer_size) {
+        printf("Crypto Error: Block CHL read size too large\n");
+        return -1;
+    }
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || buf == NULL) {
+        return -1;
+    }
+
+    if (len == 0 )  return 0;
+    read_addr = channel_info[chl].p_out_buffer_base;
+    
+    memcpy(buf, (void *) read_addr, len);
+    return len;
+}
+
+
+int Stream_CHL_Read_Data(unsigned int chl, char * buf, unsigned int len)
+{
+    int data_size = 0;
+    unsigned int temp_size = 0;
+    unsigned int read_addr;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+
+    unsigned int diff;
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || buf == NULL) {
+        return -1;
+    }
+
+    if (len == 0 )  return 0;
+
+    if (channel_info[chl].write_count <= channel_info[chl].read_count)
+        return 0;
+
+    diff = (unsigned int)(channel_info[chl].write_count - channel_info[chl].read_count);
+    if (len > diff) 
+        len = diff;
+
+    Get_CHL_OutWr_Pointer(chl);
+	wp = channel_info[chl].output_buffer.w_pointer;
+	rp = channel_info[chl].output_buffer.r_pointer;
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+    read_addr = rp;         
+	if (wp_tog != rp_tog) {
+		temp_size = channel_info[chl].p_out_buffer_base + channel_info[chl].out_buffer_size - rp;
+        if (temp_size > len) 
+            temp_size = len;
+       
+        memcpy((void *)buf, (void *)read_addr, temp_size);
+
+        len -= temp_size;
+        rp = rp + temp_size;
+        data_size += temp_size;
+        if (rp >= channel_info[chl].p_out_buffer_base + channel_info[chl].out_buffer_size) {
+            rp -= channel_info[chl].out_buffer_size;
+            rp_tog = ~rp_tog;
+        }
+        read_addr = rp;        
+        buf += temp_size;
+	}
+
+    if (len > 0) {
+        temp_size = wp - rp;
+        if (temp_size > len) 
+            temp_size = len;
+
+        memcpy((void *)buf, (void *)read_addr, temp_size);
+        data_size += temp_size;
+        rp += temp_size;
+        if (rp >= channel_info[chl].p_out_buffer_base + channel_info[chl].out_buffer_size) {
+            rp -= channel_info[chl].out_buffer_size;
+            rp_tog = ~rp_tog;
+        }
+    }
+    channel_info[chl].output_buffer.r_pointer = (rp & 0x7fffffff) | (rp_tog & 0x80000000);
+
+    Update_CHL_OutRe_Pointer(chl);
+    DEBUG_PRINTF("SEC Chl %d streaming read data: 0x%x\n", chl, data_size);
+    channel_info[chl].read_count += data_size;
+    return data_size;
+
+}
+
+int Stream_CHL_Write_Data(unsigned int chl, char * buf, unsigned int len)
+{
+    int data_size = 0;
+    unsigned int temp_size = 0;
+    unsigned int write_addr;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+
+    if (chl >= CRYPTO_CHANNEL_MAX_NUM || buf == NULL) {
+        return -1;
+    }
+
+    if (len == 0 )  return 0;
+
+    Get_CHL_InRe_Pointer(chl);
+    
+	wp = channel_info[chl].input_buffer.w_pointer;
+	rp = channel_info[chl].input_buffer.r_pointer;
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+    write_addr = wp;        
+	if (wp_tog == rp_tog) {
+		temp_size = channel_info[chl].p_in_buffer_base + channel_info[chl].in_buffer_size - wp;
+        if (temp_size > len) 
+            temp_size = len;
+
+        memcpy((void *)write_addr, buf, temp_size);
+
+        len -= temp_size;
+        wp  += temp_size;
+        data_size += temp_size;
+        if (wp >= channel_info[chl].p_in_buffer_base + channel_info[chl].in_buffer_size) {
+            wp -= channel_info[chl].in_buffer_size;
+            wp_tog = ~wp_tog;
+        }
+        write_addr = wp;
+        buf += temp_size;
+	}
+
+    if (len > 0) {
+        temp_size = rp - wp;
+        if (temp_size > len) 
+            temp_size = len;
+
+        memcpy((void *)write_addr, buf, temp_size);
+        data_size += temp_size;
+        wp += temp_size;
+        if (wp >= channel_info[chl].p_in_buffer_base + channel_info[chl].in_buffer_size) {
+            wp -= channel_info[chl].in_buffer_size;
+            wp_tog = ~wp_tog;
+        }
+    }
+    channel_info[chl].input_buffer.w_pointer = (wp & 0x7fffffff) | (wp_tog & 0x80000000);
+    Update_CHL_InWr_Pointer(chl);
+    channel_info[chl].write_count += data_size;
+    DEBUG_PRINTF("SEC Chl %d streaming write data: 0x%x\n", chl, data_size);
+    
+    return data_size;
+
+}
+
+int Block_CHL_Write_Data(unsigned int chl,  char * buf, unsigned int len)
+{
+    unsigned int write_addr;
+
+    if (len > channel_info[chl].in_buffer_size) 
+        return -1;
+    if (len == 0 )  return 0;
+    
+    write_addr = channel_info[chl].p_in_buffer_base;
+
+    memcpy((void *) write_addr, buf, len);
+    scwrite32(TDES_DATA_SIZE(chl), (unsigned int)len);
+    channel_info[chl].count = len;
+    DEBUG_PRINTF("SEC Chl %d block write data: 0x%x\n", chl, len);
+    return len;
+
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/crypto/crypto_drv.h u-boot-2011.06/drivers/cnc1900/crypto/crypto_drv.h
--- u-boot-2011.06_original/drivers/cnc1900/crypto/crypto_drv.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/crypto/crypto_drv.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,238 @@
+/**
+ * @file   crypto_drv.h
+ * @author Fan Xiaodong <xiaodong.fan@caviumnetworks.com>
+ * @date   Dec. 2011
+ * 
+ * @brief  
+ * 
+ * 
+ */
+
+
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+
+
+
+
+#define CNC_SEC_MB_BASE       0xfffff800
+
+#define MAILBOX0              (CNC_SEC_MB_BASE+0x00)
+#define MAILBOX1              (CNC_SEC_MB_BASE+0x04)
+#define MAILBOX2              (CNC_SEC_MB_BASE+0x08)
+#define MAILBOX3              (CNC_SEC_MB_BASE+0x0c)
+#define MAILBOX4              (CNC_SEC_MB_BASE+0x10)
+#define MAILBOX5              (CNC_SEC_MB_BASE+0x14)
+#define MAILBOX6              (CNC_SEC_MB_BASE+0x18)
+#define MAILBOX7              (CNC_SEC_MB_BASE+0x1c)
+
+#define CNC_CRYPTO_BASE       0x80240000
+#define TDES_INT_REG_ADDR     (CNC_CRYPTO_BASE+0x00)
+#define TDES_INT_ENB_ADDR     (CNC_CRYPTO_BASE+0x04)
+#define TDES_INT_CLS_ADDR     (CNC_CRYPTO_BASE+0x08)
+#define TDES_INT_RAW_REG_ADDR (CNC_CRYPTO_BASE+0x0c)
+
+//#define SEC_MAX_CHL_NUM  3
+#define CHL_BASE(chl)         (CNC_CRYPTO_BASE + chl * 0x100)
+
+#define TDES_IV0(chl)         (CHL_BASE(chl)+0x10)
+#define TDES_IV1(chl)         (CHL_BASE(chl)+0x14)
+#define TDES_IV2(chl)         (CHL_BASE(chl)+0x18)
+#define TDES_IV3(chl)         (CHL_BASE(chl)+0x1c)
+
+
+#define TDES_DATA_SIZE(chl)   (CHL_BASE(chl)+0x20)
+
+#define TDES_CONT(chl)        (chl?(CHL_BASE(chl)+0x20):(CHL_BASE(chl)+0x24))
+#define TDES_COM(chl)         (CHL_BASE(chl)+0x28)
+
+#define TDES_KEY0(chl)        (CHL_BASE(chl)+0x30)
+#define TDES_KEY1(chl)        (CHL_BASE(chl)+0x34)
+#define TDES_KEY2(chl)        (CHL_BASE(chl)+0x38)
+#define TDES_KEY3(chl)        (CHL_BASE(chl)+0x3c)
+#define TDES_KEY4(chl)        (CHL_BASE(chl)+0x40)
+#define TDES_KEY5(chl)        (CHL_BASE(chl)+0x44)
+#define TDES_KEY6(chl)        (CHL_BASE(chl)+0x48)
+#define TDES_KEY7(chl)        (CHL_BASE(chl)+0x4c)
+
+#define TDES_CTR_CNT_UP(chl)  (CHL_BASE(chl)+0x60)
+
+#define SAR_TS(chl)           (CNC_CRYPTO_BASE + 0x64)
+#define DAR_TS0(chl)          (CNC_CRYPTO_BASE + 0x68)
+#define BLOCK_FIFO            (CNC_CRYPTO_BASE + 0x80)
+#define BLOCK_FIFO_CNT        (CNC_CRYPTO_BASE + 0x84)
+
+#define SRC_UP_ADDR_TS(chl)   (CHL_BASE(chl)+0x64)
+#define SRC_LOW_ADDR_TS(chl)  (CHL_BASE(chl)+0x68)
+#define SRC_WR_PT_TS(chl)     (CHL_BASE(chl)+0x6c)
+#define SRC_RD_PT_TS(chl)     (CHL_BASE(chl)+0x70)
+
+#define DES_UP_ADDR_TS(chl)   (CHL_BASE(chl)+0x74)
+#define DES_LOW_ADDR_TS(chl)  (CHL_BASE(chl)+0x78)
+#define DES_WR_PT_TS(chl)     (CHL_BASE(chl)+0x7c)
+#define DES_RD_PT_TS(chl)     (CHL_BASE(chl)+0x80)
+
+#define SRC_THRESHOLD_TS(chl) (CHL_BASE(chl)+0x84)
+#define DES_THRESHOLD_TS(chl) (CHL_BASE(chl)+0x88)
+
+
+#define scSWAP(x) \
+              ((unsigned int)( \
+              (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+              (((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
+              (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
+              (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+
+#define scMin(a, b)    (((a) > (b))?(b):(a))
+
+
+/* Register operation */
+#define scwrite32(a,v) (*(volatile unsigned int *)(a) = v)
+#define scread32(a)     (*(volatile unsigned int *)(a))
+
+
+
+#define IS_TDES(x)      (((x) & 0xff0000) == 0x0)
+#define IS_AES(x)       (((x) & 0x30000) == 0x10000)
+#define IS_DVB(x)       (0) /*disable DVB now */
+
+#define IS_ECB(x)       (((x) & 0xff00) == 0x0)
+#define IS_CBC(x)       (((x) & 0xff00) == 0x100)
+
+#define IS_CLEAR(x)     (((x) & 0xff) == 0x0)
+#define IS_DVS042(x)    (((x) & 0xff) == 0x1)
+
+#define IS_ENCRYPT(x)   (((x) & 0x80000000))
+
+#define CRYPTO_CHANNEL_MAX_NUM 3
+typedef enum _SEC_ERROR_CODE
+{
+    SEC_CORE_SUCCESS                    =  0,
+    SEC_CORE_ERROR                      = -1,
+    SEC_CORE_UNSUPPORTED_OPERATION      = -2,    
+    SEC_CORE_INVALID_PARAM              = -3,
+}SEC_ERROR_CODE;
+
+typedef enum _SEC_ALGORITHM_IDX{
+	TDES = 0,
+    AES128 = 1,
+	SMS4   = 2,
+    AES192 = 9,
+    AES256 = 13,
+}SEC_ALGORITHM_IDX;
+
+
+typedef enum _SEC_CIPHER_MODE_IDX{
+	ECB	= 0,
+	CBC,
+	CFB128,
+	OFB128,
+	CTS,
+	CTR,
+	//RESERVED
+}SEC_CIPHER_MODE_IDX;
+
+typedef enum _SEC_SHORT_BLOCK_IDX{
+	CLEAR 	= 0,
+	DVS042  = 1,
+	//RESERVED
+}SEC_SHORT_BLOCK_IDX;
+
+typedef enum _SEC_EMI
+{
+	DECRYPT_AES128_IDSA	    = ((AES128 << 16) & 0xFF0000) | ((CBC << 8) & 0xFF00) | ((DVS042 << 0) & 0xFF),
+	DECRYPT_AES128_ECB	    = ((AES128 << 16) & 0xFF0000) | ((ECB << 8) & 0xFF00) | ((CLEAR << 0)  & 0xFF),
+	DECRYPT_AES128_CIPlus	= ((AES128 << 16) & 0xFF0000) | ((CBC << 8) & 0xFF00) | ((CLEAR << 0)  & 0xFF),
+	DECRYPT_TDES_CBC_DVS042 = ((TDES << 16) & 0xFF0000)  | ((CBC << 8)  & 0xFF00) | ((DVS042 << 0) & 0xFF),
+    DECRYPT_DES_ECB_CLEAR	= ((TDES << 16) & 0xFF0000)  | ((ECB << 8)  & 0xFF00) | ((CLEAR << 0)  & 0xFF),
+
+	ENCRYPT_AES128_IDSA	    = ((1<< 31) & 0xFF000000)| ((AES128 << 16)& 0xFF0000) | ((CBC << 8)& 0xFF00) | ((DVS042 << 0)& 0xFF),
+    ENCRYPT_AES128_ECB	    = ((1<< 31) & 0xFF000000)| ((AES128 << 16)& 0xFF0000) | ((ECB << 8)& 0xFF00) | ((CLEAR << 0) & 0xFF),
+    ENCRYPT_AES128_CIPlus	= ((1<< 31) & 0xFF000000)| ((AES128 << 16)& 0xFF0000) | ((CBC << 8)& 0xFF00) | ((CLEAR << 0) & 0xFF),
+	ENCRYPT_TDES_CBC_DVS042 = ((1<< 31) & 0xFF000000)| ((TDES << 16)  & 0xFF0000) | ((CBC << 8)& 0xFF00) | ((DVS042 << 0)& 0xFF),
+    ENCRYPT_DES_ECB_CLEAR	= ((1<< 31) & 0xFF000000)| ((TDES << 16)  & 0xFF0000) | ((ECB << 8)& 0xFF00) | ((CLEAR << 0) & 0xFF),    
+    NO_SET =0xFF000000,
+}SEC_EMI;
+
+
+typedef enum _CRYPTO_CHANNEL_MODE 
+{
+    BLOCK_DMA_MODE  = 0,
+    STREAMING_MODE  = 1,
+    BLOCK_HOST_MODE = 2,
+}SEC_CHANNEL_MODE;
+
+typedef struct _CRYPTO_CHANNEL_BUFFER_PINTER
+{
+    unsigned int w_pointer;
+    unsigned int r_pointer;
+
+}SEC_CHANNEL_BUFFER_POINTER;
+
+typedef struct _CRYPTO_CHANNEL_INFO
+{
+    unsigned int  open_status;
+    unsigned int  p_chl_mem_base;
+    unsigned int  chl_mem_size;
+    unsigned int  p_in_buffer_base;
+    unsigned int  in_buffer_size;
+    unsigned int  p_out_buffer_base;
+    unsigned int  out_buffer_size;
+    SEC_CHANNEL_MODE  mode; /* 0: for block; 1: for streaming */
+    SEC_CHANNEL_BUFFER_POINTER input_buffer;
+    SEC_CHANNEL_BUFFER_POINTER output_buffer;
+    unsigned int count;
+    unsigned long long write_count;
+    unsigned long long read_count;
+    unsigned int term_last_flag;
+    SEC_EMI       emi; 
+}SEC_CHANNEL_INFO;
+
+SEC_ERROR_CODE SEC_Reset(void);
+SEC_ERROR_CODE SEC_init(void);
+SEC_ERROR_CODE SEC_term(void);
+SEC_ERROR_CODE SetHostKey (unsigned int chl, 
+                          SEC_EMI emi, 
+                          unsigned char * hostkey, 
+                          int size);
+SEC_ERROR_CODE SetCryptoMode (unsigned int        chl,
+                              SEC_EMI             emi,
+                              unsigned char *     Ivector,
+                              int                 size);
+SEC_ERROR_CODE GetCryptoIV(unsigned int          chl,
+                           SEC_EMI               emi,
+                           unsigned char *       Ivector,
+                           int *                 size);
+SEC_ERROR_CODE CHL_Flush(unsigned int chl);
+SEC_ERROR_CODE CHL_Start (unsigned int chl);
+SEC_ERROR_CODE CHL_Stop(unsigned int chl);
+SEC_ERROR_CODE CHL_Reset(unsigned int chl);
+SEC_ERROR_CODE SetBlockCHLMode(unsigned int chl, 
+                               SEC_CHANNEL_MODE mode);
+SEC_ERROR_CODE GetCryptoDone (unsigned int   chl, 
+                              unsigned char* status);
+SEC_ERROR_CODE Update_CHL_InWr_Pointer(unsigned int chl);
+SEC_ERROR_CODE Get_CHL_InRe_Pointer(unsigned int chl);
+SEC_ERROR_CODE Update_CHL_OutRe_Pointer(unsigned int chl);
+SEC_ERROR_CODE Get_CHL_OutWr_Pointer(unsigned int chl);
+int CHL_Check_OutBuffer_DataSize(unsigned int chl);
+int CHL_Check_InBuffer_FreeSize(unsigned int chl);
+int Block_CHL_Read_Data (unsigned int chl, 
+                             char * buf, 
+                             unsigned int len);
+int Stream_CHL_Read_Data(unsigned int chl, 
+                             char * buf, 
+                             unsigned int len);
+int Stream_CHL_Write_Data(unsigned int chl, 
+                          char * buf, 
+                          unsigned int len);
+int Block_CHL_Write_Data(unsigned int chl, 
+                         char * buf, 
+                         unsigned int len);
+SEC_ERROR_CODE CHL_Init(unsigned int chl);
+SEC_ERROR_CODE CHL_Stop(unsigned int chl);
+SEC_ERROR_CODE CHL_Start(unsigned int chl);
+void CHL_Dump_Regs(unsigned int chl);
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/crypto/Makefile u-boot-2011.06/drivers/cnc1900/crypto/Makefile
--- u-boot-2011.06_original/drivers/cnc1900/crypto/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/crypto/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 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)libcrypto.o
+
+COBJS-$(CONFIG_CNC1900_CRYPTO) += crypto_drv.o cmd_crypto.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/crypto/sec_define.h u-boot-2011.06/drivers/cnc1900/crypto/sec_define.h
--- u-boot-2011.06_original/drivers/cnc1900/crypto/sec_define.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/crypto/sec_define.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,34 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Copyright (C) 2005-2010, Celestial SemiConductor
+/// \File 		sec_define.h
+/// \Author 	Xun.Li@celestialsemi.com 
+/// \Version 	1.0
+/// \Date 		Created at 24-2-2011
+/// \History 
+///   ---------------------------------------------------------------------- 
+/// 	<Author>		<Time>		<Version>		<Desc>
+/// 	Xun.Li         2011/2/24		1.0		     Create
+///     Xiaodong.Fan   2011/11          1.1          Changed for 1800L
+///   ---------------------------------------------------------------------- 
+///
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __SEC_DEFINE_H__
+#define __SEC_DEFINE_H__
+
+/* key ladder level */
+#define KEY_LADDER_LEVEL        2
+
+/* Software Version */
+#define xSoftwareVersionMajor    (1)
+#define xSoftwareVersionMinor    (1)
+#define xSoftwareVersionStatus   (0)
+#define xSoftwareVersionRevision (0)
+
+/* Registers */
+
+#define usleep udelay
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/df.c u-boot-2011.06/drivers/cnc1900/df/df.c
--- u-boot-2011.06_original/drivers/cnc1900/df/df.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/df.c	2015-05-18 19:41:06.764203000 +0800
@@ -0,0 +1,1668 @@
+/****************************************************************************
+ * Copyright (C) 2011 Cavium Inc.
+ * All rights reserved
+ *
+ * [RELEASE HISTORY]                           
+ * VERSION  DATE       AUTHOR                  DESCRIPTION
+ * 0.1      11-10-10       Jia Ma           		Original
+ ****************************************************************************
+ */
+#include <linux/types.h>
+#include <common.h>
+#include <asm/byteorder.h>
+#include <malloc.h>
+#include "cnc_util.h"
+#include "tve0_1900.h"
+#include "tve1_1900.h"
+#include "df_reg_def.h"
+#include "df_reg_fmt.h"
+#include "../../../board/cavium/cnc1900/power_clock.h"
+#include "df.h"
+#include "command.h"
+
+#define df_write(a,b) 	(*(volatile unsigned int*)(a) = (b))
+#define df_write16(a,b) 	(*(volatile unsigned short*)(a) = (b))
+#define df_write8(a,b) 		(*(volatile unsigned char*)(a) = (b))
+
+#define df_read(a) 		(*(volatile unsigned int*)(a))
+#define df_read16(a) 		(*(volatile unsigned short*)(a))
+#define df_read8(a) 		(*(volatile unsigned char*)(a))
+
+static int __Is_ColorBar = 0;
+//#define DEBUG_DF  
+#ifdef DEBUG_DF
+#define df_printf printf
+#else
+#define df_printf(fmt,args...)
+#endif
+static unsigned char __tve0_reg_read(unsigned char addr_base)
+{
+	unsigned char data_rd;
+	unsigned int addr ;
+	addr = TVE0_REG_BASE +(addr_base);
+	data_rd = df_read8(addr);
+
+	return data_rd;
+}
+
+static void __tve0_reg_write(unsigned char addr_base, unsigned char data)
+{
+	unsigned char data_rd;
+	unsigned int addr ;
+	addr = TVE0_REG_BASE +(addr_base);
+
+	df_write8(addr,data);
+	data_rd = df_read8(addr);
+
+	if(data_rd != data)
+	{
+		printf("TVE0: Reg Write ERROR: addr_base = %x, wr_data =%x,rd_data = %x\n",\
+				addr_base,data,data_rd);
+	}
+}
+
+int InitTVE0Raw(TVOUT_MODE DispFormat , int EnableColorBar)
+{
+	int i = 0;
+	int VIDEO_TYPE  = TVOUT_MODE_576I;
+
+	int IsHD = 0;
+	int IsProgressive = 0;
+
+
+	//Map the Display Format Value to TVE0 Format Value
+	switch (DispFormat)
+	{
+		case TVOUT_MODE_SECAM:
+			VIDEO_TYPE = TYPE_SECAM;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_N:
+			VIDEO_TYPE = TYPE_PAL_N;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_M:
+			VIDEO_TYPE = TYPE_PAL_M;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_CN:
+			VIDEO_TYPE = TYPE_PAL_CN;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_576I:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_480I:
+			VIDEO_TYPE = TYPE_NTSC;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I30:
+			VIDEO_TYPE = TYPE_1080i30;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I25:
+			VIDEO_TYPE = TYPE_1080i;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_720P60:
+			VIDEO_TYPE = TYPE_720p60;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_720P50:
+			VIDEO_TYPE = TYPE_720p50;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_480P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_576P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+			return 0;
+		default:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+	}
+	printf("IsProgressive=%d,IsHd=%d\n",IsProgressive,IsHD);
+	//Hold TVE0 Timing
+	__tve0_reg_write(TVE0_REG[0][REG_ADDR],0x1);
+
+	//DEBUG_PRINTF("[TVE0: INFO]probe REV_ID ..%d\n",TVE0_REG[1][REG_ADDR]);
+
+	for (i=2; i<TVE0_REG_NUM; i++)
+	{
+		//DEBUG_PRINTF("TVE0: ADDR=%03x,WriteDATA=%03x\n",TVE0_REG[i][REG_ADDR],TVE0_REG[i][VIDEO_TYPE]);
+		__tve0_reg_write(TVE0_REG[i][REG_ADDR],TVE0_REG[i][VIDEO_TYPE]);
+	}
+
+	if (EnableColorBar)
+	{
+		unsigned char  RegValue = 0;
+		RegValue = __tve0_reg_read(0x2);
+		RegValue |= (1 << 5);
+		__tve0_reg_write(0x2,RegValue);
+	}
+	__tve0_reg_write(TVE0_REG[0][REG_ADDR],0x0);
+	df_printf("out InitTVE0Raw\n");
+	return 0;
+}
+
+static unsigned char __tve1_reg_read(unsigned char addr_base)
+{
+	unsigned char data_rd;
+	unsigned int addr ;
+	addr = TVE1_REG_BASE +(addr_base);
+	data_rd = df_read8(addr);
+	return data_rd;
+}
+
+static void __tve1_reg_write(unsigned char addr_base, unsigned char data)
+{
+	unsigned char data_rd;
+	unsigned int addr ;
+	addr = TVE1_REG_BASE +(addr_base);
+
+	df_write8(addr,data);
+	data_rd = df_read8(addr);
+	if(data_rd != data){
+		//		printf("TVE1: Reg Write ERROR: addr_base = %02x, wr_data =%08x,rd_data = %08x\n",
+		//				addr_base,data,data_rd);
+	}
+}
+
+int InitTVE1Raw( TVOUT_MODE DispFormat , int EnableColorBar)
+{
+	int i = 0;
+	int VIDEO_TYPE  = TVOUT_MODE_576I;
+
+	int IsHD = 0;
+	int IsProgressive = 0;
+
+
+	//Map the Display Format Value to TVE1 Format Value
+	switch (DispFormat){
+		case TVOUT_MODE_SECAM:
+			VIDEO_TYPE = TYPE_SECAM;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_N:
+			VIDEO_TYPE = TYPE_PAL_N;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_M:
+			VIDEO_TYPE = TYPE_PAL_M;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_CN:
+			VIDEO_TYPE = TYPE_PAL_CN;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_576I:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_480I:
+			VIDEO_TYPE = TYPE_NTSC;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080I25:
+			VIDEO_TYPE = TYPE_1080i;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_720P60:
+			VIDEO_TYPE = TYPE_720p60;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_720P50:
+			VIDEO_TYPE = TYPE_720p50;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_480P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_576P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+			return 0;
+		default:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+	}
+	//printascii("1111111111\n");
+	//Hold TVE1 Timing
+
+	printf("Init TVE1Raw  IsProgressive=%d,IsHd=%d\n",IsProgressive,IsHD);
+	__tve1_reg_write(TVE1_REG[0][REG_ADDR],0x1);
+	//DEBUG_PRINTF("[TVE1: INFO]probe REV_ID ..%d\n",TVE1_REG[1][REG_ADDR]);
+	//printascii("222222222222\n");
+
+	for (i=2; i<TVE1_REG_NUM; i++)
+	{
+		//		printf("***TVE1: ADDR=%03x,WriteDATA=0x%08x\n",TVE1_REG[i][REG_ADDR],TVE1_REG[i][VIDEO_TYPE]);
+		__tve1_reg_write(TVE1_REG[i][REG_ADDR],TVE1_REG[i][VIDEO_TYPE]);
+	}
+
+	if (EnableColorBar)
+	{
+		unsigned char RegValue = 0;
+		RegValue = __tve1_reg_read(0x2);
+		RegValue |= (1 << 5);
+		__tve1_reg_write(0x2,RegValue);
+	}
+	__tve1_reg_write(TVE1_REG[0][REG_ADDR],0x0);
+
+	return 0;
+}
+
+static int dfreg_ctrl[16] =
+{
+	VPP_REG_GLB_CTRL_H_UPDATE_REG,VPP_REG_GLB_CTRL_M_UPDATE_REG,VPP_REG_GLB_CTRL_C_UPDATE_REG,VPP_REG_GLB_CTRL_SETTING,VPP_REG_GLB_CTRL_CLK_SETTING,
+	VPP_REG_GLB_CTRL_INT_STA_COP,VPP_REG_GLB_CTRL_INT_MSK_COP,VPP_REG_GLB_CTRL_INT_STA_HOST,VPP_REG_GLB_CTRL_INT_MSK_HOST,VPP_REG_GLB_CTRL_SCALE_COEF3,
+	VPP_REG_GLB_CTRL_SCALE_COEF4,VPP_REG_GLB_CTRL_SCALE_COEF6,VPP_REG_GLB_CTRL_CPU_WQ,VPP_REG_GLB_CTRL_COP_RQ,VPP_REG_GLB_CTRL_HAND_STATUS,VPP_REG_GLB_CTRL_TG_SETTING,
+};
+
+static int dfreg_gfx[2][14] =
+{
+	{VPP_REG_GFX_UI1_CTRL,VPP_REG_GFX_UI1_ALPHA_CTRL,VPP_REG_GFX_UI1_SIZE,VPP_REG_GFX_UI1_KEY_RED,VPP_REG_GFX_UI1_KEY_BLUE,VPP_REG_GFX_UI1_KEY_GREEN,
+		VPP_REG_GFX_UI1_BUF_START,VPP_REG_GFX_UI1_LINE_PITCH,VPP_REG_GFX_UI1_X_POSITON,VPP_REG_GFX_UI1_Y_POSITON,VPP_REG_GFX_UI1_BUF_START_3D,
+		VPP_REG_GFX_UI1_A8,VPP_REG_GFX_UI1_PHASE,VPP_REG_GFX_UI1_COEFF_GID,
+	},
+	{VPP_REG_GFX_UI2_CTRL,VPP_REG_GFX_UI2_ALPHA_CTRL,VPP_REG_GFX_UI2_SIZE,VPP_REG_GFX_UI2_KEY_RED,VPP_REG_GFX_UI2_KEY_BLUE,VPP_REG_GFX_UI2_KEY_GREEN,
+		VPP_REG_GFX_UI2_BUF_START,VPP_REG_GFX_UI2_LINE_PITCH,VPP_REG_GFX_UI2_X_POSITON,VPP_REG_GFX_UI2_Y_POSITON,VPP_REG_GFX_UI2_BUF_START_3D,
+		VPP_REG_GFX_UI2_A8,VPP_REG_GFX_UI2_PHASE,VPP_REG_GFX_UI2_COEFF_GID,
+	},
+};
+
+static int dfreg_comp[9] =
+{
+	VPP_REG_COMP_B2_BACK_GROUND,VPP_REG_COMP_B2_Z_ORDER,VPP_REG_COMP_B2_DEFAULT_ALPHA,VPP_REG_COMP_COLOR_ADJUST,VPP_REG_COMP_SHARP_Y_CTRL,
+	VPP_REG_COMP_SHARP_C_CTRL,VPP_REG_COMP_B3_BACK_GROUND,VPP_REG_COMP_B3_Z_ORDER,VPP_REG_COMP_B3_DEFAULT_ALPHA
+};
+
+static int dfreg_outif[2][9] =
+{
+	{VPP_REG_TG1_CTRL,VPP_REG_TG1_X_SIZE,VPP_REG_TG1_Y_SIZE,VPP_REG_TG1_HSYNC,VPP_REG_TG1_VSYNC,
+		VPP_REG_TG1_VGA_LEVEL,VPP_REG_TG1_V_START_LINE,VPP_REG_TG1_STA_DISP_SIZE,VPP_REG_TG1_STA_LINE
+	},
+	{VPP_REG_TG2_CTRL,VPP_REG_TG2_X_SIZE,VPP_REG_TG2_Y_SIZE,VPP_REG_TG2_HSYNC,VPP_REG_TG2_VSYNC,
+		VPP_REG_TG2_VGA_LEVEL,VPP_REG_TG2_V_START_LINE,VPP_REG_TG2_STA_DISP_SIZE,VPP_REG_TG2_STA_LINE
+	},
+};
+#if 0
+static int dfreg_video0[41] =
+{
+	DISP_VIDEO1_CTRL,DISP_VIDEO1_ALPHA_CTRL,DISP_VIDEO1_X_POSITON,DISP_VIDEO1_Y_POSITON,DISP_VIDEO1_SRC_X_CROP,DISP_VIDEO1_SRC_Y_CROP,
+	DISP_VIDEO1_LAI_PARAM,DISP_VIDEO1_YV_RATIO,DISP_VIDEO1_YH_RATIO,DISP_VIDEO1_CV_RATIO,DISP_VIDEO1_CH_RATIO,DISP_VIDEO1_Y_NOLINE_D,
+	DISP_VIDEO1_C_NOLINE_D,DISP_VIDEO1_Y_NOLINE_K,DISP_VIDEO1_C_NOLINE_K,DISP_VIDEO1_HOR_PHASE,DISP_VIDEO1_VER_PHASE,
+	DISP_VIDEO1_CUR_YT_ADDR,DISP_VIDEO1_CUR_CT_ADDR,DISP_VIDEO1_CUR_YB_ADDR,DISP_VIDEO1_CUR_CB_ADDR,DISP_VIDEO1_PRE_YT_ADDR,
+	DISP_VIDEO1_PRE_CT_ADDR,DISP_VIDEO1_PRE_YB_ADDR,DISP_VIDEO1_PRE_CB_ADDR,DISP_VIDEO1_POS_YT_ADDR,DISP_VIDEO1_POS_CT_ADDR,
+	DISP_VIDEO1_POS_YB_ADDR,DISP_VIDEO1_POS_CB_ADDR,DISP_VIDEO1_PPR_YT_ADDR,DISP_VIDEO1_PPR_CT_ADDR,DISP_VIDEO1_PPR_YB_ADDR,
+	DISP_VIDEO1_PPR_CB_ADDR,DISP_VIDEO1_STORE_Y_ADDR,DISP_VIDEO1_STORE_C_ADDR,DISP_VIDEO1_SRC_CTRL,DISP_VIDEO1_COEFF_UP,
+	DISP_VIDEO1_COEFF_ADDR,DISP_VIDEO1_F2F_START,DISP_VIDEO1_STA_F2F,DISP_VIDEO1_STA_DISP_NUM
+};
+
+static int dfreg_video1[9] =
+{
+	DISP_VIDEO2_CTRL,DISP_VIDEO2_X_POSITON,DISP_VIDEO2_Y_POSITON,DISP_VIDEO2_YT_ADDR,DISP_VIDEO2_CT_ADDR,DISP_VIDEO2_YB_ADDR,
+	DISP_VIDEO2_CB_ADDR,DISP_VIDEO2_SRC_CTRL,DISP_VIDEO2_STA_DISP_NUM
+};
+
+static int dfreg_video2[33] =
+{
+	DISP_VIDEO3_CTRL,DISP_VIDEO3_X_POSITON,DISP_VIDEO3_Y_POSITON,DISP_VIDEO3_SRC_X_CROP,DISP_VIDEO3_SRC_Y_CROP,DISP_VIDEO3_YV_RATIO,
+	DISP_VIDEO3_YH_RATIO,DISP_VIDEO3_CV_RATIO,DISP_VIDEO3_CH_RATIO,DISP_VIDEO3_Y_NOLINE_D,DISP_VIDEO3_C_NOLINE_D,
+	DISP_VIDEO3_Y_NOLINE_K,DISP_VIDEO3_C_NOLINE_K,DISP_VIDEO3_HOR_PHASE,DISP_VIDEO3_VER_PHASE,DISP_VIDEO3_YT_ADDR,
+	DISP_VIDEO3_CT_ADDR,DISP_VIDEO3_YB_ADDR,DISP_VIDEO3_CB_ADDR,DISP_VIDEO3_SRC_CTRL,DISP_VIDEO3_STA_DISP_NUM
+};
+#endif
+
+
+static  df_out_if_timing outputFormatInfo[] =
+{
+	//                 Frequency IsHD VSyncPol  HSyncPol   HTol   HActive HSyncFP HSyncWidth HSyncBP   VTol  VActline VSyncFP VSyncWidth VSyncBP VidType Vidrptr 
+	//(KHZ)   
+	{ 1,1280, 720,60, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   0,      0, 0,      0, 0,0, DISP_YUV_720P_60FPS,         "DISP_YUV_720P_60FPS"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,   1080,     2,       5,        15,    0,      0,1,      0, 0,0, DISP_YUV_1080I_30FPS,        "DISP_YUV_1080I_30FPS"       },
+	{ 1, 720, 480,60, 27000,    0,  1,         1,        858,   720,     16,      62,       60,      525,   480,      9,       6,        30,   0,      0, 0,      0, 0,0, DISP_YUV_480P,               "DISP_YUV_480P"              },
+	{ 1, 720, 480,30, 27000,    0,  1,         1,       1716,  1440,     38,     124,      114,      525,   480,      4,       3,        15,    0,      0,1,      1, 1,0, DISP_YUV_NTSC,               "DISP_YUV_NTSC"              },
+	{ 1,1280, 720,50, 74250,    1,  0,         0,       1980,  1280,    440,      40,      220,      750,   720,      5,       5,        20,    0,      0,0,      0, 0,0, DISP_YUV_720P_50FPS,         "DISP_YUV_720P_50FPS"        },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,   1080,     2,       5,        15,    0,      0,1,      0, 0,0, DISP_YUV_1080I_25FPS,        "DISP_YUV_1080I_25FPS"       },
+	{ 1, 720, 576,50, 27000,    0,  1,         1,        864,   720,     12,      64,       68,      625,   576,      5,       5,        39,    0,      0,0,      0, 0,0, DISP_YUV_576P,               "DISP_YUV_576P"              },
+	{ 1, 720, 576,25, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      625,   576,      2,       3,        19,    0,      0,1,      1, 1,1, DISP_YUV_PAL,                "DISP_YUV_PAL"               },
+	{ 1,1920,1080,60,148500,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_60FPS,        "DISP_YUV_1080P_60FPS"       },
+	{ 1,1920,1080,50,148500,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_50FPS,        "DISP_YUV_1080P_50FPS"       },
+	{ 1,1920,1080,24, 74250,    1,  0,         0,       2750,  1920,    638,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_24FPS,        "DISP_YUV_1080P_24FPS"       },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_25FPS,        "DISP_YUV_1080P_25FPS"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_30FPS,        "DISP_YUV_1080P_30FPS"       },
+	{ 1,1920,1080,25, 72000,    1,  1,         0,       2304,  1920,     32,     168,      184,     1250,  1080,     23,       5,        57,    0,      0,1,      0, 0,0, DISP_YUV_1080I_25FPS_AS,     "DISP_YUV_1080I_50FPS_F1"    },
+	{ 0, 640, 480,60, 25175,    0,  1,         1,        800,   640,     16,      96,       48,      525,   480,     10,       2,        33,    0,      0,      0,      0, 0,0, DISP_RGB_VGA_60FPS,          "DISP_RGB_VGA_60FPS"         },
+	{ 0, 800, 600,60, 40000,    0,  0,         0,       1056,   800,     40,     128,       88,      628,   600,      1,       4,        23,    0,      0,      0,      0, 0,0, DISP_RGB_SVGA_60FPS,         "DISP_RGB_SVGA_60FPS"        },
+	{ 0,1024, 768,60, 65000,    0,  1,         1,       1344,  1024,     24,     136,      160,      806,   768,      3,       6,        29,    0,      0,      0,      0, 0,0, DISP_RGB_XGA_60FPS,          "DISP_RGB_XGA_60FPS"         },
+	{ 0,1280,1024,60,108000,    1,  0,         0,       1688,  1280,     48,     112,      248,     1066,  1024,      1,       3,        38,    0,      0,      0,      0, 0,0, DISP_RGB_SXGA_60FPS,         "DISP_RGB_SXGA_60FPS"        },
+	{ 0,1600,1200,60,162000,    1,  0,         0,       2160,  1600,     64,     192,      304,     1250,  1200,      1,       3,        46,    0,      0,      0,      0, 0,0, DISP_RGB_UXGA_60FPS,         "DISP_RGB_UXGA_60FPS"        },
+	{ 0,1280, 720,60, 74375,    1,  0,         0,       1664,  1280,     56,     136,      192,      746,   720,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_720P_60FPS,         "DISP_RGB_720P_60FPS"        },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      312,   288,      2,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M1,        "DISP_1440x288P_50_M1"       },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      313,   288,      3,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M2,        "DISP_1440x288P_50_M2"       },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      314,   288,      4,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M3,        "DISP_1440x288P_50_M3"       },
+	{ 1, 720, 576,25, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      625,   576,      2,       3,        19,    0,      0,      1,      3, 0,1, DISP_2880x576I_50,           "DISP_2880x576I_50"          },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      312,   288,      2,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M1,        "DISP_2880x288P_50_M1"       },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      313,   288,      3,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M2,        "DISP_2880x288P_50_M2"       },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      314,   288,      4,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M3,        "DISP_2880x288P_50_M3"       },
+	{ 1, 720, 576,50, 54000,    0,  1,         1,       1728,  1440,     24,     128,      136,      625,   576,      5,       5,        39,    0,      0,      0,      1, 0,0, DISP_1440x576P_50,           "DISP_1440x576P_50"          },
+	{ 1, 720, 240,60, 27000,    0,  1,         1,       1716,  1440,     38,     124,      114,      262,   240,      4,       3,        15,    0,      0,      0,      1, 0,0, DISP_1440x240P_60_M1,        "DISP_1440x240P_60_M1"       },
+	{ 1, 720, 240,60, 27000,    0,  1,         1,       1716,  1440,     38,     124,      114,      263,   240,      5,       3,        15,    0,      0,      0,      1, 0,0, DISP_1440x240P_60_M2,        "DISP_1440x240P_60_M2"       },
+	{ 1, 720, 480,30, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      525,   480,      4,       3,        15,    0,      0,      1,      3, 0,0, DISP_2880x480I_60,           "DISP_2880x480I_60"          },
+	{ 1, 720, 240,60, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      262,   240,      4,       3,        15,    0,      0,      0,      3, 0,0, DISP_2880x240P_60_M1,        "DISP_2880x240P_60_M1"       },
+	{ 1, 720, 240,60, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      263,   240,      5,       3,        15,    0,      0,      0,      3, 0,0, DISP_2880x240P_60_M2,        "DISP_2880x240P_60_M2"       },
+	{ 1, 720, 480,60, 54000,    0,  1,         1,       1716,  1440,     32,     124,      120,      525,   480,      9,       6,        30,    0,      0,      0,      1, 0,0, DISP_1440x480P_60,           "DISP_1440x480P_60"          },
+	{ 0, 640, 480,60, 25175,    0,  1,         1,        800,   640,      8,      96,       40,      525,   480,     10,       2,        33,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_640x480_60,     "DISP_RGB_DMT_640x480_60"    },
+	{ 0, 640, 480,75, 31500,    0,  1,         1,        840,   640,     16,      64,      120,      500,   480,      1,       3,        16,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_640x480_75,     "DISP_RGB_DMT_640x480_75"    },
+	{ 0, 800, 600,60, 40000,    0,  0,         0,       1056,   800,     40,     128,       88,      628,   600,      1,       4,        23,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_800x600_60,     "DISP_RGB_DMT_800x600_60"    },
+	{ 0, 800, 600,75, 49500,    0,  0,         0,       1056,   800,     16,      80,      160,      625,   600,      1,       3,        21,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_800x600_75,     "DISP_RGB_DMT_800x600_75"    },
+	{ 0, 848, 480,60, 33750,    0,  0,         0,       1088,   848,     16,     112,      112,      517,   480,      6,       8,        23,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_848x480_60,     "DISP_RGB_DMT_848x480_60"    },
+	{ 0,1152, 864,75,108000,    1,  0,         0,       1600,  1152,     64,     128,      256,      900,   864,      1,       3,        32,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1152x864_75,    "DISP_RGB_DMT_1152x864_75"   },
+	{ 0,1280, 768,60, 68250,    1,  1,         0,       1440,  1280,     48,      32,       80,      790,   768,      3,       7,        12,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x768_60,    "DISP_RGB_DMT_1280x768_60"   },
+	{ 0,1280, 960,60,108000,    1,  0,         0,       1800,  1280,     96,     112,      312,     1000,   960,      1,       3,        36,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x960_60,    "DISP_RGB_DMT_1280x960_60"   },
+	{ 0,1280,1024,60,108000,    1,  0,         0,       1688,  1280,     48,     112,      248,     1066,  1024,      1,       3,        38,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x1024_60,   "DISP_RGB_DMT_1280x1024_60"  },
+	{ 0,1360, 768,60, 85500,    1,  0,         0,       1792,  1360,     64,     112,      256,      795,   768,      3,       6,        18,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1360x768_60,    "DISP_RGB_DMT_1360x768_60"   },
+	{ 0,1440, 900,60,106500,    1,  0,         1,       1904,  1440,     80,     152,      232,      934,   900,      3,       6,        25,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1440x900_60,    "DISP_RGB_DMT_1440x900_60"   },
+	{ 0, 640, 480,75, 30625,    0,  0,         1,        816,   640,     24,      64,       88,      502,   480,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_640x480_75,     "DISP_RGB_CVT_640x480_75"    },
+	{ 0, 800, 600,60, 38125,    0,  0,         1,       1024,   800,     32,      80,      112,      622,   600,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_60,     "DISP_RGB_CVT_800x600_60"    },
+	{ 0, 800, 600,75, 48875,    0,  0,         1,       1040,   800,     40,      80,      120,      627,   600,      1,       3,        23,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_75,     "DISP_RGB_CVT_800x600_75"    },
+	{ 0,1024, 768,60, 64125,    1,  0,         1,       1344,  1024,     56,     112,      168,      802,   768,      1,       3,        30,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x768_60,    "DISP_RGB_CVT_1024x768_60"   },
+	{ 0,1280,1024,60,108875,    1,  0,         1,       1712,  1280,     80,     136,      216,     1060,  1024,      1,       3,        41,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x1024_60,   "DISP_RGB_CVT_1280x1024_60"  },
+	{ 0, 848, 480,60, 31500,    0,  0,         1,       1056,   848,     16,      88,      104,      497,   480,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_60,     "DISP_RGB_CVT_848x480_60"    },
+	{ 0, 848, 480,75, 40875,    0,  0,         1,       1088,   848,     32,      88,      120,      502,   480,      1,       3,        18,   0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_75,     "DISP_RGB_CVT_848x480_75"    },
+	{ 0,1024, 576,60, 46875,    1,  0,         1,       1312,  1024,     40,     104,      144,      597,   576,      1,       3,        17,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_60,    "DISP_RGB_CVT_1024x576_60"   },
+	{ 0,1024, 576,75, 60625,    1,  0,         1,       1344,  1024,     56,     104,      160,      602,   576,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_75,    "DISP_RGB_CVT_1024x576_75"   },
+	{ 0,1280, 720,60, 74375,    1,  0,         1,       1664,  1280,     56,     136,      192,      746,   720,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_60,    "DISP_RGB_CVT_1280x720_60"   },
+	{ 0,1280, 720,75, 95625,    1,  0,         1,       1696,  1280,     72,     136,      208,      752,   720,      1,       3,        28,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_75,    "DISP_RGB_CVT_1280x720_75"   },
+	{ 0, 640, 400,75, 25000,    0,  0,         1,        800,   640,     16,      64,       80,      418,   400,      1,       3,        14,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_640x400_75,     "DISP_RGB_CVT_640x400_75"    },
+	{ 0, 768, 480,60, 28625,    0,  0,         1,        960,   768,     16,      80,       96,      497,   480,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_60,     "DISP_RGB_CVT_768x480_60"    },
+	{ 0, 768, 480,75, 37250,    0,  0,         1,        992,   768,     32,      80,      112,      502,   480,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_75,     "DISP_RGB_CVT_768x480_75"    },
+	{ 0,1024, 640,60, 52750,    1,  0,         1,       1328,  1024,     48,     104,      152,      663,   640,      1,       3,        19,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_60,    "DISP_RGB_CVT_1024x640_60"   },
+	{ 0,1024, 640,75, 67375,    1,  0,         1,       1344,  1024,     56,     104,      160,      669,   640,      1,       3,        25,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_75,    "DISP_RGB_CVT_1024x640_75"   },
+	{ 0,1280, 800,75,107250,    1,  0,         1,       1712,  1280,     80,     136,      216,      835,   800,      1,       3,        31,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x800_75,    "DISP_RGB_CVT_1280x800_75"   },
+	{ 0, 800, 600,60, 34375,    0,  1,         0,        928,   800,     32,      32,       64,      618,   600,      1,       3,        14,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_RED,    "DISP_RGB_CVT_800x600_RED"   },
+	{ 0,1024, 768,60, 54500,    1,  1,         0,       1152,  1024,     32,      32,       64,      790,   768,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x768_RED,   "DISP_RGB_CVT_1024x768_RED"  },
+	{ 0,1280, 960,60, 83375,    1,  1,         0,       1408,  1280,     32,      32,       64,      988,   960,      1,       3,        24,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x960_RED,   "DISP_RGB_CVT_1280x960_RED"  },
+	{ 0, 848, 480,60, 28875,    0,  1,         0,        976,   848,     32,      32,       64,      494,   480,      1,       3,        10,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_RED,    "DISP_RGB_CVT_848x480_RED"   },
+	{ 0,1024, 576,60, 40875,    1,  1,         0,       1152,  1024,     32,      32,       64,      593,   576,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_RED,   "DISP_RGB_CVT_1024x576_RED"  },
+	{ 0,1280, 720,60, 62500,    1,  1,         0,       1408,  1280,     32,      32,       64,      741,   720,      1,       3,        17,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_RED,   "DISP_RGB_CVT_1280x720_RED"  },
+	{ 0,1600, 900,60, 96000,    1,  1,         0,       1728,  1600,     32,      32,       64,      926,   900,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1600x900_RED,   "DISP_RGB_CVT_1600x900_RED"  },
+	{ 0, 768, 480,60, 26500,    0,  1,         0,        896,   768,     32,      32,       64,      494,   480,      1,       3,        10,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_RED,    "DISP_RGB_CVT_768x480_RED"   },
+	{ 0,1024, 640,60, 45500,    1,  1,         0,       1152,  1024,     32,      32,       64,      659,   640,      1,       3,        15,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_RED,   "DISP_RGB_CVT_1024x640_RED"  },
+	{ 0,1280, 800,60, 69500,    1,  1,         0,       1408,  1280,     32,      32,       64,      823,   800,      1,       3,        19,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x800_RED,   "DISP_RGB_CVT_1280x800_RED"  },
+	{ 0,1600,1000,60,106625,    1,  1,         0,       1728,  1600,     32,      32,       64,     1029,  1000,      1,       3,        25,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1600x1000_RED,  "DISP_RGB_CVT_1600x1000_RED" },
+	{ 1,  64, 64, 60, 11111,    0,  1,         1,        128,    64,     20,      10,       34,      128,    64,      1,       3,        60,    0,      0,      0,      0, 0,0, DISP_64x64,"DISP_64x64"},
+	{ 1,1366, 768,60, 85500,    1,  0,         0,       1792,  1366,     70,      143,      213,     798,   768,      3,       3,        24,    0,      0,      0,      0, 0,0, DISP_VGA_1366x768,"DISP_VGA_1366x768"},
+	{ 1, 720, 480,60, 54000,    0,  1,         1,        858,   720,     16,      62,       60,      525,   480,      9,       6,        30,    1,     45,      0,      0, 0,0, DISP_YUV_480P_3D,               "DISP_YUV_480P_3D"              },
+	//{ 1, 720, 480,30, 54000,    0,  1,         1,       1716,  1440,     38,     124,      114,      525,   480,      4,       3,        15,    1,      23,      1,      1, 1,0, DISP_YUV_NTSC_3D,               "DISP_YUV_NTSC_3D"              },
+	{ 1, 720, 480,30, 54000,    0,  1,         1,       858,   720,     16,      62,       60,      525,   480,      4,       3,        15,    1,      23,      1,      1, 1,0, DISP_YUV_NTSC_3D,               "DISP_YUV_NTSC_3D"              },
+	{ 1, 720, 576,50, 54000,    0,  1,         1,        864,   720,     12,      64,       68,      625,   576,      5,       5,        39,    1,      49,      0,      0, 0,0, DISP_YUV_576P_3D,               "DISP_YUV_576P_3D"              },
+	{ 1, 720, 576,25, 54000,    0,  1,         1,       1728,  1440,     24,     126,      138,      625,   576,      2,       3,        19,    1,      25,      1,      1, 1,1, DISP_YUV_PAL_3D,                "DISP_YUV_PAL_3D"               },
+	{ 1,1280, 720,60, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   1,      30, 		0,      0, 0,0, DISP_YUV_720P_60FPS_3D,         "DISP_YUV_720P_60FPS_3D"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_30FPS_3D,        "DISP_YUV_1080P_30FPS_3D"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,   1080,     2,       5,        15,    1,      23,		1,      0, 0,0, DISP_YUV_1080I_30FPS_3D,        "DISP_YUV_1080I_30FPS_3D"       },
+	{ 1,1280, 720,50, 74250,    1,  0,         0,       1980,  1280,    440,      40,      220,      750,   720,      5,       5,        20,    1,      30,		0,      0, 0,0, DISP_YUV_720P_50FPS_3D,         "DISP_YUV_720P_50FPS_3D"        },
+	{ 1,1920,1080,24, 74250,    1,  0,         0,       2750,  1920,    638,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_24FPS_3D,        "DISP_YUV_1080P_24FPS_3D"       },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_25FPS_3D,        "DISP_YUV_1080P_25FPS_3D"       },
+	{ 1,1280, 720,30, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   1,      30, 		0,      0, 0,0, DISP_YUV_720P_30FPS_3D,         "DISP_YUV_720P_30FPS_3D"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  530,      4,       5,        36,    1,      20,		0,      0, 0,0, DISP_YUV_1080P_30FPS_3D_TEMP,        "DISP_YUV_1080P_30FPS_3D_TEMP"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     500,   250*2,     4,       5,        36,    1,      17,		1,      0, 0,0, DISP_YUV_1080I_30FPS_3D_TEMP,        "DISP_YUV_1080I_30FPS_3D_TEMP"       },
+	{ 0, 640, 480,60, 25175,	0,	1,		   1,		 800,	640,	 16,	  96,		48, 	 525,	480,	 10,	   2,		 33,	0,		0,		0,		0, 0,0, DISP_RGB_VGA_59P94FPS,			"DISP_RGB_VGA_59P94FPS" 		},
+	{ 0,1600,1200,60,162000,	1,	0,		   0,		2160,  1600,	 64,	 192,	   304, 	1250,	1200,	  1,	   3,		 46,	0,		0,		0,		0, 0,0, DISP_1600x1200_60FPS,		   "DISP_1600x1200_60FPS"		  }
+	//              Frequency IsHD VSyncPol  HSyncPol   HTol   HActive HSyncFP HSyncWidth HSyncBP   VTol  VActline VSyncFP VSyncWidth VSyncBP 3dEn 	VactSpace 	VidType 	Vidrptr
+};
+
+
+df_reg_para dfreg;
+
+DF_OUTPUT_CONFIG_t df_output_config = {
+	.gfx_output = {0,0},
+	.vid_output = {0,1,0},
+	.output_mode = {DF_OUTPUT_YPBPR, DF_OUTPUT_YPBPR},
+};
+
+static int tve_2_df[] = {
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_576P,
+	DISP_YUV_480P,
+	DISP_YUV_720P_50FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080I_25FPS,
+	DISP_YUV_1080I_30FPS,
+
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_PAL,
+	DISP_YUV_PAL,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_25FPS,
+	DISP_YUV_1080P_30FPS,
+	DISP_YUV_1080P_50FPS,
+	DISP_YUV_1080P_60FPS,
+
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_NTSC,
+	DISP_YUV_NTSC,
+	DISP_YUV_576P,
+	DISP_YUV_480P,
+	DISP_YUV_480P,
+	DISP_YUV_480P,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_60FPS,
+
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_720P_50FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+
+	DISP_YUV_1080I_25FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_YUV_1080I_30FPS,
+
+	DISP_YUV_720P_50FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_24FPS,
+
+	DISP_RGB_VGA_60FPS,
+	DISP_RGB_CVT_800x600_60,
+	DISP_RGB_XGA_60FPS,
+	DISP_RGB_CVT_1280x720_60,
+	DISP_RGB_DMT_800x600_60,
+	DISP_RGB_DMT_1440x900_60,
+	DISP_RGB_DMT_1280x1024_60,
+	DISP_RGB_DMT_1360x768_60,
+	DISP_YUV_1080P_30FPS,
+	DISP_YUV_1080P_60FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_VGA_1366x768,
+	DISP_RGB_VGA_59P94FPS,
+	DISP_1600x1200_60FPS,
+};
+#if 0
+static int tve_2_clock[] = {
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_576P_50Hz,
+	_YUV_480P_60Hz,
+	_YUV_720P_50Hz,
+	_YUV_720P_60Hz,
+	_YUV_1080I_50Hz,
+	_YUV_1080I_60Hz,
+
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_PAL,
+	_YUV_PAL,
+	_YUV_1080P_24Hz,
+	_YUV_1080P_25Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_50Hz,
+	_YUV_1080P_60Hz,
+
+	_RGB_DMT_640x480_60Hz,
+	_RGB_DMT_1024x768_60Hz,
+	_RGB_DMT_1440x900_60Hz,
+	_RGB_DMT_1280x1024_60Hz,
+	_RGB_DMT_1360x768_60Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080I_60Hz,
+};
+#endif
+enum _HDMI_VIDEO_TIMING_
+{
+	HDMI_NONE_STD_VID_FORMAT       =0,
+	HDMI_V640x480p_60Hz            =1,
+	HDMI_V720x480p_60Hz_4x3        =2,
+	HDMI_V720x480p_60Hz_16x9       =3,
+	HDMI_V720x480i_60Hz_4x3        =4,
+	HDMI_V720x480i_60Hz_16x9       =5,
+	HDMI_V720x576i_50Hz_4x3        =6,
+	HDMI_V720x576i_50Hz_16x9       =7,
+	HDMI_V720x576p_50Hz_4x3        =8,
+	HDMI_V720x576p_50Hz_16x9       =9,
+	HDMI_V1280x720p_50Hz           =10,
+	HDMI_V1280x720p_60Hz           =11,
+	HDMI_V1920x1080i_50Hz          =12,
+	HDMI_V1920x1080i_60Hz          =13,
+	HDMI_V1920x1080p_50Hz          =14,
+	HDMI_V1920x1080p_60Hz          =15,
+	HDMI_V1920x1080p_24Hz          =16,
+
+	HDMI_V800x600p_60Hz		=17,
+	HDMI_V1024x768p_60Hz		= 18,
+	HDMI_V1280x720p_RGB_60Hz           =19,
+	HDMI_V800x480p_60Hz		=20,
+	HDMI_V1440x900p_60Hz		=21,
+	HDMI_V1280x1024p_60Hz	=22,
+	HDMI_V1360x768p_60Hz		=23,
+	HDMI_V1920x1080p_RGB_30Hz          =24,
+	HDMI_V1920x1080p_RGB_60Hz          =25,
+	HDMI_V1920x1080i_RGB_30Hz          =26,
+	HDMI_V1366x768p_60Hz		=27,
+};
+
+enum _HDMI_VIDEO_ASPECT_
+{
+	HDMI_ASPECT_4x3,
+	HDMI_ASPECT_16x9,
+};
+#if 0
+static int tve_2_hdmi[][2] = {
+	{HDMI_V720x576i_50Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x480i_60Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x576p_50Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x480p_60Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V1280x720p_50Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1280x720p_60Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080i_50Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080i_60Hz,HDMI_ASPECT_16x9},
+
+	{HDMI_V720x576i_50Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x480i_60Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x576i_50Hz_4x3,HDMI_ASPECT_4x3},
+	{HDMI_V720x576i_50Hz_4x3,HDMI_ASPECT_4x3},
+
+	{HDMI_V1920x1080p_24Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_50Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_60Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_50Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_60Hz,HDMI_ASPECT_16x9},
+
+	{HDMI_V640x480p_60Hz,HDMI_ASPECT_4x3},
+
+#if 1
+	{HDMI_V800x600p_60Hz,HDMI_ASPECT_4x3},
+	{HDMI_V1024x768p_60Hz,HDMI_ASPECT_4x3},
+	{HDMI_V1280x720p_RGB_60Hz,HDMI_ASPECT_16x9},
+	{HDMI_V800x480p_60Hz,-1},
+	{HDMI_V1440x900p_60Hz,-1},
+	{HDMI_V1280x1024p_60Hz,HDMI_ASPECT_4x3},
+	{HDMI_V1360x768p_60Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_RGB_30Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080p_RGB_60Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1920x1080i_RGB_30Hz,HDMI_ASPECT_16x9},
+	{HDMI_V1366x768p_60Hz,HDMI_ASPECT_16x9},
+#endif
+};
+#endif
+void __df_update_start(void)
+{
+	df_write(dfreg_ctrl[0], 1);
+	df_write(dfreg_ctrl[2], 1);
+}
+
+void __df_update_end(void)
+{
+	df_write(dfreg_ctrl[0], 0);
+	df_write(dfreg_ctrl[2], 0);
+}
+
+void __df_update_outif_start(void)
+{
+	df_write(dfreg_ctrl[1], 1);
+}
+
+void __df_update_outif_end(void)
+{
+	df_write(dfreg_ctrl[1], 0);
+}
+
+void __update_vid_handshake_start(void)
+{
+	int wait_times = 10;
+
+	do{
+		df_write(VPP_REG_GLB_CTRL_CPU_WQ,1);
+		wait_times--;
+		mdelay(10);
+		if (wait_times <= 0){
+			printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+			return;
+		}
+	}while((df_read(VPP_REG_GLB_CTRL_HAND_STATUS)&0x03)!=0x01);
+}
+
+void __update_vid_handshake_finish(void)
+{
+	df_write(VPP_REG_GLB_CTRL_CPU_WQ,0);
+}
+
+void DFSetOutIFVideoFmt(int OutIFId, DF_VIDEO_FORMAT Format, int En)
+{
+	//For Safety Format Switching It's better Disable the output clk First
+	df_outif_reg *OutIFReg= NULL;
+
+	OutIFId = OutIFId & 0x1;
+	OutIFReg = &dfreg.OutIF[OutIFId];
+
+	OutIFReg->reg_tg_ctrl.val = df_read(dfreg_outif[OutIFId][0]);
+	OutIFReg->reg_tg_x_size.val = df_read(dfreg_outif[OutIFId][1]);
+	OutIFReg->reg_tg_y_size.val = df_read(dfreg_outif[OutIFId][2]);
+	OutIFReg->reg_tg_hsync.val = df_read(dfreg_outif[OutIFId][3]);
+	OutIFReg->reg_tg_vsync.val = df_read(dfreg_outif[OutIFId][4]);
+
+	OutIFReg->reg_tg_ctrl.bits.tg_en=En;
+	OutIFReg->reg_tg_ctrl.bits.tg_is_hd=outputFormatInfo[Format].mIsHD&0x01;
+	OutIFReg->reg_tg_ctrl.bits.tg_is_interlaced=0x01&outputFormatInfo[Format].mVidType&0x01;
+	OutIFReg->reg_tg_ctrl.bits.tg_is_pal=outputFormatInfo[Format].mPALFmt&0x01;
+	OutIFReg->reg_tg_ctrl.bits.tg_dither_mode=0;
+	OutIFReg->reg_tg_ctrl.bits.tg_hsync_pol=outputFormatInfo[Format].mHSyncPol&0x01;
+	OutIFReg->reg_tg_ctrl.bits.tg_vsync_pol=outputFormatInfo[Format].mVSyncPol&0x01;
+	OutIFReg->reg_tg_ctrl.bits.tg_dither_ena=1;
+	OutIFReg->reg_tg_ctrl.bits.tg_3d_act_space=outputFormatInfo[Format].m3dVactSpace&0xff;
+	OutIFReg->reg_tg_ctrl.bits.tg_3d_en=outputFormatInfo[Format].m3dEn&0x01;
+
+	OutIFReg->reg_tg_hsync.bits.tg_hsync_front_porch=outputFormatInfo[Format].mHSyncFP&0x3ff;
+	OutIFReg->reg_tg_hsync.bits.tg_hsync_width=outputFormatInfo[Format].mHSyncWidth&0x3ff;
+	OutIFReg->reg_tg_hsync.bits.tg_hsync_back_porch=outputFormatInfo[Format].mHSyncBP&0x3ff;
+
+	OutIFReg->reg_tg_vsync.bits.tg_vsync_front_porch=outputFormatInfo[Format].mVSyncFP&0xff;
+	OutIFReg->reg_tg_vsync.bits.tg_vsync_width=outputFormatInfo[Format].mVSyncWidth&0xff;
+	OutIFReg->reg_tg_vsync.bits.tg_vsync_back_porch=outputFormatInfo[Format].mVSyncBP&0xff;
+
+
+	OutIFReg->reg_tg_x_size.bits.tg_htotal=outputFormatInfo[Format].mHRes&0x1fff;
+	OutIFReg->reg_tg_x_size.bits.tg_hactive_width=outputFormatInfo[Format].mHActive&0xfff;
+	OutIFReg->reg_tg_y_size.bits.tg_vtotal=outputFormatInfo[Format].mVRes&0x1fff;
+	OutIFReg->reg_tg_y_size.bits.tg_vactive_height= outputFormatInfo[Format].mVActline&0xfff;
+
+	if(outputFormatInfo[Format].mIsYUVorRGB){
+		OutIFReg->reg_tg_vga_level.bits.tg_vga_black_level=0;
+		OutIFReg->reg_tg_vga_level.bits.tg_vga_white_level=1023;
+	}
+	else{
+		OutIFReg->reg_tg_vga_level.bits.tg_vga_black_level=252;
+		OutIFReg->reg_tg_vga_level.bits.tg_vga_white_level=800;
+	}
+
+	OutIFReg->reg_tg_sta_line.bits.tg_v_start_line_num=6;
+
+	df_write(dfreg_outif[OutIFId][1], dfreg.OutIF[OutIFId].reg_tg_x_size.val);
+	df_write(dfreg_outif[OutIFId][2], dfreg.OutIF[OutIFId].reg_tg_y_size.val);
+	df_write(dfreg_outif[OutIFId][3], dfreg.OutIF[OutIFId].reg_tg_hsync.val);
+	df_write(dfreg_outif[OutIFId][4], dfreg.OutIF[OutIFId].reg_tg_vsync.val);
+	df_write(dfreg_outif[OutIFId][5], dfreg.OutIF[OutIFId].reg_tg_vga_level.val);
+	df_write(dfreg_outif[OutIFId][6], dfreg.OutIF[OutIFId].reg_tg_sta_line.val);
+	df_write(dfreg_outif[OutIFId][0], dfreg.OutIF[OutIFId].reg_tg_ctrl.val);
+	return;
+}
+
+/*void DFOutIFEna(int OutIFId, int IsEna)
+  {
+  df_outif_reg *OutIFReg= NULL;
+
+  OutIFId = OutIFId & 0x1;
+  OutIFReg = &dfreg.OutIF[OutIFId];
+  OutIFReg->df_outif_control_reg.val = df_read(dfreg_outif[OutIFId][0]);
+
+  OutIFReg->df_outif_control_reg.bits.iDispEn = IsEna;
+
+  df_write(dfreg_outif[OutIFId][0], OutIFReg->df_outif_control_reg.val);
+
+  return;
+  }*/
+
+void DFSetZOrder(int OutIFId, int Gfx1ZOrder, int Gfx2ZOrder, int Video1ZOrder, int Video2ZOrder)
+{
+	df_compositor_reg *Reg= NULL;
+
+	Reg = &dfreg.Comp;
+	Reg->reg_comp_b2_z_order.val = df_read(dfreg_comp[1]);
+
+	Reg->reg_comp_b2_z_order.bits.blending2_gfx1_z_order   = Gfx1ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_gfx1_z_order   = Gfx2ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_video1_z_order = Video1ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_video2_z_order = Video2ZOrder;
+
+	df_write(dfreg_comp[1], Reg->reg_comp_b2_z_order.val);
+	return;
+}
+
+void DFSetBackGroud(int OutIFId, unsigned char BGY, unsigned char BGU, unsigned char BGV)
+{
+	df_compositor_reg *Reg= NULL;
+
+	Reg = &dfreg.Comp;
+	Reg->reg_comp_b2_back_ground.val = df_read(dfreg_comp[0]);
+
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_y = BGY<<2;
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_u = BGU<<2;
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_v = BGV<<2;
+
+	df_write(dfreg_comp[0], Reg->reg_comp_b2_back_ground.val);
+	return;
+}
+
+void DFGfxEna(int GfxId, int IsEna, int IsRGB2YUVEna)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	if(DF_OUTPUT_VGA == df_output_config.output_mode[df_output_config.gfx_output[GfxId]]){
+		IsRGB2YUVEna = 0;
+	}
+	else{
+		IsRGB2YUVEna = 1;
+	}
+
+	if(IsEna)
+	{
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena = (1 << df_output_config.gfx_output[GfxId]);
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_yuv_conv_ena = IsRGB2YUVEna;
+	}
+	else
+	{
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena = 0;
+	}
+
+	df_printf("layer_output.gfx_output[%d] = %d\n",GfxId,df_output_config.gfx_output[GfxId]);
+	df_printf("Reg->df_gfx_control_reg.bits.iGfxEna = %d\n",Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena);
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+void DFGfxSetAlpha(int GfxId, unsigned short DefaultAlpha, unsigned short ARGB1555Alpha0, unsigned short ARGB1555Alpha1)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_alpha_ctrl.val = df_read(dfreg_gfx[GfxId][1]);
+
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha   = DefaultAlpha & 0x3ff;
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a0 = ARGB1555Alpha0 & 0x3ff;
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a1 = ARGB1555Alpha1 & 0x3ff;
+
+	df_write(dfreg_gfx[GfxId][1], Reg->reg_gfx_ui_alpha_ctrl.val);
+	return;
+}
+
+void DFGfxGetAlpha(int GfxId, unsigned short *DefaultAlpha, unsigned short *ARGB1555Alpha0, unsigned short *ARGB1555Alpha1)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+
+	Reg->reg_gfx_ui_alpha_ctrl.val = df_read(dfreg_gfx[GfxId][2]);
+
+	*DefaultAlpha = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha;
+	*ARGB1555Alpha0 = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a0;
+	*ARGB1555Alpha1 = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a1;
+
+	return;
+}
+
+void DFGfxSetColorKey(int GfxId, unsigned char KeyRMin, unsigned char KeyRMax, unsigned char KeyGMin, unsigned char KeyGMax, unsigned char KeyBMin, unsigned char KeyBMax)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_key_red.val = df_read(dfreg_gfx[GfxId][3]);
+	Reg->reg_gfx_ui_key_blue.val = df_read(dfreg_gfx[GfxId][4]);
+	Reg->reg_gfx_ui_key_green.val = df_read(dfreg_gfx[GfxId][5]);
+
+	Reg->reg_gfx_ui_key_red.bits.gfx_ui_r_min   = KeyRMin;
+	Reg->reg_gfx_ui_key_red.bits.gfx_ui_r_max   = KeyRMax;
+	Reg->reg_gfx_ui_key_blue.bits.gfx_ui_b_min  = KeyBMin;
+	Reg->reg_gfx_ui_key_blue.bits.gfx_ui_b_max  = KeyBMax;
+	Reg->reg_gfx_ui_key_green.bits.gfx_ui_g_min = KeyGMin;
+	Reg->reg_gfx_ui_key_green.bits.gfx_ui_g_max = KeyGMax;
+
+	df_write(dfreg_gfx[GfxId][3], Reg->reg_gfx_ui_key_red.val);
+	df_write(dfreg_gfx[GfxId][4], Reg->reg_gfx_ui_key_blue.val);
+	df_write(dfreg_gfx[GfxId][5], Reg->reg_gfx_ui_key_green.val);
+
+	return;
+}
+
+void DFGfxColorKeyEna(int GfxId,int IsEna)
+{df_gfx_reg*Reg = NULL;
+
+	GfxId = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	Reg->reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en = IsEna;
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+
+void DFGfxOpaqueOnOff(int GfxId,int OnOff)
+{
+	df_gfx_reg*Reg = NULL;
+
+	GfxId = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	Reg->reg_gfx_ui_ctrl.bits.gfx_ui_opaque = OnOff;
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+
+#define SCALOR_COEF_ADDR 0x0d000000
+void DFGfxScalorCoef(void)
+{
+
+	memcpy((char*)SCALOR_COEF_ADDR,cof3tap,sizeof(cof3tap));
+	memcpy((char*)(SCALOR_COEF_ADDR+0x2000),cof4tap,sizeof(cof4tap));
+	memcpy((char*)(SCALOR_COEF_ADDR+0x4000),cof6tap,sizeof(cof6tap));
+	df_write(dfreg_ctrl[9],(unsigned int)SCALOR_COEF_ADDR);
+	df_write(dfreg_ctrl[10],(unsigned int)(SCALOR_COEF_ADDR+0x2000));
+	df_write(dfreg_ctrl[11],(unsigned int)(SCALOR_COEF_ADDR+0x4000));
+	//df_write(dfreg_ctrl[9],(unsigned int)cof3tap);
+	//df_write(dfreg_ctrl[10],(unsigned int)cof4tap);
+	//df_write(dfreg_ctrl[11],(unsigned int)cof6tap);
+	df_printf("cof3tap=%x,cof4tap=%x,cof6tap=%x\n",(unsigned int)cof3tap,(unsigned int)cof4tap,(unsigned int)cof6tap);
+}
+
+
+//Analog Video
+typedef enum _DAC0_MODE_
+{
+	_dac0_rgb0 =0,
+	_dac0_rgb1 =1,
+	_dac0_tve0_ypbpr =2,
+	_dac0_tve0_cvbs_svideo =3,
+	_dac0_tve1_ypbpr =4,
+	_dac0_tve1_cvbs_svideo  =5,
+}DAC0_MODE;
+
+typedef enum _DAC1_MODE_
+{
+	_dac1_rgb1 = 0,
+	_dac1_tve1_ypbpr =1,
+	_dac1_tve1_cvbs_svideo  =2,
+}DAC1_MODE;
+
+
+
+#define REG_PINMUX_I2C		(CNC1900_PIN_MUX + 0x004)
+#define REG_PINMUX_DISP	(CNC1900_PIN_MUX + 0x014)
+#if 0
+void pinmux_set_dac1mode(DAC1_MODE Mode)
+{
+	unsigned short reg_val = 0;
+
+	reg_val = df_read16(REG_PINMUX_I2C);
+
+	switch(Mode)
+	{
+		case _dac1_tve0_ypbpr:
+			//			pinmux_base[REG_PINMUX_DISP>>1] &= (0<<8);
+			df_write16(REG_PINMUX_DISP, (0<<8));
+			break;
+		case _dac1_tve1_ypbpr:
+			//			pinmux_base[REG_PINMUX_DISP>>1] = (5<<8);
+			df_write16(REG_PINMUX_DISP, (5<<8));
+			break;
+		case _dac1_disp0_rgb:
+			//			pinmux_base[REG_PINMUX_DISP>>1] = (1<<8);
+			//			pinmux_base[REG_PINMUX_I2C>>1] |= (1<<1);
+			//			pinmux_base[REG_PINMUX_I2C>>1] |= (1<<2);
+			//			pinmux_base[REG_PINMUX_I2C>>1] |= (1<<3);
+			df_write16(REG_PINMUX_DISP, (1<<8));
+			df_write16(REG_PINMUX_I2C, reg_val |0xe);
+			break;
+		case _dac1_disp1_rgb:
+			//			pinmux_base[REG_PINMUX_DISP>>1] = (6<<8);
+			//			pinmux_base[REG_PINMUX_I2C>>1] |= (1<<1);
+			//			pinmux_base[REG_PINMUX_I2C>>1] |= (1<<2);
+			//			pinmux_base[REG_PINMUX_I2C>>1] &= ~(1<<3);
+			df_write16(REG_PINMUX_DISP, (6<<8));
+			df_write16(REG_PINMUX_I2C, reg_val |0x6);
+			break;
+		case _dac1_tve1_cvbs:
+			//			pinmux_base[REG_PINMUX_DISP>>1] = (4<<8);
+			df_write16(REG_PINMUX_DISP, reg_val & (4<<8));
+			break;
+	}
+
+	return;
+}
+#endif
+int pinmux_set_dac0mode(DAC0_MODE Mode)
+{
+
+	//reg_val = df_read(REG_PINMUX_I2C);
+	switch(Mode)
+	{
+		case _dac0_rgb0:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<9);
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)| (1<<9));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)& (~(1<<10)));
+			break;
+		case _dac0_rgb1:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<9);
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);	
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)| (1<<9));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)| (1<<10));
+			break;
+		case _dac0_tve0_ypbpr:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<8);
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<8));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<9)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)& (~(1<<10)));
+			break;
+		case _dac0_tve0_cvbs_svideo:
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<8));
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<8)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<9)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<10)));
+			break;
+		case _dac0_tve1_ypbpr:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<8);
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<8));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<9)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<10));
+			break;
+		case _dac0_tve1_cvbs_svideo:
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<8));
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<8)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<9)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<10));
+			break;
+	}
+
+	return 0;
+}
+
+int pinmux_set_dac1mode(DAC1_MODE Mode)
+{
+	switch(Mode){
+		case _dac1_rgb1:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<12);	
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<12));
+			break;
+		case _dac1_tve1_ypbpr:
+			//pinmux_base[REG_PINMUX_DISP>>2] |= (1<<11);
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<12));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)|(1<<11));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)&(~(1<<12)));
+			break;
+		case _dac1_tve1_cvbs_svideo:
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<11));
+			//pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<12));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)& (~(1<<11)));
+			df_write(REG_PINMUX_DISP, df_read(REG_PINMUX_DISP)& (~(1<<12)));
+			break;
+	}
+
+	return 0;
+}
+
+
+extern unsigned int GFXLINEPITCHSIZE;
+extern unsigned int GFX2BASEADDRESS;//not use so far
+extern unsigned int screen_w,screen_h,picture_color_mode;
+
+unsigned int gfxid = 0;
+unsigned int UIStarted=0;
+unsigned int UiStarted(void)
+{
+	return UIStarted;
+}
+//unsigned char testbuffer[1280*720*4];
+static int	CS_LoadDisplay (DF_GFX_IMG* ColorImg)
+{
+
+	////////////////////////////////////////////////////////////
+	__df_update_start();
+
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[gfxid][0]);
+	dfreg.Gfx[gfxid].reg_gfx_ui_buf_start.val = df_read(dfreg_gfx[gfxid][6]);
+	dfreg.Gfx[gfxid].reg_gfx_ui_line_pitch.val = df_read(dfreg_gfx[gfxid][7]);
+	dfreg.Gfx[gfxid].reg_gfx_ui_x_position.val = df_read(dfreg_gfx[gfxid][8]);
+	dfreg.Gfx[gfxid].reg_gfx_ui_y_position.val = df_read(dfreg_gfx[gfxid][9]);
+	DFGfxScalorCoef();
+
+	DFGfxEna(gfxid,1, 0);
+
+	__df_update_end();
+
+	__df_update_start();
+
+	DFGfxSetAlpha(gfxid, 0xff, 0, 0);
+
+	DFGfxSetColorKey(gfxid, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+	DFGfxColorKeyEna(gfxid, 1);
+	DFGfxOpaqueOnOff(gfxid, 0);
+
+	DFSetBackGroud(gfxid,0,128,128);
+
+
+	dfreg.Gfx[gfxid ].reg_gfx_ui_ctrl.bits.ui_tg1_en=1;
+
+	////////////////////test/////////////////////////
+	//memset(testbuffer,1280*720*4,0xff00ff00);
+	//dfreg.Gfx[gfxid].reg_gfx_ui_buf_start.val=(unsigned int)testbuffer;
+	dfreg.Gfx[gfxid].reg_gfx_ui_buf_start.val=ColorImg->StartAddress;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_line_pitch.val = ColorImg->LinePitch;
+	dfreg.Gfx[gfxid ].reg_gfx_ui_ctrl.bits.gfx_ui_format=ColorImg->ColorFormat;//picture_color_mode;
+
+	df_printf("dfreg.Gfx[gfxid ].reg_gfx_ui_ctrl.bits.gfx_ui_format=%d\n",dfreg.Gfx[gfxid ].reg_gfx_ui_ctrl.bits.gfx_ui_format);
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_ena                       = 1;
+	// dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_format                    = UiFormat; // rgb32
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_endian                    = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_opaque                    = 1;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en           = 0;
+	// dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en           = 1;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_ena_premul                = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_af_sc_dis                 = 0;//scaler
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_antiflicker_en_a          = 1;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_antiflicker_en_c          = 1;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_ena_demul                 = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_yuv_conv_ena              = 1;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.gfx_ui_bw_limit                  = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.bits.ui_tg1_en                        = 1; // ui1,ui2 using tg1 switch
+
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_size.bits.gfx_ui_src_width                 = ColorImg->PixelWidth;//info->var.xres;//1920;//ui1_src_width ;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_size.bits.gfx_ui_src_height                = ColorImg->PixelHeight;//info->var.yres;//1080;//ui1_src_height; 
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha       = 255;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_buf_start_3d.bits.gfx_ui_buf_start_3d      = dfreg.Gfx[gfxid].reg_gfx_ui_buf_start.bits.gfx_ui_buf_start ;
+
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_start         =0;// SrcDstParam.DesStartX;//ui1_dst_x_start; // 10;
+	dfreg.Gfx[gfxid].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_end           = screen_w-1;//SrcDstParam.DesEndX;//ui1_dst_x_end  ; // 1024-10;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start         = 0;//SrcDstParam.DesStartY;//ui1_dst_y_start; // 10;
+	dfreg.Gfx[gfxid].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end           = screen_h;//SrcDstParam.DesEndY;//ui1_dst_y_end  ; // 720-10;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_a8.bits.gfx_ui_a8_r                        = 100;
+	dfreg.Gfx[gfxid].reg_gfx_ui_a8.bits.gfx_ui_a8_g                        = 100;
+	dfreg.Gfx[gfxid].reg_gfx_ui_a8.bits.gfx_ui_a8_b                        = 100;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_phase.bits.gfx_ui_hphase                   = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_phase.bits.gfx_ui_vphase                   = 32;
+
+	dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.bits.gfx_ui_hcoeff_gid           = 0;
+	dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.bits.gfx_ui_vcoeff_gid           = 0;
+
+	df_printf(" dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.val=%x\n", dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.val);
+	df_write((dfreg_gfx[gfxid][0]), dfreg.Gfx[gfxid].reg_gfx_ui_ctrl.val);
+	df_write((dfreg_gfx[gfxid][1]), dfreg.Gfx[gfxid].reg_gfx_ui_alpha_ctrl.val);
+	df_write((dfreg_gfx[gfxid][2]), dfreg.Gfx[gfxid].reg_gfx_ui_size.val);
+	df_write((dfreg_gfx[gfxid][3]), dfreg.Gfx[gfxid].reg_gfx_ui_key_red.val);
+	df_write((dfreg_gfx[gfxid][4]), dfreg.Gfx[gfxid].reg_gfx_ui_key_blue.val);
+	df_write((dfreg_gfx[gfxid][5]), dfreg.Gfx[gfxid].reg_gfx_ui_key_green.val);
+	df_write((dfreg_gfx[gfxid][6]), dfreg.Gfx[gfxid].reg_gfx_ui_buf_start.val);
+	df_write((dfreg_gfx[gfxid][7]), dfreg.Gfx[gfxid].reg_gfx_ui_line_pitch.val);
+	df_write((dfreg_gfx[gfxid][8]), dfreg.Gfx[gfxid].reg_gfx_ui_x_position.val);
+	df_write((dfreg_gfx[gfxid][9]), dfreg.Gfx[gfxid].reg_gfx_ui_y_position.val);
+	df_write((dfreg_gfx[gfxid][10]), dfreg.Gfx[gfxid].reg_gfx_ui_buf_start_3d.val);
+	df_write((dfreg_gfx[gfxid][11]), dfreg.Gfx[gfxid].reg_gfx_ui_a8.val);
+	df_write((dfreg_gfx[gfxid][12]), dfreg.Gfx[gfxid].reg_gfx_ui_phase.val);
+	df_write((dfreg_gfx[gfxid][13]), dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.val);
+
+	DFGfxEna(gfxid, 1, 0);
+	/*dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.bits.gfx_ui_hcoeff_gid           = 0;
+	  dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.bits.gfx_ui_vcoeff_gid           = 0;
+	  df_write((dfreg_gfx[gfxid][13]), dfreg.Gfx[gfxid].reg_gfx_ui_coeff_gid.val);*/
+	__df_update_end();
+
+	UIStarted=1;
+
+	{
+		int i;
+		for (i=0;i<13;i++)
+			df_printf("ui reg %x,  val=%x\n",i*4,df_read(dfreg_gfx[gfxid][i]));
+	}
+	return 0;
+}
+
+#ifdef CONFIG_TVOUT_CVBS
+#define VIDEO2PITCH 2048
+#if 0
+void DFVideoEna(int VideoId, int IsEna, int v_w, int v_h, unsigned int yuv_addr)
+{
+	df_video1_reg *reg_video1 = NULL;
+	df_video2_reg *reg_video2 = NULL;
+	df_video3_reg *reg_video3 = NULL;
+
+	switch(VideoId)
+	{
+		case 0:
+			reg_video1 = &dfreg.Video1;
+			reg_video1->df_video_control_reg.val = df_read(dfreg_video0[0]);
+			reg_video1->df_video_control_reg.bits.iVideoEnable = IsEna;
+			df_write(dfreg_video0[0], reg_video1->df_video_control_reg.val);
+			break;
+		case 1:
+			reg_video2 = &dfreg.Video2;
+			reg_video2->df_video_control_reg.val = df_read(dfreg_video1[0]);
+			reg_video2->df_video_control_reg.bits.iVideoEnable = IsEna;
+			reg_video2->df_video_x_position_reg.val = 0x02d00000;
+			reg_video2->df_video_y_position_reg.val = 0x02400000;
+			reg_video2->df_video_yt_addr_reg.val = yuv_addr;
+			reg_video2->df_video_ct_addr_reg.val = yuv_addr + (VIDEO2PITCH * v_h);
+			reg_video2->df_video_yb_addr_reg.val = yuv_addr + 0x800;
+			reg_video2->df_video_cb_addr_reg.val = yuv_addr + (VIDEO2PITCH * v_h) + 0x800;
+			reg_video2->df_video_src_ctrl_reg.val = 0x00000100;	
+			df_write(dfreg_video1[1], reg_video2->df_video_x_position_reg.val);
+			df_write(dfreg_video1[2], reg_video2->df_video_y_position_reg.val);
+			df_write(dfreg_video1[3], reg_video2->df_video_yt_addr_reg.val);
+			df_write(dfreg_video1[4], reg_video2->df_video_ct_addr_reg.val);
+			df_write(dfreg_video1[5], reg_video2->df_video_yb_addr_reg.val);
+			df_write(dfreg_video1[6], reg_video2->df_video_cb_addr_reg.val);
+			df_write(dfreg_video1[7], reg_video2->df_video_src_ctrl_reg.val);
+			df_write(dfreg_video1[0], reg_video2->df_video_control_reg.val);
+			break;
+		case 2:
+			reg_video3 = &dfreg.Video3;
+			reg_video3->df_video_control_reg.val = df_read(dfreg_video2[0]);
+			reg_video3->df_video_control_reg.bits.iVideoEnable = IsEna;
+			df_write(dfreg_video2[0], reg_video3->df_video_control_reg.val);
+			break;
+		default:
+			break;
+	}
+
+	return;
+}
+
+
+void sdoutput(TVOUT_MODE mode, unsigned int addr)
+{
+	TVOUT_MODE tve1_mode;
+	int cvbs_w = 720, cvbs_h;
+
+	switch (mode){
+		case TVOUT_MODE_SECAM:
+			tve1_mode = TVOUT_MODE_SECAM;
+			cvbs_h = 576;
+			break;
+		case TVOUT_MODE_PAL_CN:
+			tve1_mode = TVOUT_MODE_PAL_CN;
+			cvbs_h = 576;
+			break;
+		case TVOUT_MODE_PAL_N:
+			tve1_mode = TVOUT_MODE_PAL_N;
+			cvbs_h = 576;
+			break;
+		case TVOUT_MODE_PAL_M:
+			tve1_mode = TVOUT_MODE_PAL_M;
+			cvbs_h = 480;
+			break;
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576P:
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P50:
+			tve1_mode = TVOUT_MODE_576I;
+			cvbs_h = 576;
+			break;
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_RGB_640X480_60FPS:
+		case TVOUT_RGB_800X600_60FPS:
+		case TVOUT_RGB_1024X768_60FPS:
+		case TVOUT_RGB_1280X720_60FPS:
+		case TVOUT_RGB_800X480_60FPS:
+		case TVOUT_RGB_1440X900_60FPS:
+		case TVOUT_RGB_1280X1024_60FPS:
+		case TVOUT_RGB_1360X768_60FPS:
+		case TVOUT_RGB_1920X1080P30:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_RGB_1920X1080I30:
+		case TVOUT_RGB_1366X768_60FPS:
+			tve1_mode = TVOUT_MODE_480I;
+			cvbs_h = 480;
+			break;
+		default:
+			tve1_mode = TVOUT_MODE_576I;
+			cvbs_h = 576;
+			break;
+	}
+
+	clock_dispset_clockmode0(1, tve_2_clock[tve1_mode]);
+	udelay(100);
+
+	InitTVE1Raw(tve1_mode, __Is_ColorBar);
+	udelay(100);
+
+	__df_update_start();
+	DFSetOutIFVideoFmt(1, tve_2_df[tve1_mode]);
+	__df_update_end();
+	udelay(100);
+
+	__df_update_start();
+	DFVideoEna(1, 1, cvbs_w, cvbs_h,addr);
+	__df_update_end();	
+
+}
+#endif
+#endif
+static int tve_2_clock[] = {
+	_YUV_PAL,
+	_YUV_480I_60Hz,
+	_YUV_576P_50Hz,
+	_YUV_480P_60Hz,
+	_YUV_720P_50Hz,
+	_YUV_720P_60Hz,
+	_YUV_1080I_50Hz,
+	_YUV_1080I_60Hz,
+
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_PAL,
+	_YUV_PAL,
+	_YUV_1080P_24Hz,
+	_YUV_1080P_25Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_50Hz,
+	_YUV_1080P_60Hz,
+
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_NTSC,
+	_YUV_480I_60Hz,
+	_YUV_576P_50Hz,
+	_YUV_480P_59p94Hz,
+	_YUV_480P_59p94Hz,
+	_YUV_480P_60Hz,
+	_YUV_720P_59p94Hz,
+	_YUV_1080I_59p94Hz,
+	_YUV_1080P_23p98Hz,
+	_YUV_1080P_59p94Hz,
+
+	_YUV_1080P_59p94Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080P_59p94Hz,
+	_YUV_1080P_60Hz,
+
+	_YUV_1080I_50Hz,
+	_YUV_1080I_59p94Hz,
+	_YUV_1080I_60Hz,
+
+	_YUV_720P_50Hz,
+	_YUV_720P_59p94Hz,
+	_YUV_720P_60Hz,
+	_YUV_1080P_23p98Hz,
+	_YUV_1080P_24Hz,
+
+	_RGB_DMT_640x480_60Hz,
+	_RGB_DMT_800x600_60Hz,
+	_RGB_DMT_1024x768_60Hz,
+	_YUV_720P_60Hz,
+	_RGB_DMT_800x600_60Hz,
+	_RGB_DMT_1440x900_60Hz,
+	_RGB_DMT_1280x1024_60Hz,
+	_RGB_DMT_1360x768_60Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080I_60Hz,
+	_RGB_DMT_1360x768_60Hz,
+	_RGB_DMT_640x480_59P94Hz,
+	_RGB_DMT_1600x1200_60Hz,
+};
+static int __Is_first = 1;
+static int _Is_interlace = 0;
+int __Is_TV = 1;
+void set_tv_mode(TVOUT_MODE mode)
+{
+	int tveid;
+
+	tveid=0;
+
+	if(__Is_first){
+		pinmux_set_dac0mode(_dac0_tve0_ypbpr);
+		pinmux_set_dac1mode(_dac1_tve1_cvbs_svideo);
+#ifdef CONFIG_TVOUT_YPBPR
+		clock_dac0_enaclock(_clock_enable);
+#endif
+#ifdef CONFIG_TVOUT_CVBS
+		clock_dac1_enaclock(_clock_enable);
+#endif
+		clock_df_enaclock(1);
+		clock_video_enaclock(1);
+	}
+
+	switch(mode){
+		case TVOUT_MODE_SECAM:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+			_Is_interlace = 1;
+			break;
+		default:
+			_Is_interlace = 0;
+	}
+
+
+	switch (mode){
+		case TVOUT_MODE_SECAM:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576P:
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+			if(DF_OUTPUT_CVBS_SVIDEO == df_output_config.output_mode[tveid]){
+				pinmux_set_dac0mode(_dac0_tve0_cvbs_svideo);
+			}
+			else{
+				pinmux_set_dac0mode(_dac0_tve0_ypbpr);
+			}
+			__Is_TV = 1;
+			break;
+		case TVOUT_RGB_640X480_60FPS:
+		case TVOUT_RGB_800X600_60FPS:
+		case TVOUT_RGB_800X480_60FPS:
+		case TVOUT_RGB_1024X768_60FPS:
+		case TVOUT_RGB_1280X720_60FPS:
+		case TVOUT_RGB_1440X900_60FPS:
+		case TVOUT_RGB_1280X1024_60FPS:
+		case TVOUT_RGB_1360X768_60FPS:
+		case TVOUT_RGB_1920X1080P30:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_RGB_1920X1080I30:
+		case TVOUT_RGB_1366X768_60FPS:
+			pinmux_set_dac0mode(_dac0_rgb0);
+			__Is_TV = 0;
+			break;
+
+		default:
+			break;
+	}
+	df_printf("tevid = %d, mode = %d\n",tveid,(int)mode);
+
+
+	if(0 == tveid){
+		clock_disp0_setclock(tve_2_clock[mode]);
+	}
+	else if(1 == tveid){
+		clock_disp1_setclock(tve_2_clock[mode]);
+	}
+
+	udelay(10);
+
+	if(__Is_TV){
+		if(tveid == 0){
+			InitTVE0Raw(mode, __Is_ColorBar);
+		}
+		else if(tveid == 1)
+			InitTVE1Raw(mode, __Is_ColorBar);
+
+		udelay(10);
+	}
+
+
+	df_printf("before __df_update_outif_start\n");
+
+	__df_update_outif_start();
+	df_printf("before DFSetOutIFVideoFmt\n");
+	DFSetOutIFVideoFmt(0,tve_2_df[mode],1);
+	df_printf("after DFSetOutIFVideoFmt\n");
+	__df_update_outif_end();
+	udelay(10);
+	__Is_first = 0;
+	df_printf("set tv mode finished\n");
+	return ;
+}
+
+static int initstatus = 0;
+static int per_mode = -1;
+extern int do_call_external_proc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+void disp_off(void)
+{
+	char* bootargs = NULL;
+	char* temp_char = NULL;
+	//int res;
+	printf("DISABLE DISPLAY RELATED MODULES!!\n");
+	DFGfxEna(0,0,0);
+	clock_df_enaclock(0);
+	clock_tve0_enaclock(_clock_disable);
+	clock_video_enaclock(0);
+	clock_dac0_enaclock(_clock_disable);
+	UIStarted=0;
+	__Is_first = 1;
+	initstatus = 0;
+	per_mode = -1;
+
+	//res=-1;
+	//modifiy bootargs, just remove outputmode
+	temp_char = NULL;
+	// set bootargs outputmode parameter
+	bootargs = getenv("bootargs");
+	//printf("bootargs = %s\n", bootargs);
+	temp_char = strstr(bootargs,"outputmode=");
+	//printf("temp_char = %s\n",temp_char);
+	if(NULL == temp_char){
+		printf("no outputmode\n");		
+	}
+	else
+	{
+		int num1 = 0;
+		int num2 = 0;
+		int templen=0;
+		char* aaa = strchr(temp_char, '=');
+		char* bbb = strchr(temp_char, ' ');
+
+		templen=strstr(bootargs,"outputmode=")-bootargs;
+		//printf("templen=%d\n",templen);
+		num1 = aaa - bootargs;
+		//printf("num1 = %d\n",num1);
+		//printf("%s\n",aaa+1);
+		if(NULL == bbb){
+			temp_char = malloc(strlen(bootargs) + 20);
+			if(0 == temp_char){
+				printf("Not enough memory!\n");
+				return;
+			}
+			//memcpy(temp_char, bootargs, num1+1);
+			//sprintf(temp_char+num1+1,"%d",res);
+			memcpy(temp_char, bootargs, strlen(bootargs)-templen);//outputmode is at the end of bootargs
+
+		}
+		else{
+			num2 = bbb - bootargs;
+			//printf("num2 = %d\n",num2);
+			temp_char = malloc(strlen(bootargs) + 20);
+			if(0 == temp_char){
+				printf("Not enough memory!\n");
+				return;
+			}
+			/*strncpy(temp_char, bootargs, num1+1);
+			  sprintf(temp_char+num1+1,"%d",res);
+			  printf("strlen(temp_char) = %d\n",strlen(temp_char));
+			  strncat(temp_char+strlen(temp_char), bbb,strlen(bbb));*/
+
+			memcpy(temp_char,bootargs,templen);
+			memcpy(temp_char+templen,bbb+1,strlen(bbb));
+		}
+		setenv("bootargs", temp_char);
+		//sprintf(temp_char, "%d", res);
+
+		free(temp_char);
+	}
+	return;
+}
+
+unsigned int flag;
+int disp_init(TVOUT_MODE mode, int pic_w, int pic_h, int dst_x, int dst_y,unsigned char * pData,int hdcp_status, int colorspace_mode)
+{
+	DF_GFX_IMG ColorImg;
+
+
+	/*int IsGfxScalerEna;
+	  int IsFetchOneField;
+	  int IsFetchTopOnly;
+	  int IsDispInterlaced;*/
+
+	flag=0x55aa55aa;
+
+	if (initstatus) {	/* already initialized */
+		printf("DF and TVE have been already initialized\n");
+
+		//		return -1;
+	}
+	df_printf("tvmode = %d\n",mode);
+	df_printf("GFXLINEPITCHSIZE = %d,screen_w %d, screen_h %d,picture_color_mode %d\n ",GFXLINEPITCHSIZE,screen_w,screen_h,picture_color_mode);
+
+	ColorImg.StartAddress = (unsigned int)pData;//GFXBASEADDRESS;
+	ColorImg.PixelWidth = pic_w;
+	ColorImg.PixelHeight = pic_h;
+	ColorImg.ColorFormat = picture_color_mode;
+	ColorImg.DefaultAlpha = 0xff;
+	ColorImg.LinePitch = GFXLINEPITCHSIZE;
+
+
+	set_tv_mode(mode);
+
+	CS_LoadDisplay (&ColorImg);
+#if 1
+	if((mode < TVOUT_MODE_MAX)&&(per_mode !=mode)){
+		char *hdmi_argv[6]={0};
+		char mode_str[5]={0};
+		char flag_addr[4]={0};
+		char hdcp_flag[4]={0};
+		char colorspace_flag[4]= {0};
+		sprintf(mode_str,"%d",mode);
+		hdmi_argv[0]="call_external_proc";
+		hdmi_argv[1]="HDMI";
+		hdmi_argv[2]=mode_str;
+
+		unsigned int addr;
+		addr=(unsigned int )&flag;
+		flag_addr[0]=(unsigned char )(addr&0x000000ff);
+		flag_addr[1]=(unsigned char )((addr&0x0000ff00)>>8);
+		flag_addr[2]=(unsigned char )((addr&0x00ff0000)>>16);
+		flag_addr[3]=(unsigned char )((addr&0xff000000)>>24);
+		//printf("%x,%x,%x,%x,%x\n",flag_addr[0],flag_addr[1],flag_addr[2],flag_addr[3],(unsigned int )&flag);
+		hdmi_argv[3]=flag_addr;
+		sprintf(hdcp_flag,"%d",hdcp_status);
+		hdmi_argv[4]=hdcp_flag;
+		sprintf(colorspace_flag,"%d",colorspace_mode);
+		hdmi_argv[5]=colorspace_flag;
+
+		//		printf("hdmi_argv[4] %s\n",hdmi_argv[4]);
+		do_call_external_proc(NULL, 0, 6, hdmi_argv);
+	}
+#endif
+	per_mode = mode;
+	initstatus = 1;
+
+	if(!flag)
+	{
+		/*printf("DISABLE DISPLAY RELATED MODULES!!\n");
+		  DFGfxEna(0,0,0);
+		  clock_df_enaclock(0);
+		  clock_tve0_enaclock(_clock_disable);
+		  clock_video_enaclock(0);
+		  clock_dac0_enaclock(_clock_disable);
+		  UIStarted=0;*/
+		disp_off();
+
+	}
+
+	return 0;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/df.h u-boot-2011.06/drivers/cnc1900/df/df.h
--- u-boot-2011.06_original/drivers/cnc1900/df/df.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/df.h	2015-05-18 19:41:06.764203000 +0800
@@ -0,0 +1,241 @@
+#ifndef _DF_H_
+#define _DF_H_
+
+typedef enum
+{
+	TVOUT_MODE_576I = 0,///<Define the timing mode is 576i@50Hz AR 4:3. /* id = 0 */
+	TVOUT_MODE_480I,///<Define the timing mode is 480i@60Hz AR 4:3.  /* id = 1 */
+	TVOUT_MODE_576P,///<Define the timing mode is 576p@50Hz AR 4:3     /* id = 2 */
+	TVOUT_MODE_480P,///<Define the timing mode is 480p@60Hz Ar 4:3     /* id = 3 */
+	TVOUT_MODE_720P50,///<Define the timing mode is 720p@50hz.   /* id = 4 */
+	TVOUT_MODE_720P60,///<Define the timing mode is 720p@60hz.   /* id = 5 */
+	TVOUT_MODE_1080I25,///<Define the timing mode is 1080i@25hz.  /* id = 6 */
+	TVOUT_MODE_1080I30,///<Define the timing mode is 1080i@30hz.  /* id = 7 */
+
+	TVOUT_MODE_SECAM,///<Define the timing mode is secam    /* id = 8 */
+	TVOUT_MODE_PAL_M,///<Define the timing mode is pal_m    /* id = 9 */
+	TVOUT_MODE_PAL_N,///<Define the timing mode is pal_n    /* id = 10 */
+	TVOUT_MODE_PAL_CN,///<Define the timing mode is pal_cn   /* id = 11 */
+
+	TVOUT_MODE_1080P24,///<Define the timing mode is 1080P@24Hz( only for HDMI interface)  /* id = 12 */
+	TVOUT_MODE_1080P25,///<Define the timing mode is 1080P@25Hz( only for HDMI interface)  /* id = 13 */
+	TVOUT_MODE_1080P30,///<Define the timing mode is 1080P@30Hz( only for HDMI interface)  /* id = 14 */
+	TVOUT_MODE_1080P50,///<Define the timing mode is 1080P@50Hz( only for HDMI interface)  /* id = 15 */
+	TVOUT_MODE_1080P60,///<Define the timing mode is 1080P@60Hz( only for HDMI interface)  /* id = 16 */
+
+	TVOUT_MODE_576I_16TO9,///<Define the timing mode is 576i@50Hz AR 16:9. /* id = 17 */
+	TVOUT_MODE_480I5994,///<Define the timing mode is 480i@59.94Hz AR 4:3.  /* id = 18 */
+	TVOUT_MODE_480I5994_16TO9,///<Define the timing mode is 480i@59.94Hz AR 16:9.  /* id = 19 */
+	TVOUT_MODE_480I60_16TO9,///<Define the timing mode is 480i@60Hz AR 16:9.  /* id = 20 */
+	TVOUT_MODE_576P50_16TO9,///<Define the timing mode is 576p@50Hz AR 16:9     /* id = 21 */
+	TVOUT_MODE_480P5994,///<Define the timing mode is 480P@59.94Hz AR 4:3( only for HDMI interface)  /* id = 22 */
+	TVOUT_MODE_480P5994_16TO9,///<Define the timing mode is 480P@59.94Hz, AR 16:9( only for HDMI interface)  /* id = 23 */
+	TVOUT_MODE_480P60_16TO9,///<Define the timing mode is 480P@60Hz AR 16:9( only for HDMI interface)  /* id = 24 */
+	TVOUT_MODE_720P5994,///<Define the timing mode is 720P@59.94Hz( only for HDMI interface)  /* id = 25 */
+	TVOUT_MODE_1080I5994,///<Define the timing mode is 1080I@59.94Hz( only for HDMI interface)  /* id = 26 */
+	TVOUT_MODE_1080P2397,///<Define the timing mode is 1080P@23.97Hz( only for HDMI interface)  /* id = 27 */
+	TVOUT_MODE_1080P5994,///<Define the timing mode is 1080P@59.94Hz( only for HDMI interface)  /* id = 28 */
+
+	TVOUT_MODE_720P5994_3DFP,///<Define the timing mode is 720P@59.94Hz 3D FP( only for HDMI interface)  /* id = 29 */
+	TVOUT_MODE_720P60_3DFP,///<Define the timing mode is 720P@60Hz 3D FP( only for HDMI interface)  /* id = 30 */
+	TVOUT_MODE_720P50_3DFP,///<Define the timing mode is 720P@60Hz 3D FP( only for HDMI interface)  /* id = 31 */
+	TVOUT_MODE_1080P2397_3DFP,///<Define the timing mode is 1080P@23.97Hz 3D FP( only for HDMI interface)  /* id = 32 */
+	TVOUT_MODE_1080P24_3DFP,///<Define the timing mode is 1080P@24Hz 3D FP( only for HDMI interface)  /* id = 33 */
+
+	TVOUT_MODE_1080I50_3DSS,///<Define the timing mode is 1080I@50Hz 3D SS( only for HDMI interface)  /* id = 34 */
+	TVOUT_MODE_1080I5994_3DSS,///<Define the timing mode is 1080I@59.94Hz 3D SS( only for HDMI interface)  /* id = 35 */
+	TVOUT_MODE_1080I60_3DSS,///<Define the timing mode is 1080I@60Hz 3D SS( only for HDMI interface)  /* id = 36 */
+
+	TVOUT_MODE_720P50_3DTB,///<Define the timing mode is 720P@50Hz 3D TB( only for HDMI interface)  /* id = 37 */
+	TVOUT_MODE_720P5994_3DTB,///<Define the timing mode is 720P@59.94Hz 3D TB( only for HDMI interface)  /* id = 38 */
+	TVOUT_MODE_720P60_3DTB,///<Define the timing mode is 720P@60Hz 3D TB( only for HDMI interface)  /* id = 39 */
+	TVOUT_MODE_1080P2397_3DTB,///<Define the timing mode is 1080P@23.97Hz 3D TB( only for HDMI interface)  /* id = 40 */
+	TVOUT_MODE_1080P24_3DTB,///<Define the timing mode is 1080P@24Hz 3D TB( only for HDMI interface)  /* id = 41 */
+
+	TVOUT_RGB_640X480_60FPS,///<Define the timing mode is 640*480@60fps(only for VGA interface) /* id = 42 */
+	TVOUT_RGB_800X600_60FPS,///<Define the timing mode is 800*600@60fps(only for VGA interface) /* id = 43 */
+	TVOUT_RGB_1024X768_60FPS,///<Define the timing mode is 1024*768@60fps(only for VGA interface) /* id = 44 */
+	TVOUT_RGB_1280X720_60FPS,///<Define the timing mode is 1280*720@60fps(only for VGA interface) /* id = 45 */
+	TVOUT_RGB_800X480_60FPS,///<Define the timing mode is 800*480@60fps(only for VGA interface) /* id = 46 */
+	TVOUT_RGB_1440X900_60FPS,///<Define the timing mode is 1440*900@60fps(only for VGA interface) /* id = 47 */
+	TVOUT_RGB_1280X1024_60FPS,///<Define the timing mode is 1280*1024@60fps(only for VGA interface) /* id = 48 */
+	TVOUT_RGB_1360X768_60FPS,///<Define the timing mode is 1366*768@60fps(only for VGA interface) /* id = 49 */
+	TVOUT_RGB_1920X1080P30,///<Define the timing mode is 1920*1080P30(only for VGA interface) /* id = 50 */
+	TVOUT_RGB_1920X1080P60,///<Define the timing mode is 1920*1080P60(only for VGA interface) /* id = 51 */
+	TVOUT_RGB_1920X1080I30,///<Define the timing mode is 1920*1080I30(only for VGA interface) /* id = 52 */
+	TVOUT_RGB_1366X768_60FPS,///<Define the timing mode is 1366*768@60fps(only for VGA interface) /* id = 53 */
+	TVOUT_RGB_640X480_5994FPS,///<Define the timing mode is 1366*768@60fps(only for VGA interface) /* id = 54 */
+	TVOUT_MODE_1600X1200_60FPS,///<Define the timing mode is 1600*1200P@60Hz/* id = 55 */
+
+	TVOUT_MODE_MAX,
+} TVOUT_MODE;
+
+typedef enum _DF_VIDEO_FORMAT_
+{
+	NOT_STANDARD_VIDEO_MODE = -1,
+	DISP_YUV_720P_60FPS        =0,
+	DISP_YUV_1080I_30FPS       =1,
+	DISP_YUV_480P              =2,
+	DISP_YUV_NTSC              =3,
+	DISP_YUV_720P_50FPS        =4,
+	DISP_YUV_1080I_25FPS       =5,
+	DISP_YUV_576P              =6,
+	DISP_YUV_PAL               =7,
+	DISP_YUV_1080P_60FPS       =8,
+	DISP_YUV_1080P_50FPS       =9,
+	DISP_YUV_1080P_24FPS       =10,
+	DISP_YUV_1080P_25FPS       =11,
+	DISP_YUV_1080P_30FPS       =12,
+	DISP_YUV_1080I_25FPS_AS    =13,
+	DISP_RGB_VGA_60FPS         =14,
+	DISP_RGB_SVGA_60FPS        =15,
+	DISP_RGB_XGA_60FPS         =16,
+	DISP_RGB_SXGA_60FPS        =17,
+	DISP_RGB_UXGA_60FPS        =18,
+	DISP_RGB_720P_60FPS        =19,
+	DISP_1440x288P_50_M1       =20,
+	DISP_1440x288P_50_M2       =21,
+	DISP_1440x288P_50_M3       =22,
+	DISP_2880x576I_50          =23,
+	DISP_2880x288P_50_M1       =24,
+	DISP_2880x288P_50_M2       =25,
+	DISP_2880x288P_50_M3       =26,
+	DISP_1440x576P_50          =27,
+	DISP_1440x240P_60_M1       =28,
+	DISP_1440x240P_60_M2       =29,
+	DISP_2880x480I_60          =30,
+	DISP_2880x240P_60_M1       =31,
+	DISP_2880x240P_60_M2       =32,
+	DISP_1440x480P_60          =33,
+	DISP_RGB_DMT_640x480_60    =34,
+	DISP_RGB_DMT_640x480_75    =35,
+	DISP_RGB_DMT_800x600_60    =36,
+	DISP_RGB_DMT_800x600_75    =37,
+	DISP_RGB_DMT_848x480_60    =38,
+	DISP_RGB_DMT_1152x864_75   =39,
+	DISP_RGB_DMT_1280x768_60   =40,
+	DISP_RGB_DMT_1280x960_60   =41,
+	DISP_RGB_DMT_1280x1024_60  =42,
+	DISP_RGB_DMT_1360x768_60   =43,
+	DISP_RGB_DMT_1440x900_60   =44,
+	DISP_RGB_CVT_640x480_75    =45,
+	DISP_RGB_CVT_800x600_60    =46,
+	DISP_RGB_CVT_800x600_75    =47,
+	DISP_RGB_CVT_1024x768_60   =48,
+	DISP_RGB_CVT_1280x1024_60  =49,
+	DISP_RGB_CVT_848x480_60    =50,
+	DISP_RGB_CVT_848x480_75    =51,
+	DISP_RGB_CVT_1024x576_60   =52,
+	DISP_RGB_CVT_1024x576_75   =53,
+	DISP_RGB_CVT_1280x720_60   =54,
+	DISP_RGB_CVT_1280x720_75   =55,
+	DISP_RGB_CVT_640x400_75    =56,
+	DISP_RGB_CVT_768x480_60    =57,
+	DISP_RGB_CVT_768x480_75    =58,
+	DISP_RGB_CVT_1024x640_60   =59,
+	DISP_RGB_CVT_1024x640_75   =60,
+	DISP_RGB_CVT_1280x800_75   =61,
+	DISP_RGB_CVT_800x600_RED   =62,
+	DISP_RGB_CVT_1024x768_RED  =63,
+	DISP_RGB_CVT_1280x960_RED  =64,
+	DISP_RGB_CVT_848x480_RED   =65,
+	DISP_RGB_CVT_1024x576_RED  =66,
+	DISP_RGB_CVT_1280x720_RED  =67,
+	DISP_RGB_CVT_1600x900_RED  =68,
+	DISP_RGB_CVT_768x480_RED   =69,
+	DISP_RGB_CVT_1024x640_RED  =70,
+	DISP_RGB_CVT_1280x800_RED  =71,
+	DISP_RGB_CVT_1600x1000_RED =72,
+	DISP_64x64                 =73,
+	DISP_VGA_1366x768		   =74,
+	DISP_YUV_480P_3D,
+	DISP_YUV_NTSC_3D,
+	DISP_YUV_576P_3D,
+	DISP_YUV_PAL_3D,
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_1080P_30FPS_3D,
+	DISP_YUV_1080I_30FPS_3D,
+	DISP_YUV_720P_50FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+	DISP_YUV_1080P_25FPS_3D,
+	DISP_YUV_720P_30FPS_3D,
+	DISP_YUV_1080P_30FPS_3D_TEMP,
+	DISP_YUV_1080I_30FPS_3D_TEMP,
+	DISP_RGB_VGA_59P94FPS,
+	DISP_1600x1200_60FPS,
+
+	DISP_FMT_MAX,
+}DF_VIDEO_FORMAT;
+
+typedef enum
+{
+	DF_OUTPUT_CVBS_SVIDEO = 0,
+	DF_OUTPUT_YPBPR,
+	DF_OUTPUT_VGA
+} DF_OUTPUT_MODE;
+
+typedef struct _DF_OUTIF_FORMAT_INFO_
+{
+	int  mIsYUVorRGB;
+	int  mWidth;
+	int  mHeight;
+	int  mFPS;
+	int  mFreq;
+	int  mIsHD;
+	int  mVSyncPol;
+	int  mHSyncPol;
+	int  mHRes;
+	int  mHActive;
+	int  mHSyncFP;
+	int  mHSyncWidth;
+	int  mHSyncBP;
+	int  mVRes;
+	int  mVActline;
+	int  mVSyncFP;
+	int  mVSyncWidth;
+	int  mVSyncBP;
+	int  m3dEn;
+	int  m3dVactSpace;
+	int  mVidType;
+	int  mVidrptr;
+	int  mYCMuxEn;
+	int  mPALFmt;
+	int  mFmtIdx;
+	char *mFmtName;
+
+} df_out_if_timing;
+
+typedef struct DF_OUTPUT_CONFIG_t_{
+	int gfx_output[2]; //gfx_layer_id
+	int vid_output[3]; //video_layer_id
+	DF_OUTPUT_MODE output_mode[2];//outif_id
+}DF_OUTPUT_CONFIG_t;
+
+typedef enum _DF_GFX_COLOR_FORMAT_
+{
+	DF_GFX_CLUT4     = 0,
+	DF_GFX_CLUT8     = 1,
+	DF_GFX_RGB565    = 2,
+	DF_GFX_ARGB4444  = 3,
+	DF_GFX_A0        = 4,
+	DF_GFX_ARGB1555  = 5,
+	DF_GFX_ARGB8888  = 6,
+	DF_GFX_XRGB8888  = 7,
+	DF_GFX_FORMA_MAX,
+
+} DF_GFX_COLOR_FORMAT;
+
+typedef struct _DF_GFX_IMG_ {
+	unsigned int PixelWidth;
+	unsigned int PixelHeight;
+	DF_GFX_COLOR_FORMAT ColorFormat;
+	unsigned int StartAddress;
+	unsigned int LinePitch;
+	//For Color Format A0
+	unsigned char  DefaultAlpha;
+	unsigned char  DefaultRed;
+	unsigned char  DefaultGreen;
+	unsigned char  DefaultBlue;
+} DF_GFX_IMG;
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/df_reg_def.h u-boot-2011.06/drivers/cnc1900/df/df_reg_def.h
--- u-boot-2011.06_original/drivers/cnc1900/df/df_reg_def.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/df_reg_def.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,507 @@
+#ifndef _DF_REG_DEF_H_
+#define _DF_REG_DEF_H_
+
+#define TVE0_REG_BASE		0x80168000
+#define TVE0_REG_SIZE		0x00001000
+#define TVE1_REG_BASE		0x80160000
+#define TVE1_REG_SIZE		0x00001000
+
+/****************Register IF******************************/
+/*
+// (1) Re-map all the Bits Defination
+// (2) Add Status Register of Each Model
+// (3) Add Interrupt Control
+*/
+
+enum _ADDRESS_SPACE_
+{
+    HW_REG_ADDR_MASK = ~(0xFFFFF),
+};
+
+#define     VPP_REG_BASE                0xb1800000
+#define 	  VPP_REG_SIZE			0x1000
+
+#define     VPP_REG_CTRL_BASE           (VPP_REG_BASE + (0x000 << 2 ))//CTRL     //0-6    ----1
+#define     VPP_REG_GFX_DMA_BASE        (VPP_REG_BASE + (0x020 << 2 ))//GFX_S    //0-9    ----1
+#define     VPP_REG_GFX_UI1_BASE         (VPP_REG_BASE + (0x050 << 2 ))//GFX_U    //0-9    ----1
+#define     VPP_REG_GFX_UI2_BASE       (VPP_REG_BASE + (0x040 << 2 ))//GFX_U    //0-9    ----1
+#define     VPP_REG_HD2SD_RD_BASE       (VPP_REG_BASE + (0x060 << 2) )//HD2SD_RD //0-8    ----1
+#define     VPP_REG_CAP_BASE           (VPP_REG_BASE + (0x080 << 2 ))//CAP //0-19   ----2
+#define     VPP_REG_COMP_BASE           (VPP_REG_BASE + (0x0a0 << 2 ))//ENH      //0-4    ----1
+#define     VPP_REG_TG1_BASE            (VPP_REG_BASE + (0x0b0 << 2 ))//DISP1    //0-7    ----1
+#define     VPP_REG_TG2_BASE            (VPP_REG_BASE + (0x0c0 << 2 ))//DISP2    //0-7    ----1
+#define     VPP_REG_MAIN_CH_BASE        (VPP_REG_BASE + (0x100 << 2 ))//MCH      //0-40   ----3
+#define     VPP_REG_SR_CH_BASE          (VPP_REG_BASE + (0x140 << 2 ))//SR       //0-33   ----2
+/***********GLB_CTRL_Register******/
+#define     VPP_REG_GLB_CTRL_H_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 0 << 2))
+#define     VPP_REG_GLB_CTRL_M_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 1 << 2))
+#define     VPP_REG_GLB_CTRL_C_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 2 << 2))
+#define     VPP_REG_GLB_CTRL_SETTING              ((VPP_REG_CTRL_BASE       ) + ( 3 << 2))
+#define     VPP_REG_GLB_CTRL_CLK_SETTING          ((VPP_REG_CTRL_BASE       ) + ( 4 << 2))
+#define     VPP_REG_GLB_CTRL_INT_STA_COP          ((VPP_REG_CTRL_BASE       ) + ( 5 << 2))
+#define     VPP_REG_GLB_CTRL_INT_MSK_COP          ((VPP_REG_CTRL_BASE       ) + ( 6 << 2))
+#define     VPP_REG_GLB_CTRL_INT_STA_HOST         ((VPP_REG_CTRL_BASE       ) + ( 7 << 2))
+#define     VPP_REG_GLB_CTRL_INT_MSK_HOST         ((VPP_REG_CTRL_BASE       ) + ( 8 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF3          ((VPP_REG_CTRL_BASE       ) + ( 9 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF4          ((VPP_REG_CTRL_BASE       ) + (10 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF6          ((VPP_REG_CTRL_BASE       ) + (11 << 2))
+#define     VPP_REG_GLB_CTRL_CPU_WQ               ((VPP_REG_CTRL_BASE       ) + (12 << 2))
+#define     VPP_REG_GLB_CTRL_COP_RQ               ((VPP_REG_CTRL_BASE       ) + (13 << 2))
+#define     VPP_REG_GLB_CTRL_HAND_STATUS          ((VPP_REG_CTRL_BASE       ) + (14 << 2))
+#define     VPP_REG_GLB_CTRL_TG_SETTING           ((VPP_REG_CTRL_BASE       ) + (15 << 2))
+/***********DMA Register**********/
+#define     VPP_REG_DMA_CTRL                      ((VPP_REG_GFX_DMA_BASE    ) + ( 0 << 2))
+#define     VPP_REG_DMA_DES_X_POSITION             ((VPP_REG_GFX_DMA_BASE    ) + ( 1 << 2))
+#define     VPP_REG_DMA_DES_Y_POSITION             ((VPP_REG_GFX_DMA_BASE    ) + ( 2 << 2))
+#define     VPP_REG_DMA_SRC_X_CROP                ((VPP_REG_GFX_DMA_BASE    ) + ( 3 << 2))
+#define     VPP_REG_DMA_SRC_Y_CROP                ((VPP_REG_GFX_DMA_BASE    ) + ( 4 << 2))
+#define     VPP_REG_DMA_RD_YF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 5 << 2))
+#define     VPP_REG_DMA_RD_CF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 6 << 2))
+#define     VPP_REG_DMA_WR_YF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 7 << 2))
+#define     VPP_REG_DMA_WR_CF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 8 << 2))
+
+/***********GFX UI1   Register******/
+#define     VPP_REG_GFX_UI1_CTRL                 ((VPP_REG_GFX_UI1_BASE    ) + ( 0 << 2))
+#define     VPP_REG_GFX_UI1_ALPHA_CTRL           ((VPP_REG_GFX_UI1_BASE    ) + ( 1 << 2))
+#define     VPP_REG_GFX_UI1_SIZE                 ((VPP_REG_GFX_UI1_BASE    ) + ( 2 << 2))
+#define     VPP_REG_GFX_UI1_KEY_RED              ((VPP_REG_GFX_UI1_BASE    ) + ( 3 << 2))
+#define     VPP_REG_GFX_UI1_KEY_BLUE             ((VPP_REG_GFX_UI1_BASE    ) + ( 4 << 2))
+#define     VPP_REG_GFX_UI1_KEY_GREEN            ((VPP_REG_GFX_UI1_BASE    ) + ( 5 << 2))
+#define     VPP_REG_GFX_UI1_BUF_START            ((VPP_REG_GFX_UI1_BASE    ) + ( 6 << 2))
+#define     VPP_REG_GFX_UI1_LINE_PITCH           ((VPP_REG_GFX_UI1_BASE    ) + ( 7 << 2))
+#define     VPP_REG_GFX_UI1_X_POSITON            ((VPP_REG_GFX_UI1_BASE    ) + ( 8 << 2))
+#define     VPP_REG_GFX_UI1_Y_POSITON            ((VPP_REG_GFX_UI1_BASE    ) + ( 9 << 2))
+#define     VPP_REG_GFX_UI1_BUF_START_3D         ((VPP_REG_GFX_UI1_BASE    ) + (10 << 2))
+#define     VPP_REG_GFX_UI1_A8                   ((VPP_REG_GFX_UI1_BASE    ) + (11 << 2))
+#define     VPP_REG_GFX_UI1_PHASE                ((VPP_REG_GFX_UI1_BASE    ) + (12 << 2))
+#define     VPP_REG_GFX_UI1_COEFF_GID            ((VPP_REG_GFX_UI1_BASE    ) + (13 << 2))
+/*****GFX UI2   Register******/
+#define     VPP_REG_GFX_UI2_CTRL                  ((VPP_REG_GFX_UI2_BASE    ) + ( 0 << 2))
+#define     VPP_REG_GFX_UI2_ALPHA_CTRL             ((VPP_REG_GFX_UI2_BASE    ) + ( 1 << 2))
+#define     VPP_REG_GFX_UI2_SIZE                   ((VPP_REG_GFX_UI2_BASE    ) + ( 2 << 2))
+#define     VPP_REG_GFX_UI2_KEY_RED                ((VPP_REG_GFX_UI2_BASE    ) + ( 3 << 2))
+#define     VPP_REG_GFX_UI2_KEY_BLUE               ((VPP_REG_GFX_UI2_BASE    ) + ( 4 << 2))
+#define     VPP_REG_GFX_UI2_KEY_GREEN              ((VPP_REG_GFX_UI2_BASE    ) + ( 5 << 2))
+#define     VPP_REG_GFX_UI2_BUF_START              ((VPP_REG_GFX_UI2_BASE    ) + ( 6 << 2))
+#define     VPP_REG_GFX_UI2_LINE_PITCH             ((VPP_REG_GFX_UI2_BASE    ) + ( 7 << 2))
+#define     VPP_REG_GFX_UI2_X_POSITON              ((VPP_REG_GFX_UI2_BASE    ) + ( 8 << 2))
+#define     VPP_REG_GFX_UI2_Y_POSITON             ((VPP_REG_GFX_UI2_BASE    ) + ( 9 << 2))
+#define     VPP_REG_GFX_UI2_BUF_START_3D           ((VPP_REG_GFX_UI2_BASE    ) + (10 << 2))
+#define     VPP_REG_GFX_UI2_A8                     ((VPP_REG_GFX_UI2_BASE    ) + (11 << 2))
+#define     VPP_REG_GFX_UI2_PHASE                  ((VPP_REG_GFX_UI2_BASE    ) + (12 << 2))
+#define     VPP_REG_GFX_UI2_COEFF_GID              ((VPP_REG_GFX_UI2_BASE    ) + (13 << 2))
+/***********HD2SD_RD Register******/
+#define     VPP_REG_HD2SD_RD_CTRL                 ((VPP_REG_HD2SD_RD_BASE   ) + ( 0 << 2))
+#define     VPP_REG_HD2SD_RD_X_POSITION            ((VPP_REG_HD2SD_RD_BASE   ) + ( 1 << 2))
+#define     VPP_REG_HD2SD_RD_Y_POSITION            ((VPP_REG_HD2SD_RD_BASE   ) + ( 2 << 2))
+#define     VPP_REG_HD2SD_RD_SRC_X_CROP           ((VPP_REG_HD2SD_RD_BASE   ) + ( 3 << 2))
+#define     VPP_REG_HD2SD_RD_SRC_Y_CROP           ((VPP_REG_HD2SD_RD_BASE   ) + ( 4 << 2))
+#define     VPP_REG_HD2SD_RD_YF_ADDR              ((VPP_REG_HD2SD_RD_BASE   ) + ( 5 << 2))
+#define     VPP_REG_HD2SD_RD_CF_ADDR              ((VPP_REG_HD2SD_RD_BASE   ) + ( 6 << 2))
+#define     VPP_REG_HD2SD_RD_STA_DISP_NUM         ((VPP_REG_HD2SD_RD_BASE   ) + ( 7 << 2))
+/*********HD2SD_CAPTURE Register***/
+#define     VPP_REG_CAP_CTRL                      ((VPP_REG_CAP_BASE   ) + ( 0 << 2))
+#define     VPP_REG_CAP_SCR_SETTING               ((VPP_REG_CAP_BASE   ) + ( 1 << 2))
+#define     VPP_REG_CAP_SCR_H_POSITION             ((VPP_REG_CAP_BASE   ) + ( 2 << 2))
+#define     VPP_REG_CAP_SCR_V_POSITION             ((VPP_REG_CAP_BASE   ) + ( 3 << 2))
+#define     VPP_REG_CAP_DES_H_POSITION            ((VPP_REG_CAP_BASE   ) + ( 4 << 2))
+#define     VPP_REG_CAP_DES_V_POSITION            ((VPP_REG_CAP_BASE   ) + ( 5 << 2))
+#define     VPP_REG_CAP_YV_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 6 << 2))
+#define     VPP_REG_CAP_YH_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 7 << 2))
+#define     VPP_REG_CAP_CV_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 8 << 2))
+#define     VPP_REG_CAP_CH_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 9 << 2))
+#define     VPP_REG_CAP_Y_NOLINE_D                ((VPP_REG_CAP_BASE   ) + (10 << 2))
+#define     VPP_REG_CAP_C_NOLINE_D                ((VPP_REG_CAP_BASE   ) + (11 << 2))
+#define     VPP_REG_CAP_Y_NOLINE_K                ((VPP_REG_CAP_BASE   ) + (12 << 2))
+#define     VPP_REG_CAP_C_NOLINE_K                ((VPP_REG_CAP_BASE   ) + (13 << 2))
+#define     VPP_REG_CAP_HOR_PHASE                 ((VPP_REG_CAP_BASE   ) + (14 << 2))
+#define     VPP_REG_CAP_VER_PHASE                 ((VPP_REG_CAP_BASE   ) + (15 << 2))
+#define     VPP_REG_CAP_YT_ADDR0                  ((VPP_REG_CAP_BASE   ) + (16 << 2))
+#define     VPP_REG_CAP_CT_ADDR0                  ((VPP_REG_CAP_BASE   ) + (17 << 2))
+#define     VPP_REG_CAP_YT_ADDR1                  ((VPP_REG_CAP_BASE   ) + (18 << 2))
+#define     VPP_REG_CAP_CT_ADDR1                  ((VPP_REG_CAP_BASE   ) + (19 << 2))
+#define     VPP_REG_CAP_YT_ADDR2                  ((VPP_REG_CAP_BASE   ) + (20 << 2))
+#define     VPP_REG_CAP_CT_ADDR2                  ((VPP_REG_CAP_BASE   ) + (21 << 2))
+#define     VPP_REG_CAP_YT_ADDR3                  ((VPP_REG_CAP_BASE   ) + (22 << 2))
+#define     VPP_REG_CAP_CT_ADDR3                  ((VPP_REG_CAP_BASE   ) + (23 << 2))
+#define     VPP_REG_CAP_YT_ADDR4                  ((VPP_REG_CAP_BASE   ) + (24 << 2))
+#define     VPP_REG_CAP_CT_ADDR4                  ((VPP_REG_CAP_BASE   ) + (25 << 2))
+#define     VPP_REG_CAP_COEFF_NO                  ((VPP_REG_CAP_BASE   ) + (26 << 2))
+#define     VPP_REG_CAP_IDX                       ((VPP_REG_CAP_BASE   ) + (27 << 2))
+#define     VPP_REG_CAP_PTS                       ((VPP_REG_CAP_BASE   ) + (28 << 2))
+#define     VPP_REG_CAP_STA_TG1                   ((VPP_REG_CAP_BASE   ) + (29 << 2))
+#define     VPP_REG_CAP_LINE_CNT                 ((VPP_REG_CAP_BASE   ) + (30 << 2))
+#define     VPP_REG_CAP_FORMAT                  ((VPP_REG_CAP_BASE   ) + (31 << 2))
+/***********COMPOSITOR Register****/
+#define     VPP_REG_COMP_B2_BACK_GROUND           ((VPP_REG_COMP_BASE       ) + ( 0 << 2))
+#define     VPP_REG_COMP_B2_Z_ORDER               ((VPP_REG_COMP_BASE       ) + ( 1 << 2))
+#define     VPP_REG_COMP_B2_DEFAULT_ALPHA         ((VPP_REG_COMP_BASE       ) + ( 2 << 2))
+#define     VPP_REG_COMP_COLOR_ADJUST             ((VPP_REG_COMP_BASE       ) + ( 3 << 2))
+#define     VPP_REG_COMP_SHARP_Y_CTRL             ((VPP_REG_COMP_BASE       ) + ( 4 << 2))
+#define     VPP_REG_COMP_SHARP_C_CTRL             ((VPP_REG_COMP_BASE       ) + ( 5 << 2))
+#define     VPP_REG_COMP_B3_BACK_GROUND          ((VPP_REG_COMP_BASE       ) + ( 6 << 2))
+#define     VPP_REG_COMP_B3_Z_ORDER                ((VPP_REG_COMP_BASE       ) + ( 7 << 2))
+#define     VPP_REG_COMP_B3_DEFAULT_ALPHA          ((VPP_REG_COMP_BASE       ) + ( 8 << 2))
+/**********TG1 Register*********/
+#define     VPP_REG_TG1_CTRL                   ((VPP_REG_TG1_BASE     ) + ( 0 << 2))
+#define     VPP_REG_TG1_X_SIZE                 ((VPP_REG_TG1_BASE     ) + ( 1 << 2))
+#define     VPP_REG_TG1_Y_SIZE                 ((VPP_REG_TG1_BASE     ) + ( 2 << 2))
+#define     VPP_REG_TG1_HSYNC                  ((VPP_REG_TG1_BASE     ) + ( 3 << 2))
+#define     VPP_REG_TG1_VSYNC                  ((VPP_REG_TG1_BASE     ) + ( 4 << 2))
+#define     VPP_REG_TG1_VGA_LEVEL              ((VPP_REG_TG1_BASE     ) + ( 5 << 2))
+#define     VPP_REG_TG1_V_START_LINE           ((VPP_REG_TG1_BASE     ) + ( 6 << 2))
+#define     VPP_REG_TG1_STA_DISP_SIZE          ((VPP_REG_TG1_BASE     ) + ( 8 << 2))
+#define     VPP_REG_TG1_STA_LINE               ((VPP_REG_TG1_BASE     ) + ( 9 << 2))
+/***********TG2 Register********/
+#define     VPP_REG_TG2_CTRL                   ((VPP_REG_TG2_BASE     ) + ( 0 << 2))
+#define     VPP_REG_TG2_X_SIZE                 ((VPP_REG_TG2_BASE     ) + ( 1 << 2))
+#define     VPP_REG_TG2_Y_SIZE                 ((VPP_REG_TG2_BASE     ) + ( 2 << 2))
+#define     VPP_REG_TG2_HSYNC                  ((VPP_REG_TG2_BASE     ) + ( 3 << 2))
+#define     VPP_REG_TG2_VSYNC                  ((VPP_REG_TG2_BASE     ) + ( 4 << 2))
+#define     VPP_REG_TG2_VGA_LEVEL              ((VPP_REG_TG2_BASE     ) + ( 5 << 2))
+#define     VPP_REG_TG2_V_START_LINE           ((VPP_REG_TG2_BASE     ) + ( 6 << 2))
+#define     VPP_REG_TG2_STA_DISP_SIZE          ((VPP_REG_TG2_BASE     ) + ( 8 << 2))
+#define     VPP_REG_TG2_STA_LINE               ((VPP_REG_TG2_BASE     ) + ( 9 << 2))
+/*********MAIN CH Register*********/
+#define     VPP_REG_MAIN_CH_DYN_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + ( 0 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FY       ((VPP_REG_MAIN_CH_BASE    ) + ( 1 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CY       ((VPP_REG_MAIN_CH_BASE    ) + ( 2 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BY       ((VPP_REG_MAIN_CH_BASE    ) + ( 3 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBY      ((VPP_REG_MAIN_CH_BASE    ) + ( 4 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 5 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 6 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 7 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBY_3DR  ((VPP_REG_MAIN_CH_BASE    ) + ( 8 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FC       ((VPP_REG_MAIN_CH_BASE    ) + ( 9 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CC       ((VPP_REG_MAIN_CH_BASE    ) + (10 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BC       ((VPP_REG_MAIN_CH_BASE    ) + (11 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBC      ((VPP_REG_MAIN_CH_BASE    ) + (12 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (13 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (14 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (15 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBC_3DR  ((VPP_REG_MAIN_CH_BASE    ) + (16 << 2))
+#define     VPP_REG_MAIN_CH_DYN_STORE_FRM_ADDR_Y  ((VPP_REG_MAIN_CH_BASE    ) + (17 << 2))
+#define     VPP_REG_MAIN_CH_DYN_STORE_FRM_ADDR_C  ((VPP_REG_MAIN_CH_BASE    ) + (18 << 2))
+#define     VPP_REG_MAIN_CH_CTRL                  ((VPP_REG_MAIN_CH_BASE    ) + (19 << 2))
+#define     VPP_REG_MAIN_CH_SRC_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + (20 << 2))
+#define     VPP_REG_MAIN_CH_SRC_H_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (21 << 2))
+#define     VPP_REG_MAIN_CH_SRC_V_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (22 << 2))
+#define     VPP_REG_MAIN_CH_DES_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + (23 << 2))
+#define     VPP_REG_MAIN_CH_DES_H_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (24 << 2))
+#define     VPP_REG_MAIN_CH_DES_V_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (25 << 2))
+#define     VPP_REG_MAIN_CH_Y_INIT_CENTOR         ((VPP_REG_MAIN_CH_BASE    ) + (26 << 2))
+#define     VPP_REG_MAIN_CH_Y_INIT_PHASE          ((VPP_REG_MAIN_CH_BASE    ) + (27 << 2))
+#define     VPP_REG_MAIN_CH_C_INIT_CENTOR         ((VPP_REG_MAIN_CH_BASE    ) + (28 << 2))
+#define     VPP_REG_MAIN_CH_C_INIT_PHASE          ((VPP_REG_MAIN_CH_BASE    ) + (29 << 2))
+#define     VPP_REG_MAIN_CH_COF_CTRL              ((VPP_REG_MAIN_CH_BASE    ) + (30 << 2))
+#define     VPP_REG_MAIN_CH_Y_TNR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (31 << 2))
+#define     VPP_REG_MAIN_CH_Y_MADI_SETTING        ((VPP_REG_MAIN_CH_BASE    ) + (32 << 2))
+#define     VPP_REG_MAIN_CH_Y_DIR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (33 << 2))
+#define     VPP_REG_MAIN_CH_Y_V_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (34 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (35 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_D0_ABS            ((VPP_REG_MAIN_CH_BASE    ) + (36 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_K                 ((VPP_REG_MAIN_CH_BASE    ) + (37 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_N1                ((VPP_REG_MAIN_CH_BASE    ) + (38 << 2))
+#define     VPP_REG_MAIN_CH_C_TNR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (39 << 2))
+#define     VPP_REG_MAIN_CH_C_MADI_SETTING        ((VPP_REG_MAIN_CH_BASE    ) + (40 << 2))
+#define     VPP_REG_MAIN_CH_C_DIR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (41 << 2))
+#define     VPP_REG_MAIN_CH_C_V_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (42 << 2))
+#define     VPP_REG_MAIN_CH_C_H_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (43 << 2))
+#define     VPP_REG_MAIN_CH_C_H_D0_ABS            ((VPP_REG_MAIN_CH_BASE    ) + (44 << 2))
+#define     VPP_REG_MAIN_CH_C_H_K                 ((VPP_REG_MAIN_CH_BASE    ) + (45 << 2))
+#define     VPP_REG_MAIN_CH_C_H_N1                ((VPP_REG_MAIN_CH_BASE    ) + (46 << 2))
+#define     VPP_REG_MAIN_F2F_STORE_PITCH          ((VPP_REG_MAIN_CH_BASE    ) + (49 << 2))
+#define     VPP_REG_MAIN_UPS_SETTING              ((VPP_REG_MAIN_CH_BASE    ) + (50 << 2))
+#define     VPP_REG_MAIN_B1_CTRL                  ((VPP_REG_MAIN_CH_BASE    ) + (51 << 2))
+#define     VPP_REG_MAIN_B1_BACK_GROUND           ((VPP_REG_MAIN_CH_BASE    ) + (52 << 2))
+#define     VPP_REG_MAIN_B1_DES_POSITION_X        ((VPP_REG_MAIN_CH_BASE    ) + (53 << 2))
+#define     VPP_REG_MAIN_B1_DES_POSITION_Y        ((VPP_REG_MAIN_CH_BASE    ) + (54 << 2))
+#define     VPP_REG_MAIN_CH_STA_DISP_NUM          ((VPP_REG_MAIN_CH_BASE    ) + (55 << 2))
+/***********SR CH Register*********/
+#define     VPP_REG_SR_CH_DYN_SETTING             ((VPP_REG_SR_CH_BASE      ) + ( 0 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CY             ((VPP_REG_SR_CH_BASE      ) + ( 1 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CY_3DR         ((VPP_REG_SR_CH_BASE      ) + ( 2 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CC             ((VPP_REG_SR_CH_BASE      ) + ( 3 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CC_3DR         ((VPP_REG_SR_CH_BASE      ) + ( 4 << 2))
+#define     VPP_REG_SR_CH_DYN_STORE_FRM_ADDR_Y    ((VPP_REG_SR_CH_BASE      ) + ( 5 << 2))
+#define     VPP_REG_SR_CH_DYN_STORE_FRM_ADDR_C    ((VPP_REG_SR_CH_BASE      ) + ( 6 << 2))
+#define     VPP_REG_SR_CH_CTRL                    ((VPP_REG_SR_CH_BASE      ) + (16 << 2))
+#define     VPP_REG_SR_CH_SRC_SETTING             ((VPP_REG_SR_CH_BASE      ) + (17 << 2))
+#define     VPP_REG_SR_CH_SRC_H_POS               ((VPP_REG_SR_CH_BASE      ) + (18 << 2))
+#define     VPP_REG_SR_CH_SRC_V_POS               ((VPP_REG_SR_CH_BASE      ) + (19 << 2))
+#define     VPP_REG_SR_CH_DES_SETTING             ((VPP_REG_SR_CH_BASE      ) + (20 << 2))
+#define     VPP_REG_SR_CH_DES_H_POS               ((VPP_REG_SR_CH_BASE      ) + (21 << 2))
+#define     VPP_REG_SR_CH_DES_V_POS               ((VPP_REG_SR_CH_BASE      ) + (22 << 2))
+#define     VPP_REG_SR_CH_SRC_LINE_PITCH          ((VPP_REG_SR_CH_BASE      ) + (23 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_V_R             ((VPP_REG_SR_CH_BASE      ) + (24 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_R             ((VPP_REG_SR_CH_BASE      ) + (25 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_D             ((VPP_REG_SR_CH_BASE      ) + (26 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_K             ((VPP_REG_SR_CH_BASE      ) + (27 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_N             ((VPP_REG_SR_CH_BASE      ) + (28 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_V_R             ((VPP_REG_SR_CH_BASE      ) + (29 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_R             ((VPP_REG_SR_CH_BASE      ) + (30 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_D             ((VPP_REG_SR_CH_BASE      ) + (31 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_K             ((VPP_REG_SR_CH_BASE      ) + (32 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_N             ((VPP_REG_SR_CH_BASE      ) + (33 << 2))
+
+
+
+#define COEFF_DATA_NUM 640
+
+
+const long long cof3tap[COEFF_DATA_NUM]=
+{
+0x0000000824412412LL,0x00000008254453e0LL,0x00000008254773aeLL,0x00000008264a937dLL,0x00000008274db34cLL,0x000000082850c31cLL,0x000000082953d2ecLL,0x000000082a56c2beLL,
+0x000000082b59b290LL,0x000000082d5ca263LL,0x000000082e5f6238LL,0x000000082f62120eLL,0x000000083164b1e6LL,0x00000008326741beLL,0x000000083369a199LL,0x00000008346bf175LL,
+0x00000008356e3152LL,0x0000000836705131LL,0x0000000836724112LL,0x00000008367420f4LL,0x000000083675e0d8LL,0x00000008357770beLL,0x000000083478f0a5LL,0x00000008327a408eLL,
+0x00000008307b7079LL,0x000000082d7c8065LL,0x00000008297d7052LL,0x00000008257e4041LL,0x000000081f7ee031LL,0x00000008197f6023LL,0x00000008127fc016LL,0x00000008097fe00bLL,
+0x0000000000800000LL,0x000000000b7ff809LL,0x00000000167fb812LL,0x00000000237f6819LL,0x00000000317ee81fLL,0x00000000417e3825LL,0x00000000527d7829LL,0x00000000657c882dLL,
+0x00000000797b7830LL,0x000000008e7a4832LL,0x00000000a578f834LL,0x00000000be777835LL,0x00000000d875e836LL,0x00000000f4742836LL,0x0000000112724836LL,0x0000000131705836LL,
+0x00000001526e3835LL,0x00000001756c0834LL,0x000000019969a833LL,0x00000001be674832LL,0x00000001e664b831LL,0x000000020e62182fLL,0x00000002385f682eLL,0x00000002635c982dLL,
+0x000000029059b82bLL,0x00000002be56c82aLL,0x00000002ec53d829LL,0x000000031c50c828LL,0x000000034c4db827LL,0x000000037d4a9826LL,0x00000003ae477825LL,0x00000003e0444825LL,
+0x000000081640b40bLL,0x000000081542f3e6LL,0x00000008144533c1LL,0x000000081447839cLL,0x000000081349b378LL,0x00000008124bf353LL,0x00000008114e232fLL,0x000000081050430cLL,
+0x000000080f5262e9LL,0x000000080e5482c6LL,0x000000080d5692a4LL,0x000000080b588283LL,0x000000080a5a8262LL,0x00000008085c7241LL,0x00000008065e4222LL,0x0000000803600203LL,
+0x000000000061b1e5LL,0x00000000036351c8LL,0x000000000764d1acLL,0x000000000c664190LL,0x000000001067a176LL,0x000000001668e15cLL,0x000000001c6a1143LL,0x00000000236b212bLL,
+0x000000002a6c1115LL,0x00000000326cf0ffLL,0x000000003b6db0eaLL,0x00000000456e50d6LL,0x000000004f6ee0c3LL,0x000000005a6f50b1LL,0x00000000676f80a1LL,0x00000000746fb091LL,
+0x00000000826fc082LL,0x00000000916fc074LL,0x00000000a16f9067LL,0x00000000b16f405aLL,0x00000000c36ee04fLL,0x00000000d66e5045LL,0x00000000ea6db03bLL,0x00000000ff6cf032LL,
+0x00000001156c102aLL,0x000000012b6b2023LL,0x00000001436a101cLL,0x000000015c68e016LL,0x000000017667a010LL,0x000000019066400cLL,0x00000001ac64d007LL,0x00000001c8635003LL,
+0x00000001e561b000LL,0x0000000203600803LL,0x00000002225e4806LL,0x00000002415c6808LL,0x00000002625a880aLL,0x000000028358980bLL,0x00000002a456980dLL,0x00000002c654880eLL,
+0x00000002e952680fLL,0x000000030c504810LL,0x000000032f4e2811LL,0x00000003534bf812LL,0x000000037849b813LL,0x000000039c477814LL,0x00000003c1453814LL,0x00000003e642f815LL,
+0x000000080f407408LL,0x000000080e4293e5LL,0x000000080d44b3c2LL,0x000000080c46c3a0LL,0x000000080b48d37eLL,0x000000080a4ae35cLL,0x00000008084ce33aLL,0x00000008074ee319LL,
+0x000000080650e2f8LL,0x000000080452d2d7LL,0x000000080254b2b7LL,0x0000000000569297LL,0x0000000002586278LL,0x00000000055a2259LL,0x00000000085bd23bLL,0x000000000b5d821dLL,
+0x000000000f5f1200LL,0x00000000136091e4LL,0x000000001861f1c9LL,0x000000001d6351aeLL,0x0000000023649194LL,0x000000002965c17bLL,0x000000003066d163LL,0x000000003867d14bLL,
+0x000000004068c134LL,0x000000004969811fLL,0x00000000536a310aLL,0x000000005e6ac0f6LL,0x00000000696b40e3LL,0x00000000756bb0d0LL,0x00000000826bf0bfLL,0x00000000906c20aeLL,
+0x000000009f6c209fLL,0x00000000ae6c1090LL,0x00000000bf6bf082LL,0x00000000d06ba075LL,0x00000000e36b4069LL,0x00000000f66ad05eLL,0x000000010a6a3053LL,0x000000011f698049LL,
+0x000000013468b040LL,0x000000014b67d038LL,0x000000016366d030LL,0x000000017b65c029LL,0x0000000194649023LL,0x00000001ae63501dLL,0x00000001c961f018LL,0x00000001e4608013LL,
+0x00000002005f000fLL,0x000000021d5d700bLL,0x000000023b5bd008LL,0x00000002595a2005LL,0x0000000278586002LL,0x0000000297569000LL,0x00000002b754b802LL,0x00000002d752d804LL,
+0x00000002f850e806LL,0x00000003194ee807LL,0x000000033a4ce808LL,0x000000035c4ae80aLL,0x000000037e48d80bLL,0x00000003a046c80cLL,0x00000003c244b80dLL,0x00000003e542980eLL,
+0x0000000000400400LL,0x000000000141e3e1LL,0x000000000343a3c3LL,0x00000000044583a4LL,0x0000000006474386LL,0x0000000008490368LL,0x00000000094ae349LL,0x000000000c4c832cLL,
+0x000000000e4e430eLL,0x00000000105002f0LL,0x000000001351a2d3LL,0x00000000165342b6LL,0x000000001a54c29aLL,0x000000001e56427eLL,0x000000002257c262LL,0x0000000027592247LL,
+0x000000002c5a822cLL,0x00000000315be211LL,0x00000000385d01f8LL,0x000000003e5e41deLL,0x00000000455f61c5LL,0x000000004d6061adLL,0x0000000056614196LL,0x000000005f62217fLL,
+0x000000006962e169LL,0x000000007363a153LL,0x000000007e64413eLL,0x000000008a64c12aLL,0x0000000097652117LL,0x00000000a4658104LL,0x00000000b265c0f2LL,0x00000000c165e0e1LL,
+0x00000000d165e0d1LL,0x00000000e165d0c1LL,0x00000000f265b0b2LL,0x00000001046570a4LL,0x0000000117652097LL,0x000000012a64b08aLL,0x000000013e64307eLL,0x0000000153639073LL,
+0x000000016962e069LL,0x000000017f62205fLL,0x0000000196614056LL,0x00000001ad60504dLL,0x00000001c55f5045LL,0x00000001de5e403eLL,0x00000001f85d1038LL,0x00000002115bd031LL,
+0x000000022c5a902cLL,0x0000000247593027LL,0x000000026257c022LL,0x000000027e56501eLL,0x000000029a54c01aLL,0x00000002b6533016LL,0x00000002d351a013LL,0x00000002f04ff010LL,
+0x000000030e4e400eLL,0x000000032c4c900cLL,0x00000003494ad009LL,0x0000000368491008LL,0x0000000386474006LL,0x00000003a4457004LL,0x00000003c343a003LL,0x00000003e141d001LL,
+0x00000000233ee3efLL,0x00000000244063d6LL,0x000000002641c3beLL,0x00000000284333a5LL,0x000000002a44a38cLL,0x000000002c460374LL,0x000000002f47635bLL,0x000000003248b343LL,
+0x00000000354a132aLL,0x00000000394b5312LL,0x000000003e4c92f9LL,0x00000000424dd2e1LL,0x00000000484ef2c9LL,0x000000004d5022b1LL,0x0000000053514299LL,0x000000005a525281LL,
+0x0000000061536269LL,0x0000000069545252LL,0x000000007155423bLL,0x000000007a561225LL,0x000000008356f20eLL,0x000000008d57b1f8LL,0x00000000985861e2LL,0x00000000a35901cdLL,
+0x00000000af5991b8LL,0x00000000bb5a11a4LL,0x00000000c85a8190LL,0x00000000d55af17cLL,0x00000000e45b3169LL,0x00000000f25b8156LL,0x00000001015bb144LL,0x00000001115bc133LL,
+0x00000001225bc122LL,0x00000001335bc111LL,0x00000001445ba101LL,0x00000001565b70f2LL,0x00000001695b40e4LL,0x000000017c5af0d5LL,0x00000001905a80c8LL,0x00000001a45a10bbLL,
+0x00000001b85990afLL,0x00000001cd5900a3LL,0x00000001e2586098LL,0x00000001f857b08dLL,0x000000020e56f083LL,0x000000022556207aLL,0x000000023b554071LL,0x0000000252545069LL,
+0x0000000269535061LL,0x000000028152505aLL,0x0000000299514053LL,0x00000002b150204dLL,0x00000002c94f0048LL,0x00000002e14dd042LL,0x00000002f94c903eLL,0x00000003124b5039LL,
+0x000000032a4a0035LL,0x000000034348b032LL,0x000000035b47602fLL,0x000000037446002cLL,0x000000038c44a02aLL,0x00000003a5433028LL,0x00000003be41d026LL,0x00000003d6406024LL,
+0x00000000383e43e4LL,0x00000000393f93ceLL,0x000000003a40d3b9LL,0x000000003c4213a3LL,0x000000003e43538dLL,0x0000000041448377LL,0x000000004445b361LL,0x000000004846e34aLL,
+0x000000004c480334LL,0x000000005049231eLL,0x00000000554a3308LL,0x000000005a4b52f1LL,0x00000000604c52dbLL,0x00000000674d42c5LL,0x000000006e4e32afLL,0x00000000754f2299LL,
+0x000000007d500283LL,0x000000008650d26dLL,0x000000008f519258LL,0x0000000098526242LL,0x00000000a353022dLL,0x00000000ad53b218LL,0x00000000b9544203LL,0x00000000c454d1efLL,
+0x00000000d15541dbLL,0x00000000de55b1c7LL,0x00000000eb5611b4LL,0x00000000f95671a0LL,0x000000010856a18eLL,0x000000011756e17bLL,0x000000012657016aLL,0x0000000136572158LL,
+0x0000000147572147LL,0x0000000158571136LL,0x000000016a570126LL,0x000000017b56e117LL,0x000000018e56a108LL,0x00000001a05660f9LL,0x00000001b45610ebLL,0x00000001c755b0deLL,
+0x00000001db5540d1LL,0x00000001ef54d0c4LL,0x00000002035440b9LL,0x000000021853b0adLL,0x000000022d5310a3LL,0x0000000242526098LL,0x000000025851a08fLL,0x000000026d50d086LL,
+0x000000028350007dLL,0x00000002994f2075LL,0x00000002af4e406eLL,0x00000002c54d4067LL,0x00000002db4c5060LL,0x00000002f14b405aLL,0x00000003084a3055LL,0x000000031e492050LL,
+0x000000033448004cLL,0x000000034a46e048LL,0x000000036145b044LL,0x0000000377448041LL,0x000000038d43503eLL,0x00000003a342103cLL,0x00000003b940d03aLL,0x00000003ce3f9039LL,
+0x00000000453dd3deLL,0x00000000453f13caLL,0x00000000474043b5LL,0x00000000494163a1LL,0x000000004b42938cLL,0x000000004e43a378LL,0x000000005144c363LL,0x000000005445e34eLL,
+0x000000005946e339LL,0x000000005d47f324LL,0x000000006348e30fLL,0x000000006849f2f9LL,0x000000006f4ad2e4LL,0x00000000754bc2cfLL,0x000000007d4c92baLL,0x00000000854d62a5LL,
+0x000000008d4e3290LL,0x00000000964ef27bLL,0x000000009f4fb266LL,0x00000000a9506251LL,0x00000000b450f23dLL,0x00000000bf518229LL,0x00000000cb521214LL,0x00000000d7528201LL,
+0x00000000e452f1edLL,0x00000000f15351daLL,0x00000000ff53b1c6LL,0x000000010d53f1b4LL,0x000000011c5431a1LL,0x000000012b54618fLL,0x000000013a54917dLL,0x000000014b54916cLL,
+0x000000015b54a15bLL,0x000000016c54914bLL,0x000000017d54813aLL,0x000000018f54612bLL,0x00000001a154311cLL,0x00000001b453f10dLL,0x00000001c653b0ffLL,0x00000001da5360f1LL,
+0x00000001ed52f0e4LL,0x00000002015280d7LL,0x00000002145210cbLL,0x00000002295180bfLL,0x000000023d50f0b4LL,0x00000002515050a9LL,0x00000002664fb09fLL,0x000000027b4ef096LL,
+0x00000002904e308dLL,0x00000002a54d7085LL,0x00000002ba4c907dLL,0x00000002cf4bc075LL,0x00000002e44ad06fLL,0x00000002f949e068LL,0x000000030f48f063LL,0x000000032447f05dLL,
+0x000000033946f059LL,0x000000034e45e054LL,0x000000036344c051LL,0x000000037843b04eLL,0x000000038c42904bLL,0x00000003a1416049LL,0x00000003b5404047LL,0x00000003ca3f1045LL,
+0x00000000523d73d7LL,0x00000000533e93c4LL,0x00000000543fa3b2LL,0x000000005640b39fLL,0x000000005841d38bLL,0x000000005b42d378LL,0x000000005e43e364LL,0x000000006244d351LL,
+0x000000006645d33dLL,0x000000006b46c329LL,0x000000007147a315LL,0x0000000077488301LL,0x000000007d4962edLL,0x00000000854a32d8LL,0x000000008c4b02c4LL,0x00000000954bb2b0LL,
+0x000000009d4c729cLL,0x00000000a74d1288LL,0x00000000b14db274LL,0x00000000bb4e5260LL,0x00000000c64ee24cLL,0x00000000d14f7238LL,0x00000000dd4fe225LL,0x00000000ea504212LL,
+0x00000000f750b1feLL,0x00000001045111ebLL,0x00000001125151d9LL,0x00000001215191c6LL,0x000000012f51d1b4LL,0x000000013f51f1a2LL,0x000000014e521191LL,0x000000015e522180LL,
+0x000000016f52216fLL,0x000000018052215eLL,0x000000019152114eLL,0x00000001a251f13fLL,0x00000001b451c12fLL,0x00000001c6519121LL,0x00000001d9515112LL,0x00000001eb510104LL,
+0x00000001fe50b0f7LL,0x00000002125050eaLL,0x00000002254fe0ddLL,0x00000002384f60d1LL,0x000000024c4ee0c6LL,0x00000002604e50bbLL,0x00000002744dc0b1LL,0x00000002884d20a7LL,
+0x000000029c4c709dLL,0x00000002b04bb095LL,0x00000002c44af08cLL,0x00000002d84a3085LL,0x00000002ed49607dLL,0x0000000301488077LL,0x000000031547a071LL,0x000000032946c06bLL,
+0x000000033d45d066LL,0x000000035144d062LL,0x000000036443e05eLL,0x000000037842d05bLL,0x000000038b41d058LL,0x000000039f40c056LL,0x00000003b23fa054LL,0x00000003c43e9053LL,
+0x00000000593d33d4LL,0x00000000593e53c2LL,0x000000005a3f63b0LL,0x000000005c40739dLL,0x000000005e41738bLL,0x0000000061427378LL,0x0000000064437365LL,0x0000000068446352LL,
+0x000000006d45433fLL,0x000000007246332bLL,0x0000000078470318LL,0x000000007e47e304LL,0x000000008448c2f0LL,0x000000008c4972ddLL,0x00000000944a32c9LL,0x000000009c4af2b5LL,
+0x00000000a54ba2a1LL,0x00000000af4c328eLL,0x00000000b94cd27aLL,0x00000000c34d7266LL,0x00000000ce4df253LL,0x00000000da4e6240LL,0x00000000e64ee22cLL,0x00000000f34f4219LL,
+0x00000001004fa206LL,0x000000010d4ff1f4LL,0x000000011b5041e1LL,0x000000012a5071cfLL,0x000000013850b1bdLL,0x000000014850d1abLL,0x000000015750f19aLL,0x0000000167510189LL,
+0x0000000178510178LL,0x0000000189510167LL,0x000000019a50f157LL,0x00000001ab50d148LL,0x00000001bd50b138LL,0x00000001cf50812aLL,0x00000001e150411bLL,0x00000001f44ff10dLL,
+0x00000002064fa100LL,0x00000002194f40f3LL,0x000000022c4ee0e6LL,0x00000002404e70daLL,0x00000002534df0ceLL,0x00000002664d60c3LL,0x000000027a4cd0b9LL,0x000000028e4c40afLL,
+0x00000002a14ba0a5LL,0x00000002b54af09cLL,0x00000002c94a3094LL,0x00000002dd49808cLL,0x00000002f048b084LL,0x000000030447e07eLL,0x0000000318471078LL,0x000000032b463072LL,
+0x000000033f45506dLL,0x0000000352446068LL,0x0000000365437064LL,0x0000000378427061LL,0x000000038b41705eLL,0x000000039d40705cLL,0x00000003b03f605aLL,0x00000003c23e5059LL,
+0x00000000643ce3ceLL,0x00000000643df3bdLL,0x00000000653ef3acLL,0x00000000673fe39bLL,0x000000006940e389LL,0x000000006c41c378LL,0x000000006f42b366LL,0x000000007343a353LL,
+0x0000000078447341LL,0x000000007d45532eLL,0x000000008346131cLL,0x000000008946e309LL,0x000000009047a2f6LL,0x00000000984852e3LL,0x00000000a04902d0LL,0x00000000a849b2bdLL,
+0x00000000b24a42aaLL,0x00000000bb4ae297LL,0x00000000c64b6284LL,0x00000000d14be271LL,0x00000000dc4c625eLL,0x00000000e84cd24bLL,0x00000000f44d4238LL,0x00000001014da225LL,
+0x000000010e4df213LL,0x000000011c4e4200LL,0x000000012a4e81eeLL,0x00000001384ec1dcLL,0x00000001474ee1cbLL,0x00000001564f11b9LL,0x00000001664f21a8LL,0x00000001764f3197LL,
+0x00000001864f4186LL,0x00000001974f3176LL,0x00000001a84f2166LL,0x00000001b94f0156LL,0x00000001cb4ee147LL,0x00000001dc4eb138LL,0x00000001ee4e812aLL,0x00000002004e411cLL,
+0x00000002134df10eLL,0x00000002254da101LL,0x00000002384d40f4LL,0x000000024b4ce0e8LL,0x000000025e4c70dcLL,0x00000002714bf0d1LL,0x00000002844b70c6LL,0x00000002974ae0bbLL,
+0x00000002aa4a50b2LL,0x00000002bd49b0a8LL,0x00000002d04900a0LL,0x00000002e3485098LL,0x00000002f647a090LL,0x000000030946e089LL,0x000000031c462083LL,0x000000032e45507dLL,
+0x0000000341447078LL,0x000000035343a073LL,0x000000036642b06fLL,0x000000037841d06cLL,0x000000038940e069LL,0x000000039b3fe067LL,0x00000003ac3ef065LL,0x00000003bd3de064LL
+};
+
+const long long cof4tap[COEFF_DATA_NUM]=
+{
+0x0000000000400000LL,0x0000200809400411LL,0x0000201812bff420LL,0x000020201d3fc42eLL,0x0000202827bf8c3bLL,0x0000203833bf3c47LL,0x000020403fbedc52LL,0x000020504cbe645bLL,
+0x000020605a3de464LL,0x00002070683d4c6bLL,0x0000208076bcac72LL,0x00002090863bec77LL,0x000020a0963b247cLL,0x000020b0a6ba4c80LL,0x000020c8b7b96482LL,0x000020d8c9386c84LL,
+0x000020f0dbb76c86LL,0x00002108ee365c86LL,0x0000212101354486LL,0x0000213914b42486LL,0x0000215928b2fc85LL,0x000021713d31bc83LL,0x0000219151b08481LL,0x000021b166af3c7eLL,
+0x000021d17c2df47cLL,0x000021f1922c9478LL,0x00002211a7ab4475LL,0x00002231be29dc71LL,0x00002259d428846dLL,0x00002279eaa71c69LL,0x000022a20125bc65LL,0x000022c217a45461LL,
+0x000022e22e22e45cLL,0x0000230a45217c58LL,0x0000232a5ba01454LL,0x0000234a719eac4fLL,0x0000236a881d444bLL,0x0000238a9d9be446LL,0x000023aab41a7c42LL,0x000023c2c919243eLL,
+0x000023e2df17c43aLL,0x000023f2f3966c36LL,0x0000240b08151c32LL,0x0000241b1b93d42eLL,0x0000242b2f928c2bLL,0x0000243342114c27LL,0x0000243354101424LL,0x00002433658ee421LL,
+0x00002433768dbc1eLL,0x00002423868c941bLL,0x00002413960b7c19LL,0x00002403a48a6c16LL,0x000023e3b2096414LL,0x000023bbbe886412LL,0x00002393ca876c10LL,0x0000235bd486840eLL,
+0x00002323de05a40cLL,0x000022dbe604cc0aLL,0x00002293ed83fc08LL,0x0000223bf3833c07LL,0x000021dbf8827c05LL,0x00002173fc01d404LL,0x00002103ff012c03LL,0x0000208a00004a00LL,
+0x000020c868b3b8d1LL,0x000020d07233c0beLL,0x000020d07c33a8adLL,0x000020d886b3909cLL,0x000020e091b3708bLL,0x000020e09cb3387cLL,0x000020e8a833006dLL,0x000020f0b3b2c05fLL,
+0x000020f8c0327051LL,0x00002100cc321845LL,0x00002108d931b039LL,0x00002118e631482eLL,0x00002120f330d823LL,0x0000212900b05819LL,0x000021310eafc810LL,0x000021411caf3808LL,
+0x000021492aaea000LL,0x00002151392dfc07LL,0x0000216147ad5c0eLL,0x00002169562cac14LL,0x00002179652bf419LL,0x00002181742b341eLL,0x00002189832a7423LL,0x0000219192a9a427LL,
+0x00002199a1a8d42aLL,0x000021a1b127fc2dLL,0x000021a9c0a71c2fLL,0x000021b1cfa64c32LL,0x000021b9df256433LL,0x000021b9ee248435LL,0x000021b9fda39436LL,0x000021ba0ca2ac37LL,
+0x000021ba1ba1bc37LL,0x000021ba2aa0cc37LL,0x000021b2391fdc37LL,0x000021aa481ee437LL,0x0000219a561df437LL,0x00002192649cfc36LL,0x0000217a719c0c35LL,0x0000216a7f9b1434LL,
+0x000021528d1a1c33LL,0x0000213a9a192c32LL,0x0000211aa7183431LL,0x000020f2b3174430LL,0x000020cabf16542fLL,0x000020a2ca95642dLL,0x00002072d5947c2cLL,0x0000203adf93942aLL,
+0x00000002ea12ac29LL,0x00000042f391cc28LL,0x00000082fc90ec26LL,0x000000cb05900c25LL,0x0000011b0d8f3424LL,0x00000173148e6423LL,0x000001cb1b0d9421LL,0x0000022b218cc420LL,
+0x0000028b270c041fLL,0x000002fb2c0b3c1eLL,0x0000036b300a841dLL,0x000003e33389cc1cLL,0x0000045b37091c1cLL,0x000004e339086c1bLL,0x0000056b3a87c41aLL,0x000005f33c07241aLL,
+0x000020d87db128fbLL,0x000020d8873120e9LL,0x000020d8913110d7LL,0x000020e09b3100c6LL,0x000020e0a5b0d8b6LL,0x000020e0b030b0a6LL,0x000020e8bb308097LL,0x000020f0c6b04089LL,
+0x000020f0d22ff87bLL,0x000020f8de2fa86eLL,0x00002100ea2f5861LL,0x00002108f62f0055LL,0x0000210902ae904aLL,0x000021110f2e2040LL,0x000021191c2da836LL,0x00002121292d302cLL,
+0x0000212936aca024LL,0x0000212943ac181bLL,0x00002131512b8014LL,0x000021395f2ae00dLL,0x000021416caa4806LL,0x000021417aa99800LL,0x0000214988a8f406LL,0x000021499628440bLL,
+0x00002151a4278c0fLL,0x00002151b226cc13LL,0x00002151c0260c17LL,0x00002151ce25441aLL,0x00002149dc24741dLL,0x00002149ea23ac20LL,0x00002141f7a2dc22LL,0x0000213a05220c24LL,
+0x0000213213213426LL,0x0000212220a05427LL,0x000021122d9f7c28LL,0x000021023a9ea429LL,0x000020ea471dc429LL,0x000020d2541ce42aLL,0x000020ba609c042aLL,0x0000209a6c9b242aLL,
+0x0000207a789a442aLL,0x0000205a84196429LL,0x000020328f188c29LL,0x000000029997ac28LL,0x00000032a496cc28LL,0x0000006aae15f427LL,0x000000a2b8151426LL,0x000000dac1943c25LL,
+0x00000122ca136c25LL,0x00000162d3129424LL,0x000001b2da91c423LL,0x00000202e210f422LL,0x00000252e9102c21LL,0x000002aaf00f6421LL,0x0000030af58ea420LL,0x00000372fa8de41fLL,
+0x000003daff8d241eLL,0x0000044b040c6c1eLL,0x000004bb080bb41dLL,0x000005330b0b041cLL,0x000005b30d8a5c1cLL,0x000006331009b41cLL,0x000006bb1109141bLL,0x0000074b1208741bLL,
+0x000020c0a02cc140LL,0x000020b8a92cb92eLL,0x000020b8b22cb11dLL,0x000020b8bbac990dLL,0x000020b8c52c80fdLL,0x000020b8cf2c60edLL,0x000020b8d92c38deLL,0x000020b8e32c10cfLL,
+0x000020b8edabd8c1LL,0x000020b8f82b98b4LL,0x000020b9032b50a7LL,0x000020b90dab109aLL,0x000020b9192ab88eLL,0x000020b9242a6083LL,0x000020b92faa0078LL,0x000020b93aa9a86dLL,
+0x000020b146293863LL,0x000020b151a8c85aLL,0x000020b15da85051LL,0x000020a96927d848LL,0x000020a975275840LL,0x000020a180a6d039LL,0x000020998ca64032LL,0x0000209198a5b02bLL,
+0x00002089a4252025LL,0x00002081b024881fLL,0x00002071bba3f019LL,0x00002069c7235814LL,0x00002059d2a2b80fLL,0x00002041de22080bLL,0x00002031e9a16007LL,0x00002019f520b003LL,
+0x0000000200200000LL,0x0000001a0b1f5403LL,0x0000003a161e9c06LL,0x0000005a209de408LL,0x0000007a2b9d2c0bLL,0x000000a2359c740dLL,0x000000ca3f1bbc0eLL,0x000000fa489b0410LL,
+0x0000012a521a4411LL,0x0000015a5b198c12LL,0x000001926418cc13LL,0x000001ca6d180c14LL,0x0000020275975415LL,0x000002427d969415LL,0x0000028a8515dc16LL,0x000002d28c951c16LL,
+0x0000031a93946416LL,0x0000036a9a93ac17LL,0x000003c2a012fc17LL,0x0000041aa6124417LL,0x00000472ab919417LL,0x000004d2b110dc17LL,0x0000053ab5103417LL,0x000005a2b98f8417LL,
+0x0000060abd8edc17LL,0x0000067ac10e3417LL,0x000006f2c38d9417LL,0x0000076ac60cf417LL,0x000007eac80c5417LL,0x0000086ac98bbc17LL,0x000008eacb0b2417LL,0x00000972cb8a9417LL,
+0x00000000d0a5f1a1LL,0x00000008d825e992LL,0x00000010e025d983LL,0x00000010e7a5d974LL,0x00000018efa5c166LL,0x00000020f7a5a958LL,0x000000290025894aLL,0x000000310825713cLL,
+0x0000003910a5492fLL,0x0000004118a52922LL,0x000000512124f915LL,0x0000005929a4c909LL,0x00000061322498fdLL,0x000000713aa460f1LL,0x00000081432420e6LL,0x000000894c23e8daLL,
+0x0000009954a3a0d0LL,0x000000b15d2358c5LL,0x000000c165a310bbLL,0x000000d16ea2c0b1LL,0x000000e9772268a8LL,0x000001017fa2109fLL,0x000001198821b896LL,0x0000013190a1608dLL,
+0x000001519920f885LL,0x00000169a120a07dLL,0x00000189a9a03875LL,0x000001a9b19fd06eLL,0x000001d1b99f6067LL,0x000001f9c19ef060LL,0x00000221c99e785aLL,0x00000249d19e0054LL,
+0x00000271d91d904eLL,0x000002a1e01d1849LL,0x000002d1e79c9844LL,0x00000301ef1c183fLL,0x00000339f61b983aLL,0x00000371fd1b1835LL,0x000003aa039a9831LL,0x000003ea0a1a102dLL,
+0x0000042a0f99902aLL,0x0000046a16190826LL,0x000004b21b988023LL,0x000004fa2117f820LL,0x000005422697701dLL,0x0000058a2c16e81aLL,0x000005da31165818LL,0x0000062a3595d016LL,
+0x000006823a154813LL,0x000006d23e94c011LL,0x0000073242143010LL,0x0000078a4613a80eLL,0x000007ea4993200cLL,0x0000084a4c92980bLL,0x000008aa4f92100aLL,0x0000091252918808LL,
+0x0000097a54910807LL,0x000009e257108006LL,0x00000a5258900005LL,0x00000ac25a8f7804LL,0x00000b325c0ef803LL,0x00000ba25d8e7802LL,0x00000c1a5d8e0002LL,0x00000c925e8d8001LL,
+0x000000a8e422d9c8LL,0x000000b0eb22d1baLL,0x000000b0f1a2d9acLL,0x000000b8f8a2c99fLL,0x000000c0ffa2b992LL,0x000000d106a2a185LL,0x000000d90e228978LL,0x000000e11522796bLL,
+0x000000f11c22615eLL,0x000000f923a24152LL,0x000001092aa22146LL,0x000001193221f93aLL,0x0000012939a1d12eLL,0x0000013940a1a923LL,0x0000015148217118LL,0x000001614f21490dLL,
+0x0000017956a11102LL,0x000001915da0d8f8LL,0x000001a96520a0edLL,0x000001c96c2060e3LL,0x000001e173a018daLL,0x000002017a9fd8d0LL,0x00000221819f90c7LL,0x00000241889f48beLL,
+0x000002698f9ef8b5LL,0x00000289969ea8adLL,0x000002b19d1e58a5LL,0x000002d9a39e089dLL,0x00000309aa9da895LL,0x00000331b11d508eLL,0x00000361b71d0086LL,0x00000391bd9c9880LL,
+0x000003c9c39c3879LL,0x00000401c99bd872LL,0x00000431d01b706cLL,0x00000471d51b1066LL,0x000004a9da9aa861LL,0x000004e9e09a385bLL,0x00000529e599d056LL,0x00000569ea996851LL,
+0x000005a9ef98f84dLL,0x000005f1f4988848LL,0x00000639f9181844LL,0x00000681fd97a840LL,0x000006d20197383cLL,0x0000071a0616c039LL,0x0000076a0a165035LL,0x000007c20d95d832LL,
+0x000008121115682fLL,0x0000086a1494f02cLL,0x000008c21714802aLL,0x0000091a1a940827LL,0x000009721d139825LL,0x000009d21f932023LL,0x00000a322212a821LL,0x00000a922412381fLL,
+0x00000af22611c01eLL,0x00000b5a2791501cLL,0x00000bc22890e01bLL,0x00000c2a2a10681aLL,0x00000c922b8ff818LL,0x00000cfa2c8f8817LL,0x00000d622d8f1816LL,0x00000dd22d0eb016LL,
+0x00000118eda139dbLL,0x00000120f42131ceLL,0x00000128fa2131c1LL,0x0000013100a129b4LL,0x00000139072119a8LL,0x000001410da1119bLL,0x0000014914a0f98fLL,0x000001591b20e183LL,
+0x0000016121a0d177LL,0x000001712820b96bLL,0x000001812f209160LL,0x0000019135a07954LL,0x000001a93c205149LL,0x000001b942a0313eLL,0x000001d149a00133LL,0x000001e9501fd928LL,
+0x00000201569fb11dLL,0x000002215d1f7913LL,0x00000239639f4909LL,0x000002596a1f10ffLL,0x00000279709ed8f5LL,0x00000299769ea0ecLL,0x000002c17d1e60e2LL,0x000002e9831e20d9LL,
+0x00000311899dd8d0LL,0x000003398f9d90c8LL,0x00000361959d50bfLL,0x000003919b9d00b7LL,0x000003c1a11cb8afLL,0x000003f1a71c68a7LL,0x00000421ac9c18a0LL,0x00000459b21bc898LL,
+0x00000489b79b7891LL,0x000004c1bc9b208bLL,0x00000501c19ac884LL,0x00000539c69a707eLL,0x00000579cb9a1078LL,0x000005b9d019b872LL,0x000005f9d519586cLL,0x00000641d918f867LL,
+0x00000681dd989862LL,0x000006c9e218305dLL,0x00000711e617d058LL,0x00000761ea176853LL,0x000007a9ed97084fLL,0x000007f9f116a04bLL,0x00000849f4963847LL,0x00000899f795d044LL,
+0x000008e9fb156840LL,0x00000941fd95003dLL,0x0000099a0014983aLL,0x000009f203142837LL,0x00000a4a0513c035LL,0x00000aa207935832LL,0x00000b020912f030LL,0x00000b5a0b92802eLL,
+0x00000bba0d12182cLL,0x00000c1a0e11b02bLL,0x00000c7a0f914829LL,0x00000cda1110d828LL,0x00000d4211907027LL,0x00000da212900826LL,0x00000e0a130fa025LL,0x00000e72130f4024LL,
+0x000001a0f61fa1ecLL,0x000001a0fc1fa1e0LL,0x000001a9021f99d4LL,0x000001b1081f91c8LL,0x000001b90e1f81bdLL,0x000001c1141f79b1LL,0x000001c91a1f71a5LL,0x000001d9201f599aLL,
+0x000001e9261f498eLL,0x000001f92c1f3183LL,0x00000209321f1978LL,0x00000219381f016dLL,0x000002313e1ee162LL,0x00000249441ec157LL,0x000002614a1e994dLL,0x000002794f9e8142LL,
+0x00000299559e5138LL,0x000002b95b9e212eLL,0x000002d9611df924LL,0x000002f9671dc91aLL,0x000003196c9da110LL,0x00000341721d6907LL,0x00000369779d38fdLL,0x000003917d1d00f4LL,
+0x000003c1829cc0ebLL,0x000003e9881c88e2LL,0x000004198d1c48daLL,0x00000449929c08d1LL,0x00000479979bc8c9LL,0x000004b19c9b80c1LL,0x000004e1a19b40b9LL,0x00000519a61af8b2LL,
+0x00000551ab1ab0aaLL,0x00000591af9a60a3LL,0x000005c9b41a189cLL,0x00000609b819c896LL,0x00000649bc99788fLL,0x00000689c0992889LL,0x000006d1c498d083LL,0x00000711c898807dLL,
+0x00000759cc182878LL,0x000007a1d017d072LL,0x000007e9d397786dLL,0x00000839d6972068LL,0x00000881da16c863LL,0x000008d1dc96705fLL,0x00000921df96105bLL,0x00000971e215b857LL,
+0x000009c1e5155853LL,0x00000a11e814f84fLL,0x00000a69e994a04cLL,0x00000ab9ec144049LL,0x00000b11ee13e046LL,0x00000b69f0138043LL,0x00000bc1f1932041LL,0x00000c19f312c03fLL,
+0x00000c71f492603dLL,0x00000cd1f592003bLL,0x00000d29f711a039LL,0x00000d89f7914038LL,0x00000de9f810e037LL,0x00000e41f9108036LL,0x00000ea1f9902035LL,0x00000f01fa0fc034LL,
+0x000001e0fa1ee1f4LL,0x000001e0ff9ee9e8LL,0x000001e9059ed9ddLL,0x000001f10b1ed9d1LL,0x000001f9111ec9c6LL,0x00000201169ec9baLL,0x000002091c9eb9afLL,0x00000219221ea9a4LL,
+0x00000229281e9199LL,0x000002392d9e818eLL,0x00000249331e7183LL,0x00000261391e5178LL,0x000002793e9e316eLL,0x00000291441e1963LL,0x000002a94a1df958LL,0x000002c14f9dd94eLL,
+0x000002e1551db144LL,0x000003015a9d893aLL,0x00000321601d6130LL,0x00000349659d3126LL,0x000003696a9d091dLL,0x00000391701cd913LL,0x000003b9751ca90aLL,0x000003e97a1c7101LL,
+0x000004117f9c38f8LL,0x00000441849c00efLL,0x00000471891bd0e6LL,0x000004a18e1b90deLL,0x000004d1931b58d5LL,0x00000509979b18cdLL,0x000005419c1ad8c5LL,0x00000579a09a90beLL,
+0x000005b1a51a50b6LL,0x000005f1a91a08afLL,0x00000629ad99c0a8LL,0x00000669b19978a1LL,0x000006a9b599309aLL,0x000006f1b918e094LL,0x00000731bd18908eLL,0x00000779c0184888LL,
+0x000007c1c397f882LL,0x00000809c717a07dLL,0x00000851ca975077LL,0x00000899cd970072LL,0x000008e9d096a86dLL,0x00000931d3165869LL,0x00000981d6160064LL,0x000009d1d895a860LL,
+0x00000a21db15505cLL,0x00000a71dd94f858LL,0x00000ac1df94a055LL,0x00000b19e1944052LL,0x00000b71e313e84fLL,0x00000bc1e513904cLL,0x00000c19e7133049LL,0x00000c71e812d847LL,
+0x00000cc9e9128045LL,0x00000d21ea922043LL,0x00000d79eb91c841LL,0x00000dd1ec916840LL,0x00000e31ec91103fLL,0x00000e89ed90b03eLL,0x00000ee9ed90583dLL,0x00000f41ee8ff83cLL,
+0x00000250ff9dc1ffLL,0x00000251051dc1f4LL,0x000002590a1dc1e9LL,0x000002590f9db9dfLL,0x00000261151db1d4LL,0x000002711a9da1c9LL,0x000002791f9da1beLL,0x00000289251d89b4LL,
+0x000002992a9d79a9LL,0x000002a92f9d699fLL,0x000002b9351d5994LL,0x000002d13a1d418aLL,0x000002e93f9d297fLL,0x00000301449d1175LL,0x00000321499cf16bLL,0x000003394e9cd961LL,
+0x00000359539cb957LL,0x00000381589c914dLL,0x000003a15d9c7143LL,0x000003c9629c413aLL,0x000003f1671c2130LL,0x000004196c1bf127LL,0x00000441709bc91eLL,0x00000471751b9915LL,
+0x000004997a1b690cLL,0x000004c97e1b4103LL,0x00000501829b08faLL,0x00000531871ad0f2LL,0x000005698b1aa0e9LL,0x000005a18f9a60e1LL,0x000005d9939a28d9LL,0x000006119799f0d1LL,
+0x000006519b19b0caLL,0x000006899f1978c2LL,0x000006c9a29938bbLL,0x00000709a618f8b4LL,0x00000749aa18b0adLL,0x00000791ad1870a6LL,0x000007d1b09828a0LL,0x00000819b417e099LL,
+0x00000861b697a093LL,0x000008a9b997508eLL,0x000008f1bc970888LL,0x00000939bf16c083LL,0x00000981c216707eLL,0x000009d1c4162879LL,0x00000a19c715d874LL,0x00000a69c9158870LL,
+0x00000ab9cb95386bLL,0x00000b09cd94e867LL,0x00000b59cf149864LL,0x00000ba9d1144860LL,0x00000bf9d293f85dLL,0x00000c51d413a05aLL,0x00000ca1d5935057LL,0x00000cf9d692f855LL,
+0x00000d49d792a853LL,0x00000da1d8925051LL,0x00000df1da11f84fLL,0x00000e49da11a84eLL,0x00000ea1db11504cLL,0x00000ef9db90f84bLL,0x00000f49dc10a04bLL,0x00000fa1dc10504aLL
+};
+
+
+const long long cof6tap[COEFF_DATA_NUM]=
+{
+0x0000000080000000LL,0x00c050197fe83005LL,0x0140a0347fa85e09LL,0x01c1004f7f48880eLL,0x0241606c7ed8b212LL,0x0241c08a7e58d815LL,0x02c230a87db8fc19LL,0x034290c87ce91e1cLL,
+0x03c300e97c093c1eLL,0x0443710b7b095a21LL,0x04c3f12e79f97423LL,0x0544615278b98c25LL,0x05c4e1777769a227LL,0x06c5619d75e9b629LL,0x0745e1c37479c82aLL,0x07c661eb72d9d82bLL,
+0x0846f2137129e42cLL,0x08c7723b6f69f02dLL,0x0947f2656d89fa2dLL,0x0a48828e6baa022dLL,0x0ac902b9699a082dLL,0x0b4992e4677a0a2dLL,0x0c4a130f654a0e2dLL,0x0cca933b62fa0e2dLL,
+0x0d4b236660ca0c2cLL,0x0e4ba3925e5a0a2cLL,0x0ecc13be5bea062bLL,0x0f4c93eb596a002aLL,0x104d041756d9fa29LL,0x10cd74435449f228LL,0x114de46f51b9ea27LL,0x124e449a4f09e026LL,
+0x12cea4c54c59d425LL,0x134f04f049a9c824LL,0x13cf551b46f9bc22LL,0x144f95444439ae21LL,0x14cfd56d4179a020LL,0x155005963eb9921eLL,0x15d035be3be9821dLL,0x165055e53929741cLL,
+0x1650660c3669641aLL,0x16d0762f33b95219LL,0x16d0765430f94218LL,0x16d056772e493216LL,0x16d046992b992015LL,0x16d016ba28e91014LL,0x16cfd6d82658fe12LL,0x16cf86f623b8ee11LL,
+0x164f27122138de10LL,0x15cec72d1eb8cc0fLL,0x154e47471c38bc0eLL,0x14cdb75e19d8ac0dLL,0x13cd177617789c0bLL,0x12cc678b15288c0aLL,0x11cba79f12e87e09LL,0x10cad7b010b86e08LL,
+0x0f49e7c00e986007LL,0x0e48f7ce0c885206LL,0x0cc7e7db0a884605LL,0x0ac6c7e508a83804LL,0x094597ed06c82c04LL,0x074447f404f82003LL,0x04c2f7fa03481402LL,0x02c187fe01980a01LL,
+0x0846012666424d60LL,0x0846413e6622215cLL,0x084681556621f358LL,0x0846c16e65e1c954LL,0x0847018665b19f50LL,0x0847319f6561754cLL,0x084771b965014d48LL,0x0847b1d364912744LL,
+0x07c7e1ed64210140LL,0x07c8220863a0dd3dLL,0x07c852236300b939LL,0x07c8823e62509735LL,0x07c8b25a61907732LL,0x0748e27660d0572eLL,0x074902925ff0392bLL,0x074932ae5f101d28LL,
+0x06c952ca5e300125LL,0x06c972e65d281b21LL,0x064983035c18351eLL,0x0649a3205b084d1cLL,0x05c9b33c59e86319LL,0x05c9b35958887716LL,0x0549c37557788d14LL,0x0549c39256089f11LL,
+0x04c9c3ae54c8b10fLL,0x0449b3cb5358c10dLL,0x03c9a3e751e8d10aLL,0x034984035068df08LL,0x02c9641e4ef8eb07LL,0x0249443a4d68f705LL,0x01c914554bd90303LL,0x00c8e46f4a490b01LL,
+0x0048a48a48a91400LL,0x80c854a446f91c01LL,0x81c814bd45592203LL,0x82c7b4d643a92804LL,0x83c754ef41e92c05LL,0x8446f50640393006LL,0x8546851e3e793407LL,0x86c605353cb93608LL,
+0x87c5854c3ae93809LL,0x88c4f5603929380aLL,0x8a4465773759380aLL,0x8b43b5883599360bLL,0x8cc3159e33c9360bLL,0x8e4265b03209340cLL,0x8f41a5c13039300cLL,0x90c0d5d22e692e0dLL,
+0x928005e32ca92a0dLL,0x9400e5f12ae9260eLL,0x9581c5ff2929200eLL,0x9702b60d27691c0eLL,0x9903b61925a9160fLL,0x9a84b62523e9100fLL,0x9c85c63022390a0fLL,0x9e86e63a2089040fLL,
+0xa00806421ed8fc0fLL,0xa20936491d38f610LL,0xa40a66501b98ee10LL,0xa60ba65619f8e610LL,0xa80cf65b1868e010LL,0xaa0e465e16e8d810LL,0xac0f96621558d010LL,0xae11066213e8c810LL,
+0x06c6515e6012bd65LL,0x0646817460129362LL,0x0646a18a5ff2695fLL,0x05c6d1a15fe23f5cLL,0x05c701b85fa21758LL,0x05c721cf5f51f155LL,0x054751e75f21c952LL,0x054771ff5eb1a54fLL,
+0x04c792175e617f4cLL,0x04c7b22f5de15b48LL,0x0447d2485d613945LL,0x0447f2615cd11742LL,0x03c8027a5c30f73fLL,0x03c812935b80d73cLL,0x034822ac5ad0b939LL,0x034832c55a109b36LL,
+0x02c832df59307f33LL,0x024842f858706330LL,0x024843125770492dLL,0x01c8332b5670312aLL,0x0148234555701928LL,0x00c8135e54700125LL,0x0048037753681722LL,0x80c7e39152382b20LL,
+0x8147c3aa51183f1eLL,0x81c7a3c34fe8531bLL,0x824773db4eb86519LL,0x834733f44d687517LL,0x83c7040c4c288515LL,0x84c6c4244ad89313LL,0x8546743c4968a111LL,0x864624534818af0fLL,
+0x86c5d46a46a8bb0dLL,0x87c574814538c50cLL,0x88c5049643c8cf0aLL,0x89c494ad4248d909LL,0x8ac424c240c8e107LL,0x8bc3a4d63f48e706LL,0x8cc324eb3db8ef04LL,0x8dc294fe3c38f503LL,
+0x8f41f5113aa8f902LL,0x904155233918fd01LL,0x9140b53637790000LL,0x9280054735e90201LL,0x9400c55734590402LL,0x9501856732b90603LL,0x9682457731290804LL,0x980315872f890804LL,
+0x9983f5932df90605LL,0x9b04d5a12c590606LL,0x9c85c5ad2ac90406LL,0x9e06b5b829390207LL,0x9f87b5c327a90007LL,0xa108b5cd2618fe08LL,0xa289c5d62488fa08LL,0xa40ad5de22f8f609LL,
+0xa60bf5e62178f209LL,0xa78d25eb1ff8ee0aLL,0xa90e45f21e78ea0aLL,0xaa8f85f51cf8e40bLL,0xac10b5fa1b88e00bLL,0xae11f5fe1a18da0bLL,0xaf9345ff18a8d40cLL,0xb11496011748d00cLL,
+0x004571b054e36157LL,0x80c581c354e33d56LL,0x80c591d654d31955LL,0x814591e954c2f554LL,0x814591fd5492d153LL,0x81c5a2105472af51LL,0x8245a22454428d50LL,0x8245923853e26b4eLL,
+0x82c5924c53b2494dLL,0x834592605362294bLL,0x8345827452f20949LL,0x83c5728852a1e948LL,0x8445629c5231cb46LL,0x84c542b151a1ad44LL,0x854522c551218f42LL,0x854502d950817340LL,
+0x85c4e2ed4ff1573eLL,0x8644c3024f413d3cLL,0x86c493164e91233aLL,0x8744632a4de10938LL,0x87c4233e4d20ef36LL,0x8843f3524c60d734LL,0x8943b3664b90c132LL,0x89c363794ac0a930LL,
+0x8a43238d49e0932eLL,0x8ac2d3a048f07f2cLL,0x8bc273b348006b2aLL,0x8c4223c647205729LL,0x8d41c3d846304527LL,0x8dc153eb45103325LL,0x8ec0f3fd44202123LL,0x8f40740e43101122LL,
+0x9000042042000120LL,0x9100843140e80f1eLL,0x918104423fd81f1dLL,0x928194513eb82b1bLL,0x938224633d88391aLL,0x9482b4723c684518LL,0x950354803b384f17LL,0x9603f48f3a085b15LL,
+0x9704949e38d86514LL,0x980544ac37986d13LL,0x990604b936687712LL,0x9a06b4c635287f10LL,0x9b0774d233e8850fLL,0x9c0844de32a88d0eLL,0x9d0914e93168930dLL,0x9e09e4f43028990cLL,
+0x9f0ab4ff2ed89d0bLL,0xa00b95082d98a10aLL,0xa10c75122c58a50aLL,0xa20d651a2b18a909LL,0xa30e552329c8ad08LL,0xa40f452a2888af07LL,0xa490452f2748b106LL,0xa59145362608b306LL,
+0xa692453b24c8b305LL,0xa713553e2388b304LL,0xa81465442248b504LL,0xa89575472108b503LL,0xa99685491fd8b302LL,0xaa17a54c1e98b302LL,0xaa98c54d1d68b301LL,0xab19e54e1c38b101LL,
+0x890001ff4143fe00LL,0x8900320c4123e702LL,0x890052184133cf05LL,0x890082244123b707LL,0x8900b23141139d09LL,0x8900f23d40f3850bLL,0x8981224a40e36d0dLL,0x8981525640c3550eLL,
+0x8981926340833f10LL,0x8981d26f40532711LL,0x8a02127b40430f13LL,0x8a0252883ff2f914LL,0x8a02a2943fb2e115LL,0x8a02e2a03f72cb16LL,0x8a8332ac3f32b517LL,0x8a8382b83ee29f18LL,
+0x8a83d2c43e828918LL,0x8b0422d03e427319LL,0x8b0482dc3dd25d19LL,0x8b04e2e73d82471aLL,0x8b8542f33d12331aLL,0x8b85a2fe3cb21f1bLL,0x8b86030a3c320b1bLL,0x8c0663153bd1f71bLL,
+0x8c06d3203b51e31bLL,0x8c87432b3ae1cf1bLL,0x8c87b3353a61bd1bLL,0x8c88234039d1ab1bLL,0x8d08a34a3951991bLL,0x8d09135438d1871bLL,0x8d09935e3841751bLL,0x8d0a136837b1631bLL,
+0x8d8a93723721531bLL,0x8d8b137b3681431aLL,0x8d8ba38435e1331aLL,0x8d8c338d3541231aLL,0x8d8cc39534a1151aLL,0x8d8d539d34010519LL,0x8d8de3a63350f719LL,0x8d8e73ae32b0e919LL,
+0x8d8f13b53200db18LL,0x8d8fb3bd3150cd18LL,0x8d9053c330a0c117LL,0x8d90f3cb2fe0b517LL,0x8d1193d12f30a917LL,0x8d1233d82e709d16LL,0x8c92e3dd2dc09116LL,0x8c9393e42d008516LL,
+0x8c1443e82c407b15LL,0x8c14f3ee2b807115LL,0x8b95a3f32ac06715LL,0x8b1653f72a005d14LL,0x8a9703fb29405514LL,0x8a17c3ff28804b14LL,0x8998740427b04314LL,0x8899340526f03b13LL,
+0x8819f40826303313LL,0x871aa40c25602b13LL,0x869b640e24a02513LL,0x859c240f23d01f12LL,0x849ce41123101712LL,0x839db41222401112LL,0x829e741321800b12LL,0x811f341220c00712LL,
+0x8584120737b40e41LL,0x8584421037c3fc3dLL,0x8584821a37a3ea3aLL,0x8504c2233793d836LL,0x8505022c3793c433LL,0x850542353783b230LL,0x8505823e3773a02dLL,0x8505d24737538e2aLL,
+0x8486125037337c27LL,0x8486625937136825LL,0x8486b26236f35622LL,0x8487026a36d34420LL,0x8487527336b3321dLL,0x8407a27c3673201bLL,0x8407f28436530e19LL,0x8408428d3622fc17LL,
+0x8408a29535e2ec15LL,0x8389029e3592da13LL,0x838952a63572c811LL,0x8389b2ae3532b610LL,0x830a12b634e2a60eLL,0x830a72be34b2940cLL,0x830ae2c63452840bLL,0x828b42ce34027409LL,
+0x828ba2d533d26208LL,0x820c12dd33625207LL,0x820c82e433124206LL,0x818cf2eb32b23205LL,0x818d62f332522204LL,0x810dd2f932021203LL,0x808e430031920402LL,0x808eb3073141f401LL,
+0x000f330d30d1e600LL,0x008fa3143071d701LL,0x011023193001c901LL,0x019093202f91bb02LL,0x021113252f31ad03LL,0x0291932b2eb19f03LL,0x031213312e419104LL,0x039293362dd18304LL,
+0x0413133d2d517505LL,0x0493a3402ce16905LL,0x059423452c615d06LL,0x0614a34b2be14f06LL,0x0715334e2b614306LL,0x0815b3532ae13707LL,0x089643572a612b07LL,0x0996d35929e12107LL,
+0x0a97635e29511508LL,0x0b97e36228d10908LL,0x0c9873652840ff08LL,0x0d99036727c0f508LL,0x0e99936b2730eb09LL,0x101a236d26a0e109LL,0x111ab36f2620d709LL,0x129b43712590cd09LL,
+0x139be3732500c309LL,0x151c73752470bb0aLL,0x169d037723e0b10aLL,0x181d93782350a90aLL,0x199e237922c0a10aLL,0x1b1ec3792230990aLL,0x1d1f537a21a0910bLL,0x1e9fe37c2100890bLL,
+0x0006820332a40668LL,0x0006c20b3293f864LL,0x008702123293e860LL,0x0087421a3283da5cLL,0x008782213283ca59LL,0x0107d2283273ba55LL,0x010812303263aa52LL,0x0188623732439c4eLL,
+0x0188b23e32338c4bLL,0x0188f24532337c48LL,0x0209424c32036e45LL,0x0209925431e35e42LL,0x0289e25a31c3503fLL,0x028a326131b3403cLL,0x030a926831833039LL,0x030ae26f31532237LL,
+0x038b327631331234LL,0x040b927c30f30432LL,0x040bf28330d2f42fLL,0x048c428930a2e62dLL,0x050ca2903062d62bLL,0x050d02963032c829LL,0x058d629c2ff2ba27LL,0x060dc2a22fc2aa25LL,
+0x068e22a82f829c23LL,0x070e82ae2f428e21LL,0x078ef2b42ef2801fLL,0x080f52ba2ec2701dLL,0x088fb2bf2e82621cLL,0x091022c52e32541aLL,0x099082ca2de24819LL,0x0a90f2cf2d923a17LL,
+0x0b1162d42d422c16LL,0x0b91d2d92cf21e15LL,0x0c9242de2ca21013LL,0x0d12a2e32c520412LL,0x0e1312e82bf1f611LL,0x0e9382ec2ba1ea10LL,0x0f9402ef2b41de0fLL,0x109472f42ae1d00eLL,
+0x1194e2f82a81c40dLL,0x129552fc2a21b80cLL,0x1395d2ff29c1ac0bLL,0x149643032961a00aLL,0x1596b3062901940aLL,0x1697330a28918809LL,0x1797a30d28317e08LL,0x1918230f27c17208LL,
+0x1a18931327616607LL,0x1b99131526f15c06LL,0x1c99831826815206LL,0x1e1a031b26114605LL,0x1f9a831c25a13c05LL,0x211af31e25413204LL,0x229b732024c12804LL,0x241be32324511e03LL,
+0x259c632323e11603LL,0x271ce32423710c03LL,0x291d532623010202LL,0x2a9dd3272280fa02LL,0x2c9e53282210f001LL,0x2e1ed32821a0e801LL,0x301f43292120e001LL,0x321fc32920b0d800LL,
+0x090901fa2da3f490LL,0x090942002da3e88cLL,0x090982062da3dc88LL,0x0989d20c2d83d084LL,0x098a12112d93c480LL,0x098a62172d83b87cLL,0x0a0aa21d2d83aa78LL,0x0a0af2232d639e75LL,
+0x0a8b32282d639271LL,0x0b0b822e2d33866eLL,0x0b0bd2332d337a6aLL,0x0b8c22392d136c67LL,0x0c0c723e2d036063LL,0x0c0cc2432cf35460LL,0x0c8d12492cc3485dLL,0x0d0d624e2cb33a5aLL,
+0x0d8db2532c932e57LL,0x0e0e02582c732254LL,0x0e8e625d2c431651LL,0x0f0eb2622c33084eLL,0x0f8f02672c02fc4cLL,0x100f626c2bd2f049LL,0x108fb2702bc2e446LL,0x119012752b82d644LL,
+0x1210627a2b62ca41LL,0x1290c27e2b32be3fLL,0x139122822af2b23dLL,0x141172872ac2a63bLL,0x1511d28b2a929a38LL,0x1592328f2a628e36LL,0x169292932a228234LL,0x1792f29729e27632LL,
+0x1893529b29926a31LL,0x1913b29e29725e2fLL,0x1a1412a22932522dLL,0x1b1472a628f2462bLL,0x1c14d2a928b23a2aLL,0x1d9532ac28722e28LL,0x1e9592af28222427LL,0x1f95f2b327e21825LL,
+0x209652b627a20c24LL,0x2216b2b827520223LL,0x231722bc2701f621LL,0x249782bd26c1ec20LL,0x2617e2c02671e01fLL,0x271842c32621d61eLL,0x2898b2c425d1cc1dLL,0x2a1912c72581c01cLL,
+0x2b9972c92531b61bLL,0x2d19d2cb24e1ac1aLL,0x2e9a42cc2491a219LL,0x301aa2cf24319818LL,0x319b02d023e18e18LL,0x339b62d123918417LL,0x351bd2d323317a16LL,0x371c32d322e17016LL,
+0x389c92d622816615LL,0x3a9cf2d622315e14LL,0x3c1d52d821d15414LL,0x3e1dc2d821714c13LL,0x401e22d921114213LL,0x421e82d820c13a13LL,0x441ee2da20613012LL,0x461f42da20012812LL,
+0x0e0a31f42b63e8a3LL,0x0e0a71f92b63de9fLL,0x0e8ab1fe2b63d29bLL,0x0e8b02042b43c897LL,0x0e8b42092b53bc93LL,0x0f0b820e2b43b28fLL,0x0f0bd2132b43a68bLL,0x0f8c12182b339c87LL,
+0x0f8c621d2b339083LL,0x100cb2222b038680LL,0x108cf2262b137a7cLL,0x108d422b2af37079LL,0x110d92302ae36475LL,0x118de2342ad35872LL,0x120e32392ab34e6eLL,0x128e823e2a93426bLL,
+0x130ed2422a733868LL,0x138f22472a532c65LL,0x140f724b2a432062LL,0x148fc24f2a23165fLL,0x159012532a030a5cLL,0x1610625829e2fe59LL,0x1690b25c29c2f456LL,0x179112602982e854LL,
+0x181162642972dc51LL,0x1911b2672942d24fLL,0x1992126b2922c64cLL,0x1a92626f28f2ba4aLL,0x1b92b27228d2b047LL,0x1c9312762892a445LL,0x1d93627928629a43LL,0x1e93c27d28228e41LL,
+0x1f9412802802823fLL,0x2094728227d2783dLL,0x2194d28627926c3bLL,0x2295228927626239LL,0x2395828d27225637LL,0x2515d28f26f24c35LL,0x2616329226b24233LL,0x2796929426723632LL,
+0x2896e29726422c30LL,0x2a1742982602222fLL,0x2b17a29c25c2162dLL,0x2c97f29e25820c2cLL,0x2e1852a02532022bLL,0x2f98b2a224f1f829LL,0x311902a424b1ee28LL,0x329962a52471e427LL,
+0x3419c2a72421da26LL,0x359a12a923e1d025LL,0x371a72ab2391c624LL,0x391ac2ad2341bc23LL,0x3a9b22ae2301b222LL,0x3c9b82af22b1a821LL,0x3e1bd2b122619e21LL,0x401c32b022219620LL,
+0x419c82b321d18c1fLL,0x439ce2b32181821fLL,0x459d32b421317a1eLL,0x479d92b420e1701eLL,0x499de2b52091681dLL,0x4b9e42b42041601dLL,0x4d9e92b61fe1561dLL,0x4f9ef2b61f914e1cLL,
+0x180c11e827e3d0c1LL,0x180c51ec27e3c8bdLL,0x180c91f127d3c0b9LL,0x188cd1f527d3b6b5LL,0x188d21f927c3aeb1LL,0x188d61fd27c3a6adLL,0x190da20127c39ca9LL,0x190df20527b394a5LL,
+0x198e320927b38aa1LL,0x198e720c27c3829dLL,0x1a0ec21027a3789aLL,0x1a8f021427a36e96LL,0x1b0f521827836692LL,0x1b8f921b27835c8fLL,0x1c0fe21f2763548bLL,0x1c90322327434a88LL,
+0x1d10722627434085LL,0x1d90c22927333881LL,0x1e91122d27032e7eLL,0x1f1152302703247bLL,0x2011a23326e31a78LL,0x2091f23726b31275LL,0x2192323a26a30872LL,0x2212823d2692fe6fLL,
+0x2312d2402672f46cLL,0x241322432652ea69LL,0x251372462622e266LL,0x2613b2492612d863LL,0x2714024b25f2ce61LL,0x2814524e25d2c45eLL,0x2914a25125a2ba5cLL,0x2a14f2532592b059LL,
+0x2b9542562542a857LL,0x2c95825925329e54LL,0x2e15d25a25129452LL,0x2f16225d24e28a50LL,0x3096725f24b2804eLL,0x3196c2612492764cLL,0x3317126224626e4aLL,0x3497526524326448LL,
+0x3617a26724025a46LL,0x3797f26923d25044LL,0x3918426a23a24643LL,0x3a98926b23723e41LL,0x3c18d26e23323440LL,0x3d99227023022a3eLL,0x3f19727022d2223dLL,0x4099c2732292183bLL,
+0x429a027422620e3aLL,0x441a527422320639LL,0x459aa27621f1fc38LL,0x479ae27821b1f237LL,0x491b32782181ea36LL,0x4b1b727a2141e035LL,0x4d1bc27a2101d834LL,0x4e9c127c20c1ce33LL,
+0x509c527b2091c633LL,0x529ca27b2051be32LL,0x549ce27c2011b432LL,0x569d327c1fd1ac31LL,0x589d727c1f91a431LL,0x5a9db27d1f519a31LL,0x5c9e027d1f119230LL,0x5e9e427e1ec18a30LL
+};
+
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/df_reg_fmt.h u-boot-2011.06/drivers/cnc1900/df/df_reg_fmt.h
--- u-boot-2011.06_original/drivers/cnc1900/df/df_reg_fmt.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/df_reg_fmt.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,2161 @@
+#ifndef __DF_REG_FMT_H__
+#define __DF_REG_FMT_H__
+
+
+
+typedef struct _GLB
+{
+    union
+    {
+        struct
+        {
+            unsigned int wr_lb_limit:16;
+            unsigned int reserved:16;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_ctrl_setting;
+	union
+	{
+		struct 
+		{
+			unsigned int clk_gate:5;
+			unsigned int reserved1:3;
+			unsigned int clk_en_sr:1;
+			unsigned int clk_en_main:1;
+			unsigned int clk_en_ui1:1;
+			unsigned int clk_en_ui2:1;
+			unsigned int clk_en_cap:1;
+			unsigned int clk_en_rd2:1;
+			unsigned int reserved2:19;
+		}bits;
+
+		unsigned int val;
+	}reg_glb_ctrl_clk_setting;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+        unsigned int val;
+    }reg_glb_h_update;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+        unsigned int val;
+    }reg_glb_m_update;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_c_update;
+
+    union
+    {
+        struct
+        {
+            unsigned int cop_int_sta_disp1_err:1;
+            unsigned int cop_int_sta_disp2_err:1;
+            unsigned int cop_int_sta_cap_err:1;     
+            unsigned int cop_int_sta_disp1_sync:1;
+            unsigned int cop_int_sta_disp1_field:1;
+            unsigned int cop_int_sta_disp1_frame:1;
+            unsigned int cop_int_sta_disp2_frame:1;
+            unsigned int cop_int_sta_cap_finish:1;  
+            unsigned int cop_int_sta_main_f2f_finish:1;
+            unsigned int cop_int_sta_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_sta_cop;
+
+    union
+    {
+        struct
+        {
+            unsigned int cop_int_msk_disp1_err:1;
+            unsigned int cop_int_msk_disp2_err:1;
+            unsigned int cop_int_msk_cap_err:1;      
+            unsigned int cop_int_msk_disp1_sync:1;
+            unsigned int cop_int_msk_disp1_field:1;
+            unsigned int cop_int_msk_disp1_frame:1;
+            unsigned int cop_int_msk_disp2_frame:1;
+            unsigned int cop_int_msk_cap_finish:1;    
+            unsigned int cop_int_msk_main_f2f_finish:1;
+            unsigned int cop_int_msk_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_msk_cop;
+
+    union
+    {
+        struct
+        {
+            unsigned int host_int_sta_disp1_err:1;
+            unsigned int host_int_sta_disp2_err:1;
+            unsigned int host_int_sta_cap_err:1;     
+            unsigned int host_int_sta_disp1_sync:1;
+            unsigned int host_int_sta_disp1_field:1;
+            unsigned int host_int_sta_disp1_frame:1;
+            unsigned int host_int_sta_disp2_frame:1;
+            unsigned int host_int_sta_cap_finish:1;   
+            unsigned int host_int_sta_main_f2f_finish:1;
+            unsigned int host_int_sta_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_sta_host;
+
+    union
+    {
+        struct
+        {
+            unsigned int host_int_msk_disp1_err:1;
+            unsigned int host_int_msk_disp2_err:1;
+            unsigned int host_int_msk_cap_err:1;
+            unsigned int host_int_msk_disp1_sync:1;
+            unsigned int host_int_msk_disp1_field:1;
+            unsigned int host_int_msk_disp1_frame:1;
+            unsigned int host_int_msk_disp2_frame:1;
+            unsigned int host_int_msk_cap_finish:1;   
+            unsigned int host_int_msk_main_f2f_finish:1;
+            unsigned int host_int_msk_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_msk_host;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef3:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef3;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef4:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef4;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef6:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef6;
+
+    union
+    {
+       struct
+       {
+          unsigned int cpu_wq:1;
+              unsigned int reserved:31;
+       }bits;
+       unsigned int val;
+    }reg_glb_cpu_wq;
+
+    union
+    {
+       struct
+       {
+          unsigned int mips_rq:1;
+              unsigned int reserved:31;
+       }bits;
+       unsigned int val;
+    }reg_glb_mips_rq;
+
+    union
+    {
+       struct
+       {
+          unsigned int cur_status:2;
+              unsigned int reserved1:14;
+              unsigned int need_update:1;
+              unsigned int reserved2:15;
+       }bits;
+       unsigned int val;
+    }reg_glb_cur_status;
+
+    union
+    {
+       struct
+       {
+              unsigned int tg1_v_int_before_line_num:11;
+          unsigned int tg1_frame_int_sel:1;
+              unsigned int reserved1:4;
+              unsigned int tg2_v_int_before_line_num:11;
+          unsigned int tg2_frame_int_sel:1;
+              unsigned int reserved2:4;
+       }bits;
+       unsigned int val;
+    }reg_glb_tg_setting;
+}df_ctrl_reg;
+
+typedef struct _SR
+{
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_top_field:1;
+            unsigned int reserved_1:3;
+            unsigned int sr_f2f_start:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_f2f_3dr:1;
+            unsigned int reserved_3:3;
+            unsigned int sr_f2f_des_top_field:1;
+            unsigned int reserved_4:19;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_setting;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_f2f_store_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_store_frm_addr_y;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_f2f_store_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_store_frm_addr_c;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cy:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cy;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cy_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cc:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_src_line_pitch_128x:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_c_src_line_pitch_128x:6;
+            unsigned int reserved_2:18;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_line_pitch;
+    union
+    {
+        struct
+        {
+            unsigned int sr_en:1;
+            unsigned int reserved_1:3;
+			unsigned int sr_rd_qa_en:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_f2f_mode:1;
+			unsigned int sr_lb_init_step:6;
+			unsigned int reserved_3:1;
+            unsigned int sr_k:8;
+            unsigned int reserved_4:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_is_i:1;
+            unsigned int reserved_1:7;
+            unsigned int sr_src_c_h_sample:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_src_c_v_sample:1;
+            unsigned int reserved_3:3;
+            unsigned int sr_scr_v1_full:12;
+            unsigned int reserved_4:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_h_start:11;
+            unsigned int reserved_1:5;
+            unsigned int sr_src_h_end:11;
+            unsigned int reserved_2:5;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_h_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_src_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_v_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_is_i:1;
+            unsigned int reserved_1:3;
+            unsigned int sr_des_c_h_sample:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_des_c_v_sample:1;
+            unsigned int reserved_3:23;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_des_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_h_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_des_h_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_des_v_end:12;
+            unsigned int reserved_2:4;
+            }bits;
+        unsigned int val;
+    }reg_sr_ch_des_v_pos;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_v_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_y_v_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_v_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_y_h_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_d;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int sr_y_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_y_h_k_radix:5;
+            unsigned int reserved_3:7;
+            }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_n;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:8;
+            unsigned int sr_c_v_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_v_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_c_h_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_d;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int sr_c_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_c_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_n;
+}SR;
+
+typedef struct _MAIN
+{
+
+    union
+    {
+        struct
+        {
+            unsigned int main_f2f_start:1;
+            unsigned int reserved_1:3;
+            unsigned int main_src_top_field:1;
+            unsigned int reserved_2:3;
+            unsigned int main_f2f_3dr:1;
+            unsigned int reserved_3:7;
+            unsigned int main_f2f_des_top_field:1;
+            unsigned int reserved_4:15;
+            }bits;
+        unsigned int val;
+    }reg_main_ch_dysetting;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_f2f_store_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_store_frm_addr_y;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_f2f_store_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_store_frm_addr_c;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fy:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fy;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cy:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cy;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_by:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_by;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bby:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bby;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fy_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cy_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_by_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_by_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bby_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bby_3dr;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bc;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bbc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bbc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fc_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cc_3dr;
+
+    union {
+        struct{
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bc_3dr:25;
+            }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bbc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bbc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_f2f_store_line_pitch:6;
+            unsigned int reserved_1:26;
+        }bits;
+        unsigned int val;
+    }reg_main_f2f_store_pitch;
+
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_0:1;
+            unsigned int main_src_c_h_sample:1;
+            unsigned int main_src_c_v_sample:1;
+            unsigned int reserved_1:1;
+            unsigned int main_src_is_i:1;
+            unsigned int reserved_2:11;
+            unsigned int main_src_y_line_pitch_128x:6;
+            unsigned int reserved_3:2;
+            unsigned int main_src_c_line_pitch_128x:6;
+            unsigned int reserved_4:2;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_src_h_start:11;
+            unsigned int reserved_1:5;
+            unsigned int main_src_h_end:11;
+            unsigned int reserved_2:5;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_h_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_src_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_src_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_v_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_is_i:1;
+            unsigned int main_des_c_h_sample:1;
+            unsigned int main_des_c_v_sample:1;
+            unsigned int reserved_1:29;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_h_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_h_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_des_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_v_position;
+
+
+    union {
+        struct
+        {
+            unsigned int main_y_v_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_y_v_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_v_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_y_h_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_d0_abs;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int main_y_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int main_y_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_n1;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_v_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int reserved_2:12;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_v_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_c_h_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_d0_abs;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int main_c_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int main_c_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_n1;
+    union
+    {
+        struct
+        {
+            unsigned int main_cof_yv6_group:4;
+            unsigned int main_cof_yv3_group:4;
+            unsigned int main_cof_yh6_group:4;
+            unsigned int main_cof_ch6_group:4;
+            unsigned int reserved_1:16;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_cof_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_ups_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_ups_pv:1;
+            unsigned int reserved_2:3;
+            unsigned int main_ups_th_up:8;
+            unsigned int main_ups_th_dn:8;
+            unsigned int main_ups_th_factor:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ups_setting;
+    union
+    {
+        struct
+        {
+            unsigned int main_y_en:1;
+            unsigned int main_c_en:1;
+            unsigned int main_src_i_bf_invert:1;
+            unsigned int reserved_1:1;
+            unsigned int main_rd_qa_en:1;
+            unsigned int reserved_2:3;
+            unsigned int main_f2f_mode:1;
+			unsigned int main_lb_init_step:6;
+			unsigned int reserved_3:1;
+            unsigned int main_scr_v1_full:12;
+            unsigned int reserved_4:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int main_y_tnr_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_tnr_frame:1;
+            unsigned int reserved_2:3;
+            unsigned int main_y_tnr_gate:6;
+            unsigned int reserved_3:2;
+            unsigned int main_y_tnr_div:2;
+            unsigned int reserved_4:14;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_tnr_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_madi_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_madi_gate:3;
+            unsigned int reserved_2:1;
+            unsigned int main_y_madi_force_3d:1;
+            unsigned int reserved_3:23;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_madi_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_dir_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_dir_min0:5;
+            unsigned int reserved_2:3;
+            unsigned int main_y_dir_min1:5;
+            unsigned int reserved_3:3;
+            unsigned int main_y_dir_k0:4;
+            unsigned int main_y_dir_k1:4;
+            unsigned int main_y_dir_max:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_dir_setting;
+    union
+    {
+        struct
+        {
+            unsigned int main_c_tnr_en:1;
+            unsigned int reserved_1:7;
+            unsigned int main_c_tnr_gate:6;
+            unsigned int reserved_3:2;
+            unsigned int main_c_tnr_div:2;
+            unsigned int reserved_4:14;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_tnr_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_madi_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_c_madi_gate:3;
+            unsigned int reserved_2:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_madi_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_dir_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_c_dir_min0:5;
+            unsigned int reserved_2:3;
+            unsigned int main_c_dir_min1:5;
+            unsigned int reserved_3:3;
+            unsigned int main_c_dir_k0:4;
+            unsigned int main_c_dir_k1:4;
+            unsigned int main_c_dir_max:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_dir_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_bg_y:10;
+            unsigned int blend1_bg_u:10;
+            unsigned int blend1_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_back_ground;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_result_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int blend1_result_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_des_position_x;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_result_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int blend1_result_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_des_position_y;
+    union
+    {
+        struct
+        {
+            unsigned int main_bg_en:1;
+            unsigned int reserved_1:31;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int line_cnt_y_f2f_wr:12;
+            unsigned int reserved_1:4;
+            unsigned int main_wr_f2f_finish:1;
+            unsigned int reserved_2:15;
+        }bits;
+        unsigned int val;
+    }reg_main_sta_vpp_num;
+}MAIN;
+
+typedef struct _F2F_RD
+{
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int f2f_rd_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_yf_addr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int f2f_rd_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_cf_addr;
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_video_en:1;
+            unsigned int reserved_1:15;
+            unsigned int f2f_rd_line_pitch:6;
+            unsigned int reserved_2:10;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_src_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_src_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_src_x_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_src_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_src_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_src_y_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_disp_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_x_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_disp_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_y_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_num:32;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_disp_num;
+
+}F2F_RD;
+
+typedef struct _HD2SD_RD
+{
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int hd2sd_rd_y_128_addr_frame:25;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_yf_addr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int hd2sd_rd_c_128_addr_frame:25;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_cf_addr;
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_en:1;
+            unsigned int reserved_1:15;
+            unsigned int hd2sd_rd_line_pitch:6;
+            unsigned int reserved_2:10;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_src_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_src_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_src_x_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_src_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_src_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_src_y_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_video_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_x_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_video_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_y_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_disp_num:32;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_disp_num;
+}HD2SD_RD;
+
+typedef struct _DMA
+{
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_rd_yf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_rd_yf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_rd_cf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_rd_cf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_wr_yf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_wr_yf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_wr_cf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_wr_cf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int dma_en:1;
+                unsigned int reserved1:3;
+                unsigned int dma_src_c_v_sample:1;
+                unsigned int reserved2:3;
+                unsigned int dma_start:1;
+                unsigned int reserved3:7;
+                unsigned int dma_rd_line_pitch:6;
+                unsigned int reserved4:2;
+                unsigned int dma_wr_line_pitch:6;
+                unsigned int reserved5:2;
+         }bits;
+            unsigned int val;
+        }reg_dma_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int dma_src_x_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_src_x_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_src_x_crop;
+        union
+        {
+            struct
+            {
+                unsigned int dma_src_y_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_src_y_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_src_y_crop;
+        union
+        {
+            struct
+            {
+                unsigned int dma_des_x_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_des_x_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_des_x_position;
+        union
+        {
+            struct
+            {
+                unsigned int dma_des_y_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_des_y_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_des_y_position;
+}DMA;
+
+typedef struct _CAP
+{
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_en:1;
+			unsigned int cap_c_v_sample:1;
+			unsigned int reserved_1:2;
+			unsigned int cap_des_is_i:1;
+			unsigned int reserved_2:3;
+			unsigned int cap_cap_left:1;
+			unsigned int reserved_3:3;
+			unsigned int hd2sd_3frame_mode:1;
+            unsigned int reserved_4:1;
+            unsigned int cap_frame_get:1;
+			unsigned int hd2sd_frame_release:1;
+			unsigned int cap_line_pitch:6;
+			unsigned int reserved_5:10;
+        }bits;
+        unsigned int val;
+	}reg_cap_ctrl;
+	union
+	{
+		struct
+		{
+			unsigned int cap_src_ext:1;
+			unsigned int cap_ext_fs_sel:1;
+			unsigned int cap_ext_fs_pol:1;
+			unsigned int cap_ext_vs_pol:1;
+			unsigned int cap_ext_hs_pol:1;
+			unsigned int cap_ext_emb_en:1;
+			unsigned int cap_ext_2lane:1;
+			unsigned int cap_ext_10bpc:1;
+			unsigned int cap_ext_csc_en:1;
+			unsigned int cap_scr_is_i:1;
+			unsigned int cap_scr_c_h_sample:1;
+			unsigned int reserved_1:21;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_setting;
+	union
+	{
+		struct
+		{
+			unsigned int cap_scr_h_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_scr_h_end:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_h_position;
+	union
+	{
+		struct
+		{
+			unsigned int cap_scr_v_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_scr_v1_full:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_v_position;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_des_h_start:12;
+            unsigned int reserved_1:4;
+			unsigned int cap_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+	}reg_cap_des_h_position;
+	union
+	{
+		struct
+		{
+			unsigned int cap_des_v_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_des_v_end:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_des_v_position;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_v_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_yv_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_h_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_yh_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_v_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_cv_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_h_r0:17;
+            unsigned int reserved_1:15;
+        }bits;
+        unsigned int val;
+	}reg_cap_ch_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_d0_abs:24;
+			unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+	}reg_cap_y_noline_d;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_d0_abs:24;
+			unsigned int reserved_1:8;
+		}bits;
+		unsigned int val;
+	}reg_cap_c_noline_d;
+    union
+    {
+        struct
+		{
+			unsigned int cap_sca_y_h_k_abs:13;
+			unsigned int reserved_1:2;
+			unsigned int cap_sca_y_h_k_sign:1;
+			unsigned int cap_sca_y_h_k_radix:5;
+			unsigned int cap_sca_y_h_n1:11;
+		}bits;
+		unsigned int val;
+	}reg_cap_y_noline_k;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_h_k_abs:13;
+			unsigned int reserved_1:2;
+			unsigned int cap_sca_c_h_k_sign:1;
+			unsigned int cap_sca_c_h_k_radix:5;
+			unsigned int cap_sca_c_h_n1:11;
+        }bits;
+        unsigned int val;
+	}reg_cap_c_noline_k;
+	union
+	{
+		struct
+		{
+			unsigned int cap_iphase_h_y:6;
+			unsigned int reserved_1:10;
+			unsigned int cap_iphase_h_c:6;
+			unsigned int reserved_2:10;
+		}bits;
+		unsigned int val;
+	}reg_cap_hor_phase;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_iphase_v_y:6;
+			unsigned int reserved_1:26;
+		}bits;
+		unsigned int val;
+	}reg_cap_ver_phase;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame0:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr0;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame0:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr0;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame1:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr1;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame1:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr1;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame2:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr2;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame2:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr2;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame3:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr3;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame3:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr3;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame4:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr4;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame4:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr4;
+	union
+	{
+		struct
+		{
+			unsigned int cap_cof_yv4_group:4;
+			unsigned int cap_cof_cv4_group:4;
+			unsigned int cap_cof_yh6_group:4;
+			unsigned int cap_cof_ch6_group:4;
+			unsigned int cap_line_finish_cnt:12;
+			unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+	}reg_cap_coeff_no;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_idx:3;
+			unsigned int reserved:29;
+		}bits;
+		unsigned int val;
+	}reg_cap_idx;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_pts:32;
+		}bits;
+		unsigned int val;
+	}reg_cap_pts;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_stc:32;
+		}bits;
+		unsigned int val;
+	}reg_cap_stc_tg1;
+	union
+	{
+		struct
+		{
+			unsigned int cap_line_cnt:12;
+			unsigned int reserved_1:20;
+		}bits;
+		unsigned int val;
+	}reg_cap_line_cnt;
+
+    union
+    {
+        struct
+        {
+            unsigned int cap_status:32;
+        }bits;
+        unsigned int val;
+    }reg_cap_status;
+    union
+    {
+        struct
+        {
+            unsigned int cap_h_resolution:12;
+            unsigned int reserved_1:4;
+            unsigned int cap_v_resolution:12;
+            unsigned int reserved_2:3;
+            unsigned int cap_format_change:1;
+        }bits;
+        unsigned int val;
+    }reg_cap_format;
+
+}CAP;
+
+typedef struct _COMP
+{
+    union{
+        struct{
+            unsigned int blending2_bg_y:10;
+            unsigned int blending2_bg_u:10;
+            unsigned int blending2_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_back_ground;
+
+    union{
+        struct{
+            unsigned int blending2_video1_z_order:2;
+            unsigned int reserved_1:2;
+            unsigned int blending2_video2_z_order:2;
+            unsigned int reserved_2:2;
+            unsigned int blending2_gfx1_z_order:2;
+            unsigned int reserved_3:2;
+            unsigned int blending2_gfx2_z_order:2;
+            unsigned int reserved_4:18;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_z_order;
+
+    union{
+        struct{
+            unsigned int blending2_default_alpha1:10;
+            unsigned int reserved_1:6;
+            unsigned int blending2_default_alpha2:10;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_default_alpha;
+    union{
+        struct{
+            unsigned int blending3_bg_y:10;
+            unsigned int blending3_bg_u:10;
+            unsigned int blending3_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_back_ground;
+
+    union{
+        struct{
+            unsigned int blending3_video1_z_order:2;
+            unsigned int reserved_1:2;
+            unsigned int reserved_2:4;
+            unsigned int blending3_gfx1_z_order:2;
+            unsigned int reserved_3:4;
+            unsigned int reserved_4:18;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_z_order;
+
+    union{
+        struct{
+            unsigned int blending3_default_alpha1:10;
+            unsigned int reserved_1:6;
+            unsigned int reserved_2:16;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_default_alpha;
+
+
+    union{
+        struct{
+            unsigned int enh_y_sharp_en:1;
+            unsigned int enh_y_median_en:1;
+            unsigned int enh_y_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_y_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_y_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_y_bpw:8;
+            unsigned int enh_y_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_y;
+
+    union{
+        struct{
+            unsigned int enh_c_sharp_en:1;
+            unsigned int enh_c_median_en:1;
+            unsigned int enh_c_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_c_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_c_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_c_bpw:8;
+            unsigned int enh_c_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_c;
+
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_color_adjust;
+}df_compositor_reg;
+
+typedef struct _TG
+{
+    union
+    {
+        struct
+        {
+            unsigned int tg_en:1;
+            unsigned int reserved_1:1;
+            unsigned int tg_is_hd:1;
+            unsigned int reserved_2:2;
+            unsigned int tg_is_interlaced:1;
+            unsigned int reserved_3:1;
+            unsigned int tg_is_pal:1;
+            unsigned int reserved_3_1:3;
+            unsigned int tg_dither_mode:1;
+            unsigned int tg_hsync_pol:1;
+            unsigned int tg_vsync_pol:1;
+            unsigned int tg_dither_ena:1;
+            unsigned int reserved_4:1;
+            unsigned int tg_3d_act_space:8;
+            unsigned int tg_3d_en:1;
+            unsigned int reserved_5:7;
+        }bits;
+        unsigned int val;
+    }reg_tg_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_htotal:13;
+            unsigned int reserved_1:3;
+            unsigned int tg_hactive_width:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_x_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vtotal:13;
+            unsigned int reserved_1:3;
+            unsigned int tg_vactive_height:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_y_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_hsync_front_porch:10;
+            unsigned int tg_hsync_width:10;
+            unsigned int tg_hsync_back_porch:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_tg_hsync;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vsync_front_porch:8;
+            unsigned int tg_vsync_width:8;
+            unsigned int tg_vsync_back_porch:8;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_tg_vsync;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vga_black_level:10;
+            unsigned int reserved_1:6;
+            unsigned int tg_vga_white_level:10;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_tg_vga_level;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_v_start_line_num: 6;
+            unsigned int reserved_1:10;
+            unsigned int reserved_2:16;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_line;
+
+    union
+    {
+        struct
+        {
+            unsigned int disp_width: 12;
+            unsigned int reserved_1:4;
+            unsigned int disp_height: 12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_disp_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int disp_scan_line_cnt: 13;
+            unsigned int reserved_1:3;
+            unsigned int disp_scan_line_active_line: 1;
+            unsigned int reserved_2:3;
+            unsigned int disp_bottom_flag: 1;
+            unsigned int reserved_3:3;
+            unsigned int disp_vsync: 1;
+            unsigned int reserved_4:7;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_disp_line;
+}df_outif_reg;
+
+typedef struct _UI
+{
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_ena:1;
+                unsigned int gfx_ui_format:3;
+                unsigned int gfx_ui_endian:2;
+                unsigned int gfx_ui_opaque:1;
+                unsigned int gfx_ui_color_keying_en:1;
+                unsigned int gfx_ui_ena_premul:1;
+                unsigned int gfx_ui_af_sc_dis:1;
+                unsigned int gfx_ui_antiflicker_en_a:1;
+                unsigned int gfx_ui_antiflicker_en_c:1;
+                unsigned int gfx_ui_ena_demul:1;
+                unsigned int gfx_ui_yuv_conv_ena:1;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_bw_limit:8;
+                unsigned int ui_tg1_en:1;
+                unsigned int reserved2:7;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_src_width:16;
+                unsigned int gfx_ui_src_height:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_size;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_default_alpha:8;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_argb1555_a0:8;
+                unsigned int reserved2:2;
+                unsigned int gfx_ui_argb1555_a1:8;
+                unsigned int reserved3:4;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_alpha_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_r_min:8;
+                unsigned int gfx_ui_r_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_red;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_b_min:8;
+                unsigned int gfx_ui_b_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_blue;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_g_min:8;
+                unsigned int gfx_ui_g_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_green;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_buf_start:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_buf_start;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_buf_start_3d:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_buf_start_3d;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_line_pitch:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_line_pitch;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_dst_x_start:16;
+                unsigned int gfx_ui_dst_x_end:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_x_position;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_dst_y_start:16;
+                unsigned int gfx_ui_dst_y_end:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_y_position;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_a8_r:8;
+                unsigned int gfx_ui_a8_g:8;
+                unsigned int gfx_ui_a8_b:8;
+                unsigned int reserved1:8;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_a8;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_hphase:6;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_vphase:6;
+                unsigned int reserved2:18;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_phase;
+
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_hcoeff_gid:4;
+                unsigned int gfx_ui_vcoeff_gid:4;
+                unsigned int reserved1:24;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_coeff_gid;
+
+}df_gfx_reg;
+
+
+typedef struct _DF_REG_PARA_
+{
+	df_ctrl_reg		Ctrl;
+	df_gfx_reg		Gfx[2];
+	//df_video1_reg		Video1;
+	//df_video2_reg		Video2;
+	//df_video3_reg		Video3;
+	df_compositor_reg	Comp;
+	//df_hd2sd_reg		HD2SD;
+	df_outif_reg		OutIF[2];
+}df_reg_para;
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/hdmi_sw_hw_if.h u-boot-2011.06/drivers/cnc1900/df/hdmi_sw_hw_if.h
--- u-boot-2011.06_original/drivers/cnc1900/df/hdmi_sw_hw_if.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/hdmi_sw_hw_if.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,25 @@
+#ifndef _HDMI_SW_HW_IF_H_
+#define _HDMI_SW_HW_IF_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+typedef enum _CLOCK_RESET_
+{
+  _do_reset =0,
+  _do_set   =1,
+}CLOCK_RESET;
+
+int HDMI_REG_Init(void);
+void HW_REG_WRITE(unsigned int ByteAddr, unsigned int Data);
+unsigned int  HW_REG_READ (unsigned int ByteAddr);
+int  HW_REG_READ_CHECK (unsigned int ByteAddr, unsigned int Data);
+
+void clock_hdmi_reset(CLOCK_RESET ResetOrSet);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/Makefile u-boot-2011.06/drivers/cnc1900/df/Makefile
--- u-boot-2011.06_original/drivers/cnc1900/df/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,44 @@
+#
+# (C) Copyright 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)libdf.o
+
+COBJS-$(CONFIG_CNC1900_DF) += df.o 
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+all:	$(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS) $(HDMIOBJ))
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/tve0_1900.h u-boot-2011.06/drivers/cnc1900/df/tve0_1900.h
--- u-boot-2011.06_original/drivers/cnc1900/df/tve0_1900.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/tve0_1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,77 @@
+#ifndef _CSM_TVE0_H
+#define _CSM_TVE0_H
+
+//2 TVE
+#define  TVE0_REG_NUM		(45)
+#define  REG_ADDR    		(0) 
+#define  TYPE_NTSC   		(1)
+#define  TYPE_PAL    		(2)
+#define  TYPE_PAL_M  		(3)
+#define  TYPE_PAL_N  		(4)
+#define  TYPE_PAL_CN 		(5)
+#define  TYPE_SECAM  		(6)
+#define  TYPE_480p   		(7)
+#define  TYPE_720p50   		(8)
+#define  TYPE_720p60   		(9)
+#define  TYPE_1080i  		(10)
+#define  TYPE_1080i30		(11)//duliguo
+#define  TVE0_TYPE_TOTAL  	(12)
+
+//1TVE0
+
+//dont change this table
+static unsigned char TVE0_REG[TVE0_REG_NUM][TVE0_TYPE_TOTAL] =
+{
+/*      address ntsc  pal   PAL_M PAL-N PAL-CN SECAM 480p  720p50 720p60 1080i25 1080i30 */
+/*0*/   {0x00,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_SOFT_RESET_VAL
+/*1*/   {0x01,  0x50, 0x50, 0x50, 0x50, 0x50,  0x50, 0x50, 0x50,  0x50,  0x51,   0x50    }, //CVE_REV_ID_VAL
+/*2*/   {0x02,  0x1c, 0x1c, 0x1c, 0x1c, 0x1c,  0x1c, 0x1c, 0x1c,  0x1c,  0x1c,   0x10    }, //CVE_INPUT_CTL_VAL
+/*3*/   {0x04,  0x09, 0x09, 0x09, 0x09, 0x09,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    }, //CVE_OUT_CTL_VAL
+/*4*/   {0x06,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SLV_MD_TH_VAL
+/*5*/   {0x07,  0x00, 0x04, 0x24, 0x24, 0x34,  0x3C, 0x01, 0x03,  0x03,  0x02,   0x02    }, //CVE_VID_STD_VAL
+/*6*/   {0x08,  0x02, 0x02, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x04,   0x04    }, //CVE_NUM_LINES_H_VAL
+/*7*/   {0x09,  0x0d, 0x71, 0x0D, 0x71, 0x71,  0x71, 0x0D, 0xEE,  0xEE,  0x65,   0x65    }, //CVE_NUM_LINES_L_VAL
+/*8*/   {0x0a,  0x15, 0x17, 0x15, 0x17, 0x17,  0x17, 0x2a, 0x19,  0x19,  0x14,   20      }, //CVE_FST_VID_LINE_VAL
+/*9*/   {0x0b,  0x7e, 0x7e, 0x7e, 0x7e, 0x7e,  0x7e, 0x7e, 0x40,  0x50,  0x58,   88      }, //CVE_HSYNC_WIDTH_VAL
+/*10*/  {0x0d,  0x68, 0x80, 0x76, 0x8a, 0x8a,  0x8a, 0x68, 0xdc,  0xd0,  0x94,   148     }, //CVE_BACK_PORCH_VAL
+/*11*/  {0x0e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01,  0x00,  0x02,   0       }, //CVE_FRONT_PORCH_H_VAL
+/*12*/  {0x0f,  0x32, 0x28, 0x20, 0x18, 0x18,  0x18, 0x32, 0xb8,  0x48,  0x10,   44      }, //CVE_FRONT_PORCH_L_VAL
+/*13*/  {0x10,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x09,   7       }, //CVE_ACTIVELINE_H_VAL
+/*14*/  {0x11,  0x9c, 0x9a, 0xa0, 0xa0, 0xa0,  0xa0, 0x9c, 0x00,  0x0a,  0x38,   128     }, //CVE_ACTIVELINE_L_VAL
+/*15*/  {0x12,  0x44, 0x40, 0x44, 0x40, 0x44,  0x40, 0x44, 0x08,  0x08,  0x08,   8       }, //CVE_BURST_WDITH_VAL
+/*16*/  {0x13,  0x16, 0x1a, 0x12, 0x1a, 0x1a,  0x1a, 0x16, 0x08,  0x08,  0x08,   8       }, //CVE_BREEZE_WAY_VAL
+/*17*/  {0x16,  0x10, 0x15, 0x10, 0x15, 0x10,  0x14, 0x15, 0x15,  0x15,  0x15,   0x10    }, //CVE_CHROMA_FREQ_3_VAL
+/*18*/  {0x17,  0xf8, 0x04, 0xF3, 0x04, 0xFB,  0xE3, 0x04, 0x04,  0x04,  0x04,   0xf8    }, //CVE_CHROMA_FREQ_2_VAL
+/*19*/  {0x18,  0x3e, 0xc5, 0x77, 0xc5, 0x4A,  0x8E, 0xc5, 0xc5,  0xc5,  0xc5,   0x3e    }, //CVE_CHROMA_FREQ_1_VAL
+/*20*/  {0x19,  0x0f, 0x66, 0xD2, 0x66, 0x23,  0x39, 0x66, 0x66,  0x66,  0x66,   0x0f    }, //CVE_CHROMA_FREQ_0_VAL
+/*21*/  {0x1a,  0x14, 0x14, 0x14, 0x14, 0x00,  0x14, 0x14, 0x14,  0x14,  0xc5,   0x00    }, /*freq2*/
+/*22*/  {0x1b,  0x25, 0x25, 0x25, 0x00, 0x00,  0x25, 0x25, 0x25,  0x25,  0x66,   0x00    },
+/*23*/  {0x1c,  0xed, 0xed, 0xed, 0x00, 0x00,  0xed, 0xed, 0xed,  0xed,  0x00,   0x00    },
+/*24*/  {0x1d,  0x09, 0x09, 0x09, 0x00, 0x00,  0x09, 0x09, 0x09,  0x09,  0x00,   0x00    },
+/*25*/  {0x1e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CHROMA_PHASE_VAL
+/*26*/  {0x1f,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_TINT_VAL
+/*27*/  {0x20,  0x14, 0x04, 0x04, 0x04, 0x04,  0x04, 0x04, 0x04,  0x04,  0x04,   36      }, //CVE_NA_WI_CH_CH_CP_VAL
+/*28*/  {0x21,  0x44, 0x30, 0x2a, 0x2a, 0x2c,  0x00, 0x30, 0x30,  0x30,  0x30,   60      }, //CVE_CB_BURST_AMP_VAL
+/*29*/  {0x22,  0x00, 0x24, 0x1d, 0x1d, 0x1f,  0x00, 0x24, 0x24,  0x24,  0x24,   0       }, //CVE_CR_BURST_AMP_VAL
+/*30*/  {0x23,  0xa2, 0xb2, 0xa2, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xbc,   180     }, //CVE_CB_GAIN_VAL
+/*31*/  {0x24,  0xa2, 0xb2, 0xa2, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xbc,   180     }, //CVE_CR_GAIN_VAL
+/*32*/  {0x27,  0x02, 0x03, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x03,   3       }, //CVE_WHITE_LEVEL_H_VAL
+/*33*/  {0x28,  0xf8, 0x10, 0xf8, 0x00, 0xf8,  0xf8, 0xf8, 0xf8,  0xf8,  0x20,   32      }, //CVE_WHITE_LEVEL_L_VAL
+/*34*/  {0x29,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0       }, //CVE_BLACK_LEVEL_H_VAL
+/*35*/  {0x2a,  0xb0, 0xb0, 0xb0, 0xb0, 0xb0,  0xb0, 0xb0, 0xfb,  0xfb,  0xfc,   208     }, //CVE_BLACK_LEVEL_L_VAL
+/*36*/  {0x2b,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_BLANK_LEVEL_H_VAL
+/*37*/  {0x2c,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   251     }, //CVE_BLANK_LEVEL_L_VAL
+/*38*/  {0x2d,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_VBI_BLANK_LEVEL_H_VAL
+/*39*/  {0x2e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   251     }, //CVE_VBI_BLANK_LEVEL_L_VAL
+/*40*/  {0x2f,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_CLAMP_LEVEL_H_VAL
+/*41*/  {0x30,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   0       }, //CVE_CLAMP_LEVEL_L_VAL
+/*42*/  {0x31,  0x10, 0x10, 0x10, 0x10, 0x10,  0x10, 0x10, 0x10,  0x10,  0x10,   16      }, //CVE_SYNC_LEVEL_VAL
+/*43*/  {0x33,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   1       }, //CVE_SYNC_HIGH_LEVEL_H_VAL
+/*44*/  {0x34,  0xeb, 0xeb, 0xeb, 0xeb, 0xeb,  0xeb, 0xeb, 0xeb,  0xeb,  0xe8,   230     }, //CVE_SYNC_HIGH_LEVEL_L_VAL
+//*45*/ {0x37,  0x09, 0x15, 0x08, 0x08, 0x08,  0x08, 0x15, 0x15,  0x15,  0x08,   8       }, //CVE_NOTCH_EN_WI_FR_VAL
+//*46*/ {0x38,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0       }, //CVE_NO_SH_NO_VAL
+//*47*/ {0x39,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x05,   5       }, //CVE_NOISE_THRESHOLD_VAL
+//*48*/ {0x3a,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a,  0x0a, 0x0a, 0x0a,  0x0a,  0x0a,   10      }, //CVE_SHARPEN_THRESHOLD_VAL
+};
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/cnc1900/df/tve1_1900.h u-boot-2011.06/drivers/cnc1900/df/tve1_1900.h
--- u-boot-2011.06_original/drivers/cnc1900/df/tve1_1900.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/cnc1900/df/tve1_1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,72 @@
+
+#ifndef _CSM_TVE1_H
+#define _CSM_TVE1_H
+
+//1TVE1
+
+#define  TVE1_REG_NUM		(57)
+#define  TVE1_TYPE_TOTAL  	(13)
+
+//dont change this table
+static unsigned char TVE1_REG[TVE1_REG_NUM][TVE1_TYPE_TOTAL] =
+{
+/*      address ntsc  pal   PAL_M PAL-N PAL-CN SECAM 480p  720p50 720p60 1080i25 1080i30 */
+/*0*/   {0x00,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_SOFT_RESET_VAL
+/*1*/   {0x01,  0x50, 0x51, 0x50, 0x50, 0x50,  0x50, 0x50, 0x50,  0x50,  0x50,   0x50    }, //CVE_REV_ID_VAL
+/*2*/   {0x02,  0x0c, 0x14, 0x10, 0x1c, 0x1c,  0x1c, 0x1c, 0x1c,  0x1c,  0x1c,   0x1c    }, //CVE_INPUT_CTL_VAL
+/*3*/   {0x04,  0x09, 0x09, 0x09, 0x09, 0x09,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    }, //CVE_OUT_CTL_VAL
+/*4*/   {0x06,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SLV_MD_TH_VAL
+/*5*/   {0x07,  0x00, 0x14, 0x24, 0x24, 0x34,  0x3C, 0x01, 0x03,  0x03,  0x02,   0x01    }, //CVE_VID_STD_VAL
+/*6*/   {0x08,  0x02, 0x02, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x04,   0x02    }, //CVE_NUM_LINES_H_VAL
+/*7*/   {0x09,  0x0d, 0x71, 0x0D, 0x71, 0x71,  0x71, 0x0D, 0xEE,  0xEE,  0x65,   0x0D    }, //CVE_NUM_LINES_L_VAL
+/*8*/   {0x0a,  0x15, 0x17, 0x15, 0x17, 0x17,  0x17, 0x2a, 0x19,  0x19,  0x14,   0x2c    }, //CVE_FST_VID_LINE_VAL
+/*9*/   {0x0b,  0x7e, 0x7e, 0x7e, 0x7e, 0x7e,  0x7e, 0x7e, 0x40,  0x50,  0x66,   0xC0    }, //CVE_HSYNC_WIDTH_VAL
+/*10*/  {0x0d,  0x7c, 0x8a, 0x76, 0x8a, 0x8a,  0x8a, 0x68, 0xdc,  0xd0,  0x80,   0x60    }, //CVE_BACK_PORCH_VAL
+/*11*/  {0x0e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01,  0x00,  0x00,   0x00    }, //CVE_FRONT_PORCH_H_VAL
+/*12*/  {0x0f,  0x20, 0x18, 0x20, 0x18, 0x18,  0x18, 0x32, 0xb8,  0x48,  0x40,   0x20    }, //CVE_FRONT_PORCH_L_VAL
+/*13*/  {0x10,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x07,   0x05    }, //CVE_ACTIVELINE_H_VAL
+/*14*/  {0x11,  0xa0, 0xa0, 0xa0, 0xa0, 0xa0,  0xa0, 0x9c, 0x00,  0x0a,  0x80,   0x00    }, //CVE_ACTIVELINE_L_VAL
+/*15*/  {0x12,  0x44, 0x40, 0x44, 0x40, 0x44,  0x40, 0x44, 0x08,  0x08,  0x08,   0x44    }, //CVE_BURST_WDITH_VAL
+/*16*/  {0x13,  0x10, 0x1a, 0x12, 0x1a, 0x1a,  0x1a, 0x16, 0x08,  0x08,  0x08,   0x16    }, //CVE_BREEZE_WAY_VAL
+/*17*/  {0x16,  0x10, 0x15, 0x10, 0x10, 0x10,  0x14, 0x15, 0x15,  0x15,  0x15,   0x15    }, //CVE_CHROMA_FREQ_3_VAL
+/*18*/  {0x17,  0xf8, 0x04, 0xF3, 0xFB, 0xFB,  0xE3, 0x04, 0x04,  0x04,  0x04,   0x04    }, //CVE_CHROMA_FREQ_2_VAL
+/*19*/  {0x18,  0x3e, 0xc5, 0x77, 0x4A, 0x4A,  0x8E, 0xc5, 0xc5,  0xc5,  0xc5,   0xC5    }, //CVE_CHROMA_FREQ_1_VAL
+/*20*/  {0x19,  0x0f, 0x66, 0xD0, 0x33, 0x23,  0x39, 0x66, 0x66,  0x66,  0x66,   0x66    }, //CVE_CHROMA_FREQ_0_VAL
+/*21*/  {0x1a,  0x14, 0x14, 0x14, 0x14, 0x00,  0x14, 0x14, 0x14,  0x14,  0x14,   0x14    }, /*freq2*/
+/*22*/  {0x1b,  0x25, 0x25, 0x25, 0x00, 0x00,  0x25, 0x25, 0x25,  0x25,  0x25,   0x25    },
+/*23*/  {0x1c,  0xed, 0xed, 0xed, 0x00, 0x00,  0xed, 0xed, 0xed,  0xed,  0xed,   0xED    },
+/*24*/  {0x1d,  0x09, 0x09, 0x09, 0x00, 0x00,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    },
+/*25*/  {0x1e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CHROMA_PHASE_VAL
+/*26*/  {0x1f,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_TINT_VAL
+/*27*/  {0x20,  0x24, 0x04, 0x04, 0x04, 0x04,  0x04, 0x04, 0x04,  0x04,  0x04,   0x04    }, //CVE_NA_WI_CH_CH_CP_VAL
+/*28*/  {0x21,  0x3c, 0x2e, 0x2a, 0x2a, 0x2c,  0x00, 0x30, 0x30,  0x30,  0x30,   0x30    }, //CVE_CB_BURST_AMP_VAL
+/*29*/  {0x22,  0x00, 0x21, 0x1d, 0x1d, 0x1f,  0x00, 0x24, 0x24,  0x24,  0x24,   0x24    }, //CVE_CR_BURST_AMP_VAL
+/*30*/  {0x23,  0x90, 0x94, 0xcc, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xb8,   0xD4    }, //CVE_CB_GAIN_VAL
+/*31*/  {0x24,  0x90, 0x94, 0xcc, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xb8,   0xD0    }, //CVE_CR_GAIN_VAL
+/*32*/  {0x27,  0x03, 0x03, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x02,   0x03    }, //CVE_WHITE_LEVEL_H_VAL
+/*33*/  {0x28,  0x20, 0x20, 0xc6, 0x80, 0xf8,  0xf8, 0xf8, 0xf8,  0xf8,  0xf8,   0x28    }, //CVE_WHITE_LEVEL_L_VAL
+/*34*/  {0x29,  0x01, 0x01, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_BLACK_LEVEL_H_VAL
+/*35*/  {0x2a,  0x1a, 0x00, 0xb0, 0xb0, 0xb0,  0xb0, 0xb0, 0xfb,  0xfb,  0xb0,   0xB0    }, //CVE_BLACK_LEVEL_L_VAL
+/*36*/  {0x2b,  0x00, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_BLANK_LEVEL_H_VAL
+/*37*/  {0x2c,  0xf0, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_BLANK_LEVEL_L_VAL
+/*38*/  {0x2d,  0x00, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_VBI_BLANK_LEVEL_H_VAL
+/*39*/  {0x2e,  0xf0, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_VBI_BLANK_LEVEL_L_VAL
+/*40*/  {0x2f,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_CLAMP_LEVEL_H_VAL
+/*41*/  {0x30,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CLAMP_LEVEL_L_VAL
+/*42*/  {0x31,  0x10, 0x16, 0x10, 0x10, 0x10,  0x10, 0x10, 0x10,  0x10,  0x10,   0x10    }, //CVE_SYNC_LEVEL_VAL
+/*43*/  {0x33,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SYNC_HIGH_LEVEL_H_VAL
+/*44*/  {0x34,  0xeb, 0xeb, 0xeb, 0xeb, 0xeb,  0xeb, 0xeb, 0xeb,  0xeb,  0xeb,   0xEB    }, //CVE_SYNC_HIGH_LEVEL_L_VAL
+//*45*/ {0x37,  0x09, 0x08, 0x08, 0x08, 0x08,  0x08, 0x15, 0x15,  0x15,  0x15,   0x15    }, //CVE_NOTCH_EN_WI_FR_VAL
+//*46*/ {0x38,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_NO_SH_NO_VAL
+//*47*/ {0x39,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x05,   0x05    }, //CVE_NOISE_THRESHOLD_VAL
+//*48*/ {0x3a,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a,  0x0a, 0x0a, 0x0a,  0x0a,  0x0a,   0x0A    }, //CVE_SHARPEN_THRESHOLD_VAL
+/*49*/  {0x60,  0x50, 0x64, 0x70, 0x70, 0x70,  0x70, 0x70, 0x70,  0x70,  0x70,   0x70    }, //CVE_WSS_CGMS_REG
+/*50*/  {0x61,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_WSS_CLOCK_H
+/*51*/  {0x62,  0x0f, 0x7b, 0x0f, 0x0f, 0x0f,  0x0f, 0x0f, 0x0f,  0x0f,  0x0f,   0x0f    }, //CVE_WSS_CLOCK_L
+/*52*/  {0x63,  0x02, 0x02, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x02,   0x02    }, //CVE_WSS_LEVEL_H
+/*53*/  {0x64,  0x78, 0x82, 0x78, 0x78, 0x78,  0x78, 0x78, 0x78,  0x78,  0x78,   0x78    }, //CVE_WSS_LEVEL_L
+/*54*/  {0x65,  0x13, 0x16, 0x13, 0x13, 0x13,  0x13, 0x13, 0x13,  0x13,  0x13,   0x13    }, //CVE_WSS_LINEF0
+/*55*/  {0x66,  0x13, 0x16, 0x13, 0x13, 0x13,  0x13, 0x13, 0x13,  0x13,  0x13,   0x13    }, //CVE_WSS_LINEF1
+/*56*/  {0x5a,  0x00, 0x01, 0x00, 0x01, 0x01,  0x01, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_SYS625_50
+};
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/gpio/cnc1900_gpio.c u-boot-2011.06/drivers/gpio/cnc1900_gpio.c
--- u-boot-2011.06_original/drivers/gpio/cnc1900_gpio.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/gpio/cnc1900_gpio.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,109 @@
+
+/*
+ * Basic GPIO functions
+ *
+ * Copyright (c) 2008 Celestial Semiconductor
+ *
+ * This package is free software;  you can redistribute it and/or
+ * modify it under the terms of the license found in the file
+ * named COPYING that should have accompanied this file.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Tu BaoZhao bz.tu@celestialsemi.com, Celestial Semiconductor
+ *
+ * Copyright (c) 2007 Celestial Semiconductor
+ *
+ */
+
+#include <common.h>
+
+#define GPIO_READ 	0
+#define GPIO_WRITE	1
+
+static volatile unsigned char *gpio_base  = (volatile unsigned char *)(CNC1900_GPIO_BASE);
+
+int
+gpio_hw_set_direct(int gpio_id, int dir)
+{	
+	unsigned int flags;
+	if((gpio_id < 32)&&(gpio_id >= 0))
+	{
+		flags = (1 << gpio_id);
+		switch (dir) {
+			case GPIO_READ:
+				*(unsigned int *)(gpio_base+REG_GPIO_SWPORTA_DDR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTA_DDR))|(flags);
+				break;
+			case GPIO_WRITE:
+				*(unsigned int *)(gpio_base+REG_GPIO_SWPORTA_DDR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTA_DDR))&(~flags);
+				break;
+			default:
+				return -1;
+		}
+	}
+	else if((gpio_id >= 32)&&(gpio_id < 41))
+	{
+		gpio_id = gpio_id - 32;
+		flags = (1 << gpio_id);
+		switch (dir) {
+			case GPIO_READ:
+				*(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DDR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTB_DDR))|(flags);
+				break;
+			case GPIO_WRITE:
+				*(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DDR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTB_DDR))&(~flags);
+				break;
+			default:
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+unsigned short
+gpio_hw_read(int gpio_id)
+{
+	gpio_hw_set_direct(gpio_id, GPIO_READ);
+	if((gpio_id < 32)&&(gpio_id >= 0))
+		return((*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_EXT_PORTA))>>gpio_id)& 0x1;
+	else if((gpio_id >= 32)&&(gpio_id < 41))
+	{
+		gpio_id = gpio_id - 32;
+		return((*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_EXT_PORTB))>>gpio_id)& 0x1;
+	}
+	
+	return 0;
+}
+
+int
+gpio_hw_write(int gpio_id, unsigned short data)
+{
+	unsigned int flags ;
+	gpio_hw_set_direct(gpio_id, GPIO_WRITE);
+
+	if((gpio_id < 32)&&(gpio_id >= 0))
+	{
+		flags = (1<<gpio_id);
+		if (!data) {
+			*(unsigned int *)(gpio_base+REG_GPIO_SWPORTA_DR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTA_DR))&(~flags);
+		} else {
+			*(unsigned int *)(gpio_base+REG_GPIO_SWPORTA_DR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTA_DR))|(flags);
+		}
+	}
+	else if((gpio_id >= 32)&&(gpio_id < 41))
+	{
+		gpio_id = gpio_id - 32;
+		flags = (1<<gpio_id);
+		if (!data) {
+		*(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTB_DR))&(~flags);
+			//gpio_base[REG_GPIO_SWPORTB_DR ] &= ~flags;
+		} else {
+			//printf("\n befs  *(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DR) = %0x\n",*(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DR));
+			*(unsigned int *)(gpio_base+REG_GPIO_SWPORTB_DR) =(*(unsigned int *)(CNC1900_GPIO_BASE+REG_GPIO_SWPORTB_DR))|(flags);
+		}
+	}
+	return 0;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/gpio/Makefile u-boot-2011.06/drivers/gpio/Makefile
--- u-boot-2011.06_original/drivers/gpio/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/gpio/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -25,6 +25,7 @@
 
 LIB 	:= $(obj)libgpio.o
 
+COBJS-$(CONFIG_CNC1900_GPIO)	+= cnc1900_gpio.o
 COBJS-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
 COBJS-$(CONFIG_MARVELL_MFP)	+= mvmfp.o
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/i2c/cnc1900_i2c.c u-boot-2011.06/drivers/i2c/cnc1900_i2c.c
--- u-boot-2011.06_original/drivers/i2c/cnc1900_i2c.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/i2c/cnc1900_i2c.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,455 @@
+#include <common.h>
+#include <asm/io.h>
+#include "cnc1900_i2c.h"
+
+#if defined(CONFIG_HARD_I2C)
+
+#define i2c_writeb(v,a)    writeb(v, (CONFIG_SYS_I2C_BASE + (a)))
+#define i2c_writew(v,a)    writew(v, (CONFIG_SYS_I2C_BASE + (a)))
+#define i2c_writel(v,a)    writel(v, (CONFIG_SYS_I2C_BASE + (a)))
+
+#define i2c_readb(a)       readb((CONFIG_SYS_I2C_BASE + (a)))
+#define i2c_readw(a)       readw((CONFIG_SYS_I2C_BASE + (a)))
+#define i2c_readl(a)       readl((CONFIG_SYS_I2C_BASE + (a)))
+
+#define I2C_CLK_MHZ  (45000000/1000000)
+
+#define I2C_DEBUG_LEVEL0	(0)	/* Quiet   */
+#define I2C_DEBUG_LEVEL1	(1)	/* Audible */
+#define I2C_DEBUG_LEVEL2	(2)	/* Loud    */
+#define I2C_DEBUG_LEVEL3	(3)	/* Noisy   */
+
+//#define CONFIG_CNC1800L_I2C_DEBUG
+//#define CONFIG_I2C_DEBUG_VERBOSE 3
+
+#ifdef CONFIG_CNC1900_I2C_DEBUG
+#define DEBUG_CNC1900I2C(n, args...)				\
+ 	do {						\
+		if (n <= CONFIG_I2C_DEBUG_VERBOSE)	\
+			printf(args);			\
+	} while(0)
+#else /* CONFIG_I2C_DEBUG */
+#define DEBUG_CNC1900I2C(n, args...) do { } while(0)
+#endif
+
+static unsigned int previous_speed_cnt;
+
+
+static unsigned int ss_ic_sclh_cnt;
+static unsigned int ss_ic_scl_cnt;
+static unsigned int fs_ic_sclh_cnt;
+static unsigned int fs_ic_scl_cnt;
+static unsigned int default_speed_cnt;
+
+static uchar previous_chip = 0x7f;
+int i2c_probe (uchar chip)
+{
+    int i = 0;
+    int time_cnt;
+    int fifocount=0;
+    fifocount=fifocount;
+    i2c_writew(0x0,IC_RESET);
+    i=i2c_readw(IC_RAW_INTR_STAT);
+    fifocount = i2c_readw(IC_TXFLR);
+    i2c_writew(0x1, IC_ENABLE);
+    i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD);
+    i2c_writew(0x00,IC_DATA_CMD);
+    i2c_writew(0x00,IC_DATA_CMD);
+    i2c_writew(0x00,IC_DATA_CMD);
+    i2c_writew(0x00,IC_DATA_CMD);
+    i2c_writew(0x01,IC_TX_TL);
+//     if (i2c_readw(IC_STAT) & 0x8) {
+//         i = i2c_readw(IC_DATA_CMD);
+//     }
+    time_cnt =0;
+    do {
+        time_cnt ++;
+        i=i2c_readw(IC_RAW_INTR_STAT);
+    } while (i==0 && time_cnt < 1000000);
+    if (time_cnt>=1000000) {              //Bus Err
+        i2c_writew(0x03,IC_FIFO_CLR);	  //clear tx/rx fifo
+        i2c_writew(0x1,IC_RESET);
+        i2c_writew(0x0,IC_RESET);
+        i2c_writew(0x1,IC_ENABLE);
+        i2c_writew(0x700,IC_DATA_CMD);    //write stop bit
+        DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+        return 1;
+    }
+    if (i&0x20) {								//No ACK
+        i2c_writew(0x20,IC_INTR_CLR);
+        i2c_writew(0x03,IC_FIFO_CLR);			//clear tx/rx fifo
+        i2c_writew(0x700,IC_DATA_CMD);
+        DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+        return 1;
+    }
+    i2c_writew(0x20,IC_INTR_CLR);
+    i2c_writew(0x03,IC_FIFO_CLR);			//clear tx/rx fifo
+    i2c_writew(0x700,IC_DATA_CMD);
+    return 0;
+}
+
+
+int i2c_read(uchar chip,uint addr, int alen, uchar * buffer, int len)
+{
+    int i;
+    int cmd_cnt;
+    int data_cnt;
+    unsigned int time_cnt;
+    unsigned char *byte_addr = (unsigned char *) &addr;
+    unsigned char *p = buffer;
+    //    printf("alen =%d\n",alen);
+    time_cnt=0;
+    while (i2c_readw(IC_STAT)&0x20) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+    }
+    i2c_writew(0x1, IC_ENABLE);
+    if (alen > 0) {
+        i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD);
+    }
+    for (i = alen - 1; i >= 0; i--) {
+        i2c_writew(0x200|(byte_addr[i]& 0xff),IC_DATA_CMD);
+        DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL3,"Chipaddress=0x%x, subaddr=0x%x, written_addr=0x%x\n",
+              chip, addr, byte_addr[i]);
+    }
+    i2c_writew(0x101|((chip<<1)&0xff),IC_DATA_CMD);
+    data_cnt = 0;
+    cmd_cnt = 0;
+    time_cnt=0;
+    while (data_cnt < len) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+        while ((cmd_cnt < len) && (i2c_readw(IC_STAT) & 0x2)) {
+            if (cmd_cnt+1==len) {
+                i2c_writew(0x600,IC_DATA_CMD);		//write stop bit
+            } else {
+                i2c_writew(0x400, IC_DATA_CMD);
+            }
+            cmd_cnt++;
+        }
+        if (i2c_readw(IC_STAT) & 0x8) {
+            *p = i2c_readw(IC_DATA_CMD);
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL3,"Chipaddress=0x%x, subaddr=0x%x, readed=0x%x\n",
+                  chip, addr, *p);
+            p++;
+            data_cnt++;
+        }
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);			//clear tx/rx fifo
+            if (i&0x40) {							//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {							//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+    }
+    time_cnt=0;
+    while (!(i2c_readw(IC_STAT)&0x04)) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);			//clear tx/rx fifo
+            if (i&0x40) {							//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {							//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+    }             //wait all data send
+    time_cnt=0;
+    while (i2c_readw(IC_STAT) & 0x20) {
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);			//clear tx/rx fifo
+            if (i&0x40) {							//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {							//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+    }
+    //wait for stop signal
+    return 0;
+}
+
+
+int i2c_write(uchar chip,uint addr, int alen,uchar * buffer, int len)
+{
+    int i;
+    int data_cnt;
+    unsigned int  time_cnt;
+    unsigned char *byte_addr = (unsigned char *) &addr;
+    unsigned char *p = buffer;
+    //    i2c_writew(0x0,IC_RESET);
+    time_cnt=0;
+    while (i2c_readw(IC_STAT)&0x20) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+    }
+    i2c_writew(0x1, IC_ENABLE);
+    i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD);
+    for (i = alen - 1; i >= 0; i--) {
+        i2c_writew(0x200|byte_addr[i],IC_DATA_CMD);
+    }
+    data_cnt = 0;
+    time_cnt=0;
+    while (data_cnt < len) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+        if (i2c_readw(IC_STAT) & 0x2) {
+            if (data_cnt!=len-1) {
+                i2c_writew(0x200|(*p), IC_DATA_CMD);
+            } else {
+                i2c_writew(0x300|(*p),IC_DATA_CMD);				//Stop
+            }
+            p++;
+            data_cnt++;
+        }
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);				//clear tx/rx fifo
+            if (i&0x40) {								//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {								//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);		//Stop
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+    }
+    time_cnt=0;
+    while (!(i2c_readw(IC_STAT)&0x04)) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);				//clear tx/rx fifo
+            if (i&0x40) {						//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {						//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);				//Stop
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+    }             //wait all data send
+    time_cnt=0;
+    while (i2c_readw(IC_STAT) & 0x20) {
+        if (time_cnt>=100000) {       //Bus Err
+            i2c_writew(0x1,IC_RESET);
+            i2c_writew(0x0,IC_RESET);
+            i2c_writew(0x1,IC_ENABLE);
+            i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+            previous_chip = 0;
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            return 1;
+        }
+        time_cnt++;
+        if ((i=i2c_readw(IC_RAW_INTR_STAT)) & 0xe0) {
+            DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+                  chip, addr, i);
+            i2c_writew(0x03,IC_FIFO_CLR);				//clear tx/rx fifo
+            if (i&0x40) {						//Arbitration Lost
+                i2c_writew(0x40,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+            }
+            if (i&0x80) {
+                i2c_writew(0x80,IC_INTR_CLR);
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+            }
+            if (i&0x20) {								//No ACK
+                i2c_writew(0x20,IC_INTR_CLR);
+                i2c_writew(0x700,IC_DATA_CMD);		//Stop
+                DEBUG_CNC1900I2C(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+            }
+            previous_chip = 0;
+            return -1;
+        }
+    }
+    return 0;
+}
+
+uchar i2c_reg_read (uchar chip, uchar reg)
+{
+    uchar readed;
+    if (i2c_read(chip, reg, 1, &readed, 1) == 1 ) {
+        printf("Read I2C Error !\n");
+        return 0;
+    }
+    return readed;
+}
+
+void  i2c_reg_write(uchar chip, uchar reg, uchar val)
+{
+    if (i2c_write(chip, reg, 1,&val, 1) == 1) {
+        printf("Write I2C Error !\n");
+    }
+}
+
+void i2c_init(int speed, int slaveaddr)
+{
+    //printf("Init CNC19xx I2C ");
+    ss_ic_sclh_cnt = (45000000 ) /(4*100000);
+    ss_ic_scl_cnt = (45000000 ) /(2*100000);
+    fs_ic_sclh_cnt = (45000000) / (24 * 100000);
+    fs_ic_scl_cnt = (45000000) / (8 * 100000);
+    previous_chip = slaveaddr;
+    i2c_writew(0x0, IC_ENABLE);
+    if (speed > 150000) {
+        i2c_writew(fs_ic_sclh_cnt, IC_SCLH_CNT);
+        i2c_writew(fs_ic_scl_cnt - fs_ic_sclh_cnt, IC_SCLL_CNT);
+        previous_speed_cnt = fs_ic_scl_cnt;
+        default_speed_cnt = fs_ic_scl_cnt;
+    } else {
+        i2c_writew(ss_ic_sclh_cnt, IC_SCLH_CNT);
+        i2c_writew(ss_ic_scl_cnt - ss_ic_sclh_cnt, IC_SCLL_CNT);
+        previous_speed_cnt = ss_ic_scl_cnt;
+        default_speed_cnt = ss_ic_scl_cnt;
+    }
+}
+
+int i2c_set_bus_speed(unsigned int speed) /* only support 100KHz and 400KHz */
+{
+    static unsigned int speed_cnt;
+    if (speed > 150000)
+        speed_cnt = fs_ic_scl_cnt;
+    else
+        speed_cnt = ss_ic_scl_cnt;
+    if (speed_cnt!=previous_speed_cnt) {
+        i2c_writew(0x0, IC_ENABLE);
+        while (!(i2c_readw(IC_STAT)& 0x1));					//wait disabled
+        if ((speed_cnt==ss_ic_scl_cnt)) {					//Standard Speed
+            i2c_writew(ss_ic_sclh_cnt,IC_SCLH_CNT);
+            i2c_writew(ss_ic_scl_cnt-ss_ic_sclh_cnt,IC_SCLL_CNT);
+            previous_speed_cnt = ss_ic_scl_cnt;
+        } else if (speed_cnt==fs_ic_scl_cnt) {					//Fast Speed
+            i2c_writew(fs_ic_sclh_cnt,IC_SCLH_CNT);
+            i2c_writew(fs_ic_scl_cnt-fs_ic_sclh_cnt,IC_SCLL_CNT);
+            previous_speed_cnt =fs_ic_scl_cnt;
+        }
+    }
+    return 0;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+    if (previous_speed_cnt ==  fs_ic_scl_cnt)
+        return 400000;
+    if (previous_speed_cnt ==  ss_ic_scl_cnt)
+        return 100000;
+    else
+        return 0;
+}
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/i2c/cnc1900_i2c.h u-boot-2011.06/drivers/i2c/cnc1900_i2c.h
--- u-boot-2011.06_original/drivers/i2c/cnc1900_i2c.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/i2c/cnc1900_i2c.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#ifndef __CNC1900_I2C_H__
+#define	__CNC1900_I2C_H__
+
+#define		IC_ENABLE			0x00
+#define		IC_SCLH_CNT			0x04
+#define		IC_SCLL_CNT			0x08
+#define		IC_DATA_CMD			0x0c
+#define		IC_INTR_STAT		0x10
+#define		IC_RAW_INTR_STAT	0x14
+#define		IC_INTR_MASK		0x18
+#define		IC_INTR_CLR			0x1c
+#define		IC_STAT				0x20
+#define		IC_RX_TL			0x24
+#define		IC_TX_TL			0x28
+#define		IC_TXFLR			0x2c
+#define		IC_RXFLR			0x30
+#define		IC_FIFO_CLR			0x34
+#define		IC_RESET			0x38
+#define		IC_SLV_TIMEOUT_L	0x3c
+#define		IC_SLV_TIMEOUT_H	0x3e
+#define		IC_SLV_TIMEOUT_EN	0x40
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/i2c/Makefile u-boot-2011.06/drivers/i2c/Makefile
--- u-boot-2011.06_original/drivers/i2c/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/i2c/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -42,6 +42,7 @@
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
+COBJS-$(CONFIG_CNC1900_I2C) += cnc1900_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/cnc_dw_mmc.c u-boot-2011.06/drivers/mmc/cnc_dw_mmc.c
--- u-boot-2011.06_original/drivers/mmc/cnc_dw_mmc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/cnc_dw_mmc.c	2014-08-28 18:12:18.974057000 +0800
@@ -0,0 +1,57 @@
+#include <common.h>
+#include <dwmmc.h>
+#include <malloc.h>
+
+#define UHS_REG_EXT   0x108
+
+#define SDMMC_UHS_EXT_DRV_SHIFT 23
+#define SDMMC_UHS_EXT_SMP_SHIFT 16
+
+static void cnc_dwmci_init(struct dwmci_host *host)
+{
+	/* Enable SD controller clock */
+	writel(readl(0xb2100140) | (1 << 7) , 0xb2100140);
+	/* Pin mux for SD0/1 both 4-bit */
+	writel(0x03, 0xB2110024);
+
+	dwmci_writel(host, UHS_REG_EXT, 0xA0000000 | (6 << SDMMC_UHS_EXT_DRV_SHIFT)|(3 << SDMMC_UHS_EXT_SMP_SHIFT));
+}
+
+static unsigned int cnc_dwmci_get_clk(int dev_index)
+{
+	return 90000000;
+}
+
+int cnc_dwmci_add_port(int index, u32 regbase, int bus_width)
+{
+	struct dwmci_host *host = NULL;
+	host = malloc(sizeof(struct dwmci_host));
+	if (!host) {
+		printf("dwmci_host malloc fail!\n");
+		return 1;
+	}
+
+	host->name = "DWMMC";
+	host->ioaddr = (void *)regbase;
+	host->buswidth = bus_width;
+
+	host->dev_index = index;
+	host->mmc_clk = cnc_dwmci_get_clk;
+	/* Add the mmc channel to be registered with mmc core */
+	if (add_dwmci(host, 25000000, 400000)) {
+		debug("dwmmc%d registration failed\n", index);
+		return -1;
+	}
+
+	cnc_dwmci_init(host);
+	return 0;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+	cnc_dwmci_add_port(0, CONFIG_CNC1900_SD0_BASE, 4);
+#ifdef CONFIG_CNC1900_SD1
+	cnc_dwmci_add_port(1, CONFIG_CNC1900_SD1_BASE, 4);
+#endif
+	return 0;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/dw_mmc.c u-boot-2011.06/drivers/mmc/dw_mmc.c
--- u-boot-2011.06_original/drivers/mmc/dw_mmc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/dw_mmc.c	2014-08-28 18:56:15.764773000 +0800
@@ -0,0 +1,371 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ * Rajeshawari Shinde <rajeshwari.s@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <dwmmc.h>
+#include <asm-generic/errno.h>
+
+#define PAGE_SIZE 4096
+
+static int dwmci_wait_reset(struct dwmci_host *host, u32 value)
+{
+	unsigned long timeout = 1000;
+	u32 ctrl;
+
+	dwmci_writel(host, DWMCI_CTRL, value);
+
+	while (timeout--) {
+		ctrl = dwmci_readl(host, DWMCI_CTRL);
+		if (!(ctrl & DWMCI_RESET_ALL))
+			return 1;
+	}
+	return 0;
+}
+
+static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
+		u32 desc0, u32 desc1, u32 desc2)
+{
+	struct dwmci_idmac *desc = idmac;
+
+	desc->flags = desc0;
+	desc->cnt = desc1;
+	desc->addr = desc2;
+	desc->next_addr = (unsigned int)desc + sizeof(struct dwmci_idmac);
+}
+
+static void dwmci_prepare_data(struct dwmci_host *host,
+		struct mmc_data *data, struct dwmci_idmac *cur_idmac)
+{
+	unsigned long ctrl;
+	unsigned int i = 0, flags, cnt, blk_cnt;
+	ulong data_start, data_end, start_addr;
+
+
+	blk_cnt = data->blocks;
+
+	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
+
+	data_start = (ulong)cur_idmac;
+	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);
+
+	if (data->flags == MMC_DATA_READ)
+		start_addr = (unsigned int)data->dest;
+	else
+		start_addr = (unsigned int)data->src;
+
+	do {
+		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
+		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
+		if (blk_cnt <= 8) {
+			flags |= DWMCI_IDMAC_LD;
+			cnt = data->blocksize * blk_cnt;
+		} else
+			cnt = data->blocksize * 8;
+
+		dwmci_set_idma_desc(cur_idmac, flags, cnt,
+				start_addr + (i * PAGE_SIZE));
+
+		if (blk_cnt <= 8)
+			break;
+		blk_cnt -= 8;
+		cur_idmac++;
+		i++;
+	} while(1);
+
+	data_end = (ulong)cur_idmac;
+	flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
+
+	ctrl = dwmci_readl(host, DWMCI_CTRL);
+	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
+	dwmci_writel(host, DWMCI_CTRL, ctrl);
+
+	ctrl = dwmci_readl(host, DWMCI_BMOD);
+	ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN;
+	dwmci_writel(host, DWMCI_BMOD, ctrl);
+
+	dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
+	dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
+}
+
+static int dwmci_set_transfer_mode(struct dwmci_host *host,
+		struct mmc_data *data)
+{
+	unsigned long mode;
+
+	mode = DWMCI_CMD_DATA_EXP;
+	if (data->flags & MMC_DATA_WRITE)
+		mode |= DWMCI_CMD_RW;
+
+	return mode;
+}
+
+static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+		struct mmc_data *data)
+{
+	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
+				 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
+	int flags = 0, i;
+	unsigned int timeout = 100000;
+	u32 retry = 10000;
+	u32 mask, ctrl;
+	ulong start = get_timer(0);
+
+	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
+		if (get_timer(start) > timeout) {
+			printf("Timeout on data busy\n");
+			return TIMEOUT;
+		}
+	}
+
+	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
+
+	if (data)
+		dwmci_prepare_data(host, data, cur_idmac);
+
+	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
+
+	if (data)
+		flags = dwmci_set_transfer_mode(host, data);
+
+	if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
+		return -1;
+
+	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+		flags |= DWMCI_CMD_ABORT_STOP;
+	else
+		flags |= DWMCI_CMD_PRV_DAT_WAIT;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		flags |= DWMCI_CMD_RESP_EXP;
+		if (cmd->resp_type & MMC_RSP_136)
+			flags |= DWMCI_CMD_RESP_LENGTH;
+	}
+
+	if (cmd->resp_type & MMC_RSP_CRC)
+		flags |= DWMCI_CMD_CHECK_CRC;
+
+	flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
+
+	debug("Sending CMD%d\n",cmd->cmdidx);
+
+	dwmci_writel(host, DWMCI_CMD, flags);
+
+	for (i = 0; i < retry; i++) {
+		mask = dwmci_readl(host, DWMCI_RINTSTS);
+		if (mask & DWMCI_INTMSK_CDONE) {
+			if (!data)
+				dwmci_writel(host, DWMCI_RINTSTS, mask);
+			break;
+		}
+	}
+
+	if (i == retry)
+		return TIMEOUT;
+
+	if (mask & DWMCI_INTMSK_RTO) {
+		debug("Response Timeout..\n");
+		return TIMEOUT;
+	} else if (mask & DWMCI_INTMSK_RE) {
+		debug("Response Error..\n");
+		return -1;
+	}
+
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		if (cmd->resp_type & MMC_RSP_136) {
+			cmd->response[0] = dwmci_readl(host, DWMCI_RESP3);
+			cmd->response[1] = dwmci_readl(host, DWMCI_RESP2);
+			cmd->response[2] = dwmci_readl(host, DWMCI_RESP1);
+			cmd->response[3] = dwmci_readl(host, DWMCI_RESP0);
+		} else {
+			cmd->response[0] = dwmci_readl(host, DWMCI_RESP0);
+		}
+	}
+
+	if (data) {
+		do {
+			mask = dwmci_readl(host, DWMCI_RINTSTS);
+			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
+				debug("DATA ERROR!\n");
+				return -1;
+			}
+		} while (!(mask & DWMCI_INTMSK_DTO));
+
+		dwmci_writel(host, DWMCI_RINTSTS, mask);
+
+		ctrl = dwmci_readl(host, DWMCI_CTRL);
+		ctrl &= ~(DWMCI_DMA_EN);
+		dwmci_writel(host, DWMCI_CTRL, ctrl);
+	}
+
+	udelay(100);
+
+	return 0;
+}
+
+static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
+{
+	u32 div, status;
+	int timeout = 10000;
+	unsigned long sclk;
+
+	if ((freq == host->clock) || (freq == 0))
+		return 0;
+	/*
+	 * If host->mmc_clk didn't define,
+	 * then assume that host->bus_hz is source clock value.
+	 * host->bus_hz should be set from user.
+	 */
+	if (host->mmc_clk)
+		sclk = host->mmc_clk(host->dev_index);
+	else if (host->bus_hz)
+		sclk = host->bus_hz;
+	else {
+		printf("Didn't get source clock value..\n");
+		return -EINVAL;
+	}
+
+	if (sclk == freq)
+		div = 0;
+	else
+		div = DIV_ROUND_UP(sclk, 2 * freq);
+
+	dwmci_writel(host, DWMCI_CLKENA, 0);
+	dwmci_writel(host, DWMCI_CLKSRC, 0);
+
+	dwmci_writel(host, DWMCI_CLKDIV, div);
+	dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
+			DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
+
+	do {
+		status = dwmci_readl(host, DWMCI_CMD);
+		if (timeout-- < 0) {
+			printf("TIMEOUT error!!\n");
+			return -ETIMEDOUT;
+		}
+	} while (status & DWMCI_CMD_START);
+
+	dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE |
+			DWMCI_CLKEN_LOW_PWR);
+
+	dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
+			DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
+
+	timeout = 10000;
+	do {
+		status = dwmci_readl(host, DWMCI_CMD);
+		if (timeout-- < 0) {
+			printf("TIMEOUT error!!\n");
+			return -ETIMEDOUT;
+		}
+	} while (status & DWMCI_CMD_START);
+
+	host->clock = freq;
+
+	return 0;
+}
+
+static void dwmci_set_ios(struct mmc *mmc)
+{
+	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+	u32 ctype;
+
+	debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock);
+
+	dwmci_setup_bus(host, mmc->clock);
+	switch (mmc->bus_width) {
+	case 8:
+		ctype = DWMCI_CTYPE_8BIT;
+		break;
+	case 4:
+		ctype = DWMCI_CTYPE_4BIT;
+		break;
+	default:
+		ctype = DWMCI_CTYPE_1BIT;
+		break;
+	}
+
+	dwmci_writel(host, DWMCI_CTYPE, ctype);
+
+	if (host->clksel)
+		host->clksel(host);
+}
+
+static int dwmci_init(struct mmc *mmc)
+{
+	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+
+	dwmci_writel(host, DWMCI_PWREN, 1);
+
+	if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
+		debug("%s[%d] Fail-reset!!\n",__func__,__LINE__);
+		return -1;
+	}
+
+	/* Enumerate at 400KHz */
+	dwmci_setup_bus(host, mmc->f_min);
+
+	dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
+	dwmci_writel(host, DWMCI_INTMASK, 0);
+
+	dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);
+
+	dwmci_writel(host, DWMCI_IDINTEN, 0);
+	dwmci_writel(host, DWMCI_BMOD, 1);
+
+	if (host->fifoth_val) {
+		dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
+	}
+	
+	dwmci_writel(host, DWMCI_CLKENA, 0);
+	dwmci_writel(host, DWMCI_CLKSRC, 0);
+
+	return 0;
+}
+
+int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
+{
+	struct mmc *mmc;
+	int err = 0;
+
+	mmc = calloc(sizeof(struct mmc), 1);
+	if (!mmc) {
+		printf("mmc calloc fail!\n");
+		return -1;
+	}
+
+	mmc->priv = host;
+	host->mmc = mmc;
+
+	sprintf(mmc->name, "%s", host->name);
+	mmc->send_cmd = dwmci_send_cmd;
+	mmc->set_ios = dwmci_set_ios;
+	mmc->init = dwmci_init;
+	mmc->f_min = min_clk;
+	mmc->f_max = max_clk;
+
+	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+
+	mmc->host_caps = host->caps;
+
+	if (host->buswidth == 8) {
+		mmc->host_caps |= MMC_MODE_8BIT;
+		mmc->host_caps &= ~MMC_MODE_4BIT;
+	} else {
+		mmc->host_caps |= MMC_MODE_4BIT;
+		mmc->host_caps &= ~MMC_MODE_8BIT;
+	}
+	mmc->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+
+	err = mmc_register(mmc);
+
+	return err;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/Makefile u-boot-2011.06/drivers/mmc/Makefile
--- u-boot-2011.06_original/drivers/mmc/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -38,6 +38,9 @@
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
 COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
 COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
+COBJS-$(CONFIG_DWMMC) += dw_mmc.o
+COBJS-$(CONFIG_CNC_DWMMC) += cnc_dw_mmc.o
+COBJS-$(CONFIG_GENERIC_MMC) += mmc_write.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/mmc.c u-boot-2011.06/drivers/mmc/mmc.c
--- u-boot-2011.06_original/drivers/mmc/mmc.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/mmc.c	2014-07-29 17:28:38.819972000 +0800
@@ -4,23 +4,7 @@
  *
  * Based vaguely on the Linux code
  *
- * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <config.h>
@@ -31,6 +15,7 @@
 #include <malloc.h>
 #include <linux/list.h>
 #include <div64.h>
+#include "mmc_private.h"
 
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
@@ -40,23 +25,44 @@
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
-int __board_mmc_getcd(u8 *cd, struct mmc *mmc) {
+int __weak board_mmc_getwp(struct mmc *mmc)
+{
 	return -1;
 }
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
+int mmc_getwp(struct mmc *mmc)
+{
+	int wp;
+
+	wp = board_mmc_getwp(mmc);
+
+	if (wp < 0) {
+		if (mmc->getwp)
+			wp = mmc->getwp(mmc);
+		else
+			wp = 0;
+	}
+
+	return wp;
+}
+
+int __board_mmc_getcd(struct mmc *mmc) {
+	return -1;
+}
+
+int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
 	alias("__board_mmc_getcd")));
 
 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
-#ifdef CONFIG_MMC_TRACE
 	int ret;
+
+#ifdef CONFIG_MMC_TRACE
 	int i;
 	u8 *ptr;
 
 	printf("CMD_SEND:%d\n", cmd->cmdidx);
 	printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
-	printf("\t\tFLAG\t\t\t %d\n", cmd->flags);
 	ret = mmc->send_cmd(mmc, cmd, data);
 	switch (cmd->resp_type) {
 		case MMC_RSP_NONE:
@@ -84,7 +90,7 @@
 			for (i = 0; i < 4; i++) {
 				int j;
 				printf("\t\t\t\t\t%03d - ", i*4);
-				ptr = &cmd->response[i];
+				ptr = (u8 *)&cmd->response[i];
 				ptr += 3;
 				for (j = 0; j < 4; j++)
 					printf("%02X ", *ptr--);
@@ -99,46 +105,54 @@
 			printf("\t\tERROR MMC rsp not supported\n");
 			break;
 	}
-	return ret;
 #else
-	return mmc->send_cmd(mmc, cmd, data);
+	ret = mmc->send_cmd(mmc, cmd, data);
 #endif
+	return ret;
 }
 
 int mmc_send_status(struct mmc *mmc, int timeout)
 {
 	struct mmc_cmd cmd;
-	int err;
+	int err, retries = 5;
 #ifdef CONFIG_MMC_TRACE
 	int status;
 #endif
 
 	cmd.cmdidx = MMC_CMD_SEND_STATUS;
 	cmd.resp_type = MMC_RSP_R1;
-	cmd.cmdarg = 0;
-	cmd.flags = 0;
+	if (!mmc_host_is_spi(mmc))
+		cmd.cmdarg = mmc->rca << 16;
 
 	do {
 		err = mmc_send_cmd(mmc, &cmd, NULL);
-		if (err)
+		if (!err) {
+			if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
+			    (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
+			     MMC_STATE_PRG)
+				break;
+			else if (cmd.response[0] & MMC_STATUS_MASK) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+				printf("Status Error: 0x%08X\n",
+					cmd.response[0]);
+#endif
+				return COMM_ERR;
+			}
+		} else if (--retries < 0)
 			return err;
-		else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
-			break;
 
 		udelay(1000);
 
-		if (cmd.response[0] & MMC_STATUS_MASK) {
-			printf("Status Error: 0x%08X\n", cmd.response[0]);
-			return COMM_ERR;
-		}
 	} while (timeout--);
 
 #ifdef CONFIG_MMC_TRACE
 	status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
 	printf("CURR STATE:%d\n", status);
 #endif
-	if (!timeout) {
+	if (timeout <= 0) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 		printf("Timeout waiting card ready\n");
+#endif
 		return TIMEOUT;
 	}
 
@@ -152,7 +166,6 @@
 	cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
 	cmd.resp_type = MMC_RSP_R1;
 	cmd.cmdarg = len;
-	cmd.flags = 0;
 
 	return mmc_send_cmd(mmc, &cmd, NULL);
 }
@@ -169,96 +182,18 @@
 			return m;
 	}
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 	printf("MMC Device %d not found\n", dev_num);
+#endif
 
 	return NULL;
 }
 
-static ulong
-mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
+static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
+			   lbaint_t blkcnt)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
-	int timeout = 1000;
-
-	if ((start + blkcnt) > mmc->block_dev.lba) {
-		printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
-			start + blkcnt, mmc->block_dev.lba);
-		return 0;
-	}
-
-	if (blkcnt > 1)
-		cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
-	else
-		cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
-
-	if (mmc->high_capacity)
-		cmd.cmdarg = start;
-	else
-		cmd.cmdarg = start * mmc->write_bl_len;
-
-	cmd.resp_type = MMC_RSP_R1;
-	cmd.flags = 0;
-
-	data.src = src;
-	data.blocks = blkcnt;
-	data.blocksize = mmc->write_bl_len;
-	data.flags = MMC_DATA_WRITE;
-
-	if (mmc_send_cmd(mmc, &cmd, &data)) {
-		printf("mmc write failed\n");
-		return 0;
-	}
-
-	/* SPI multiblock writes terminate using a special
-	 * token, not a STOP_TRANSMISSION request.
-	 */
-	if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
-		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
-		cmd.cmdarg = 0;
-		cmd.resp_type = MMC_RSP_R1b;
-		cmd.flags = 0;
-		if (mmc_send_cmd(mmc, &cmd, NULL)) {
-			printf("mmc fail to send stop cmd\n");
-			return 0;
-		}
-
-		/* Waiting for the ready status */
-		mmc_send_status(mmc, timeout);
-	}
-
-	return blkcnt;
-}
-
-static ulong
-mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
-{
-	lbaint_t cur, blocks_todo = blkcnt;
-
-	struct mmc *mmc = find_mmc_device(dev_num);
-	if (!mmc)
-		return 0;
-
-	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
-		return 0;
-
-	do {
-		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;
-		start += cur;
-		src += cur * mmc->write_bl_len;
-	} while (blocks_todo > 0);
-
-	return blkcnt;
-}
-
-int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
-{
-	struct mmc_cmd cmd;
-	struct mmc_data data;
-	int timeout = 1000;
 
 	if (blkcnt > 1)
 		cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
@@ -271,7 +206,6 @@
 		cmd.cmdarg = start * mmc->read_bl_len;
 
 	cmd.resp_type = MMC_RSP_R1;
-	cmd.flags = 0;
 
 	data.dest = dst;
 	data.blocks = blkcnt;
@@ -285,20 +219,18 @@
 		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 		cmd.cmdarg = 0;
 		cmd.resp_type = MMC_RSP_R1b;
-		cmd.flags = 0;
 		if (mmc_send_cmd(mmc, &cmd, NULL)) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			printf("mmc fail to send stop cmd\n");
+#endif
 			return 0;
 		}
-
-		/* Waiting for the ready status */
-		mmc_send_status(mmc, timeout);
 	}
 
 	return blkcnt;
 }
 
-static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
+static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
 {
 	lbaint_t cur, blocks_todo = blkcnt;
 
@@ -310,8 +242,10 @@
 		return 0;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
-		printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
 			start + blkcnt, mmc->block_dev.lba);
+#endif
 		return 0;
 	}
 
@@ -330,7 +264,7 @@
 	return blkcnt;
 }
 
-int mmc_go_idle(struct mmc* mmc)
+static int mmc_go_idle(struct mmc *mmc)
 {
 	struct mmc_cmd cmd;
 	int err;
@@ -340,7 +274,6 @@
 	cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
 	cmd.cmdarg = 0;
 	cmd.resp_type = MMC_RSP_NONE;
-	cmd.flags = 0;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -352,8 +285,7 @@
 	return 0;
 }
 
-int
-sd_send_op_cond(struct mmc *mmc)
+static int sd_send_op_cond(struct mmc *mmc)
 {
 	int timeout = 1000;
 	int err;
@@ -363,7 +295,6 @@
 		cmd.cmdidx = MMC_CMD_APP_CMD;
 		cmd.resp_type = MMC_RSP_R1;
 		cmd.cmdarg = 0;
-		cmd.flags = 0;
 
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -404,7 +335,6 @@
 		cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
 		cmd.resp_type = MMC_RSP_R3;
 		cmd.cmdarg = 0;
-		cmd.flags = 0;
 
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -420,53 +350,75 @@
 	return 0;
 }
 
+/* We pass in the cmd since otherwise the init seems to fail */
+static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
+		int use_arg)
+{
+	int err;
+
+	cmd->cmdidx = MMC_CMD_SEND_OP_COND;
+	cmd->resp_type = MMC_RSP_R3;
+	cmd->cmdarg = 0;
+	if (use_arg && !mmc_host_is_spi(mmc)) {
+		cmd->cmdarg =
+			(mmc->voltages &
+			(mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
+			(mmc->op_cond_response & OCR_ACCESS_MODE);
+
+		if (mmc->host_caps & MMC_MODE_HC)
+			cmd->cmdarg |= OCR_HCS;
+	}
+	err = mmc_send_cmd(mmc, cmd, NULL);
+	if (err)
+		return err;
+	mmc->op_cond_response = cmd->response[0];
+	return 0;
+}
+
 int mmc_send_op_cond(struct mmc *mmc)
 {
-	int timeout = 10000;
 	struct mmc_cmd cmd;
-	int err;
+	int err, i;
 
 	/* Some cards seem to need this */
 	mmc_go_idle(mmc);
 
  	/* Asking to the card its capabilities */
- 	cmd.cmdidx = MMC_CMD_SEND_OP_COND;
- 	cmd.resp_type = MMC_RSP_R3;
- 	cmd.cmdarg = 0;
- 	cmd.flags = 0;
-
- 	err = mmc_send_cmd(mmc, &cmd, NULL);
+	mmc->op_cond_pending = 1;
+	for (i = 0; i < 2; i++) {
+		err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
+		if (err)
+			return err;
 
- 	if (err)
- 		return err;
+		/* exit if not busy (flag seems to be inverted) */
+		if (mmc->op_cond_response & OCR_BUSY)
+			return 0;
+	}
+	return IN_PROGRESS;
+}
 
- 	udelay(1000);
+int mmc_complete_op_cond(struct mmc *mmc)
+{
+	struct mmc_cmd cmd;
+	int timeout = 1000;
+	uint start;
+	int err;
 
+	mmc->op_cond_pending = 0;
+	start = get_timer(0);
 	do {
-		cmd.cmdidx = MMC_CMD_SEND_OP_COND;
-		cmd.resp_type = MMC_RSP_R3;
-		cmd.cmdarg = (mmc_host_is_spi(mmc) ? 0 :
-				(mmc->voltages &
-				(cmd.response[0] & OCR_VOLTAGE_MASK)) |
-				(cmd.response[0] & OCR_ACCESS_MODE));
-		cmd.flags = 0;
-
-		err = mmc_send_cmd(mmc, &cmd, NULL);
-
+		err = mmc_send_op_cond_iter(mmc, &cmd, 1);
 		if (err)
 			return err;
-
-		udelay(1000);
-	} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
-
-	if (timeout <= 0)
-		return UNUSABLE_ERR;
+		if (get_timer(start) > timeout)
+			return UNUSABLE_ERR;
+		udelay(100);
+	} while (!(mmc->op_cond_response & OCR_BUSY));
 
 	if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
 		cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
 		cmd.resp_type = MMC_RSP_R3;
 		cmd.cmdarg = 0;
-		cmd.flags = 0;
 
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -484,7 +436,7 @@
 }
 
 
-int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
+static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
@@ -494,11 +446,10 @@
 	cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
 	cmd.resp_type = MMC_RSP_R1;
 	cmd.cmdarg = 0;
-	cmd.flags = 0;
 
-	data.dest = ext_csd;
+	data.dest = (char *)ext_csd;
 	data.blocks = 1;
-	data.blocksize = 512;
+	data.blocksize = MMC_MAX_BLOCK_LEN;
 	data.flags = MMC_DATA_READ;
 
 	err = mmc_send_cmd(mmc, &cmd, &data);
@@ -507,7 +458,7 @@
 }
 
 
-int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 {
 	struct mmc_cmd cmd;
 	int timeout = 1000;
@@ -518,20 +469,20 @@
 	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
 				 (index << 16) |
 				 (value << 8);
-	cmd.flags = 0;
 
 	ret = mmc_send_cmd(mmc, &cmd, NULL);
 
 	/* Waiting for the ready status */
-	mmc_send_status(mmc, timeout);
+	if (!ret)
+		ret = mmc_send_status(mmc, timeout);
 
 	return ret;
 
 }
 
-int mmc_change_freq(struct mmc *mmc)
+static int mmc_change_freq(struct mmc *mmc)
 {
-	char ext_csd[512];
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
 	char cardtype;
 	int err;
 
@@ -544,14 +495,12 @@
 	if (mmc->version < MMC_VERSION_4)
 		return 0;
 
-	mmc->card_caps |= MMC_MODE_4BIT;
-
 	err = mmc_send_ext_csd(mmc, ext_csd);
 
 	if (err)
 		return err;
 
-	cardtype = ext_csd[196] & 0xf;
+	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
 
 	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
 
@@ -565,7 +514,7 @@
 		return err;
 
 	/* No high-speed support */
-	if (!ext_csd[185])
+	if (!ext_csd[EXT_CSD_HS_TIMING])
 		return 0;
 
 	/* High Speed is set, there are two types: 52MHz and 26MHz */
@@ -577,19 +526,68 @@
 	return 0;
 }
 
+static int mmc_set_capacity(struct mmc *mmc, int part_num)
+{
+	switch (part_num) {
+	case 0:
+		mmc->capacity = mmc->capacity_user;
+		break;
+	case 1:
+	case 2:
+		mmc->capacity = mmc->capacity_boot;
+		break;
+	case 3:
+		mmc->capacity = mmc->capacity_rpmb;
+		break;
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+		mmc->capacity = mmc->capacity_gp[part_num - 4];
+		break;
+	default:
+		return -1;
+	}
+
+	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+
+	return 0;
+}
+
 int mmc_switch_part(int dev_num, unsigned int part_num)
 {
 	struct mmc *mmc = find_mmc_device(dev_num);
+	int ret;
 
 	if (!mmc)
 		return -1;
 
-	return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
-			  (mmc->part_config & ~PART_ACCESS_MASK)
-			  | (part_num & PART_ACCESS_MASK));
+	ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+			 (mmc->part_config & ~PART_ACCESS_MASK)
+			 | (part_num & PART_ACCESS_MASK));
+	if (ret)
+		return ret;
+
+	return mmc_set_capacity(mmc, part_num);
+}
+
+int mmc_getcd(struct mmc *mmc)
+{
+	int cd;
+
+	cd = board_mmc_getcd(mmc);
+
+	if (cd < 0) {
+		if (mmc->getcd)
+			cd = mmc->getcd(mmc);
+		else
+			cd = 1;
+	}
+
+	return cd;
 }
 
-int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
+static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
@@ -600,7 +598,6 @@
 	cmd.cmdarg = (mode << 31) | 0xffffff;
 	cmd.cmdarg &= ~(0xf << (group * 4));
 	cmd.cmdarg |= value << (group * 4);
-	cmd.flags = 0;
 
 	data.dest = (char *)resp;
 	data.blocksize = 64;
@@ -611,12 +608,12 @@
 }
 
 
-int sd_change_freq(struct mmc *mmc)
+static int sd_change_freq(struct mmc *mmc)
 {
 	int err;
 	struct mmc_cmd cmd;
-	uint scr[2];
-	uint switch_status[16];
+	ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
 	struct mmc_data data;
 	int timeout;
 
@@ -629,7 +626,6 @@
 	cmd.cmdidx = MMC_CMD_APP_CMD;
 	cmd.resp_type = MMC_RSP_R1;
 	cmd.cmdarg = mmc->rca << 16;
-	cmd.flags = 0;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -639,12 +635,11 @@
 	cmd.cmdidx = SD_CMD_APP_SEND_SCR;
 	cmd.resp_type = MMC_RSP_R1;
 	cmd.cmdarg = 0;
-	cmd.flags = 0;
 
 	timeout = 3;
 
 retry_scr:
-	data.dest = (char *)&scr;
+	data.dest = (char *)scr;
 	data.blocksize = 8;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
@@ -670,6 +665,8 @@
 			break;
 		case 2:
 			mmc->version = SD_VERSION_2;
+			if ((mmc->scr[0] >> 15) & 0x1)
+				mmc->version = SD_VERSION_3;
 			break;
 		default:
 			mmc->version = SD_VERSION_1_0;
@@ -686,7 +683,7 @@
 	timeout = 4;
 	while (timeout--) {
 		err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
-				(u8 *)&switch_status);
+				(u8 *)switch_status);
 
 		if (err)
 			return err;
@@ -700,7 +697,17 @@
 	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
 		return 0;
 
-	err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
+	/*
+	 * If the host doesn't support SD_HIGHSPEED, do not switch card to
+	 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
+	 * This can avoid furthur problem when the card runs in different
+	 * mode between the host.
+	 */
+	if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
+		(mmc->host_caps & MMC_MODE_HS)))
+		return 0;
+
+	err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
 
 	if (err)
 		return err;
@@ -742,7 +749,7 @@
 	80,
 };
 
-void mmc_set_ios(struct mmc *mmc)
+static void mmc_set_ios(struct mmc *mmc)
 {
 	mmc->set_ios(mmc);
 }
@@ -760,20 +767,21 @@
 	mmc_set_ios(mmc);
 }
 
-void mmc_set_bus_width(struct mmc *mmc, uint width)
+static void mmc_set_bus_width(struct mmc *mmc, uint width)
 {
 	mmc->bus_width = width;
 
 	mmc_set_ios(mmc);
 }
 
-int mmc_startup(struct mmc *mmc)
+static int mmc_startup(struct mmc *mmc)
 {
-	int err;
+	int err, i;
 	uint mult, freq;
-	u64 cmult, csize;
+	u64 cmult, csize, capacity;
 	struct mmc_cmd cmd;
-	char ext_csd[512];
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
 	int timeout = 1000;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
@@ -781,7 +789,6 @@
 		cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
 		cmd.resp_type = MMC_RSP_R1;
 		cmd.cmdarg = 1;
-		cmd.flags = 0;
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
 		if (err)
@@ -794,7 +801,6 @@
 		MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
 	cmd.resp_type = MMC_RSP_R2;
 	cmd.cmdarg = 0;
-	cmd.flags = 0;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -812,7 +818,6 @@
 		cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
 		cmd.cmdarg = mmc->rca << 16;
 		cmd.resp_type = MMC_RSP_R6;
-		cmd.flags = 0;
 
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -827,7 +832,6 @@
 	cmd.cmdidx = MMC_CMD_SEND_CSD;
 	cmd.resp_type = MMC_RSP_R2;
 	cmd.cmdarg = mmc->rca << 16;
-	cmd.flags = 0;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -890,42 +894,111 @@
 		cmult = (mmc->csd[2] & 0x00038000) >> 15;
 	}
 
-	mmc->capacity = (csize + 1) << (cmult + 2);
-	mmc->capacity *= mmc->read_bl_len;
+	mmc->capacity_user = (csize + 1) << (cmult + 2);
+	mmc->capacity_user *= mmc->read_bl_len;
+	mmc->capacity_boot = 0;
+	mmc->capacity_rpmb = 0;
+	for (i = 0; i < 4; i++)
+		mmc->capacity_gp[i] = 0;
 
-	if (mmc->read_bl_len > 512)
-		mmc->read_bl_len = 512;
+	if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
+		mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
 
-	if (mmc->write_bl_len > 512)
-		mmc->write_bl_len = 512;
+	if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
+		mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
 
 	/* Select the card, and put it into Transfer Mode */
 	if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
 		cmd.cmdidx = MMC_CMD_SELECT_CARD;
-		cmd.resp_type = MMC_RSP_R1b;
+		cmd.resp_type = MMC_RSP_R1;
 		cmd.cmdarg = mmc->rca << 16;
-		cmd.flags = 0;
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 
 		if (err)
 			return err;
 	}
 
+	/*
+	 * For SD, its erase group is always one sector
+	 */
+	mmc->erase_grp_size = 1;
 	mmc->part_config = MMCPART_NOAVAILABLE;
 	if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
 		/* check  ext_csd version and capacity */
 		err = mmc_send_ext_csd(mmc, ext_csd);
-		if (!err & (ext_csd[192] >= 2)) {
-			mmc->capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
-					ext_csd[214] << 16 | ext_csd[215] << 24;
-			mmc->capacity *= 512;
+		if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
+			/*
+			 * According to the JEDEC Standard, the value of
+			 * ext_csd's capacity is valid if the value is more
+			 * than 2GB
+			 */
+			capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
+					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
+					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
+					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+			capacity *= MMC_MAX_BLOCK_LEN;
+			if ((capacity >> 20) > 2 * 1024)
+				mmc->capacity_user = capacity;
+		}
+
+		switch (ext_csd[EXT_CSD_REV]) {
+		case 1:
+			mmc->version = MMC_VERSION_4_1;
+			break;
+		case 2:
+			mmc->version = MMC_VERSION_4_2;
+			break;
+		case 3:
+			mmc->version = MMC_VERSION_4_3;
+			break;
+		case 5:
+			mmc->version = MMC_VERSION_4_41;
+			break;
+		case 6:
+			mmc->version = MMC_VERSION_4_5;
+			break;
+		}
+
+		/*
+		 * Check whether GROUP_DEF is set, if yes, read out
+		 * group size from ext_csd directly, or calculate
+		 * the group size from the csd value.
+		 */
+		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
+			mmc->erase_grp_size =
+				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
+					MMC_MAX_BLOCK_LEN * 1024;
+		} else {
+			int erase_gsz, erase_gmul;
+			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
+			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
+			mmc->erase_grp_size = (erase_gsz + 1)
+				* (erase_gmul + 1);
 		}
 
 		/* store the partition info of emmc */
-		if (ext_csd[160] & PART_SUPPORT)
-			mmc->part_config = ext_csd[179];
+		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
+		    ext_csd[EXT_CSD_BOOT_MULT])
+			mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
+
+		mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+		mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+
+		for (i = 0; i < 4; i++) {
+			int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
+			mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
+				(ext_csd[idx + 1] << 8) + ext_csd[idx];
+			mmc->capacity_gp[i] *=
+				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+			mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+		}
 	}
 
+	err = mmc_set_capacity(mmc, mmc->part_num);
+	if (err)
+		return err;
+
 	if (IS_SD(mmc))
 		err = sd_change_freq(mmc);
 	else
@@ -942,7 +1015,6 @@
 			cmd.cmdidx = MMC_CMD_APP_CMD;
 			cmd.resp_type = MMC_RSP_R1;
 			cmd.cmdarg = mmc->rca << 16;
-			cmd.flags = 0;
 
 			err = mmc_send_cmd(mmc, &cmd, NULL);
 			if (err)
@@ -951,7 +1023,6 @@
 			cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
 			cmd.resp_type = MMC_RSP_R1;
 			cmd.cmdarg = 2;
-			cmd.flags = 0;
 			err = mmc_send_cmd(mmc, &cmd, NULL);
 			if (err)
 				return err;
@@ -960,59 +1031,105 @@
 		}
 
 		if (mmc->card_caps & MMC_MODE_HS)
-			mmc_set_clock(mmc, 50000000);
+			mmc->tran_speed = 50000000;
 		else
-			mmc_set_clock(mmc, 25000000);
+			mmc->tran_speed = 25000000;
 	} else {
-		if (mmc->card_caps & MMC_MODE_4BIT) {
-			/* Set the card to use 4 bit*/
-			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-					EXT_CSD_BUS_WIDTH,
-					EXT_CSD_BUS_WIDTH_4);
+		int idx;
 
-			if (err)
-				return err;
+		/* An array of possible bus widths in order of preference */
+		static unsigned ext_csd_bits[] = {
+			EXT_CSD_BUS_WIDTH_8,
+			EXT_CSD_BUS_WIDTH_4,
+			EXT_CSD_BUS_WIDTH_1,
+		};
+
+		/* An array to map CSD bus widths to host cap bits */
+		static unsigned ext_to_hostcaps[] = {
+			[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
+			[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
+		};
+
+		/* An array to map chosen bus width to an integer */
+		static unsigned widths[] = {
+			8, 4, 1,
+		};
+
+		for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
+			unsigned int extw = ext_csd_bits[idx];
+
+			/*
+			 * Check to make sure the controller supports
+			 * this bus width, if it's more than 1
+			 */
+			if (extw != EXT_CSD_BUS_WIDTH_1 &&
+					!(mmc->host_caps & ext_to_hostcaps[extw]))
+				continue;
 
-			mmc_set_bus_width(mmc, 4);
-		} else if (mmc->card_caps & MMC_MODE_8BIT) {
-			/* Set the card to use 8 bit*/
 			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-					EXT_CSD_BUS_WIDTH,
-					EXT_CSD_BUS_WIDTH_8);
+					EXT_CSD_BUS_WIDTH, extw);
 
 			if (err)
-				return err;
+				continue;
+
+			mmc_set_bus_width(mmc, widths[idx]);
 
-			mmc_set_bus_width(mmc, 8);
+			err = mmc_send_ext_csd(mmc, test_csd);
+			if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
+				    == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
+				 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
+				    == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
+				 && ext_csd[EXT_CSD_REV] \
+				    == test_csd[EXT_CSD_REV]
+				 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
+				    == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+				 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
+					&test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
+
+				mmc->card_caps |= ext_to_hostcaps[extw];
+				break;
+			}
 		}
 
 		if (mmc->card_caps & MMC_MODE_HS) {
 			if (mmc->card_caps & MMC_MODE_HS_52MHz)
-				mmc_set_clock(mmc, 52000000);
+				mmc->tran_speed = 52000000;
 			else
-				mmc_set_clock(mmc, 26000000);
-		} else
-			mmc_set_clock(mmc, 20000000);
+				mmc->tran_speed = 26000000;
+		}
 	}
 
+	mmc_set_clock(mmc, mmc->tran_speed);
+
 	/* fill in device description */
 	mmc->block_dev.lun = 0;
 	mmc->block_dev.type = 0;
 	mmc->block_dev.blksz = mmc->read_bl_len;
+	mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
 	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
-	sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
-			(mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
-	sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
-			(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
-			(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
-	sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
-			(mmc->cid[2] >> 24) & 0xf);
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
+		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
+		(mmc->cid[3] >> 16) & 0xffff);
+	sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
+		(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
+		(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
+		(mmc->cid[2] >> 24) & 0xff);
+	sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
+		(mmc->cid[2] >> 16) & 0xf);
+#else
+	mmc->block_dev.vendor[0] = 0;
+	mmc->block_dev.product[0] = 0;
+	mmc->block_dev.revision[0] = 0;
+#endif
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
 	init_part(&mmc->block_dev);
+#endif
 
 	return 0;
 }
 
-int mmc_send_if_cond(struct mmc *mmc)
+static int mmc_send_if_cond(struct mmc *mmc)
 {
 	struct mmc_cmd cmd;
 	int err;
@@ -1021,7 +1138,6 @@
 	/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
 	cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
 	cmd.resp_type = MMC_RSP_R7;
-	cmd.flags = 0;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
@@ -1044,6 +1160,7 @@
 	mmc->block_dev.removable = 1;
 	mmc->block_dev.block_read = mmc_bread;
 	mmc->block_dev.block_write = mmc_bwrite;
+	mmc->block_dev.block_erase = mmc_berase;
 	if (!mmc->b_max)
 		mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
@@ -1054,17 +1171,29 @@
 	return 0;
 }
 
+#ifdef CONFIG_PARTITIONS
 block_dev_desc_t *mmc_get_dev(int dev)
 {
 	struct mmc *mmc = find_mmc_device(dev);
+	if (!mmc || mmc_init(mmc))
+		return NULL;
 
-	return mmc ? &mmc->block_dev : NULL;
+	return &mmc->block_dev;
 }
+#endif
 
-int mmc_init(struct mmc *mmc)
+int mmc_start_init(struct mmc *mmc)
 {
 	int err;
 
+	if (mmc_getcd(mmc) == 0) {
+		mmc->has_init = 0;
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+		printf("MMC: no card present\n");
+#endif
+		return NO_CARD_ERR;
+	}
+
 	if (mmc->has_init)
 		return 0;
 
@@ -1095,17 +1224,49 @@
 	if (err == TIMEOUT) {
 		err = mmc_send_op_cond(mmc);
 
-		if (err) {
+		if (err && err != IN_PROGRESS) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			printf("Card did not respond to voltage select!\n");
+#endif
 			return UNUSABLE_ERR;
 		}
 	}
 
-	err = mmc_startup(mmc);
+	if (err == IN_PROGRESS)
+		mmc->init_in_progress = 1;
+
+	return err;
+}
+
+static int mmc_complete_init(struct mmc *mmc)
+{
+	int err = 0;
+
+	if (mmc->op_cond_pending)
+		err = mmc_complete_op_cond(mmc);
+
+	if (!err)
+		err = mmc_startup(mmc);
 	if (err)
 		mmc->has_init = 0;
 	else
 		mmc->has_init = 1;
+	mmc->init_in_progress = 0;
+	return err;
+}
+
+int mmc_init(struct mmc *mmc)
+{
+	int err = IN_PROGRESS;
+
+	if (mmc->has_init)
+		return 0;
+	if (!mmc->init_in_progress)
+		err = mmc_start_init(mmc);
+
+	if (!err || err == IN_PROGRESS)
+		err = mmc_complete_init(mmc);
+//	debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
 	return err;
 }
 
@@ -1121,6 +1282,8 @@
 int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+
 void print_mmc_devices(char separator)
 {
 	struct mmc *m;
@@ -1138,11 +1301,34 @@
 	printf("\n");
 }
 
+#else
+void print_mmc_devices(char separator) { }
+#endif
+
 int get_mmc_num(void)
 {
 	return cur_dev_num;
 }
 
+void mmc_set_preinit(struct mmc *mmc, int preinit)
+{
+	mmc->preinit = preinit;
+}
+
+static void do_preinit(void)
+{
+	struct mmc *m;
+	struct list_head *entry;
+
+	list_for_each(entry, &mmc_devices) {
+		m = list_entry(entry, struct mmc, link);
+
+		if (m->preinit)
+			mmc_start_init(m);
+	}
+}
+
+
 int mmc_initialize(bd_t *bis)
 {
 	INIT_LIST_HEAD (&mmc_devices);
@@ -1151,7 +1337,144 @@
 	if (board_mmc_init(bis) < 0)
 		cpu_mmc_init(bis);
 
+#ifndef CONFIG_SPL_BUILD
 	print_mmc_devices(',');
+#endif
+
+	do_preinit();
+	return 0;
+}
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+/*
+ * This function changes the size of boot partition and the size of rpmb
+ * partition present on EMMC devices.
+ *
+ * Input Parameters:
+ * struct *mmc: pointer for the mmc device strcuture
+ * bootsize: size of boot partition
+ * rpmbsize: size of rpmb partition
+ *
+ * Returns 0 on success.
+ */
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+				unsigned long rpmbsize)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	/* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = MMC_CMD62_ARG1;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
+		return err;
+	}
+
+	/* Boot partition changing mode */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = MMC_CMD62_ARG2;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
+		return err;
+	}
+	/* boot partition size is multiple of 128KB */
+	bootsize = (bootsize * 1024) / 128;
+
+	/* Arg: boot partition size */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = bootsize;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+		return err;
+	}
+	/* RPMB partition size is multiple of 128KB */
+	rpmbsize = (rpmbsize * 1024) / 128;
+	/* Arg: RPMB partition size */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = rpmbsize;
 
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+		return err;
+	}
 	return 0;
 }
+
+/*
+ * This function shall form and send the commands to open / close the
+ * boot partition specified by user.
+ *
+ * Input Parameters:
+ * ack: 0x0 - No boot acknowledge sent (default)
+ *	0x1 - Boot acknowledge sent during boot operation
+ * part_num: User selects boot data that will be sent to master
+ *	0x0 - Device not boot enabled (default)
+ *	0x1 - Boot partition 1 enabled for boot
+ *	0x2 - Boot partition 2 enabled for boot
+ * access: User selects partitions to access
+ *	0x0 : No access to boot partition (default)
+ *	0x1 : R/W boot partition 1
+ *	0x2 : R/W boot partition 2
+ *	0x3 : R/W Replay Protected Memory Block (RPMB)
+ *
+ * Returns 0 on success.
+ */
+int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	/* Boot ack enable, boot partition enable , boot partition access */
+	cmd.cmdidx = MMC_CMD_SWITCH;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+			(EXT_CSD_PART_CONF << 16) |
+			((EXT_CSD_BOOT_ACK(ack) |
+			EXT_CSD_BOOT_PART_NUM(part_num) |
+			EXT_CSD_PARTITION_ACCESS(access)) << 8);
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		if (access) {
+			debug("mmc boot partition#%d open fail:Error1 = %d\n",
+			      part_num, err);
+		} else {
+			debug("mmc boot partition#%d close fail:Error = %d\n",
+			      part_num, err);
+		}
+		return err;
+	}
+
+	if (access) {
+		/* 4bit transfer mode at booting time. */
+		cmd.cmdidx = MMC_CMD_SWITCH;
+		cmd.resp_type = MMC_RSP_R1b;
+
+		cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+				(EXT_CSD_BOOT_BUS_WIDTH << 16) |
+				((1 << 0) << 8);
+
+		err = mmc_send_cmd(mmc, &cmd, NULL);
+		if (err) {
+			debug("mmc boot partition#%d open fail:Error2 = %d\n",
+			      part_num, err);
+			return err;
+		}
+	}
+	return 0;
+}
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/mmc_private.h u-boot-2011.06/drivers/mmc/mmc_private.h
--- u-boot-2011.06_original/drivers/mmc/mmc_private.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/mmc_private.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008,2010 Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _MMC_PRIVATE_H_
+#define _MMC_PRIVATE_H_
+
+#include <mmc.h>
+
+extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+			struct mmc_data *data);
+extern int mmc_send_status(struct mmc *mmc, int timeout);
+extern int mmc_set_blocklen(struct mmc *mmc, int len);
+
+#ifndef CONFIG_SPL_BUILD
+
+extern unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt);
+
+extern ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+		const void *src);
+
+#else /* CONFIG_SPL_BUILD */
+
+/* SPL will never write or erase, declare dummies to reduce code size. */
+
+static inline unsigned long mmc_berase(int dev_num, lbaint_t start,
+		lbaint_t blkcnt)
+{
+	return 0;
+}
+
+static inline ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+		const void *src)
+{
+	return 0;
+}
+
+#endif /* CONFIG_SPL_BUILD */
+
+#endif /* _MMC_PRIVATE_H_ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/mmc_write.c u-boot-2011.06/drivers/mmc/mmc_write.c
--- u-boot-2011.06_original/drivers/mmc/mmc_write.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/mmc_write.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <part.h>
+#include "mmc_private.h"
+
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+{
+	struct mmc_cmd cmd;
+	ulong end;
+	int err, start_cmd, end_cmd;
+
+	if (mmc->high_capacity) {
+		end = start + blkcnt - 1;
+	} else {
+		end = (start + blkcnt - 1) * mmc->write_bl_len;
+		start *= mmc->write_bl_len;
+	}
+
+	if (IS_SD(mmc)) {
+		start_cmd = SD_CMD_ERASE_WR_BLK_START;
+		end_cmd = SD_CMD_ERASE_WR_BLK_END;
+	} else {
+		start_cmd = MMC_CMD_ERASE_GROUP_START;
+		end_cmd = MMC_CMD_ERASE_GROUP_END;
+	}
+
+	cmd.cmdidx = start_cmd;
+	cmd.cmdarg = start;
+	cmd.resp_type = MMC_RSP_R1;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	cmd.cmdidx = end_cmd;
+	cmd.cmdarg = end;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	cmd.cmdidx = MMC_CMD_ERASE;
+	cmd.cmdarg = SECURE_ERASE;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	return 0;
+
+err_out:
+	puts("mmc erase failed\n");
+	return err;
+}
+
+unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
+{
+	int err = 0;
+	struct mmc *mmc = find_mmc_device(dev_num);
+	lbaint_t blk = 0, blk_r = 0;
+	int timeout = 1000;
+
+	if (!mmc)
+		return -1;
+
+	if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
+		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+		       "The erase range would be change to "
+		       "0x" LBAF "~0x" LBAF "\n\n",
+		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+		       ((start + blkcnt + mmc->erase_grp_size)
+		       & ~(mmc->erase_grp_size - 1)) - 1);
+
+	while (blk < blkcnt) {
+		blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
+			mmc->erase_grp_size : (blkcnt - blk);
+		err = mmc_erase_t(mmc, start + blk, blk_r);
+		if (err)
+			break;
+
+		blk += blk_r;
+
+		/* Waiting for the ready status */
+		if (mmc_send_status(mmc, timeout))
+			return 0;
+	}
+
+	return blk;
+}
+
+static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
+		lbaint_t blkcnt, const void *src)
+{
+	struct mmc_cmd cmd;
+	struct mmc_data data;
+	int timeout = 1000;
+
+	if ((start + blkcnt) > mmc->block_dev.lba) {
+		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
+		       start + blkcnt, mmc->block_dev.lba);
+		return 0;
+	}
+
+	if (blkcnt == 0)
+		return 0;
+	else if (blkcnt == 1)
+		cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+	else
+		cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+
+	if (mmc->high_capacity)
+		cmd.cmdarg = start;
+	else
+		cmd.cmdarg = start * mmc->write_bl_len;
+
+	cmd.resp_type = MMC_RSP_R1;
+
+	data.src = src;
+	data.blocks = blkcnt;
+	data.blocksize = mmc->write_bl_len;
+	data.flags = MMC_DATA_WRITE;
+
+	if (mmc_send_cmd(mmc, &cmd, &data)) {
+		printf("mmc write failed\n");
+		return 0;
+	}
+
+	/* SPI multiblock writes terminate using a special
+	 * token, not a STOP_TRANSMISSION request.
+	 */
+	if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
+		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+		cmd.cmdarg = 0;
+		cmd.resp_type = MMC_RSP_R1b;
+		if (mmc_send_cmd(mmc, &cmd, NULL)) {
+			printf("mmc fail to send stop cmd\n");
+			return 0;
+		}
+	}
+
+	/* Waiting for the ready status */
+	if (mmc_send_status(mmc, timeout))
+		return 0;
+
+	return blkcnt;
+}
+
+ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src)
+{
+	lbaint_t cur, blocks_todo = blkcnt;
+
+	struct mmc *mmc = find_mmc_device(dev_num);
+	if (!mmc)
+		return 0;
+
+	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
+		return 0;
+
+	do {
+		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;
+		start += cur;
+		src += cur * mmc->write_bl_len;
+	} while (blocks_todo > 0);
+
+	return blkcnt;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mmc/mshci.h u-boot-2011.06/drivers/mmc/mshci.h
--- u-boot-2011.06_original/drivers/mmc/mshci.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mmc/mshci.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,324 @@
+/*
+ * (C) Copyright 2011 Cavium Inc.
+ * Scott Shu <sshu@caviumnetworks.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
+ */
+
+#ifndef _CNS3000_MMC_H
+#define _CNS3000_MMC_H
+
+/* MSHC Internal Registers */
+#define MSHCI_CTRL	0x00	/* Control */
+#define MSHCI_PWREN	0x04   	/* Power-enable */
+#define MSHCI_CLKDIV	0x08   	/* Clock divider */
+#define MSHCI_CLKSRC	0x0C   	/* Clock source */
+#define MSHCI_CLKENA	0x10	/* Clock enable */
+#define MSHCI_TMOUT	0x14	/* Timeout */
+#define MSHCI_CTYPE	0x18	/* Card type */
+#define MSHCI_BLKSIZ	0x1C	/* Block Size */
+#define MSHCI_BYTCNT	0x20	/* Byte count */
+#define MSHCI_INTMSK	0x24	/* Interrupt Mask */
+#define MSHCI_CMDARG	0x28	/* Command Argument */
+#define MSHCI_CMD	0x2C	/* Command */
+#define MSHCI_RESP0	0x30	/* Response 0 */
+#define MSHCI_RESP1	0x34	/* Response 1 */
+#define MSHCI_RESP2	0x38	/* Response 2 */
+#define MSHCI_RESP3	0x3C	/* Response 3 */
+#define MSHCI_MINTSTS	0x40	/* Masked interrupt status */
+#define MSHCI_RINTSTS	0x44	/* Raw interrupt status */
+#define MSHCI_STATUS	0x48	/* Status */
+#define MSHCI_FIFOTH	0x4C	/* FIFO threshold */
+#define MSHCI_CDETECT	0x50	/* Card detect */
+#define MSHCI_WRTPRT	0x54	/* Write protect */
+#define MSHCI_GPIO	0x58	/* General Purpose IO */
+#define MSHCI_TCBCNT	0x5C	/* Transferred CIU byte count */
+#define MSHCI_TBBCNT	0x60	/* Transferred host/DMA to/from byte count */
+#define MSHCI_DEBNCE	0x64	/* Card detect debounce */
+#define MSHCI_USRID	0x68	/* User ID */
+#define MSHCI_VERID	0x6C	/* Version ID */
+#define MSHCI_HCON	0x70	/* Hardware Configuration */
+#define MSHCI_UHS_REG	0x74	/* UHS and DDR setting */
+#define MSHCI_BMOD	0x80    /* Bus mode register */
+#define MSHCI_PLDMND	0x84    /* Poll demand */
+#define MSHCI_DBADDR	0x88    /* Descriptor list base address */
+#define MSHCI_IDSTS	0x8C    /* Internal DMAC status */
+#define MSHCI_IDINTEN	0x90    /* Internal DMAC interrupt enable */
+#define MSHCI_DSCADDR	0x94    /* Current host descriptor address */
+#define MSHCI_BUFADDR	0x98    /* Current host buffer address */
+#define MSHCI_CLKSEL	0x9C
+#define MSHCI_WAKEUPCON	0xA0    /* Wakeup control register */
+#define MSHCI_CLOCKCON	0xA4    /* Clock (delay) control register */
+#define MSHCI_UHS_REG_EXT	0x108
+#define MSHCI_FIFODAT	0x200	/* FIFO data read write */
+
+#define SDMMC_UHS_EXT_DRV_SHIFT 23
+#define SDMMC_UHS_EXT_SMP_SHIFT 16
+
+/* Control Register Register (0x00) */
+#define CTRL_RESET	(0x1<<0)	/* Reset DWC_mobile_storage controller */	
+#define FIFO_RESET	(0x1<<1)	/* Reset FIFO */
+#define DMA_RESET	(0x1<<2)	/* Reset DMA interface */
+#define INT_ENABLE	(0x1<<4)	/* Global interrupt enable/disable bit */
+#define DMA_ENABLE	(0x1<<5)	/* DMA transfer mode enable/disable bit */
+#define READ_WAIT	(0x1<<6)	/* For sending read-wait to SDIO cards */
+#define SEND_IRQ_RESP	(0x1<<7)	/* Send auto IRQ response */
+#define ABRT_READ_DATA	(0x1<<8)	
+#define SEND_CCSD	(0x1<<9)
+#define SEND_AS_CCSD	(0x1<<10)
+#define CEATA_INTSTAT	(0x1<<11)
+#define CARD_VOLA	(0xF<<16)
+#define CARD_VOLB	(0xF<<20)
+#define ENABLE_OD_PULLUP (0x1<<24)	
+#define ENABLE_IDMAC    (0x1<<25)
+
+#define MSHCI_RESET_ALL	(0x1)
+
+/* Power Enable Register (0x04) */
+#define POWER_ENABLE	(0x1<<0)
+
+/* Clock Divider Register (0x08) */
+#define CLK_DIVIDER0	(0xFF<<0)
+#define CLK_DIVIDER1	(0xFF<<8)
+#define	CLK_DIVIDER2	(0xFF<<16)
+#define CLK_DIVIDER3	(0xFF<<24)
+
+/* Clock Enable Register (0x10) */
+#define CLK_SDMMC_MAX	(48000000)
+#define CLK_ENABLE	(0x1<<0)
+#define CLK_DISABLE	(0x0<<0)
+
+/* Timeout  Register (0x14) */
+#define RSP_TIMEOUT	(0xFF<<0)
+#define DATA_TIMEOUT	(0xFFFFFF<<8)
+
+/* Card Type Register (0x18) */
+#define CARD_WIDTH4	(0xFFFF<<0)
+#define CARD_WIDTH8	(0xFFFF<<16)
+
+/* Block Size Register (0x1C) */
+#define BLK_SIZ		(0xFFFF<<0)
+
+/* Interrupt Mask Register (0x24) */
+#define INT_MASK	(0xFFFF<<0)
+#define	SDIO_INT_MASK	(0xFFFF<<16)
+#define SDIO_INT_ENABLE (0x1<<16)
+
+/* interrupt bits */
+#define INTMSK_ALL	0xFFFFFFFF
+#define INTMSK_CDETECT 	(0x1<<0) 
+#define INTMSK_RE	(0x1<<1)
+#define INTMSK_CDONE 	(0x1<<2)
+#define INTMSK_DTO	(0x1<<3)
+#define INTMSK_TXDR     (0x1<<4)
+#define INTMSK_RXDR     (0x1<<5)
+#define INTMSK_RCRC     (0x1<<6)
+#define INTMSK_DCRC     (0x1<<7)
+#define INTMSK_RTO      (0x1<<8)
+#define INTMSK_DRTO    	(0x1<<9) 
+#define INTMSK_HTO      (0x1<<10)
+#define INTMSK_FRUN     (0x1<<11)
+#define INTMSK_HLE      (0x1<<12)
+#define INTMSK_SBE      (0x1<<13)
+#define INTMSK_ACD      (0x1<<14)
+#define INTMSK_EBE	(0x1<<15)
+#define INTMSK_DMA	(INTMSK_ACD|INTMSK_RXDR|INTMSK_TXDR)
+
+#define INT_SRC_IDMAC   (0x0)
+#define INT_SRC_MINT    (0x1)
+
+
+/* Command Register (0x2C) */
+#define CMD_RESP_EXP_BIT	(0x1<<6)	
+#define CMD_RESP_LENGTH_BIT	(0x1<<7)
+#define CMD_CHECK_CRC_BIT	(0x1<<8)
+#define CMD_DATA_EXP_BIT	(0x1<<9)
+#define CMD_RW_BIT		(0x1<<10)
+#define CMD_TRANSMODE_BIT	(0x1<<11)
+#define CMD_SENT_AUTO_STOP_BIT	(0x1<<12)
+#define CMD_WAIT_PRV_DAT_BIT	(0x1<<13)
+#define CMD_ABRT_CMD_BIT	(0x1<<14)
+#define CMD_SEND_INIT_BIT	(0x1<<15)
+#define CMD_CARD_NUM_BITS	(0x1F<<16)
+#define CMD_SEND_CLK_ONLY	(0x1<<21)
+#define CMD_READ_CEATA		(0x1<<22)
+#define CMD_CCS_EXPECTED	(0x1<<23)
+#define CMD_STRT_BIT		(0x1<<31)
+#define CMD_ONLY_CLK		(CMD_STRT_BIT | CMD_SEND_CLK_ONLY | \
+						CMD_WAIT_PRV_DAT_BIT)
+/* Masked Interrupt Status Register (0x40) */
+
+/* Raw Interrupt Register (0x44) */
+#define INT_STATUS	(0xFFFF<<0)
+#define SDIO_INTR	(0xFFFF<<16)
+#define DATA_ERR	(INTMSK_EBE|INTMSK_SBE|INTMSK_HLE|INTMSK_FRUN |\
+					INTMSK_EBE |INTMSK_DCRC)
+#define DATA_TOUT	(INTMSK_HTO|INTMSK_DRTO)
+#define DATA_STATUS	(DATA_ERR|DATA_TOUT|INTMSK_RXDR|INTMSK_TXDR|INTMSK_DTO)
+#define CMD_STATUS	(INTMSK_RTO|INTMSK_RCRC|INTMSK_CDONE|INTMSK_RE)
+#define CMD_ERROR       (INTMSK_RCRC|INTMSK_RTO|INTMSK_RE)
+
+/* Status Register (0x48) */
+#define FIFO_RXWTRMARK	(0x1<<0)
+#define FIFO_TXWTRMARK	(0x1<<1)
+#define FIFO_EMPTY	(0x1<<2)
+#define FIFO_FULL	(0x1<<3)
+#define CMD_FSMSTAT	(0xF<<4)
+#define	DATA_3STATUS	(0x1<<8)
+#define DATA_BUSY	(0x1<<9)
+#define DATA_MCBUSY	(0x1<<10)
+#define RSP_INDEX	(0x3F<<11)
+#define FIFO_COUNT	(0x1FFF<<17)
+#define	DMA_ACK		(0x1<<30)
+#define	DMA_REQ		(0x1<<31)
+#define FIFO_WIDTH 	(0x4)
+#define FIFO_DEPTH      (0x20)
+
+/*Command FSM status */
+#define FSM_IDLE		(0 <<4)          		
+#define FSM_SEND_INIT_SEQ	(1 <<4)  
+#define FSM_TX_CMD_STARTBIT	(2 <<4)
+#define FSM_TX_CMD_TXBIT   	(3 <<4)
+#define	FSM_TX_CMD_INDEX_ARG	(4 <<4)
+#define	FSM_TX_CMD_CRC7		(5 <<4)
+#define FSM_TX_CMD_ENDBIT	(6 <<4)
+#define	FSM_RX_RESP_STARTBIT	(7 <<4)
+#define FSM_RX_RESP_IRQRESP	(8 <<4)
+#define FSM_RX_RESP_TXBIT	(9 <<4)
+#define FSM_RX_RESP_CMDIDX	(10<<4)
+#define FSM_RX_RESP_DATA	(11<<4)
+#define FSM_RX_RESP_CRC7	(12<<4)
+#define FSM_RX_RESP_ENDBIT	(13<<4)
+#define FSM_CMD_PATHWAITNCC	(14<<4)
+#define FSM_WAIT		(15<<4)
+
+/* FIFO Threshold Watermark Register (0x4C) */
+#define TX_WMARK		(0xFFF<<0)
+#define RX_WMARK		(0xFFF<<16)
+#define MSIZE_MASK		(0x7<<28)
+
+/* DW DMA Mutiple Transaction Size */
+#define MSIZE_1			(0<<28)
+#define MSIZE_4			(1<<28)
+#define MSIZE_8			(2<<28)
+#define MSIZE_16		(3<<28)
+#define MSIZE_32		(4<<28)
+#define MSIZE_64		(5<<28)		
+#define MSIZE_128		(6<<28)
+#define MSIZE_256		(7<<28)
+
+/* FIFO Threshold Watermark Register (0x4C) */
+#define GPI			(0xFF<<0)
+#define	GPO			(0xFFFF<<8)
+
+/* Card Detect Register (0x50) */
+#define CARD_PRESENT	(0x1<<0)
+
+/* Write Protect Register (0x54) */
+#define WRTPRT_ON	(0x1<<0)
+
+/* Bus Mode Register (0x80) */
+#define BMOD_IDMAC_RESET        (0x1<<0)
+#define BMOD_IDMAC_FB           (0x1<<1)
+#define BMOD_IDMAC_ENABLE       (0x1<<7)
+
+/* Hardware Configuration  Register (0x70) */
+#define CARD_TYPE		(0x1<<0)
+#define NUM_CARDS		(0x1F<<1)
+#define H_BUS_TYPE		(0x1<<6)
+#define H_DATA_WIDTH		(0x7<<7)
+#define H_ADDR_WIDTH		(0x3F<<10)
+#define DMA_INTERFACE		(0x3<<16)
+#define	GE_DMA_DATA_WIDTH	(0x7<<18)
+#define FIFO_RAM_INSIDE		(0x1<<21)
+#define UMPLEMENT_HOLD_REG	(0x1<<22)
+#define SET_CLK_FALSE_PATH	(0x1<<23)
+#define NUM_CLK_DIVIDER		(0x3<<24)
+
+/* Hardware Configuration  Register (0x8C) */
+#define IDSTS_FSM               (0xf<<13)
+#define IDSTS_EB                (0x7<<10)
+#define IDSTS_AIS               (0x1<<9)
+#define IDSTS_NIS               (0x1<<8)
+#define IDSTS_CES               (0x1<<5)
+#define IDSTS_DU                (0x1<<4)
+#define IDSTS_FBE               (0x1<<2)
+#define IDSTS_RI                (0x1<<1)
+#define IDSTS_TI                (0x1<<0)
+
+struct mshci_ops;
+
+struct mshci_idmac {
+        u32     des0;
+        u32     des1;
+        u32     des2;
+        u32     des3;
+#define MSHCI_IDMAC_OWN         (1<<31)
+#define MSHCI_IDMAC_ER          (1<<5)
+#define MSHCI_IDMAC_CH          (1<<4)
+#define MSHCI_IDMAC_FS          (1<<3)
+#define MSHCI_IDMAC_LD          (1<<2)
+#define MSHCI_IDMAC_DIC         (1<<1)
+#define INTMSK_IDMAC_ALL        (0x337)
+#define INTMSK_IDMAC_ERROR      (0x214)        
+};
+
+#ifndef __iomem
+#define __iomem
+#endif
+
+struct mshci_host {
+	/* Data set by hardware interface driver */
+	const char		*hw_name;	/* Hardware bus name */
+
+	int			irq;		/* Device IRQ */
+	void __iomem *		ioaddr;		/* Mapped address */
+
+	/* Internal data */
+	struct mmc		*mmc;		/* MMC structure */
+	u64			dma_mask;	/* custom DMA mask */
+
+	int			flags;		/* Host attributes */
+#define MSHCI_USE_IDMA		(1<<1)		/* Host is ADMA capable */
+#define MSHCI_REQ_USE_DMA	(1<<2)		/* Use DMA for this req. */
+#define MSHCI_DEVICE_DEAD	(1<<3)		/* Device unresponsive */
+
+
+	unsigned int		version;	/* SDHCI spec. version */
+
+	unsigned int		max_clk;	/* Max possible freq (MHz) */
+	unsigned int		timeout_clk;	/* Timeout freq (KHz) */
+
+	unsigned int		clock;		/* Current clock (MHz) */
+	unsigned short		power;		/* Current voltage */
+
+	dma_addr_t		adma_addr;	/* Mapped ADMA descr. table */
+};
+
+static inline void mshci_writel(struct mshci_host *host, u32 val, int reg)
+{
+	writel(val, host->ioaddr + reg);
+}
+
+static inline u32 mshci_readl(struct mshci_host *host, int reg)
+{
+	return readl(host->ioaddr + reg);
+}
+
+#endif /* _CNS3000_MMC_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/cnc_nand.c u-boot-2011.06/drivers/mtd/nand/cnc_nand.c
--- u-boot-2011.06_original/drivers/mtd/nand/cnc_nand.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/cnc_nand.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2007 STMicroelectronics, <www.st.com>
+ * (C) Copyright 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <linux/mtd/nand_ecc.h>
+
+#define CE0_CFG0 (CONFIG_CNC_NAND_BASE + 0x00)
+#define CE0_CFG1 (CONFIG_CNC_NAND_BASE + 0x04)
+#define CE0_CFG2 (CONFIG_CNC_NAND_BASE + 0x08)
+#define CE0_CFG3 (CONFIG_CNC_NAND_BASE + 0x0C)
+
+#define SMC_STAT (CONFIG_CNC_NAND_BASE + 0x30)
+#define SMC_MODE (CONFIG_CNC_NAND_BASE + 0x38)
+#define SMC_ECC_CODE (CONFIG_CNC_NAND_BASE + 0x40)
+#define SMC_ECC_CONT (CONFIG_CNC_NAND_BASE + 0x44)
+#define SMC_ECC_ADDR (CONFIG_CNC_NAND_BASE + 0x48)
+
+#define FORCE_CE_LOW 0x200
+#define STATUS_READY 0x001
+
+#define CFG0_16BIT 0x01000000
+
+#define MASK_ALE	(1 << 22)
+#define MASK_CLE	(1 << 21)
+
+static void cnc_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+	struct nand_chip *nand = mtd->priv;
+
+	if (mode == NAND_ECC_READ)
+		__raw_writel((unsigned int)(nand->IO_ADDR_R), (volatile unsigned int *) SMC_ECC_ADDR);
+
+	if (mode == NAND_ECC_WRITE)
+		__raw_writel((unsigned int) (nand->IO_ADDR_W), (volatile unsigned int *) SMC_ECC_ADDR);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int cnc_nand_calculate(struct mtd_info *mtd,
+		const u_char *dat, u_char *ecc_code)
+{
+	unsigned int ecc = __raw_readl(SMC_ECC_CODE);
+
+	ecc_code[0] = (u_char)(ecc);
+	ecc_code[1] = (u_char)(ecc >> 8);
+	ecc_code[2] = (u_char)(ecc >> 16);
+	return 0;
+}
+
+static int cnc_nand_dev_ready(struct mtd_info *mtd)
+{
+	unsigned int st = __raw_readl(SMC_STAT);
+	return st & STATUS_READY;
+}
+
+static void cnc_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
+{
+	struct nand_chip *nand = mtd->priv;
+
+	if (len % 4)
+		__raw_readsb((u32)nand->IO_ADDR_R, buf, len);
+	else
+		__raw_readsl((u32)nand->IO_ADDR_R, buf, len / 4);
+}
+
+static void cnc_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
+{
+	struct nand_chip *nand = mtd->priv;
+
+	if (len % 4)
+		__raw_writesb((u32)nand->IO_ADDR_W, buf, len);
+	else
+		__raw_writesl((u32)nand->IO_ADDR_W, buf, len / 4);
+}
+
+static void cnc_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *nand = mtd->priv;
+	unsigned int addr = CONFIG_SYS_NAND_BASE;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE)
+			addr |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			addr |= MASK_ALE;
+
+		nand->IO_ADDR_W = (void *)addr; 
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		__raw_writeb(cmd, nand->IO_ADDR_W);
+}
+
+static void cnc_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct nand_chip *nand = mtd->priv;
+	unsigned int cfg0 = 0;
+
+	cfg0 = __raw_readl(CE0_CFG0);
+	if (nand->options & NAND_BUSWIDTH_16)
+		cfg0 |= CFG0_16BIT;
+	else
+		cfg0 &= ~CFG0_16BIT;
+
+	if (chip >= 0)
+		__raw_writel(cfg0 | FORCE_CE_LOW, CE0_CFG0);
+}
+
+static void cnc_nand_init(void)
+{
+
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+	nand->options = NAND_USE_FLASH_BBT;
+	nand->chip_delay = 5;
+
+	/* Set address of hardware control function */
+	nand->select_chip = cnc_nand_select_chip;
+	nand->cmd_ctrl	  = cnc_nand_cmd_ctrl;
+	nand->dev_ready	  = cnc_nand_dev_ready;
+
+	/* Speed up buffer I/O */
+	nand->read_buf    = cnc_nand_read_buf;
+	nand->write_buf   = cnc_nand_write_buf;
+
+	/* Use board-specific ECC config */
+	nand->ecc.mode      = NAND_ECC_HW;
+	nand->ecc.hwctl     = cnc_nand_hwctl;
+	nand->ecc.calculate = cnc_nand_calculate;
+	nand->ecc.correct   = nand_correct_data;
+	nand->ecc.size      = 512;
+	nand->ecc.bytes     = 3;
+
+	cnc_nand_init();
+	return 0;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/erase u-boot-2011.06/drivers/mtd/nand/erase
--- u-boot-2011.06_original/drivers/mtd/nand/erase	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/erase	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+info:1:nand_util.c:83:	const char *mtd_device = meminfo->name;
+info:2:nand_util.c:85:	struct nand_chip *chip = meminfo->priv;
+info:3:nand_util.c:87:	if ((opts->offset & (meminfo->writesize - 1)) != 0) {
+info:4:nand_util.c:96:	erase.len  = meminfo->erasesize;
+info:5:nand_util.c:98:	erase_length = lldiv(opts->length + meminfo->erasesize - 1,
+info:6:nand_util.c:99:			     meminfo->erasesize);
+info:7:nand_util.c:110:		struct nand_chip *priv_nand = meminfo->priv;
+info:8:nand_util.c:125:	     erase.addr += meminfo->erasesize) {
+info:9:nand_util.c:130:			int ret = meminfo->block_isbad(meminfo, erase.addr);
+info:10:nand_util.c:153:		result = meminfo->erase(meminfo, &erase);
+info:11:nand_util.c:168:			result = meminfo->write_oob(meminfo,
+info:12:nand_util.c:205:		struct nand_chip *priv_nand = meminfo->priv;
+nand_util.c:83:	const char *mtd_device = meminfo->name;
+nand_util.c:85:	struct nand_chip *chip = meminfo->priv;
+nand_util.c:87:	if ((opts->offset & (meminfo->writesize - 1)) != 0) {
+nand_util.c:96:	erase.len  = meminfo->erasesize;
+nand_util.c:98:	erase_length = lldiv(opts->length + meminfo->erasesize - 1,
+nand_util.c:99:			     meminfo->erasesize);
+nand_util.c:110:		struct nand_chip *priv_nand = meminfo->priv;
+nand_util.c:125:	     erase.addr += meminfo->erasesize) {
+nand_util.c:130:			int ret = meminfo->block_isbad(meminfo, erase.addr);
+nand_util.c:153:		result = meminfo->erase(meminfo, &erase);
+nand_util.c:168:			result = meminfo->write_oob(meminfo,
+nand_util.c:205:		struct nand_chip *priv_nand = meminfo->priv;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/info u-boot-2011.06/drivers/mtd/nand/info
--- u-boot-2011.06_original/drivers/mtd/nand/info	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/info	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,12 @@
+nand_util.c:83:	const char *mtd_device = meminfo->name;
+nand_util.c:85:	struct nand_chip *chip = meminfo->priv;
+nand_util.c:87:	if ((opts->offset & (meminfo->writesize - 1)) != 0) {
+nand_util.c:96:	erase.len  = meminfo->erasesize;
+nand_util.c:98:	erase_length = lldiv(opts->length + meminfo->erasesize - 1,
+nand_util.c:99:			     meminfo->erasesize);
+nand_util.c:110:		struct nand_chip *priv_nand = meminfo->priv;
+nand_util.c:125:	     erase.addr += meminfo->erasesize) {
+nand_util.c:130:			int ret = meminfo->block_isbad(meminfo, erase.addr);
+nand_util.c:153:		result = meminfo->erase(meminfo, &erase);
+nand_util.c:168:			result = meminfo->write_oob(meminfo,
+nand_util.c:205:		struct nand_chip *priv_nand = meminfo->priv;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/Makefile u-boot-2011.06/drivers/mtd/nand/Makefile
--- u-boot-2011.06_original/drivers/mtd/nand/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -33,6 +33,7 @@
 COBJS-y += nand_ids.o
 COBJS-y += nand_util.o
 
+COBJS-$(CONFIG_CNC_NAND) += cnc_nand.o
 COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
 COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
 COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_base.c u-boot-2011.06/drivers/mtd/nand/nand_base.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_base.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_base.c	2014-07-29 17:28:38.819972000 +0800
@@ -88,8 +88,8 @@
 		   48, 49, 50, 51, 52, 53, 54, 55,
 		   56, 57, 58, 59, 60, 61, 62, 63},
 	.oobfree = {
-		{.offset = 2,
-		 .length = 38}}
+		{.offset = 0,
+		 .length = 40}}
 };
 
 static struct nand_ecclayout nand_oob_128 = {
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_base_profiling.c u-boot-2011.06/drivers/mtd/nand/nand_base_profiling.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_base_profiling.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_base_profiling.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,3053 @@
+/*
+ *  drivers/mtd/nand.c
+ *
+ *  Overview:
+ *   This is the generic MTD driver for NAND flash devices. It should be
+ *   capable of working with almost all NAND chips currently available.
+ *   Basic support for AG-AND chips is provided.
+ *
+ *	Additional technical information is available on
+ *	http://www.linux-mtd.infradead.org/doc/nand.html
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+ *		  2002-2006 Thomas Gleixner (tglx@linutronix.de)
+ *
+ *  Credits:
+ *	David Woodhouse for adding multichip support
+ *
+ *	Aleph One Ltd. and Toby Churchill Ltd. for supporting the
+ *	rework for 2K page size chips
+ *
+ *  TODO:
+ *	Enable cached programming for 2k page size chips
+ *	Check, if mtd->ecctype should be set to MTD_ECC_HW
+ *	if we have HW ecc support.
+ *	The AG-AND chips have nice features for speed improvement,
+ *	which are not supported yet. Read / program 4 pages in one go.
+ *	BBT table is not serialized, has to be fixed
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <common.h>
+
+#define ENOTSUPP	524	/* Operation is not supported */
+
+#include <malloc.h>
+#include <watchdog.h>
+#include <linux/err.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/errno.h>
+
+/*
+ * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting
+ * a flash.  NAND flash is initialized prior to interrupts so standard timers
+ * can't be used.  CONFIG_SYS_NAND_RESET_CNT should be set to a value
+ * which is greater than (max NAND reset time / NAND status read time).
+ * A conservative default of 200000 (500 us / 25 ns) is used as a default.
+ */
+#ifndef CONFIG_SYS_NAND_RESET_CNT
+#define CONFIG_SYS_NAND_RESET_CNT 200000
+#endif
+
+unsigned long long time_stamp[10000];
+int trace_i = 0;
+int item = 0;
+
+/* Define default oob placement schemes for large and small page devices */
+static struct nand_ecclayout nand_oob_8 = {
+	.eccbytes = 3,
+	.eccpos = {0, 1, 2},
+	.oobfree = {
+		{.offset = 3,
+		 .length = 2},
+		{.offset = 6,
+		 .length = 2}}
+};
+
+static struct nand_ecclayout nand_oob_16 = {
+	.eccbytes = 6,
+	.eccpos = {0, 1, 2, 3, 6, 7},
+	.oobfree = {
+		{.offset = 8,
+		 . length = 8}}
+};
+
+static struct nand_ecclayout nand_oob_64 = {
+	.eccbytes = 24,
+	.eccpos = {
+		   40, 41, 42, 43, 44, 45, 46, 47,
+		   48, 49, 50, 51, 52, 53, 54, 55,
+		   56, 57, 58, 59, 60, 61, 62, 63},
+	.oobfree = {
+		{.offset = 0,
+		 .length = 40}}
+};
+
+static struct nand_ecclayout nand_oob_128 = {
+	.eccbytes = 48,
+	.eccpos = {
+		    80,  81,  82,  83,	84,  85,  86,  87,
+		    88,  89,  90,  91,	92,  93,  94,  95,
+		    96,  97,  98,  99, 100, 101, 102, 103,
+		   104, 105, 106, 107, 108, 109, 110, 111,
+		   112, 113, 114, 115, 116, 117, 118, 119,
+		   120, 121, 122, 123, 124, 125, 126, 127},
+	.oobfree = {
+		{.offset = 2,
+		 .length = 78}}
+};
+
+
+static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
+			   int new_state);
+
+static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+			     struct mtd_oob_ops *ops);
+
+static int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
+
+/**
+ * nand_release_device - [GENERIC] release chip
+ * @mtd:	MTD device structure
+ *
+ * Deselect, release chip lock and wake up anyone waiting on the device
+ */
+static void nand_release_device (struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	this->select_chip(mtd, -1);	/* De-select the NAND device */
+}
+
+/**
+ * nand_read_byte - [DEFAULT] read one byte from the chip
+ * @mtd:	MTD device structure
+ *
+ * Default read function for 8bit buswith
+ */
+static uint8_t nand_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	return readb(chip->IO_ADDR_R);
+}
+
+/**
+ * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
+ * @mtd:	MTD device structure
+ *
+ * Default read function for 16bit buswith with
+ * endianess conversion
+ */
+static uint8_t nand_read_byte16(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
+}
+
+/**
+ * nand_read_word - [DEFAULT] read one word from the chip
+ * @mtd:	MTD device structure
+ *
+ * Default read function for 16bit buswith without
+ * endianess conversion
+ */
+static u16 nand_read_word(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	return readw(chip->IO_ADDR_R);
+}
+
+/**
+ * nand_select_chip - [DEFAULT] control CE line
+ * @mtd:	MTD device structure
+ * @chipnr:	chipnumber to select, -1 for deselect
+ *
+ * Default select function for 1 chip devices.
+ */
+static void nand_select_chip(struct mtd_info *mtd, int chipnr)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	switch (chipnr) {
+	case -1:
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+		break;
+	case 0:
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+/**
+ * nand_write_buf - [DEFAULT] write buffer to chip
+ * @mtd:	MTD device structure
+ * @buf:	data buffer
+ * @len:	number of bytes to write
+ *
+ * Default write function for 8bit buswith
+ */
+static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		writeb(buf[i], chip->IO_ADDR_W);
+}
+
+/**
+ * nand_read_buf - [DEFAULT] read chip data into buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer to store date
+ * @len:	number of bytes to read
+ *
+ * Default read function for 8bit buswith
+ */
+static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		buf[i] = readb(chip->IO_ADDR_R);
+}
+
+/**
+ * nand_verify_buf - [DEFAULT] Verify chip data against buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer containing the data to compare
+ * @len:	number of bytes to compare
+ *
+ * Default verify function for 8bit buswith
+ */
+static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		if (buf[i] != readb(chip->IO_ADDR_R))
+			return -EFAULT;
+	return 0;
+}
+
+/**
+ * nand_write_buf16 - [DEFAULT] write buffer to chip
+ * @mtd:	MTD device structure
+ * @buf:	data buffer
+ * @len:	number of bytes to write
+ *
+ * Default write function for 16bit buswith
+ */
+static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+	u16 *p = (u16 *) buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		writew(p[i], chip->IO_ADDR_W);
+
+}
+
+/**
+ * nand_read_buf16 - [DEFAULT] read chip data into buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer to store date
+ * @len:	number of bytes to read
+ *
+ * Default read function for 16bit buswith
+ */
+static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+	u16 *p = (u16 *) buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		p[i] = readw(chip->IO_ADDR_R);
+}
+
+/**
+ * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer containing the data to compare
+ * @len:	number of bytes to compare
+ *
+ * Default verify function for 16bit buswith
+ */
+static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+	u16 *p = (u16 *) buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		if (p[i] != readw(chip->IO_ADDR_R))
+			return -EFAULT;
+
+	return 0;
+}
+
+/**
+ * nand_block_bad - [DEFAULT] Read bad block marker from the chip
+ * @mtd:	MTD device structure
+ * @ofs:	offset from device start
+ * @getchip:	0, if the chip is already selected
+ *
+ * Check, if the block is bad.
+ */
+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+	int page, chipnr, res = 0;
+	struct nand_chip *chip = mtd->priv;
+	u16 bad;
+
+	page = (int)(ofs >> chip->page_shift) & chip->pagemask;
+
+	if (getchip) {
+		chipnr = (int)(ofs >> chip->chip_shift);
+
+		nand_get_device(chip, mtd, FL_READING);
+
+		/* Select the NAND device */
+		chip->select_chip(mtd, chipnr);
+	}
+
+	if (chip->options & NAND_BUSWIDTH_16) {
+		chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
+			      page);
+		bad = cpu_to_le16(chip->read_word(mtd));
+		if (chip->badblockpos & 0x1)
+			bad >>= 8;
+		if ((bad & 0xFF) != 0xff)
+			res = 1;
+	} else {
+		chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
+		if (chip->read_byte(mtd) != 0xff)
+			res = 1;
+	}
+
+	if (getchip)
+		nand_release_device(mtd);
+
+	return res;
+}
+
+/**
+ * nand_default_block_markbad - [DEFAULT] mark a block bad
+ * @mtd:	MTD device structure
+ * @ofs:	offset from device start
+ *
+ * This is the default implementation, which can be overridden by
+ * a hardware specific driver.
+*/
+static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	struct nand_chip *chip = mtd->priv;
+	uint8_t buf[2] = { 0, 0 };
+	int block, ret;
+
+	/* Get block number */
+	block = (int)(ofs >> chip->bbt_erase_shift);
+	if (chip->bbt)
+		chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+
+	/* Do we have a flash based bad block table ? */
+	if (chip->options & NAND_USE_FLASH_BBT)
+		ret = nand_update_bbt(mtd, ofs);
+	else {
+		/* We write two bytes, so we dont have to mess with 16 bit
+		 * access
+		 */
+		nand_get_device(chip, mtd, FL_WRITING);
+		ofs += mtd->oobsize;
+		chip->ops.len = chip->ops.ooblen = 2;
+		chip->ops.datbuf = NULL;
+		chip->ops.oobbuf = buf;
+		chip->ops.ooboffs = chip->badblockpos & ~0x01;
+
+		ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+		nand_release_device(mtd);
+	}
+	if (!ret)
+		mtd->ecc_stats.badblocks++;
+
+	return ret;
+}
+
+/**
+ * nand_check_wp - [GENERIC] check if the chip is write protected
+ * @mtd:	MTD device structure
+ * Check, if the device is write protected
+ *
+ * The function expects, that the device is already selected
+ */
+static int nand_check_wp(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	/* Check the WP bit */
+	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+	return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
+}
+
+/**
+ * nand_block_checkbad - [GENERIC] Check if a block is marked bad
+ * @mtd:	MTD device structure
+ * @ofs:	offset from device start
+ * @getchip:	0, if the chip is already selected
+ * @allowbbt:	1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad. Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
+			       int allowbbt)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if (!(chip->options & NAND_BBT_SCANNED)) {
+		chip->options |= NAND_BBT_SCANNED;
+		chip->scan_bbt(mtd);
+	}
+
+	if (!chip->bbt)
+		return chip->block_bad(mtd, ofs, getchip);
+
+	/* Return info from the table */
+	return nand_isbad_bbt(mtd, ofs, allowbbt);
+}
+
+/*
+ * Wait for the ready pin, after a command
+ * The timeout is catched later.
+ */
+void nand_wait_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
+	u32 time_start;
+
+	time_start = get_timer(0);
+
+	/* wait until command is processed or timeout occures */
+	while (get_timer(time_start) < timeo) {
+		if (chip->dev_ready)
+			if (chip->dev_ready(mtd))
+				break;
+	}
+}
+
+/**
+ * nand_command - [DEFAULT] Send command to NAND device
+ * @mtd:	MTD device structure
+ * @command:	the command to be sent
+ * @column:	the column address for this command, -1 if none
+ * @page_addr:	the page address for this command, -1 if none
+ *
+ * Send command to NAND device. This function is used for small page
+ * devices (256/512 Bytes per page)
+ */
+static void nand_command(struct mtd_info *mtd, unsigned int command,
+			 int column, int page_addr)
+{
+	register struct nand_chip *chip = mtd->priv;
+	int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
+	uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
+
+	/*
+	 * Write out the command to the device.
+	 */
+	if (command == NAND_CMD_SEQIN) {
+		int readcmd;
+
+		if (column >= mtd->writesize) {
+			/* OOB area */
+			column -= mtd->writesize;
+			readcmd = NAND_CMD_READOOB;
+		} else if (column < 256) {
+			/* First 256 bytes --> READ0 */
+			readcmd = NAND_CMD_READ0;
+		} else {
+			column -= 256;
+			readcmd = NAND_CMD_READ1;
+		}
+		chip->cmd_ctrl(mtd, readcmd, ctrl);
+		ctrl &= ~NAND_CTRL_CHANGE;
+	}
+	chip->cmd_ctrl(mtd, command, ctrl);
+
+	/*
+	 * Address cycle, when necessary
+	 */
+	ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
+	/* Serially input address */
+	if (column != -1) {
+		/* Adjust columns for 16 bit buswidth */
+		if (chip->options & NAND_BUSWIDTH_16)
+			column >>= 1;
+		chip->cmd_ctrl(mtd, column, ctrl);
+		ctrl &= ~NAND_CTRL_CHANGE;
+	}
+	if (page_addr != -1) {
+		chip->cmd_ctrl(mtd, page_addr, ctrl);
+		ctrl &= ~NAND_CTRL_CHANGE;
+		chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
+		/* One more address cycle for devices > 32MiB */
+		if (chip->chipsize > (32 << 20))
+			chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
+	}
+	chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	/*
+	 * program and erase have their own busy handlers
+	 * status and sequential in needs no delay
+	 */
+	switch (command) {
+
+	case NAND_CMD_PAGEPROG:
+	case NAND_CMD_ERASE1:
+	case NAND_CMD_ERASE2:
+	case NAND_CMD_SEQIN:
+	case NAND_CMD_STATUS:
+		return;
+
+	case NAND_CMD_RESET:
+		if (chip->dev_ready)
+			break;
+		udelay(chip->chip_delay);
+		chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
+			       NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+		chip->cmd_ctrl(mtd,
+			       NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+		while (!(chip->read_byte(mtd) & NAND_STATUS_READY) &&
+			(rst_sts_cnt--));
+		return;
+
+		/* This applies to read commands */
+	default:
+		/*
+		 * If we don't have access to the busy pin, we apply the given
+		 * command delay
+		 */
+		if (!chip->dev_ready) {
+			udelay(chip->chip_delay);
+			return;
+		}
+	}
+	/* Apply this short delay always to ensure that we do wait tWB in
+	 * any case on any machine. */
+	ndelay(100);
+
+	nand_wait_ready(mtd);
+}
+
+/**
+ * nand_command_lp - [DEFAULT] Send command to NAND large page device
+ * @mtd:	MTD device structure
+ * @command:	the command to be sent
+ * @column:	the column address for this command, -1 if none
+ * @page_addr:	the page address for this command, -1 if none
+ *
+ * Send command to NAND device. This is the version for the new large page
+ * devices We dont have the separate regions as we have in the small page
+ * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
+ */
+static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
+			    int column, int page_addr)
+{
+	register struct nand_chip *chip = mtd->priv;
+	uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
+
+	/* Emulate NAND_CMD_READOOB */
+	if (command == NAND_CMD_READOOB) {
+		column += mtd->writesize;
+		command = NAND_CMD_READ0;
+	}
+
+	/* Command latch cycle */
+	chip->cmd_ctrl(mtd, command & 0xff,
+		       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+
+	if (column != -1 || page_addr != -1) {
+		int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
+
+		/* Serially input address */
+		if (column != -1) {
+			/* Adjust columns for 16 bit buswidth */
+			if (chip->options & NAND_BUSWIDTH_16)
+				column >>= 1;
+			chip->cmd_ctrl(mtd, column, ctrl);
+			ctrl &= ~NAND_CTRL_CHANGE;
+			chip->cmd_ctrl(mtd, column >> 8, ctrl);
+		}
+		if (page_addr != -1) {
+			chip->cmd_ctrl(mtd, page_addr, ctrl);
+			chip->cmd_ctrl(mtd, page_addr >> 8,
+				       NAND_NCE | NAND_ALE);
+			/* One more address cycle for devices > 128MiB */
+			if (chip->chipsize > (128 << 20))
+				chip->cmd_ctrl(mtd, page_addr >> 16,
+					       NAND_NCE | NAND_ALE);
+		}
+	}
+	chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	/*
+	 * program and erase have their own busy handlers
+	 * status, sequential in, and deplete1 need no delay
+	 */
+	switch (command) {
+
+	case NAND_CMD_CACHEDPROG:
+	case NAND_CMD_PAGEPROG:
+	case NAND_CMD_ERASE1:
+	case NAND_CMD_ERASE2:
+	case NAND_CMD_SEQIN:
+	case NAND_CMD_RNDIN:
+	case NAND_CMD_STATUS:
+	case NAND_CMD_DEPLETE1:
+		return;
+
+		/*
+		 * read error status commands require only a short delay
+		 */
+	case NAND_CMD_STATUS_ERROR:
+	case NAND_CMD_STATUS_ERROR0:
+	case NAND_CMD_STATUS_ERROR1:
+	case NAND_CMD_STATUS_ERROR2:
+	case NAND_CMD_STATUS_ERROR3:
+		udelay(chip->chip_delay);
+		return;
+
+	case NAND_CMD_RESET:
+		if (chip->dev_ready)
+			break;
+		udelay(chip->chip_delay);
+		chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
+			       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE,
+			       NAND_NCE | NAND_CTRL_CHANGE);
+		while (!(chip->read_byte(mtd) & NAND_STATUS_READY) &&
+			(rst_sts_cnt--));
+		return;
+
+	case NAND_CMD_RNDOUT:
+		/* No ready / busy check necessary */
+		chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
+			       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE,
+			       NAND_NCE | NAND_CTRL_CHANGE);
+		return;
+
+	case NAND_CMD_READ0:
+		chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
+			       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE,
+			       NAND_NCE | NAND_CTRL_CHANGE);
+
+		/* This applies to read commands */
+	default:
+		/*
+		 * If we don't have access to the busy pin, we apply the given
+		 * command delay
+		 */
+		if (!chip->dev_ready) {
+			udelay(chip->chip_delay);
+			return;
+		}
+	}
+
+	/* Apply this short delay always to ensure that we do wait tWB in
+	 * any case on any machine. */
+	ndelay(100);
+
+	nand_wait_ready(mtd);
+}
+
+/**
+ * nand_get_device - [GENERIC] Get chip for selected access
+ * @chip:	the nand chip descriptor
+ * @mtd:	MTD device structure
+ * @new_state:	the state which is requested
+ *
+ * Get the device and lock it for exclusive access
+ */
+static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
+{
+	this->state = new_state;
+	return 0;
+}
+
+/**
+ * nand_wait - [DEFAULT]  wait until the command is done
+ * @mtd:	MTD device structure
+ * @chip:	NAND chip structure
+ *
+ * Wait for command done. This applies to erase and program only
+ * Erase can take up to 400ms and program up to 20ms according to
+ * general NAND and SmartMedia specs
+ */
+static int nand_wait(struct mtd_info *mtd, struct nand_chip *this)
+{
+	unsigned long	timeo;
+	int state = this->state;
+	u32 time_start;
+
+	if (state == FL_ERASING)
+		timeo = (CONFIG_SYS_HZ * 400) / 1000;
+	else
+		timeo = (CONFIG_SYS_HZ * 20) / 1000;
+
+	if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
+		this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
+	else
+		this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+
+	time_start = get_timer(0);
+
+	while (1) {
+		if (get_timer(time_start) > timeo) {
+			printf("Timeout!");
+			return 0x01;
+		}
+
+		if (this->dev_ready) {
+			if (this->dev_ready(mtd))
+				break;
+		} else {
+			if (this->read_byte(mtd) & NAND_STATUS_READY)
+				break;
+		}
+	}
+#ifdef PPCHAMELON_NAND_TIMER_HACK
+	time_start = get_timer(0);
+	while (get_timer(time_start) < 10)
+		;
+#endif /*  PPCHAMELON_NAND_TIMER_HACK */
+
+	return this->read_byte(mtd);
+}
+
+/**
+ * nand_read_page_raw - [Intern] read raw page data without ecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
+ */
+static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int page)
+{
+	chip->read_buf(mtd, buf, mtd->writesize);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
+}
+
+/**
+ * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * We need a special oob layout and handling even when OOB isn't used.
+ */
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int page)
+{
+	int eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	uint8_t *oob = chip->oob_poi;
+	int steps, size;
+
+	for (steps = chip->ecc.steps; steps > 0; steps--) {
+		chip->read_buf(mtd, buf, eccsize);
+		buf += eccsize;
+
+		if (chip->ecc.prepad) {
+			chip->read_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->read_buf(mtd, oob, eccbytes);
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->read_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	size = mtd->oobsize - (oob - chip->oob_poi);
+	if (size)
+		chip->read_buf(mtd, oob, size);
+
+	return 0;
+}
+
+/**
+ * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ */
+static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	chip->ecc.read_page_raw(mtd, chip, buf, page);
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+
+/**
+ * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @data_offs:	offset of requested data within the page
+ * @readlen:	data length
+ * @bufpoi:	buffer to store read data
+ */
+static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
+{
+	int start_step, end_step, num_steps;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *p;
+	int data_col_addr, i, gaps = 0;
+	int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
+	int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
+
+	/* Column address wihin the page aligned to ECC size (256bytes). */
+	start_step = data_offs / chip->ecc.size;
+	end_step = (data_offs + readlen - 1) / chip->ecc.size;
+	num_steps = end_step - start_step + 1;
+
+	/* Data size aligned to ECC ecc.size*/
+	datafrag_len = num_steps * chip->ecc.size;
+	eccfrag_len = num_steps * chip->ecc.bytes;
+
+	data_col_addr = start_step * chip->ecc.size;
+	/* If we read not a page aligned data */
+	if (data_col_addr != 0)
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
+
+	p = bufpoi + data_col_addr;
+	chip->read_buf(mtd, p, datafrag_len);
+
+	/* Calculate  ECC */
+	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
+		chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
+
+	/* The performance is faster if to position offsets
+	   according to ecc.pos. Let make sure here that
+	   there are no gaps in ecc positions */
+	for (i = 0; i < eccfrag_len - 1; i++) {
+		if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
+			eccpos[i + start_step * chip->ecc.bytes + 1]) {
+			gaps = 1;
+			break;
+		}
+	}
+	if (gaps) {
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	} else {
+		/* send the command to read the particular ecc bytes */
+		/* take care about buswidth alignment in read_buf */
+		aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1);
+		aligned_len = eccfrag_len;
+		if (eccpos[start_step * chip->ecc.bytes] & (busw - 1))
+			aligned_len++;
+		if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1))
+			aligned_len++;
+
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1);
+		chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
+	}
+
+	for (i = 0; i < eccfrag_len; i++)
+		chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]];
+
+	p = bufpoi + data_col_addr;
+	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
+		if (stat == -1)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+
+/**
+ * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * Not for syndrome calculating ecc controllers which need a special oob layout
+ */
+static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+    /*for debug only */
+    trace_i =0;
+    time_stamp[trace_i] = get_ticks_u();
+    trace_i++;
+    /*end debug code */
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+        /*for debug only */        
+        time_stamp[trace_i] = get_ticks_u();
+        trace_i++;
+        /*end debug code */
+
+		chip->read_buf(mtd, p, eccsize);
+        /*for debug only */        
+        time_stamp[trace_i] = get_ticks_u();
+        trace_i++;
+        /*end debug code */
+
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+        /*for debug only */        
+        time_stamp[trace_i] = get_ticks_u();
+        trace_i++;
+        /*end debug code */
+    
+	}
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+    /*for debug only */
+    
+    time_stamp[trace_i] = get_ticks_u();
+    trace_i++;
+    /*end debug code */
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+    /*for debug only */
+    
+    time_stamp[trace_i] = get_ticks_u();
+    trace_i++;
+    /*end debug code */
+
+	}
+
+    /* debug*/
+    printf("trace result:\n");
+    for (item=1; item<trace_i; item++) {
+        printf("Time[item]=%lld\n", time_stamp[item]-time_stamp[item-1] );
+        
+    }
+
+	return 0;
+}
+
+/**
+ * nand_read_page_hwecc_oob_first - [REPLACABLE] hw ecc, read oob first
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * Hardware ECC for large page chips, require OOB to be read first.
+ * For this ECC mode, the write_page method is re-used from ECC_HW.
+ * These methods read/write ECC from the OOB area, unlike the
+ * ECC_HW_SYNDROME support with multiple ECC steps, follows the
+ * "infix ECC" scheme and reads/writes ECC from the data area, by
+ * overwriting the NAND manufacturer bad block markings.
+ */
+static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
+	struct nand_chip *chip, uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+
+
+	/* Read the OOB area first */
+	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+
+	return 0;
+}
+
+/**
+ * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * The hw generator calculates the error syndrome automatically. Therefor
+ * we need a special oob layout and handling.
+ */
+static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+				   uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *oob = chip->oob_poi;
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+
+		if (chip->ecc.prepad) {
+			chip->read_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
+		chip->read_buf(mtd, oob, eccbytes);
+		stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->read_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	/* Calculate remaining oob bytes */
+	i = mtd->oobsize - (oob - chip->oob_poi);
+	if (i)
+		chip->read_buf(mtd, oob, i);
+
+	return 0;
+}
+
+/**
+ * nand_transfer_oob - [Internal] Transfer oob to client buffer
+ * @chip:	nand chip structure
+ * @oob:	oob destination address
+ * @ops:	oob ops structure
+ * @len:	size of oob to transfer
+ */
+static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+				  struct mtd_oob_ops *ops, size_t len)
+{
+	switch(ops->mode) {
+
+	case MTD_OOB_PLACE:
+	case MTD_OOB_RAW:
+		memcpy(oob, chip->oob_poi + ops->ooboffs, len);
+		return oob + len;
+
+	case MTD_OOB_AUTO: {
+		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		uint32_t boffs = 0, roffs = ops->ooboffs;
+		size_t bytes = 0;
+
+		for(; free->length && len; free++, len -= bytes) {
+			/* Read request not from offset 0 ? */
+			if (unlikely(roffs)) {
+				if (roffs >= free->length) {
+					roffs -= free->length;
+					continue;
+				}
+				boffs = free->offset + roffs;
+				bytes = min_t(size_t, len,
+					      (free->length - roffs));
+				roffs = 0;
+			} else {
+				bytes = min_t(size_t, len, free->length);
+				boffs = free->offset;
+			}
+			memcpy(oob, chip->oob_poi + boffs, bytes);
+			oob += bytes;
+		}
+		return oob;
+	}
+	default:
+		BUG();
+	}
+	return NULL;
+}
+
+/**
+ * nand_do_read_ops - [Internal] Read data with ECC
+ *
+ * @mtd:	MTD device structure
+ * @from:	offset to read from
+ * @ops:	oob ops structure
+ *
+ * Internal function. Called with chip held.
+ */
+static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
+			    struct mtd_oob_ops *ops)
+{
+	int chipnr, page, realpage, col, bytes, aligned;
+	struct nand_chip *chip = mtd->priv;
+	struct mtd_ecc_stats stats;
+	int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
+	int sndcmd = 1;
+	int ret = 0;
+	uint32_t readlen = ops->len;
+	uint32_t oobreadlen = ops->ooblen;
+	uint8_t *bufpoi, *oob, *buf;
+
+	stats = mtd->ecc_stats;
+
+	chipnr = (int)(from >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+	realpage = (int)(from >> chip->page_shift);
+	page = realpage & chip->pagemask;
+
+	col = (int)(from & (mtd->writesize - 1));
+
+	buf = ops->datbuf;
+	oob = ops->oobbuf;
+
+	while(1) {
+		WATCHDOG_RESET();
+ 
+		bytes = min(mtd->writesize - col, readlen);
+		aligned = (bytes == mtd->writesize);
+
+		/* Is the current page in the buffer ? */
+		if (realpage != chip->pagebuf || oob) {
+			bufpoi = aligned ? buf : chip->buffers->databuf;
+
+			if (likely(sndcmd)) {
+				chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+				sndcmd = 0;
+			}
+
+
+			/* Now read the page into the buffer */
+			if (unlikely(ops->mode == MTD_OOB_RAW))
+				ret = chip->ecc.read_page_raw(mtd, chip,
+						bufpoi, page);
+			else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
+				ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi);
+			else
+				ret = chip->ecc.read_page(mtd, chip, bufpoi,
+						page);
+			if (ret < 0)
+				break;
+
+
+			/* Transfer not aligned data */
+			if (!aligned) {
+				if (!NAND_SUBPAGE_READ(chip) && !oob)
+					chip->pagebuf = realpage;
+				memcpy(buf, chip->buffers->databuf + col, bytes);
+			}
+
+			buf += bytes;
+            
+			if (unlikely(oob)) {
+				/* Raw mode does data:oob:data:oob */
+				if (ops->mode != MTD_OOB_RAW) {
+					int toread = min(oobreadlen,
+						chip->ecc.layout->oobavail);
+					if (toread) {
+						oob = nand_transfer_oob(chip,
+							oob, ops, toread);
+						oobreadlen -= toread;
+					}
+				} else
+					buf = nand_transfer_oob(chip,
+						buf, ops, mtd->oobsize);
+			}
+
+			if (!(chip->options & NAND_NO_READRDY)) {
+				/*
+				 * Apply delay or wait for ready/busy pin. Do
+				 * this before the AUTOINCR check, so no
+				 * problems arise if a chip which does auto
+				 * increment is marked as NOAUTOINCR by the
+				 * board driver.
+				 */
+				if (!chip->dev_ready)
+					udelay(chip->chip_delay);
+				else
+					nand_wait_ready(mtd);
+			}
+		} else {
+			memcpy(buf, chip->buffers->databuf + col, bytes);
+			buf += bytes;
+            
+		}
+
+		readlen -= bytes;
+
+		if (!readlen)
+			break;
+
+		/* For subsequent reads align to page boundary. */
+		col = 0;
+		/* Increment page address */
+		realpage++;
+
+		page = realpage & chip->pagemask;
+		/* Check, if we cross a chip boundary */
+		if (!page) {
+			chipnr++;
+			chip->select_chip(mtd, -1);
+			chip->select_chip(mtd, chipnr);
+		}
+
+		/* Check, if the chip supports auto page increment
+		 * or if we have hit a block boundary.
+		 */
+		if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
+			sndcmd = 1;
+        
+	}
+
+
+	ops->retlen = ops->len - (size_t) readlen;
+	if (oob)
+		ops->oobretlen = ops->ooblen - oobreadlen;
+
+	if (ret)
+		return ret;
+
+	if (mtd->ecc_stats.failed - stats.failed)
+		return -EBADMSG;
+
+	return	mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+}
+
+/**
+ * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
+ * @mtd:	MTD device structure
+ * @from:	offset to read from
+ * @len:	number of bytes to read
+ * @retlen:	pointer to variable to store the number of read bytes
+ * @buf:	the databuffer to put data
+ *
+ * Get hold of the chip and call nand_do_read
+ */
+
+static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
+		     size_t *retlen, uint8_t *buf)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret;
+
+	/* Do not allow reads past end of device */
+	if ((from + len) > mtd->size)
+		return -EINVAL;
+	if (!len)
+		return 0;
+
+	nand_get_device(chip, mtd, FL_READING);
+
+	chip->ops.len = len;
+	chip->ops.datbuf = buf;
+	chip->ops.oobbuf = NULL;
+
+	ret = nand_do_read_ops(mtd, from, &chip->ops);
+
+	*retlen = chip->ops.retlen;
+
+	nand_release_device(mtd);
+
+	return ret;
+}
+
+/**
+ * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @page:	page number to read
+ * @sndcmd:	flag whether to issue read command or not
+ */
+static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+			     int page, int sndcmd)
+{
+	if (sndcmd) {
+		chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+		sndcmd = 0;
+	}
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return sndcmd;
+}
+
+/**
+ * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
+ *			    with syndromes
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @page:	page number to read
+ * @sndcmd:	flag whether to issue read command or not
+ */
+static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+				  int page, int sndcmd)
+{
+	uint8_t *buf = chip->oob_poi;
+	int length = mtd->oobsize;
+	int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
+	int eccsize = chip->ecc.size;
+	uint8_t *bufpoi = buf;
+	int i, toread, sndrnd = 0, pos;
+
+	chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
+	for (i = 0; i < chip->ecc.steps; i++) {
+		if (sndrnd) {
+			pos = eccsize + i * (eccsize + chunk);
+			if (mtd->writesize > 512)
+				chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
+			else
+				chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
+		} else
+			sndrnd = 1;
+		toread = min_t(int, length, chunk);
+		chip->read_buf(mtd, bufpoi, toread);
+		bufpoi += toread;
+		length -= toread;
+	}
+	if (length > 0)
+		chip->read_buf(mtd, bufpoi, length);
+
+	return 1;
+}
+
+/**
+ * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @page:	page number to write
+ */
+static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	int status = 0;
+	const uint8_t *buf = chip->oob_poi;
+	int length = mtd->oobsize;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+	chip->write_buf(mtd, buf, length);
+	/* Send command to program the OOB data */
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+	status = chip->waitfunc(mtd, chip);
+
+	return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/**
+ * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
+ *			     with syndrome - only for large page flash !
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @page:	page number to write
+ */
+static int nand_write_oob_syndrome(struct mtd_info *mtd,
+				   struct nand_chip *chip, int page)
+{
+	int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
+	int eccsize = chip->ecc.size, length = mtd->oobsize;
+	int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
+	const uint8_t *bufpoi = chip->oob_poi;
+
+	/*
+	 * data-ecc-data-ecc ... ecc-oob
+	 * or
+	 * data-pad-ecc-pad-data-pad .... ecc-pad-oob
+	 */
+	if (!chip->ecc.prepad && !chip->ecc.postpad) {
+		pos = steps * (eccsize + chunk);
+		steps = 0;
+	} else
+		pos = eccsize;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
+	for (i = 0; i < steps; i++) {
+		if (sndcmd) {
+			if (mtd->writesize <= 512) {
+				uint32_t fill = 0xFFFFFFFF;
+
+				len = eccsize;
+				while (len > 0) {
+					int num = min_t(int, len, 4);
+					chip->write_buf(mtd, (uint8_t *)&fill,
+							num);
+					len -= num;
+				}
+			} else {
+				pos = eccsize + i * (eccsize + chunk);
+				chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1);
+			}
+		} else
+			sndcmd = 1;
+		len = min_t(int, length, chunk);
+		chip->write_buf(mtd, bufpoi, len);
+		bufpoi += len;
+		length -= len;
+	}
+	if (length > 0)
+		chip->write_buf(mtd, bufpoi, length);
+
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+	status = chip->waitfunc(mtd, chip);
+
+	return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/**
+ * nand_do_read_oob - [Intern] NAND read out-of-band
+ * @mtd:	MTD device structure
+ * @from:	offset to read from
+ * @ops:	oob operations description structure
+ *
+ * NAND read out-of-band data from the spare area
+ */
+static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+			    struct mtd_oob_ops *ops)
+{
+	int page, realpage, chipnr, sndcmd = 1;
+	struct nand_chip *chip = mtd->priv;
+	int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
+	int readlen = ops->ooblen;
+	int len;
+	uint8_t *buf = ops->oobbuf;
+
+	MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
+		  (unsigned long long)from, readlen);
+
+	if (ops->mode == MTD_OOB_AUTO)
+		len = chip->ecc.layout->oobavail;
+	else
+		len = mtd->oobsize;
+
+	if (unlikely(ops->ooboffs >= len)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt to start read outside oob\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow reads past end of device */
+	if (unlikely(from >= mtd->size ||
+		     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
+					(from >> chip->page_shift)) * len)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt read beyond end of device\n");
+		return -EINVAL;
+	}
+
+	chipnr = (int)(from >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+	/* Shift to get page */
+	realpage = (int)(from >> chip->page_shift);
+	page = realpage & chip->pagemask;
+
+	while(1) {
+		WATCHDOG_RESET();
+		sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
+
+		len = min(len, readlen);
+		buf = nand_transfer_oob(chip, buf, ops, len);
+
+		if (!(chip->options & NAND_NO_READRDY)) {
+			/*
+			 * Apply delay or wait for ready/busy pin. Do this
+			 * before the AUTOINCR check, so no problems arise if a
+			 * chip which does auto increment is marked as
+			 * NOAUTOINCR by the board driver.
+			 */
+			if (!chip->dev_ready)
+				udelay(chip->chip_delay);
+			else
+				nand_wait_ready(mtd);
+		}
+
+		readlen -= len;
+		if (!readlen)
+			break;
+
+		/* Increment page address */
+		realpage++;
+
+		page = realpage & chip->pagemask;
+		/* Check, if we cross a chip boundary */
+		if (!page) {
+			chipnr++;
+			chip->select_chip(mtd, -1);
+			chip->select_chip(mtd, chipnr);
+		}
+
+		/* Check, if the chip supports auto page increment
+		 * or if we have hit a block boundary.
+		 */
+		if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
+			sndcmd = 1;
+	}
+
+	ops->oobretlen = ops->ooblen;
+	return 0;
+}
+
+/**
+ * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
+ * @mtd:	MTD device structure
+ * @from:	offset to read from
+ * @ops:	oob operation description structure
+ *
+ * NAND read data and/or out-of-band data
+ */
+static int nand_read_oob(struct mtd_info *mtd, loff_t from,
+			 struct mtd_oob_ops *ops)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret = -ENOTSUPP;
+
+	ops->retlen = 0;
+
+	/* Do not allow reads past end of device */
+	if (ops->datbuf && (from + ops->len) > mtd->size) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt read beyond end of device\n");
+		return -EINVAL;
+	}
+
+	nand_get_device(chip, mtd, FL_READING);
+
+	switch(ops->mode) {
+	case MTD_OOB_PLACE:
+	case MTD_OOB_AUTO:
+	case MTD_OOB_RAW:
+		break;
+
+	default:
+		goto out;
+	}
+
+	if (!ops->datbuf)
+		ret = nand_do_read_oob(mtd, from, ops);
+	else
+		ret = nand_do_read_ops(mtd, from, ops);
+
+ out:
+	nand_release_device(mtd);
+	return ret;
+}
+
+
+/**
+ * nand_write_page_raw - [Intern] raw page write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
+ */
+static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf)
+{
+	chip->write_buf(mtd, buf, mtd->writesize);
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+}
+
+/**
+ * nand_write_page_raw_syndrome - [Intern] raw page write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ *
+ * We need a special oob layout and handling even when ECC isn't checked.
+ */
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf)
+{
+	int eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	uint8_t *oob = chip->oob_poi;
+	int steps, size;
+
+	for (steps = chip->ecc.steps; steps > 0; steps--) {
+		chip->write_buf(mtd, buf, eccsize);
+		buf += eccsize;
+
+		if (chip->ecc.prepad) {
+			chip->write_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->read_buf(mtd, oob, eccbytes);
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->write_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	size = mtd->oobsize - (oob - chip->oob_poi);
+	if (size)
+		chip->write_buf(mtd, oob, size);
+}
+/**
+ * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ */
+static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+				  const uint8_t *buf)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	const uint8_t *p = buf;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	/* Software ecc calculation */
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	chip->ecc.write_page_raw(mtd, chip, buf);
+}
+
+/**
+ * nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ */
+static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				  const uint8_t *buf)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	const uint8_t *p = buf;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+		chip->write_buf(mtd, p, eccsize);
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+	}
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+}
+
+/**
+ * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ *
+ * The hw generator calculates the error syndrome automatically. Therefor
+ * we need a special oob layout and handling.
+ */
+static void nand_write_page_syndrome(struct mtd_info *mtd,
+				    struct nand_chip *chip, const uint8_t *buf)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	const uint8_t *p = buf;
+	uint8_t *oob = chip->oob_poi;
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+
+		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+		chip->write_buf(mtd, p, eccsize);
+
+		if (chip->ecc.prepad) {
+			chip->write_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->ecc.calculate(mtd, p, oob);
+		chip->write_buf(mtd, oob, eccbytes);
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->write_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	/* Calculate remaining oob bytes */
+	i = mtd->oobsize - (oob - chip->oob_poi);
+	if (i)
+		chip->write_buf(mtd, oob, i);
+}
+
+/**
+ * nand_write_page - [REPLACEABLE] write one page
+ * @mtd:	MTD device structure
+ * @chip:	NAND chip descriptor
+ * @buf:	the data to write
+ * @page:	page number to write
+ * @cached:	cached programming
+ * @raw:	use _raw version of write_page
+ */
+static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+			   const uint8_t *buf, int page, int cached, int raw)
+{
+	int status;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
+
+	if (unlikely(raw))
+		chip->ecc.write_page_raw(mtd, chip, buf);
+	else
+		chip->ecc.write_page(mtd, chip, buf);
+
+	/*
+	 * Cached progamming disabled for now, Not sure if its worth the
+	 * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
+	 */
+	cached = 0;
+
+	if (!cached || !(chip->options & NAND_CACHEPRG)) {
+
+		chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+		status = chip->waitfunc(mtd, chip);
+		/*
+		 * See if operation failed and additional status checks are
+		 * available
+		 */
+		if ((status & NAND_STATUS_FAIL) && (chip->errstat))
+			status = chip->errstat(mtd, chip, FL_WRITING, status,
+					       page);
+
+		if (status & NAND_STATUS_FAIL)
+			return -EIO;
+	} else {
+		chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1);
+		status = chip->waitfunc(mtd, chip);
+	}
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+	/* Send command to read back the data */
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	if (chip->verify_buf(mtd, buf, mtd->writesize))
+		return -EIO;
+#endif
+	return 0;
+}
+
+/**
+ * nand_fill_oob - [Internal] Transfer client buffer to oob
+ * @chip:	nand chip structure
+ * @oob:	oob data buffer
+ * @ops:	oob ops structure
+ */
+static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
+				  struct mtd_oob_ops *ops)
+{
+	size_t len = ops->ooblen;
+
+	switch(ops->mode) {
+
+	case MTD_OOB_PLACE:
+	case MTD_OOB_RAW:
+		memcpy(chip->oob_poi + ops->ooboffs, oob, len);
+		return oob + len;
+
+	case MTD_OOB_AUTO: {
+		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		uint32_t boffs = 0, woffs = ops->ooboffs;
+		size_t bytes = 0;
+
+		for(; free->length && len; free++, len -= bytes) {
+			/* Write request not from offset 0 ? */
+			if (unlikely(woffs)) {
+				if (woffs >= free->length) {
+					woffs -= free->length;
+					continue;
+				}
+				boffs = free->offset + woffs;
+				bytes = min_t(size_t, len,
+					      (free->length - woffs));
+				woffs = 0;
+			} else {
+				bytes = min_t(size_t, len, free->length);
+				boffs = free->offset;
+			}
+			memcpy(chip->oob_poi + boffs, oob, bytes);
+			oob += bytes;
+		}
+		return oob;
+	}
+	default:
+		BUG();
+	}
+	return NULL;
+}
+
+#define NOTALIGNED(x)	(x & (chip->subpagesize - 1)) != 0
+
+/**
+ * nand_do_write_ops - [Internal] NAND write with ECC
+ * @mtd:	MTD device structure
+ * @to:		offset to write to
+ * @ops:	oob operations description structure
+ *
+ * NAND write with ECC
+ */
+static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
+			     struct mtd_oob_ops *ops)
+{
+	int chipnr, realpage, page, blockmask, column;
+	struct nand_chip *chip = mtd->priv;
+	uint32_t writelen = ops->len;
+	uint8_t *oob = ops->oobbuf;
+	uint8_t *buf = ops->datbuf;
+	int ret, subpage;
+
+	ops->retlen = 0;
+	if (!writelen)
+		return 0;
+
+	column = to & (mtd->writesize - 1);
+	subpage = column || (writelen & (mtd->writesize - 1));
+
+	if (subpage && oob)
+		return -EINVAL;
+
+	chipnr = (int)(to >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+	/* Check, if it is write protected */
+	if (nand_check_wp(mtd)) {
+		printk (KERN_NOTICE "nand_do_write_ops: Device is write protected\n");
+		return -EIO;
+	}
+
+	realpage = (int)(to >> chip->page_shift);
+	page = realpage & chip->pagemask;
+	blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
+
+	/* Invalidate the page cache, when we write to the cached page */
+	if (to <= (chip->pagebuf << chip->page_shift) &&
+	    (chip->pagebuf << chip->page_shift) < (to + ops->len))
+		chip->pagebuf = -1;
+
+	/* If we're not given explicit OOB data, let it be 0xFF */
+	if (likely(!oob))
+		memset(chip->oob_poi, 0xff, mtd->oobsize);
+
+	while(1) {
+		WATCHDOG_RESET();
+
+		int bytes = mtd->writesize;
+		int cached = writelen > bytes && page != blockmask;
+		uint8_t *wbuf = buf;
+
+		/* Partial page write ? */
+		if (unlikely(column || writelen < (mtd->writesize - 1))) {
+			cached = 0;
+			bytes = min_t(int, bytes - column, (int) writelen);
+			chip->pagebuf = -1;
+			memset(chip->buffers->databuf, 0xff, mtd->writesize);
+			memcpy(&chip->buffers->databuf[column], buf, bytes);
+			wbuf = chip->buffers->databuf;
+		}
+
+		if (unlikely(oob))
+			oob = nand_fill_oob(chip, oob, ops);
+
+		ret = chip->write_page(mtd, chip, wbuf, page, cached,
+				       (ops->mode == MTD_OOB_RAW));
+		if (ret)
+			break;
+
+		writelen -= bytes;
+		if (!writelen)
+			break;
+
+		column = 0;
+		buf += bytes;
+		realpage++;
+
+		page = realpage & chip->pagemask;
+		/* Check, if we cross a chip boundary */
+		if (!page) {
+			chipnr++;
+			chip->select_chip(mtd, -1);
+			chip->select_chip(mtd, chipnr);
+		}
+	}
+
+	ops->retlen = ops->len - writelen;
+	if (unlikely(oob))
+		ops->oobretlen = ops->ooblen;
+	return ret;
+}
+
+/**
+ * nand_write - [MTD Interface] NAND write with ECC
+ * @mtd:	MTD device structure
+ * @to:		offset to write to
+ * @len:	number of bytes to write
+ * @retlen:	pointer to variable to store the number of written bytes
+ * @buf:	the data to write
+ *
+ * NAND write with ECC
+ */
+static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
+			  size_t *retlen, const uint8_t *buf)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret;
+
+	/* Do not allow reads past end of device */
+	if ((to + len) > mtd->size)
+		return -EINVAL;
+	if (!len)
+		return 0;
+
+	nand_get_device(chip, mtd, FL_WRITING);
+
+	chip->ops.len = len;
+	chip->ops.datbuf = (uint8_t *)buf;
+	chip->ops.oobbuf = NULL;
+
+	ret = nand_do_write_ops(mtd, to, &chip->ops);
+
+	*retlen = chip->ops.retlen;
+
+	nand_release_device(mtd);
+
+	return ret;
+}
+
+/**
+ * nand_do_write_oob - [MTD Interface] NAND write out-of-band
+ * @mtd:	MTD device structure
+ * @to:		offset to write to
+ * @ops:	oob operation description structure
+ *
+ * NAND write out-of-band
+ */
+static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+			     struct mtd_oob_ops *ops)
+{
+	int chipnr, page, status, len;
+	struct nand_chip *chip = mtd->priv;
+
+	MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
+		  (unsigned int)to, (int)ops->ooblen);
+
+	if (ops->mode == MTD_OOB_AUTO)
+		len = chip->ecc.layout->oobavail;
+	else
+		len = mtd->oobsize;
+
+	/* Do not allow write past end of page */
+	if ((ops->ooboffs + ops->ooblen) > len) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: "
+			  "Attempt to write past end of page\n");
+		return -EINVAL;
+	}
+
+	if (unlikely(ops->ooboffs >= len)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt to start write outside oob\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow reads past end of device */
+	if (unlikely(to >= mtd->size ||
+		     ops->ooboffs + ops->ooblen >
+			((mtd->size >> chip->page_shift) -
+			 (to >> chip->page_shift)) * len)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt write beyond end of device\n");
+		return -EINVAL;
+	}
+
+	chipnr = (int)(to >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+	/* Shift to get page */
+	page = (int)(to >> chip->page_shift);
+
+	/*
+	 * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
+	 * of my DiskOnChip 2000 test units) will clear the whole data page too
+	 * if we don't do this. I have no clue why, but I seem to have 'fixed'
+	 * it in the doc2000 driver in August 1999.  dwmw2.
+	 */
+	chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+	/* Check, if it is write protected */
+	if (nand_check_wp(mtd))
+		return -EROFS;
+
+	/* Invalidate the page cache, if we write to the cached page */
+	if (page == chip->pagebuf)
+		chip->pagebuf = -1;
+
+	memset(chip->oob_poi, 0xff, mtd->oobsize);
+	nand_fill_oob(chip, ops->oobbuf, ops);
+	status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
+	memset(chip->oob_poi, 0xff, mtd->oobsize);
+
+	if (status)
+		return status;
+
+	ops->oobretlen = ops->ooblen;
+
+	return 0;
+}
+
+/**
+ * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
+ * @mtd:	MTD device structure
+ * @to:		offset to write to
+ * @ops:	oob operation description structure
+ */
+static int nand_write_oob(struct mtd_info *mtd, loff_t to,
+			  struct mtd_oob_ops *ops)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret = -ENOTSUPP;
+
+	ops->retlen = 0;
+
+	/* Do not allow writes past end of device */
+	if (ops->datbuf && (to + ops->len) > mtd->size) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			  "Attempt read beyond end of device\n");
+		return -EINVAL;
+	}
+
+	nand_get_device(chip, mtd, FL_WRITING);
+
+	switch(ops->mode) {
+	case MTD_OOB_PLACE:
+	case MTD_OOB_AUTO:
+	case MTD_OOB_RAW:
+		break;
+
+	default:
+		goto out;
+	}
+
+	if (!ops->datbuf)
+		ret = nand_do_write_oob(mtd, to, ops);
+	else
+		ret = nand_do_write_ops(mtd, to, ops);
+
+ out:
+	nand_release_device(mtd);
+	return ret;
+}
+
+/**
+ * single_erease_cmd - [GENERIC] NAND standard block erase command function
+ * @mtd:	MTD device structure
+ * @page:	the page address of the block which will be erased
+ *
+ * Standard erase command for NAND chips
+ */
+static void single_erase_cmd(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *chip = mtd->priv;
+	/* Send commands to erase a block */
+	chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
+	chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
+}
+
+/**
+ * multi_erease_cmd - [GENERIC] AND specific block erase command function
+ * @mtd:	MTD device structure
+ * @page:	the page address of the block which will be erased
+ *
+ * AND multi block erase command function
+ * Erase 4 consecutive blocks
+ */
+static void multi_erase_cmd(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *chip = mtd->priv;
+	/* Send commands to erase a block */
+	chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+	chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+	chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
+	chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
+	chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
+}
+
+/**
+ * nand_erase - [MTD Interface] erase block(s)
+ * @mtd:	MTD device structure
+ * @instr:	erase instruction
+ *
+ * Erase one ore more blocks
+ */
+static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	return nand_erase_nand(mtd, instr, 0);
+}
+
+#define BBT_PAGE_MASK	0xffffff3f
+/**
+ * nand_erase_nand - [Internal] erase block(s)
+ * @mtd:	MTD device structure
+ * @instr:	erase instruction
+ * @allowbbt:	allow erasing the bbt area
+ *
+ * Erase one ore more blocks
+ */
+int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+		    int allowbbt)
+{
+	int page, status, pages_per_block, ret, chipnr;
+	struct nand_chip *chip = mtd->priv;
+	loff_t rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS] = {0};
+	unsigned int bbt_masked_page = 0xffffffff;
+	loff_t len;
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%012llx, "
+		 "len = %llu\n", (unsigned long long) instr->addr,
+		 (unsigned long long) instr->len);
+
+	/* Start address must align on block boundary */
+	if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
+		return -EINVAL;
+	}
+
+	/* Length must align on block boundary */
+	if (instr->len & ((1 << chip->phys_erase_shift) - 1)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0,
+			  "nand_erase: Length not block aligned\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow erase past end of device */
+	if ((instr->len + instr->addr) > mtd->size) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0,
+			  "nand_erase: Erase past end of device\n");
+		return -EINVAL;
+	}
+
+	instr->fail_addr = 0xffffffff;
+
+	/* Grab the lock and see if the device is available */
+	nand_get_device(chip, mtd, FL_ERASING);
+
+	/* Shift to get first page */
+	page = (int)(instr->addr >> chip->page_shift);
+	chipnr = (int)(instr->addr >> chip->chip_shift);
+
+	/* Calculate pages in each block */
+	pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift);
+
+	/* Select the NAND device */
+	chip->select_chip(mtd, chipnr);
+
+	/* Check, if it is write protected */
+	if (nand_check_wp(mtd)) {
+		MTDDEBUG (MTD_DEBUG_LEVEL0,
+			  "nand_erase: Device is write protected!!!\n");
+		instr->state = MTD_ERASE_FAILED;
+		goto erase_exit;
+	}
+
+	/*
+	 * If BBT requires refresh, set the BBT page mask to see if the BBT
+	 * should be rewritten. Otherwise the mask is set to 0xffffffff which
+	 * can not be matched. This is also done when the bbt is actually
+	 * erased to avoid recusrsive updates
+	 */
+	if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
+		bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
+
+	/* Loop through the pages */
+	len = instr->len;
+
+	instr->state = MTD_ERASING;
+
+	while (len) {
+		WATCHDOG_RESET();
+		/*
+		 * heck if we have a bad block, we do not erase bad blocks !
+		 */
+		if (nand_block_checkbad(mtd, ((loff_t) page) <<
+					chip->page_shift, 0, allowbbt)) {
+			printk(KERN_WARNING "nand_erase: attempt to erase a "
+			       "bad block at page 0x%08x\n", page);
+			instr->state = MTD_ERASE_FAILED;
+			goto erase_exit;
+		}
+
+		/*
+		 * Invalidate the page cache, if we erase the block which
+		 * contains the current cached page
+		 */
+		if (page <= chip->pagebuf && chip->pagebuf <
+		    (page + pages_per_block))
+			chip->pagebuf = -1;
+
+		chip->erase_cmd(mtd, page & chip->pagemask);
+
+		status = chip->waitfunc(mtd, chip);
+
+		/*
+		 * See if operation failed and additional status checks are
+		 * available
+		 */
+		if ((status & NAND_STATUS_FAIL) && (chip->errstat))
+			status = chip->errstat(mtd, chip, FL_ERASING,
+					       status, page);
+
+		/* See if block erase succeeded */
+		if (status & NAND_STATUS_FAIL) {
+			MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: "
+				  "Failed erase, page 0x%08x\n", page);
+			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr = ((loff_t)page << chip->page_shift);
+			goto erase_exit;
+		}
+
+		/*
+		 * If BBT requires refresh, set the BBT rewrite flag to the
+		 * page being erased
+		 */
+		if (bbt_masked_page != 0xffffffff &&
+		    (page & BBT_PAGE_MASK) == bbt_masked_page)
+			rewrite_bbt[chipnr] =
+				((loff_t)page << chip->page_shift);
+
+		/* Increment page address and decrement length */
+		len -= (1 << chip->phys_erase_shift);
+		page += pages_per_block;
+
+		/* Check, if we cross a chip boundary */
+		if (len && !(page & chip->pagemask)) {
+			chipnr++;
+			chip->select_chip(mtd, -1);
+			chip->select_chip(mtd, chipnr);
+
+			/*
+			 * If BBT requires refresh and BBT-PERCHIP, set the BBT
+			 * page mask to see if this BBT should be rewritten
+			 */
+			if (bbt_masked_page != 0xffffffff &&
+			    (chip->bbt_td->options & NAND_BBT_PERCHIP))
+				bbt_masked_page = chip->bbt_td->pages[chipnr] &
+					BBT_PAGE_MASK;
+		}
+	}
+	instr->state = MTD_ERASE_DONE;
+
+ erase_exit:
+
+	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
+
+	/* Deselect and wake up anyone waiting on the device */
+	nand_release_device(mtd);
+
+	/* Do call back function */
+	if (!ret)
+		mtd_erase_callback(instr);
+
+	/*
+	 * If BBT requires refresh and erase was successful, rewrite any
+	 * selected bad block tables
+	 */
+	if (bbt_masked_page == 0xffffffff || ret)
+		return ret;
+
+	for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
+		if (!rewrite_bbt[chipnr])
+			continue;
+		/* update the BBT for chip */
+		MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt "
+			  "(%d:0x%0llx 0x%0x)\n", chipnr, rewrite_bbt[chipnr],
+			  chip->bbt_td->pages[chipnr]);
+		nand_update_bbt(mtd, rewrite_bbt[chipnr]);
+	}
+
+	/* Return more or less happy */
+	return ret;
+}
+
+/**
+ * nand_sync - [MTD Interface] sync
+ * @mtd:	MTD device structure
+ *
+ * Sync is actually a wait for chip ready function
+ */
+static void nand_sync(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
+
+	/* Grab the lock and see if the device is available */
+	nand_get_device(chip, mtd, FL_SYNCING);
+	/* Release it and go back */
+	nand_release_device(mtd);
+}
+
+/**
+ * nand_block_isbad - [MTD Interface] Check if block at offset is bad
+ * @mtd:	MTD device structure
+ * @offs:	offset relative to mtd start
+ */
+static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
+{
+	/* Check for invalid offset */
+	if (offs > mtd->size)
+		return -EINVAL;
+
+	return nand_block_checkbad(mtd, offs, 1, 0);
+}
+
+/**
+ * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
+ * @mtd:	MTD device structure
+ * @ofs:	offset relative to mtd start
+ */
+static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret;
+
+	if ((ret = nand_block_isbad(mtd, ofs))) {
+		/* If it was bad already, return success and do nothing. */
+		if (ret > 0)
+			return 0;
+		return ret;
+	}
+
+	return chip->block_markbad(mtd, ofs);
+}
+
+/*
+ * Set default functions
+ */
+static void nand_set_defaults(struct nand_chip *chip, int busw)
+{
+	/* check for proper chip_delay setup, set 20us if not */
+	if (!chip->chip_delay)
+		chip->chip_delay = 20;
+
+	/* check, if a user supplied command function given */
+	if (chip->cmdfunc == NULL)
+		chip->cmdfunc = nand_command;
+
+	/* check, if a user supplied wait function given */
+	if (chip->waitfunc == NULL)
+		chip->waitfunc = nand_wait;
+
+	if (!chip->select_chip)
+		chip->select_chip = nand_select_chip;
+	if (!chip->read_byte)
+		chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
+	if (!chip->read_word)
+		chip->read_word = nand_read_word;
+	if (!chip->block_bad)
+		chip->block_bad = nand_block_bad;
+	if (!chip->block_markbad)
+		chip->block_markbad = nand_default_block_markbad;
+	if (!chip->write_buf)
+		chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
+	if (!chip->read_buf)
+		chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
+	if (!chip->verify_buf)
+		chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
+	if (!chip->scan_bbt)
+		chip->scan_bbt = nand_default_bbt;
+	if (!chip->controller)
+		chip->controller = &chip->hwcontrol;
+}
+
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
+{
+	int i;
+
+	while (len--) {
+		crc ^= *p++ << 8;
+		for (i = 0; i < 8; i++)
+			crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+	}
+
+	return crc;
+}
+
+/*
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ */
+static int nand_flash_detect_onfi(struct mtd_info *mtd,
+					struct nand_chip *chip,
+					int *busw)
+{
+	struct nand_onfi_params *p = &chip->onfi_params;
+	int i;
+	int val;
+
+	chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
+	if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
+		chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
+		return 0;
+
+	printk(KERN_INFO "ONFI flash detected\n");
+	chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
+	for (i = 0; i < 3; i++) {
+		chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+		if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
+						le16_to_cpu(p->crc)) {
+			printk(KERN_INFO "ONFI param page %d valid\n", i);
+			break;
+		}
+	}
+
+	if (i == 3)
+		return 0;
+
+	/* check version */
+	val = le16_to_cpu(p->revision);
+	if (val & (1 << 5))
+		chip->onfi_version = 23;
+	else if (val & (1 << 4))
+		chip->onfi_version = 22;
+	else if (val & (1 << 3))
+		chip->onfi_version = 21;
+	else if (val & (1 << 2))
+		chip->onfi_version = 20;
+	else if (val & (1 << 1))
+		chip->onfi_version = 10;
+	else
+		chip->onfi_version = 0;
+
+	if (!chip->onfi_version) {
+		printk(KERN_INFO "%s: unsupported ONFI "
+					"version: %d\n", __func__, val);
+		return 0;
+	}
+
+	if (!mtd->name)
+		mtd->name = p->model;
+
+	mtd->writesize = le32_to_cpu(p->byte_per_page);
+	mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+	mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+	chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
+	*busw = 0;
+	if (le16_to_cpu(p->features) & 1)
+		*busw = NAND_BUSWIDTH_16;
+
+	return 1;
+}
+#else
+static inline int nand_flash_detect_onfi(struct mtd_info *mtd,
+					struct nand_chip *chip,
+					int *busw)
+{
+	return 0;
+}
+#endif
+
+static void nand_flash_detect_non_onfi(struct mtd_info *mtd,
+					struct nand_chip *chip,
+					const struct nand_flash_dev *type,
+					int *busw)
+{
+	/* Newer devices have all the information in additional id bytes */
+	if (!type->pagesize) {
+		int extid;
+		/* The 3rd id byte holds MLC / multichip data */
+		chip->cellinfo = chip->read_byte(mtd);
+		/* The 4th id byte is the important one */
+		extid = chip->read_byte(mtd);
+		/* Calc pagesize */
+		mtd->writesize = 1024 << (extid & 0x3);
+		extid >>= 2;
+		/* Calc oobsize */
+		mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
+		extid >>= 2;
+		/* Calc blocksize. Blocksize is multiples of 64KiB */
+		mtd->erasesize = (64 * 1024) << (extid & 0x03);
+		extid >>= 2;
+		/* Get buswidth information */
+		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+
+	} else {
+		/*
+		 * Old devices have chip data hardcoded in the device id table
+		 */
+		mtd->erasesize = type->erasesize;
+		mtd->writesize = type->pagesize;
+		mtd->oobsize = mtd->writesize / 32;
+		*busw = type->options & NAND_BUSWIDTH_16;
+	}
+}
+
+/*
+ * Get the flash and manufacturer id and lookup if the type is supported
+ */
+static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+						  struct nand_chip *chip,
+						  int busw,
+						  int *maf_id, int *dev_id,
+						  const struct nand_flash_dev *type)
+{
+	int ret, maf_idx;
+	int tmp_id, tmp_manf;
+
+	/* Select the device */
+	chip->select_chip(mtd, 0);
+
+	/*
+	 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
+	 * after power-up
+	 */
+	chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+	/* Send the command for reading device ID */
+	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+	/* Read manufacturer and device IDs */
+	*maf_id = chip->read_byte(mtd);
+	*dev_id = chip->read_byte(mtd);
+
+	/* Try again to make sure, as some systems the bus-hold or other
+	 * interface concerns can cause random data which looks like a
+	 * possibly credible NAND flash to appear. If the two results do
+	 * not match, ignore the device completely.
+	 */
+
+	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+	/* Read manufacturer and device IDs */
+
+	tmp_manf = chip->read_byte(mtd);
+	tmp_id = chip->read_byte(mtd);
+
+	if (tmp_manf != *maf_id || tmp_id != *dev_id) {
+		printk(KERN_INFO "%s: second ID read did not match "
+		       "%02x,%02x against %02x,%02x\n", __func__,
+		       *maf_id, *dev_id, tmp_manf, tmp_id);
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (!type)
+		type = nand_flash_ids;
+
+	for (; type->name != NULL; type++)
+		if (*dev_id == type->id)
+			break;
+
+	if (!type->name) {
+		/* supress warning if there is no nand */
+		if (*maf_id != 0x00 && *maf_id != 0xff &&
+		    *dev_id  != 0x00 && *dev_id  != 0xff)
+			printk(KERN_INFO "%s: unknown NAND device: "
+				"Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
+				__func__, *maf_id, *dev_id);
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (!mtd->name)
+		mtd->name = type->name;
+
+	chip->chipsize = (uint64_t)type->chipsize << 20;
+	chip->onfi_version = 0;
+
+	ret = nand_flash_detect_onfi(mtd, chip, &busw);
+	if (!ret)
+		nand_flash_detect_non_onfi(mtd, chip, type, &busw);
+
+	/* Get chip options, preserve non chip based options */
+	chip->options &= ~NAND_CHIPOPTIONS_MSK;
+	chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+
+	/*
+	 * Set chip as a default. Board drivers can override it, if necessary
+	 */
+	chip->options |= NAND_NO_AUTOINCR;
+
+	/* Try to identify manufacturer */
+	for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
+		if (nand_manuf_ids[maf_idx].id == *maf_id)
+			break;
+	}
+
+	/*
+	 * Check, if buswidth is correct. Hardware drivers should set
+	 * chip correct !
+	 */
+	if (busw != (chip->options & NAND_BUSWIDTH_16)) {
+		printk(KERN_INFO "NAND device: Manufacturer ID:"
+		       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
+		       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+		printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
+		       (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
+		       busw ? 16 : 8);
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* Calculate the address shift from the page size */
+	chip->page_shift = ffs(mtd->writesize) - 1;
+	/* Convert chipsize to number of pages per chip -1. */
+	chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+
+	chip->bbt_erase_shift = chip->phys_erase_shift =
+		ffs(mtd->erasesize) - 1;
+	if (chip->chipsize & 0xffffffff)
+		chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
+	else
+		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 31;
+
+	/* Set the bad block position */
+	chip->badblockpos = mtd->writesize > 512 ?
+		NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
+
+	/* Check if chip is a not a samsung device. Do not clear the
+	 * options for chips which are not having an extended id.
+	 */
+	if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
+		chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
+
+	/* Check for AND chips with 4 page planes */
+	if (chip->options & NAND_4PAGE_ARRAY)
+		chip->erase_cmd = multi_erase_cmd;
+	else
+		chip->erase_cmd = single_erase_cmd;
+
+	/* Do not replace user supplied command function ! */
+	if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
+		chip->cmdfunc = nand_command_lp;
+
+	MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"
+		  " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
+		  nand_manuf_ids[maf_idx].name, type->name);
+
+	return type;
+}
+
+/**
+ * nand_scan_ident - [NAND Interface] Scan for the NAND device
+ * @mtd:	     MTD device structure
+ * @maxchips:	     Number of chips to scan for
+ * @table:	     Alternative NAND ID table
+ *
+ * This is the first phase of the normal nand_scan() function. It
+ * reads the flash ID and sets up MTD fields accordingly.
+ *
+ * The mtd->owner field must be set to the module of the caller.
+ */
+int nand_scan_ident(struct mtd_info *mtd, int maxchips,
+		    const struct nand_flash_dev *table)
+{
+	int i, busw, nand_maf_id, nand_dev_id;
+	struct nand_chip *chip = mtd->priv;
+	const struct nand_flash_dev *type;
+
+	/* Get buswidth to select the correct functions */
+	busw = chip->options & NAND_BUSWIDTH_16;
+	/* Set the default functions */
+	nand_set_defaults(chip, busw);
+
+	/* Read the flash type */
+	type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table);
+
+	if (IS_ERR(type)) {
+#ifndef CONFIG_SYS_NAND_QUIET_TEST
+		printk(KERN_WARNING "No NAND device found!!!\n");
+#endif
+		chip->select_chip(mtd, -1);
+		return PTR_ERR(type);
+	}
+
+	/* Check for a chip array */
+	for (i = 1; i < maxchips; i++) {
+		chip->select_chip(mtd, i);
+		/* See comment in nand_get_flash_type for reset */
+		chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+		/* Send the command for reading device ID */
+		chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+		/* Read manufacturer and device IDs */
+		if (nand_maf_id != chip->read_byte(mtd) ||
+		    nand_dev_id != chip->read_byte(mtd))
+			break;
+	}
+#ifdef DEBUG
+	if (i > 1)
+		printk(KERN_INFO "%d NAND chips detected\n", i);
+#endif
+
+	/* Store the number of chips and calc total size for mtd */
+	chip->numchips = i;
+	mtd->size = i * chip->chipsize;
+
+	return 0;
+}
+
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd:	    MTD device structure
+ *
+ * This is the second phase of the normal nand_scan() function. It
+ * fills out all the uninitialized function pointers with the defaults
+ * and scans for a bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	if (!(chip->options & NAND_OWN_BUFFERS))
+		chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
+	if (!chip->buffers)
+		return -ENOMEM;
+
+	/* Set the internal oob buffer location, just after the page data */
+	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
+
+	/*
+	 * If no default placement scheme is given, select an appropriate one
+	 */
+	if (!chip->ecc.layout) {
+		switch (mtd->oobsize) {
+		case 8:
+			chip->ecc.layout = &nand_oob_8;
+			break;
+		case 16:
+			chip->ecc.layout = &nand_oob_16;
+			break;
+		case 64:
+			chip->ecc.layout = &nand_oob_64;
+			break;
+		case 128:
+			chip->ecc.layout = &nand_oob_128;
+			break;
+		default:
+			printk(KERN_WARNING "No oob scheme defined for "
+			       "oobsize %d\n", mtd->oobsize);
+		}
+	}
+
+	if (!chip->write_page)
+		chip->write_page = nand_write_page;
+
+	/*
+	 * check ECC mode, default to software if 3byte/512byte hardware ECC is
+	 * selected and we have 256 byte pagesize fallback to software ECC
+	 */
+
+	switch (chip->ecc.mode) {
+	case NAND_ECC_HW_OOB_FIRST:
+		/* Similar to NAND_ECC_HW, but a separate read_page handle */
+		if (!chip->ecc.calculate || !chip->ecc.correct ||
+		     !chip->ecc.hwctl) {
+			printk(KERN_WARNING "No ECC functions supplied, "
+			       "Hardware ECC not possible\n");
+			BUG();
+		}
+		if (!chip->ecc.read_page)
+			chip->ecc.read_page = nand_read_page_hwecc_oob_first;
+
+	case NAND_ECC_HW:
+		/* Use standard hwecc read page function ? */
+		if (!chip->ecc.read_page)
+			chip->ecc.read_page = nand_read_page_hwecc;
+		if (!chip->ecc.write_page)
+			chip->ecc.write_page = nand_write_page_hwecc;
+		if (!chip->ecc.read_page_raw)
+			chip->ecc.read_page_raw = nand_read_page_raw;
+		if (!chip->ecc.write_page_raw)
+			chip->ecc.write_page_raw = nand_write_page_raw;
+		if (!chip->ecc.read_oob)
+			chip->ecc.read_oob = nand_read_oob_std;
+		if (!chip->ecc.write_oob)
+			chip->ecc.write_oob = nand_write_oob_std;
+
+	case NAND_ECC_HW_SYNDROME:
+		if ((!chip->ecc.calculate || !chip->ecc.correct ||
+		     !chip->ecc.hwctl) &&
+		    (!chip->ecc.read_page ||
+		     chip->ecc.read_page == nand_read_page_hwecc ||
+		     !chip->ecc.write_page ||
+		     chip->ecc.write_page == nand_write_page_hwecc)) {
+			printk(KERN_WARNING "No ECC functions supplied, "
+			       "Hardware ECC not possible\n");
+			BUG();
+		}
+		/* Use standard syndrome read/write page function ? */
+		if (!chip->ecc.read_page)
+			chip->ecc.read_page = nand_read_page_syndrome;
+		if (!chip->ecc.write_page)
+			chip->ecc.write_page = nand_write_page_syndrome;
+		if (!chip->ecc.read_page_raw)
+			chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
+		if (!chip->ecc.write_page_raw)
+			chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
+		if (!chip->ecc.read_oob)
+			chip->ecc.read_oob = nand_read_oob_syndrome;
+		if (!chip->ecc.write_oob)
+			chip->ecc.write_oob = nand_write_oob_syndrome;
+
+		if (mtd->writesize >= chip->ecc.size)
+			break;
+		printk(KERN_WARNING "%d byte HW ECC not possible on "
+		       "%d byte page size, fallback to SW ECC\n",
+		       chip->ecc.size, mtd->writesize);
+		chip->ecc.mode = NAND_ECC_SOFT;
+
+	case NAND_ECC_SOFT:
+		chip->ecc.calculate = nand_calculate_ecc;
+		chip->ecc.correct = nand_correct_data;
+		chip->ecc.read_page = nand_read_page_swecc;
+		chip->ecc.read_subpage = nand_read_subpage;
+		chip->ecc.write_page = nand_write_page_swecc;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
+		chip->ecc.read_oob = nand_read_oob_std;
+		chip->ecc.write_oob = nand_write_oob_std;
+		chip->ecc.size = 256;
+		chip->ecc.bytes = 3;
+		break;
+
+	case NAND_ECC_NONE:
+		printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
+		       "This is not recommended !!\n");
+		chip->ecc.read_page = nand_read_page_raw;
+		chip->ecc.write_page = nand_write_page_raw;
+		chip->ecc.read_oob = nand_read_oob_std;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
+		chip->ecc.write_oob = nand_write_oob_std;
+		chip->ecc.size = mtd->writesize;
+		chip->ecc.bytes = 0;
+		break;
+
+	default:
+		printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
+		       chip->ecc.mode);
+		BUG();
+	}
+
+	/*
+	 * The number of bytes available for a client to place data into
+	 * the out of band area
+	 */
+	chip->ecc.layout->oobavail = 0;
+	for (i = 0; chip->ecc.layout->oobfree[i].length
+			&& i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)
+		chip->ecc.layout->oobavail +=
+			chip->ecc.layout->oobfree[i].length;
+	mtd->oobavail = chip->ecc.layout->oobavail;
+
+	/*
+	 * Set the number of read / write steps for one page depending on ECC
+	 * mode
+	 */
+	chip->ecc.steps = mtd->writesize / chip->ecc.size;
+	if(chip->ecc.steps * chip->ecc.size != mtd->writesize) {
+		printk(KERN_WARNING "Invalid ecc parameters\n");
+		BUG();
+	}
+	chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+
+	/*
+	 * Allow subpage writes up to ecc.steps. Not possible for MLC
+	 * FLASH.
+	 */
+	if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
+	    !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+		switch(chip->ecc.steps) {
+		case 2:
+			mtd->subpage_sft = 1;
+			break;
+		case 4:
+		case 8:
+		case 16:
+			mtd->subpage_sft = 2;
+			break;
+		}
+	}
+	chip->subpagesize = mtd->writesize >> mtd->subpage_sft;
+
+	/* Initialize state */
+	chip->state = FL_READY;
+
+	/* De-select the device */
+	chip->select_chip(mtd, -1);
+
+	/* Invalidate the pagebuffer reference */
+	chip->pagebuf = -1;
+
+	/* Fill in remaining MTD driver data */
+	mtd->type = MTD_NANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH;
+	mtd->erase = nand_erase;
+	mtd->point = NULL;
+	mtd->unpoint = NULL;
+	mtd->read = nand_read;
+	mtd->write = nand_write;
+	mtd->read_oob = nand_read_oob;
+	mtd->write_oob = nand_write_oob;
+	mtd->sync = nand_sync;
+	mtd->lock = NULL;
+	mtd->unlock = NULL;
+	mtd->block_isbad = nand_block_isbad;
+	mtd->block_markbad = nand_block_markbad;
+
+	/* propagate ecc.layout to mtd_info */
+	mtd->ecclayout = chip->ecc.layout;
+
+	/* Check, if we should skip the bad block table scan */
+	if (chip->options & NAND_SKIP_BBTSCAN)
+		chip->options |= NAND_BBT_SCANNED;
+
+	return 0;
+}
+
+/**
+ * nand_scan - [NAND Interface] Scan for the NAND device
+ * @mtd:	MTD device structure
+ * @maxchips:	Number of chips to scan for
+ *
+ * This fills out all the uninitialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ * The mtd->owner field must be set to the module of the caller
+ *
+ */
+int nand_scan(struct mtd_info *mtd, int maxchips)
+{
+	int ret;
+
+	ret = nand_scan_ident(mtd, maxchips, NULL);
+	if (!ret)
+		ret = nand_scan_tail(mtd);
+	return ret;
+}
+
+/**
+ * nand_release - [NAND Interface] Free resources held by the NAND device
+ * @mtd:	MTD device structure
+*/
+void nand_release(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	/* Deregister partitions */
+	del_mtd_partitions(mtd);
+#endif
+
+	/* Free bad block table memory */
+	kfree(chip->bbt);
+	if (!(chip->options & NAND_OWN_BUFFERS))
+		kfree(chip->buffers);
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_bbt.c u-boot-2011.06/drivers/mtd/nand/nand_bbt.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_bbt.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_bbt.c	2014-07-29 17:28:38.819972000 +0800
@@ -462,11 +462,11 @@
 {
 	struct nand_chip *this = mtd->priv;
 	int i, chips;
-	int bits, startblock, block, dir;
+	int bits=0, startblock, block, dir;
 	int scanlen = mtd->writesize + mtd->oobsize;
 	int bbtblocks;
 	int blocktopage = this->bbt_erase_shift - this->page_shift;
-
+	bits=bits;
 	/* Search direction top -> down ? */
 	if (td->options & NAND_BBT_LASTBLOCK) {
 		startblock = (mtd->size >> this->bbt_erase_shift) - 1;
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_ecc.c u-boot-2011.06/drivers/mtd/nand/nand_ecc.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_ecc.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_ecc.c	2014-09-22 17:55:56.799649000 +0800
@@ -1,13 +1,18 @@
 /*
- * This file contains an ECC algorithm from Toshiba that detects and
- * corrects 1 bit errors in a 256 byte block of data.
+ * This file contains an ECC algorithm that detects and corrects 1 bit
+ * errors in a 256 byte block of data.
  *
  * drivers/mtd/nand/nand_ecc.c
  *
- * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
- *                         Toshiba America Electronics Components, Inc.
+ * Copyright © 2008 Koninklijke Philips Electronics NV.
+ *                  Author: Frans Meulenbroeks
  *
- * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ * Completely replaces the previous ECC implementation which was written by:
+ *   Steven J. Hill (sjhill@realitydiluted.com)
+ *   Thomas Gleixner (tglx@linutronix.de)
+ *
+ * Information on how this algorithm works and how it was developed
+ * can be found in Documentation/mtd/nand_ecc.txt
  *
  * This file is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -23,22 +28,21 @@
  * with this file; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  *
- * As a special exception, if other files instantiate templates or use
- * macros or inline functions from these files, or you compile these
- * files and link them with other works to produce a work based on these
- * files, these files do not by themselves cause the resulting work to be
- * covered by the GNU General Public License. However the source code for
- * these files must still be made available in accordance with section (3)
- * of the GNU General Public License.
- *
- * This exception does not invalidate any other reasons why a work based on
- * this file might be covered by the GNU General Public License.
  */
 
+/*
+ * The STANDALONE macro is useful when running the code outside the kernel
+ * e.g. when running the code in a testbed or a benchmark program.
+ * When STANDALONE is used, the module related macros are commented out
+ * as well as the linux include files.
+ * Instead a private definition of mtd_info is given to satisfy the compiler
+ * (the code does not use mtd_info, so the code does not care)
+ */
 #include <common.h>
 
 #include <asm/errno.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
 
 /* The PPC4xx NDFC uses Smart Media (SMC) bytes order */
 #ifdef CONFIG_NAND_NDFC
@@ -51,152 +55,473 @@
  */
 
 #ifndef CONFIG_NAND_SPL
+
+/*
+ * invparity is a 256 byte table that contains the odd parity
+ * for each byte. So if the number of bits in a byte is even,
+ * the array element is 1, and when the number of bits is odd
+ * the array eleemnt is 0.
+ */
+static const char invparity[256] = {
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+	1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
+};
+#endif
+/*
+ * bitsperbyte contains the number of bits per byte
+ * this is only used for testing and repairing parity
+ * (a precalculated value slightly improves performance)
+ */
+static const char bitsperbyte[256] = {
+	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
+
 /*
- * Pre-calculated 256-way 1 byte column parity
+ * addressbits is a lookup table to filter out the bits from the xor-ed
+ * ECC data that identify the faulty location.
+ * this is only used for repairing parity
+ * see the comments in nand_correct_data for more details
  */
-static const u_char nand_ecc_precalc_table[] = {
-	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
-	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+static const char addressbits[256] = {
+	0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+	0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+	0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+	0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+	0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+	0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+	0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+	0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+	0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+	0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+	0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+	0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+	0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+	0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+	0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+	0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+	0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+	0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+	0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+	0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+	0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+	0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+	0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+	0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+	0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+	0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+	0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+	0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+	0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+	0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+	0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+	0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
 };
 
+#ifndef CONFIG_NAND_SPL
+
 /**
- * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
- * @mtd:	MTD block structure
- * @dat:	raw data
- * @ecc_code:	buffer for ECC
+ * __nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
+ *			 block
+ * @buf:	input buffer with raw data
+ * @eccsize:	data bytes per ECC step (256 or 512)
+ * @code:	output buffer with ECC
  */
-int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-		       u_char *ecc_code)
+void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
+		       unsigned char *code)
 {
-	uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
 	int i;
+	const uint32_t *bp = (uint32_t *)buf;
+	/* 256 or 512 bytes/ecc  */
+	const uint32_t eccsize_mult = eccsize >> 8;
+	uint32_t cur;		/* current value in buffer */
+	/* rp0..rp15..rp17 are the various accumulated parities (per byte) */
+	uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
+	uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
+	uint32_t uninitialized_var(rp17);	/* to make compiler happy */
+	uint32_t par;		/* the cumulative parity for all data */
+	uint32_t tmppar;	/* the cumulative parity for this iteration;
+				   for rp12, rp14 and rp16 at the end of the
+				   loop */
+
+	par = 0;
+	rp4 = 0;
+	rp6 = 0;
+	rp8 = 0;
+	rp10 = 0;
+	rp12 = 0;
+	rp14 = 0;
+	rp16 = 0;
+
+	/*
+	 * The loop is unrolled a number of times;
+	 * This avoids if statements to decide on which rp value to update
+	 * Also we process the data by longwords.
+	 * Note: passing unaligned data might give a performance penalty.
+	 * It is assumed that the buffers are aligned.
+	 * tmppar is the cumulative sum of this iteration.
+	 * needed for calculating rp12, rp14, rp16 and par
+	 * also used as a performance improvement for rp6, rp8 and rp10
+	 */
+	for (i = 0; i < eccsize_mult << 2; i++) {
+		cur = *bp++;
+		tmppar = cur;
+		rp4 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp6 ^= tmppar;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp8 ^= tmppar;
+
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		rp6 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp6 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp10 ^= tmppar;
+
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		rp6 ^= cur;
+		rp8 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp6 ^= cur;
+		rp8 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		rp8 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp8 ^= cur;
+
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		rp6 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp6 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+		rp4 ^= cur;
+		cur = *bp++;
+		tmppar ^= cur;
+
+		par ^= tmppar;
+		if ((i & 0x1) == 0)
+			rp12 ^= tmppar;
+		if ((i & 0x2) == 0)
+			rp14 ^= tmppar;
+		if (eccsize_mult == 2 && (i & 0x4) == 0)
+			rp16 ^= tmppar;
+	}
 
-	/* Initialize variables */
-	reg1 = reg2 = reg3 = 0;
-
-	/* Build up column parity */
-	for(i = 0; i < 256; i++) {
-		/* Get CP0 - CP5 from table */
-		idx = nand_ecc_precalc_table[*dat++];
-		reg1 ^= (idx & 0x3f);
-
-		/* All bit XOR = 1 ? */
-		if (idx & 0x40) {
-			reg3 ^= (uint8_t) i;
-			reg2 ^= ~((uint8_t) i);
-		}
+	/*
+	 * handle the fact that we use longword operations
+	 * we'll bring rp4..rp14..rp16 back to single byte entities by
+	 * shifting and xoring first fold the upper and lower 16 bits,
+	 * then the upper and lower 8 bits.
+	 */
+	rp4 ^= (rp4 >> 16);
+	rp4 ^= (rp4 >> 8);
+	rp4 &= 0xff;
+	rp6 ^= (rp6 >> 16);
+	rp6 ^= (rp6 >> 8);
+	rp6 &= 0xff;
+	rp8 ^= (rp8 >> 16);
+	rp8 ^= (rp8 >> 8);
+	rp8 &= 0xff;
+	rp10 ^= (rp10 >> 16);
+	rp10 ^= (rp10 >> 8);
+	rp10 &= 0xff;
+	rp12 ^= (rp12 >> 16);
+	rp12 ^= (rp12 >> 8);
+	rp12 &= 0xff;
+	rp14 ^= (rp14 >> 16);
+	rp14 ^= (rp14 >> 8);
+	rp14 &= 0xff;
+	if (eccsize_mult == 2) {
+		rp16 ^= (rp16 >> 16);
+		rp16 ^= (rp16 >> 8);
+		rp16 &= 0xff;
 	}
 
-	/* Create non-inverted ECC code from line parity */
-	tmp1  = (reg3 & 0x80) >> 0; /* B7 -> B7 */
-	tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
-	tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
-	tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
-	tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
-	tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
-	tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
-	tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
-
-	tmp2  = (reg3 & 0x08) << 4; /* B3 -> B7 */
-	tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
-	tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
-	tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
-	tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
-	tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
-	tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
-	tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
+	/*
+	 * we also need to calculate the row parity for rp0..rp3
+	 * This is present in par, because par is now
+	 * rp3 rp3 rp2 rp2 in little endian and
+	 * rp2 rp2 rp3 rp3 in big endian
+	 * as well as
+	 * rp1 rp0 rp1 rp0 in little endian and
+	 * rp0 rp1 rp0 rp1 in big endian
+	 * First calculate rp2 and rp3
+	 */
+#ifdef __BIG_ENDIAN
+	rp2 = (par >> 16);
+	rp2 ^= (rp2 >> 8);
+	rp2 &= 0xff;
+	rp3 = par & 0xffff;
+	rp3 ^= (rp3 >> 8);
+	rp3 &= 0xff;
+#else
+	rp3 = (par >> 16);
+	rp3 ^= (rp3 >> 8);
+	rp3 &= 0xff;
+	rp2 = par & 0xffff;
+	rp2 ^= (rp2 >> 8);
+	rp2 &= 0xff;
+#endif
 
-	/* Calculate final ECC code */
-#ifdef CONFIG_MTD_NAND_ECC_SMC
-	ecc_code[0] = ~tmp2;
-	ecc_code[1] = ~tmp1;
+	/* reduce par to 16 bits then calculate rp1 and rp0 */
+	par ^= (par >> 16);
+#ifdef __BIG_ENDIAN
+	rp0 = (par >> 8) & 0xff;
+	rp1 = (par & 0xff);
 #else
-	ecc_code[0] = ~tmp1;
-	ecc_code[1] = ~tmp2;
+	rp1 = (par >> 8) & 0xff;
+	rp0 = (par & 0xff);
 #endif
-	ecc_code[2] = ((~reg1) << 2) | 0x03;
 
-	return 0;
+	/* finally reduce par to 8 bits */
+	par ^= (par >> 8);
+	par &= 0xff;
+
+	/*
+	 * and calculate rp5..rp15..rp17
+	 * note that par = rp4 ^ rp5 and due to the commutative property
+	 * of the ^ operator we can say:
+	 * rp5 = (par ^ rp4);
+	 * The & 0xff seems superfluous, but benchmarking learned that
+	 * leaving it out gives slightly worse results. No idea why, probably
+	 * it has to do with the way the pipeline in pentium is organized.
+	 */
+	rp5 = (par ^ rp4) & 0xff;
+	rp7 = (par ^ rp6) & 0xff;
+	rp9 = (par ^ rp8) & 0xff;
+	rp11 = (par ^ rp10) & 0xff;
+	rp13 = (par ^ rp12) & 0xff;
+	rp15 = (par ^ rp14) & 0xff;
+	if (eccsize_mult == 2)
+		rp17 = (par ^ rp16) & 0xff;
+
+	/*
+	 * Finally calculate the ECC bits.
+	 * Again here it might seem that there are performance optimisations
+	 * possible, but benchmarks showed that on the system this is developed
+	 * the code below is the fastest
+	 */
+#ifdef CONFIG_MTD_NAND_ECC_SMC
+	code[0] =
+	    (invparity[rp7] << 7) |
+	    (invparity[rp6] << 6) |
+	    (invparity[rp5] << 5) |
+	    (invparity[rp4] << 4) |
+	    (invparity[rp3] << 3) |
+	    (invparity[rp2] << 2) |
+	    (invparity[rp1] << 1) |
+	    (invparity[rp0]);
+	code[1] =
+	    (invparity[rp15] << 7) |
+	    (invparity[rp14] << 6) |
+	    (invparity[rp13] << 5) |
+	    (invparity[rp12] << 4) |
+	    (invparity[rp11] << 3) |
+	    (invparity[rp10] << 2) |
+	    (invparity[rp9] << 1)  |
+	    (invparity[rp8]);
+#else
+	code[1] =
+	    (invparity[rp7] << 7) |
+	    (invparity[rp6] << 6) |
+	    (invparity[rp5] << 5) |
+	    (invparity[rp4] << 4) |
+	    (invparity[rp3] << 3) |
+	    (invparity[rp2] << 2) |
+	    (invparity[rp1] << 1) |
+	    (invparity[rp0]);
+	code[0] =
+	    (invparity[rp15] << 7) |
+	    (invparity[rp14] << 6) |
+	    (invparity[rp13] << 5) |
+	    (invparity[rp12] << 4) |
+	    (invparity[rp11] << 3) |
+	    (invparity[rp10] << 2) |
+	    (invparity[rp9] << 1)  |
+	    (invparity[rp8]);
+#endif
+	if (eccsize_mult == 1)
+		code[2] =
+		    (invparity[par & 0xf0] << 7) |
+		    (invparity[par & 0x0f] << 6) |
+		    (invparity[par & 0xcc] << 5) |
+		    (invparity[par & 0x33] << 4) |
+		    (invparity[par & 0xaa] << 3) |
+		    (invparity[par & 0x55] << 2) |
+		    3;
+	else
+		code[2] =
+		    (invparity[par & 0xf0] << 7) |
+		    (invparity[par & 0x0f] << 6) |
+		    (invparity[par & 0xcc] << 5) |
+		    (invparity[par & 0x33] << 4) |
+		    (invparity[par & 0xaa] << 3) |
+		    (invparity[par & 0x55] << 2) |
+		    (invparity[rp17] << 1) |
+		    (invparity[rp16] << 0);
 }
-#endif /* CONFIG_NAND_SPL */
 
-static inline int countbits(uint32_t byte)
+/**
+ * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
+ *			 block
+ * @mtd:	MTD block structure
+ * @buf:	input buffer with raw data
+ * @code:	output buffer with ECC
+ */
+int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
+		       unsigned char *code)
 {
-	int res = 0;
+	__nand_calculate_ecc(buf,
+			((struct nand_chip *)mtd->priv)->ecc.size, code);
 
-	for (;byte; byte >>= 1)
-		res += byte & 0x01;
-	return res;
+	return 0;
 }
+#endif
 
 /**
- * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
- * @mtd:	MTD block structure
- * @dat:	raw data read from the chip
+ * __nand_correct_data - [NAND Interface] Detect and correct bit error(s)
+ * @buf:	raw data read from the chip
  * @read_ecc:	ECC from the chip
  * @calc_ecc:	the ECC calculated from raw data
+ * @eccsize:	data bytes per ECC step (256 or 512)
  *
- * Detect and correct a 1 bit error for 256 byte block
+ * Detect and correct a 1 bit error for eccsize byte block
  */
-int nand_correct_data(struct mtd_info *mtd, u_char *dat,
-		      u_char *read_ecc, u_char *calc_ecc)
+int __nand_correct_data(unsigned char *buf,
+			unsigned char *read_ecc, unsigned char *calc_ecc,
+			unsigned int eccsize)
 {
-	uint8_t s0, s1, s2;
-
+	unsigned char b0, b1, b2, bit_addr;
+	unsigned int byte_addr;
+	/* 256 or 512 bytes/ecc  */
+	const uint32_t eccsize_mult = eccsize >> 8;
+
+	/*
+	 * b0 to b2 indicate which bit is faulty (if any)
+	 * we might need the xor result  more than once,
+	 * so keep them in a local var
+	*/
 #ifdef CONFIG_MTD_NAND_ECC_SMC
-	s0 = calc_ecc[0] ^ read_ecc[0];
-	s1 = calc_ecc[1] ^ read_ecc[1];
-	s2 = calc_ecc[2] ^ read_ecc[2];
+	b0 = read_ecc[0] ^ calc_ecc[0];
+	b1 = read_ecc[1] ^ calc_ecc[1];
 #else
-	s1 = calc_ecc[0] ^ read_ecc[0];
-	s0 = calc_ecc[1] ^ read_ecc[1];
-	s2 = calc_ecc[2] ^ read_ecc[2];
-#endif
-	if ((s0 | s1 | s2) == 0)
-		return 0;
-
-	/* Check for a single bit error */
-	if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
-	    ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
-	    ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
-
-		uint32_t byteoffs, bitnum;
-
-		byteoffs = (s1 << 0) & 0x80;
-		byteoffs |= (s1 << 1) & 0x40;
-		byteoffs |= (s1 << 2) & 0x20;
-		byteoffs |= (s1 << 3) & 0x10;
-
-		byteoffs |= (s0 >> 4) & 0x08;
-		byteoffs |= (s0 >> 3) & 0x04;
-		byteoffs |= (s0 >> 2) & 0x02;
-		byteoffs |= (s0 >> 1) & 0x01;
-
-		bitnum = (s2 >> 5) & 0x04;
-		bitnum |= (s2 >> 4) & 0x02;
-		bitnum |= (s2 >> 3) & 0x01;
+	b0 = read_ecc[1] ^ calc_ecc[1];
+	b1 = read_ecc[0] ^ calc_ecc[0];
+#endif
+	b2 = read_ecc[2] ^ calc_ecc[2];
 
-		dat[byteoffs] ^= (1 << bitnum);
+	/* check if there are any bitfaults */
 
-		return 1;
-	}
+	/* repeated if statements are slightly more efficient than switch ... */
+	/* ordered in order of likelihood */
 
-	if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
+	if ((b0 | b1 | b2) == 0)
+		return 0;	/* no error */
+
+	if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
+	    (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
+	    ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
+	     (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
+	/* single bit error */
+		/*
+		 * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty
+		 * byte, cp 5/3/1 indicate the faulty bit.
+		 * A lookup table (called addressbits) is used to filter
+		 * the bits from the byte they are in.
+		 * A marginal optimisation is possible by having three
+		 * different lookup tables.
+		 * One as we have now (for b0), one for b2
+		 * (that would avoid the >> 1), and one for b1 (with all values
+		 * << 4). However it was felt that introducing two more tables
+		 * hardly justify the gain.
+		 *
+		 * The b2 shift is there to get rid of the lowest two bits.
+		 * We could also do addressbits[b2] >> 1 but for the
+		 * performance it does not make any difference
+		 */
+		if (eccsize_mult == 1)
+			byte_addr = (addressbits[b1] << 4) + addressbits[b0];
+		else
+			byte_addr = (addressbits[b2 & 0x3] << 8) +
+				    (addressbits[b1] << 4) + addressbits[b0];
+		bit_addr = addressbits[b2 >> 2];
+		/* flip the bit */
+		buf[byte_addr] ^= (1 << bit_addr);
+		printf("1-bit error corrected\n");
 		return 1;
 
+	}
+	/* count nr of bits; use table lookup, faster than calculating it */
+	if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
+		return 1;	/* error in ECC data; no action needed */
+
+	printf("more than 1-bit error detected, uncorrectable error.");
 	return -EBADMSG;
 }
+
+/**
+ * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
+ * @mtd:	MTD block structure
+ * @buf:	raw data read from the chip
+ * @read_ecc:	ECC from the chip
+ * @calc_ecc:	the ECC calculated from raw data
+ *
+ * Detect and correct a 1 bit error for 256/512 byte block
+ */
+int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
+		      unsigned char *read_ecc, unsigned char *calc_ecc)
+{
+	return __nand_correct_data(buf, read_ecc, calc_ecc,
+				   ((struct nand_chip *)mtd->priv)->ecc.size);
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_util.c u-boot-2011.06/drivers/mtd/nand/nand_util.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_util.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_util.c	2014-10-30 20:54:29.112101000 +0800
@@ -188,13 +188,10 @@
 			 */
 			if (percent != percent_complete) {
 				percent_complete = percent;
-
-				printf("\rErasing at 0x%llx -- %3d%% complete.",
-				       erase.addr, percent);
+				printf("Erasing at 0x%llx -- %3d%% complete.\n",erase.addr, percent);
 
 				if (opts->jffs2 && result == 0)
-					printf(" Cleanmarker written at 0x%llx.",
-					       erase.addr);
+					printf(" Cleanmarker written at 0x%llx.\n",erase.addr);
 			}
 		}
 	}
@@ -499,6 +496,7 @@
 		return -EINVAL;
 	}
 
+#if !defined(CONFIG_CMD_NAND_YAFFS)
 	if (!need_skip) {
 		rval = nand_write (nand, offset, length, buffer);
 		if (rval == 0)
@@ -509,6 +507,7 @@
 			offset, rval);
 		return rval;
 	}
+#endif
 
 	while (left_to_write > 0) {
 		size_t block_offset = offset & (nand->erasesize - 1);
@@ -548,7 +547,7 @@
 				ops.oobbuf = ops.datbuf + pagesize;
 
 				rval = nand->write_oob(nand, offset, &ops);
-				if (!rval)
+				if (rval != 0)
 					break;
 
 				offset += pagesize;
@@ -597,6 +596,8 @@
 	size_t left_to_read = *length;
 	u_char *p_buffer = buffer;
 	int need_skip;
+	int dc = dcache_status();
+	dcache_enable();
 
 	if ((offset & (nand->writesize - 1)) != 0) {
 		printf ("Attempt to read non page aligned data\n");
@@ -613,12 +614,15 @@
 
 	if (!need_skip) {
 		rval = nand_read (nand, offset, length, buffer);
-		if (!rval || rval == -EUCLEAN)
+		if (!rval || rval == -EUCLEAN){
+			if(!dc)dcache_disable();
 			return 0;
+		}
 
 		*length = 0;
 		printf ("NAND read from offset %llx failed %d\n",
 			offset, rval);
+		if(!dc)dcache_disable();
 		return rval;
 	}
 
@@ -645,6 +649,7 @@
 			printf ("NAND read from offset %llx failed %d\n",
 				offset, rval);
 			*length -= left_to_read;
+			if(!dc)dcache_disable();
 			return rval;
 		}
 
@@ -653,5 +658,6 @@
 		p_buffer     += read_length;
 	}
 
+	if(!dc)dcache_disable();
 	return 0;
 }
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/nand/nand_util_profiling.c u-boot-2011.06/drivers/mtd/nand/nand_util_profiling.c
--- u-boot-2011.06_original/drivers/mtd/nand/nand_util_profiling.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/nand/nand_util_profiling.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,671 @@
+/*
+ * drivers/mtd/nand/nand_util.c
+ *
+ * Copyright (C) 2006 by Weiss-Electronic GmbH.
+ * All rights reserved.
+ *
+ * @author:	Guido Classen <clagix@gmail.com>
+ * @descr:	NAND Flash support
+ * @references: borrowed heavily from Linux mtd-utils code:
+ *		flash_eraseall.c by Arcom Control System Ltd
+ *		nandwrite.c by Steven J. Hill (sjhill@realitydiluted.com)
+ *			       and Thomas Gleixner (tglx@linutronix.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 version
+ * 2 as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ * Copyright 2010 Freescale Semiconductor
+ * The portions of this file whose copyright is held by Freescale and which
+ * are not considered a derived work of GPL v2-only code may be distributed
+ * and/or modified 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 <command.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <div64.h>
+
+#include <asm/errno.h>
+#include <linux/mtd/mtd.h>
+#include <nand.h>
+#include <jffs2/jffs2.h>
+
+typedef struct erase_info erase_info_t;
+typedef struct mtd_info	  mtd_info_t;
+
+/* support only for native endian JFFS2 */
+#define cpu_to_je16(x) (x)
+#define cpu_to_je32(x) (x)
+
+/*****************************************************************************/
+static int nand_block_bad_scrub(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+	return 0;
+}
+
+/**
+ * nand_erase_opts: - erase NAND flash with support for various options
+ *		      (jffs2 formating)
+ *
+ * @param meminfo	NAND device to erase
+ * @param opts		options,  @see struct nand_erase_options
+ * @return		0 in case of success
+ *
+ * This code is ported from flash_eraseall.c from Linux mtd utils by
+ * Arcom Control System Ltd.
+ */
+int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
+{
+	struct jffs2_unknown_node cleanmarker;
+	erase_info_t erase;
+	unsigned long erase_length, erased_length; /* in blocks */
+	int bbtest = 1;
+	int result;
+	int percent_complete = -1;
+	int (*nand_block_bad_old)(struct mtd_info *, loff_t, int) = NULL;
+	const char *mtd_device = meminfo->name;
+	struct mtd_oob_ops oob_opts;
+	struct nand_chip *chip = meminfo->priv;
+
+	if ((opts->offset & (meminfo->writesize - 1)) != 0) {
+		printf("Attempt to erase non page aligned data\n");
+		return -1;
+	}
+
+	memset(&erase, 0, sizeof(erase));
+	memset(&oob_opts, 0, sizeof(oob_opts));
+
+	erase.mtd = meminfo;
+	erase.len  = meminfo->erasesize;
+	erase.addr = opts->offset;
+	erase_length = lldiv(opts->length + meminfo->erasesize - 1,
+			     meminfo->erasesize);
+
+	cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
+	cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
+	cleanmarker.totlen = cpu_to_je32(8);
+
+	/* scrub option allows to erase badblock. To prevent internal
+	 * check from erase() method, set block check method to dummy
+	 * and disable bad block table while erasing.
+	 */
+	if (opts->scrub) {
+		struct nand_chip *priv_nand = meminfo->priv;
+
+		nand_block_bad_old = priv_nand->block_bad;
+		priv_nand->block_bad = nand_block_bad_scrub;
+		/* we don't need the bad block table anymore...
+		 * after scrub, there are no bad blocks left!
+		 */
+		if (priv_nand->bbt) {
+			kfree(priv_nand->bbt);
+		}
+		priv_nand->bbt = NULL;
+	}
+
+	for (erased_length = 0;
+	     erased_length < erase_length;
+	     erase.addr += meminfo->erasesize) {
+
+		WATCHDOG_RESET ();
+
+		if (!opts->scrub && bbtest) {
+			int ret = meminfo->block_isbad(meminfo, erase.addr);
+			if (ret > 0) {
+				if (!opts->quiet)
+					printf("\rSkipping bad block at  "
+					       "0x%08llx                 "
+					       "                         \n",
+					       erase.addr);
+
+				if (!opts->spread)
+					erased_length++;
+
+				continue;
+
+			} else if (ret < 0) {
+				printf("\n%s: MTD get bad block failed: %d\n",
+				       mtd_device,
+				       ret);
+				return -1;
+			}
+		}
+
+		erased_length++;
+
+		result = meminfo->erase(meminfo, &erase);
+		if (result != 0) {
+			printf("\n%s: MTD Erase failure: %d\n",
+			       mtd_device, result);
+			continue;
+		}
+
+		/* format for JFFS2 ? */
+		if (opts->jffs2 && chip->ecc.layout->oobavail >= 8) {
+			chip->ops.ooblen = 8;
+			chip->ops.datbuf = NULL;
+			chip->ops.oobbuf = (uint8_t *)&cleanmarker;
+			chip->ops.ooboffs = 0;
+			chip->ops.mode = MTD_OOB_AUTO;
+
+			result = meminfo->write_oob(meminfo,
+			                            erase.addr,
+			                            &chip->ops);
+			if (result != 0) {
+				printf("\n%s: MTD writeoob failure: %d\n",
+				       mtd_device, result);
+				continue;
+			}
+		}
+
+		if (!opts->quiet) {
+			unsigned long long n = erased_length * 100ULL;
+			int percent;
+
+			do_div(n, erase_length);
+			percent = (int)n;
+
+			/* output progress message only at whole percent
+			 * steps to reduce the number of messages printed
+			 * on (slow) serial consoles
+			 */
+			if (percent != percent_complete) {
+				percent_complete = percent;
+
+				printf("\rErasing at 0x%llx -- %3d%% complete.",
+				       erase.addr, percent);
+
+				if (opts->jffs2 && result == 0)
+					printf(" Cleanmarker written at 0x%llx.",
+					       erase.addr);
+			}
+		}
+	}
+	if (!opts->quiet)
+		printf("\n");
+
+	if (nand_block_bad_old) {
+		struct nand_chip *priv_nand = meminfo->priv;
+
+		priv_nand->block_bad = nand_block_bad_old;
+		priv_nand->scan_bbt(meminfo);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
+
+/******************************************************************************
+ * Support for locking / unlocking operations of some NAND devices
+ *****************************************************************************/
+
+#define NAND_CMD_LOCK		0x2a
+#define NAND_CMD_LOCK_TIGHT	0x2c
+#define NAND_CMD_UNLOCK1	0x23
+#define NAND_CMD_UNLOCK2	0x24
+#define NAND_CMD_LOCK_STATUS	0x7a
+
+/**
+ * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT
+ *	      state
+ *
+ * @param mtd		nand mtd instance
+ * @param tight		bring device in lock tight mode
+ *
+ * @return		0 on success, -1 in case of error
+ *
+ * The lock / lock-tight command only applies to the whole chip. To get some
+ * parts of the chip lock and others unlocked use the following sequence:
+ *
+ * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
+ * - Call nand_unlock() once for each consecutive area to be unlocked
+ * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
+ *
+ *   If the device is in lock-tight state software can't change the
+ *   current active lock/unlock state of all pages. nand_lock() / nand_unlock()
+ *   calls will fail. It is only posible to leave lock-tight state by
+ *   an hardware signal (low pulse on _WP pin) or by power down.
+ */
+int nand_lock(struct mtd_info *mtd, int tight)
+{
+	int ret = 0;
+	int status;
+	struct nand_chip *chip = mtd->priv;
+
+	/* select the NAND device */
+	chip->select_chip(mtd, 0);
+
+	chip->cmdfunc(mtd,
+		      (tight ? NAND_CMD_LOCK_TIGHT : NAND_CMD_LOCK),
+		      -1, -1);
+
+	/* call wait ready function */
+	status = chip->waitfunc(mtd, chip);
+
+	/* see if device thinks it succeeded */
+	if (status & 0x01) {
+		ret = -1;
+	}
+
+	/* de-select the NAND device */
+	chip->select_chip(mtd, -1);
+	return ret;
+}
+
+/**
+ * nand_get_lock_status: - query current lock state from one page of NAND
+ *			   flash
+ *
+ * @param mtd		nand mtd instance
+ * @param offset	page address to query (muss be page aligned!)
+ *
+ * @return		-1 in case of error
+ *			>0 lock status:
+ *			  bitfield with the following combinations:
+ *			  NAND_LOCK_STATUS_TIGHT: page in tight state
+ *			  NAND_LOCK_STATUS_LOCK:  page locked
+ *			  NAND_LOCK_STATUS_UNLOCK: page unlocked
+ *
+ */
+int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)
+{
+	int ret = 0;
+	int chipnr;
+	int page;
+	struct nand_chip *chip = mtd->priv;
+
+	/* select the NAND device */
+	chipnr = (int)(offset >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+
+	if ((offset & (mtd->writesize - 1)) != 0) {
+		printf ("nand_get_lock_status: "
+			"Start address must be beginning of "
+			"nand page!\n");
+		ret = -1;
+		goto out;
+	}
+
+	/* check the Lock Status */
+	page = (int)(offset >> chip->page_shift);
+	chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask);
+
+	ret = chip->read_byte(mtd) & (NAND_LOCK_STATUS_TIGHT
+					  | NAND_LOCK_STATUS_LOCK
+					  | NAND_LOCK_STATUS_UNLOCK);
+
+ out:
+	/* de-select the NAND device */
+	chip->select_chip(mtd, -1);
+	return ret;
+}
+
+/**
+ * nand_unlock: - Unlock area of NAND pages
+ *		  only one consecutive area can be unlocked at one time!
+ *
+ * @param mtd		nand mtd instance
+ * @param start		start byte address
+ * @param length	number of bytes to unlock (must be a multiple of
+ *			page size nand->writesize)
+ *
+ * @return		0 on success, -1 in case of error
+ */
+int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)
+{
+	int ret = 0;
+	int chipnr;
+	int status;
+	int page;
+	struct nand_chip *chip = mtd->priv;
+	printf ("nand_unlock: start: %08x, length: %d!\n",
+		(int)start, (int)length);
+
+	/* select the NAND device */
+	chipnr = (int)(start >> chip->chip_shift);
+	chip->select_chip(mtd, chipnr);
+
+	/* check the WP bit */
+	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+	if (!(chip->read_byte(mtd) & NAND_STATUS_WP)) {
+		printf ("nand_unlock: Device is write protected!\n");
+		ret = -1;
+		goto out;
+	}
+
+	if ((start & (mtd->erasesize - 1)) != 0) {
+		printf ("nand_unlock: Start address must be beginning of "
+			"nand block!\n");
+		ret = -1;
+		goto out;
+	}
+
+	if (length == 0 || (length & (mtd->erasesize - 1)) != 0) {
+		printf ("nand_unlock: Length must be a multiple of nand block "
+			"size %08x!\n", mtd->erasesize);
+		ret = -1;
+		goto out;
+	}
+
+	/*
+	 * Set length so that the last address is set to the
+	 * starting address of the last block
+	 */
+	length -= mtd->erasesize;
+
+	/* submit address of first page to unlock */
+	page = (int)(start >> chip->page_shift);
+	chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask);
+
+	/* submit ADDRESS of LAST page to unlock */
+	page += (int)(length >> chip->page_shift);
+	chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1, page & chip->pagemask);
+
+	/* call wait ready function */
+	status = chip->waitfunc(mtd, chip);
+	/* see if device thinks it succeeded */
+	if (status & 0x01) {
+		/* there was an error */
+		ret = -1;
+		goto out;
+	}
+
+ out:
+	/* de-select the NAND device */
+	chip->select_chip(mtd, -1);
+	return ret;
+}
+#endif
+
+/**
+ * check_skip_len
+ *
+ * Check if there are any bad blocks, and whether length including bad
+ * blocks fits into device
+ *
+ * @param nand NAND device
+ * @param offset offset in flash
+ * @param length image length
+ * @return 0 if the image fits and there are no bad blocks
+ *         1 if the image fits, but there are bad blocks
+ *        -1 if the image does not fit
+ */
+static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length)
+{
+	size_t len_excl_bad = 0;
+	int ret = 0;
+
+	while (len_excl_bad < length) {
+		size_t block_len, block_off;
+		loff_t block_start;
+
+		if (offset >= nand->size)
+			return -1;
+
+		block_start = offset & ~(loff_t)(nand->erasesize - 1);
+		block_off = offset & (nand->erasesize - 1);
+		block_len = nand->erasesize - block_off;
+
+		if (!nand_block_isbad(nand, block_start))
+			len_excl_bad += block_len;
+		else
+			ret = 1;
+
+		offset += block_len;
+	}
+
+	return ret;
+}
+
+/**
+ * nand_write_skip_bad:
+ *
+ * Write image to NAND flash.
+ * Blocks that are marked bad are skipped and the is written to the next
+ * block instead as long as the image is short enough to fit even after
+ * skipping the bad blocks.
+ *
+ * @param nand  	NAND device
+ * @param offset	offset in flash
+ * @param length	buffer length
+ * @param buffer        buffer to read from
+ * @param withoob	whether write with yaffs format
+ * @return		0 in case of success
+ */
+int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
+			u_char *buffer, int withoob)
+{
+	int rval = 0, blocksize;
+	size_t left_to_write = *length;
+	u_char *p_buffer = buffer;
+	int need_skip;
+
+#ifdef CONFIG_CMD_NAND_YAFFS
+	if (withoob) {
+		int pages;
+		pages = nand->erasesize / nand->writesize;
+		blocksize = (pages * nand->oobsize) + nand->erasesize;
+		if (*length % (nand->writesize + nand->oobsize)) {
+			printf ("Attempt to write incomplete page"
+				" in yaffs mode\n");
+			return -EINVAL;
+		}
+	} else
+#endif
+	{
+		blocksize = nand->erasesize;
+	}
+
+	/*
+	 * nand_write() handles unaligned, partial page writes.
+	 *
+	 * We allow length to be unaligned, for convenience in
+	 * using the $filesize variable.
+	 *
+	 * However, starting at an unaligned offset makes the
+	 * semantics of bad block skipping ambiguous (really,
+	 * you should only start a block skipping access at a
+	 * partition boundary).  So don't try to handle that.
+	 */
+	if ((offset & (nand->writesize - 1)) != 0) {
+		printf ("Attempt to write non page aligned data\n");
+		*length = 0;
+		return -EINVAL;
+	}
+
+	need_skip = check_skip_len(nand, offset, *length);
+	if (need_skip < 0) {
+		printf ("Attempt to write outside the flash area\n");
+		*length = 0;
+		return -EINVAL;
+	}
+
+#if !defined(CONFIG_CMD_NAND_YAFFS)
+	if (!need_skip) {
+		rval = nand_write (nand, offset, length, buffer);
+		if (rval == 0)
+			return 0;
+
+		*length = 0;
+		printf ("NAND write to offset %llx failed %d\n",
+			offset, rval);
+		return rval;
+	}
+#endif
+
+	while (left_to_write > 0) {
+		size_t block_offset = offset & (nand->erasesize - 1);
+		size_t write_size;
+
+		WATCHDOG_RESET ();
+
+		if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
+			printf ("Skip bad block 0x%08llx\n",
+				offset & ~(nand->erasesize - 1));
+			offset += nand->erasesize - block_offset;
+			continue;
+		}
+
+		if (left_to_write < (blocksize - block_offset))
+			write_size = left_to_write;
+		else
+			write_size = blocksize - block_offset;
+
+#ifdef CONFIG_CMD_NAND_YAFFS
+		if (withoob) {
+			int page, pages;
+			size_t pagesize = nand->writesize;
+			size_t pagesize_oob = pagesize + nand->oobsize;
+			struct mtd_oob_ops ops;
+
+			ops.len = pagesize;
+			ops.ooblen = nand->oobsize;
+			ops.mode = MTD_OOB_AUTO;
+			ops.ooboffs = 0;
+
+			pages = write_size / pagesize_oob;
+			for (page = 0; page < pages; page++) {
+				WATCHDOG_RESET();
+
+				ops.datbuf = p_buffer;
+				ops.oobbuf = ops.datbuf + pagesize;
+
+				rval = nand->write_oob(nand, offset, &ops);
+				if (rval != 0)
+					break;
+
+				offset += pagesize;
+				p_buffer += pagesize_oob;
+			}
+		}
+		else
+#endif
+		{
+			rval = nand_write (nand, offset, &write_size, p_buffer);
+			offset += write_size;
+			p_buffer += write_size;
+		}
+
+		if (rval != 0) {
+			printf ("NAND write to offset %llx failed %d\n",
+				offset, rval);
+			*length -= left_to_write;
+			return rval;
+		}
+
+		left_to_write -= write_size;
+	}
+
+	return 0;
+}
+
+/**
+ * nand_read_skip_bad:
+ *
+ * Read image from NAND flash.
+ * Blocks that are marked bad are skipped and the next block is readen
+ * instead as long as the image is short enough to fit even after skipping the
+ * bad blocks.
+ *
+ * @param nand NAND device
+ * @param offset offset in flash
+ * @param length buffer length, on return holds remaining bytes to read
+ * @param buffer buffer to write to
+ * @return 0 in case of success
+ */
+
+int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
+		       u_char *buffer)
+{
+	int rval;
+	size_t left_to_read = *length;
+	u_char *p_buffer = buffer;
+	int need_skip;
+
+
+
+	if ((offset & (nand->writesize - 1)) != 0) {
+		printf ("Attempt to read non page aligned data\n");
+		*length = 0;
+		return -EINVAL;
+	}
+
+	need_skip = check_skip_len(nand, offset, *length);
+	if (need_skip < 0) {
+		printf ("Attempt to read outside the flash area\n");
+		*length = 0;
+		return -EINVAL;
+	}
+
+
+	if (!need_skip) {
+		rval = nand_read (nand, offset, length, buffer);
+
+		if (!rval || rval == -EUCLEAN) {
+
+
+            return 0;
+        }
+
+		*length = 0;
+		printf ("NAND read from offset %llx failed %d\n",
+			offset, rval);
+		return rval;
+	}
+
+	while (left_to_read > 0) {
+		size_t block_offset = offset & (nand->erasesize - 1);
+		size_t read_length;
+
+		WATCHDOG_RESET ();
+
+		if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
+			printf ("Skipping bad block 0x%08llx\n",
+                    offset & ~(nand->erasesize - 1));
+			offset += nand->erasesize - block_offset;
+			continue;
+            
+		}
+        
+		if (left_to_read < (nand->erasesize - block_offset))
+			read_length = left_to_read;
+		else
+			read_length = nand->erasesize - block_offset;
+
+
+		rval = nand_read (nand, offset, &read_length, p_buffer);
+        
+		if (rval && rval != -EUCLEAN) {
+			printf ("NAND read from offset %llx failed %d\n",
+                    offset, rval);
+			*length -= left_to_read;
+			return rval;
+		}
+        
+		left_to_read -= read_length;
+		offset       += read_length;
+		p_buffer     += read_length;
+	}
+    
+
+	return 0;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/cnc1900_spi.c u-boot-2011.06/drivers/mtd/spi/cnc1900_spi.c
--- u-boot-2011.06_original/drivers/mtd/spi/cnc1900_spi.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/cnc1900_spi.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,878 @@
+/**/
+#include <common.h>
+#include <command.h>
+#include "cnc1900_spi.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_CMD_SF)
+
+#define CONFIG_SPI_DMA_EN
+
+#define CFG_SPI_FREQ 180000000 
+
+#define MAX_RCV_SZ   0x1000
+#define DMA_RD_BAUD  0x10
+#define DMA_WR_BAUD  0x10
+#define IO_RD_BAUD   0x10
+#define IO_WR_BAUD   0x10
+
+#ifdef CONFIG_SPI_DMA_EN
+#define RD_BAUD DMA_RD_BAUD
+#define WR_BAUD DMA_WR_BAUD
+#else
+#define RD_BAUD IO_RD_BAUD
+#define WR_BAUD IO_WR_BAUD
+#endif
+
+
+unsigned char alen = 3;
+
+static void inline spin_wheel (void)
+{
+	static int p = 0;
+	static char w[] = "\\/-";
+
+	printf ("\010%c", w[p]);
+	(++p == 3) ? (p = 0) : 0;
+}
+
+void spi__init(void)
+{
+	unsigned int ctrl0 = 0;
+
+    /* enable spi pinmux */
+	spi_write(SPI_PINMUX, 0x1);
+
+	/* Disable the ssi by write 0 to SSIEN,tx and rx buffer was cleared */
+	spi_write(rSSIENR, 0x0);
+
+	/* Config the CTRLR0 register */
+    ctrl0 = 0x0 << 12  | /* CFS (Control Frame Size). 4bit length */
+        0x0 << 11  |     /* SRL 0:nomormod;1:test mode            */
+        0x0 << 10  |     /* SLV_OE                                */
+        0x0 << 8   |     /* TMOD master  TODO 0                   */
+        0x1 << 7   |     /* SCPOL clock inactive state            */
+        0x1 << 6   |     /* SCPH                                  */
+        0x0 << 4   |     /* frame format select  SPI              */
+        0x7 << 0;        /* DFS data frame size                   */
+
+	/*  rCTRLR0=0x2B00; receive and transmit enable */
+
+	spi_write(rCTRLR0, ctrl0);
+
+	/* ctrl1 */
+	spi_write(rCTRLR1, (MAX_RCV_SZ-1));
+
+	/* SSI_CLK baud out */
+	spi_write(rBAUDR, IO_WR_BAUD);
+
+	/* rSER, select the device */
+	spi_write(rSER, 0x1);
+
+	/* rSSIENR, enable the ssi bus */
+	spi_write(rSSIENR, 0x1);
+
+/*    alen = spi_read(BOOTCFG)>>5 & 0x3;*/
+}
+
+#if 0
+void spi_baud(unsigned short baud)
+{
+	spi_write(rSSIENR, 0x0);
+	spi_write(rBAUDR, baud);
+	spi_write(rSSIENR, 0x1);
+}
+
+static void master_set_mode(TMOD_E tmod, TIMING_E tm)
+{
+	unsigned short ctrl0 = spi_read(rCTRLR0);
+
+	ctrl0 &= ~(0xf<<6);
+	ctrl0 |= (tmod<<8 | tm<<6);
+
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, ctrl0);
+	spi_write(rSSIENR, 0x1);
+}
+static unsigned char master_check_mode(TMOD_E tmod, TIMING_E tm)
+{
+	unsigned short ctrl0 = spi_read(rCTRLR0);
+
+	if (ctrl0 & (tmod<<8 | tm<<6))
+		return 1;
+
+	return 0;
+}
+
+/*===================================================================
+ * 	flash oepration
+ */
+static inline void read_out_data(volatile unsigned char *buf, int size)
+{
+	int i = 0, j = 0;
+
+	while (i < size) {
+		while (!(j = spi_read(rRXFLR)));
+		while (j > 0) {
+			if (buf) buf[i] = spi_read(rDR);
+			else     spi_read(rDR);
+
+			i++; j--;
+		}
+	}
+}
+
+static inline unsigned char flash_status(void)
+{
+	unsigned char buf[2];
+
+	/* If check fail, return 0xff, also satisfy while's condition */
+	if (! master_check_mode(TMOD_TXRX, TIMING3))
+		return -1;
+
+	spi_write(rDR, CMD_RDSR); spi_write(rDR, 0x0);
+	read_out_data(buf, 2);
+/*    printf("status: %x\n", buf[1]);*/
+	return buf[1];
+}
+
+static void wait_for_finish(void)
+{
+	int tmp = 0;
+
+	while (flash_status() & 1) {
+		udelay(1000);
+		if (!(tmp % 100))
+			spin_wheel();
+		tmp++;
+	}
+}
+
+/* Only Used For Erase Read Write */
+static void flash_send_cmd(unsigned char cmd, unsigned int caddr)
+{
+	int i;
+	unsigned char *byte_addr = (unsigned char *) &caddr;
+
+	if (/*CMD_PP == cmd || */ CMD_SE == cmd ||
+	    CMD_BE == cmd || CMD_CE == cmd) {
+
+		master_set_mode(TMOD_TXRX, TIMING3);
+		if (CMD_CE == cmd) {
+			spi_write(rDR, cmd);
+			read_out_data(NULL, 1);
+		} else {
+			spi_write(rDR, cmd);
+			for (i = alen - 1; i >= 0; i--)
+				spi_write(rDR, byte_addr[i]);
+
+			/*if (CMD_PP != cmd)*/
+				read_out_data(NULL, alen+1);
+		}
+
+	} else if (CMD_WREN == cmd) {
+
+/*                master_set_mode(TMOD_TXRX, TIMING3);*/
+		master_set_mode(TMOD_TXRX, TIMING0);
+		spi_write(rDR, cmd);
+		read_out_data(NULL, 1);
+
+	} else if (CMD_PP == cmd) {
+
+		master_set_mode(TMOD_TX, TIMING3);
+		spi_write(rDR, cmd);
+		for (i = alen - 1; i >= 0; i--)
+			spi_write(rDR, byte_addr[i]);
+
+	} else if (CMD_READ == cmd || CMD_RDID == cmd) {
+
+		master_set_mode(TMOD_EE, TIMING3);
+		if (CMD_RDID == cmd) {
+			spi_write(rDR, cmd);
+		} else {
+			spi_write(rDR, cmd);
+			for (i = alen - 1; i >= 0; i--)
+				spi_write(rDR, byte_addr[i]);
+		}
+
+	} else {
+		printf("flash_send_cmd: Not Support this command!\n");
+	}
+
+	return;
+}
+#endif
+
+static inline void wait_for_finish(void)
+{
+	unsigned int status;
+
+	spi_write(rSSIENR,  0x0     );
+	spi_write(rCTRLR0,  0x3c7   );
+	spi_write(rCTRLR1,  0x0     );
+	spi_write(rSSIENR,  0x1     );
+
+	do {
+		spi_write(rDR,  CMD_RDSR);
+		while(spi_read(rRXFLR) != 1);
+		status = spi_read(rDR);
+/*        printf("status : %x\n", status);*/
+		//spin_wheel();
+	} while(status & 0x1);
+}
+
+static int _flash_read(unsigned int caddr, unsigned char *buf, int size)
+{
+	unsigned char *addr = (unsigned char *)&caddr;
+
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, 0x3c7);
+	spi_write(rCTRLR1, (MAX_RCV_SZ-1));
+	spi_write(rBAUDR,  IO_RD_BAUD);
+	spi_write(rSSIENR, 0x1);
+
+	spi_write(rDR, CMD_READ);
+	spi_write(rDR, addr[2]);
+	spi_write(rDR, addr[1]);
+	spi_write(rDR, addr[0]);
+
+	while (size > 0) {
+		if (size >= 16) {
+			while (spi_read(rRXFLR) < 16);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			size -= 16;
+		} else if (size >= 8) {
+			while (spi_read(rRXFLR) < 8);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			size -= 8;
+		} else if (size >= 4) {
+			while (spi_read(rRXFLR) < 4);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			size -= 4;
+		} else if (size >= 2) {
+			while (spi_read(rRXFLR) < 2);
+			*buf++ = spi_read(rDR);
+			*buf++ = spi_read(rDR);
+			size -= 2;
+		} else if (size > 0) {
+			while (spi_read(rRXFLR) == 0);
+			*buf++ = spi_read(rDR);
+			size -= 1;
+		}
+	}
+
+	while ((spi_read(rSR) & 0x5) != 0x4);
+	udelay (100);
+
+#if 0
+	if (spi_read(rSR) & (1<<5))
+		printf("Error   T error! 5 \n");
+
+	if (spi_read(rSR) & (1<<6))
+		printf("Error   T data error! 6 \n");
+#endif
+
+	return 0;
+}
+
+static int _flash_write(unsigned int caddr, volatile unsigned char *buf, int size)
+{
+	unsigned char *addr = (unsigned char *)&caddr;
+
+	/* Unprotect flash */
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, 0x107);
+	spi_write(rSSIENR, 0x1);
+	spi_write(rDR, CMD_WREN);
+	while ((spi_read(rSR) & 0x5) != 0x4);
+
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, 0x1c7);
+	spi_write(rBAUDR,  IO_WR_BAUD);
+	spi_write(rSSIENR, 0x1);
+
+	spi_write(rDR, CMD_PP);
+	spi_write(rDR, addr[2]);
+	spi_write(rDR, addr[1]);
+	spi_write(rDR, addr[0]);
+
+	while (size) {
+		if (size >= 16) {
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			while (spi_read(rTXFLR) > 8);
+			size -= 16;
+		} else if (size >= 8) {
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			while (spi_read(rTXFLR) > 8);
+			size -= 8;
+		} else if (size >= 4) {
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			while (spi_read(rTXFLR) > 8);
+			size -= 4;
+		} else if (size >= 2) {
+			spi_write(rDR, *buf++);
+			spi_write(rDR, *buf++);
+			while (spi_read(rTXFLR) > 8);
+			size -= 2;
+		} else if (size > 0) {
+			spi_write(rDR, *buf++);
+			while (spi_read(rTXFLR) > 8);
+			size -= 1;
+		}
+	}
+
+	while ((spi_read(rSR) & 0x5) != 0x4);
+
+	wait_for_finish();
+
+	return 0;
+}
+
+static int _flash_erase(unsigned int caddr, unsigned short cmd)
+{
+	unsigned char *addr = (unsigned char *)&caddr;
+
+	/* Unprotect flash */
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, 0x107);
+	spi_write(rSSIENR, 0x1);
+	spi_write(rDR, CMD_WREN);
+	while ((spi_read(rSR) & 0x5) != 0x4);
+
+	spi_write(rSSIENR, 0x0);
+	spi_write(rBAUDR, IO_WR_BAUD);
+	spi_write(rCTRLR0, 0x1c7);
+	spi_write(rSSIENR, 0x1);
+
+	spi_write(rDR, cmd);
+	spi_write(rDR, addr[2]);
+	spi_write(rDR, addr[1]);
+	spi_write(rDR, addr[0]);
+	while ((spi_read(rSR) & 0x5) != 0x4);
+
+	wait_for_finish();
+
+	return 0;
+}
+
+
+#define  WriteReg(a, v) 		(*(volatile unsigned int *)(a) = (v))
+#define  WriteReg8(a, v) 		(*(volatile unsigned char *)(a) = (v))
+#define  WriteReg32(a, v) 		(*(volatile unsigned int *)(a) = (v))
+#define  WriteReg16(a, v) 		(*(volatile unsigned short *)(a) = (v))
+
+#define  ReadReg(a) 			(*(volatile unsigned int *)(a))
+#define  ReadReg8(a) 			(*(volatile unsigned char *)(a))
+#define  ReadReg16(a) 			(*(volatile unsigned short *)(a))
+#define  ReadReg32(a) 			(*(volatile unsigned int *)(a))
+
+enum {
+    SPI_CTRLR0      = 0x80150000,
+    SPI_CTRLR1      = 0x80150004,
+    SPI_SSIENR      = 0x80150008,
+    SPI_SER         = 0x80150010,
+    SPI_BAUDR       = 0x80150014,
+    SPI_TXFLR       = 0x80150020,
+    SPI_RXFLR       = 0x80150024,
+    SPI_SR          = 0x80150028,
+    SPI_IMR         = 0x8015002c,
+    SPI_DMACR       = 0x8015004c,
+    SPI_DMATDLR     = 0x80150050,
+    SPI_DMARDLR     = 0x80150054,
+    SPI_DR          = 0x80150060,
+
+    PINMUX_SPI      = 0xB211000c,
+
+    SAR0            = 0x80154000,
+    DAR0            = 0x80154008,
+    LLP0            = 0x80154010,
+    CTL0            = 0x80154018,
+    SSTAT0          = 0x80154020,
+    DSTAT0          = 0x80154028,
+    SSTATAR0        = 0x80154030,
+    DSTATAR0        = 0x80154038,
+    CFG0            = 0x80154040,
+    SGR0            = 0x80154048,
+    DSR0            = 0x80154050,
+
+	RawTfr			= 0x801542c0,
+	RawBlock		= 0x801542c8,
+	RawDstTran		= 0x801542d0,
+	RawSrcTran		= 0x801542d8,
+	RawErr			= 0x801542e0,
+
+	StatusTfr		= 0x801542e8,
+	StatusBlock		= 0x801542f0,
+	StatusSrcTran	= 0x801540f8,
+	StatusDstTran	= 0x80154300,
+	StatusErr		= 0x80154308,
+
+	StatusInt		= 0x80154360,
+
+    MASK_TFR        = 0x80154310,
+    CLEAR_TFR       = 0x80154338,
+    CHEN            = 0x801543a0,
+    DMACFG          = 0x80154398,
+    MaskTfr         = 0x80154310,
+    ClearTfr        = 0x80154338
+};
+
+#if defined(CONFIG_SPI_DMA_EN)
+
+static inline void SetupDMA_LLP_SG_RX(const u32 caddr, u32 maddr, u32 size)
+{
+    unsigned int llp = CONFIG_SPI_DMA_BUF_BASE;
+    unsigned int ctl_lo =  0   /* CTL[31:0]                    */
+              | ( 0x1  << 28)  /* LLP_SRC_EN                   */
+              | ( 0x1  << 27)  /* LLP_DST_EN                   */
+              | ( 0x0  << 25)  /* SRC Master                   */
+              | ( 0x1  << 23)  /* DST Master                   */
+              | ( 0x2  << 20)  /* P -> M, M as flow controller */
+              | ( 0x0  << 18)  /* DSCATTER_EN                  */
+              | ( 0x0  << 17)  /* SGATHER_EN                   */
+              | ( 0x1  << 14)  /* SMSIZE:  4 * 1B              */
+              | ( 0x3  << 11)  /* DMSIZE: 16 * 4B              */
+              | ( 0x2  <<  9)  /* SINC: no change              */
+              | ( 0x0  <<  7)  /* DINC: increment              */
+              | ( 0x0  <<  4)  /* SRC_TR_WIDTH:  8b            */
+              | ( 0x2  <<  1)  /* DST_TR_WIDTH: 32b            */
+              | ( 0x0  <<  0); /* INT_EN                       */
+
+
+    /* 4B align */
+    if (size & 0x3) {
+        printf("%s: size not 4B align!\n", __func__);
+        return;
+    }
+
+    /* Controller init */
+    WriteReg16(SPI_SSIENR , 0x0              );
+    WriteReg16(SPI_CTRLR0 , 0x3c7            );
+    WriteReg16(SPI_CTRLR1 , (size-1)         );
+    WriteReg16(SPI_BAUDR  , DMA_RD_BAUD          );
+    WriteReg16(SPI_DMARDLR, 3                ); /* When 4bytes got, send to DMA controller immediately */
+    WriteReg16(SPI_DMACR  , 0x1              ); /* Receive FIFO DMA request enabled */
+    WriteReg16(SPI_SSIENR , 0x1              );
+
+    /* DMA enable */
+    WriteReg(DMACFG,    0x1                  ); /* Gloabl Enable */
+
+    WriteReg(llp +  0, SPI_DR                ); /* SAR           */
+    WriteReg(llp +  4, maddr                 ); /* DAR           */
+    WriteReg(llp +  8, (llp + 32) | 0x1      ); /* Next LLP from previous llp */
+    WriteReg(llp + 12, ctl_lo                );
+    WriteReg(llp + 16, (size>2048)?2048:size );
+
+    if (size > 2048) {
+    WriteReg(llp + 32, SPI_DR                ); /* SAR      */
+    WriteReg(llp + 36, maddr+2048            ); /* DAR      */
+    WriteReg(llp + 40, 0                     ); /* Next LLP */
+    WriteReg(llp + 44, ctl_lo                );
+    WriteReg(llp + 48, size-2048             );
+    } else
+    WriteReg(llp + 8, 0                      );
+
+#if 0
+	{
+		int i;
+		for (i = 0; i <= 48; i+=4) {
+			printf("%d: -------------- 0x%x\n",i, ReadReg(llp+i));
+		}
+		printf("\n");
+		printf("\n");
+	}
+#endif
+
+    WriteReg(CTL0,      0x3 << 27            ); /* LLP_SRC_EN/LLP_DST_EN                           */
+    WriteReg(CFG0 + 4,  0x1 <<  7            ); /* use RX handshaking signals for source periphral */
+    WriteReg(CFG0,      0x1 << 10            ); /* HS_SEL_DST = 0 (HW), HS_SEL_DST = 1 (SW)        */
+    WriteReg(LLP0,      llp | 0x1            ); /* LMS = 1, external DRAM                          */
+    WriteReg(CHEN,      (0x1 << 8) | 0x1     ); /* Enable the only channel                         */
+
+    WriteReg(ClearTfr,  0x1                  );
+    WriteReg(MaskTfr,   (0x1 << 8) | 0x1     );
+
+    /* Send Read command */
+    WriteReg16(SPI_SSIENR , 0x3              );
+    WriteReg16(SPI_DR, CMD_READ           );
+    WriteReg16(SPI_DR, (caddr>>16) & 0xff );
+    WriteReg16(SPI_DR, (caddr>>8)  & 0xff );
+    WriteReg16(SPI_DR, (caddr)     & 0xff );
+    WriteReg16(SPI_SSIENR , 0x1              );
+
+    /* Wait dma finished  */
+    while (ReadReg(CHEN));
+}
+
+static inline void SetupDMA_LLP_SG_TX(u32 caddr, const u32 maddr, u32 size)
+{
+    unsigned int llp = CONFIG_SPI_DMA_BUF_BASE;
+    unsigned int ctl_lo =  0     /* CTL[31:0]                    */
+                | ( 0x1  << 28)  /* LLP_SRC_EN                   */
+                | ( 0x1  << 27)  /* LLP_DST_EN                   */
+                | ( 0x1  << 25)  /* SRC Master                   */
+                | ( 0x0  << 23)  /* DST Master                   */
+                | ( 0x1  << 20)  /* M -> P, M as flow controller */
+                | ( 0x0  << 18)  /* DSCATTER_EN                  */
+                | ( 0x0  << 17)  /* SGATHER_EN                   */
+                | ( 0x3  << 14)  /* SMSIZE: 16 * 4B              */
+                | ( 0x1  << 11)  /* DMSIZE:  4 * 1B              */
+                | ( 0x0  <<  9)  /* SINC: increment              */
+                | ( 0x2  <<  7)  /* DINC: no charge              */
+                | ( 0x2  <<  4)  /* SRC_TR_WIDTH: 32b            */
+                | ( 0x0  <<  1)  /* DST_TR_WIDTH:  8b            */
+                | ( 0x1  <<  0); /* INT_EN                       */
+
+    /* 4 Byte align */
+    if (size & 0x3) {
+        printf("%s: size not 4B align!\n", __func__);
+        return;
+    }
+
+    /* Unprotect flash */
+    spi_write(rSSIENR, 0x0               );
+    spi_write(rCTRLR0, 0x107             );
+    spi_write(rSSIENR, 0x1               );
+    spi_write(rDR    , CMD_WREN          );
+    while ((spi_read(rSR) & 0x5) != 0x4  );
+
+    /* Init Controller */
+    WriteReg16(SPI_SSIENR , 0x0          );
+    WriteReg16(SPI_BAUDR  , DMA_WR_BAUD      );
+    WriteReg16(SPI_CTRLR0 , 0x1c7        ); /* Transmit Only                                                */
+    WriteReg16(SPI_DMATDLR, 16           ); /* When FIFO half full, receive from DMA controller immediately */
+    WriteReg16(SPI_DMACR  , 0x2          ); /* Transmit FIFO DMA request enabled                            */
+    WriteReg16(SPI_SSIENR , 0x1          );
+
+    /* Enable DMA */
+    WriteReg(DMACFG,    0x1              ); /* Gloabl Enable                                   */
+
+    WriteReg(llp +  0, maddr             ); /* SAR                                             */
+    WriteReg(llp +  4, SPI_DR            ); /* DAR                                             */
+    WriteReg(llp +  8, 0                 ); /* Next LLP                                        */
+    WriteReg(llp + 12, ctl_lo            );
+    WriteReg(llp + 16, (size + 4) / 4    ); /* 256B data + 4B command                          */
+
+    WriteReg(CTL0,      0x3 << 27        ); /* LLP_SRC_EN/LLP_DST_EN                           */
+    WriteReg(CFG0 + 4,  0x0 <<  7        ); /* use TX handshaking signals for source periphral */
+    WriteReg(CFG0,      0x2 << 10        ); /* HS_SEL_DST = 0 (HW), HS_SEL_DST = 1 (SW)        */
+    WriteReg(LLP0,      llp | 0x1        ); /* LMS = 1, external DRAM                          */
+    WriteReg(CHEN,      (0x1 << 8) | 0x1 ); /* Enable the only channel                         */
+
+    WriteReg(ClearTfr,  0x1              );
+    WriteReg(MaskTfr,   (0x1 << 8) | 0x1 );
+
+    /* Wait dma finish  */
+    while (ReadReg(CHEN));
+    /* Wait spi transfer finish  */
+    while((ReadReg16(SPI_SR) & 0x5) != 0x4);
+    /* Wait flash program finish */
+    wait_for_finish();
+}
+
+
+#if 0
+int do_sflashre_dma(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unsigned char *maddr;
+	unsigned int caddr;
+	unsigned int size;
+
+	if (argc != 4) {
+		printf("Usage: %s\n", cmdtp->help);
+		return -1;
+	}
+
+	maddr = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
+	caddr = simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	printf("caddr: 0x%x, maddr: 0x%x, size: 0x%x\n",
+	      caddr, maddr, size);
+
+	seeprom_read(caddr, maddr, size);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sfdre,	CFG_MAXARGS/*5*/,	0,	do_sflashre_dma,
+	"sfre    - spi flash read byte.\n",
+	"\nsfre <maddr> <offset> <len>\n"
+	);
+#endif
+
+#endif /* CONFIG_SPI_DMA */
+
+/*--------------------------------------------------------------------------------*/
+
+int seeprom_read(unsigned caddr, uchar *maddr, unsigned size)
+{
+	unsigned cnt;
+
+    /* Make sure 4B align */
+    if (size & 0x3)
+        size = ((size + 4) >> 2) << 2;
+
+	while (size > 0) {
+		cnt = (size >= MAX_RCV_SZ) ? MAX_RCV_SZ : size;
+
+#if defined(CONFIG_SPI_DMA_EN)
+		/* DMA controller */
+		SetupDMA_LLP_SG_RX((u32)caddr, (u32)maddr, cnt );
+#else
+		_flash_read(caddr, maddr, cnt);
+#endif
+
+		caddr += cnt;
+		maddr += cnt;
+		size  -= cnt;
+	}
+
+    /* fix dma bug, reload with 4byte offset */
+    WriteReg16(SPI_SSIENR , 0x0 );
+    WriteReg16(SPI_DMARDLR, 0x0 );
+    WriteReg16(SPI_DMACR  , 0x0 );
+    WriteReg16(SPI_SSIENR , 0x1 );
+
+	return 0;
+}
+
+int seeprom_write(unsigned caddr, uchar *maddr, unsigned size)
+{
+	unsigned cnt;
+#if defined(CONFIG_SPI_DMA_EN)
+	unsigned int v_bak;
+#endif
+
+	printf("Page Write from 0x%x to 0x%x ...  ", (unsigned int)maddr, caddr);
+
+	while (size > 0) {
+		cnt = (size >= PP_SZ) ? PP_SZ : size;
+
+#if defined(CONFIG_SPI_DMA_EN)
+        /* Backup Address */
+		v_bak = *(unsigned int *)(maddr - 4);
+
+        /* Initialize Write Command */
+        WriteReg8((maddr-4),  CMD_PP           );
+        WriteReg8((maddr-3),  (caddr>>16)&0xff );
+        WriteReg8((maddr-2),  (caddr>>8)&0xff  );
+        WriteReg8((maddr-1),  (caddr)&0xff     );
+
+        if (cnt % 0x3)
+            _flash_write(caddr, maddr, cnt);
+        else
+            SetupDMA_LLP_SG_TX((u32)caddr, (u32)(maddr-4), cnt);
+
+        /* Restore Address */
+		*(unsigned int *)(maddr - 4) = v_bak;
+#else
+		_flash_write(caddr, maddr, cnt);
+#endif
+
+		caddr += cnt;
+		maddr += cnt;
+		size  -= cnt;
+	}
+	printf(" ok!\n");
+
+	return 0;
+}
+
+int seeprom_erase(unsigned cmd, unsigned saddr, unsigned size)
+{
+	unsigned eaddr;
+	unsigned sector_size = gd->sf_inf->sector_size;
+
+	eaddr = saddr + size;
+	if (eaddr > gd->sf_size)
+		eaddr = gd->sf_size;
+
+	switch (cmd) {
+		case CMD_CE: /* chip */
+			printf("Chip Erase ...  ");
+			_flash_erase(saddr, cmd);
+			break;
+
+		case CMD_BE: /* block */
+			printf("Block Erase from 0x%x to 0x%x ...  ", saddr, eaddr);
+			if (gd->sf_inf->jedec_id == 0x1c2017)
+				if (saddr < 0x10000) {
+					_flash_erase(0x0000, cmd);
+					_flash_erase(0x1000, cmd);
+					_flash_erase(0x2000, cmd);
+					_flash_erase(0x4000, cmd);
+					_flash_erase(0x8000, cmd);
+
+					if (eaddr >= 0x10000)
+						saddr = 0x10000;
+				}
+
+			while (saddr < eaddr) {
+				_flash_erase(saddr, cmd);
+				saddr+=sector_size;
+			}
+			break;
+
+		case CMD_SE:	/* sector */
+			printf("Sector Erase from 0x%x to 0x%x ...  ", saddr, eaddr);
+			while (saddr < eaddr) {
+				_flash_erase(saddr, cmd);
+				saddr+=0x1000;
+			}
+			break;
+
+		default:
+			printf("Error! No such chioce.\n");
+			return -1;
+	}
+	printf(" ok!\n");
+
+	return 0;
+}
+
+static sfinf_t sflash_data [] = {
+	/* Winbond */
+	{ "W25D80", 0xef3014, 0, 4 * 1024, 256},
+	{ "W25D16", 0xef3015, 0, 4 * 1024, 512},
+	{ "W25D32", 0xef3016, 0, 4 * 1024, 1024},
+	{ "W25D64", 0xef3017, 0, 4 * 1024, 2048},
+	{ "W25Q80", 0xef4014, 0, 4 * 1024, 256},
+	{ "W25Q16", 0xef4015, 0, 4 * 1024, 512},
+	{ "W25Q32", 0xef4016, 0, 4 * 1024, 1024},
+	{ "W25Q64", 0xef4017, 0, 4 * 1024, 2048},
+	{ "W25Q128", 0xef4018, 0, 4 * 1024, 4096},
+	{ "W25Q64DW", 0xef6017, 0, 4 * 1024, 2048},
+	/* Macronix */
+	{ "MX25L4006E", 0xc22013, 0, 4 * 1024, 128},
+	{ "MX25L8006E", 0xc22014, 0, 4 * 1024, 256},
+	{ "MX25L1605D", 0xc22015, 0, 4 * 1024, 512},
+	{ "MX25L3205D", 0xc22016, 0, 4 * 1024, 1024},
+	{ "MX25L6405D/6406E", 0xc22017, 0, 4 * 1024, 2048},
+	{ "MX25L12805D", 0xc22018, 0, 4 * 1024, 4096},
+	{ "MX25L12855E", 0xc22618, 0, 4 * 1024, 4095},
+	{ "MX25L512E", 0xc22010, 0, 4 * 1024, 16},
+	/* Giga Devices */
+	{ "GD25Q512", 0xc84010, 0, 4 * 1024, 16,},
+	{ "GD25Q80",  0xc84014, 0, 4 * 1024, 256,},
+	{ "GD25Q64",  0xc84017, 0, 4 * 1024, 2048,},
+};
+
+static void get_manufacture_id(unsigned char *buf, int size)
+{
+	spi_write(rSSIENR, 0x0);
+	spi_write(rCTRLR0, 0x3c7);
+	spi_write(rCTRLR1, 0x4);
+	spi_write(rSSIENR, 0x1);
+
+	spi_write(rDR, CMD_RDID);
+	while (spi_read(rRXFLR) < 5);
+
+	*buf++ = spi_read(rDR);
+	*buf++ = spi_read(rDR);
+	*buf++ = spi_read(rDR);
+	*buf++ = spi_read(rDR);
+	*buf++ = spi_read(rDR);
+}
+
+int seeprom_probe(void)
+{
+	int			tmp;
+	u8			id[5];
+	u32			jedec;
+	u16                     ext_jedec;
+	struct sflash_info	*info;
+
+	get_manufacture_id(id, 5);
+	jedec = id[0];
+	jedec = jedec << 8;
+	jedec |= id[1];
+	jedec = jedec << 8;
+	jedec |= id[2];
+
+	ext_jedec = id[3] << 8 | id[4];
+
+	for (tmp = 0, info = sflash_data;
+			tmp < ARRAY_SIZE(sflash_data);
+			tmp++, info++) {
+		if (info->jedec_id == jedec) {
+			if (info->ext_id != 0 && info->ext_id != ext_jedec)
+				continue;
+			goto found;
+		}
+	}
+
+	printf("SPI Probe Fail! No Such Devices! --- jedec id: 0x%08x\n", jedec);
+
+	return 0;
+
+found:
+	gd->sf_inf = info;
+	gd->sf_alen = alen;
+	if ((spi_read(BOOTCFG) & 0x1) &&
+	    (spi_read(BOOTCFG) & 0x10))
+		gd->sf_boot = 1;
+	else 	gd->sf_boot = 0;
+
+	gd->sf_rspd = CFG_SPI_FREQ/1000000/RD_BAUD;
+	gd->sf_wspd = CFG_SPI_FREQ/1000000/WR_BAUD;
+    //printf("RD_BAUD=%d, WR_BAUD=%d, gd-sf_rspd=%d", RD_BAUD, WR_BAUD,gd->sf_rspd);
+	gd->sf_size  = info->sector_size * info->n_sectors;
+
+	return 1;
+}
+
+#endif //(CONFIG_COMMANDS & CFG_CMD_SPI)
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/gigadevice.c u-boot-2011.06/drivers/mtd/spi/gigadevice.c
--- u-boot-2011.06_original/drivers/mtd/spi/gigadevice.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/gigadevice.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2008, Network Appliance Inc.
+ * Author: Jason McMullan <mcmullan <at> netapp.com>
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi_flash.h>
+
+#include "spi_flash_internal.h"
+
+/* M25Pxx-specific commands */
+#define CMD_W25_WREN		0x06	/* Write Enable */
+#define CMD_W25_WRDI		0x04	/* Write Disable */
+#define CMD_W25_RDSR		0x05	/* Read Status Register */
+#define CMD_W25_WRSR		0x01	/* Write Status Register */
+#define CMD_W25_READ		0x03	/* Read Data Bytes */
+#define CMD_W25_FAST_READ	0x0b	/* Read Data Bytes at Higher Speed */
+#define CMD_W25_PP		0x02	/* Page Program */
+#define CMD_W25_SE		0x20	/* Sector (4K) Erase */
+#define CMD_W25_BE		0xd8	/* Block (64K) Erase */
+#define CMD_W25_CE		0xc7	/* Chip Erase */
+#define CMD_W25_DP		0xb9	/* Deep Power-down */
+#define CMD_W25_RES		0xab	/* Release from DP, and Read Signature */
+
+struct gigadevice_spi_flash_params {
+	uint16_t	id;
+	/* Log2 of page size in power-of-two mode */
+	uint8_t		l2_page_size;
+	uint16_t	pages_per_sector;
+	uint16_t	sectors_per_block;
+	uint16_t	nr_blocks;
+	const char	*name;
+};
+
+/* spi_flash needs to be first so upper layers can free() it */
+struct gigadevice_spi_flash {
+	struct spi_flash flash;
+	const struct gigadevice_spi_flash_params *params;
+};
+
+static inline struct gigadevice_spi_flash *
+to_gigadevice_spi_flash(struct spi_flash *flash)
+{
+	return container_of(flash, struct gigadevice_spi_flash, flash);
+}
+
+static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
+	{
+		.id			= 0x4014,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 16,
+		.name			= "GD25Q80",
+	},
+	{
+		.id			= 0x4015,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 32,
+		.name			= "GD25Q16",
+	},
+	{
+		.id			= 0x4016,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 64,
+		.name			= "GD25Q32",
+	},
+	{
+		.id			= 0x4017,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 128,
+		.name			= "GD25Q64",
+	},
+	{
+		.id			= 0x4018,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 256,
+		.name			= "GD25Q128",
+	},
+};
+
+static int gigadevice_write(struct spi_flash *flash,
+		u32 offset, size_t len, const void *buf)
+{
+	struct gigadevice_spi_flash *stm = to_gigadevice_spi_flash(flash);
+	unsigned long page_addr;
+	unsigned long byte_addr;
+	unsigned long page_size;
+	unsigned int page_shift;
+	size_t chunk_len;
+	size_t actual;
+	int ret;
+	u8 cmd[4];
+
+	page_shift = stm->params->l2_page_size;
+	page_size = (1 << page_shift);
+	page_addr = offset / page_size;
+	byte_addr = offset % page_size;
+
+	ret = spi_claim_bus(flash->spi);
+	if (ret) {
+		debug("SF: Unable to claim SPI bus\n");
+		return ret;
+	}
+
+	for (actual = 0; actual < len; actual += chunk_len) {
+		chunk_len = min(len - actual, page_size - byte_addr);
+
+		cmd[0] = CMD_W25_PP;
+		cmd[1] = page_addr >> (16 - page_shift);
+		cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
+		cmd[3] = byte_addr;
+		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
+			buf + actual,
+			cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+
+		ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
+		if (ret < 0) {
+			debug("SF: Enabling Write failed\n");
+			goto out;
+		}
+
+		ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+				buf + actual, chunk_len);
+		if (ret < 0) {
+			debug("SF: GD Page Program failed\n");
+			goto out;
+		}
+
+		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+		if (ret)
+			goto out;
+
+		page_addr++;
+		byte_addr = 0;
+	}
+
+	debug("SF: GD: Successfully programmed %u bytes @ 0x%x\n",
+			len, offset);
+	ret = 0;
+
+out:
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
+static int gigadevice_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+	return spi_flash_cmd_erase(flash, CMD_W25_SE, offset, len);
+}
+
+struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode)
+{
+	const struct gigadevice_spi_flash_params *params;
+	unsigned page_size;
+	struct gigadevice_spi_flash *stm;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gigadevice_spi_flash_table); i++) {
+		params = &gigadevice_spi_flash_table[i];
+		if (params->id == ((idcode[1] << 8) | idcode[2]))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(gigadevice_spi_flash_table)) {
+		debug("SF: Unsupported GigaDevice ID %02x%02x\n",
+				idcode[1], idcode[2]);
+		return NULL;
+	}
+
+	stm = malloc(sizeof(struct gigadevice_spi_flash));
+	if (!stm) {
+		debug("SF: Failed to allocate memory\n");
+		return NULL;
+	}
+
+	stm->params = params;
+	stm->flash.spi = spi;
+	stm->flash.name = params->name;
+
+	/* Assuming power-of-two page size initially. */
+	page_size = 1 << params->l2_page_size;
+
+	stm->flash.write = gigadevice_write;
+	stm->flash.erase = gigadevice_erase;
+	stm->flash.read = spi_flash_cmd_read_fast;
+	stm->flash.sector_size = (1 << stm->params->l2_page_size) *
+		stm->params->pages_per_sector;
+	stm->flash.size = page_size * params->pages_per_sector
+				* params->sectors_per_block
+				* params->nr_blocks;
+
+	return &stm->flash;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/macronix.c u-boot-2011.06/drivers/mtd/spi/macronix.c
--- u-boot-2011.06_original/drivers/mtd/spi/macronix.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/macronix.c	2015-09-18 12:03:14.952265000 +0800
@@ -71,6 +71,30 @@
 
 static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
 	{
+		.idcode = 0x2012,
+		.page_size = 256,
+		.pages_per_sector = 16,
+		.sectors_per_block = 16,
+		.nr_blocks = 4, 
+		.name = "MX25L2006E",
+	},
+	{
+		.idcode = 0x2013,
+		.page_size = 256,
+		.pages_per_sector = 16,
+		.sectors_per_block = 16,
+		.nr_blocks = 8,
+		.name = "MX25L4006E",
+	},
+	{
+		.idcode = 0x2014,
+		.page_size = 256,
+		.pages_per_sector = 16,
+		.sectors_per_block = 16,
+		.nr_blocks = 16,
+		.name = "MX25L8006E",
+	},
+	{
 		.idcode = 0x2015,
 		.page_size = 256,
 		.pages_per_sector = 16,
@@ -87,6 +111,14 @@
 		.name = "MX25L3205D",
 	},
 	{
+		.idcode = 0x9e16,
+		.page_size = 256,
+		.pages_per_sector = 16,
+		.sectors_per_block = 16,
+		.nr_blocks = 64,
+		.name = "MX25L3255E",
+	},
+{
 		.idcode = 0x2017,
 		.page_size = 256,
 		.pages_per_sector = 16,
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/Makefile u-boot-2011.06/drivers/mtd/spi/Makefile
--- u-boot-2011.06_original/drivers/mtd/spi/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -25,14 +25,16 @@
 
 LIB	:= $(obj)libspi_flash.o
 
-COBJS-$(CONFIG_SPI_FLASH)	+= spi_flash.o
-COBJS-$(CONFIG_SPI_FLASH_ATMEL)	+= atmel.o
-COBJS-$(CONFIG_SPI_FLASH_EON)	+= eon.o
+COBJS-$(CONFIG_SPI_FLASH)		+= spi_flash.o
+COBJS-$(CONFIG_SPI_FLASH_CNC1900)	+= cnc1900_spi.o
+COBJS-$(CONFIG_SPI_FLASH_ATMEL)		+= atmel.o
+COBJS-$(CONFIG_SPI_FLASH_EON)		+= eon.o
 COBJS-$(CONFIG_SPI_FLASH_MACRONIX)	+= macronix.o
 COBJS-$(CONFIG_SPI_FLASH_SPANSION)	+= spansion.o
-COBJS-$(CONFIG_SPI_FLASH_SST)	+= sst.o
+COBJS-$(CONFIG_SPI_FLASH_SST)		+= sst.o
 COBJS-$(CONFIG_SPI_FLASH_STMICRO)	+= stmicro.o
 COBJS-$(CONFIG_SPI_FLASH_WINBOND)	+= winbond.o
+COBJS-$(CONFIG_SPI_FLASH_GIGADEVICE)+= gigadevice.o
 COBJS-$(CONFIG_SPI_FRAM_RAMTRON)	+= ramtron.o
 COBJS-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/spi_flash.c u-boot-2011.06/drivers/mtd/spi/spi_flash.c
--- u-boot-2011.06_original/drivers/mtd/spi/spi_flash.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/spi_flash.c	2014-07-29 17:28:38.819972000 +0800
@@ -6,7 +6,6 @@
  *
  * Licensed under the GPL-2 or later.
  */
-
 #include <common.h>
 #include <malloc.h>
 #include <spi.h>
@@ -36,13 +35,14 @@
 
 	ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
 	if (ret) {
-		debug("SF: Failed to send command (%zu bytes): %d\n",
+		printf("SF: Failed to send command (%zu bytes): %d\n",
 				cmd_len, ret);
 	} else if (data_len != 0) {
 		ret = spi_xfer(spi, data_len * 8, data_out, data_in, SPI_XFER_END);
-		if (ret)
-			debug("SF: Failed to transfer %zu bytes of data: %d\n",
+		if (ret){
+			printf("SF: Failed to transfer %zu bytes of data: %d\n",
 					data_len, ret);
+		}
 	}
 
 	return ret;
@@ -141,14 +141,15 @@
 	u8 cmd[4];
 
 	erase_size = flash->sector_size;
+	debug("flash->sector_size = %d\n",flash->sector_size);
 	if (offset % erase_size || len % erase_size) {
-		debug("SF: Erase offset/length not multiple of erase size\n");
+		printf("SF: Erase offset/length not multiple of erase size\n");
 		return -1;
 	}
 
 	ret = spi_claim_bus(flash->spi);
 	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
+		printf("SF: Unable to claim SPI bus\n");
 		return ret;
 	}
 
@@ -175,9 +176,8 @@
 		if (ret)
 			goto out;
 	}
-
-	debug("SF: Successfully erased %lu bytes @ %#x\n",
-	      len * erase_size, start);
+	printf("SF: Successfully erased %lu bytes @ %#x\n",
+	      (long unsigned int)len, start);
 
  out:
 	spi_release_bus(flash->spi);
@@ -235,6 +235,9 @@
 #ifdef CONFIG_SPI_FLASH_WINBOND
 	{ 0, 0xef, spi_flash_probe_winbond, },
 #endif
+#ifdef CONFIG_SPI_FLASH_GIGADEVICE
+	{ 0, 0xc8, spi_flash_probe_gigadevice, },
+#endif
 #ifdef CONFIG_SPI_FRAM_RAMTRON
 	{ 6, 0xc2, spi_fram_probe_ramtron, },
 # undef IDCODE_CONT_LEN
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/spi_flash_internal.h u-boot-2011.06/drivers/mtd/spi/spi_flash_internal.h
--- u-boot-2011.06_original/drivers/mtd/spi/spi_flash_internal.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/spi_flash_internal.h	2014-07-29 17:28:38.819972000 +0800
@@ -74,4 +74,6 @@
 struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
+struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/mtd/spi/winbond.c u-boot-2011.06/drivers/mtd/spi/winbond.c
--- u-boot-2011.06_original/drivers/mtd/spi/winbond.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/mtd/spi/winbond.c	2014-07-29 17:28:38.819972000 +0800
@@ -48,6 +48,14 @@
 
 static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
 	{
+		.id			= 0x3014,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 16,
+		.name			= "W25X80",
+	},
+	{
 		.id			= 0x3015,
 		.l2_page_size		= 8,
 		.pages_per_sector	= 16,
@@ -72,6 +80,14 @@
 		.name			= "W25X64",
 	},
 	{
+		.id			= 0x4014,
+		.l2_page_size		= 8,
+		.pages_per_sector	= 16,
+		.sectors_per_block	= 16,
+		.nr_blocks		= 16,
+		.name			= "W25Q80",
+	},
+	{
 		.id			= 0x4015,
 		.l2_page_size		= 8,
 		.pages_per_sector	= 16,
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/net/cn100.c u-boot-2011.06/drivers/net/cn100.c
--- u-boot-2011.06_original/drivers/net/cn100.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/net/cn100.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,542 @@
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h> 
+#include <malloc.h>
+#include "cn100.h"
+
+#undef CONFIG_CN100_DEBUG
+
+//#define CONFIG_CN100_DEBUG
+#ifdef CONFIG_CN100_DEBUG
+#define CN100_DBG(fmt,args...) printf(fmt ,##args)
+#else
+#define CN100_DBG(fmt,args...)
+#endif
+
+/* Structure/enum declaration ------------------------------- */
+#define SWAP(x) ( ( ( x >> 24 ) & 0xFF ) | ( ( x >> 8 ) & 0xFF00 ) | ( ( x << 8 ) & 0xFF0000 ) | ( ( x << 24 ) & 0xFF000000 ) )
+
+//#define CONFIG_CN100_DATA_BASE	0x07C00000
+
+#define RX_BUFFER_ITEM_SIZE 		1600
+#define RX_BUFFER_ITEM_NUM 		   	256	
+#define TX_BUFFER_NOD_LEN			( 64 )
+#define TX_BUFFER_DATA_LEN			( 2048 )
+#define TX_BUFFER_LEN				( TX_BUFFER_NOD_LEN +  TX_BUFFER_DATA_LEN )
+#define RX_BUFFER_LEN				( RX_BUFFER_ITEM_SIZE * RX_BUFFER_ITEM_NUM )
+
+
+typedef struct
+{
+	u32 buffer_addr;
+	u32 buffer_len;
+	u32 next_link_item;
+	u32 next_item_valid_flag;
+} tx_buffer_f;
+
+
+typedef struct 
+{
+	u32 rx_buffer_addr[RX_BUFFER_ITEM_NUM];
+	u32 buffer_num;
+} rx_buffer_f;
+
+typedef struct
+{
+	u32 index;
+	u32 shift;
+	u32 ctl_offset;
+	u32 mac_offset;
+
+	unsigned char *tx_buffer;
+	unsigned char *rx_buffer;
+	unsigned char rx_buffer_x[RX_BUFFER_ITEM_SIZE];
+
+	rx_buffer_f rx_buffer_list;
+	tx_buffer_f *tx_buffer_nod;
+
+} cn100_priv;
+
+
+
+int cn100_initialize ( bd_t * bd, int index);
+int cn100_init(struct eth_device *dev, bd_t * bd);
+int cn100_send(struct eth_device *dev, volatile void *, int);
+int cn100_recv(struct eth_device *dev);
+void cn100_halt(struct eth_device *dev);
+int cn100_write_hwaddr (struct eth_device* dev);
+
+static int 	init_eth_hw 	(cn100_priv *priv);
+static int 	release_eth_hw (cn100_priv *priv);
+static int 	init_phy_hw 	(cn100_priv *priv);
+static int 	release_phy_hw (cn100_priv *priv);
+static void set_tx_int 		(cn100_priv *priv, int enable );
+static void set_rx_enable 	(cn100_priv *priv, int enable );
+static void set_rx_int 		(cn100_priv *priv, int enable );
+static int 	set_tx_buffer 	(cn100_priv *priv);
+static int 	set_rx_buffer 	(cn100_priv *priv);
+static void set_hw_clock 	(cn100_priv *priv);
+static int 	set_mac_addr 	(cn100_priv *priv, u8 mac_addr[6] );
+static void cn100_reset		(cn100_priv *priv);
+
+
+#define CN100_outl(r,d) 	( *(volatile u32 *)((r) + CONFIG_CN100_BASEADDRESS) = d )
+#define CN100_inl(r) 		(*(volatile u32 *)((r) + CONFIG_CN100_BASEADDRESS))
+
+#ifdef CONFIG_CN100_DEBUG
+static void cn100_dump_regs(cn100_priv *priv)
+{
+	CN100_DBG("\n");
+	CN100_DBG ( "ETH_CFG_ADDR:			0x%08x\n", CN100_inl(ETH_CFG_ADDR));
+	CN100_DBG ( "ETH_INT_REG_ADDR: 		0x%08x\n", CN100_inl(ETH_INT_REG_ADDR));
+	CN100_DBG ( "ETH_INT_ENB_ADDR: 		0x%08x\n", CN100_inl(ETH_INT_ENB_ADDR));
+	CN100_DBG ( "ETH_TX_DMA_ADDR: 		0x%08x\n", CN100_inl(ETH_TX_DMA_ADDR));
+	CN100_DBG ( "ETH_TX_STATES_ADDR: 	0x%08x\n", CN100_inl(ETH_TX_STATES_ADDR));
+	CN100_DBG ( "ETH_RX_BASE_ADDR: 		0x%08x\n", CN100_inl(ETH_RX_BASE_ADDR));
+	CN100_DBG ( "ETH_RX_CFG_ADDR: 		0x%08x\n", CN100_inl(ETH_RX_CFG_ADDR));
+	CN100_DBG ( "ETH_RX_RD_ADDR:		0x%08x\n", CN100_inl(ETH_RX_RD_ADDR));
+	CN100_DBG ( "ETH_RX_WR_ADDR: 		0x%08x\n", CN100_inl(ETH_RX_WR_ADDR));
+	CN100_DBG ( "ETH_RX_STATES_ADDR: 	0x%08x\n", CN100_inl(ETH_RX_STATES_ADDR));
+	CN100_DBG ( "ETH_MAC_SA_MASK: 		0x%08x\n", CN100_inl(ETH_MAC_SA_MASK));
+	CN100_DBG ( "ETH_MAC_HASH_TAB0: 	0x%08x\n", CN100_inl(ETH_MAC_HASH_TAB0));
+	CN100_DBG ( "ETH_MAC_HASH_TAB1: 	0x%08x\n", CN100_inl(ETH_MAC_HASH_TAB1));
+
+	CN100_DBG ( "ETH_MAC_CFG0: 			0x%08x\n", CN100_inl(ETH_MAC_CFG0));
+	CN100_DBG ( "ETH_MAC_CFG1: 			0x%08x\n", CN100_inl(ETH_MAC_CFG1));
+	CN100_DBG ( "ETH_MAC_IPGT: 			0x%08x\n", CN100_inl(ETH_MAC_IPGT));
+	CN100_DBG ( "ETH_MAC_IPGR: 			0x%08x\n", CN100_inl(ETH_MAC_IPGR));
+	CN100_DBG ( "ETH_MAC_CLRT: 			0x%08x\n", CN100_inl(ETH_MAC_CLRT));
+	CN100_DBG ( "ETH_MAC_MAXF: 			0x%08x\n", CN100_inl(ETH_MAC_MAXF));
+	CN100_DBG ( "ETH_MAC_SUPP: 			0x%08x\n", CN100_inl(ETH_MAC_SUPP));
+	CN100_DBG ( "ETH_MAC_TEST: 			0x%08x\n", CN100_inl(ETH_MAC_TEST));
+	CN100_DBG ( "ETH_MAC_MCFG: 			0x%08x\n", CN100_inl(ETH_MAC_MCFG));
+	CN100_DBG ( "ETH_MAC_MCMD: 			0x%08x\n", CN100_inl(ETH_MAC_MCMD));
+	CN100_DBG ( "ETH_MAC_MADR: 			0x%08x\n", CN100_inl(ETH_MAC_MADR));
+	CN100_DBG ( "ETH_MAC_MWTD: 			0x%08x\n", CN100_inl(ETH_MAC_MWTD));
+	CN100_DBG ( "ETH_MAC_MRDD: 			0x%08x\n", CN100_inl(ETH_MAC_MRDD));
+	CN100_DBG ( "ETH_MAC_MIND: 			0x%08x\n", CN100_inl(ETH_MAC_MIND));
+	CN100_DBG ( "ETH_MAC_SA0: 			0x%08x\n", CN100_inl(ETH_MAC_SA0));
+	CN100_DBG ( "ETH_MAC_SA1: 			0x%08x\n", CN100_inl(ETH_MAC_SA1));
+	CN100_DBG ( "ETH_MAC_SA2: 			0x%08x\n", CN100_inl(ETH_MAC_SA2));
+	CN100_DBG ( "ETH_MAC_TSV0: 			0x%08x\n", CN100_inl(ETH_MAC_TSV0));
+	CN100_DBG ( "ETH_MAC_TSV1: 			0x%08x\n", CN100_inl(ETH_MAC_TSV1));
+	CN100_DBG ( "ETH_MAC_RSV: 			0x%08x\n", CN100_inl(ETH_MAC_RSV));
+	CN100_DBG("\n");
+}
+#endif
+
+static int alloc_eth_mem (cn100_priv *priv)
+{
+	s32 i = 0;
+
+	priv->tx_buffer_nod = memalign(ARCH_DMA_MINALIGN, sizeof(tx_buffer_f));
+	priv->tx_buffer = memalign(ARCH_DMA_MINALIGN, TX_BUFFER_LEN);
+	if(priv->tx_buffer_nod == NULL || priv->tx_buffer == NULL) return -1;
+	priv->tx_buffer_nod->buffer_addr = SWAP((u32)priv->tx_buffer);
+	priv->tx_buffer_nod->buffer_len = 0;
+	priv->tx_buffer_nod->next_link_item = 0;
+	priv->tx_buffer_nod->next_link_item = 0;
+
+	/* init rx buffer struct */
+	priv->rx_buffer_list.buffer_num = RX_BUFFER_ITEM_NUM;
+	priv->rx_buffer = memalign(ARCH_DMA_MINALIGN, RX_BUFFER_ITEM_SIZE * RX_BUFFER_ITEM_NUM);
+	if(priv->rx_buffer == NULL) return -1;
+		
+	for(i = 0; i < priv->rx_buffer_list.buffer_num; i++){
+		priv->rx_buffer_list.rx_buffer_addr[i] = (u32)priv->rx_buffer + RX_BUFFER_ITEM_SIZE * i;
+	}
+	CN100_DBG("tx_buffer_nod = %08x\n", (u32)priv->tx_buffer_nod);
+	CN100_DBG("tx_buffer = %08x\n", (u32)priv->tx_buffer);
+	CN100_DBG("rx_buffer = %08x\n", (u32)priv->rx_buffer);
+	return 0;
+}
+
+static int release_eth_mem (cn100_priv *priv)
+{
+	s32 i = 0;
+
+	if (NULL != priv->tx_buffer){
+		free(priv->tx_buffer);
+		priv->tx_buffer = NULL;
+	}
+
+	if (NULL != priv->tx_buffer_nod){
+		free(priv->tx_buffer_nod);
+		priv->tx_buffer_nod = NULL;
+	}
+
+
+	/* RX */
+	for ( i = 0; i < priv->rx_buffer_list.buffer_num; i ++ )
+	{
+		priv->rx_buffer_list.rx_buffer_addr[i] = 0;
+	}
+	priv->rx_buffer_list.buffer_num = 0;
+	if (NULL != priv->rx_buffer){
+		free(priv->rx_buffer);
+		priv->rx_buffer = NULL;
+	}
+
+	return 0;
+}
+
+
+static void set_tx_int (cn100_priv *priv, int enable )
+{
+	u32 value = 0;
+	value = CN100_inl ( ETH_INT_ENB_ADDR );
+	if ( enable ){
+		value |= ETH_INT_TX;
+	}else{
+		value &= ~ETH_INT_TX;
+	}
+	CN100_outl ( ETH_INT_ENB_ADDR, value );
+}
+
+static int init_eth_hw (cn100_priv *priv)
+{
+	u32 value = 0;
+
+	cn100_reset 	(priv);
+	set_rx_int	  	(priv, 0);
+	set_tx_int	  	(priv, 0);
+	set_rx_enable 	(priv, 0);
+	set_rx_buffer 	(priv);
+
+	CN100_outl 		(ETH_CFG_ADDR, 0x00005500 );
+	CN100_outl 		(ETH_MAC_SUPP, 0x00000100 );
+	CN100_outl 		(ETH_MAC_IPGT, 0x00000015 );
+	CN100_outl 		(ETH_MAC_IPGR, 0x00000c12 );
+	CN100_outl 		(ETH_MAC_SA_MASK, 0x3 );
+	CN100_outl 		(ETH_MAC_HASH_TAB0, 0x0 );
+	CN100_outl 		(ETH_MAC_HASH_TAB1, 0x0 );
+	value = CN100_inl (ETH_MAC_CFG1 );
+	value |= 0x1;
+	CN100_outl 		(ETH_MAC_CFG1, value );
+	set_rx_enable 	(priv, 1);
+	set_rx_int	  	(priv, 1);
+	set_tx_int    	(priv, 1);
+	set_hw_clock  	(priv);
+#ifdef CONFIG_CN100_DEBUG
+	//cn100_dump_regs(priv);
+#endif
+	return 0;
+}
+
+static int release_eth_hw (cn100_priv *priv)
+{
+	/* free interrupt */
+	cn100_reset(priv);
+	return 0;
+}
+
+static int init_phy_hw (cn100_priv *priv)
+{
+    CN100_outl(ETH_MAC_MADR, 6<<8);
+	return 0;
+}
+
+static int release_phy_hw (cn100_priv __attribute__((unused)) *priv)
+{
+	return 0;
+}
+
+static void set_rx_enable (cn100_priv *priv, int enable)
+{
+	u32 value = 0;
+	value = CN100_inl (ETH_MAC_CFG0 );
+	if( enable ){
+		value |= 0x01;
+	}else{
+		value &= 0xFFFFFFFE;
+	}
+	CN100_outl (ETH_MAC_CFG0, value );
+	value = CN100_inl (ETH_RX_CFG_ADDR );
+	if( enable ){
+		value |= 0x80000000;
+	}else{
+		value &= 0x7FFFFFFF;
+	}
+	CN100_outl (ETH_RX_CFG_ADDR, value );
+}
+
+static void set_rx_int (cn100_priv *priv, int enable)
+{
+	u32 value = 0;
+	value = CN100_inl (ETH_INT_ENB_ADDR );
+	if ( enable ){
+		value |= ETH_INT_RX;
+	}else{
+		value &= ~ETH_INT_RX;
+	}
+	CN100_outl (ETH_INT_ENB_ADDR, value );
+}
+
+static void set_hw_clock (cn100_priv *priv)
+{
+	CN100_outl (ETH_MAC_MCFG, 0x1c );
+}
+
+static int set_mac_addr (cn100_priv *priv, u8 mac_addr[6])
+{
+	u32 value = 0;
+	/* Set Node Address */
+	value = (u32)mac_addr[1];
+	value = (value<<8) | mac_addr[0];
+	CN100_outl (ETH_MAC_SA2, value );
+	value = (u32)mac_addr[3];
+	value = (value<<8) | mac_addr[2];
+	CN100_outl (ETH_MAC_SA1, value );
+	value = (u32)mac_addr[5];
+	value = (value<<8) | mac_addr[4];
+	CN100_outl (ETH_MAC_SA0, value );
+/*
+	printf("Setting MAC address to eth%d ", priv->index); 
+	for(value = 0; value < 6; value++){
+		printf("%02x%s", mac_addr[value], value == 5? "\n":":");
+	}
+	*/
+	return 0;
+}
+
+static int set_rx_buffer (cn100_priv *priv)
+{
+	u32 value = 0;
+
+	if ( 0 == priv->rx_buffer_list.buffer_num ){
+		return -1;
+	}
+	/* get virtual map physcial address */
+	value = (u32)priv->rx_buffer;
+	CN100_outl (ETH_RX_BASE_ADDR, ( value >> 3 ) );
+	value = priv->rx_buffer_list.buffer_num;
+	value = ( ( value << 8 ) & 0x7FFF00 ) | ( ( RX_BUFFER_ITEM_SIZE >> 3 ) & 0xFF ) ;
+	CN100_outl (ETH_RX_CFG_ADDR, value );
+	/* set output ptr equal input ptr */
+	value = CN100_inl (ETH_RX_WR_ADDR );
+	CN100_outl (ETH_RX_RD_ADDR, value );
+
+	return 0;
+}
+
+static int set_tx_buffer(cn100_priv *priv)
+{
+	u32 value = 0;
+	if ( NULL == priv->tx_buffer )
+	{
+		return -1;
+	}
+	value = (u32)priv->tx_buffer_nod;
+	CN100_outl (ETH_TX_DMA_ADDR, value );
+	return 0;
+}
+
+/* General Purpose cn100 reset routine */
+static void cn100_reset(cn100_priv *priv)
+{
+	CN100_DBG ( "resetting\n" );
+	u32 value = 0x000000b7;
+	/* disable rx and tx */
+	set_rx_int	  (priv, 0);
+	set_tx_int	  (priv, 0);
+	set_rx_enable (priv, 0);
+
+	CN100_outl ( ETH_MAC_CFG0, 0x00008000 );
+	udelay(1000);
+	CN100_outl ( ETH_MAC_CFG0, 0x00000001 );
+	CN100_outl ( ETH_INT_SET_ADDR, 0 );
+	CN100_outl ( ETH_MAC_CFG1, value );
+	udelay(1000);		/* delay 1ms */
+}
+
+#define SCS_CLK_EN 0xB2100140
+#define CLK_XPORT_MASK (1 << 21)
+
+static void cnc_xport_enable(void)
+{
+	u32 val = __raw_readl(SCS_CLK_EN);
+	__raw_writel(val | CLK_XPORT_MASK, SCS_CLK_EN);
+}
+
+
+/* Initilize cn100 board
+*/
+int cn100_initialize ( bd_t * bd, int index)
+{
+	struct eth_device *dev;
+	cn100_priv *priv;
+
+	dev = (struct eth_device *) malloc (sizeof(*dev));
+	priv = (cn100_priv *) malloc (sizeof(*priv));
+	memset (dev, 0, sizeof(*dev));
+	memset (priv, 0, sizeof(*priv));
+
+	priv->index = index;
+	if(index){
+		priv->shift = 16;
+		priv->ctl_offset = ETH1_CTL_BASE - ETH0_CTL_BASE;
+		priv->mac_offset = ETH1_MAC_BASE - ETH0_MAC_BASE;
+	}
+
+	if ( 0 != alloc_eth_mem (priv)  )
+	{
+		printf ( "alloc eth memory resource fail\n" );
+		release_eth_mem (priv);
+		return 0;
+	}
+
+	dev->priv = priv;
+	dev->init = cn100_init;
+	dev->halt = cn100_halt;
+	dev->send = cn100_send;
+	dev->recv = cn100_recv;
+	dev->write_hwaddr = cn100_write_hwaddr;
+
+	cnc_xport_enable();
+
+	sprintf (dev->name, "CN100:%d", index);
+	eth_register (dev);
+	return 1;
+}
+
+int cn100_init(struct eth_device *dev, bd_t * bis)
+{
+	s32 ret = 0;
+	cn100_priv *priv = (cn100_priv *)dev->priv;
+
+	/* init eth hard register */
+	if ( 0 != ( ret = init_eth_hw (priv) ) )
+	{
+		printf ( "init eth hw resource fail\n");
+		goto ERROR_INIT_ETH_HW;
+	}
+
+	/* init phy hard register */
+	if ( 0 != ( ret = init_phy_hw (priv) ) )
+	{
+		printf ( "init phy resource fail\n");
+		goto ERROR_INIT_PHY_HW;
+	}
+	return 1;
+
+ERROR_INIT_PHY_HW:
+	release_eth_hw (priv);
+ERROR_INIT_ETH_HW:
+	return -2;
+}
+
+int  cn100_write_hwaddr(struct eth_device* dev)
+{
+	cn100_priv *priv = (cn100_priv *)dev->priv;
+	set_mac_addr(priv, dev->enetaddr);
+	return 1;
+}
+
+/*
+   Hardware start transmission.
+   Send a packet to media from the upper layer.
+   */
+int cn100_send(struct eth_device *dev, volatile void *packet, int length)
+{
+	cn100_priv *priv = (cn100_priv *)dev->priv;
+
+	CN100_DBG("eth_send: length: %d\n", length);
+#if 0
+	for (i = 0; i < length; i++)
+	{
+		if (i % 8 == 0)
+		{
+			CN100_DBG("\nSend: 02x: ", i);
+		}
+		CN100_DBG("%02x ", ((unsigned char *) packet)[i]);
+	}
+	CN100_DBG("\n");
+#endif
+	memcpy (priv->tx_buffer, (void *)packet, length);
+	flush_dcache_range((u32)priv->tx_buffer, (u32)priv->tx_buffer + TX_BUFFER_DATA_LEN);
+	priv->tx_buffer_nod->buffer_len = SWAP ( length );
+	flush_dcache_range((u32)priv->tx_buffer_nod, (u32)priv->tx_buffer_nod + TX_BUFFER_NOD_LEN);
+	set_tx_buffer (priv);
+	while ( ! (CN100_inl ( ETH_INT_REG_ADDR ) & ETH_INT_TX) ); 
+
+	/* clr send interrupt */
+	CN100_outl (ETH_INT_CLS_ADDR, ETH_INT_TX);
+	CN100_DBG("transmit done\n\n");
+ #ifdef CONFIG_CN100_DEBUG
+   //cn100_dump_regs();
+ #endif
+	return 0;
+}
+
+/*
+   Stop the interface.
+   The interface is stopped when it is brought.
+   */
+void cn100_halt(struct eth_device *dev)
+{
+	CN100_DBG ( "eth_halt\n" );
+	cn100_reset ((cn100_priv*)dev->priv);
+	CN100_DBG ( "eth_halt finish\n" );
+}
+
+
+/*
+   Received a packet and pass to upper layer
+   */
+int cn100_recv(struct eth_device *dev)
+{
+	u32 RxLen = 0;
+	u32 isr;
+	u32 read_ptr;
+	cn100_priv *priv = (cn100_priv *)dev->priv;
+
+	/* Check packet ready or not */
+	isr = CN100_inl( ETH_INT_REG_ADDR );
+	if(isr & ETH_INT_RX ){
+		CN100_outl ( ETH_INT_CLS_ADDR, ETH_INT_RX );
+	}
+	if ( isr & ETH_INT_TX){
+		CN100_outl ( ETH_INT_CLS_ADDR, ETH_INT_TX );
+	}
+
+/*	do{*/
+		CN100_DBG ( "receiving packet\n");
+		read_ptr = CN100_inl ( ETH_RX_RD_ADDR );
+
+		/* No more packet to process if RX FIFO is empty */
+		if(read_ptr & ETH_FIFO_EMPTY) return 0;
+
+		invalidate_dcache_range(priv->rx_buffer_list.rx_buffer_addr[read_ptr & ETH_FIFO_MASK], 
+			priv->rx_buffer_list.rx_buffer_addr[read_ptr & ETH_FIFO_MASK] + RX_BUFFER_ITEM_SIZE);
+		RxLen = *(volatile u32 *)( priv->rx_buffer_list.rx_buffer_addr[read_ptr & ETH_FIFO_MASK] + 4 );
+		RxLen = SWAP ( RxLen );
+
+		CN100_DBG("rx len: %d\n", RxLen);
+
+		if ( RxLen > RX_BUFFER_ITEM_SIZE - 16 ){
+			printf("rx length too big\n");
+			cn100_reset(priv);
+			init_eth_hw(priv); 
+			RxLen = 0;
+		}else{
+			/* Move data from CN100 */
+			memcpy ( priv->rx_buffer_x,
+				(u32 *)(priv->rx_buffer_list.rx_buffer_addr[read_ptr & ETH_FIFO_MASK] + 8),
+				RxLen );
+			read_ptr++;
+
+			if((read_ptr & ETH_FIFO_MASK ) == ( priv->rx_buffer_list.buffer_num) )
+				read_ptr = (~read_ptr) & ETH_FIFO_TOG;
+
+			CN100_outl ( ETH_RX_RD_ADDR, read_ptr );
+
+			/* Pass to upper layer */
+			CN100_DBG("passing packet to upper layer\n");
+			NetReceive(priv->rx_buffer_x, RxLen);
+		}
+/*	}while(1);*/
+	return RxLen;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/net/cn100.h u-boot-2011.06/drivers/net/cn100.h
--- u-boot-2011.06_original/drivers/net/cn100.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/net/cn100.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,60 @@
+/* cn100 net driver */
+#ifndef _CN100_H_
+#define _CN100_H_
+
+#define	ETH_CFG_ADDR			( 0x0800 )
+#define	ETH_INT_REG_ADDR        ( 0x0840 )
+#define	ETH_INT_ENB_ADDR        ( 0x0844 )
+#define	ETH_INT_SET_ADDR        ( 0x0848 )
+#define	ETH_INT_CLS_ADDR        ( 0x084c )
+
+#define	ETH_TX_DMA_ADDR        	( priv->ctl_offset + 0x09c0 )
+#define	ETH_TX_STATES_ADDR     	( priv->ctl_offset + 0x09c4 )
+#define	ETH_RX_BASE_ADDR       	( priv->ctl_offset + 0x09c8 )
+#define	ETH_RX_CFG_ADDR        	( priv->ctl_offset + 0x09cc )
+#define	ETH_RX_RD_ADDR         	( priv->ctl_offset + 0x09d0 )
+#define	ETH_RX_WR_ADDR         	( priv->ctl_offset + 0x09d4 )
+#define	ETH_RX_STATES_ADDR     	( priv->ctl_offset + 0x09dc )
+
+#define	ETH_MAC_SA_MASK        	( 0x0a98 )
+#define	ETH_MAC_HASH_TAB0      	( 0x0a9c )
+#define	ETH_MAC_HASH_TAB1      	( 0x0aa0 )
+
+#define	ETH_MAC_CFG0          	( priv->mac_offset + 0x0a40 )
+#define	ETH_MAC_CFG1          	( priv->mac_offset + 0x0a44 )
+#define	ETH_MAC_IPGT          	( priv->mac_offset + 0x0a48 )
+#define	ETH_MAC_IPGR          	( priv->mac_offset + 0x0a4c )
+#define	ETH_MAC_CLRT          	( priv->mac_offset + 0x0a50 )
+#define	ETH_MAC_MAXF          	( priv->mac_offset + 0x0a54 )
+#define	ETH_MAC_SUPP          	( priv->mac_offset + 0x0a58 )
+#define	ETH_MAC_TEST          	( priv->mac_offset + 0x0a5c )
+
+#define	ETH_MAC_MCFG          	( 0x0a60 )
+#define	ETH_MAC_MCMD          	( 0x0a64 )
+#define	ETH_MAC_MADR          	( 0x0a68 )
+#define	ETH_MAC_MWTD          	( 0x0a6c )
+#define	ETH_MAC_MRDD          	( 0x0a70 )
+#define	ETH_MAC_MIND          	( 0x0a74 )
+
+#define	ETH_MAC_SA0           	( priv->mac_offset + 0x0a80 )
+#define	ETH_MAC_SA1           	( priv->mac_offset + 0x0a84 )
+#define	ETH_MAC_SA2           	( priv->mac_offset + 0x0a88 )
+#define	ETH_MAC_TSV0           	( priv->mac_offset + 0x0a8c )
+#define	ETH_MAC_TSV1           	( priv->mac_offset + 0x0a90 )
+#define	ETH_MAC_RSV            	( priv->mac_offset + 0x0a94 )
+
+#define ETH0_CTL_BASE			( 0x09c0 )
+#define ETH0_MAC_BASE			( 0x0a40 )
+#define ETH1_CTL_BASE			( 0x0a00 )
+#define ETH1_MAC_BASE			( 0x0ac0 )
+
+#define ETH_INT_TX				(0x01 << priv->shift)
+#define ETH_INT_RX				(0x02 << priv->shift)
+#define ETH_INT_HALF			(0x04 << priv->shift)
+#define ETH_INT_MASK			(0x07 << priv->shift)
+
+#define ETH_FIFO_EMPTY			0x40000000
+#define ETH_FIFO_TOG			0x80000000
+#define ETH_FIFO_MASK			0x00000FFF
+
+#endif // _CN100_H_
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/net/Makefile u-boot-2011.06/drivers/net/Makefile
--- u-boot-2011.06_original/drivers/net/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/net/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -84,6 +84,7 @@
 COBJS-$(CONFIG_ULI526X) += uli526x.o
 COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
 COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+COBJS-$(CONFIG_DRIVER_CN100) += cn100.o
 
 COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/serial/ns16550.c u-boot-2011.06/drivers/serial/ns16550.c
--- u-boot-2011.06_original/drivers/serial/ns16550.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/serial/ns16550.c	2014-11-19 00:41:17.367468000 +0800
@@ -4,12 +4,15 @@
  * modified to use CONFIG_SYS_ISA_MEM and new defines
  */
 
+#include <common.h>
 #include <config.h>
 #include <ns16550.h>
 #include <watchdog.h>
 #include <linux/types.h>
 #include <asm/io.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define UART_LCRVAL UART_LCR_8N1		/* 8 data, 1 stop, no parity */
 #define UART_MCRVAL (UART_MCR_DTR | \
 		     UART_MCR_RTS)		/* RTS/DTR */
@@ -20,30 +23,34 @@
 #define serial_out(x,y)	outb(x,(ulong)y)
 #define serial_in(y)	inb((ulong)y)
 #else
-#define serial_out(x,y) writeb(x,y)
-#define serial_in(y) 	readb(y)
+#define serial_out(x,y) writel(x,y)
+#define serial_in(y) 	readl(y)
 #endif
 
 #ifndef CONFIG_SYS_NS16550_IER
 #define CONFIG_SYS_NS16550_IER  0x00
 #endif /* CONFIG_SYS_NS16550_IER */
 
+#ifdef CONFIG_UART_LOCK
+extern int otp_check_uart_lock(void);
+#endif
+
 void NS16550_init (NS16550_t com_port, int baud_divisor)
 {
-	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
+	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); //0x4 = 0
 #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
 	serial_out(0x7, &com_port->mdr1);	/* mode select reset TL16C750*/
 #endif
-	serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
-	serial_out(0, &com_port->dll);
-	serial_out(0, &com_port->dlm);
-	serial_out(UART_LCRVAL, &com_port->lcr);
-	serial_out(UART_MCRVAL, &com_port->mcr);
-	serial_out(UART_FCRVAL, &com_port->fcr);
-	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
-	serial_out(baud_divisor & 0xff, &com_port->dll);
-	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
-	serial_out(UART_LCRVAL, &com_port->lcr);
+	serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr); //0xC = 0x83
+	serial_out(0, &com_port->dll); //0x0 = 0
+	serial_out(0, &com_port->dlm); //0x4 = 0
+	serial_out(UART_LCRVAL, &com_port->lcr); //0xC = 3
+	serial_out(UART_MCRVAL, &com_port->mcr); // 0x10 = 3
+	serial_out(UART_FCRVAL, &com_port->fcr); // 0x8 = 7
+	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); //0xC = 0x83
+	serial_out(baud_divisor & 0xff, &com_port->dll); //0x0 = 0xF
+	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); //0x4 = 0
+	serial_out(UART_LCRVAL, &com_port->lcr); //0xC = 3
 #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
 #if defined(CONFIG_APTIX)
 	serial_out(3, &com_port->mdr1);	/* /13 mode so Aptix 6MHz can hit 115200 */
@@ -51,12 +58,15 @@
 	serial_out(0, &com_port->mdr1);	/* /16 is proper to hit 115200 with 48MHz */
 #endif
 #endif /* CONFIG_OMAP */
+#ifdef CONFIG_UART_LOCK
+	gd->uart_locked = otp_check_uart_lock();
+#endif
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
 void NS16550_reinit (NS16550_t com_port, int baud_divisor)
 {
-	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
+	serial_out( ( unsigned int) CONFIG_SYS_NS16550_IER, (volatile unsigned int*)  &com_port->ier);
 	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
 	serial_out(0, &com_port->dll);
 	serial_out(0, &com_port->dlm);
@@ -72,8 +82,14 @@
 
 void NS16550_putc (NS16550_t com_port, char c)
 {
-	while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0);
-	serial_out(c, &com_port->thr);
+#ifdef CONFIG_UART_LOCK
+	if(!gd->uart_locked){
+#endif
+		while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0); // *0x14 & 0x20
+		serial_out(c, &com_port->thr); //0x0 = ?
+#ifdef CONFIG_UART_LOCK
+	}
+#endif
 
 	/*
 	 * Call watchdog_reset() upon newline. This is done here in putc
@@ -88,6 +104,11 @@
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
 char NS16550_getc (NS16550_t com_port)
 {
+#ifdef CONFIG_UART_LOCK
+	if(gd->uart_locked){
+		while(1)WATCHDOG_RESET();
+	}else{
+#endif
 	while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
 #ifdef CONFIG_USB_TTY
 		extern void usbtty_poll(void);
@@ -95,12 +116,23 @@
 #endif
 		WATCHDOG_RESET();
 	}
+#ifdef CONFIG_UART_LOCK
+	}
+#endif
 	return serial_in(&com_port->rbr);
 }
 
 int NS16550_tstc (NS16550_t com_port)
 {
+#ifdef CONFIG_UART_LOCK
+	if(gd->uart_locked){
+		return 0;
+	}else{
+#endif
 	return ((serial_in(&com_port->lsr) & UART_LSR_DR) != 0);
+#ifdef CONFIG_UART_LOCK
+	}
+#endif
 }
 
 #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/spi/dw_spi.c u-boot-2011.06/drivers/spi/dw_spi.c
--- u-boot-2011.06_original/drivers/spi/dw_spi.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/spi/dw_spi.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,257 @@
+/*
+ * Designware SPI core controller driver (refer pxa2xx_spi.c)
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <spi.h>
+
+#include "dw_spi.h"
+
+#define to_dws(s) container_of(s, struct dw_spi, slave)
+
+static inline void cs1_low(void)
+{
+	*((volatile unsigned int *)0x8010000c) |= 0x200;
+}
+
+static inline void cs1_high(void)
+{
+	*((volatile unsigned int *)0x8010000c) &= (~0x200);
+}
+
+/* Return the max entries we can fill into tx fifo */
+static inline u32 tx_max(struct dw_spi *dws)
+{
+	u32 tx_left, tx_room;
+
+	tx_left = ((dws->tx0_end - dws->tx0))
+			/ dws->n_bytes;
+	tx_room = dws->fifo_len - dw_readw(dws, DW_SPI_TXFLR);
+	return min(tx_left, tx_room);
+}
+
+/* Return the max entries we should read out of rx fifo */
+static inline u32 rx_max(struct dw_spi *dws)
+{
+	u32 rx_left, rx_room;
+
+	rx_left = ((dws->rx0_end - dws->rx0) )
+			/ dws->n_bytes;
+	rx_room = dw_readw(dws, DW_SPI_RXFLR);
+//	printf("left=%d, room=%d count = %d\n", rx_left, rx_room, maxx);
+	return min(rx_left, rx_room);
+}
+static void dw_writer(struct dw_spi *dws)
+{
+	u32 max = tx_max(dws);
+	u16 txw = 0;
+//	printf("max=%d\n", max);
+	while (max--) {
+		/* Set the tx word if the transfer's original "tx" is not null */
+		if (dws->tx0 < dws->tx0_end) {
+			if (dws->tx0_end - dws->len0) {
+				if (dws->n_bytes == 1)
+					txw = *(u8 *)(dws->tx0);
+				else
+					txw = *(u16 *)(dws->tx0);
+			}
+			dw_writew(dws, DW_SPI_DR, txw);
+			dws->tx0 += dws->n_bytes;
+		} else {
+			txw = 0;
+			dw_writew(dws, DW_SPI_DR, txw);
+			printf("F");
+		}
+	}
+}
+
+static void dw_reader(struct dw_spi *dws)
+{
+	u32 max = rx_max(dws);
+	u16 rxw;
+
+	while (max--) {
+		rxw = dw_readw(dws, DW_SPI_DR);
+		/* Care rx only if the transfer's original "rx" is not null */
+		if (dws->rx0 < dws->rx0_end) {
+			if (dws->rx0_end - dws->len0) {
+				if (dws->n_bytes == 1)
+					*(u8 *)(dws->rx0) = rxw;
+				else
+					*(u16 *)(dws->rx0) = rxw;
+			}
+			dws->rx0 += dws->n_bytes;
+		}	
+	}
+}
+
+
+/* Must be called inside pump_transfers() */
+static void poll_transfer(struct dw_spi *dws)
+{
+	do {
+		dw_writer(dws);
+		dw_reader(dws);
+		//printf("dws->rx0_end = %x, dws->rx0 = %x\n", dws->rx0_end, dws->rx0);
+	} while ((dws->rx0_end > dws->rx0));
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	struct dw_spi *dws = to_dws(slave);
+	/* assume spi core configured to do 8 bit transfers */
+	uint bytes = bitlen / 8;
+
+	if (bitlen == 0)
+		goto done;
+
+	if (bitlen % 8) {
+		flags |= SPI_XFER_END;
+		goto done;
+	}
+//	printf("XFER %d\n", bytes);
+
+	if (flags & SPI_XFER_BEGIN){
+//		printf("XFER_BEGIN\n");
+		spi_set_cr0(dws, dws->cr0);
+//		printf("Set CR0 = %x\n", dws->cr0);
+		spi_set_clk(dws, dws->max_freq / dws->speed_hz);
+//		printf("Set speed = %x\n", dws->max_freq / dws->speed_hz);
+		//spi_set_clk(dws, 0x8);
+		spi_chip_sel(dws, 1);
+		spi_mask_intr(dws, 0xff);
+		cs1_low();
+
+		spi_enable_chip(dws, 1);
+	}
+
+	dws->tx0 = (void *)dout;
+	dws->tx0_end = dws->tx0 + bytes;
+	dws->rx0 = din;
+	dws->rx0_end = dws->rx0 + bytes;
+	dws->len0 = bytes;
+
+//	printf("T0 %p %d\n", dws->tx0, dws->len0);
+//	printf("R0 %p %d\n", dws->rx0, dws->len0);
+	poll_transfer(dws);
+
+ done:
+	if (flags & SPI_XFER_END){
+//		printf("XFER_END\n");
+		spi_enable_chip(dws, 0);
+		cs1_high();
+	}
+
+	return 0;
+}
+
+void spi_init()
+{
+	    /* do nothing */
+}
+
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	    return bus == 0 && cs == 0;
+}
+
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int max_hz, unsigned int mode)
+{
+	struct dw_spi *dws;
+	int bits_per_word = 8;
+	int type = 0;
+	
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	dws = malloc(sizeof(*dws));
+	if (!dws)
+		return NULL;
+
+	memset(dws, 0, sizeof(*dws));
+
+	dws->slave.bus = bus;
+	dws->slave.cs = cs;
+	dws->regs = 0x80150000;
+
+	spi_enable_chip(dws, 0);
+	spi_mask_intr(dws, 0xff);
+	spi_enable_chip(dws, 1);
+
+	if (bits_per_word <= 8) {
+		dws->n_bytes = 1;
+	} else if (bits_per_word <= 16) {
+		dws->n_bytes = 2;
+	}	
+	
+	dws->bits_per_word = bits_per_word;
+
+	dws->max_freq = 189000000;
+	dws->speed_hz = max_hz; 
+
+	/* Default SPI mode is SCPOL = 0, SCPH = 0 */
+	dws->cr0 = (bits_per_word - 1)
+			| (type << SPI_FRF_OFFSET)
+			| (mode  << SPI_MODE_OFFSET)
+			| (0 << SPI_TMOD_OFFSET);
+
+//	printf("Setup slave cr0 = %x", dws->cr0);
+	 /* Try to detect the FIFO depth if not set by interface driver,
+	 * the depth could be from 2 to 256 from HW spec
+	 */
+	if (!dws->fifo_len) {
+		u32 fifo;
+		for (fifo = 2; fifo <= 257; fifo++) {
+			dw_writew(dws, DW_SPI_TXFLTR, fifo);
+			if (fifo != dw_readw(dws, DW_SPI_TXFLTR))
+				break;
+		}
+
+		dws->fifo_len = (fifo == 257) ? 0 : fifo;
+		dw_writew(dws, DW_SPI_TXFLTR, 0);
+	}
+	spi_enable_chip(dws, 0);
+
+	return &dws->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	struct dw_spi *dws = to_dws(slave);
+	free(dws);
+	
+	spi_enable_chip(dws, 0);
+	/* Disable clk */
+	spi_set_clk(dws, 0);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/spi/dw_spi.h u-boot-2011.06/drivers/spi/dw_spi.h
--- u-boot-2011.06_original/drivers/spi/dw_spi.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/spi/dw_spi.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,170 @@
+#ifndef DW_SPI_HEADER_H
+#define DW_SPI_HEADER_H
+
+/* Register offsets */
+#define DW_SPI_CTRL0			0x00
+#define DW_SPI_CTRL1			0x04
+#define DW_SPI_SSIENR			0x08
+#define DW_SPI_MWCR			0x0c
+#define DW_SPI_SER			0x10
+#define DW_SPI_BAUDR			0x14
+#define DW_SPI_TXFLTR			0x18
+#define DW_SPI_RXFLTR			0x1c
+#define DW_SPI_TXFLR			0x20
+#define DW_SPI_RXFLR			0x24
+#define DW_SPI_SR			0x28
+#define DW_SPI_IMR			0x2c
+#define DW_SPI_ISR			0x30
+#define DW_SPI_RISR			0x34
+#define DW_SPI_TXOICR			0x38
+#define DW_SPI_RXOICR			0x3c
+#define DW_SPI_RXUICR			0x40
+#define DW_SPI_MSTICR			0x44
+#define DW_SPI_ICR			0x48
+#define DW_SPI_DMACR			0x4c
+#define DW_SPI_DMATDLR			0x50
+#define DW_SPI_DMARDLR			0x54
+#define DW_SPI_IDR			0x58
+#define DW_SPI_VERSION			0x5c
+#define DW_SPI_DR			0x60
+
+/* Bit fields in CTRLR0 */
+#define SPI_DFS_OFFSET			0
+
+#define SPI_FRF_OFFSET			4
+#define SPI_FRF_SPI			0x0
+#define SPI_FRF_SSP			0x1
+#define SPI_FRF_MICROWIRE		0x2
+#define SPI_FRF_RESV			0x3
+
+#define SPI_MODE_OFFSET			6
+#define SPI_SCPH_OFFSET			6
+#define SPI_SCOL_OFFSET			7
+
+#define SPI_TMOD_OFFSET			8
+#define SPI_TMOD_MASK			(0x3 << SPI_TMOD_OFFSET)
+#define	SPI_TMOD_TR			0x0		/* xmit & recv */
+#define SPI_TMOD_TO			0x1		/* xmit only */
+#define SPI_TMOD_RO			0x2		/* recv only */
+#define SPI_TMOD_EPROMREAD		0x3		/* eeprom read mode */
+
+#define SPI_SLVOE_OFFSET		10
+#define SPI_SRL_OFFSET			11
+#define SPI_CFS_OFFSET			12
+
+/* Bit fields in SR, 7 bits */
+#define SR_MASK				0x7f		/* cover 7 bits */
+#define SR_BUSY				(1 << 0)
+#define SR_TF_NOT_FULL			(1 << 1)
+#define SR_TF_EMPT			(1 << 2)
+#define SR_RF_NOT_EMPT			(1 << 3)
+#define SR_RF_FULL			(1 << 4)
+#define SR_TX_ERR			(1 << 5)
+#define SR_DCOL				(1 << 6)
+
+/* Bit fields in ISR, IMR, RISR, 7 bits */
+#define SPI_INT_TXEI			(1 << 0)
+#define SPI_INT_TXOI			(1 << 1)
+#define SPI_INT_RXUI			(1 << 2)
+#define SPI_INT_RXOI			(1 << 3)
+#define SPI_INT_RXFI			(1 << 4)
+#define SPI_INT_MSTI			(1 << 5)
+
+/* TX RX interrupt level threshold, max can be 256 */
+#define SPI_INT_THRESHOLD		32
+
+enum dw_ssi_type {
+	SSI_MOTO_SPI = 0,
+	SSI_TI_SSP,
+	SSI_NS_MICROWIRE,
+};
+
+
+struct dw_spi {
+	struct spi_slave slave;
+	enum dw_ssi_type	type;
+
+	ulong		regs;
+	u32			fifo_len;	/* depth of the FIFO buffer */
+	u32			max_freq;	/* max bus freq supported */
+	u32			speed_hz;
+	u32			cr0;
+
+	size_t			len0;
+	void			*tx0;
+	void			*tx0_end;
+	void			*rx0;
+	void			*rx0_end;
+
+	u8			bits_per_word;	/* maxim is 16b */
+	u8			n_bytes;
+};
+
+static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
+{
+	return *((volatile unsigned int*)(dws->regs + offset));
+}
+
+static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
+{
+	*((volatile unsigned int *)(dws->regs + offset)) = val;
+}
+int maxx = 0;
+static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
+{
+	if(offset == DW_SPI_DR)maxx++;
+	return *((volatile u16*)(dws->regs + offset));
+}
+
+static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
+{
+	*((volatile u16 *)(dws->regs + offset)) = val;
+}
+
+static inline void spi_enable_chip(struct dw_spi *dws, int enable)
+{
+	dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));
+//	printf("SSIENR = %x\n", (enable ? 1:0));
+}
+
+static inline void spi_set_cr0(struct dw_spi *dws, u32 cr0)
+{
+	dw_writel(dws, DW_SPI_CTRL0, cr0);
+}
+
+static inline void spi_set_cr1(struct dw_spi *dws, u32 cr0)
+{
+	dw_writel(dws, DW_SPI_CTRL1, cr0);
+}
+
+static inline void spi_set_clk(struct dw_spi *dws, u16 div)
+{
+	dw_writel(dws, DW_SPI_BAUDR, div);
+}
+
+static inline void spi_chip_sel(struct dw_spi *dws, u16 cs)
+{
+	dw_writel(dws, DW_SPI_SER, 1 << (cs));
+//	printf("SER = %x\n", dw_readl(dws, DW_SPI_SER));
+}
+
+/* Disable IRQ bits */
+static inline void spi_mask_intr(struct dw_spi *dws, u32 mask)
+{
+	u32 new_mask;
+
+	new_mask = dw_readl(dws, DW_SPI_IMR) & ~mask;
+	dw_writel(dws, DW_SPI_IMR, new_mask);
+}
+
+/* Enable IRQ bits */
+static inline void spi_umask_intr(struct dw_spi *dws, u32 mask)
+{
+	u32 new_mask;
+
+	new_mask = dw_readl(dws, DW_SPI_IMR) | mask;
+	dw_writel(dws, DW_SPI_IMR, new_mask);
+}
+
+
+#endif /* DW_SPI_HEADER_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/spi/Makefile u-boot-2011.06/drivers/spi/Makefile
--- u-boot-2011.06_original/drivers/spi/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/spi/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -40,6 +40,7 @@
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
 COBJS-$(CONFIG_SH_SPI) += sh_spi.o
 COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
+COBJS-$(CONFIG_DW_SPI) += dw_spi.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/eth/asix.c u-boot-2011.06/drivers/usb/eth/asix.c
--- u-boot-2011.06_original/drivers/usb/eth/asix.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/eth/asix.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,28 +1,14 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
- * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
 #include <usb.h>
 #include <linux/mii.h>
 #include "usb_ether.h"
+#include <malloc.h>
 
 
 /* ASIX AX8817X based USB 2.0 Ethernet Devices */
@@ -31,10 +17,12 @@
 #define AX_CMD_READ_MII_REG		0x07
 #define AX_CMD_WRITE_MII_REG		0x08
 #define AX_CMD_SET_HW_MII		0x0a
+#define AX_CMD_READ_EEPROM		0x0b
 #define AX_CMD_READ_RX_CTL		0x0f
 #define AX_CMD_WRITE_RX_CTL		0x10
 #define AX_CMD_WRITE_IPG0		0x12
 #define AX_CMD_READ_NODE_ID		0x13
+#define AX_CMD_WRITE_NODE_ID	0x14
 #define AX_CMD_READ_PHY_ID		0x19
 #define AX_CMD_WRITE_MEDIUM_MODE	0x1b
 #define AX_CMD_WRITE_GPIOS		0x1f
@@ -97,9 +85,21 @@
 #define AX_RX_URB_SIZE 2048
 #define PHY_CONNECT_TIMEOUT 5000
 
+/* asix_flags defines */
+#define FLAG_NONE			0
+#define FLAG_TYPE_AX88172	(1U << 0)
+#define FLAG_TYPE_AX88772	(1U << 1)
+#define FLAG_TYPE_AX88772B	(1U << 2)
+#define FLAG_EEPROM_MAC		(1U << 3) /* initial mac address in eeprom */
+
 /* local vars */
 static int curr_eth_dev; /* index for name of next device detected */
 
+/* driver private */
+struct asix_private {
+	int flags;
+};
+
 /*
  * Asix infrastructure commands
  */
@@ -168,27 +168,28 @@
 
 static int asix_mdio_read(struct ueth_data *dev, int phy_id, int loc)
 {
-	__le16 res;
+	ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
 
 	asix_set_sw_mii(dev);
-	asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res);
+	asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, res);
 	asix_set_hw_mii(dev);
 
 	debug("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
-			phy_id, loc, le16_to_cpu(res));
+			phy_id, loc, le16_to_cpu(*res));
 
-	return le16_to_cpu(res);
+	return le16_to_cpu(*res);
 }
 
 static void
 asix_mdio_write(struct ueth_data *dev, int phy_id, int loc, int val)
 {
-	__le16 res = cpu_to_le16(val);
+	ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
+	*res = cpu_to_le16(val);
 
 	debug("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
 			phy_id, loc, val);
 	asix_set_sw_mii(dev);
-	asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
+	asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, res);
 	asix_set_hw_mii(dev);
 }
 
@@ -210,7 +211,8 @@
 
 static inline int asix_get_phy_addr(struct ueth_data *dev)
 {
-	u8 buf[2];
+	ALLOC_CACHE_ALIGN_BUFFER(u8, buf, 2);
+
 	int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
 
 	debug("asix_get_phy_addr()\n");
@@ -219,7 +221,7 @@
 		debug("Error reading PHYID register: %02x\n", ret);
 		goto out;
 	}
-	debug("asix_get_phy_addr() returning 0x%04x\n", *((__le16 *)buf));
+	debug("asix_get_phy_addr() returning 0x%02x%02x\n", buf[0], buf[1]);
 	ret = buf[1];
 
 out:
@@ -242,13 +244,14 @@
 
 static u16 asix_read_rx_ctl(struct ueth_data *dev)
 {
-	__le16 v;
-	int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
+	ALLOC_CACHE_ALIGN_BUFFER(__le16, v, 1);
+
+	int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, v);
 
 	if (ret < 0)
 		debug("Error reading RX_CTL register: %02x\n", ret);
 	else
-		ret = le16_to_cpu(v);
+		ret = le16_to_cpu(*v);
 	return ret;
 }
 
@@ -281,6 +284,21 @@
 	return ret;
 }
 
+static int asix_write_hwaddr(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	int ret;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
+
+	memcpy(buf, eth->enetaddr, ETH_ALEN);
+
+	ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf);
+	if (ret < 0)
+		debug("Failed to set MAC address: %02x\n", ret);
+
+	return ret;
+}
+
 /*
  * mii commands
  */
@@ -307,92 +325,107 @@
 	return r;
 }
 
-/*
- * Asix callbacks
- */
-static int asix_init(struct eth_device *eth, bd_t *bd)
+static int asix_read_mac(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct asix_private *priv = (struct asix_private *)dev->dev_priv;
+	int i;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
+
+	if (priv->flags & FLAG_EEPROM_MAC) {
+		for (i = 0; i < (ETH_ALEN >> 1); i++) {
+			if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
+					  0x04 + i, 0, 2, buf) < 0) {
+				debug("Failed to read SROM address 04h.\n");
+				return -1;
+			}
+			memcpy((eth->enetaddr + i * 2), buf, 2);
+		}
+	} else {
+		if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)
+		     < 0) {
+			debug("Failed to read MAC address.\n");
+			return -1;
+		}
+		memcpy(eth->enetaddr, buf, ETH_ALEN);
+	}
+
+	return 0;
+}
+
+static int asix_basic_reset(struct ueth_data *dev)
 {
 	int embd_phy;
-	unsigned char buf[ETH_ALEN];
 	u16 rx_ctl;
-	struct ueth_data	*dev = (struct ueth_data *)eth->priv;
-	int timeout = 0;
-#define TIMEOUT_RESOLUTION 50	/* ms */
-	int link_detected;
-
-	debug("** %s()\n", __func__);
 
 	if (asix_write_gpio(dev,
 			AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0)
-		goto out_err;
+		return -1;
 
 	/* 0x10 is the phy id of the embedded 10/100 ethernet phy */
 	embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
 	if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
 				embd_phy, 0, 0, NULL) < 0) {
 		debug("Select PHY #1 failed\n");
-		goto out_err;
+		return -1;
 	}
 
 	if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0)
-		goto out_err;
+		return -1;
 
 	if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0)
-		goto out_err;
+		return -1;
 
 	if (embd_phy) {
 		if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0)
-			goto out_err;
+			return -1;
 	} else {
 		if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0)
-			goto out_err;
+			return -1;
 	}
 
 	rx_ctl = asix_read_rx_ctl(dev);
 	debug("RX_CTL is 0x%04x after software reset\n", rx_ctl);
 	if (asix_write_rx_ctl(dev, 0x0000) < 0)
-		goto out_err;
+		return -1;
 
 	rx_ctl = asix_read_rx_ctl(dev);
 	debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 
-	/* Get the MAC address */
-	if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
-				0, 0, ETH_ALEN, buf) < 0) {
-		debug("Failed to read MAC address.\n");
-		goto out_err;
-	}
-	memcpy(eth->enetaddr, buf, ETH_ALEN);
-	debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-		eth->enetaddr[0], eth->enetaddr[1],
-		eth->enetaddr[2], eth->enetaddr[3],
-		eth->enetaddr[4], eth->enetaddr[5]);
-
 	dev->phy_id = asix_get_phy_addr(dev);
 	if (dev->phy_id < 0)
 		debug("Failed to read phy id\n");
 
-	if (asix_sw_reset(dev, AX_SWRESET_PRL) < 0)
-		goto out_err;
-
-	if (asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL) < 0)
-		goto out_err;
-
 	asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
 	asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
 			ADVERTISE_ALL | ADVERTISE_CSMA);
 	mii_nway_restart(dev);
 
 	if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
-		goto out_err;
+		return -1;
 
 	if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
 				AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
 				AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
 		debug("Write IPG,IPG1,IPG2 failed\n");
-		goto out_err;
+		return -1;
 	}
 
+	return 0;
+}
+
+/*
+ * Asix callbacks
+ */
+static int asix_init(struct eth_device *eth, bd_t *bd)
+{
+	struct ueth_data	*dev = (struct ueth_data *)eth->priv;
+	int timeout = 0;
+#define TIMEOUT_RESOLUTION 50	/* ms */
+	int link_detected;
+
+	debug("** %s()\n", __func__);
+
 	if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
 		goto out_err;
 
@@ -425,7 +458,8 @@
 	int err;
 	u32 packet_len;
 	int actual_len;
-	unsigned char msg[PKTSIZE + sizeof(packet_len)];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
+		PKTSIZE + sizeof(packet_len));
 
 	debug("** %s(), len %d\n", __func__, length);
 
@@ -452,7 +486,7 @@
 static int asix_recv(struct eth_device *eth)
 {
 	struct ueth_data *dev = (struct ueth_data *)eth->priv;
-	static unsigned char  recv_buf[AX_RX_URB_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, recv_buf, AX_RX_URB_SIZE);
 	unsigned char *buf_ptr;
 	int err;
 	int actual_len;
@@ -489,13 +523,13 @@
 		}
 		memcpy(&packet_len, buf_ptr, sizeof(packet_len));
 		le32_to_cpus(&packet_len);
-		if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) {
+		if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
 			debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
-			      packet_len, (packet_len >> 16) ^ 0xffff,
-			      packet_len & 0xffff);
+			      packet_len, (~packet_len >> 16) & 0x7ff,
+			      packet_len & 0x7ff);
 			return -1;
 		}
-		packet_len = packet_len & 0xffff;
+		packet_len = packet_len & 0x7ff;
 		if (packet_len > actual_len - sizeof(packet_len)) {
 			debug("Rx: too large packet: %d\n", packet_len);
 			return -1;
@@ -530,19 +564,25 @@
 struct asix_dongle {
 	unsigned short vendor;
 	unsigned short product;
+	int flags;
 };
 
-static struct asix_dongle asix_dongles[] = {
-	{ 0x05ac, 0x1402 },	/* Apple USB Ethernet Adapter */
-	{ 0x07d1, 0x3c05 },	/* D-Link DUB-E100 H/W Ver B1 */
-	{ 0x0b95, 0x772a },	/* Cables-to-Go USB Ethernet Adapter */
-	{ 0x0b95, 0x7720 },	/* Trendnet TU2-ET100 V3.0R */
-	{ 0x0b95, 0x1720 },	/* SMC */
-	{ 0x0db0, 0xa877 },	/* MSI - ASIX 88772a */
-	{ 0x13b1, 0x0018 },	/* Linksys 200M v2.1 */
-	{ 0x1557, 0x7720 },	/* 0Q0 cable ethernet */
-	{ 0x2001, 0x3c05 },	/* DLink DUB-E100 H/W Ver B1 Alternate */
-	{ 0x0000, 0x0000 }	/* END - Do not remove */
+static const struct asix_dongle const asix_dongles[] = {
+	{ 0x05ac, 0x1402, FLAG_TYPE_AX88772 },	/* Apple USB Ethernet Adapter */
+	{ 0x07d1, 0x3c05, FLAG_TYPE_AX88772 },	/* D-Link DUB-E100 H/W Ver B1 */
+	{ 0x2001, 0x1a02, FLAG_TYPE_AX88772 },	/* D-Link DUB-E100 H/W Ver C1 */
+	/* Cables-to-Go USB Ethernet Adapter */
+	{ 0x0b95, 0x772a, FLAG_TYPE_AX88772 },
+	{ 0x0b95, 0x7720, FLAG_TYPE_AX88772 },	/* Trendnet TU2-ET100 V3.0R */
+	{ 0x0b95, 0x1720, FLAG_TYPE_AX88172 },	/* SMC */
+	{ 0x0db0, 0xa877, FLAG_TYPE_AX88772 },	/* MSI - ASIX 88772a */
+	{ 0x13b1, 0x0018, FLAG_TYPE_AX88172 },	/* Linksys 200M v2.1 */
+	{ 0x1557, 0x7720, FLAG_TYPE_AX88772 },	/* 0Q0 cable ethernet */
+	/* DLink DUB-E100 H/W Ver B1 Alternate */
+	{ 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
+	/* ASIX 88772B */
+	{ 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+	{ 0x0000, 0x0000, FLAG_NONE }	/* END - Do not remove */
 };
 
 /* Probe to see if a new device is actually an asix device */
@@ -551,6 +591,7 @@
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *iface_desc;
+	int ep_in_found = 0, ep_out_found = 0;
 	int i;
 
 	/* let's examine the device now */
@@ -579,6 +620,13 @@
 	ss->subclass = iface_desc->bInterfaceSubClass;
 	ss->protocol = iface_desc->bInterfaceProtocol;
 
+	/* alloc driver private */
+	ss->dev_priv = calloc(1, sizeof(struct asix_private));
+	if (!ss->dev_priv)
+		return 0;
+
+	((struct asix_private *)ss->dev_priv)->flags = asix_dongles[i].flags;
+
 	/*
 	 * We are expecting a minimum of 3 endpoints - in, out (bulk), and
 	 * int. We will ignore any others.
@@ -587,13 +635,20 @@
 		/* is it an BULK endpoint? */
 		if ((iface->ep_desc[i].bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
-			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
-				ss->ep_in = iface->ep_desc[i].bEndpointAddress &
-					USB_ENDPOINT_NUMBER_MASK;
-			else
-				ss->ep_out =
-					iface->ep_desc[i].bEndpointAddress &
-					USB_ENDPOINT_NUMBER_MASK;
+			u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
+			if (ep_addr & USB_DIR_IN) {
+				if (!ep_in_found) {
+					ss->ep_in = ep_addr &
+						USB_ENDPOINT_NUMBER_MASK;
+					ep_in_found = 1;
+				}
+			} else {
+				if (!ep_out_found) {
+					ss->ep_out = ep_addr &
+						USB_ENDPOINT_NUMBER_MASK;
+					ep_out_found = 1;
+				}
+			}
 		}
 
 		/* is it an interrupt endpoint? */
@@ -620,6 +675,8 @@
 int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
 				struct eth_device *eth)
 {
+	struct asix_private *priv = (struct asix_private *)ss->dev_priv;
+
 	if (!eth) {
 		debug("%s: missing parameter.\n", __func__);
 		return 0;
@@ -629,7 +686,20 @@
 	eth->send = asix_send;
 	eth->recv = asix_recv;
 	eth->halt = asix_halt;
+	if (!(priv->flags & FLAG_TYPE_AX88172))
+		eth->write_hwaddr = asix_write_hwaddr;
 	eth->priv = ss;
 
+	if (asix_basic_reset(ss))
+		return 0;
+
+	/* Get the MAC address */
+	if (asix_read_mac(eth))
+		return 0;
+	printf("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 
+		eth->enetaddr[0], eth->enetaddr[1], 
+		eth->enetaddr[2], eth->enetaddr[3],
+		eth->enetaddr[4], eth->enetaddr[5]);
+
 	return 1;
 }
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/eth/Makefile u-boot-2011.06/drivers/usb/eth/Makefile
--- u-boot-2011.06_original/drivers/usb/eth/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/eth/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -28,6 +28,9 @@
 ifdef CONFIG_USB_ETHER_ASIX
 COBJS-y += asix.o
 endif
+ifdef CONFIG_USB_ETHER_SMSC95XX
+COBJS-y += smsc95xx.o
+endif
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/eth/smsc95xx.c u-boot-2011.06/drivers/usb/eth/smsc95xx.c
--- u-boot-2011.06_original/drivers/usb/eth/smsc95xx.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/usb/eth/smsc95xx.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,897 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (C) 2009 NVIDIA, Corporation
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/unaligned.h>
+#include <common.h>
+#include <usb.h>
+#include <linux/mii.h>
+#include "usb_ether.h"
+#include <malloc.h>
+
+/* SMSC LAN95xx based USB 2.0 Ethernet Devices */
+
+/* LED defines */
+#define LED_GPIO_CFG			(0x24)
+#define LED_GPIO_CFG_SPD_LED		(0x01000000)
+#define LED_GPIO_CFG_LNK_LED		(0x00100000)
+#define LED_GPIO_CFG_FDX_LED		(0x00010000)
+
+/* Tx command words */
+#define TX_CMD_A_FIRST_SEG_		0x00002000
+#define TX_CMD_A_LAST_SEG_		0x00001000
+
+/* Rx status word */
+#define RX_STS_FL_			0x3FFF0000	/* Frame Length */
+#define RX_STS_ES_			0x00008000	/* Error Summary */
+
+/* SCSRs */
+#define ID_REV				0x00
+
+#define INT_STS				0x08
+
+#define TX_CFG				0x10
+#define TX_CFG_ON_			0x00000004
+
+#define HW_CFG				0x14
+#define HW_CFG_BIR_			0x00001000
+#define HW_CFG_RXDOFF_			0x00000600
+#define HW_CFG_MEF_			0x00000020
+#define HW_CFG_BCE_			0x00000002
+#define HW_CFG_LRST_			0x00000008
+
+#define PM_CTRL				0x20
+#define PM_CTL_PHY_RST_			0x00000010
+
+#define AFC_CFG				0x2C
+
+/*
+ * Hi watermark = 15.5Kb (~10 mtu pkts)
+ * low watermark = 3k (~2 mtu pkts)
+ * backpressure duration = ~ 350us
+ * Apply FC on any frame.
+ */
+#define AFC_CFG_DEFAULT			0x00F830A1
+
+#define E2P_CMD				0x30
+#define E2P_CMD_BUSY_			0x80000000
+#define E2P_CMD_READ_			0x00000000
+#define E2P_CMD_TIMEOUT_		0x00000400
+#define E2P_CMD_LOADED_			0x00000200
+#define E2P_CMD_ADDR_			0x000001FF
+
+#define E2P_DATA			0x34
+
+#define BURST_CAP			0x38
+
+#define INT_EP_CTL			0x68
+#define INT_EP_CTL_PHY_INT_		0x00008000
+
+#define BULK_IN_DLY			0x6C
+
+/* MAC CSRs */
+#define MAC_CR				0x100
+#define MAC_CR_MCPAS_			0x00080000
+#define MAC_CR_PRMS_			0x00040000
+#define MAC_CR_HPFILT_			0x00002000
+#define MAC_CR_TXEN_			0x00000008
+#define MAC_CR_RXEN_			0x00000004
+
+#define ADDRH				0x104
+
+#define ADDRL				0x108
+
+#define MII_ADDR			0x114
+#define MII_WRITE_			0x02
+#define MII_BUSY_			0x01
+#define MII_READ_			0x00 /* ~of MII Write bit */
+
+#define MII_DATA			0x118
+
+#define FLOW				0x11C
+
+#define VLAN1				0x120
+
+#define COE_CR				0x130
+#define Tx_COE_EN_			0x00010000
+#define Rx_COE_EN_			0x00000001
+
+/* Vendor-specific PHY Definitions */
+#define PHY_INT_SRC			29
+
+#define PHY_INT_MASK			30
+#define PHY_INT_MASK_ANEG_COMP_		((u16)0x0040)
+#define PHY_INT_MASK_LINK_DOWN_		((u16)0x0010)
+#define PHY_INT_MASK_DEFAULT_		(PHY_INT_MASK_ANEG_COMP_ | \
+					 PHY_INT_MASK_LINK_DOWN_)
+
+/* USB Vendor Requests */
+#define USB_VENDOR_REQUEST_WRITE_REGISTER	0xA0
+#define USB_VENDOR_REQUEST_READ_REGISTER	0xA1
+
+/* Some extra defines */
+#define HS_USB_PKT_SIZE			512
+#define FS_USB_PKT_SIZE			64
+#define DEFAULT_HS_BURST_CAP_SIZE	(16 * 1024 + 5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE	(6 * 1024 + 33 * FS_USB_PKT_SIZE)
+#define DEFAULT_BULK_IN_DELAY		0x00002000
+#define MAX_SINGLE_PACKET_SIZE		2048
+#define EEPROM_MAC_OFFSET		0x01
+#define SMSC95XX_INTERNAL_PHY_ID	1
+#define ETH_P_8021Q	0x8100          /* 802.1Q VLAN Extended Header  */
+
+/* local defines */
+#define SMSC95XX_BASE_NAME "sms"
+#define USB_CTRL_SET_TIMEOUT 5000
+#define USB_CTRL_GET_TIMEOUT 5000
+#define USB_BULK_SEND_TIMEOUT 5000
+#define USB_BULK_RECV_TIMEOUT 5000
+
+#define AX_RX_URB_SIZE 2048
+#define PHY_CONNECT_TIMEOUT 5000
+
+#define TURBO_MODE
+
+/* local vars */
+static int curr_eth_dev; /* index for name of next device detected */
+
+/* driver private */
+struct smsc95xx_private {
+	size_t rx_urb_size;  /* maximum USB URB size */
+	u32 mac_cr;  /* MAC control register value */
+	int have_hwaddr;  /* 1 if we have a hardware MAC address */
+};
+
+/*
+ * Smsc95xx infrastructure commands
+ */
+static int smsc95xx_write_reg(struct ueth_data *dev, u32 index, u32 data)
+{
+	int len;
+	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
+
+	cpu_to_le32s(&data);
+	tmpbuf[0] = data;
+
+	len = usb_control_msg(dev->pusb_dev, usb_sndctrlpipe(dev->pusb_dev, 0),
+		USB_VENDOR_REQUEST_WRITE_REGISTER,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		00, index, tmpbuf, sizeof(data), USB_CTRL_SET_TIMEOUT);
+	if (len != sizeof(data)) {
+		debug("smsc95xx_write_reg failed: index=%d, data=%d, len=%d",
+		      index, data, len);
+		return -1;
+	}
+	return 0;
+}
+
+static int smsc95xx_read_reg(struct ueth_data *dev, u32 index, u32 *data)
+{
+	int len;
+	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
+
+	len = usb_control_msg(dev->pusb_dev, usb_rcvctrlpipe(dev->pusb_dev, 0),
+		USB_VENDOR_REQUEST_READ_REGISTER,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		00, index, tmpbuf, sizeof(data), USB_CTRL_GET_TIMEOUT);
+	*data = tmpbuf[0];
+	if (len != sizeof(data)) {
+		debug("smsc95xx_read_reg failed: index=%d, len=%d",
+		      index, len);
+		return -1;
+	}
+
+	le32_to_cpus(data);
+	return 0;
+}
+
+/* Loop until the read is completed with timeout */
+static int smsc95xx_phy_wait_not_busy(struct ueth_data *dev)
+{
+	unsigned long start_time = get_timer(0);
+	u32 val;
+
+	do {
+		smsc95xx_read_reg(dev, MII_ADDR, &val);
+		if (!(val & MII_BUSY_))
+			return 0;
+	} while (get_timer(start_time) < 1 * 1000 * 1000);
+
+	return -1;
+}
+
+static int smsc95xx_mdio_read(struct ueth_data *dev, int phy_id, int idx)
+{
+	u32 val, addr;
+
+	/* confirm MII not busy */
+	if (smsc95xx_phy_wait_not_busy(dev)) {
+		debug("MII is busy in smsc95xx_mdio_read\n");
+		return -1;
+	}
+
+	/* set the address, index & direction (read from PHY) */
+	addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+	smsc95xx_write_reg(dev, MII_ADDR, addr);
+
+	if (smsc95xx_phy_wait_not_busy(dev)) {
+		debug("Timed out reading MII reg %02X\n", idx);
+		return -1;
+	}
+
+	smsc95xx_read_reg(dev, MII_DATA, &val);
+
+	return (u16)(val & 0xFFFF);
+}
+
+static void smsc95xx_mdio_write(struct ueth_data *dev, int phy_id, int idx,
+				int regval)
+{
+	u32 val, addr;
+
+	/* confirm MII not busy */
+	if (smsc95xx_phy_wait_not_busy(dev)) {
+		debug("MII is busy in smsc95xx_mdio_write\n");
+		return;
+	}
+
+	val = regval;
+	smsc95xx_write_reg(dev, MII_DATA, val);
+
+	/* set the address, index & direction (write to PHY) */
+	addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+	smsc95xx_write_reg(dev, MII_ADDR, addr);
+
+	if (smsc95xx_phy_wait_not_busy(dev))
+		debug("Timed out writing MII reg %02X\n", idx);
+}
+
+static int smsc95xx_eeprom_confirm_not_busy(struct ueth_data *dev)
+{
+	unsigned long start_time = get_timer(0);
+	u32 val;
+
+	do {
+		smsc95xx_read_reg(dev, E2P_CMD, &val);
+		if (!(val & E2P_CMD_BUSY_))
+			return 0;
+		udelay(40);
+	} while (get_timer(start_time) < 1 * 1000 * 1000);
+
+	debug("EEPROM is busy\n");
+	return -1;
+}
+
+static int smsc95xx_wait_eeprom(struct ueth_data *dev)
+{
+	unsigned long start_time = get_timer(0);
+	u32 val;
+
+	do {
+		smsc95xx_read_reg(dev, E2P_CMD, &val);
+		if (!(val & E2P_CMD_BUSY_) || (val & E2P_CMD_TIMEOUT_))
+			break;
+		udelay(40);
+	} while (get_timer(start_time) < 1 * 1000 * 1000);
+
+	if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) {
+		debug("EEPROM read operation timeout\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int smsc95xx_read_eeprom(struct ueth_data *dev, u32 offset, u32 length,
+				u8 *data)
+{
+	u32 val;
+	int i, ret;
+
+	ret = smsc95xx_eeprom_confirm_not_busy(dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < length; i++) {
+		val = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (offset & E2P_CMD_ADDR_);
+		smsc95xx_write_reg(dev, E2P_CMD, val);
+
+		ret = smsc95xx_wait_eeprom(dev);
+		if (ret < 0)
+			return ret;
+
+		smsc95xx_read_reg(dev, E2P_DATA, &val);
+		data[i] = val & 0xFF;
+		offset++;
+	}
+	return 0;
+}
+
+/*
+ * mii_nway_restart - restart NWay (autonegotiation) for this interface
+ *
+ * Returns 0 on success, negative on error.
+ */
+static int mii_nway_restart(struct ueth_data *dev)
+{
+	int bmcr;
+	int r = -1;
+
+	/* if autoneg is off, it's an error */
+	bmcr = smsc95xx_mdio_read(dev, dev->phy_id, MII_BMCR);
+
+	if (bmcr & BMCR_ANENABLE) {
+		bmcr |= BMCR_ANRESTART;
+		smsc95xx_mdio_write(dev, dev->phy_id, MII_BMCR, bmcr);
+		r = 0;
+	}
+	return r;
+}
+
+static int smsc95xx_phy_initialize(struct ueth_data *dev)
+{
+	smsc95xx_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
+	smsc95xx_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
+		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
+		ADVERTISE_PAUSE_ASYM);
+
+	/* read to clear */
+	smsc95xx_mdio_read(dev, dev->phy_id, PHY_INT_SRC);
+
+	smsc95xx_mdio_write(dev, dev->phy_id, PHY_INT_MASK,
+		PHY_INT_MASK_DEFAULT_);
+	mii_nway_restart(dev);
+
+	debug("phy initialised succesfully\n");
+	return 0;
+}
+
+static int smsc95xx_init_mac_address(struct eth_device *eth,
+		struct ueth_data *dev)
+{
+	/* try reading mac address from EEPROM */
+	if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+			eth->enetaddr) == 0) {
+		if (is_valid_ether_addr(eth->enetaddr)) {
+			/* eeprom values are valid so use them */
+			debug("MAC address read from EEPROM\n");
+			return 0;
+		}
+	}
+
+	/*
+	 * No eeprom, or eeprom values are invalid. Generating a random MAC
+	 * address is not safe. Just return an error.
+	 */
+	return -1;
+}
+
+static int smsc95xx_write_hwaddr(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct smsc95xx_private *priv = dev->dev_priv;
+	u32 addr_lo = __get_unaligned_le32(&eth->enetaddr[0]);
+	u32 addr_hi = __get_unaligned_le16(&eth->enetaddr[4]);
+	int ret;
+
+	/* set hardware address */
+	debug("** %s()\n", __func__);
+	ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_write_reg(dev, ADDRH, addr_hi);
+	if (ret < 0)
+		return ret;
+
+	debug("MAC %pM\n", eth->enetaddr);
+	priv->have_hwaddr = 1;
+	return 0;
+}
+
+/* Enable or disable Tx & Rx checksum offload engines */
+static int smsc95xx_set_csums(struct ueth_data *dev,
+		int use_tx_csum, int use_rx_csum)
+{
+	u32 read_buf;
+	int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
+	if (ret < 0)
+		return ret;
+
+	if (use_tx_csum)
+		read_buf |= Tx_COE_EN_;
+	else
+		read_buf &= ~Tx_COE_EN_;
+
+	if (use_rx_csum)
+		read_buf |= Rx_COE_EN_;
+	else
+		read_buf &= ~Rx_COE_EN_;
+
+	ret = smsc95xx_write_reg(dev, COE_CR, read_buf);
+	if (ret < 0)
+		return ret;
+
+	debug("COE_CR = 0x%08x\n", read_buf);
+	return 0;
+}
+
+static void smsc95xx_set_multicast(struct ueth_data *dev)
+{
+	struct smsc95xx_private *priv = dev->dev_priv;
+
+	/* No multicast in u-boot */
+	priv->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
+}
+
+/* starts the TX path */
+static void smsc95xx_start_tx_path(struct ueth_data *dev)
+{
+	struct smsc95xx_private *priv = dev->dev_priv;
+	u32 reg_val;
+
+	/* Enable Tx at MAC */
+	priv->mac_cr |= MAC_CR_TXEN_;
+
+	smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr);
+
+	/* Enable Tx at SCSRs */
+	reg_val = TX_CFG_ON_;
+	smsc95xx_write_reg(dev, TX_CFG, reg_val);
+}
+
+/* Starts the Receive path */
+static void smsc95xx_start_rx_path(struct ueth_data *dev)
+{
+	struct smsc95xx_private *priv = dev->dev_priv;
+
+	priv->mac_cr |= MAC_CR_RXEN_;
+	smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr);
+}
+
+/*
+ * Smsc95xx callbacks
+ */
+static int smsc95xx_init(struct eth_device *eth, bd_t *bd)
+{
+	int ret;
+	u32 write_buf;
+	u32 read_buf;
+	u32 burst_cap;
+	int timeout;
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct smsc95xx_private *priv =
+		(struct smsc95xx_private *)dev->dev_priv;
+#define TIMEOUT_RESOLUTION 50	/* ms */
+	int link_detected;
+
+	debug("** %s()\n", __func__);
+	dev->phy_id = SMSC95XX_INTERNAL_PHY_ID; /* fixed phy id */
+
+	write_buf = HW_CFG_LRST_;
+	ret = smsc95xx_write_reg(dev, HW_CFG, write_buf);
+	if (ret < 0)
+		return ret;
+
+	timeout = 0;
+	do {
+		ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+		if (ret < 0)
+			return ret;
+		udelay(10 * 1000);
+		timeout++;
+	} while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
+
+	if (timeout >= 100) {
+		debug("timeout waiting for completion of Lite Reset\n");
+		return -1;
+	}
+
+	write_buf = PM_CTL_PHY_RST_;
+	ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf);
+	if (ret < 0)
+		return ret;
+
+	timeout = 0;
+	do {
+		ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
+		if (ret < 0)
+			return ret;
+		udelay(10 * 1000);
+		timeout++;
+	} while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
+	if (timeout >= 100) {
+		debug("timeout waiting for PHY Reset\n");
+		return -1;
+	}
+	if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0)
+		priv->have_hwaddr = 1;
+	if (!priv->have_hwaddr) {
+		puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n");
+		return -1;
+	}
+	if (smsc95xx_write_hwaddr(eth) < 0)
+		return -1;
+
+	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from HW_CFG : 0x%08x\n", read_buf);
+
+	read_buf |= HW_CFG_BIR_;
+	ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from HW_CFG after writing "
+		"HW_CFG_BIR_: 0x%08x\n", read_buf);
+
+#ifdef TURBO_MODE
+	if (dev->pusb_dev->speed == USB_SPEED_HIGH) {
+		burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
+		priv->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+	} else {
+		burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
+		priv->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+	}
+#else
+	burst_cap = 0;
+	priv->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+#endif
+	debug("rx_urb_size=%ld\n", (ulong)priv->rx_urb_size);
+
+	ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from BURST_CAP after writing: 0x%08x\n", read_buf);
+
+	read_buf = DEFAULT_BULK_IN_DELAY;
+	ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from BULK_IN_DLY after writing: "
+			"0x%08x\n", read_buf);
+
+	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from HW_CFG: 0x%08x\n", read_buf);
+
+#ifdef TURBO_MODE
+	read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_);
+#endif
+	read_buf &= ~HW_CFG_RXDOFF_;
+
+#define NET_IP_ALIGN 0
+	read_buf |= NET_IP_ALIGN << 9;
+
+	ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
+
+	write_buf = 0xFFFFFFFF;
+	ret = smsc95xx_write_reg(dev, INT_STS, write_buf);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, ID_REV, &read_buf);
+	if (ret < 0)
+		return ret;
+	debug("ID_REV = 0x%08x\n", read_buf);
+
+	/* Configure GPIO pins as LED outputs */
+	write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
+		LED_GPIO_CFG_FDX_LED;
+	ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
+	if (ret < 0)
+		return ret;
+	debug("LED_GPIO_CFG set\n");
+
+	/* Init Tx */
+	write_buf = 0;
+	ret = smsc95xx_write_reg(dev, FLOW, write_buf);
+	if (ret < 0)
+		return ret;
+
+	read_buf = AFC_CFG_DEFAULT;
+	ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf);
+	if (ret < 0)
+		return ret;
+
+	ret = smsc95xx_read_reg(dev, MAC_CR, &priv->mac_cr);
+	if (ret < 0)
+		return ret;
+
+	/* Init Rx. Set Vlan */
+	write_buf = (u32)ETH_P_8021Q;
+	ret = smsc95xx_write_reg(dev, VLAN1, write_buf);
+	if (ret < 0)
+		return ret;
+
+	/* Disable checksum offload engines */
+	ret = smsc95xx_set_csums(dev, 0, 0);
+	if (ret < 0) {
+		debug("Failed to set csum offload: %d\n", ret);
+		return ret;
+	}
+	smsc95xx_set_multicast(dev);
+
+	if (smsc95xx_phy_initialize(dev) < 0)
+		return -1;
+	ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf);
+	if (ret < 0)
+		return ret;
+
+	/* enable PHY interrupts */
+	read_buf |= INT_EP_CTL_PHY_INT_;
+
+	ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf);
+	if (ret < 0)
+		return ret;
+
+	smsc95xx_start_tx_path(dev);
+	smsc95xx_start_rx_path(dev);
+
+	timeout = 0;
+	do {
+		link_detected = smsc95xx_mdio_read(dev, dev->phy_id, MII_BMSR)
+			& BMSR_LSTATUS;
+		if (!link_detected) {
+			if (timeout == 0)
+				printf("Waiting for Ethernet connection... ");
+			udelay(TIMEOUT_RESOLUTION * 1000);
+			timeout += TIMEOUT_RESOLUTION;
+		}
+	} while (!link_detected && timeout < PHY_CONNECT_TIMEOUT);
+	if (link_detected) {
+		if (timeout != 0)
+			printf("done.\n");
+	} else {
+		printf("unable to connect.\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int smsc95xx_send(struct eth_device *eth, volatile void* packet, int length)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	int err;
+	int actual_len;
+	u32 tx_cmd_a;
+	u32 tx_cmd_b;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
+				 PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
+
+	debug("** %s(), len %d, buf %#x\n", __func__, length, (int)msg);
+	if (length > PKTSIZE)
+		return -1;
+
+	tx_cmd_a = (u32)length | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
+	tx_cmd_b = (u32)length;
+	cpu_to_le32s(&tx_cmd_a);
+	cpu_to_le32s(&tx_cmd_b);
+
+	/* prepend cmd_a and cmd_b */
+	memcpy(msg, &tx_cmd_a, sizeof(tx_cmd_a));
+	memcpy(msg + sizeof(tx_cmd_a), &tx_cmd_b, sizeof(tx_cmd_b));
+	memcpy(msg + sizeof(tx_cmd_a) + sizeof(tx_cmd_b), (void *)packet,
+	       length);
+	err = usb_bulk_msg(dev->pusb_dev,
+				usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
+				(void *)msg,
+				length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b),
+				&actual_len,
+				USB_BULK_SEND_TIMEOUT);
+	debug("Tx: len = %u, actual = %u, err = %d\n",
+	      length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b),
+	      actual_len, err);
+	return err;
+}
+
+static int smsc95xx_recv(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	DEFINE_CACHE_ALIGN_BUFFER(unsigned char, recv_buf, AX_RX_URB_SIZE);
+	unsigned char *buf_ptr;
+	int err;
+	int actual_len;
+	u32 packet_len;
+	int cur_buf_align;
+
+	debug("** %s()\n", __func__);
+	err = usb_bulk_msg(dev->pusb_dev,
+				usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
+				(void *)recv_buf,
+				AX_RX_URB_SIZE,
+				&actual_len,
+				USB_BULK_RECV_TIMEOUT);
+	debug("Rx: len = %u, actual = %u, err = %d\n", AX_RX_URB_SIZE,
+	      actual_len, err);
+	if (err != 0) {
+		debug("Rx: failed to receive\n");
+		return -1;
+	}
+	if (actual_len > AX_RX_URB_SIZE) {
+		debug("Rx: received too many bytes %d\n", actual_len);
+		return -1;
+	}
+
+	buf_ptr = recv_buf;
+	while (actual_len > 0) {
+		/*
+		 * 1st 4 bytes contain the length of the actual data plus error
+		 * info. Extract data length.
+		 */
+		if (actual_len < sizeof(packet_len)) {
+			debug("Rx: incomplete packet length\n");
+			return -1;
+		}
+		memcpy(&packet_len, buf_ptr, sizeof(packet_len));
+		le32_to_cpus(&packet_len);
+		if (packet_len & RX_STS_ES_) {
+			debug("Rx: Error header=%#x", packet_len);
+			return -1;
+		}
+		packet_len = ((packet_len & RX_STS_FL_) >> 16);
+
+		if (packet_len > actual_len - sizeof(packet_len)) {
+			debug("Rx: too large packet: %d\n", packet_len);
+			return -1;
+		}
+
+		/* Notify net stack */
+		NetReceive(buf_ptr + sizeof(packet_len), packet_len - 4);
+
+		/* Adjust for next iteration */
+		actual_len -= sizeof(packet_len) + packet_len;
+		buf_ptr += sizeof(packet_len) + packet_len;
+		cur_buf_align = (int)buf_ptr - (int)recv_buf;
+
+		if (cur_buf_align & 0x03) {
+			int align = 4 - (cur_buf_align & 0x03);
+
+			actual_len -= align;
+			buf_ptr += align;
+		}
+	}
+	return err;
+}
+
+static void smsc95xx_halt(struct eth_device *eth)
+{
+	debug("** %s()\n", __func__);
+}
+
+/*
+ * SMSC probing functions
+ */
+void smsc95xx_eth_before_probe(void)
+{
+	curr_eth_dev = 0;
+}
+
+struct smsc95xx_dongle {
+	unsigned short vendor;
+	unsigned short product;
+};
+
+static const struct smsc95xx_dongle smsc95xx_dongles[] = {
+	{ 0x0424, 0xec00 },	/* LAN9512/LAN9514 Ethernet */
+	{ 0x0424, 0x9500 },	/* LAN9500 Ethernet */
+	{ 0x0424, 0x9730 },	/* LAN9730 Ethernet (HSIC) */
+	{ 0x0424, 0x9900 },	/* SMSC9500 USB Ethernet Device (SAL10) */
+	{ 0x0000, 0x0000 }	/* END - Do not remove */
+};
+
+/* Probe to see if a new device is actually an SMSC device */
+int smsc95xx_eth_probe(struct usb_device *dev, unsigned int ifnum,
+		      struct ueth_data *ss)
+{
+	struct usb_interface *iface;
+	struct usb_interface_descriptor *iface_desc;
+	int i;
+
+	/* let's examine the device now */
+	iface = &dev->config.if_desc[ifnum];
+	iface_desc = &dev->config.if_desc[ifnum].desc;
+
+	for (i = 0; smsc95xx_dongles[i].vendor != 0; i++) {
+		if (dev->descriptor.idVendor == smsc95xx_dongles[i].vendor &&
+		    dev->descriptor.idProduct == smsc95xx_dongles[i].product)
+			/* Found a supported dongle */
+			break;
+	}
+	if (smsc95xx_dongles[i].vendor == 0)
+		return 0;
+
+	/* At this point, we know we've got a live one */
+	debug("\n\nUSB Ethernet device detected\n");
+	memset(ss, '\0', sizeof(struct ueth_data));
+
+	/* Initialize the ueth_data structure with some useful info */
+	ss->ifnum = ifnum;
+	ss->pusb_dev = dev;
+	ss->subclass = iface_desc->bInterfaceSubClass;
+	ss->protocol = iface_desc->bInterfaceProtocol;
+
+	/*
+	 * We are expecting a minimum of 3 endpoints - in, out (bulk), and int.
+	 * We will ignore any others.
+	 */
+	for (i = 0; i < iface_desc->bNumEndpoints; i++) {
+		/* is it an BULK endpoint? */
+		if ((iface->ep_desc[i].bmAttributes &
+		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
+			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
+				ss->ep_in =
+					iface->ep_desc[i].bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+			else
+				ss->ep_out =
+					iface->ep_desc[i].bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+		}
+
+		/* is it an interrupt endpoint? */
+		if ((iface->ep_desc[i].bmAttributes &
+		    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
+			ss->ep_int = iface->ep_desc[i].bEndpointAddress &
+				USB_ENDPOINT_NUMBER_MASK;
+			ss->irqinterval = iface->ep_desc[i].bInterval;
+		}
+	}
+	debug("Endpoints In %d Out %d Int %d\n",
+		  ss->ep_in, ss->ep_out, ss->ep_int);
+
+	/* Do some basic sanity checks, and bail if we find a problem */
+	if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
+	    !ss->ep_in || !ss->ep_out || !ss->ep_int) {
+		debug("Problems with device\n");
+		return 0;
+	}
+	dev->privptr = (void *)ss;
+
+	/* alloc driver private */
+	ss->dev_priv = calloc(1, sizeof(struct smsc95xx_private));
+	if (!ss->dev_priv)
+		return 0;
+
+	return 1;
+}
+
+int smsc95xx_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
+				struct eth_device *eth)
+{
+	debug("** %s()\n", __func__);
+	if (!eth) {
+		debug("%s: missing parameter.\n", __func__);
+		return 0;
+	}
+	sprintf(eth->name, "%s%d", SMSC95XX_BASE_NAME, curr_eth_dev++);
+	eth->init = smsc95xx_init;
+	eth->send = smsc95xx_send;
+	eth->recv = smsc95xx_recv;
+	eth->halt = smsc95xx_halt;
+	eth->write_hwaddr = smsc95xx_write_hwaddr;
+	eth->priv = ss;
+	return 1;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/eth/usb_ether.c u-boot-2011.06/drivers/usb/eth/usb_ether.c
--- u-boot-2011.06_original/drivers/usb/eth/usb_ether.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/eth/usb_ether.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,22 +1,7 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
- * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
@@ -45,6 +30,13 @@
 		.get_info = asix_eth_get_info,
 	},
 #endif
+#ifdef CONFIG_USB_ETHER_SMSC95XX
+	{
+		.before_probe = smsc95xx_eth_before_probe,
+		.probe = smsc95xx_eth_probe,
+		.get_info = smsc95xx_eth_get_info,
+	},
+#endif
 	{ },		/* END */
 };
 
@@ -73,6 +65,7 @@
  */
 static void probe_valid_drivers(struct usb_device *dev)
 {
+	struct eth_device *eth;
 	int j;
 
 	for (j = 0; prob_dev[j].probe && prob_dev[j].get_info; j++) {
@@ -81,9 +74,10 @@
 		/*
 		 * ok, it is a supported eth device. Get info and fill it in
 		 */
+		eth = &usb_eth[usb_max_eth_dev].eth_dev;
 		if (prob_dev[j].get_info(dev,
 			&usb_eth[usb_max_eth_dev],
-			&usb_eth[usb_max_eth_dev].eth_dev)) {
+			eth)) {
 			/* found proper driver */
 			/* register with networking stack */
 			usb_max_eth_dev++;
@@ -93,7 +87,12 @@
 			 * call since eth_current_changed (internally called)
 			 * relies on it
 			 */
-			eth_register(&usb_eth[usb_max_eth_dev - 1].eth_dev);
+			eth_register(eth);
+#if 0 
+			if (eth_write_hwaddr(eth, "usbeth",
+					usb_max_eth_dev - 1))
+				puts("Warning: failed to set MAC address\n");
+#endif
 			break;
 			}
 		}
@@ -111,12 +110,15 @@
 
 
 	if (mode == 1)
-		printf("       scanning bus for ethernet devices... ");
+		printf("       scanning usb for ethernet devices... ");
 
 	old_async = usb_disable_asynch(1); /* asynch transfer not allowed */
 
-	for (i = 0; i < USB_MAX_ETH_DEV; i++)
-		memset(&usb_eth[i], 0, sizeof(usb_eth[i]));
+	/* unregister a previously detected device */
+	for (i = 0; i < usb_max_eth_dev; i++)
+		eth_unregister(&usb_eth[i].eth_dev);
+
+	memset(usb_eth, 0, sizeof(usb_eth));
 
 	for (i = 0; prob_dev[i].probe; i++) {
 		if (prob_dev[i].before_probe)
@@ -128,7 +130,7 @@
 		dev = usb_get_dev_index(i); /* get device */
 		debug("i=%d\n", i);
 		if (dev == NULL)
-			break; /* no more devices avaiable */
+			break; /* no more devices available */
 
 		/* find valid usb_ether driver for this device, if any */
 		probe_valid_drivers(dev);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/host/ehci-cnc.c u-boot-2011.06/drivers/usb/host/ehci-cnc.c
--- u-boot-2011.06_original/drivers/usb/host/ehci-cnc.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/drivers/usb/host/ehci-cnc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,47 @@
+/****************************************************************************
+  * Copyright (C) 2012 Cavium Inc.
+  * All rights reserved
+  *
+  * [RELEASE HISTORY]                           
+  * VERSION  DATE       AUTHOR                  DESCRIPTION
+  * 0.1      12-6-4     Guo Yi         		Original
+  *****************************************************************************/
+
+#include <common.h>
+#include <usb.h>
+#include <asm/io.h>
+
+#include "ehci.h"
+#include "ehci-core.h"
+
+/*
+ * Initialize SOC EHCI Controller
+ */
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+{
+	*((volatile unsigned long *)0xb2100140) |= (1<<25);
+	udelay(100);
+	*((volatile unsigned long *)0xb2100200) |= 0xff800000;
+	udelay(100);
+	*((volatile unsigned long *)0xb2100390) =0x0;
+	udelay(100);
+	/* Hook the memory mapped registers for EHCI-Controller */
+	*hccr = (struct ehci_hccr *)CONFIG_SYS_USB_EHCI_REGS_BASE;
+	*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+				HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
+	return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(int index)
+{
+	/* Stop the USB controller */
+	*((volatile unsigned long *)0xb2100218) =0x0;
+
+	return 0;
+}
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/host/ehci.h u-boot-2011.06/drivers/usb/host/ehci.h
--- u-boot-2011.06_original/drivers/usb/host/ehci.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/host/ehci.h	2014-08-28 18:12:18.974057000 +0800
@@ -22,26 +22,12 @@
 #ifndef USB_EHCI_H
 #define USB_EHCI_H
 
+#include <usb.h>
+
 #if !defined(CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS	2
 #endif
 
-/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
-#define DeviceRequest \
-	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
-
-#define DeviceOutRequest \
-	((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
-
-#define InterfaceRequest \
-	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
-
-#define EndpointRequest \
-	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
-
-#define EndpointOutRequest \
-	((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
-
 /*
  * Register Space.
  */
@@ -55,7 +41,7 @@
 #define HCS_N_PORTS(p)		(((p) >> 0) & 0xf)
 	uint32_t cr_hccparams;
 	uint8_t cr_hcsp_portrt[8];
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
 
 struct ehci_hcor {
 	uint32_t or_usbcmd;
@@ -68,7 +54,8 @@
 #define CMD_RESET	(1 << 1)		/* reset HC not bus */
 #define CMD_RUN		(1 << 0)		/* start/stop HC */
 	uint32_t or_usbsts;
-#define	STD_ASS		(1 << 15)
+#define STS_ASS		(1 << 15)
+#define	STS_PSS		(1 << 14)
 #define STS_HALT	(1 << 12)
 	uint32_t or_usbintr;
 #define INTR_UE         (1 << 0)                /* USB interrupt enable */
@@ -80,12 +67,21 @@
 	uint32_t or_ctrldssegment;
 	uint32_t or_periodiclistbase;
 	uint32_t or_asynclistaddr;
-	uint32_t _reserved_[9];
+	uint32_t _reserved_0_;
+	uint32_t or_burstsize;
+	uint32_t or_txfilltuning;
+#define TXFIFO_THRESH_MASK		(0x3f << 16)
+#define TXFIFO_THRESH(p)		((p & 0x3f) << 16)
+	uint32_t _reserved_1_[6];
 	uint32_t or_configflag;
 #define FLAG_CF		(1 << 0)	/* true:  we'll support "high speed" */
 	uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS];
+#define PORTSC_PSPD(x)		(((x) >> 26) & 0x3)
+#define PORTSC_PSPD_FS			0x0
+#define PORTSC_PSPD_LS			0x1
+#define PORTSC_PSPD_HS			0x2
 	uint32_t or_systune;
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
 
 #define USBMODE		0x68		/* USB Device mode */
 #define USBMODE_SDIS	(1 << 3)	/* Stream disable */
@@ -167,16 +163,40 @@
 /* Queue Element Transfer Descriptor (qTD). */
 struct qTD {
 	/* this part defined by EHCI spec */
-	uint32_t qt_next;		/* see EHCI 3.5.1 */
+	uint32_t qt_next;			/* see EHCI 3.5.1 */
 #define	QT_NEXT_TERMINATE	1
-	uint32_t qt_altnext;		/* see EHCI 3.5.2 */
-	uint32_t qt_token;		/* see EHCI 3.5.3 */
-	uint32_t qt_buffer[5];		/* see EHCI 3.5.4 */
-	uint32_t qt_buffer_hi[5];	/* Appendix B */
+	uint32_t qt_altnext;			/* see EHCI 3.5.2 */
+	uint32_t qt_token;			/* see EHCI 3.5.3 */
+#define QT_TOKEN_DT(x)		(((x) & 0x1) << 31)	/* Data Toggle */
+#define QT_TOKEN_GET_DT(x)		(((x) >> 31) & 0x1)
+#define QT_TOKEN_TOTALBYTES(x)	(((x) & 0x7fff) << 16)	/* Total Bytes to Transfer */
+#define QT_TOKEN_GET_TOTALBYTES(x)	(((x) >> 16) & 0x7fff)
+#define QT_TOKEN_IOC(x)		(((x) & 0x1) << 15)	/* Interrupt On Complete */
+#define QT_TOKEN_CPAGE(x)	(((x) & 0x7) << 12)	/* Current Page */
+#define QT_TOKEN_CERR(x)	(((x) & 0x3) << 10)	/* Error Counter */
+#define QT_TOKEN_PID(x)		(((x) & 0x3) << 8)	/* PID Code */
+#define QT_TOKEN_PID_OUT		0x0
+#define QT_TOKEN_PID_IN			0x1
+#define QT_TOKEN_PID_SETUP		0x2
+#define QT_TOKEN_STATUS(x)	(((x) & 0xff) << 0)	/* Status */
+#define QT_TOKEN_GET_STATUS(x)		(((x) >> 0) & 0xff)
+#define QT_TOKEN_STATUS_ACTIVE		0x80
+#define QT_TOKEN_STATUS_HALTED		0x40
+#define QT_TOKEN_STATUS_DATBUFERR	0x20
+#define QT_TOKEN_STATUS_BABBLEDET	0x10
+#define QT_TOKEN_STATUS_XACTERR		0x08
+#define QT_TOKEN_STATUS_MISSEDUFRAME	0x04
+#define QT_TOKEN_STATUS_SPLITXSTATE	0x02
+#define QT_TOKEN_STATUS_PERR		0x01
+#define QT_BUFFER_CNT		5
+	uint32_t qt_buffer[QT_BUFFER_CNT];	/* see EHCI 3.5.4 */
+	uint32_t qt_buffer_hi[QT_BUFFER_CNT];	/* Appendix B */
 	/* pad struct for 32 byte alignment */
 	uint32_t unused[3];
 };
 
+#define EHCI_PAGE_SIZE		4096
+
 /* Queue Head (QH). */
 struct QH {
 	uint32_t qh_link;
@@ -186,18 +206,52 @@
 #define	QH_LINK_TYPE_SITD	4
 #define	QH_LINK_TYPE_FSTN	6
 	uint32_t qh_endpt1;
+#define QH_ENDPT1_RL(x)		(((x) & 0xf) << 28)	/* NAK Count Reload */
+#define QH_ENDPT1_C(x)		(((x) & 0x1) << 27)	/* Control Endpoint Flag */
+#define QH_ENDPT1_MAXPKTLEN(x)	(((x) & 0x7ff) << 16)	/* Maximum Packet Length */
+#define QH_ENDPT1_H(x)		(((x) & 0x1) << 15)	/* Head of Reclamation List Flag */
+#define QH_ENDPT1_DTC(x)	(((x) & 0x1) << 14)	/* Data Toggle Control */
+#define QH_ENDPT1_DTC_IGNORE_QTD_TD	0x0
+#define QH_ENDPT1_DTC_DT_FROM_QTD	0x1
+#define QH_ENDPT1_EPS(x)	(((x) & 0x3) << 12)	/* Endpoint Speed */
+#define QH_ENDPT1_EPS_FS		0x0
+#define QH_ENDPT1_EPS_LS		0x1
+#define QH_ENDPT1_EPS_HS		0x2
+#define QH_ENDPT1_ENDPT(x)	(((x) & 0xf) << 8)	/* Endpoint Number */
+#define QH_ENDPT1_I(x)		(((x) & 0x1) << 7)	/* Inactivate on Next Transaction */
+#define QH_ENDPT1_DEVADDR(x)	(((x) & 0x7f) << 0)	/* Device Address */
 	uint32_t qh_endpt2;
+#define QH_ENDPT2_MULT(x)	(((x) & 0x3) << 30)	/* High-Bandwidth Pipe Multiplier */
+#define QH_ENDPT2_PORTNUM(x)	(((x) & 0x7f) << 23)	/* Port Number */
+#define QH_ENDPT2_HUBADDR(x)	(((x) & 0x7f) << 16)	/* Hub Address */
+#define QH_ENDPT2_UFCMASK(x)	(((x) & 0xff) << 8)	/* Split Completion Mask */
+#define QH_ENDPT2_UFSMASK(x)	(((x) & 0xff) << 0)	/* Interrupt Schedule Mask */
 	uint32_t qh_curtd;
 	struct qTD qh_overlay;
 	/*
 	 * Add dummy fill value to make the size of this struct
 	 * aligned to 32 bytes
 	 */
-	uint8_t fill[16];
+	union {
+		uint32_t fill[4];
+		void *buffer;
+	};
+};
+
+struct ehci_ctrl {
+	struct ehci_hccr *hccr;	/* R/O registers, not need for volatile */
+	struct ehci_hcor *hcor;
+	int rootdev;
+	uint16_t portreset;
+	struct QH qh_list __aligned(USB_DMA_MINALIGN);
+	struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
+	uint32_t *periodic_list;
+	int ntds;
 };
 
 /* Low level init functions */
-int ehci_hcd_init(void);
-int ehci_hcd_stop(void);
+int ehci_hcd_init(int index, 
+		struct ehci_hccr **hccr, struct ehci_hcor **hcor);
+int ehci_hcd_stop(int index);
 
 #endif /* USB_EHCI_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/host/ehci-hcd.c u-boot-2011.06/drivers/usb/host/ehci-hcd.c
--- u-boot-2011.06_original/drivers/usb/host/ehci-hcd.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/host/ehci-hcd.c	2014-08-28 18:12:18.974057000 +0800
@@ -21,20 +21,31 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <errno.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <usb.h>
 #include <asm/io.h>
 #include <malloc.h>
 #include <watchdog.h>
+#include <linux/compiler.h>
 
 #include "ehci.h"
 
-int rootdev;
-struct ehci_hccr *hccr;	/* R/O registers, not need for volatile */
-volatile struct ehci_hcor *hcor;
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#endif
+
+/*
+ * EHCI spec page 20 says that the HC may take up to 16 uFrames (= 4ms) to halt.
+ * Let's time out after 8 to have a little safety margin on top of that.
+ */
+#define HCHALT_TIMEOUT (8 * 1000)
 
-static uint16_t portreset;
-static struct QH qh_list __attribute__((aligned(32)));
+static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+
+#define ALIGN_END_ADDR(type, ptr, size)			\
+	((uint32_t)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
 
 static struct descriptor {
 	struct usb_hub_descriptor hub;
@@ -48,7 +59,7 @@
 		0x29,		/* bDescriptorType: hub descriptor */
 		2,		/* bNrPorts -- runtime modified */
 		0,		/* wHubCharacteristics */
-		0xff,		/* bPwrOn2PwrGood */
+		10,		/* bPwrOn2PwrGood */
 		0,		/* bHubCntrCurrent */
 		{},		/* Device removable */
 		{}		/* at most 7 ports! XXX */
@@ -108,98 +119,38 @@
 #define ehci_is_TDI()	(0)
 #endif
 
-#if defined(CONFIG_EHCI_DCACHE)
-/*
- * Routines to handle (flush/invalidate) the dcache for the QH and qTD
- * structures and data buffers. This is needed on platforms using this
- * EHCI support with dcache enabled.
- */
-static void flush_invalidate(u32 addr, int size, int flush)
+int __ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
 {
-	if (flush)
-		flush_dcache_range(addr, addr + size);
-	else
-		invalidate_dcache_range(addr, addr + size);
+	return PORTSC_PSPD(reg);
 }
 
-static void cache_qtd(struct qTD *qtd, int flush)
-{
-	u32 *ptr = (u32 *)qtd->qt_buffer[0];
-	int len = (qtd->qt_token & 0x7fff0000) >> 16;
-
-	flush_invalidate((u32)qtd, sizeof(struct qTD), flush);
-	if (ptr && len)
-		flush_invalidate((u32)ptr, len, flush);
-}
-
-
-static inline struct QH *qh_addr(struct QH *qh)
-{
-	return (struct QH *)((u32)qh & 0xffffffe0);
-}
+int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+	__attribute__((weak, alias("__ehci_get_port_speed")));
 
-static void cache_qh(struct QH *qh, int flush)
+void __ehci_set_usbmode(int index)
 {
-	struct qTD *qtd;
-	struct qTD *next;
-	static struct qTD *first_qtd;
-
-	/*
-	 * Walk the QH list and flush/invalidate all entries
-	 */
-	while (1) {
-		flush_invalidate((u32)qh_addr(qh), sizeof(struct QH), flush);
-		if ((u32)qh & QH_LINK_TYPE_QH)
-			break;
-		qh = qh_addr(qh);
-		qh = (struct QH *)qh->qh_link;
-	}
-	qh = qh_addr(qh);
-
-	/*
-	 * Save first qTD pointer, needed for invalidating pass on this QH
-	 */
-	if (flush)
-		first_qtd = qtd = (struct qTD *)(*(u32 *)&qh->qh_overlay &
-						 0xffffffe0);
-	else
-		qtd = first_qtd;
+	uint32_t tmp;
+	uint32_t *reg_ptr;
 
-	/*
-	 * Walk the qTD list and flush/invalidate all entries
-	 */
-	while (1) {
-		if (qtd == NULL)
-			break;
-		cache_qtd(qtd, flush);
-		next = (struct qTD *)((u32)qtd->qt_next & 0xffffffe0);
-		if (next == qtd)
-			break;
-		qtd = next;
-	}
+	reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE);
+	tmp = ehci_readl(reg_ptr);
+	tmp |= USBMODE_CM_HC;
+#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
+	tmp |= USBMODE_BE;
+#endif
+	ehci_writel(reg_ptr, tmp);
 }
 
-static inline void ehci_flush_dcache(struct QH *qh)
-{
-	cache_qh(qh, 1);
-}
+void ehci_set_usbmode(int index)
+	__attribute__((weak, alias("__ehci_set_usbmode")));
 
-static inline void ehci_invalidate_dcache(struct QH *qh)
-{
-	cache_qh(qh, 0);
-}
-#else /* CONFIG_EHCI_DCACHE */
-/*
- *
- */
-static inline void ehci_flush_dcache(struct QH *qh)
+void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
+	mdelay(50);
 }
 
-static inline void ehci_invalidate_dcache(struct QH *qh)
-{
-}
-#endif /* CONFIG_EHCI_DCACHE */
+void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+	__attribute__((weak, alias("__ehci_powerup_fixup")));
 
 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 {
@@ -217,80 +168,83 @@
 	return -1;
 }
 
-static void ehci_free(void *p, size_t sz)
-{
-
-}
-
-static int ehci_reset(void)
+static int ehci_reset(int index)
 {
 	uint32_t cmd;
-	uint32_t tmp;
-	uint32_t *reg_ptr;
 	int ret = 0;
 
-	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	cmd = (cmd & ~CMD_RUN) | CMD_RESET;
-	ehci_writel(&hcor->or_usbcmd, cmd);
-	ret = handshake((uint32_t *)&hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000);
+	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
+	ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd,
+			CMD_RESET, 0, 250 * 1000);
 	if (ret < 0) {
 		printf("EHCI fail to reset\n");
 		goto out;
 	}
 
-	if (ehci_is_TDI()) {
-		reg_ptr = (uint32_t *)((u8 *)hcor + USBMODE);
-		tmp = ehci_readl(reg_ptr);
-		tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-		tmp |= USBMODE_BE;
+	if (ehci_is_TDI())
+		ehci_set_usbmode(index);
+
+#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
+	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
+	cmd &= ~TXFIFO_THRESH_MASK;
+	cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
+	ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd);
 #endif
-		ehci_writel(reg_ptr, tmp);
-	}
 out:
 	return ret;
 }
 
-static void *ehci_alloc(size_t sz, size_t align)
+static int ehci_shutdown(struct ehci_ctrl *ctrl)
 {
-	static struct QH qh __attribute__((aligned(32)));
-	static struct qTD td[3] __attribute__((aligned (32)));
-	static int ntds;
-	void *p;
-
-	switch (sz) {
-	case sizeof(struct QH):
-		p = &qh;
-		ntds = 0;
-		break;
-	case sizeof(struct qTD):
-		if (ntds == 3) {
-			debug("out of TDs\n");
-			return NULL;
+	int i, ret = 0;
+	uint32_t cmd, reg;
+
+	if (!ctrl || !ctrl->hcor)
+		return -EINVAL;
+
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+	cmd &= ~(CMD_PSE | CMD_ASE);
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+	ret = handshake(&ctrl->hcor->or_usbsts, STS_ASS | STS_PSS, 0,
+		100 * 1000);
+
+	if (!ret) {
+		for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) {
+			reg = ehci_readl(&ctrl->hcor->or_portsc[i]);
+			reg |= EHCI_PS_SUSP;
+			ehci_writel(&ctrl->hcor->or_portsc[i], reg);
 		}
-		p = &td[ntds];
-		ntds++;
-		break;
-	default:
-		debug("unknown allocation size\n");
-		return NULL;
+
+		cmd &= ~CMD_RUN;
+		ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+		ret = handshake(&ctrl->hcor->or_usbsts, STS_HALT, STS_HALT,
+			HCHALT_TIMEOUT);
 	}
 
-	memset(p, 0, sz);
-	return p;
+	if (ret)
+		puts("EHCI failed to shut down host controller.\n");
+
+	return ret;
 }
 
 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 {
-	uint32_t addr, delta, next;
+	uint32_t delta, next;
+	uint32_t addr = (uint32_t)buf;
 	int idx;
 
-	addr = (uint32_t) buf;
+	if (addr != ALIGN(addr, ARCH_DMA_MINALIGN))
+		debug("EHCI-HCD: Misaligned buffer address (%p)\n", buf);
+
+	flush_dcache_range(addr, ALIGN(addr + sz, ARCH_DMA_MINALIGN));
+
 	idx = 0;
-	while (idx < 5) {
+	while (idx < QT_BUFFER_CNT) {
 		td->qt_buffer[idx] = cpu_to_hc32(addr);
 		td->qt_buffer_hi[idx] = 0;
-		next = (addr + 4096) & ~4095;
+		next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1);
 		delta = next - addr;
 		if (delta >= sz)
 			break;
@@ -299,28 +253,43 @@
 		idx++;
 	}
 
-	if (idx == 5) {
-		debug("out of buffer pointers (%u bytes left)\n", sz);
+	if (idx == QT_BUFFER_CNT) {
+		printf("out of buffer pointers (%u bytes left)\n", sz);
 		return -1;
 	}
 
 	return 0;
 }
 
+static inline u8 ehci_encode_speed(enum usb_device_speed speed)
+{
+	#define QH_HIGH_SPEED	2
+	#define QH_FULL_SPEED	0
+	#define QH_LOW_SPEED	1
+	if (speed == USB_SPEED_HIGH)
+		return QH_HIGH_SPEED;
+	if (speed == USB_SPEED_LOW)
+		return QH_LOW_SPEED;
+	return QH_FULL_SPEED;
+}
+
 static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		   int length, struct devrequest *req)
 {
-	struct QH *qh;
-	struct qTD *td;
+	ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN);
+	struct qTD *qtd;
+	int qtd_count = 0;
+	int qtd_counter = 0;
 	volatile struct qTD *vtd;
 	unsigned long ts;
 	uint32_t *tdp;
-	uint32_t endpt, token, usbsts;
+	uint32_t endpt, maxpacket, token, usbsts;
 	uint32_t c, toggle;
 	uint32_t cmd;
 	int timeout;
 	int ret = 0;
+	struct ehci_ctrl *ctrl = dev->controller;
 
 	debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
 	      buffer, length, req);
@@ -331,210 +300,351 @@
 		      le16_to_cpu(req->value), le16_to_cpu(req->value),
 		      le16_to_cpu(req->index));
 
-	qh = ehci_alloc(sizeof(struct QH), 32);
-	if (qh == NULL) {
-		debug("unable to allocate QH\n");
+#define PKT_ALIGN	512
+	/*
+	 * The USB transfer is split into qTD transfers. Eeach qTD transfer is
+	 * described by a transfer descriptor (the qTD). The qTDs form a linked
+	 * list with a queue head (QH).
+	 *
+	 * Each qTD transfer starts with a new USB packet, i.e. a packet cannot
+	 * have its beginning in a qTD transfer and its end in the following
+	 * one, so the qTD transfer lengths have to be chosen accordingly.
+	 *
+	 * Each qTD transfer uses up to QT_BUFFER_CNT data buffers, mapped to
+	 * single pages. The first data buffer can start at any offset within a
+	 * page (not considering the cache-line alignment issues), while the
+	 * following buffers must be page-aligned. There is no alignment
+	 * constraint on the size of a qTD transfer.
+	 */
+	if (req != NULL)
+		/* 1 qTD will be needed for SETUP, and 1 for ACK. */
+		qtd_count += 1 + 1;
+	if (length > 0 || req == NULL) {
+		/*
+		 * Determine the qTD transfer size that will be used for the
+		 * data payload (not considering the first qTD transfer, which
+		 * may be longer or shorter, and the final one, which may be
+		 * shorter).
+		 *
+		 * In order to keep each packet within a qTD transfer, the qTD
+		 * transfer size is aligned to PKT_ALIGN, which is a multiple of
+		 * wMaxPacketSize (except in some cases for interrupt transfers,
+		 * see comment in submit_int_msg()).
+		 *
+		 * By default, i.e. if the input buffer is aligned to PKT_ALIGN,
+		 * QT_BUFFER_CNT full pages will be used.
+		 */
+		int xfr_sz = QT_BUFFER_CNT;
+		/*
+		 * However, if the input buffer is not aligned to PKT_ALIGN, the
+		 * qTD transfer size will be one page shorter, and the first qTD
+		 * data buffer of each transfer will be page-unaligned.
+		 */
+		if ((uint32_t)buffer & (PKT_ALIGN - 1))
+			xfr_sz--;
+		/* Convert the qTD transfer size to bytes. */
+		xfr_sz *= EHCI_PAGE_SIZE;
+		/*
+		 * Approximate by excess the number of qTDs that will be
+		 * required for the data payload. The exact formula is way more
+		 * complicated and saves at most 2 qTDs, i.e. a total of 128
+		 * bytes.
+		 */
+		qtd_count += 2 + length / xfr_sz;
+	}
+/*
+ * Threshold value based on the worst-case total size of the allocated qTDs for
+ * a mass-storage transfer of 65535 blocks of 512 bytes.
+ */
+#if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024
+#warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI
+#endif
+	qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD));
+	if (qtd == NULL) {
+		printf("unable to allocate TDs\n");
 		return -1;
 	}
-	qh->qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
-	c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
-	     usb_pipeendpoint(pipe) == 0) ? 1 : 0;
-	endpt = (8 << 28) |
-	    (c << 27) |
-	    (usb_maxpacket(dev, pipe) << 16) |
-	    (0 << 15) |
-	    (1 << 14) |
-	    (usb_pipespeed(pipe) << 12) |
-	    (usb_pipeendpoint(pipe) << 8) |
-	    (0 << 7) | (usb_pipedevice(pipe) << 0);
+
+	memset(qh, 0, sizeof(struct QH));
+	memset(qtd, 0, qtd_count * sizeof(*qtd));
+
+	toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+
+	/*
+	 * Setup QH (3.6 in ehci-r10.pdf)
+	 *
+	 *   qh_link ................. 03-00 H
+	 *   qh_endpt1 ............... 07-04 H
+	 *   qh_endpt2 ............... 0B-08 H
+	 * - qh_curtd
+	 *   qh_overlay.qt_next ...... 13-10 H
+	 * - qh_overlay.qt_altnext
+	 */
+	qh->qh_link = cpu_to_hc32((uint32_t)&ctrl->qh_list | QH_LINK_TYPE_QH);
+	c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
+	maxpacket = usb_maxpacket(dev, pipe);
+	endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
+		QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) |
+		QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) |
+		QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
+		QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
+		QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
 	qh->qh_endpt1 = cpu_to_hc32(endpt);
-	endpt = (1 << 30) |
-	    (dev->portnr << 23) |
-	    (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
+	endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) |
+		QH_ENDPT2_HUBADDR(dev->parent->devnum) |
+		QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
 	qh->qh_endpt2 = cpu_to_hc32(endpt);
 	qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
-	td = NULL;
 	tdp = &qh->qh_overlay.qt_next;
 
-	toggle =
-	    usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
-
 	if (req != NULL) {
-		td = ehci_alloc(sizeof(struct qTD), 32);
-		if (td == NULL) {
-			debug("unable to allocate SETUP td\n");
+		/*
+		 * Setup request qTD (3.5 in ehci-r10.pdf)
+		 *
+		 *   qt_next ................ 03-00 H
+		 *   qt_altnext ............. 07-04 H
+		 *   qt_token ............... 0B-08 H
+		 *
+		 *   [ buffer, buffer_hi ] loaded with "req".
+		 */
+		qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+		qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+		token = QT_TOKEN_DT(0) | QT_TOKEN_TOTALBYTES(sizeof(*req)) |
+			QT_TOKEN_IOC(0) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) |
+			QT_TOKEN_PID(QT_TOKEN_PID_SETUP) |
+			QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
+		qtd[qtd_counter].qt_token = cpu_to_hc32(token);
+		if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req))) {
+			printf("unable to construct SETUP TD\n");
 			goto fail;
 		}
-		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-		token = (0 << 31) |
-		    (sizeof(*req) << 16) |
-		    (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
-		td->qt_token = cpu_to_hc32(token);
-		if (ehci_td_buffer(td, req, sizeof(*req)) != 0) {
-			debug("unable construct SETUP td\n");
-			ehci_free(td, sizeof(*td));
-			goto fail;
-		}
-		*tdp = cpu_to_hc32((uint32_t) td);
-		tdp = &td->qt_next;
+		/* Update previous qTD! */
+		*tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
+		tdp = &qtd[qtd_counter++].qt_next;
 		toggle = 1;
 	}
 
 	if (length > 0 || req == NULL) {
-		td = ehci_alloc(sizeof(struct qTD), 32);
-		if (td == NULL) {
-			debug("unable to allocate DATA td\n");
-			goto fail;
-		}
-		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-		token = (toggle << 31) |
-		    (length << 16) |
-		    ((req == NULL ? 1 : 0) << 15) |
-		    (0 << 12) |
-		    (3 << 10) |
-		    ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0);
-		td->qt_token = cpu_to_hc32(token);
-		if (ehci_td_buffer(td, buffer, length) != 0) {
-			debug("unable construct DATA td\n");
-			ehci_free(td, sizeof(*td));
-			goto fail;
-		}
-		*tdp = cpu_to_hc32((uint32_t) td);
-		tdp = &td->qt_next;
+		uint8_t *buf_ptr = buffer;
+		int left_length = length;
+
+		do {
+			/*
+			 * Determine the size of this qTD transfer. By default,
+			 * QT_BUFFER_CNT full pages can be used.
+			 */
+			int xfr_bytes = QT_BUFFER_CNT * EHCI_PAGE_SIZE;
+			/*
+			 * However, if the input buffer is not page-aligned, the
+			 * portion of the first page before the buffer start
+			 * offset within that page is unusable.
+			 */
+			xfr_bytes -= (uint32_t)buf_ptr & (EHCI_PAGE_SIZE - 1);
+			/*
+			 * In order to keep each packet within a qTD transfer,
+			 * align the qTD transfer size to PKT_ALIGN.
+			 */
+			xfr_bytes &= ~(PKT_ALIGN - 1);
+			/*
+			 * This transfer may be shorter than the available qTD
+			 * transfer size that has just been computed.
+			 */
+			xfr_bytes = min(xfr_bytes, left_length);
+
+			/*
+			 * Setup request qTD (3.5 in ehci-r10.pdf)
+			 *
+			 *   qt_next ................ 03-00 H
+			 *   qt_altnext ............. 07-04 H
+			 *   qt_token ............... 0B-08 H
+			 *
+			 *   [ buffer, buffer_hi ] loaded with "buffer".
+			 */
+			qtd[qtd_counter].qt_next =
+					cpu_to_hc32(QT_NEXT_TERMINATE);
+			qtd[qtd_counter].qt_altnext =
+					cpu_to_hc32(QT_NEXT_TERMINATE);
+			token = QT_TOKEN_DT(toggle) |
+				QT_TOKEN_TOTALBYTES(xfr_bytes) |
+				QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) |
+				QT_TOKEN_CERR(3) |
+				QT_TOKEN_PID(usb_pipein(pipe) ?
+					QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) |
+				QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
+			qtd[qtd_counter].qt_token = cpu_to_hc32(token);
+			if (ehci_td_buffer(&qtd[qtd_counter], buf_ptr,
+						xfr_bytes)) {
+				printf("unable to construct DATA TD\n");
+				goto fail;
+			}
+			/* Update previous qTD! */
+			*tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
+			tdp = &qtd[qtd_counter++].qt_next;
+			/*
+			 * Data toggle has to be adjusted since the qTD transfer
+			 * size is not always an even multiple of
+			 * wMaxPacketSize.
+			 */
+			if ((xfr_bytes / maxpacket) & 1)
+				toggle ^= 1;
+			buf_ptr += xfr_bytes;
+			left_length -= xfr_bytes;
+		} while (left_length > 0);
 	}
 
 	if (req != NULL) {
-		td = ehci_alloc(sizeof(struct qTD), 32);
-		if (td == NULL) {
-			debug("unable to allocate ACK td\n");
-			goto fail;
-		}
-		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-		token = (toggle << 31) |
-		    (0 << 16) |
-		    (1 << 15) |
-		    (0 << 12) |
-		    (3 << 10) |
-		    ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0);
-		td->qt_token = cpu_to_hc32(token);
-		*tdp = cpu_to_hc32((uint32_t) td);
-		tdp = &td->qt_next;
+		/*
+		 * Setup request qTD (3.5 in ehci-r10.pdf)
+		 *
+		 *   qt_next ................ 03-00 H
+		 *   qt_altnext ............. 07-04 H
+		 *   qt_token ............... 0B-08 H
+		 */
+		qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+		qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+		token = QT_TOKEN_DT(1) | QT_TOKEN_TOTALBYTES(0) |
+			QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) |
+			QT_TOKEN_PID(usb_pipein(pipe) ?
+				QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) |
+			QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
+		qtd[qtd_counter].qt_token = cpu_to_hc32(token);
+		/* Update previous qTD! */
+		*tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
+		tdp = &qtd[qtd_counter++].qt_next;
 	}
 
-	qh_list.qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
+	ctrl->qh_list.qh_link = cpu_to_hc32((uint32_t)qh | QH_LINK_TYPE_QH);
 
 	/* Flush dcache */
-	ehci_flush_dcache(&qh_list);
+	flush_dcache_range((uint32_t)&ctrl->qh_list,
+		ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
+	flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1));
+	flush_dcache_range((uint32_t)qtd,
+			   ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
 
-	usbsts = ehci_readl(&hcor->or_usbsts);
-	ehci_writel(&hcor->or_usbsts, (usbsts & 0x3f));
+	/* Set async. queue head pointer. */
+	ehci_writel(&ctrl->hcor->or_asynclistaddr, (uint32_t)&ctrl->qh_list);
+
+	usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
+	ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
 
 	/* Enable async. schedule. */
-	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	cmd |= CMD_ASE;
-	ehci_writel(&hcor->or_usbcmd, cmd);
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
 
-	ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, STD_ASS,
+	ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS,
 			100 * 1000);
 	if (ret < 0) {
-		printf("EHCI fail timeout STD_ASS set\n");
+		printf("EHCI fail timeout STS_ASS set\n");
 		goto fail;
 	}
 
 	/* Wait for TDs to be processed. */
 	ts = get_timer(0);
-	vtd = td;
+	vtd = &qtd[qtd_counter - 1];
 	timeout = USB_TIMEOUT_MS(pipe);
 	do {
 		/* Invalidate dcache */
-		ehci_invalidate_dcache(&qh_list);
+		invalidate_dcache_range((uint32_t)&ctrl->qh_list,
+			ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
+		invalidate_dcache_range((uint32_t)qh,
+			ALIGN_END_ADDR(struct QH, qh, 1));
+		invalidate_dcache_range((uint32_t)qtd,
+			ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
+
 		token = hc32_to_cpu(vtd->qt_token);
-		if (!(token & 0x80))
+		if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE))
 			break;
 		WATCHDOG_RESET();
 	} while (get_timer(ts) < timeout);
 
+	/*
+	 * Invalidate the memory area occupied by buffer
+	 * Don't try to fix the buffer alignment, if it isn't properly
+	 * aligned it's upper layer's fault so let invalidate_dcache_range()
+	 * vow about it. But we have to fix the length as it's actual
+	 * transfer length and can be unaligned. This is potentially
+	 * dangerous operation, it's responsibility of the calling
+	 * code to make sure enough space is reserved.
+	 */
+	invalidate_dcache_range((uint32_t)buffer,
+		ALIGN((uint32_t)buffer + length, ARCH_DMA_MINALIGN));
+
 	/* Check that the TD processing happened */
-	if (token & 0x80) {
+	if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)
 		printf("EHCI timed out on TD - token=%#x\n", token);
-		goto fail;
-	}
 
 	/* Disable async schedule. */
-	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	cmd &= ~CMD_ASE;
-	ehci_writel(&hcor->or_usbcmd, cmd);
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
 
-	ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, 0,
+	ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, 0,
 			100 * 1000);
 	if (ret < 0) {
-		printf("EHCI fail timeout STD_ASS reset\n");
+		printf("EHCI fail timeout STS_ASS reset\n");
 		goto fail;
 	}
 
-	qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
-
 	token = hc32_to_cpu(qh->qh_overlay.qt_token);
-	if (!(token & 0x80)) {
+	if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) {
 		debug("TOKEN=%#x\n", token);
-		switch (token & 0xfc) {
+		switch (QT_TOKEN_GET_STATUS(token) &
+			~(QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR)) {
 		case 0:
-			toggle = token >> 31;
+			toggle = QT_TOKEN_GET_DT(token);
 			usb_settoggle(dev, usb_pipeendpoint(pipe),
 				       usb_pipeout(pipe), toggle);
 			dev->status = 0;
 			break;
-		case 0x40:
+		case QT_TOKEN_STATUS_HALTED:
 			dev->status = USB_ST_STALLED;
 			break;
-		case 0xa0:
-		case 0x20:
+		case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR:
+		case QT_TOKEN_STATUS_DATBUFERR:
 			dev->status = USB_ST_BUF_ERR;
 			break;
-		case 0x50:
-		case 0x10:
+		case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET:
+		case QT_TOKEN_STATUS_BABBLEDET:
 			dev->status = USB_ST_BABBLE_DET;
 			break;
 		default:
 			dev->status = USB_ST_CRC_ERR;
-			if ((token & 0x40) == 0x40)
+			if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_HALTED)
 				dev->status |= USB_ST_STALLED;
 			break;
 		}
-		dev->act_len = length - ((token >> 16) & 0x7fff);
+		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
-		      dev->devnum, ehci_readl(&hcor->or_usbsts),
-		      ehci_readl(&hcor->or_portsc[0]),
-		      ehci_readl(&hcor->or_portsc[1]));
+		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
+		      ehci_readl(&ctrl->hcor->or_portsc[0]),
+		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
+	free(qtd);
 	return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
 
 fail:
-	td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
-	while (td != (void *)QT_NEXT_TERMINATE) {
-		qh->qh_overlay.qt_next = td->qt_next;
-		ehci_free(td, sizeof(*td));
-		td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
-	}
-	ehci_free(qh, sizeof(*qh));
+	free(qtd);
 	return -1;
 }
 
-static inline int min3(int a, int b, int c)
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
 {
+	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		/* Printing the message would cause a scan failure! */
+		debug("The request port(%u) is not configured\n", port);
+		return NULL;
+	}
 
-	if (b < a)
-		a = b;
-	if (c < a)
-		a = c;
-	return a;
+	return (uint32_t *)&hcor->or_portsc[port];
 }
 
 int
@@ -547,14 +657,9 @@
 	int len, srclen;
 	uint32_t reg;
 	uint32_t *status_reg;
+	int port = le16_to_cpu(req->index) & 0xff;
+	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n",
-			le16_to_cpu(req->index) - 1);
-		return -1;
-	}
-	status_reg = (uint32_t *)&hcor->or_portsc[
-						le16_to_cpu(req->index) - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -565,17 +670,32 @@
 	typeReq = req->request | req->requesttype << 8;
 
 	switch (typeReq) {
+	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
+	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+		status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+		if (!status_reg)
+			return -1;
+		break;
+	default:
+		status_reg = NULL;
+		break;
+	}
+
+	switch (typeReq) {
 	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
 		switch (le16_to_cpu(req->value) >> 8) {
 		case USB_DT_DEVICE:
 			debug("USB_DT_DEVICE request\n");
 			srcptr = &descriptor.device;
-			srclen = 0x12;
+			srclen = descriptor.device.bLength;
 			break;
 		case USB_DT_CONFIG:
 			debug("USB_DT_CONFIG config\n");
 			srcptr = &descriptor.config;
-			srclen = 0x19;
+			srclen = descriptor.config.bLength +
+					descriptor.interface.bLength +
+					descriptor.endpoint.bLength;
 			break;
 		case USB_DT_STRING:
 			debug("USB_DT_STRING config\n");
@@ -610,7 +730,7 @@
 		case USB_DT_HUB:
 			debug("USB_DT_HUB config\n");
 			srcptr = &descriptor.hub;
-			srclen = 0x8;
+			srclen = descriptor.hub.bLength;
 			break;
 		default:
 			debug("unknown value %x\n", le16_to_cpu(req->value));
@@ -619,7 +739,7 @@
 		break;
 	case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
 		debug("USB_REQ_SET_ADDRESS\n");
-		rootdev = le16_to_cpu(req->value);
+		ctrl->rootdev = le16_to_cpu(req->value);
 		break;
 	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
 		debug("USB_REQ_SET_CONFIGURATION\n");
@@ -648,13 +768,13 @@
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
 
 		if (ehci_is_TDI()) {
-			switch ((reg >> 26) & 3) {
-			case 0:
+			switch (ehci_get_port_speed(ctrl->hcor, reg)) {
+			case PORTSC_PSPD_FS:
 				break;
-			case 1:
+			case PORTSC_PSPD_LS:
 				tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
 				break;
-			case 2:
+			case PORTSC_PSPD_HS:
 			default:
 				tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
 				break;
@@ -669,7 +789,7 @@
 			tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
 		if (reg & EHCI_PS_OCC)
 			tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
-		if (portreset & (1 << le16_to_cpu(req->index)))
+		if (ctrl->portreset & (1 << port))
 			tmpbuf[2] |= USB_PORT_STAT_C_RESET;
 
 		srcptr = tmpbuf;
@@ -684,7 +804,7 @@
 			ehci_writel(status_reg, reg);
 			break;
 		case USB_PORT_FEAT_POWER:
-			if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams))) {
+			if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams))) {
 				reg |= EHCI_PS_PP;
 				ehci_writel(status_reg, reg);
 			}
@@ -695,7 +815,7 @@
 			    EHCI_PS_IS_LOWSPEED(reg)) {
 				/* Low speed device, give up ownership. */
 				debug("port %d low speed --> companion\n",
-				      req->index - 1);
+				      port - 1);
 				reg |= EHCI_PS_PO;
 				ehci_writel(status_reg, reg);
 				break;
@@ -710,8 +830,8 @@
 				 * usb 2.0 specification say 50 ms resets on
 				 * root
 				 */
-				wait_ms(50);
-				/* terminate the reset */
+				ehci_powerup_fixup(status_reg, &reg);
+
 				ehci_writel(status_reg, reg & ~EHCI_PS_PR);
 				/*
 				 * A host controller must terminate the reset
@@ -721,40 +841,47 @@
 				ret = handshake(status_reg, EHCI_PS_PR, 0,
 						2 * 1000);
 				if (!ret)
-					portreset |=
-						1 << le16_to_cpu(req->index);
+					ctrl->portreset |= 1 << port;
 				else
 					printf("port(%d) reset error\n",
-					le16_to_cpu(req->index) - 1);
+					       port - 1);
 			}
 			break;
+		case USB_PORT_FEAT_TEST:
+			ehci_shutdown(ctrl);
+			reg &= ~(0xf << 16);
+			reg |= ((le16_to_cpu(req->index) >> 8) & 0xf) << 16;
+			ehci_writel(status_reg, reg);
+			break;
 		default:
 			debug("unknown feature %x\n", le16_to_cpu(req->value));
 			goto unknown;
 		}
 		/* unblock posted writes */
-		(void) ehci_readl(&hcor->or_usbcmd);
+		(void) ehci_readl(&ctrl->hcor->or_usbcmd);
 		break;
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
 		reg = ehci_readl(status_reg);
+		reg &= ~EHCI_PS_CLEAR;
 		switch (le16_to_cpu(req->value)) {
 		case USB_PORT_FEAT_ENABLE:
 			reg &= ~EHCI_PS_PE;
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
+			reg |= EHCI_PS_PE;
 			break;
 		case USB_PORT_FEAT_POWER:
-			if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams)))
-				reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
+			if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams)))
+				reg &= ~EHCI_PS_PP;
+			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
+			reg |= EHCI_PS_CSC;
 			break;
 		case USB_PORT_FEAT_OVER_CURRENT:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
+			reg |= EHCI_PS_OCC;
 			break;
 		case USB_PORT_FEAT_C_RESET:
-			portreset &= ~(1 << le16_to_cpu(req->index));
+			ctrl->portreset &= ~(1 << port);
 			break;
 		default:
 			debug("unknown feature %x\n", le16_to_cpu(req->value));
@@ -762,14 +889,14 @@
 		}
 		ehci_writel(status_reg, reg);
 		/* unblock posted write */
-		(void) ehci_readl(&hcor->or_usbcmd);
+		(void) ehci_readl(&ctrl->hcor->or_usbcmd);
 		break;
 	default:
 		debug("Unknown request\n");
 		goto unknown;
 	}
 
-	wait_ms(1);
+	mdelay(1);
 	len = min3(srclen, le16_to_cpu(req->length), length);
 	if (srcptr != NULL && len > 0)
 		memcpy(buffer, srcptr, len);
@@ -790,72 +917,135 @@
 	return -1;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
-	return ehci_hcd_stop();
+	ehci_shutdown(&ehcic[index]);
+	return ehci_hcd_stop(index);
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	uint32_t reg;
 	uint32_t cmd;
-
-	if (ehci_hcd_init() != 0)
-		return -1;
+	struct QH *qh_list;
+	struct QH *periodic;
+	int i;
+	int rc;
+
+	rc = ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor);
+	if (rc)
+		return rc;
 
 	/* EHCI spec section 4.1 */
-	if (ehci_reset() != 0)
+	if (ehci_reset(index))
 		return -1;
 
 #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
-	if (ehci_hcd_init() != 0)
-		return -1;
+	rc = ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor);
+	if (rc)
+		return rc;
 #endif
+	/* Set the high address word (aka segment) for 64-bit controller */
+	if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
+		ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);
+
+	qh_list = &ehcic[index].qh_list;
 
 	/* Set head of reclaim list */
-	memset(&qh_list, 0, sizeof(qh_list));
-	qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
-	qh_list.qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
-	qh_list.qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
-	qh_list.qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-	qh_list.qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-	qh_list.qh_overlay.qt_token = cpu_to_hc32(0x40);
+	memset(qh_list, 0, sizeof(*qh_list));
+	qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
+	qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) |
+						QH_ENDPT1_EPS(USB_SPEED_HIGH));
+	qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh_list->qh_overlay.qt_token =
+			cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
+
+	flush_dcache_range((uint32_t)qh_list,
+			   ALIGN_END_ADDR(struct QH, qh_list, 1));
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&hcor->or_asynclistaddr, (uint32_t)&qh_list);
+	ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
+
+	/*
+	 * Set up periodic list
+	 * Step 1: Parent QH for all periodic transfers.
+	 */
+	periodic = &ehcic[index].periodic_queue;
+	memset(periodic, 0, sizeof(*periodic));
+	periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
+	periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+	periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+
+	flush_dcache_range((uint32_t)periodic,
+			   ALIGN_END_ADDR(struct QH, periodic, 1));
+
+	/*
+	 * Step 2: Setup frame-list: Every microframe, USB tries the same list.
+	 *         In particular, device specifications on polling frequency
+	 *         are disregarded. Keyboards seem to send NAK/NYet reliably
+	 *         when polled with an empty buffer.
+	 *
+	 *         Split Transactions will be spread across microframes using
+	 *         S-mask and C-mask.
+	 */
+	if (ehcic[index].periodic_list == NULL)
+		ehcic[index].periodic_list = memalign(4096, 1024 * 4);
 
-	reg = ehci_readl(&hccr->cr_hcsparams);
+	if (!ehcic[index].periodic_list)
+		return -ENOMEM;
+	for (i = 0; i < 1024; i++) {
+		ehcic[index].periodic_list[i] = cpu_to_hc32((uint32_t)periodic
+						| QH_LINK_TYPE_QH);
+	}
+
+	flush_dcache_range((uint32_t)ehcic[index].periodic_list,
+			   ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list,
+					  1024));
+
+	/* Set periodic list base address */
+	ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
+		(uint32_t)ehcic[index].periodic_list);
+
+	reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
 	descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
-	printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
+	debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
 	/* Port Indicators */
 	if (HCS_INDICATOR(reg))
-		descriptor.hub.wHubCharacteristics |= 0x80;
+		put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
+				| 0x80, &descriptor.hub.wHubCharacteristics);
 	/* Port Power Control */
 	if (HCS_PPC(reg))
-		descriptor.hub.wHubCharacteristics |= 0x01;
+		put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
+				| 0x01, &descriptor.hub.wHubCharacteristics);
 
 	/* Start the host controller. */
-	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	/*
 	 * Philips, Intel, and maybe others need CMD_RUN before the
 	 * root hub will detect new devices (why?); NEC doesn't
 	 */
 	cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
 	cmd |= CMD_RUN;
-	ehci_writel(&hcor->or_usbcmd, cmd);
+	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
-	cmd = ehci_readl(&hcor->or_configflag);
+	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
-	ehci_writel(&hcor->or_configflag, cmd);
+	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
-	cmd = ehci_readl(&hcor->or_usbcmd);
-	wait_ms(5);
-	reg = HC_VERSION(ehci_readl(&hccr->cr_capbase));
+	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+	mdelay(5);
+	reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase));
 	printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
 
-	rootdev = 0;
+	ehcic[index].rootdev = 0;
 
+	*controller = &ehcic[index];
 	return 0;
 }
 
@@ -875,26 +1065,338 @@
 submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		   int length, struct devrequest *setup)
 {
+	struct ehci_ctrl *ctrl = dev->controller;
 
 	if (usb_pipetype(pipe) != PIPE_CONTROL) {
 		debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
 		return -1;
 	}
 
-	if (usb_pipedevice(pipe) == rootdev) {
-		if (rootdev == 0)
+	if (usb_pipedevice(pipe) == ctrl->rootdev) {
+		if (!ctrl->rootdev)
 			dev->speed = USB_SPEED_HIGH;
 		return ehci_submit_root(dev, pipe, buffer, length, setup);
 	}
 	return ehci_submit_async(dev, pipe, buffer, length, setup);
 }
 
+struct int_queue {
+	struct QH *first;
+	struct QH *current;
+	struct QH *last;
+	struct qTD *tds;
+};
+
+#define NEXT_QH(qh) (struct QH *)(hc32_to_cpu((qh)->qh_link) & ~0x1f)
+
+static int
+enable_periodic(struct ehci_ctrl *ctrl)
+{
+	uint32_t cmd;
+	struct ehci_hcor *hcor = ctrl->hcor;
+	int ret;
+
+	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd |= CMD_PSE;
+	ehci_writel(&hcor->or_usbcmd, cmd);
+
+	ret = handshake((uint32_t *)&hcor->or_usbsts,
+			STS_PSS, STS_PSS, 100 * 1000);
+	if (ret < 0) {
+		printf("EHCI failed: timeout when enabling periodic list\n");
+		return -ETIMEDOUT;
+	}
+	udelay(1000);
+	return 0;
+}
+
+static int
+disable_periodic(struct ehci_ctrl *ctrl)
+{
+	uint32_t cmd;
+	struct ehci_hcor *hcor = ctrl->hcor;
+	int ret;
+
+	cmd = ehci_readl(&hcor->or_usbcmd);
+	cmd &= ~CMD_PSE;
+	ehci_writel(&hcor->or_usbcmd, cmd);
+
+	ret = handshake((uint32_t *)&hcor->or_usbsts,
+			STS_PSS, 0, 100 * 1000);
+	if (ret < 0) {
+		printf("EHCI failed: timeout when disabling periodic list\n");
+		return -ETIMEDOUT;
+	}
+	return 0;
+}
+
+static int periodic_schedules;
+
+struct int_queue *
+create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
+		 int elementsize, void *buffer)
+{
+	struct ehci_ctrl *ctrl = dev->controller;
+	struct int_queue *result = NULL;
+	int i;
+
+	debug("Enter create_int_queue\n");
+	if (usb_pipetype(pipe) != PIPE_INTERRUPT) {
+		debug("non-interrupt pipe (type=%lu)", usb_pipetype(pipe));
+		return NULL;
+	}
+
+	/* limit to 4 full pages worth of data -
+	 * we can safely fit them in a single TD,
+	 * no matter the alignment
+	 */
+	if (elementsize >= 16384) {
+		debug("too large elements for interrupt transfers\n");
+		return NULL;
+	}
+
+	result = malloc(sizeof(*result));
+	if (!result) {
+		debug("ehci intr queue: out of memory\n");
+		goto fail1;
+	}
+	result->first = memalign(USB_DMA_MINALIGN,
+				 sizeof(struct QH) * queuesize);
+	if (!result->first) {
+		debug("ehci intr queue: out of memory\n");
+		goto fail2;
+	}
+	result->current = result->first;
+	result->last = result->first + queuesize - 1;
+	result->tds = memalign(USB_DMA_MINALIGN,
+			       sizeof(struct qTD) * queuesize);
+	if (!result->tds) {
+		debug("ehci intr queue: out of memory\n");
+		goto fail3;
+	}
+	memset(result->first, 0, sizeof(struct QH) * queuesize);
+	memset(result->tds, 0, sizeof(struct qTD) * queuesize);
+
+	for (i = 0; i < queuesize; i++) {
+		struct QH *qh = result->first + i;
+		struct qTD *td = result->tds + i;
+		void **buf = &qh->buffer;
+
+		qh->qh_link = cpu_to_hc32((uint32_t)(qh+1) | QH_LINK_TYPE_QH);
+		if (i == queuesize - 1)
+			qh->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
+
+		qh->qh_overlay.qt_next = cpu_to_hc32((uint32_t)td);
+		qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+		qh->qh_endpt1 =
+			cpu_to_hc32((0 << 28) | /* No NAK reload (ehci 4.9) */
+			(usb_maxpacket(dev, pipe) << 16) | /* MPS */
+			(1 << 14) |
+			QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
+			(usb_pipeendpoint(pipe) << 8) | /* Endpoint Number */
+			(usb_pipedevice(pipe) << 0));
+		qh->qh_endpt2 = cpu_to_hc32((1 << 30) | /* 1 Tx per mframe */
+			(1 << 0)); /* S-mask: microframe 0 */
+		if (dev->speed == USB_SPEED_LOW ||
+				dev->speed == USB_SPEED_FULL) {
+			debug("TT: port: %d, hub address: %d\n",
+				dev->portnr, dev->parent->devnum);
+			qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
+				(dev->parent->devnum << 16) |
+				(0x1c << 8)); /* C-mask: microframes 2-4 */
+		}
+
+		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+		debug("communication direction is '%s'\n",
+		      usb_pipein(pipe) ? "in" : "out");
+		td->qt_token = cpu_to_hc32((elementsize << 16) |
+			((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */
+			0x80); /* active */
+		td->qt_buffer[0] =
+		    cpu_to_hc32((uint32_t)buffer + i * elementsize);
+		td->qt_buffer[1] =
+		    cpu_to_hc32((td->qt_buffer[0] + 0x1000) & ~0xfff);
+		td->qt_buffer[2] =
+		    cpu_to_hc32((td->qt_buffer[0] + 0x2000) & ~0xfff);
+		td->qt_buffer[3] =
+		    cpu_to_hc32((td->qt_buffer[0] + 0x3000) & ~0xfff);
+		td->qt_buffer[4] =
+		    cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff);
+
+		*buf = buffer + i * elementsize;
+	}
+
+	flush_dcache_range((uint32_t)buffer,
+			   ALIGN_END_ADDR(char, buffer,
+					  queuesize * elementsize));
+	flush_dcache_range((uint32_t)result->first,
+			   ALIGN_END_ADDR(struct QH, result->first,
+					  queuesize));
+	flush_dcache_range((uint32_t)result->tds,
+			   ALIGN_END_ADDR(struct qTD, result->tds,
+					  queuesize));
+
+	if (disable_periodic(ctrl) < 0) {
+		debug("FATAL: periodic should never fail, but did");
+		goto fail3;
+	}
+
+	/* hook up to periodic list */
+	struct QH *list = &ctrl->periodic_queue;
+	result->last->qh_link = list->qh_link;
+	list->qh_link = cpu_to_hc32((uint32_t)result->first | QH_LINK_TYPE_QH);
+
+	flush_dcache_range((uint32_t)result->last,
+			   ALIGN_END_ADDR(struct QH, result->last, 1));
+	flush_dcache_range((uint32_t)list,
+			   ALIGN_END_ADDR(struct QH, list, 1));
+
+	if (enable_periodic(ctrl) < 0) {
+		debug("FATAL: periodic should never fail, but did");
+		goto fail3;
+	}
+	periodic_schedules++;
+
+	debug("Exit create_int_queue\n");
+	return result;
+fail3:
+	if (result->tds)
+		free(result->tds);
+fail2:
+	if (result->first)
+		free(result->first);
+	if (result)
+		free(result);
+fail1:
+	return NULL;
+}
+
+void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+	struct QH *cur = queue->current;
+
+	/* depleted queue */
+	if (cur == NULL) {
+		debug("Exit poll_int_queue with completed queue\n");
+		return NULL;
+	}
+	/* still active */
+	invalidate_dcache_range((uint32_t)cur,
+				ALIGN_END_ADDR(struct QH, cur, 1));
+	if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
+		debug("Exit poll_int_queue with no completed intr transfer. "
+		      "token is %x\n", cur->qh_overlay.qt_token);
+		return NULL;
+	}
+	if (!(cur->qh_link & QH_LINK_TERMINATE))
+		queue->current++;
+	else
+		queue->current = NULL;
+	debug("Exit poll_int_queue with completed intr transfer. "
+	      "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
+	      &cur->qh_overlay.qt_token, queue->first);
+	return cur->buffer;
+}
+
+/* Do not free buffers associated with QHs, they're owned by someone else */
+int
+destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+	struct ehci_ctrl *ctrl = dev->controller;
+	int result = -1;
+	unsigned long timeout;
+
+	if (disable_periodic(ctrl) < 0) {
+		debug("FATAL: periodic should never fail, but did");
+		goto out;
+	}
+	periodic_schedules--;
+
+	struct QH *cur = &ctrl->periodic_queue;
+	timeout = get_timer(0) + 500; /* abort after 500ms */
+	while (!(cur->qh_link & cpu_to_hc32(QH_LINK_TERMINATE))) {
+		debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
+		if (NEXT_QH(cur) == queue->first) {
+			debug("found candidate. removing from chain\n");
+			cur->qh_link = queue->last->qh_link;
+			result = 0;
+			break;
+		}
+		cur = NEXT_QH(cur);
+		if (get_timer(0) > timeout) {
+			printf("Timeout destroying interrupt endpoint queue\n");
+			result = -1;
+			goto out;
+		}
+	}
+
+	if (periodic_schedules > 0) {
+		result = enable_periodic(ctrl);
+		if (result < 0)
+			debug("FATAL: periodic should never fail, but did");
+	}
+
+out:
+	free(queue->tds);
+	free(queue->first);
+	free(queue);
+
+	return result;
+}
+
 int
 submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	       int length, int interval)
 {
+	void *backbuffer;
+	struct int_queue *queue;
+	unsigned long timeout;
+	int result = 0, ret;
 
 	debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
 	      dev, pipe, buffer, length, interval);
-	return -1;
+
+	/*
+	 * Interrupt transfers requiring several transactions are not supported
+	 * because bInterval is ignored.
+	 *
+	 * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2
+	 * <= PKT_ALIGN if several qTDs are required, while the USB
+	 * specification does not constrain this for interrupt transfers. That
+	 * means that ehci_submit_async() would support interrupt transfers
+	 * requiring several transactions only as long as the transfer size does
+	 * not require more than a single qTD.
+	 */
+	if (length > usb_maxpacket(dev, pipe)) {
+		printf("%s: Interrupt transfers requiring several "
+			"transactions are not supported.\n", __func__);
+		return -1;
+	}
+
+	queue = create_int_queue(dev, pipe, 1, length, buffer);
+
+	timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
+	while ((backbuffer = poll_int_queue(dev, queue)) == NULL)
+		if (get_timer(0) > timeout) {
+			printf("Timeout poll on interrupt endpoint\n");
+			result = -ETIMEDOUT;
+			break;
+		}
+
+	if (backbuffer != buffer) {
+		debug("got wrong buffer back (%x instead of %x)\n",
+		      (uint32_t)backbuffer, (uint32_t)buffer);
+		return -EINVAL;
+	}
+
+	invalidate_dcache_range((uint32_t)buffer,
+				ALIGN_END_ADDR(char, buffer, length));
+
+	ret = destroy_int_queue(dev, queue);
+	if (ret < 0)
+		return ret;
+
+	/* everything worked out fine */
+	return result;
 }
diff '--exclude=.svn' -Naur u-boot-2011.06_original/drivers/usb/host/Makefile u-boot-2011.06/drivers/usb/host/Makefile
--- u-boot-2011.06_original/drivers/usb/host/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/drivers/usb/host/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -46,6 +46,7 @@
 COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o
 COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
 COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
+COBJS-$(CONFIG_USB_EHCI_CNC) += ehci-cnc.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/examples/standalone/Makefile u-boot-2011.06/examples/standalone/Makefile
--- u-boot-2011.06_original/examples/standalone/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/examples/standalone/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -95,7 +95,7 @@
 
 $(ELF):
 $(obj)%:	$(obj)%.o $(LIB)
-		$(LD) -g -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) \
+		$(LD) -g -Ttext 0x1000000 \
 			-o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \
 			-L$(gcclibdir) -lgcc
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/fs/fat/fat.c u-boot-2011.06/fs/fat/fat.c
--- u-boot-2011.06_original/fs/fat/fat.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/fs/fat/fat.c	2014-07-29 17:28:38.819972000 +0800
@@ -30,7 +30,8 @@
 #include <fat.h>
 #include <asm/byteorder.h>
 #include <part.h>
-
+#include <malloc.h>
+#include <linux/compiler.h>
 /*
  * Convert a string to lowercase.
  */
@@ -69,7 +70,7 @@
 
 int fat_register_device (block_dev_desc_t * dev_desc, int part_no)
 {
-	unsigned char buffer[SECTOR_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, SECTOR_SIZE);
 
 	disk_partition_t info;
 
@@ -296,7 +297,7 @@
 		return -1;
 	}
 	if (size % FS_BLOCK_SIZE) {
-		__u8 tmpbuf[FS_BLOCK_SIZE];
+		ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, FS_BLOCK_SIZE);
 
 		idx = size / FS_BLOCK_SIZE;
 		if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
@@ -312,6 +313,9 @@
 	return 0;
 }
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+extern int check_write_to_code_area (unsigned long addr, unsigned long size);
+#endif
 /*
  * Read at most 'maxsize' bytes from the file associated with 'dentptr'
  * into 'buffer'.
@@ -332,6 +336,11 @@
 	if (maxsize > 0 && filesize > maxsize)
 		filesize = maxsize;
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+	if (check_write_to_code_area ((unsigned long) buffer, filesize))
+		return -1;
+#endif
+
 	debug("%ld bytes\n", filesize);
 
 	actsize = bytesperclust;
@@ -430,8 +439,8 @@
  * into 'retdent'
  * Return 0 on success, -1 otherwise.
  */
-__attribute__ ((__aligned__ (__alignof__ (dir_entry))))
-__u8 get_vfatname_block[MAX_CLUSTSIZE];
+__u8 get_vfatname_block[MAX_CLUSTSIZE]
+	__aligned(ARCH_DMA_MINALIGN);
 
 static int
 get_vfatname (fsdata *mydata, int curclust, __u8 *cluster,
@@ -536,8 +545,8 @@
  * Get the directory entry associated with 'filename' from the directory
  * starting at 'startsect'
  */
-__attribute__ ((__aligned__ (__alignof__ (dir_entry))))
-__u8 get_dentfromdir_block[MAX_CLUSTSIZE];
+__u8 get_dentfromdir_block[MAX_CLUSTSIZE]
+	__aligned(ARCH_DMA_MINALIGN);
 
 static dir_entry *get_dentfromdir (fsdata *mydata, int startsect,
 				   char *filename, dir_entry *retdent,
@@ -702,7 +711,7 @@
 static int
 read_bootsectandvi (boot_sector *bs, volume_info *volinfo, int *fatsize)
 {
-	__u8 block[FS_BLOCK_SIZE];
+	ALLOC_CACHE_ALIGN_BUFFER(__u8, block, FS_BLOCK_SIZE);
 
 	volume_info *vistart;
 
@@ -752,9 +761,8 @@
 	return -1;
 }
 
-__attribute__ ((__aligned__ (__alignof__ (dir_entry))))
-__u8 do_fat_read_block[MAX_CLUSTSIZE];
-
+__u8 do_fat_read_block[MAX_CLUSTSIZE]
+	__aligned(ARCH_DMA_MINALIGN);
 long
 do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
 	     int dols)
@@ -809,6 +817,11 @@
 	}
 
 	mydata->fatbufnum = -1;
+	mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
+	if (mydata->fatbuf == NULL) {
+		debug("Error: allocating memory\n");
+		return -1;
+	}
 
 #ifdef CONFIG_SUPPORT_VFAT
 	debug("VFAT Support enabled\n");
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/asn1.h u-boot-2011.06/include/asn1.h
--- u-boot-2011.06_original/include/asn1.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/asn1.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,343 @@
+/**
+ * \file asn1.h
+ *
+ * \brief Generic ASN.1 parsing
+ *
+ *  Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_ASN1_H
+#define POLARSSL_ASN1_H
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_BIGNUM_C)
+#include "bignum.h"
+#endif
+
+#include <linux/string.h>
+
+/**
+ * \addtogroup asn1_module
+ * \{
+ */
+
+/**
+ * \name ASN1 Error codes
+ * These error codes are OR'ed to X509 error codes for
+ * higher error granularity.
+ * ASN1 is a standard to specify data structures.
+ * \{
+ */
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA                      -0x0060  /**< Out of data when parsing an ASN1 data structure. */
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG                   -0x0062  /**< ASN1 tag was of an unexpected value. */
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH                   -0x0064  /**< Error when trying to determine the length or invalid length. */
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH                  -0x0066  /**< Actual length differs from expected length. */
+#define POLARSSL_ERR_ASN1_INVALID_DATA                     -0x0068  /**< Data is invalid. (not used) */
+#define POLARSSL_ERR_ASN1_MALLOC_FAILED                    -0x006A  /**< Memory allocation failed */
+#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL                    -0x006C  /**< Buffer too small when writing ASN.1 data structure. */
+
+/* \} name */
+
+/**
+ * \name DER constants
+ * These constants comply with DER encoded the ANS1 type tags.
+ * DER encoding uses hexadecimal representation.
+ * An example DER sequence is:\n
+ * - 0x02 -- tag indicating INTEGER
+ * - 0x01 -- length in octets
+ * - 0x05 -- value
+ * Such sequences are typically read into \c ::x509_buf.
+ * \{
+ */
+#define ASN1_BOOLEAN                 0x01
+#define ASN1_INTEGER                 0x02
+#define ASN1_BIT_STRING              0x03
+#define ASN1_OCTET_STRING            0x04
+#define ASN1_NULL                    0x05
+#define ASN1_OID                     0x06
+#define ASN1_UTF8_STRING             0x0C
+#define ASN1_SEQUENCE                0x10
+#define ASN1_SET                     0x11
+#define ASN1_PRINTABLE_STRING        0x13
+#define ASN1_T61_STRING              0x14
+#define ASN1_IA5_STRING              0x16
+#define ASN1_UTC_TIME                0x17
+#define ASN1_GENERALIZED_TIME        0x18
+#define ASN1_UNIVERSAL_STRING        0x1C
+#define ASN1_BMP_STRING              0x1E
+#define ASN1_PRIMITIVE               0x00
+#define ASN1_CONSTRUCTED             0x20
+#define ASN1_CONTEXT_SPECIFIC        0x80
+/* \} name */
+/* \} addtogroup asn1_module */
+
+/** Returns the size of the binary string, without the trailing \\0 */
+#define OID_SIZE(x) (sizeof(x) - 1)
+
+/** Compares two asn1_buf structures for the same OID. Only works for
+ *  'defined' oid_str values (OID_HMAC_SHA1), you cannot use a 'unsigned
+ *  char *oid' here!
+ */
+#define OID_CMP(oid_str, oid_buf)                                   \
+        ( ( OID_SIZE(oid_str) == (oid_buf)->len ) &&                \
+          memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name Functions to parse ASN.1 data structures
+ * \{
+ */
+
+/**
+ * Type-length-value structure that allows for ASN1 using DER.
+ */
+typedef struct _asn1_buf
+{
+    int tag;                /**< ASN1 type, e.g. ASN1_UTF8_STRING. */
+    size_t len;             /**< ASN1 length, e.g. in octets. */
+    unsigned char *p;       /**< ASN1 data, e.g. in ASCII. */
+}
+asn1_buf;
+
+/**
+ * Container for ASN1 bit strings.
+ */
+typedef struct _asn1_bitstring
+{
+    size_t len;                 /**< ASN1 length, e.g. in octets. */
+    unsigned char unused_bits;  /**< Number of unused bits at the end of the string */
+    unsigned char *p;           /**< Raw ASN1 data for the bit string */
+}
+asn1_bitstring;
+
+/**
+ * Container for a sequence of ASN.1 items
+ */
+typedef struct _asn1_sequence
+{
+    asn1_buf buf;                   /**< Buffer containing the given ASN.1 item. */
+    struct _asn1_sequence *next;    /**< The next entry in the sequence. */
+}
+asn1_sequence;
+
+/**
+ * Container for a sequence or list of 'named' ASN.1 data items
+ */
+typedef struct _asn1_named_data
+{
+    asn1_buf oid;                   /**< The object identifier. */
+    asn1_buf val;                   /**< The named value. */
+    struct _asn1_named_data *next;  /**< The next entry in the sequence. */
+}
+asn1_named_data;
+
+/**
+ * \brief       Get the length of an ASN.1 element.
+ *              Updates the pointer to immediately behind the length.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   The variable that will receive the value
+ *
+ * \return      0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching
+ *              end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is
+ *              unparseable.
+ */
+int asn1_get_len( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len );
+
+/**
+ * \brief       Get the tag and length of the tag. Check for the requested tag.
+ *              Updates the pointer to immediately behind the tag and length.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   The variable that will receive the length
+ * \param tag   The expected tag
+ *
+ * \return      0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did
+ *              not match requested tag, or another specific ASN.1 error code.
+ */
+int asn1_get_tag( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len, int tag );
+
+/**
+ * \brief       Retrieve a boolean ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param val   The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int asn1_get_bool( unsigned char **p,
+                   const unsigned char *end,
+                   int *val );
+
+/**
+ * \brief       Retrieve an integer ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param val   The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int asn1_get_int( unsigned char **p,
+                  const unsigned char *end,
+                  int *val );
+
+/**
+ * \brief       Retrieve a bitstring ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param bs    The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
+                        asn1_bitstring *bs);
+
+/**
+ * \brief       Retrieve a bitstring ASN.1 tag without unused bits and its
+ *              value.
+ *              Updates the pointer to the beginning of the bit/octet string.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   Length of the actual bit/octect string in bytes
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+                             size_t *len );
+
+/**
+ * \brief       Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ *              Updated the pointer to immediately behind the full sequence tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param cur   First variable in the chain to fill
+ * \param tag   Type of sequence
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int asn1_get_sequence_of( unsigned char **p,
+                          const unsigned char *end,
+                          asn1_sequence *cur,
+                          int tag);
+
+#if defined(POLARSSL_BIGNUM_C)
+/**
+ * \brief       Retrieve a MPI value from an integer ASN.1 tag.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param X     The MPI that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int asn1_get_mpi( unsigned char **p,
+                  const unsigned char *end,
+                  mpi *X );
+#endif /* POLARSSL_BIGNUM_C */
+
+/**
+ * \brief       Retrieve an AlgorithmIdentifier ASN.1 sequence.
+ *              Updates the pointer to immediately behind the full
+ *              AlgorithmIdentifier.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param alg   The buffer to receive the OID
+ * \param params The buffer to receive the params (if any)
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int asn1_get_alg( unsigned char **p,
+                  const unsigned char *end,
+                  asn1_buf *alg, asn1_buf *params );
+
+/**
+ * \brief       Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
+ *              params.
+ *              Updates the pointer to immediately behind the full
+ *              AlgorithmIdentifier.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param alg   The buffer to receive the OID
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int asn1_get_alg_null( unsigned char **p,
+                       const unsigned char *end,
+                       asn1_buf *alg );
+
+/**
+ * \brief       Find a specific named_data entry in a sequence or list based on
+ *              the OID.
+ *
+ * \param list  The list to seek through
+ * \param oid   The OID to look for
+ * \param len   Size of the OID
+ *
+ * \return      NULL if not found, or a pointer to the existing entry.
+ */
+asn1_named_data *asn1_find_named_data( asn1_named_data *list,
+                                       const char *oid, size_t len );
+
+/**
+ * \brief       Free a asn1_named_data entry
+ *
+ * \param entry The named data entry to free
+ */
+void asn1_free_named_data( asn1_named_data *entry );
+
+/**
+ * \brief       Free all entries in a asn1_named_data list
+ *              Head will be set to NULL
+ *
+ * \param head  Pointer to the head of the list of named data entries to free
+ */
+void asn1_free_named_data_list( asn1_named_data **head );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* asn1.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/bignum.h u-boot-2011.06/include/bignum.h
--- u-boot-2011.06_original/include/bignum.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/bignum.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,749 @@
+/**
+ * \file bignum.h
+ *
+ * \brief  Multi-precision integer library
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_BIGNUM_H
+#define POLARSSL_BIGNUM_H
+
+//#include <stdio.h>
+//#include <string.h>
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
+#include <basetsd.h>
+#if (_MSC_VER <= 1200)
+typedef   signed short  int16_t;
+typedef unsigned short uint16_t;
+#else
+typedef  INT16  int16_t;
+typedef UINT16 uint16_t;
+#endif
+typedef  INT32  int32_t;
+typedef  INT64  int64_t;
+typedef UINT32 uint32_t;
+typedef UINT64 uint64_t;
+#else
+#include <linux/types.h>
+#endif /* _MSC_VER && !EFIX64 && !EFI32 */
+
+#define POLARSSL_ERR_MPI_FILE_IO_ERROR                     -0x0002  /**< An error occurred while reading from or writing to a file. */
+#define POLARSSL_ERR_MPI_BAD_INPUT_DATA                    -0x0004  /**< Bad input parameters to function. */
+#define POLARSSL_ERR_MPI_INVALID_CHARACTER                 -0x0006  /**< There is an invalid character in the digit string. */
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008  /**< The buffer is too small to write to. */
+#define POLARSSL_ERR_MPI_NEGATIVE_VALUE                    -0x000A  /**< The input arguments are negative or result in illegal output. */
+#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO                  -0x000C  /**< The input argument for division is zero, which is not allowed. */
+#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE                    -0x000E  /**< The input arguments are not acceptable. */
+#define POLARSSL_ERR_MPI_MALLOC_FAILED                     -0x0010  /**< Memory allocation failed. */
+
+#define MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
+
+/*
+ * Maximum size MPIs are allowed to grow to in number of limbs.
+ */
+#define POLARSSL_MPI_MAX_LIMBS                             10000
+
+#if !defined(POLARSSL_CONFIG_OPTIONS)
+/*
+ * Maximum window size used for modular exponentiation. Default: 6
+ * Minimum value: 1. Maximum value: 6.
+ *
+ * Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used
+ * for the sliding window calculation. (So 64 by default)
+ *
+ * Reduction in size, reduces speed.
+ */
+#define POLARSSL_MPI_WINDOW_SIZE                           6        /**< Maximum windows size used. */
+
+/*
+ * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
+ * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
+ *
+ * Note: Calculations can results temporarily in larger MPIs. So the number
+ * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
+ */
+#define POLARSSL_MPI_MAX_SIZE                              512      /**< Maximum number of bytes for usable MPIs. */
+
+#endif /* !POLARSSL_CONFIG_OPTIONS */
+
+#define POLARSSL_MPI_MAX_BITS                              ( 8 * POLARSSL_MPI_MAX_SIZE )    /**< Maximum number of bits for usable MPIs. */
+
+/*
+ * When reading from files with mpi_read_file() and writing to files with
+ * mpi_write_file() the buffer should have space
+ * for a (short) label, the MPI (in the provided radix), the newline
+ * characters and the '\0'.
+ *
+ * By default we assume at least a 10 char label, a minimum radix of 10
+ * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
+ * Autosized at compile time for at least a 10 char label, a minimum radix
+ * of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size.
+ *
+ * This used to be statically sized to 1250 for a maximum of 4096 bit
+ * numbers (1234 decimal chars).
+ *
+ * Calculate using the formula:
+ *  POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) +
+ *                                LabelSize + 6
+ */
+#define POLARSSL_MPI_MAX_BITS_SCALE100          ( 100 * POLARSSL_MPI_MAX_BITS )
+#define LN_2_DIV_LN_10_SCALE100                 332
+#define POLARSSL_MPI_RW_BUFFER_SIZE             ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
+
+/*
+ * Define the base integer type, architecture-wise
+ */
+#if defined(POLARSSL_HAVE_INT8)
+typedef   signed char  t_sint;
+typedef unsigned char  t_uint;
+typedef uint16_t       t_udbl;
+#define POLARSSL_HAVE_UDBL
+#else
+#if defined(POLARSSL_HAVE_INT16)
+typedef  int16_t t_sint;
+typedef uint16_t t_uint;
+typedef uint32_t t_udbl;
+#define POLARSSL_HAVE_UDBL
+#else
+  /*
+   * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes)
+   * by defining POLARSSL_HAVE_INT32 and undefining POARSSL_HAVE_ASM
+   */
+  #if ( ! defined(POLARSSL_HAVE_INT32) && \
+          defined(_MSC_VER) && defined(_M_AMD64) )
+    #define POLARSSL_HAVE_INT64
+    typedef  int64_t t_sint;
+    typedef uint64_t t_uint;
+  #else
+    #if ( ! defined(POLARSSL_HAVE_INT32) &&               \
+          defined(__GNUC__) && (                          \
+          defined(__amd64__) || defined(__x86_64__)    || \
+          defined(__ppc64__) || defined(__powerpc64__) || \
+          defined(__ia64__)  || defined(__alpha__)     || \
+          (defined(__sparc__) && defined(__arch64__))  || \
+          defined(__s390x__) ) )
+       #define POLARSSL_HAVE_INT64
+       typedef  int64_t t_sint;
+       typedef uint64_t t_uint;
+       typedef unsigned int t_udbl __attribute__((mode(TI)));
+       #define POLARSSL_HAVE_UDBL
+    #else
+       #define POLARSSL_HAVE_INT32
+       typedef  int32_t t_sint;
+       typedef uint32_t t_uint;
+       #if ( defined(_MSC_VER) && defined(_M_IX86) )
+         typedef uint64_t t_udbl;
+         #define POLARSSL_HAVE_UDBL
+       #else
+         #if defined( POLARSSL_HAVE_LONGLONG )
+           typedef unsigned long long t_udbl;
+           #define POLARSSL_HAVE_UDBL
+         #endif
+       #endif
+    #endif
+  #endif
+#endif /* POLARSSL_HAVE_INT16 */
+#endif /* POLARSSL_HAVE_INT8  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          MPI structure
+ */
+typedef struct
+{
+    int s;              /*!<  integer sign      */
+    size_t n;           /*!<  total # of limbs  */
+    t_uint *p;          /*!<  pointer to limbs  */
+}
+mpi;
+
+/**
+ * \brief           Initialize one MPI
+ *
+ * \param X         One MPI to initialize.
+ */
+void mpi_init( mpi *X );
+
+/**
+ * \brief          Unallocate one MPI
+ *
+ * \param X        One MPI to unallocate.
+ */
+void mpi_free( mpi *X );
+
+/**
+ * \brief          Enlarge to the specified number of limbs
+ *
+ * \param X        MPI to grow
+ * \param nblimbs  The target number of limbs
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_grow( mpi *X, size_t nblimbs );
+
+/**
+ * \brief          Resize down, keeping at least the specified number of limbs
+ *
+ * \param X        MPI to shrink
+ * \param nblimbs  The minimum number of limbs to keep
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_shrink( mpi *X, size_t nblimbs );
+
+/**
+ * \brief          Copy the contents of Y into X
+ *
+ * \param X        Destination MPI
+ * \param Y        Source MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_copy( mpi *X, const mpi *Y );
+
+/**
+ * \brief          Swap the contents of X and Y
+ *
+ * \param X        First MPI value
+ * \param Y        Second MPI value
+ */
+void mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief          Safe conditional assignement X = Y if assign is 1
+ *
+ * \param X        MPI to conditionally assign to
+ * \param Y        Value to be assigned
+ * \param assign   1: perform the assignment, 0: keep X's original value
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *
+ * \note           This function is equivalent to
+ *                      if( assign ) mpi_copy( X, Y );
+ *                 except that it avoids leaking any information about whether
+ *                 the assignment was done or not (the above code may leak
+ *                 information through branch prediction and/or memory access
+ *                 patterns analysis).
+ */
+int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign );
+
+/**
+ * \brief          Safe conditional swap X <-> Y if swap is 1
+ *
+ * \param X        First mpi value
+ * \param Y        Second mpi value
+ * \param assign   1: perform the swap, 0: keep X and Y's original values
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *
+ * \note           This function is equivalent to
+ *                      if( assign ) mpi_swap( X, Y );
+ *                 except that it avoids leaking any information about whether
+ *                 the assignment was done or not (the above code may leak
+ *                 information through branch prediction and/or memory access
+ *                 patterns analysis).
+ */
+int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char assign );
+
+/**
+ * \brief          Set value from integer
+ *
+ * \param X        MPI to set
+ * \param z        Value to use
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_lset( mpi *X, t_sint z );
+
+/**
+ * \brief          Get a specific bit from X
+ *
+ * \param X        MPI to use
+ * \param pos      Zero-based index of the bit in X
+ *
+ * \return         Either a 0 or a 1
+ */
+int mpi_get_bit( const mpi *X, size_t pos );
+
+/**
+ * \brief          Set a bit of X to a specific value of 0 or 1
+ *
+ * \note           Will grow X if necessary to set a bit to 1 in a not yet
+ *                 existing limb. Will not grow if bit should be set to 0
+ *
+ * \param X        MPI to use
+ * \param pos      Zero-based index of the bit in X
+ * \param val      The value to set the bit to (0 or 1)
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
+ */
+int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
+
+/**
+ * \brief          Return the number of zero-bits before the least significant
+ *                 '1' bit
+ *
+ * Note: Thus also the zero-based index of the least significant '1' bit
+ *
+ * \param X        MPI to use
+ */
+size_t mpi_lsb( const mpi *X );
+
+/**
+ * \brief          Return the number of bits up to and including the most
+ *                 significant '1' bit'
+ *
+ * Note: Thus also the one-based index of the most significant '1' bit
+ *
+ * \param X        MPI to use
+ */
+size_t mpi_msb( const mpi *X );
+
+/**
+ * \brief          Return the total size in bytes
+ *
+ * \param X        MPI to use
+ */
+size_t mpi_size( const mpi *X );
+
+/**
+ * \brief          Import from an ASCII string
+ *
+ * \param X        Destination MPI
+ * \param radix    Input numeric base
+ * \param s        Null-terminated string buffer
+ *
+ * \return         0 if successful, or a POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_string( mpi *X, int radix, const char *s );
+
+/**
+ * \brief          Export into an ASCII string
+ *
+ * \param X        Source MPI
+ * \param radix    Output numeric base
+ * \param s        String buffer
+ * \param slen     String buffer size
+ *
+ * \return         0 if successful, or a POLARSSL_ERR_MPI_XXX error code.
+ *                 *slen is always updated to reflect the amount
+ *                 of data that has (or would have) been written.
+ *
+ * \note           Call this function with *slen = 0 to obtain the
+ *                 minimum required buffer size in *slen.
+ */
+int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
+
+#if defined(POLARSSL_FS_IO)
+/**
+ * \brief          Read X from an opened file
+ *
+ * \param X        Destination MPI
+ * \param radix    Input numeric base
+ * \param fin      Input file handle
+ *
+ * \return         0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if
+ *                 the file read buffer is too small or a
+ *                 POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief          Write X into an opened file, or stdout if fout is NULL
+ *
+ * \param p        Prefix, can be NULL
+ * \param X        Source MPI
+ * \param radix    Output numeric base
+ * \param fout     Output file handle (can be NULL)
+ *
+ * \return         0 if successful, or a POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note           Set fout == NULL to print X on the console.
+ */
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
+#endif /* POLARSSL_FS_IO */
+
+/**
+ * \brief          Import X from unsigned binary data, big endian
+ *
+ * \param X        Destination MPI
+ * \param buf      Input buffer
+ * \param buflen   Input buffer size
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief          Export X into unsigned binary data, big endian
+ *
+ * \param X        Source MPI
+ * \param buf      Output buffer
+ * \param buflen   Output buffer size
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ */
+int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
+
+/**
+ * \brief          Left-shift: X <<= count
+ *
+ * \param X        MPI to shift
+ * \param count    Amount to shift
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_shift_l( mpi *X, size_t count );
+
+/**
+ * \brief          Right-shift: X >>= count
+ *
+ * \param X        MPI to shift
+ * \param count    Amount to shift
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_shift_r( mpi *X, size_t count );
+
+/**
+ * \brief          Compare unsigned values
+ *
+ * \param X        Left-hand MPI
+ * \param Y        Right-hand MPI
+ *
+ * \return         1 if |X| is greater than |Y|,
+ *                -1 if |X| is lesser  than |Y| or
+ *                 0 if |X| is equal to |Y|
+ */
+int mpi_cmp_abs( const mpi *X, const mpi *Y );
+
+/**
+ * \brief          Compare signed values
+ *
+ * \param X        Left-hand MPI
+ * \param Y        Right-hand MPI
+ *
+ * \return         1 if X is greater than Y,
+ *                -1 if X is lesser  than Y or
+ *                 0 if X is equal to Y
+ */
+int mpi_cmp_mpi( const mpi *X, const mpi *Y );
+
+/**
+ * \brief          Compare signed values
+ *
+ * \param X        Left-hand MPI
+ * \param z        The integer value to compare to
+ *
+ * \return         1 if X is greater than z,
+ *                -1 if X is lesser  than z or
+ *                 0 if X is equal to z
+ */
+int mpi_cmp_int( const mpi *X, t_sint z );
+
+/**
+ * \brief          Unsigned addition: X = |A| + |B|
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Unsigned subtraction: X = |A| - |B|
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Signed addition: X = A + B
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Signed subtraction: X = A - B
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Signed addition: X = A + b
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param b        The integer value to add
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_add_int( mpi *X, const mpi *A, t_sint b );
+
+/**
+ * \brief          Signed subtraction: X = A - b
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param b        The integer value to subtract
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
+
+/**
+ * \brief          Baseline multiplication: X = A * B
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Baseline multiplication: X = A * b
+ *                 Note: despite the functon signature, b is treated as a
+ *                 t_uint.  Negative values of b are treated as large positive
+ *                 values.
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param b        The integer value to multiply with
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
+
+/**
+ * \brief          Division by mpi: A = Q * B + R
+ *
+ * \param Q        Destination MPI for the quotient
+ * \param R        Destination MPI for the rest value
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note           Either Q or R can be NULL.
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Division by int: A = Q * b + R
+ *
+ * \param Q        Destination MPI for the quotient
+ * \param R        Destination MPI for the rest value
+ * \param A        Left-hand MPI
+ * \param b        Integer to divide by
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note           Either Q or R can be NULL.
+ */
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
+
+/**
+ * \brief          Modulo: R = A mod B
+ *
+ * \param R        Destination MPI for the rest value
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
+ *                 POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
+ */
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Modulo: r = A mod b
+ *
+ * \param r        Destination t_uint
+ * \param A        Left-hand MPI
+ * \param b        Integer to divide by
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
+ *                 POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
+ */
+int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
+
+/**
+ * \brief          Sliding-window exponentiation: X = A^E mod N
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param E        Exponent MPI
+ * \param N        Modular MPI
+ * \param _RR      Speed-up MPI used for recalculations
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
+ *                 if E is negative
+ *
+ * \note           _RR is used to avoid re-computing R*R mod N across
+ *                 multiple calls, which speeds up things a bit. It can
+ *                 be set to NULL if the extra performance is unneeded.
+ */
+int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
+
+/**
+ * \brief          Fill an MPI X with size bytes of random
+ *
+ * \param X        Destination MPI
+ * \param size     Size in bytes
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_fill_random( mpi *X, size_t size,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief          Greatest common divisor: G = gcd(A, B)
+ *
+ * \param G        Destination MPI
+ * \param A        Left-hand MPI
+ * \param B        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
+
+/**
+ * \brief          Modular inverse: X = A^-1 mod N
+ *
+ * \param X        Destination MPI
+ * \param A        Left-hand MPI
+ * \param N        Right-hand MPI
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
+                   POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ */
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
+
+/**
+ * \brief          Miller-Rabin primality test
+ *
+ * \param X        MPI to check
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ *
+ * \return         0 if successful (probably prime),
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int mpi_is_prime( mpi *X,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng );
+
+/**
+ * \brief          Prime number generation
+ *
+ * \param X        Destination MPI
+ * \param nbits    Required size of X in bits
+ *                 ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS )
+ * \param dh_flag  If 1, then (X-1)/2 will be prime too
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ *
+ * \return         0 if successful (probably prime),
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
+                   int (*f_rng)(void *, unsigned char *, size_t),
+                   void *p_rng );
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/bn_mul.h u-boot-2011.06/include/bn_mul.h
--- u-boot-2011.06_original/include/bn_mul.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/bn_mul.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,631 @@
+/**
+ * \file bn_mul.h
+ */
+/*
+ *      Multiply source vector [s] with b, add result
+ *       to destination vector [d] and set carry c.
+ *
+ *      Currently supports:
+ *
+ *         . IA-32 (386+)         . AMD64 / EM64T
+ *         . IA-32 (SSE2)         . Motorola 68000
+ *         . PowerPC, 32-bit      . MicroBlaze
+ *         . PowerPC, 64-bit      . TriCore
+ *         . SPARC v8             . ARM v3+
+ *         . Alpha                . MIPS32
+ *         . C, longlong          . C, generic
+ */
+#ifndef XYSSL_BN_MUL_H
+#define XYSSL_BN_MUL_H
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT                            \
+    asm( "movl   %%ebx, %0      " : "=m" (t));  \
+    asm( "movl   %0, %%esi      " :: "m" (s));  \
+    asm( "movl   %0, %%edi      " :: "m" (d));  \
+    asm( "movl   %0, %%ecx      " :: "m" (c));  \
+    asm( "movl   %0, %%ebx      " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "lodsl                 " );            \
+    asm( "mull   %ebx           " );            \
+    asm( "addl   %ecx,   %eax   " );            \
+    asm( "adcl   $0,     %edx   " );            \
+    asm( "addl   (%edi), %eax   " );            \
+    asm( "adcl   $0,     %edx   " );            \
+    asm( "movl   %edx,   %ecx   " );            \
+    asm( "stosl                 " );
+
+#define MULADDC_STOP                            \
+    asm( "movl   %0, %%ebx      " :: "m" (t));  \
+    asm( "movl   %%ecx, %0      " : "=m" (c));  \
+    asm( "movl   %%edi, %0      " : "=m" (d));  \
+    asm( "movl   %%esi, %0      " : "=m" (s) :: \
+    "eax", "ecx", "edx", "esi", "edi" );
+
+#if defined(XYSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT                            \
+    asm( "movd     %ecx,     %mm1     " );      \
+    asm( "movd     %ebx,     %mm0     " );      \
+    asm( "movd     (%edi),   %mm3     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     (%esi),   %mm2     " );      \
+    asm( "pmuludq  %mm0,     %mm2     " );      \
+    asm( "movd     4(%esi),  %mm4     " );      \
+    asm( "pmuludq  %mm0,     %mm4     " );      \
+    asm( "movd     8(%esi),  %mm6     " );      \
+    asm( "pmuludq  %mm0,     %mm6     " );      \
+    asm( "movd     12(%esi), %mm7     " );      \
+    asm( "pmuludq  %mm0,     %mm7     " );      \
+    asm( "paddq    %mm2,     %mm1     " );      \
+    asm( "movd     4(%edi),  %mm3     " );      \
+    asm( "paddq    %mm4,     %mm3     " );      \
+    asm( "movd     8(%edi),  %mm5     " );      \
+    asm( "paddq    %mm6,     %mm5     " );      \
+    asm( "movd     12(%edi), %mm4     " );      \
+    asm( "paddq    %mm4,     %mm7     " );      \
+    asm( "movd     %mm1,     (%edi)   " );      \
+    asm( "movd     16(%esi), %mm2     " );      \
+    asm( "pmuludq  %mm0,     %mm2     " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     20(%esi), %mm4     " );      \
+    asm( "pmuludq  %mm0,     %mm4     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     24(%esi), %mm6     " );      \
+    asm( "pmuludq  %mm0,     %mm6     " );      \
+    asm( "movd     %mm1,     4(%edi)  " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     28(%esi), %mm3     " );      \
+    asm( "pmuludq  %mm0,     %mm3     " );      \
+    asm( "paddq    %mm5,     %mm1     " );      \
+    asm( "movd     16(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm2     " );      \
+    asm( "movd     %mm1,     8(%edi)  " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm7,     %mm1     " );      \
+    asm( "movd     20(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm4     " );      \
+    asm( "movd     %mm1,     12(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm2,     %mm1     " );      \
+    asm( "movd     24(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm6     " );      \
+    asm( "movd     %mm1,     16(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm4,     %mm1     " );      \
+    asm( "movd     28(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm3     " );      \
+    asm( "movd     %mm1,     20(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm6,     %mm1     " );      \
+    asm( "movd     %mm1,     24(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     %mm1,     28(%edi) " );      \
+    asm( "addl     $32,      %edi     " );      \
+    asm( "addl     $32,      %esi     " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     %mm1,     %ecx     " );
+
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT                            \
+    asm( "movq   %0, %%rsi      " :: "m" (s));  \
+    asm( "movq   %0, %%rdi      " :: "m" (d));  \
+    asm( "movq   %0, %%rcx      " :: "m" (c));  \
+    asm( "movq   %0, %%rbx      " :: "m" (b));  \
+    asm( "xorq   %r8, %r8       " );
+
+#define MULADDC_CORE                            \
+    asm( "movq  (%rsi),%rax     " );            \
+    asm( "mulq   %rbx           " );            \
+    asm( "addq   $8,   %rsi     " );            \
+    asm( "addq   %rcx, %rax     " );            \
+    asm( "movq   %r8,  %rcx     " );            \
+    asm( "adcq   $0,   %rdx     " );            \
+    asm( "nop                   " );            \
+    asm( "addq   %rax, (%rdi)   " );            \
+    asm( "adcq   %rdx, %rcx     " );            \
+    asm( "addq   $8,   %rdi     " );
+
+#define MULADDC_STOP                            \
+    asm( "movq   %%rcx, %0      " : "=m" (c));  \
+    asm( "movq   %%rdi, %0      " : "=m" (d));  \
+    asm( "movq   %%rsi, %0      " : "=m" (s) :: \
+    "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT                            \
+    asm( "movl   %0, %%a2       " :: "m" (s));  \
+    asm( "movl   %0, %%a3       " :: "m" (d));  \
+    asm( "movl   %0, %%d3       " :: "m" (c));  \
+    asm( "movl   %0, %%d2       " :: "m" (b));  \
+    asm( "moveq  #0, %d0        " );
+
+#define MULADDC_CORE                            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d4:%d1   " );            \
+    asm( "addl   %d3, %d1       " );            \
+    asm( "addxl  %d0, %d4       " );            \
+    asm( "moveq  #0,  %d3       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "addxl  %d4, %d3       " );
+
+#define MULADDC_STOP                            \
+    asm( "movl   %%d3, %0       " : "=m" (c));  \
+    asm( "movl   %%a3, %0       " : "=m" (d));  \
+    asm( "movl   %%a2, %0       " : "=m" (s) :: \
+    "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
+
+#define MULADDC_HUIT                            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d4:%d1   " );            \
+    asm( "addxl  %d3, %d1       " );            \
+    asm( "addxl  %d0, %d4       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d3:%d1   " );            \
+    asm( "addxl  %d4, %d1       " );            \
+    asm( "addxl  %d0, %d3       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d4:%d1   " );            \
+    asm( "addxl  %d3, %d1       " );            \
+    asm( "addxl  %d0, %d4       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d3:%d1   " );            \
+    asm( "addxl  %d4, %d1       " );            \
+    asm( "addxl  %d0, %d3       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d4:%d1   " );            \
+    asm( "addxl  %d3, %d1       " );            \
+    asm( "addxl  %d0, %d4       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d3:%d1   " );            \
+    asm( "addxl  %d4, %d1       " );            \
+    asm( "addxl  %d0, %d3       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d4:%d1   " );            \
+    asm( "addxl  %d3, %d1       " );            \
+    asm( "addxl  %d0, %d4       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "movel  %a2@+, %d1     " );            \
+    asm( "mulul  %d2, %d3:%d1   " );            \
+    asm( "addxl  %d4, %d1       " );            \
+    asm( "addxl  %d0, %d3       " );            \
+    asm( "addl   %d1, %a3@+     " );            \
+    asm( "addxl  %d0, %d3       " );
+
+#endif /* MC68000 */
+
+#if defined(__powerpc__)   || defined(__ppc__)
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#define MULADDC_INIT                            \
+    asm( "ld     %%r3, %0       " :: "m" (s));  \
+    asm( "ld     %%r4, %0       " :: "m" (d));  \
+    asm( "ld     %%r5, %0       " :: "m" (c));  \
+    asm( "ld     %%r6, %0       " :: "m" (b));  \
+    asm( "addi   %r3, %r3, -8   " );            \
+    asm( "addi   %r4, %r4, -8   " );            \
+    asm( "addic  %r5, %r5,  0   " );
+
+#define MULADDC_CORE                            \
+    asm( "ldu    %r7, 8(%r3)    " );            \
+    asm( "mulld  %r8, %r7, %r6  " );            \
+    asm( "mulhdu %r9, %r7, %r6  " );            \
+    asm( "adde   %r8, %r8, %r5  " );            \
+    asm( "ld     %r7, 8(%r4)    " );            \
+    asm( "addze  %r5, %r9       " );            \
+    asm( "addc   %r8, %r8, %r7  " );            \
+    asm( "stdu   %r8, 8(%r4)    " );
+
+#define MULADDC_STOP                            \
+    asm( "addze  %r5, %r5       " );            \
+    asm( "addi   %r4, %r4, 8    " );            \
+    asm( "addi   %r3, %r3, 8    " );            \
+    asm( "std    %%r5, %0       " : "=m" (c));  \
+    asm( "std    %%r4, %0       " : "=m" (d));  \
+    asm( "std    %%r3, %0       " : "=m" (s) :: \
+    "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT                            \
+    asm( "lwz    %%r3, %0       " :: "m" (s));  \
+    asm( "lwz    %%r4, %0       " :: "m" (d));  \
+    asm( "lwz    %%r5, %0       " :: "m" (c));  \
+    asm( "lwz    %%r6, %0       " :: "m" (b));  \
+    asm( "addi   %r3, %r3, -4   " );            \
+    asm( "addi   %r4, %r4, -4   " );            \
+    asm( "addic  %r5, %r5,  0   " );
+
+#define MULADDC_CORE                            \
+    asm( "lwzu   %r7, 4(%r3)    " );            \
+    asm( "mullw  %r8, %r7, %r6  " );            \
+    asm( "mulhwu %r9, %r7, %r6  " );            \
+    asm( "adde   %r8, %r8, %r5  " );            \
+    asm( "lwz    %r7, 4(%r4)    " );            \
+    asm( "addze  %r5, %r9       " );            \
+    asm( "addc   %r8, %r8, %r7  " );            \
+    asm( "stwu   %r8, 4(%r4)    " );
+
+#define MULADDC_STOP                            \
+    asm( "addze  %r5, %r5       " );            \
+    asm( "addi   %r4, %r4, 4    " );            \
+    asm( "addi   %r3, %r3, 4    " );            \
+    asm( "stw    %%r5, %0       " : "=m" (c));  \
+    asm( "stw    %%r4, %0       " : "=m" (d));  \
+    asm( "stw    %%r3, %0       " : "=m" (s) :: \
+    "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif /* PPC32 */
+#endif /* PPC64 */
+
+#if defined(__sparc__)
+
+#define MULADDC_INIT                            \
+    asm( "ld     %0, %%o0       " :: "m" (s));  \
+    asm( "ld     %0, %%o1       " :: "m" (d));  \
+    asm( "ld     %0, %%o2       " :: "m" (c));  \
+    asm( "ld     %0, %%o3       " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "ld    [%o0], %o4      " );            \
+    asm( "inc      4,  %o0      " );            \
+    asm( "ld    [%o1], %o5      " );            \
+    asm( "umul   %o3,  %o4, %o4 " );            \
+    asm( "addcc  %o4,  %o2, %o4 " );            \
+    asm( "rd      %y,  %g1      " );            \
+    asm( "addx   %g1,    0, %g1 " );            \
+    asm( "addcc  %o4,  %o5, %o4 " );            \
+    asm( "st     %o4, [%o1]     " );            \
+    asm( "addx   %g1,    0, %o2 " );            \
+    asm( "inc      4,  %o1      " );
+
+#define MULADDC_STOP                            \
+    asm( "st     %%o2, %0       " : "=m" (c));  \
+    asm( "st     %%o1, %0       " : "=m" (d));  \
+    asm( "st     %%o0, %0       " : "=m" (s) :: \
+    "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+
+#endif /* SPARCv8 */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT                            \
+    asm( "lwi   r3,   %0        " :: "m" (s));  \
+    asm( "lwi   r4,   %0        " :: "m" (d));  \
+    asm( "lwi   r5,   %0        " :: "m" (c));  \
+    asm( "lwi   r6,   %0        " :: "m" (b));  \
+    asm( "andi  r7,   r6, 0xffff" );            \
+    asm( "bsrli r6,   r6, 16    " );
+
+#define MULADDC_CORE                            \
+    asm( "lhui  r8,   r3,   0   " );            \
+    asm( "addi  r3,   r3,   2   " );            \
+    asm( "lhui  r9,   r3,   0   " );            \
+    asm( "addi  r3,   r3,   2   " );            \
+    asm( "mul   r10,  r9,  r6   " );            \
+    asm( "mul   r11,  r8,  r7   " );            \
+    asm( "mul   r12,  r9,  r7   " );            \
+    asm( "mul   r13,  r8,  r6   " );            \
+    asm( "bsrli  r8, r10,  16   " );            \
+    asm( "bsrli  r9, r11,  16   " );            \
+    asm( "add   r13, r13,  r8   " );            \
+    asm( "add   r13, r13,  r9   " );            \
+    asm( "bslli r10, r10,  16   " );            \
+    asm( "bslli r11, r11,  16   " );            \
+    asm( "add   r12, r12, r10   " );            \
+    asm( "addc  r13, r13,  r0   " );            \
+    asm( "add   r12, r12, r11   " );            \
+    asm( "addc  r13, r13,  r0   " );            \
+    asm( "lwi   r10,  r4,   0   " );            \
+    asm( "add   r12, r12, r10   " );            \
+    asm( "addc  r13, r13,  r0   " );            \
+    asm( "add   r12, r12,  r5   " );            \
+    asm( "addc   r5, r13,  r0   " );            \
+    asm( "swi   r12,  r4,   0   " );            \
+    asm( "addi   r4,  r4,   4   " );
+
+#define MULADDC_STOP                            \
+    asm( "swi   r5,   %0        " : "=m" (c));  \
+    asm( "swi   r4,   %0        " : "=m" (d));  \
+    asm( "swi   r3,   %0        " : "=m" (s) :: \
+     "r3", "r4" , "r5" , "r6" , "r7" , "r8" ,   \
+     "r9", "r10", "r11", "r12", "r13" );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT                            \
+    asm( "ld.a   %%a2, %0       " :: "m" (s));  \
+    asm( "ld.a   %%a3, %0       " :: "m" (d));  \
+    asm( "ld.w   %%d4, %0       " :: "m" (c));  \
+    asm( "ld.w   %%d1, %0       " :: "m" (b));  \
+    asm( "xor    %d5, %d5       " );
+
+#define MULADDC_CORE                            \
+    asm( "ld.w   %d0,   [%a2+]      " );        \
+    asm( "madd.u %e2, %e4, %d0, %d1 " );        \
+    asm( "ld.w   %d0,   [%a3]       " );        \
+    asm( "addx   %d2,    %d2,  %d0  " );        \
+    asm( "addc   %d3,    %d3,    0  " );        \
+    asm( "mov    %d4,    %d3        " );        \
+    asm( "st.w  [%a3+],  %d2        " );
+
+#define MULADDC_STOP                            \
+    asm( "st.w   %0, %%d4       " : "=m" (c));  \
+    asm( "st.a   %0, %%a3       " : "=m" (d));  \
+    asm( "st.a   %0, %%a2       " : "=m" (s) :: \
+    "d0", "d1", "e2", "d4", "a2", "a3" );
+
+#endif /* TriCore */
+
+#if defined(__ARM__)
+
+#define MULADDC_INIT                            \
+    asm( "ldr    r0, %0         " :: "m" (s));  \
+    asm( "ldr    r1, %0         " :: "m" (d));  \
+    asm( "ldr    r2, %0         " :: "m" (c));  \
+    asm( "ldr    r3, %0         " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "ldr    r4, [r0], #4   " );            \
+    asm( "mov    r5, #0         " );            \
+    asm( "ldr    r6, [r1]       " );            \
+    asm( "umlal  r2, r5, r3, r4 " );            \
+    asm( "adds   r7, r6, r2     " );            \
+    asm( "adc    r2, r5, #0     " );            \
+    asm( "str    r7, [r1], #4   " );
+
+#define MULADDC_STOP                            \
+    asm( "str    r2, %0         " : "=m" (c));  \
+    asm( "str    r1, %0         " : "=m" (d));  \
+    asm( "str    r0, %0         " : "=m" (s) :: \
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT                            \
+    asm( "ldq    $1, %0         " :: "m" (s));  \
+    asm( "ldq    $2, %0         " :: "m" (d));  \
+    asm( "ldq    $3, %0         " :: "m" (c));  \
+    asm( "ldq    $4, %0         " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "ldq    $6,  0($1)     " );            \
+    asm( "addq   $1,  8, $1     " );            \
+    asm( "mulq   $6, $4, $7     " );            \
+    asm( "umulh  $6, $4, $6     " );            \
+    asm( "addq   $7, $3, $7     " );            \
+    asm( "cmpult $7, $3, $3     " );            \
+    asm( "ldq    $5,  0($2)     " );            \
+    asm( "addq   $7, $5, $7     " );            \
+    asm( "cmpult $7, $5, $5     " );            \
+    asm( "stq    $7,  0($2)     " );            \
+    asm( "addq   $2,  8, $2     " );            \
+    asm( "addq   $6, $3, $3     " );            \
+    asm( "addq   $5, $3, $3     " );
+
+#define MULADDC_STOP                            \
+    asm( "stq    $3, %0         " : "=m" (c));  \
+    asm( "stq    $2, %0         " : "=m" (d));  \
+    asm( "stq    $1, %0         " : "=m" (s) :: \
+    "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
+
+#endif /* Alpha */
+
+#if defined(__mips__)
+
+#define MULADDC_INIT                            \
+    asm( "lw     $10, %0        " :: "m" (s));  \
+    asm( "lw     $11, %0        " :: "m" (d));  \
+    asm( "lw     $12, %0        " :: "m" (c));  \
+    asm( "lw     $13, %0        " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "lw     $14, 0($10)    " );            \
+    asm( "multu  $13, $14       " );            \
+    asm( "addi   $10, $10, 4    " );            \
+    asm( "mflo   $14            " );            \
+    asm( "mfhi   $9             " );            \
+    asm( "addu   $14, $12, $14  " );            \
+    asm( "lw     $15, 0($11)    " );            \
+    asm( "sltu   $12, $14, $12  " );            \
+    asm( "addu   $15, $14, $15  " );            \
+    asm( "sltu   $14, $15, $14  " );            \
+    asm( "addu   $12, $12, $9   " );            \
+    asm( "sw     $15, 0($11)    " );            \
+    asm( "addu   $12, $12, $14  " );            \
+    asm( "addi   $11, $11, 4    " );
+
+#define MULADDC_STOP                            \
+    asm( "sw     $12, %0        " : "=m" (c));  \
+    asm( "sw     $11, %0        " : "=m" (d));  \
+    asm( "sw     $10, %0        " : "=m" (s) :: \
+    "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
+
+#endif /* MIPS */
+#elif defined(__CC_ARM)
+#define MULADDC_INIT                            \
+    register int r0, r1, r2, r3, r4, r5, r6, r7;\
+    __asm( "mov    r0, s         " );           \
+    __asm( "mov    r1, d         " );           \
+    __asm( "mov    r2, c         " );           \
+    __asm( "mov    r3, b         " );           
+
+#define MULADDC_CORE                            \
+    __asm( "ldr    r4, [r0], #4   " );          \
+    __asm( "mov    r5, #0         " );          \
+    __asm( "ldr    r6, [r1]       " );          \
+    __asm( "umlal  r2, r5, r3, r4 " );          \
+    __asm( "adds   r7, r6, r2     " );          \
+    __asm( "adc    r2, r5, #0     " );          \
+    __asm( "str    r7, [r1], #4   " );            
+
+
+#define MULADDC_STOP                            \
+    __asm( "mov    c, r2         ");            \
+    __asm( "mov    d, r1         ");            \
+    __asm( "mov    s, r0         ");
+
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT                            \
+    __asm   mov     esi, s                      \
+    __asm   mov     edi, d                      \
+    __asm   mov     ecx, c                      \
+    __asm   mov     ebx, b
+
+#define MULADDC_CORE                            \
+    __asm   lodsd                               \
+    __asm   mul     ebx                         \
+    __asm   add     eax, ecx                    \
+    __asm   adc     edx, 0                      \
+    __asm   add     eax, [edi]                  \
+    __asm   adc     edx, 0                      \
+    __asm   mov     ecx, edx                    \
+    __asm   stosd
+
+#define MULADDC_STOP                            \
+    __asm   mov     c, ecx                      \
+    __asm   mov     d, edi                      \
+    __asm   mov     s, esi                      \
+
+#if defined(XYSSL_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT                            \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0xC9             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0xC3             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x1F             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x16             \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x66  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xE0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x76  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x7E  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF8             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCA             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x5F  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xDC             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xEE             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x67  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xFC             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x0F             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x56  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD0             \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x66  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xE0             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x76  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF0             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x5E  EMIT 0x1C  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD8             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCD             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xD5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCF             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xE5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCA             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xF5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCC             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x1C  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xDD             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCE             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x1C  \
+    EMIT 0x83  EMIT 0xC7  EMIT 0x20             \
+    EMIT 0x83  EMIT 0xC6  EMIT 0x20             \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0xC9
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#if !defined(MULADDC_CORE)
+#if defined(XYSSL_HAVE_LONGLONG)
+
+#define MULADDC_INIT                    \
+{                                       \
+    t_dbl r;                            \
+    t_int r0, r1;
+
+#define MULADDC_CORE                    \
+    r   = *(s++) * (t_dbl) b;           \
+    r0  = r;                            \
+    r1  = r >> biL;                     \
+    r0 += c;  r1 += (r0 <  c);          \
+    r0 += *d; r1 += (r0 < *d);          \
+    c = r1; *(d++) = r0;
+
+#define MULADDC_STOP                    \
+}
+
+#else
+#define MULADDC_INIT                    \
+{                                       \
+    t_int s0, s1, b0, b1;               \
+    t_int r0, r1, rx, ry;               \
+    b0 = ( b << biH ) >> biH;           \
+    b1 = ( b >> biH );
+
+#define MULADDC_CORE                    \
+    s0 = ( *s << biH ) >> biH;          \
+    s1 = ( *s >> biH ); s++;            \
+    rx = s0 * b1; r0 = s0 * b0;         \
+    ry = s1 * b0; r1 = s1 * b1;         \
+    r1 += ( rx >> biH );                \
+    r1 += ( ry >> biH );                \
+    rx <<= biH; ry <<= biH;             \
+    r0 += rx; r1 += (r0 < rx);          \
+    r0 += ry; r1 += (r0 < ry);          \
+    r0 +=  c; r1 += (r0 <  c);          \
+    r0 += *d; r1 += (r0 < *d);          \
+    c = r1; *(d++) = r0;
+
+#define MULADDC_STOP                    \
+}
+
+#endif /* C (generic)  */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/bouncebuf.h u-boot-2011.06/include/bouncebuf.h
--- u-boot-2011.06_original/include/bouncebuf.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/bouncebuf.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,72 @@
+/*
+ * Generic bounce buffer implementation
+ *
+ * Copyright (C) 2012 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __INCLUDE_BOUNCEBUF_H__
+#define __INCLUDE_BOUNCEBUF_H__
+
+#include <linux/types.h>
+
+/*
+ * GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware.
+ * The source buffer is copied into the bounce buffer (if unaligned, otherwise
+ * the source buffer is used directly) upon start() call, then the operation
+ * requiring the aligned transfer happens, then the bounce buffer is lost upon
+ * stop() call.
+ */
+#define GEN_BB_READ	(1 << 0)
+/*
+ * GEN_BB_WRITE -- Data are written into the buffer eg. by DMA hardware.
+ * The source buffer starts in an undefined state upon start() call, then the
+ * operation requiring the aligned transfer happens, then the bounce buffer is
+ * copied into the destination buffer (if unaligned, otherwise destination
+ * buffer is used directly) upon stop() call.
+ */
+#define GEN_BB_WRITE	(1 << 1)
+/*
+ * GEN_BB_RW -- Data are read and written into the buffer eg. by DMA hardware.
+ * The source buffer is copied into the bounce buffer (if unaligned, otherwise
+ * the source buffer is used directly) upon start() call, then the  operation
+ * requiring the aligned transfer happens, then the bounce buffer is  copied
+ * into the destination buffer (if unaligned, otherwise destination buffer is
+ * used directly) upon stop() call.
+ */
+#define GEN_BB_RW	(GEN_BB_READ | GEN_BB_WRITE)
+
+struct bounce_buffer {
+	/* Copy of data parameter passed to start() */
+	void *user_buffer;
+	/*
+	 * DMA-aligned buffer. This field is always set to the value that
+	 * should be used for DMA; either equal to .user_buffer, or to a
+	 * freshly allocated aligned buffer.
+	 */
+	void *bounce_buffer;
+	/* Copy of len parameter passed to start() */
+	size_t len;
+	/* DMA-aligned buffer length */
+	size_t len_aligned;
+	/* Copy of flags parameter passed to start() */
+	unsigned int flags;
+};
+
+/**
+ * bounce_buffer_start() -- Start the bounce buffer session
+ * state:	stores state passed between bounce_buffer_{start,stop}
+ * data:	pointer to buffer to be aligned
+ * len:		length of the buffer
+ * flags:	flags describing the transaction, see above.
+ */
+int bounce_buffer_start(struct bounce_buffer *state, void *data,
+			size_t len, unsigned int flags);
+/**
+ * bounce_buffer_stop() -- Finish the bounce buffer session
+ * state:	stores state passed between bounce_buffer_{start,stop}
+ */
+int bounce_buffer_stop(struct bounce_buffer *state);
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1800l_demux.h u-boot-2011.06/include/cnc1800l_demux.h
--- u-boot-2011.06_original/include/cnc1800l_demux.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1800l_demux.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,200 @@
+#ifndef __CNC1800L_DEMUX_H__
+#define __CNC1800L_DEMUX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSDEMUX_INVALID_HANDLE     -1
+
+typedef void *CSDEMUX_HANDLE;
+
+typedef enum
+{
+	DEMUX_SUCCEED = 0,
+	DEMUX_FAILED = -1
+} CSDEMUX_RESULT;
+
+typedef enum
+{
+	DEMUX_DISABLE = 0,
+	DEMUX_ENABLE = 1,
+} CSDEMUX_STATUS;
+
+typedef enum
+{
+	DEMUX_CHL_UNDEF = -1,
+	DEMUX_CHL_ID0 = 0,
+	DEMUX_CHL_ID1,
+	DEMUX_CHL_NUM
+} CSDEMUX_CHL_ID;
+
+typedef enum
+{
+	DEMUX_PIDFT_UNDEF = -1,
+	DEMUX_PIDFT_ID0 = 0,
+	DEMUX_PIDFT_ID1,
+	DEMUX_PIDFT_ID2,
+	DEMUX_PIDFT_ID3,
+	DEMUX_PIDFT_ID4,
+	DEMUX_PIDFT_ID5,
+	DEMUX_PIDFT_ID6,
+	DEMUX_PIDFT_ID7,
+	DEMUX_PIDFT_ID8,
+	DEMUX_PIDFT_ID9,
+	DEMUX_PIDFT_ID10,
+	DEMUX_PIDFT_ID11,
+	DEMUX_PIDFT_ID12,
+	DEMUX_PIDFT_ID13,
+	DEMUX_PIDFT_ID14,
+	DEMUX_PIDFT_ID15,
+	DEMUX_PIDFT_ID16,
+	DEMUX_PIDFT_ID17,
+	DEMUX_PIDFT_ID18,
+	DEMUX_PIDFT_ID19,
+	DEMUX_PIDFT_ID20,
+	DEMUX_PIDFT_ID21,
+	DEMUX_PIDFT_ID22,
+	DEMUX_PIDFT_ID23,
+	DEMUX_PIDFT_ID24,
+	DEMUX_PIDFT_ID25,
+	DEMUX_PIDFT_ID26,
+	DEMUX_PIDFT_ID27,
+	DEMUX_PIDFT_ID28,
+	DEMUX_PIDFT_ID29,
+	DEMUX_PIDFT_ID30,
+	DEMUX_PIDFT_ID31,
+	DEMUX_PIDFT_ID32,
+	DEMUX_PIDFT_ID33,
+	DEMUX_PIDFT_ID34,
+	DEMUX_PIDFT_ID35,
+	DEMUX_PIDFT_ID36,
+	DEMUX_PIDFT_ID37,
+	DEMUX_PIDFT_ID38,
+	DEMUX_PIDFT_ID39,
+	DEMUX_PIDFT_ID40,
+	DEMUX_PIDFT_ID41,
+	DEMUX_PIDFT_ID42,
+	DEMUX_PIDFT_ID43,
+	DEMUX_PIDFT_ID44,
+	DEMUX_PIDFT_ID45,
+	DEMUX_PIDFT_ID46,
+	DEMUX_PIDFT_ID47,
+	DEMUX_PIDFT_ID48,
+	DEMUX_PIDFT_ID49,
+	DEMUX_PIDFT_ID50,
+	DEMUX_PIDFT_ID51,
+	DEMUX_PIDFT_ID52,
+	DEMUX_PIDFT_ID53,
+	DEMUX_PIDFT_ID54,
+	DEMUX_PIDFT_ID55,
+	DEMUX_PIDFT_ID56,
+	DEMUX_PIDFT_ID57,
+	DEMUX_PIDFT_ID58,
+	DEMUX_PIDFT_ID59,
+	DEMUX_PIDFT_ID60,
+	DEMUX_PIDFT_ID61,
+	DEMUX_PIDFT_ID62,
+	DEMUX_PIDFT_ID63,
+	DEMUX_PIDFT_NUM
+} CSDEMUX_PIDFT_ID;
+
+typedef enum
+{
+	DEMUX_FILTER_UNDEF = -1,
+	DEMUX_FILTER_ID0 = 0,
+	DEMUX_FILTER_ID1,
+	DEMUX_FILTER_ID2,
+	DEMUX_FILTER_ID3,
+	DEMUX_FILTER_ID4,
+	DEMUX_FILTER_ID5,
+	DEMUX_FILTER_ID6,
+	DEMUX_FILTER_ID7,
+	DEMUX_FILTER_ID8,
+	DEMUX_FILTER_ID9,
+	DEMUX_FILTER_ID10,
+	DEMUX_FILTER_ID11,
+	DEMUX_FILTER_ID12,
+	DEMUX_FILTER_ID13,
+	DEMUX_FILTER_ID14,
+	DEMUX_FILTER_ID15,
+	DEMUX_FILTER_ID16,
+	DEMUX_FILTER_ID17,
+	DEMUX_FILTER_ID18,
+	DEMUX_FILTER_ID19,
+	DEMUX_FILTER_ID20,
+	DEMUX_FILTER_ID21,
+	DEMUX_FILTER_ID22,
+	DEMUX_FILTER_ID23,
+	DEMUX_FILTER_ID24,
+	DEMUX_FILTER_ID25,
+	DEMUX_FILTER_ID26,
+	DEMUX_FILTER_ID27,
+	DEMUX_FILTER_ID28,
+	DEMUX_FILTER_ID29,
+	DEMUX_FILTER_ID30,
+	DEMUX_FILTER_ID31,
+	DEMUX_FILTER_NUM
+} CSDEMUX_FILTER_ID;
+
+typedef enum
+{
+	DEMUX_FILTER_TYPE_UNDEF = -1,
+	DEMUX_FILTER_TYPE_SEC = 0,
+	DEMUX_FILTER_TYPE_TS,
+	DEMUX_FILTER_TYPE_PES,
+	DEMUX_FILTER_TYPE_ES
+} CSDEMUX_FILTER_TYPE;
+
+typedef enum
+{
+	DEMUX_INPUT_MOD_TUNER = 0,
+	DEMUX_INPUT_MOD_DMA,
+	DEMUX_INPUT_MOD_DIRECT
+} CSDEMUX_INPUT_MOD;
+
+typedef enum
+{
+	DEMUX_TUNER_MOD_PARALLEL = 0,
+	DEMUX_TUNER_MOD_SERIAL,
+} CSDEMUX_TUNER_MOD;
+
+/*XPORT API*/
+/* common interface*/
+CSDEMUX_RESULT CSDEMUX_Init(void);
+
+/* channel interface */
+CSDEMUX_HANDLE CSDEMUX_CHL_Open(CSDEMUX_CHL_ID chl_id);
+CSDEMUX_RESULT CSDEMUX_CHL_Close(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_CHL_SetInputMode(CSDEMUX_HANDLE handle, CSDEMUX_INPUT_MOD input_mod);
+CSDEMUX_RESULT CSDEMUX_CHL_Enable(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_CHL_Disable(CSDEMUX_HANDLE handle);
+
+/*pid filter interface*/
+CSDEMUX_HANDLE CSDEMUX_PIDFT_Open(CSDEMUX_PIDFT_ID pidfilter_id);
+CSDEMUX_RESULT CSDEMUX_PIDFT_Close(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_PIDFT_SetChannel(CSDEMUX_HANDLE handle, CSDEMUX_CHL_ID chl_id);
+CSDEMUX_RESULT CSDEMUX_PIDFT_SetPID(CSDEMUX_HANDLE handle, unsigned short pid);
+CSDEMUX_RESULT CSDEMUX_PIDFT_Enable(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_PIDFT_Disable(CSDEMUX_HANDLE handle);
+
+/* Filter interface */
+CSDEMUX_HANDLE CSDEMUX_Filter_Open(CSDEMUX_FILTER_ID filter_id);
+CSDEMUX_RESULT CSDEMUX_Filter_Close(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_Filter_SetFilterType(CSDEMUX_HANDLE handle, CSDEMUX_FILTER_TYPE type);
+CSDEMUX_RESULT CSDEMUX_Filter_SetFilter(CSDEMUX_HANDLE handle, const unsigned char *const filter_ptr, const unsigned char *const mask_ptr);
+CSDEMUX_RESULT CSDEMUX_Filter_AddPID(CSDEMUX_HANDLE handle, unsigned short pid);
+CSDEMUX_RESULT CSDEMUX_Filter_ResetPID(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_Filter_ReadWait(CSDEMUX_HANDLE handle, unsigned int ms_timeout);
+CSDEMUX_RESULT CSDEMUX_Filter_CheckDataSize(CSDEMUX_HANDLE handle, unsigned int *size);
+CSDEMUX_RESULT CSDEMUX_Filter_GetSectionCount(CSDEMUX_HANDLE handle, unsigned int *count);
+CSDEMUX_RESULT CSDEMUX_Filter_ReadSectionData(CSDEMUX_HANDLE handle, unsigned char *buf, unsigned int *size);
+CSDEMUX_RESULT CSDEMUX_Filter_Enable(CSDEMUX_HANDLE handle);
+CSDEMUX_RESULT CSDEMUX_Filter_Disable(CSDEMUX_HANDLE handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1800l_spi.h u-boot-2011.06/include/cnc1800l_spi.h
--- u-boot-2011.06_original/include/cnc1800l_spi.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1800l_spi.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,114 @@
+#ifndef __CNC1800L_SPI_H__
+#define __CNC1800L_SPI_H__
+#define SREG_BASE   	0x80150000
+
+#define rCTRLR0	    (SREG_BASE + 0x00)
+#define rCTRLR1	    (SREG_BASE + 0x04)
+#define rSSIENR	    (SREG_BASE + 0x08)
+#define rMWCR  	    (SREG_BASE + 0x0C)
+#define rSER   	    (SREG_BASE + 0x10)
+#define rBAUDR    	(SREG_BASE + 0x14)
+#define rTXFTLR 	(SREG_BASE + 0x18)
+#define rRXFTLR 	(SREG_BASE + 0x1C)
+#define rTXFLR  	(SREG_BASE + 0x20)
+#define rRXFLR  	(SREG_BASE + 0x24)
+#define rSR    		(SREG_BASE + 0x28)
+#define rIMR   		(SREG_BASE + 0x2C)
+#define rISR   		(SREG_BASE + 0x30)
+#define rRISR  		(SREG_BASE + 0x34)
+#define rTXOICR 	(SREG_BASE + 0x38)
+#define rRXOICR 	(SREG_BASE + 0x3C)
+#define rRXUICR		(SREG_BASE + 0x40)
+#define rMSTICR		(SREG_BASE + 0x44)
+#define rICR   		(SREG_BASE + 0x48)
+#define rDR    		(SREG_BASE + 0x60)
+
+#define SPI_PINMUX  (0xb211000c)
+
+#define BOOTCFG		0x80100034
+
+#define spi_write(a, v) 	(*((volatile unsigned short *)(a)) = (v))
+#define spi_read(a) 		(*((volatile unsigned short *)(a)))
+
+#define mdelay(s) 	({ int _tmp = 0; while (_tmp++ < (s)) udelay(1000); })
+#define mdelay_wheel(s)	({ int _tmp = 0; while (_tmp++ < (s)) { udelay(1000); if (!(_tmp % 100)) spin_wheel(); } })
+
+#define CMD_RDSR 	0x05
+#define CMD_WRSR 	0x01
+#define CMD_READ 	0x03
+#define CMD_WREN 	0x06
+#define CMD_PP 		0x02
+#define CMD_SE 		0x20
+#define CMD_BE 		0xd8
+#define CMD_CE 		0xc7
+#define CMD_RDID 	0x9f
+
+#define PP_SZ        256
+#define PP_TIME_US 	1500
+//#define FL_SEC_SZ 	0x1000
+//#define FL_BLK_SZ 	0x10000
+
+/****************************************************************************/
+
+//#define SPI_DEBUG
+#ifdef SPI_DEBUG
+#define SDEBUG(args...)                     \
+	do {                                    \
+		printf(args);                       \
+	} while(0)
+#else
+#define SDEBUG(args...) do { } while(0)
+#endif
+
+/****************************************************************************/
+
+typedef enum {
+	ERASE_SEC,
+	ERASE_BLK,
+	ERASE_CHIP
+} flasherase_t;
+
+typedef enum {
+	TMOD_TXRX = 0x0,
+	TMOD_TX   = 0x1,
+	TMOD_RX   = 0x2,
+	TMOD_EE   = 0x3 } TMOD_E;
+typedef enum {
+	TIMING0   = 0,
+	TIMING1   = 1,
+	TIMING2   = 2,
+	TIMING3   = 3   } TIMING_E;
+
+typedef enum {
+	BOOT_NOR  = 0,
+	BOOT_SPI  = 1,
+	BOOT_NAND = 2   } BOOT_TYPE_E;
+
+typedef struct sflash_info {
+	char	*name;
+	u32		jedec_id;
+	u16     ext_id;
+
+	unsigned sector_size;
+	u16		n_sectors;
+
+	u16		flags;
+#define	SECT_4K		0x01
+} sfinf_t;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x)		(sizeof(x) / sizeof((x)[0]))
+#endif
+
+/**********************************************************************************/
+
+void spi__init(void);
+
+int seeprom_read(unsigned caddr, uchar *maddr, unsigned size);
+int seeprom_write(unsigned caddr, uchar *maddr, unsigned size);
+int seeprom_erase(unsigned cmd, unsigned saddr, unsigned size);
+int seeprom_probe(void);
+
+/**********************************************************************************/
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1800l_tuner.h u-boot-2011.06/include/cnc1800l_tuner.h
--- u-boot-2011.06_original/include/cnc1800l_tuner.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1800l_tuner.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,78 @@
+
+#ifndef	_CNC1800L_TUNER_H_
+#define	_CNC1800L_TUNER_H_
+
+#include <common.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum { 
+	TUNER_DVBS,
+	TUNER_DVBC
+} TUNER_DEV_TYPE;
+
+typedef enum {
+        TUNER_FEC_NONE = 0,
+        TUNER_FEC_1_2,
+        TUNER_FEC_2_3,
+        TUNER_FEC_3_4,
+        TUNER_FEC_4_5,
+        TUNER_FEC_5_6,
+        TUNER_FEC_6_7,
+        TUNER_FEC_7_8,
+        TUNER_FEC_8_9,
+        TUNER_FEC_AUTO
+} CSTUNER_FEC_RATES;
+
+typedef enum {
+	TUNER_STATUS_UNLOCKED = 0,
+	TUNER_STATUS_FE_LOCKED,
+	TUNER_STATUS_PLL_LOCKED,
+	TUNER_STATUS_SCANNING,
+	TUNER_STATUS_NOT_FOUND
+} TUNER_STATUS_E;
+
+typedef enum {
+	INVERSION_NORMAL = 0,
+	INVERSION_INVERTED,
+	INVERSION_AUTO
+} TUNER_SPECTRAL_INVERSION_E;
+
+typedef enum {
+	QAM_4 = 0,
+	QAM_16,
+	QAM_32,
+	QAM_64,
+	QAM_128,
+	QAM_256,
+	QAM_AUTO
+} TUNER_QAM_MODULATION_E;
+
+typedef struct {
+	unsigned int frequency;		/* MHz */
+	unsigned int symbol_rate;	/* MS/s */
+
+	/* dvbc */
+	TUNER_QAM_MODULATION_E modulation;
+	TUNER_SPECTRAL_INVERSION_E inversion;
+
+	/* dvbs */
+	CSTUNER_FEC_RATES FECRates;
+	unsigned int  LnbFrequency;     /* MHz */
+	unsigned int  Polarization;     /* 'V' FALSE 'H' TRUE */
+
+} TUNER_PARAMS_S;
+
+int	CSTUNER_Init(void);
+int	CSTUNER_Open(TUNER_DEV_TYPE type);
+int	CSTUNER_Close(void);
+int	CSTUNER_SetFrequency(TUNER_PARAMS_S *params);
+int	CSTUNER_GetTunerInfo(TUNER_PARAMS_S *params);
+int	CSTUNER_ReadStatus(TUNER_STATUS_E *status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*	_CS_TUNER_LG_H_	*/
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1900_audio_reg.h u-boot-2011.06/include/cnc1900_audio_reg.h
--- u-boot-2011.06_original/include/cnc1900_audio_reg.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1900_audio_reg.h	2015-08-20 19:25:54.678159000 +0800
@@ -0,0 +1,148 @@
+#ifndef __CSM1800_AUDIO_REGISTERS_H__
+#define __CSM1800_AUDIO_REGISTERS_H__
+
+#define CSM1300_REG_BASE_ADDR 0xb1200000
+
+/* ----------------- Common Register ------------------ */
+#define CSM1300_AUD_STC             (CSM1300_REG_BASE_ADDR + 0x0000)
+#define CSM1300_AUD_HISTC           (CSM1300_REG_BASE_ADDR + 0x0004)
+#define CSM1300_AUD_MAILBOX0        (CSM1300_REG_BASE_ADDR + 0x0100)
+#define CSM1300_AUD_MAILBOX1        (CSM1300_REG_BASE_ADDR + 0x0104)
+#define CSM1300_AUD_MAILBOX2        (CSM1300_REG_BASE_ADDR + 0x0108)
+#define CSM1300_AUD_MAILBOX3        (CSM1300_REG_BASE_ADDR + 0x010c)
+#define CSM1300_AUD_MAILBOX4        (CSM1300_REG_BASE_ADDR + 0x0110)
+#define CSM1300_AUD_MAILBOX5        (CSM1300_REG_BASE_ADDR + 0x0114)
+#define CSM1300_AUD2VID_MAILBOX0    (CSM1300_REG_BASE_ADDR + 0x0118)
+#define CSM1300_AUD2VID_MAILBOX1    (CSM1300_REG_BASE_ADDR + 0x0120)
+#if 1
+#define CSM1300_VID2AUD_MAILBOX0    (CSM1300_REG_BASE_ADDR + 0x011c)
+#define CSM1300_VID2AUD_MAILBOX1    (CSM1300_REG_BASE_ADDR + 0x0124)
+#endif
+#define CSM1300_AUD_INT             (CSM1300_REG_BASE_ADDR + 0x0200)
+#define CSM1300_DSP_INT_SRC         (CSM1300_REG_BASE_ADDR + 0x0204)
+#define CSM1300_DSP_INT_MASK        (CSM1300_REG_BASE_ADDR + 0x0208)
+#define CSM1300_DSP_INT_INPUT_BIT   0x01
+#define CSM1300_DSP_INT_SFT_BIT     0x02
+#define CSM1300_DSP_INT_UART_BIT    0x04
+#define CSM1300_DSP_INT_TIMER0_BIT  0x08
+#define CSM1300_DSP_INT_TIMER1_BIT  0x10
+#define CSM1300_AUD_DDR_IO          (CSM1300_REG_BASE_ADDR + 0x0504)
+
+/* ------------------ I2s input ---------------------- */
+#define CSM1300_AUDIO_INPUT_LEVEL   (CSM1300_REG_BASE_ADDR + 0x0300)
+#define CSM1300_AUDIO_INPUT_CTRL    (CSM1300_REG_BASE_ADDR + 0x0304)
+#define CSM1300_AUDIO_INPUT_CTRL_ENABLE_BIT     0x1
+#define CSM1300_AUDIO_INPUT_CTRL_INVERT_WS_BIT  0x10
+#define CSM1300_AUDIO_INPUT_CTRL_INVERT_SCK_BIT 0x100
+#define CSM1300_AUDIO_INPUT_CTRL_SHIFT_CNT_BIT  0x1f0000
+
+#define CSM1300_AUDIO_INPUT_CNT     (CSM1300_REG_BASE_ADDR + 0x0308)
+#define CSM1300_AUDIO_INPUT_SAMPLE  (CSM1300_REG_BASE_ADDR + 0x030c)
+#define CSM1300_AUDIO_INPUT_RATE    (CSM1300_REG_BASE_ADDR + 0x0310)
+#if !ENA_DMA_IFIFO
+#define CSM1300_AUD_PTS0RP          (CSM1300_REG_BASE_ADDR + 0x0400)
+#define CSM1300_AUD_PTS0WP          (CSM1300_REG_BASE_ADDR + 0x0404)
+#define CSM1300_AUD_PTS0UP          (CSM1300_REG_BASE_ADDR + 0x0408)
+#define CSM1300_AUD_PTS0LOW         (CSM1300_REG_BASE_ADDR + 0x040c)
+#define CSM1300_AUD_PTS1RP          (CSM1300_REG_BASE_ADDR + 0x0410)
+#define CSM1300_AUD_PTS1WP          (CSM1300_REG_BASE_ADDR + 0x0414)
+#define CSM1300_AUD_PTS1UP          (CSM1300_REG_BASE_ADDR + 0x0418)
+#define CSM1300_AUD_PTS1LOW         (CSM1300_REG_BASE_ADDR + 0x041c)
+#endif
+#define CSM1300_AUD_PTS_BITWIDTH    (0x7FFFFFF8)
+#define CSM1300_AUD_PTS_TOGGLEBIT   (0x80000000)
+
+
+
+/* ------------------ INPUT FIFO --------------------- */
+#if !ENA_DMA_IFIFO
+#define CSM1300_AUD_CAB0RP          (CSM1300_REG_BASE_ADDR + 0x4100)
+#define CSM1300_AUD_CAB0WP          (CSM1300_REG_BASE_ADDR + 0x4104)
+#define CSM1300_AUD_CAB0UP          (CSM1300_REG_BASE_ADDR + 0x4108)
+#define CSM1300_AUD_CAB0LOW         (CSM1300_REG_BASE_ADDR + 0x410c)
+#define CSM1300_AUD_IFIFO0          (CSM1300_REG_BASE_ADDR + 0x4110)
+#define CSM1300_AUD_CAB1RP          (CSM1300_REG_BASE_ADDR + 0x4200)
+#define CSM1300_AUD_CAB1WP          (CSM1300_REG_BASE_ADDR + 0x4204)
+#define CSM1300_AUD_CAB1UP          (CSM1300_REG_BASE_ADDR + 0x4208)
+#define CSM1300_AUD_CAB1LOW         (CSM1300_REG_BASE_ADDR + 0x420c)
+#define CSM1300_AUD_CAB_BITWIDTH    (0x0FFFFFF8)
+#define CSM1300_AUD_CAB_TOGGLEBIT   (0x10000000)
+
+#define CSM1300_AUD_IFIFO1          (CSM1300_REG_BASE_ADDR + 0x4210)
+#define CSM1300_AUD_IFIFO_CTRL      (CSM1300_REG_BASE_ADDR + 0x4000)
+#define CSM1300_AUD_IFIFO_CTRL_ENABLE0 0x1
+#define CSM1300_AUD_IFIFO_CTRL_ENABLE1 0x2
+#define CSM1300_AUD_IFIFO_CTRL_CLEAR0  0x4 // disable first, then clear
+#define CSM1300_AUD_IFIFO_CTRL_CLEAR1  0x8
+#define CSM1300_AUD_IFIFOCNT        (CSM1300_REG_BASE_ADDR + 0x4004)
+                                    // high 16 bits for fifo1,
+                                    // low 16 bits for fifo0.
+#else
+
+
+//#define CSM1300_AUDIN_RPWP_INDEX     (CSM1300_REG_BASE_ADDR + 0x4104) // CSM1300_AUD_CAB0WP          //(CSM1300_REG_BASE_ADDR + 0x410c) // CSM1300_AUD_CAB0LOW
+//#define CSM1300_AUDIN_LOWUP_INDEX    (CSM1300_REG_BASE_ADDR + 0x4108) // CSM1300_AUD_CAB0UP
+#define CSM1300_AUDIN_CAB_BITWIDTH    (0x7FFFFFFC)
+#define CSM1300_AUDIN_CAB_TOGGLEBIT   (0x80000000)
+#ifdef SUPPORT_VOIP
+#define CSM1300_AUDOUT_CAB_BITWIDTH   (0x7FFFFFFF)
+#define CSM1300_AUDOUT_CAB_TOGGLEBIT  (0x80000000)
+#endif
+#define CSM1300_FW_VERSION_REG		 (CSM1300_REG_BASE_ADDR + 0x410c) // CSM1300_AUD_CAB0LOW         
+#endif
+
+/* ------------------ AUDIO I2S ----------------------- */
+#define CSM1300_AUD_I2S_SHIFTCNT    (CSM1300_REG_BASE_ADDR + 0x1000)
+#define CSM1300_AUD_I2S_CNTL        (CSM1300_REG_BASE_ADDR + 0x1004)
+#define CSM1300_AUD_I2S_RP0         (CSM1300_REG_BASE_ADDR + 0x1100)
+#define CSM1300_AUD_I2S_WP0         (CSM1300_REG_BASE_ADDR + 0x1104)
+#define CSM1300_AUD_I2S_UP0         (CSM1300_REG_BASE_ADDR + 0x1108)
+#define CSM1300_AUD_I2S_LOW0        (CSM1300_REG_BASE_ADDR + 0x110c)
+#define CSM1300_AUD_I2S_SCAL0       (CSM1300_REG_BASE_ADDR + 0x1110)
+#define CSM1300_AUD_I2S_RP1         (CSM1300_REG_BASE_ADDR + 0x1114)
+#define CSM1300_AUD_I2S_WP1         (CSM1300_REG_BASE_ADDR + 0x1118)
+#define CSM1300_AUD_I2S_UP1         (CSM1300_REG_BASE_ADDR + 0x111c)
+#define CSM1300_AUD_I2S_LOW1        (CSM1300_REG_BASE_ADDR + 0x1120)
+#define CSM1300_AUD_I2S_SCAL1       (CSM1300_REG_BASE_ADDR + 0x1124)
+#define CSM1300_AUD_I2S_BITWIDTH    0x7FFFFFF8
+#define CSM1300_AUD_I2S_TOGGLEBIT   0x80000000
+
+// CSM1300_AUD_I2Sx_yyy = CSM1300_AUD_I2S_yyy + 0x100*x. x = [0, 1, 2, 3]
+
+/* ------------------ AUDIO I2S ----------------------- */
+#define CSM1300_AUD_SPDIF_CNTL      (CSM1300_REG_BASE_ADDR + 0x2000)
+#define CSM1300_AUD_SPDIF_RP0       (CSM1300_REG_BASE_ADDR + 0x2100)
+#define CSM1300_AUD_SPDIF_WP0       (CSM1300_REG_BASE_ADDR + 0x2104)
+#define CSM1300_AUD_SPDIF_UP0       (CSM1300_REG_BASE_ADDR + 0x2108)
+#define CSM1300_AUD_SPDIF_LOW0      (CSM1300_REG_BASE_ADDR + 0x210c)
+#define CSM1300_AUD_SPDIF_SCAL0     (CSM1300_REG_BASE_ADDR + 0x2110)
+#define CSM1300_AUD_SPDIF_RP1       (CSM1300_REG_BASE_ADDR + 0x2114)
+#define CSM1300_AUD_SPDIF_WP1       (CSM1300_REG_BASE_ADDR + 0x2118)
+#define CSM1300_AUD_SPDIF_UP1       (CSM1300_REG_BASE_ADDR + 0x211c)
+#define CSM1300_AUD_SPDIF_LOW1      (CSM1300_REG_BASE_ADDR + 0x2120)
+#define CSM1300_AUD_SPDIF_SCAL1     (CSM1300_REG_BASE_ADDR + 0x2124)
+#define CSM1300_AUD_SPDIF_VERSION   (CSM1300_REG_BASE_ADDR + 0x2200)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS1  (CSM1300_REG_BASE_ADDR + 0x2204)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS12 (CSM1300_REG_BASE_ADDR + 0x2208)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS2  (CSM1300_REG_BASE_ADDR + 0x220c)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS3  (CSM1300_REG_BASE_ADDR + 0x2210)  // Audio bit rate
+#define CSM1300_AUD_SPDIF_VALID           (CSM1300_REG_BASE_ADDR + 0x2238)
+#define CSM1300_AUD_SPDIF_FIFO_STATUS     (CSM1300_REG_BASE_ADDR + 0x223c)
+#define CSM1300_AUD_SPDIF_BITWIDTH    0x7FFFFFF8
+#define CSM1300_AUD_SPDIF_TOGGLEBIT   0x80000000
+
+
+/* not used spdif regs */
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS4 (CSM1300_REG_BASE_ADDR + 0x2214)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS5 (CSM1300_REG_BASE_ADDR + 0x2218)
+#define CSM1300_AUD_SPDIF_CHANNELSTATUS6 (CSM1300_REG_BASE_ADDR + 0x221C)
+#define CSM1300_AUD_SPDIF_USERDATA1      (CSM1300_REG_BASE_ADDR + 0x2220)
+#define CSM1300_AUD_SPDIF_USERDATA2      (CSM1300_REG_BASE_ADDR + 0x2224)
+#define CSM1300_AUD_SPDIF_USERDATA3      (CSM1300_REG_BASE_ADDR + 0x2228)
+#define CSM1300_AUD_SPDIF_USERDATA4      (CSM1300_REG_BASE_ADDR + 0x222C)
+#define CSM1300_AUD_SPDIF_USERDATA5      (CSM1300_REG_BASE_ADDR + 0x2230)
+#define CSM1300_AUD_SPDIF_USERDATA6      (CSM1300_REG_BASE_ADDR + 0x2234)
+
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1900_clock_reg.h u-boot-2011.06/include/cnc1900_clock_reg.h
--- u-boot-2011.06_original/include/cnc1900_clock_reg.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1900_clock_reg.h	2015-08-20 19:25:54.678159000 +0800
@@ -0,0 +1,79 @@
+#ifndef _CNC1900_CLOCK_REG_H_
+#define _CNC1900_CLOCK_REG_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+typedef enum _CLOCK_REG_BANK_
+{
+  CNC1900_ID_SCS                    =0xB2100000,
+
+  CLOCK_ID_BASE                     =(CNC1900_ID_SCS+(0<<2)),
+  CLOCK_PLL_BASE                    =(CNC1900_ID_SCS+(0x40<<2)),
+  CLOCK_MUX_BASE                    =(CNC1900_ID_SCS+(0x50<<2)),
+  CLOCK_RESET_BASE                  =(CNC1900_ID_SCS+(0x80<<2)),
+  PLL_PARA_BASE                     =(CNC1900_ID_SCS+(0xC0<<2)),
+  VDAC_BASE                         =(CNC1900_ID_SCS+(0xD4<<2)),
+  CPU_PWR_BASE                      =(CNC1900_ID_SCS+(0xD8<<2)),
+
+  CLOCK_ID_LO                       =(CLOCK_ID_BASE+(0<<2)),
+  CLOCK_ID_HI                       =(CLOCK_ID_BASE+(1<<2)),
+
+  //B2100100
+  CLOCK_PLL_AVS_DIV                 =(CLOCK_PLL_BASE+(1<<2)),       
+  CLOCK_AUD_DIV                     =(CLOCK_PLL_BASE+(6<<2)),
+  CLOCK_CLK_GEN_DIV                 =(CLOCK_PLL_BASE+(8<<2)),
+
+  //B2100140
+  CLOCK_PLL_CLK_EN                  =(CLOCK_MUX_BASE+(0<<2)),
+  CLK_SRC_SEL                       =(CLOCK_MUX_BASE+(1<<2)),
+  CLOCK_TVE_DIV_N		            =(CLOCK_MUX_BASE+(2<<2)),
+
+  //B2100200
+  CLOCK_SOFT_RESET                  =(CLOCK_RESET_BASE+(0<<2)),
+  CLOCK_CLK_RESET                   =(CLOCK_RESET_BASE+(1<<2)),
+  CLOCK_PLL_SLEEP_N                 =(CLOCK_RESET_BASE+(3<<2)),
+  CLOCK_HDMI_CLK_SEL                =(CLOCK_RESET_BASE+(6<<2)),
+  SB_CTRL                           =(CLOCK_RESET_BASE+(7<<2)),
+  SB_STATUS                         =(CLOCK_RESET_BASE+(8<<2)),
+
+  //B2100300
+  CPUCLK_ST_INT                     =(PLL_PARA_BASE+ (5<<2)),
+  PLL_CPU_DIV                       =(PLL_PARA_BASE+ (6<<2)),
+  PLL_TVE_PARA_Q                    =(PLL_PARA_BASE+ (7<<2)),
+  PLL_TVE_PARA_F                    =(PLL_PARA_BASE+ (8<<2)),
+  PLL_AUD_PARA_Q                    =(PLL_PARA_BASE+ (9<<2)),
+  PLL_AUD_PARA_F                    =(PLL_PARA_BASE+ (0x0A<<2)),
+  PLL_SYS_PARA_Q                    =(PLL_PARA_BASE+ (0x0B<<2)),
+  PLL_SYS_PARA_F                    =(PLL_PARA_BASE+ (0x0C<<2)),
+  PLL_DDR_PARA_Q                    =(PLL_PARA_BASE+ (0x0D<<2)),
+  PLL_DDR_PARA_F                    =(PLL_PARA_BASE+ (0x0E<<2)),
+  PLL_NEWDIV                        =(PLL_PARA_BASE+ (0x0F<<2)),
+  PLL_CODA_PARA_Q                   =(PLL_PARA_BASE+ (0x11<<2)),
+  PLL_CODA_PARA_F                   =(PLL_PARA_BASE+ (0x12<<2)),
+  CPU_PWR_MODE                   	=(PLL_PARA_BASE+ (0x20<<2)),
+  PLL_CLK_EN                   		=(PLL_PARA_BASE+ (0x50<<2)),
+
+  //B2100350
+  VDAC0_CTRL                        =(VDAC_BASE    + (0<<2)),
+  VDAC1_CTRL                        =(VDAC_BASE    + (1<<2)),
+  VDAC_CABLE_DET                    =(VDAC_BASE    + (2<<2)),
+
+  //B2100360
+  CPU_POWER_STATUS                  =(CPU_PWR_BASE + (0<<2)),
+  CPU_POWER_CTRL                    =(CPU_PWR_BASE + (1<<2)),
+  CPU_RST_CTRL                      =(CPU_PWR_BASE + (2<<2)),
+  CPU_SCU_EV_ABORT                  =(CPU_PWR_BASE + (3<<2)),
+  CPU_SCU_CHRC_CNT                  =(CPU_PWR_BASE + (4<<2)),
+  CPU_POWER_MODE                    =(CPU_PWR_BASE + (8<<2)),
+  USB_CTRL                          =(CPU_PWR_BASE + (0x0C<<2)),
+  STC_CTRL                          =(CPU_PWR_BASE + (0x10<<2)),
+
+  CLOCK_REG_SIZE = 0x1000,
+}CLOCK_REG_BANK;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc1900_spi.h u-boot-2011.06/include/cnc1900_spi.h
--- u-boot-2011.06_original/include/cnc1900_spi.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc1900_spi.h	2015-05-29 15:18:31.577595000 +0800
@@ -0,0 +1,112 @@
+#ifndef __CNC1900_SPI_H__
+#define __CNC1900_SPI_H__
+#define SREG_BASE   	0x80150000
+
+#define rCTRLR0	    (SREG_BASE + 0x00)
+#define rCTRLR1	    (SREG_BASE + 0x04)
+#define rSSIENR	    (SREG_BASE + 0x08)
+#define rMWCR  	    (SREG_BASE + 0x0C)
+#define rSER   	    (SREG_BASE + 0x10)
+#define rBAUDR    	(SREG_BASE + 0x14)
+#define rTXFTLR 	(SREG_BASE + 0x18)
+#define rRXFTLR 	(SREG_BASE + 0x1C)
+#define rTXFLR  	(SREG_BASE + 0x20)
+#define rRXFLR  	(SREG_BASE + 0x24)
+#define rSR    		(SREG_BASE + 0x28)
+#define rIMR   		(SREG_BASE + 0x2C)
+#define rISR   		(SREG_BASE + 0x30)
+#define rRISR  		(SREG_BASE + 0x34)
+#define rTXOICR 	(SREG_BASE + 0x38)
+#define rRXOICR 	(SREG_BASE + 0x3C)
+#define rRXUICR		(SREG_BASE + 0x40)
+#define rMSTICR		(SREG_BASE + 0x44)
+#define rICR   		(SREG_BASE + 0x48)
+#define rDR    		(SREG_BASE + 0x60)
+
+#define SPI_PINMUX  (0xb211000c)
+
+#define BOOTCFG		0x80100034
+
+#define spi_write(a, v) 	(*((volatile unsigned short *)(a)) = (v))
+#define spi_read(a) 		(*((volatile unsigned short *)(a)))
+
+#define CMD_RDSR 	0x05
+#define CMD_WRSR 	0x01
+#define CMD_READ 	0x03
+#define CMD_WREN 	0x06
+#define CMD_PP 		0x02
+#define CMD_SE 		0x20
+#define CMD_BE 		0xd8
+#define CMD_CE 		0xc7
+#define CMD_RDID 	0x9f
+
+#define PP_SZ        256
+#define PP_TIME_US 	1500
+//#define FL_SEC_SZ 	0x1000
+//#define FL_BLK_SZ 	0x10000
+
+/****************************************************************************/
+
+#define SPI_DEBUG
+#ifdef SPI_DEBUG
+#define SDEBUG(args...)                     \
+	do {                                    \
+		printf(args);                       \
+	} while(0)
+#else
+#define SDEBUG(args...) do { } while(0)
+#endif
+
+/****************************************************************************/
+
+typedef enum {
+	ERASE_SEC,
+	ERASE_BLK,
+	ERASE_CHIP
+} flasherase_t;
+
+typedef enum {
+	TMOD_TXRX = 0x0,
+	TMOD_TX   = 0x1,
+	TMOD_RX   = 0x2,
+	TMOD_EE   = 0x3 } TMOD_E;
+typedef enum {
+	TIMING0   = 0,
+	TIMING1   = 1,
+	TIMING2   = 2,
+	TIMING3   = 3   } TIMING_E;
+
+typedef enum {
+	BOOT_NOR  = 0,
+	BOOT_SPI  = 1,
+	BOOT_NAND = 2   } BOOT_TYPE_E;
+
+typedef struct sflash_info {
+	char	*name;
+	u32		jedec_id;
+	u16     ext_id;
+
+	unsigned sector_size;
+	u16		n_sectors;
+
+	u16		flags;
+#define	SECT_4K		0x01
+} sfinf_t;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x)		(sizeof(x) / sizeof((x)[0]))
+#endif
+
+/**********************************************************************************/
+
+void spi__init(void);
+
+int seeprom_read(unsigned caddr, uchar *maddr, unsigned size);
+int seeprom_write(unsigned caddr, uchar *maddr, unsigned size);
+int seeprom_erase(unsigned cmd, unsigned saddr, unsigned size);
+int seeprom_probe(void);
+
+/**********************************************************************************/
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/cnc_util.h u-boot-2011.06/include/cnc_util.h
--- u-boot-2011.06_original/include/cnc_util.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/cnc_util.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,129 @@
+#ifndef __CNC_UTIL_H__
+#define __CNC_UTIL_H__
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#include <usb.h>
+#include <jffs2/jffs2.h>
+#include <nand.h>
+#include <rsa_verify.h>
+#include <spi_flash.h>
+
+#define xColorBlack            "\e[1;30m"
+#define xColorRed              "\e[1;31m"
+#define xColorGreen            "\e[1;32m"
+#define xColorYellow           "\e[1;33m"
+#define xColorBlue             "\e[1;34m"
+#define xColorMagenta          "\e[1;35m"
+#define xColorCyan             "\e[1;36m"
+#define xColorWhite            "\e[1;37m"
+
+#define xColorLightBlack       "\e[0;30m"
+#define xColorLightRed         "\e[0;31m"
+#define xColorLightGreen       "\e[0;32m"
+#define xColorLightYellow      "\e[0;33m"
+#define xColorLightBlue        "\e[0;34m"
+#define xColorLightMagenta     "\e[0;35m"
+#define xColorLightCyan        "\e[0;36m"
+#define xColorLightWhite       "\e[0;37m"
+
+#define xColorNormal		   "\e[m"
+#define xBlinkOn               "\e[1;5m"
+
+typedef enum cnc_ImageType
+{
+	KERNEL=0, //preserve mkimg header.
+	RAMDISK=1, //preserve mkimg header
+	JFFS2=2,  //remove mkimg header
+	RAW=3,    //no-header (don't try to do parsing of mkimage header)
+}cnc_ImageType;
+
+#define MAXIUM_NO_OF_IMAGE     16
+#define PARTITION_NAME_LENGTH  64
+typedef struct ImagePartition_t
+{
+	char   mMtdId[16];
+	char   mPartionName[PARTITION_NAME_LENGTH];
+	UInt32 mFlashAddress;
+	UInt32 mDdrAddress;
+	UInt32 mLength;
+}ImagePartition_t;
+
+typedef struct ImagePartitionList_t
+{
+	int mNoOfPartition;
+	ImagePartition_t mImagePartitionList[MAXIUM_NO_OF_IMAGE];
+}ImagePartitionList_t;
+
+/*Public key for Secure Kernel::the declaration/definition of pkey must be adjacent to blob_pkey,
+* or else the function public_key_does_not_match_mine() will not work */
+extern unsigned char pkey[];
+
+/*Public key for Secure Blob::the declaration/definition of blob_pkey must be adjacent to pkey,
+ * or else the function public_key_does_not_match_mine() will not work */
+extern unsigned char blob_pkey[];
+extern char ColorBlack[];
+extern char ColorRed[];
+extern char ColorGreen[];
+extern char ColorYellow[];
+extern char ColorBlue[];
+extern char ColorMagenta[];
+extern char ColorCyan[];
+extern char ColorWhite[];
+extern char ColorLightBlack[];
+extern char ColorLightRed[];
+extern char ColorLightGreen[];
+extern char ColorLightYellow[];
+extern char ColorLightBlue[];
+extern char ColorLightMagenta[];
+extern char ColorLightCyan[];
+extern char ColorLightWhite[];
+extern char ColorNormal[];
+extern char BlinkOn[];
+
+void Cnc_DumpMemory(UInt32 aStartAddress, UInt32 aCount);
+
+int cnc_NorErase(UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_NorVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_NorRead(UInt32 aFlashSourceAddress, UInt32 aDdrDestinationAddress,  UInt32 aLength);
+int cnc_NorWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength);
+
+int cnc_NandErase(UInt32 aFlashStartAddress, UInt32 aLength , UInt32 aEraseSpread);
+int cnc_NandVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_NandRead(uint32_t aSrcAddressInFlash,  uint32_t aDstAddressInDram,  uint32_t alen);
+int cnc_NandWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength, cnc_ImageType aImageType );
+
+//int cnc_EMMCErase(UInt32 aFlashStartAddress, UInt32 aLength , UInt32 aEraseSpread);
+int cnc_EMMCVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_EMMCVerify2(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_EMMCRead(uint32_t aSrcAddressInFlash,  uint32_t aDstAddressInDram,  uint32_t alen);
+int cnc_EMMCWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength, cnc_ImageType aImageType );
+int cnc_EMMCWrite2(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength, cnc_ImageType aImageType );
+int cnc_CreatGPTPartitionTable(ImagePartitionList_t *pt_list);
+int cnc_EMMCRescan(void);
+
+int cnc_SpiErase(UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_SpiVerify(UInt32 aDdrStartAddress, UInt32 aFlashStartAddress, UInt32 aLength);
+int cnc_SpiRead(UInt32 aFlashSourceAddress, UInt32 aDdrDestinationAddress,  UInt32 aLength);
+int cnc_SpiWrite(UInt32 aDdrSourceAddress, UInt32 aFlashDestinationAddress, UInt32 aLength);
+
+int cnc_UsbStart(void);
+int cnc_UsbStop(void);
+int cnc_LoadFileFromUsb(const char* pFileName, UInt32 aAddress, UInt32 * apFileSize);
+int Cnc_InPlaceDecryptOnlyImage(UInt32 aSrcDstAddress, UInt32 aLength);
+int Cnc_InPlaceDecryptOnlyImage_AES(UInt8 *KeyLadder, UInt32 aSrcDstAddress, UInt32 aLength);
+int Cnc_DecryptImage(UInt32 aSourceAddress, UInt32 aDestinationAddress, UInt32 aLength);
+int Cnc_DecryptImageGetHash(UInt32 aSourceAddress, UInt32 aDestinationAddress, UInt32 aLength, UInt8* apHashBuf, int aHasBufLength);
+int Cnc_ImgHybRsa_Verify (UInt8 hash[32], UInt32 asignAddress, UInt8 *publicKey);
+unsigned int SecHWGetRSAEnable(void);
+int cnc_Read_MtdPartition(const char *apMtdID, const char* apMtdPartitionName, UInt32 aDestinationAddress, UInt32 aLength /* 0xFFFFFFFF - to read comple region */);
+int ProgramAndVerify2Spi(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength );
+int ProgramAndVerify2Nand(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength);
+int ProgramAndVerify2EMMC(UInt32 aDdrAddress, UInt32 aFlashAddress, UInt32 aLength);
+int ImgRsa_Verify (uint32_t aImgAddress, uint32_t aLen, uint32_t asignAddress, cnc_ImageType imageType);
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/command.h u-boot-2011.06/include/command.h
--- u-boot-2011.06_original/include/command.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/command.h	2014-07-29 17:28:38.819972000 +0800
@@ -101,6 +101,12 @@
 extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 
+enum command_ret_t {
+	CMD_RET_SUCCESS,	/* 0 = Success */
+	CMD_RET_FAILURE,	/* 1 = Failure */
+	CMD_RET_USAGE = -1,	/* Failure, please report 'usage' error */
+};
+
 #endif	/* __ASSEMBLY__ */
 
 /*
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/common.h u-boot-2011.06/include/common.h
--- u-boot-2011.06_original/include/common.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/common.h	2015-05-29 14:14:51.790650000 +0800
@@ -34,6 +34,23 @@
 typedef volatile unsigned short vu_short;
 typedef volatile unsigned char	vu_char;
 
+typedef int          Int32;
+typedef unsigned int UInt32;
+
+typedef short          Int16;
+typedef unsigned short UInt16;
+
+typedef char          Int8;
+typedef unsigned char UInt8;
+typedef unsigned char byte;
+
+#ifndef	BOOL_WAS_DEFINED
+#define BOOL_WAS_DEFINED
+typedef unsigned int bool;
+#endif
+
+
+
 #include <config.h>
 #include <asm-offsets.h>
 #include <linux/bitops.h>
@@ -112,6 +129,13 @@
 #include <asm/arch/hardware.h>
 #endif
 
+#ifdef CONFIG_SPI_FLASH_CNC1800L
+#include <cnc1800l_spi.h>
+#endif
+#ifdef CONFIG_SPI_FLASH_CNC1900
+#include <cnc1900_spi.h>
+#endif
+
 #include <part.h>
 #include <flash.h>
 #include <image.h>
@@ -192,6 +216,48 @@
 #define MIN(x, y)  min(x, y)
 #define MAX(x, y)  max(x, y)
 
+#define min3(X, Y, Z)				\
+	({ typeof(X) __x = (X);			\
+		typeof(Y) __y = (Y);		\
+		typeof(Z) __z = (Z);		\
+		__x < __y ? (__x < __z ? __x : __z) :	\
+		(__y < __z ? __y : __z); })
+
+#define max3(X, Y, Z)				\
+	({ typeof(X) __x = (X);			\
+		typeof(Y) __y = (Y);		\
+		typeof(Z) __z = (Z);		\
+		__x > __y ? (__x > __z ? __x : __z) :	\
+		(__y > __z ? __y : __z); })
+
+#define MIN3(x, y, z)  min3(x, y, z)
+#define MAX3(x, y, z)  max3(x, y, z)
+
+/*
+ * Return the absolute value of a number.
+ *
+ * This handles unsigned and signed longs, ints, shorts and chars.  For all
+ * input types abs() returns a signed long.
+ *
+ * For 64-bit types, use abs64()
+ */
+#define abs(x) ({						\
+		long ret;					\
+		if (sizeof(x) == sizeof(long)) {		\
+			long __x = (x);				\
+			ret = (__x < 0) ? -__x : __x;		\
+		} else {					\
+			int __x = (x);				\
+			ret = (__x < 0) ? -__x : __x;		\
+		}						\
+		ret;						\
+	})
+
+#define abs64(x) ({				\
+		s64 __x = (x);			\
+		(__x < 0) ? -__x : __x;		\
+	})
+
 #if defined(CONFIG_ENV_IS_EMBEDDED)
 #define TOTAL_MALLOC_LEN	CONFIG_SYS_MALLOC_LEN
 #elif ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \
@@ -610,9 +676,14 @@
 ulong	video_setmem (ulong);
 
 /* arch/$(ARCH)/lib/cache.c */
+void	enable_caches(void);
 void	flush_cache   (unsigned long, unsigned long);
+void	flush_dcache_all(void);
 void	flush_dcache_range(unsigned long start, unsigned long stop);
 void	invalidate_dcache_range(unsigned long start, unsigned long stop);
+void	invalidate_dcache_all(void);
+void	invalidate_icache_all(void);
+
 
 
 /* arch/$(ARCH)/lib/ticks.S */
@@ -644,6 +715,7 @@
 
 /* lib/time.c */
 void	udelay        (unsigned long);
+void mdelay(unsigned long);
 
 /* lib/vsprintf.c */
 ulong	simple_strtoul(const char *cp,char **endp,unsigned int base);
@@ -751,7 +823,7 @@
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
-#define ROUND(a,b)		(((a) + (b)) & ~((b) - 1))
+#define ROUND(a,b)		(((a) + (b) - 1) & ~((b) - 1))
 #define DIV_ROUND(n,d)		(((n) + ((d)/2)) / (d))
 #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
 #define roundup(x, y)		((((x) + ((y) - 1)) / (y)) * (y))
@@ -759,4 +831,91 @@
 #define ALIGN(x,a)		__ALIGN_MASK((x),(typeof(x))(a)-1)
 #define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
 
+/*
+ * ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture.  It
+ * is used to align DMA buffers.
+ */
+#ifndef __ASSEMBLY__
+#include <asm/cache.h>
+#endif
+
+/*
+ * The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
+ * stack that meets the minimum architecture alignment requirements for DMA.
+ * Such a buffer is useful for DMA operations where flushing and invalidating
+ * the cache before and after a read and/or write operation is required for
+ * correct operations.
+ *
+ * When called the macro creates an array on the stack that is sized such
+ * that:
+ *
+ * 1) The beginning of the array can be advanced enough to be aligned.
+ *
+ * 2) The size of the aligned portion of the array is a multiple of the minimum
+ *    architecture alignment required for DMA.
+ *
+ * 3) The aligned portion contains enough space for the original number of
+ *    elements requested.
+ *
+ * The macro then creates a pointer to the aligned portion of this array and
+ * assigns to the pointer the address of the first element in the aligned
+ * portion of the array.
+ *
+ * Calling the macro as:
+ *
+ *     ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
+ *
+ * Will result in something similar to saying:
+ *
+ *     uint32_t    buffer[1024];
+ *
+ * The following differences exist:
+ *
+ * 1) The resulting buffer is guaranteed to be aligned to the value of
+ *    ARCH_DMA_MINALIGN.
+ *
+ * 2) The buffer variable created by the macro is a pointer to the specified
+ *    type, and NOT an array of the specified type.  This can be very important
+ *    if you want the address of the buffer, which you probably do, to pass it
+ *    to the DMA hardware.  The value of &buffer is different in the two cases.
+ *    In the macro case it will be the address of the pointer, not the address
+ *    of the space reserved for the buffer.  However, in the second case it
+ *    would be the address of the buffer.  So if you are replacing hard coded
+ *    stack buffers with this macro you need to make sure you remove the & from
+ *    the locations where you are taking the address of the buffer.
+ *
+ * Note that the size parameter is the number of array elements to allocate,
+ * not the number of bytes.
+ *
+ * This macro can not be used outside of function scope, or for the creation
+ * of a function scoped static buffer.  It can not be used to create a cache
+ * line aligned global buffer.
+ */
+#define PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1)
+#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
+#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad)		\
+	char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align)  \
+		      + (align - 1)];					\
+									\
+	type *name = (type *) ALIGN((uintptr_t)__##name, align)
+#define ALLOC_ALIGN_BUFFER(type, name, size, align)		\
+	ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1)
+#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad)		\
+	ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)
+#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size)			\
+	ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
+
+/*
+ * DEFINE_CACHE_ALIGN_BUFFER() is similar to ALLOC_CACHE_ALIGN_BUFFER, but it's
+ * purpose is to allow allocating aligned buffers outside of function scope.
+ * Usage of this macro shall be avoided or used with extreme care!
+ */
+#define DEFINE_ALIGN_BUFFER(type, name, size, align)			\
+	static char __##name[roundup(size * sizeof(type), align)]	\
+			__aligned(align);				\
+									\
+	static type *name = (type *)__##name
+#define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)			\
+	DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
+
 #endif	/* __COMMON_H_ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_cmd_all.h u-boot-2011.06/include/config_cmd_all.h
--- u-boot-2011.06_original/include/config_cmd_all.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/config_cmd_all.h	2014-07-29 17:28:38.819972000 +0800
@@ -25,7 +25,7 @@
 #define CONFIG_CMD_CDP		/* Cisco Discovery Protocol	*/
 #define CONFIG_CMD_CONSOLE	/* coninfo			*/
 #define CONFIG_CMD_DATE		/* support for RTC, date/time...*/
-#define CONFIG_CMD_DHCP		/* DHCP Support			*/
+//#define CONFIG_CMD_DHCP		/* DHCP Support			*/
 #define CONFIG_CMD_DIAG		/* Diagnostics			*/
 #define CONFIG_CMD_DISPLAY	/* Display support		*/
 #define CONFIG_CMD_DOC		/* Disk-On-Chip Support		*/
@@ -61,12 +61,12 @@
 #define CONFIG_CMD_MMC		/* MMC support			*/
 #define CONFIG_CMD_MTDPARTS	/* mtd parts support		*/
 #define CONFIG_CMD_NAND		/* NAND support			*/
-#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
-#define CONFIG_CMD_NFS		/* NFS support			*/
+//#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
+//#define CONFIG_CMD_NFS		/* NFS support			*/
 #define CONFIG_CMD_ONENAND	/* OneNAND support		*/
 #define CONFIG_CMD_PCI		/* pciinfo			*/
 #define CONFIG_CMD_PCMCIA	/* PCMCIA support		*/
-#define CONFIG_CMD_PING		/* ping support			*/
+//#define CONFIG_CMD_PING		/* ping support			*/
 #define CONFIG_CMD_PORTIO	/* Port I/O			*/
 #define CONFIG_CMD_REGINFO	/* Register dump		*/
 #define CONFIG_CMD_REISER	/* Reiserfs support		*/
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_cmd_default.h u-boot-2011.06/include/config_cmd_default.h
--- u-boot-2011.06_original/include/config_cmd_default.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/config_cmd_default.h	2014-07-29 17:28:38.819972000 +0800
@@ -32,8 +32,8 @@
 #define CONFIG_CMD_LOADS	/* loads			*/
 #define CONFIG_CMD_MEMORY	/* md mm nm mw cp cmp crc base loop mtest */
 #define CONFIG_CMD_MISC		/* Misc functions like sleep etc*/
-#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
-#define CONFIG_CMD_NFS		/* NFS support			*/
+//#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
+//#define CONFIG_CMD_NFS		/* NFS support			*/
 #define CONFIG_CMD_RUN		/* run command in env variable	*/
 #define CONFIG_CMD_SAVEENV	/* saveenv			*/
 #define CONFIG_CMD_SETGETDCR	/* DCR support on 4xx		*/
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_defaults.h u-boot-2011.06/include/config_defaults.h
--- u-boot-2011.06_original/include/config_defaults.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/config_defaults.h	2014-07-29 17:28:38.819972000 +0800
@@ -17,4 +17,8 @@
 #define CONFIG_GZIP 1
 #define CONFIG_ZLIB 1
 
+#define CONFIG_RSAVERIFY 1
+#define CONFIG_MD5 1
+#define CONFIG_SHA256 1
+
 #endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_polarssl.h u-boot-2011.06/include/config_polarssl.h
--- u-boot-2011.06_original/include/config_polarssl.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/config_polarssl.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,47 @@
+/**
+ * \file config.h
+ *
+ * \brief Configuration options (set of defines)
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+#ifndef POLARSSL_CONFIG_H
+#define POLARSSL_CONFIG_H
+
+#define POLARSSL_HAVE_INT32
+#define POLARSSL_HAVE_ASM
+#define POLARSSL_PKCS1_V21
+#define POLARSSL_PKCS1_V15
+#define POLARSSL_RSA_C
+#define POLARSSL_BIGNUM_C
+#define POLARSSL_SHA256_C
+#define POLARSSL_MD_C
+#define POLARSSL_ASN1_PARSE_C
+#define POLARSSL_OID_C
+
+typedef unsigned int size_t;
+
+#endif /* POLARSSL_CONFIG_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/configs/cnc1900.h u-boot-2011.06/include/configs/cnc1900.h
--- u-boot-2011.06_original/include/configs/cnc1900.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/configs/cnc1900.h	2015-08-20 19:25:54.678159000 +0800
@@ -0,0 +1,283 @@
+/*
+ * (C) Copyright 2012
+ *  Cavium Xiaodong.Fan
+ * Configuration settings for the "CNC1900 FPGA Board",
+ * the evaluation board for the Nomadik 8815 System on Chip.
+ *
+ * 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_H
+#define __CONFIG_H
+
+#define CONFIG_ARMV7
+#define CONFIG_ARCH_CNC1900
+#define CONFIG_256M_DDR
+
+/* commands */
+#include <config_cmd_default.h>
+
+#define CONFIG_L2_OFF 1
+
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_CACHE
+
+#define CONFIG_CMD_BOOTS
+#define CONFIG_CMD_ESP1800L_FLASH_UTIL
+
+#define CONFIG_CMD_CSLOGO
+
+/* i2c */
+#define CONFIG_CNC1900_I2C
+#define CONFIG_CMD_I2C
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED	100000
+#define CONFIG_SYS_I2C_SLAVE    0x7f
+#define CONFIG_SYS_I2C_BASE     0x80170000
+#define CONFIG_SYS_I2C_CLK      CONFIG_SYS_PCLK_FREQ
+
+#if defined(CONFIG_CNC1900_I2C)
+#define CONFIG_CMD_EEPROM
+#endif
+
+#define CONFIG_CMD_GPIO
+#define CONFIG_CNC1900_GPIO
+#define CNC1900_GPIO_BASE      0x80260000
+#define REG_GPIO_SWPORTA_DDR 0x24
+#define REG_GPIO_SWPORTB_DDR 0x38
+#define REG_GPIO_EXT_PORTA   0x60
+#define REG_GPIO_EXT_PORTB   0x64
+#define REG_GPIO_SWPORTA_DR  0x20
+#define REG_GPIO_SWPORTB_DR  0x34
+
+/* user interface */
+#define CONFIG_CNC1900_CRYPTO
+#define CONFIG_CMD_CNC1900_OTP
+
+//#define DEBUG
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT		"CNC1900> "
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_CBSIZE		512	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+#define CONFIG_SYS_MAXARGS	    16
+#define CONFIG_SYS_LOAD_ADDR	0x800000	/* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+/* polarssl config */
+#define POLARSSL_CONFIG_FILE "config_polarssl.h"
+
+/* boot config */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_BOOTDELAY 1
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+/*sd/mmc slot */
+#define CONFIG_DWMMC
+#define CONFIG_CNC_DWMMC
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+
+/* GPT */
+#define HAVE_BLOCK_DEVICE
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_EFI_PARTITION
+#define CONFIG_CMD_GPT
+
+/* Simg */
+#define CONFIG_CMD_SIMG
+
+/* eeprom */
+#if defined(CONFIG_CMD_EEPROM)
+#define CONFIG_SYS_I2C_EEPROM_ADDR            0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN        2
+#define CONFIG_ETHADDR_EEPROM_OFFSET          0x114
+#endif
+
+/* memory-related information */
+#define CONFIG_NR_DRAM_BANKS	1
+#define PHYS_SDRAM_1		0x00000000	/* DDR-SDRAM Bank #1 */
+#ifdef DDR_SIZE_1G
+#define PHYS_SDRAM_1_SIZE       0x40000000      /* 1G MB */
+#elif defined DDR_SIZE_512M
+#define PHYS_SDRAM_1_SIZE	0x10000000	/* 512 MB */
+#else
+#define PHYS_SDRAM_1_SIZE	0x10000000	/* 256 MB */
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE	    PHYS_SDRAM_1
+#define CONFIG_SYS_SDRAM_SIZE	    PHYS_SDRAM_1_SIZE
+#define CONFIG_SYS_TEXT_BASE        0x2000000
+#define CONFIG_SYS_PHY_UBOOT_BASE   CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR     (CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN - 512)
+
+#define CONFIG_SYS_MEM_TOP_HIDE     (0x4100000) /* 65MB */
+#define CONFIG_STACKSIZE	        (512 * 1024)	/* regular stack */
+
+#define CONFIG_USE_IRQ
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ	(4 * 1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4 * 1024)	/* FIQ stack */
+#endif
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END		0x0FFFFFFF
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 12 * 1024 * 1024)
+
+/* timing informazion */
+#define CONFIG_SYS_PCLK_FREQ        CONFIG_SYS_CPU_CLK
+#define CONFIG_SYS_HZ		        1000
+
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_CONS_INDEX	          1
+#define CONFIG_SYS_NS16550_REG_SIZE   (-4)
+#define CONFIG_BAUDRATE		          115200
+#define CONFIG_SYS_BAUDRATE_TABLE	  { 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_SYS_NS16550_COM1       0x801F1000
+#define CONFIG_SYS_NS16550_COM2       0x801F2000
+
+/* NAND */
+#define CONFIG_CMD_NAND
+#define CONFIG_CNC_NAND
+#define CONFIG_CNC_NAND_BASE    0x80100000
+#define CONFIG_SYS_NAND_BASE	0xA4000000
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+
+/* ETH */
+#define CONFIG_NET_MULTI
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CN100_BASEADDRESS	0xb1400000
+
+/* EHCI */
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_CNC
+#define CONFIG_SYS_USB_EHCI_REGS_BASE	    0x80200000
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS  2
+#define CONFIG_DOS_PARTITION
+#define CONFIG_LBA48
+#define CONFIG_USB_STORAGE
+#define CONFIG_AUTO_UPDATE
+
+/* environment */
+#define CONFIG_CMD_SAVEENV
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_CMD_ANDR_BOOT
+#define CONFIG_CMD_AUTO_BOOT
+
+
+/* Legacy SPI flash commands, will remove later */
+#if 0
+#define CONFIG_SPI_FLASH_CNC1900
+#define CONFIG_CMD_SF_LEGACY
+#endif
+
+#define  SPI_TOKEN  "cnc-spi"
+
+/* New SPI driver */
+#define CONFIG_CMD_SF
+#define CONFIG_DW_SPI
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SPI_FLASH_GIGADEVICE
+#define CONFIG_CMD_SF
+#define CONFIG_SF_DEFAULT_SPEED 25000000
+
+
+/* reserve 10M for u-boot self, log buf, TLB, bd_t, irq stack, abort stack and so on */
+#ifdef CONFIG_SYS_MEM_TOP_HIDE
+    /*
+     * Ethernet DMA buffer can only use memory less than 256MiB,
+     * so use 256MiB instead of 512MiB as base address on 512MiB RAM board
+     */
+    #if (PHYS_SDRAM_1_SIZE >= 0x10000000)
+        #define CONFIG_MEM_DEFINE_BASE  (0x10000000 - CONFIG_SYS_MEM_TOP_HIDE - CONFIG_SYS_MALLOC_LEN - 0xa00000)
+	 #define CONFIG_USB_UPGRADE_DATA_ADDR 	(0x10000000)
+    #else
+        #define CONFIG_MEM_DEFINE_BASE  (PHYS_SDRAM_1_SIZE - CONFIG_SYS_MEM_TOP_HIDE - CONFIG_SYS_MALLOC_LEN - 0xa00000)
+	 #define CONFIG_USB_UPGRADE_DATA_ADDR 	(0x1000000)
+    #endif
+#else
+    #if (PHYS_SDRAM_1_SIZE >= 0x10000000)
+        #define CONFIG_MEM_DEFINE_BASE  (0x10000000 - CONFIG_SYS_MALLOC_LEN - 0xa00000)
+	 #define CONFIG_USB_UPGRADE_DATA_ADDR 	(0x10000000)
+    #else
+        #define CONFIG_MEM_DEFINE_BASE  (PHYS_SDRAM_1_SIZE - CONFIG_SYS_MALLOC_LEN - 0xa00000)
+	 #define CONFIG_USB_UPGRADE_DATA_ADDR 	(0x1000000)
+    #endif
+#endif
+
+#define CONFIG_UBOOT_EXTERNAL_PROC_LEN (0x100000) //for PIC processes code such as hdmi or OTA that will be combined after u-boot.bin
+
+#define CONFIG_SPI_DMA_BUF_LEN 0x800000
+#define CONFIG_SPI_DMA_BUF_BASE (CONFIG_MEM_DEFINE_BASE - CONFIG_SPI_DMA_BUF_LEN)
+
+#define CONFIG_XPORT_MEM_LEN 0x800000
+#define CONFIG_XPORT_MEM_BASE (CONFIG_SPI_DMA_BUF_BASE - CONFIG_XPORT_MEM_LEN)
+#define CRYPTO_MEM_SIZE 0x300000
+#define CRYPTO_MEM_REGION (CONFIG_XPORT_MEM_BASE - CRYPTO_MEM_SIZE)
+#define CONFIG_ALIGNED_PIC_PROC_MEM_SIZE CONFIG_UBOOT_EXTERNAL_PROC_LEN
+#define CONFIG_ALIGNED_PIC_PROC_MEM_BASE (((CRYPTO_MEM_REGION - CONFIG_ALIGNED_PIC_PROC_MEM_SIZE-sizeof(int))+(sizeof(int)-1))&(0xFFFFFFFC))
+
+/* this is needed to make hello_world.c and other stuff happy */
+#define CONFIG_SYS_MAX_FLASH_SECT	512
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+
+#include <config_target_specific.h>
+
+#define CONFIG_CNC1900_SD0_BASE  0x80290000  /* Mobile Storage Host Controller (MMC/SD/SDIO) */
+#define CONFIG_CNC1900_SD1_BASE  0x802a0000  /* Mobile Storage Host Controller (MMC/SD/SDIO) */
+
+#define CONFIG_PARTITIONS
+#define CONFIG_DOS_PARTITION
+
+#define CONFIG_CMD_CALL_EXTERNAL_PROC
+#define CONFIG_CMD_UPGRADE
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+#define CONFIG_CNC1900_DF
+#define CONFIG_CMD_CNC1900_AUDIO
+/** System Cotrol */
+#define CNC1900_SYSCTL_BASE             0xB2000000
+/* Pin Mux */
+#define CNC1900_PIN_MUX                 (CNC1900_SYSCTL_BASE + 0x00110000)
+#define BOARD_LATE_INIT
+
+#endif /* __CONFIG_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/configs/orion.h u-boot-2011.06/include/configs/orion.h
--- u-boot-2011.06_original/include/configs/orion.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/configs/orion.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,209 @@
+/*
+ * (C) Copyright 2005
+ * STMicroelectronics.
+ * Configuration settings for the "Nomadik Hardware Kit" NHK-8815,
+ * the evaluation board for the Nomadik 8815 System on Chip.
+ *
+ * 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_H
+#define __CONFIG_H
+
+#define CONFIG_ARM926EJS
+#define CONFIG_ARCH_CSM1800
+#define CONFIG_256M_DDR
+
+#define CONFIG_SKIP_LOWLEVEL_INIT /* we have already been loaded to RAM */
+
+/* commands */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_NFS
+/* There is no NOR flash, so undefine these commands */
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_SYS_NO_FLASH
+/* There is NAND storage */
+//#define CONFIG_NAND_NOMADIK
+#define CONFIG_CMD_JFFS2
+/* There is EEPROM storage */
+#define CONFIG_CMD_EEPROM
+
+/* user interface */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT		"CSM1800h> "
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_CBSIZE		256	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+#define CONFIG_SYS_MAXARGS	16
+#define CONFIG_SYS_LOAD_ADDR	0x800000	/* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+/* boot config */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_BOOTDELAY	1
+#define CONFIG_ETHADDR	00:12:57:5b:4c:ce
+#define CONFIG_SERVERIP	192.168.18.74
+#define CONFIG_IPADDR   192.168.18.117
+#define CONFIG_BOOTARGS	"root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
+/*
+#define CONFIG_BOOTCOMMAND	"fsload 0x100000 kernel.uimg;" \
+				" fsload 0x800000 initrd.gz.uimg;" \
+				" bootm 0x100000 0x800000"
+*/
+
+/* memory-related information */
+#define CONFIG_NR_DRAM_BANKS	1
+#define PHYS_SDRAM_1		0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE	0x10000000	/* 256 MB */
+//#define PHYS_SDRAM_2		0x08000000	/* SDR-SDRAM BANK #2*/
+//#define PHYS_SDRAM_2_SIZE	0x04000000	/* 64 MB */
+#define CONFIG_SYS_SDRAM_BASE	PHYS_SDRAM_1
+#define CONFIG_SYS_SDRAM_SIZE	PHYS_SDRAM_1_SIZE
+#define CONFIG_SYS_TEXT_BASE        0x2000000
+#define CONFIG_SYS_PHY_UBOOT_BASE   CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN - 512)
+
+#define CONFIG_STACKSIZE	(512 * 1024)	/* regular stack */
+
+#define CONFIG_USE_IRQ
+#ifdef CONFIG_USE_IRQ
+#  define CONFIG_STACKSIZE_IRQ	(4 * 1024)	/* IRQ stack */
+#  define CONFIG_STACKSIZE_FIQ	(4 * 1024)	/* FIQ stack */
+#endif
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END		0x0FFFFFFF
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 12 * 1024 * 1024)
+
+/* timing informazion */
+#define CONFIG_SYS_CPU_CLK              378000000
+#define CONFIG_SYS_PCLK_FREQ            (CONFIG_SYS_CPU_CLK / 8)
+#define CONFIG_SYS_HZ		        1000
+#define CONFIG_SYS_TIMERBASE	        0x101E2000
+#define CONFIG_SYS_TIMER_INTERVAL       10000
+#define CONFIG_SYS_TIMER_RELOAD         (CONFIG_SYS_TIMER_INTERVAL >> 4)  /* Divide by 16 */
+#define CONFIG_SYS_TIMER_CTRL          0x84                              /* Enable, Clock / 16 */
+
+/* usb */
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_USB
+
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_REGS_BASE        0x80210000
+#define CONFIG_SYS_USB_OHCI_SLOT_NAME        "CSM1800H"
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS   1
+#define CONFIG_DOS_PARTITION
+#define CONFIG_USB_CSM
+#define CONFIG_USB_STORAGE
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_CLK          CONFIG_SYS_PCLK_FREQ
+#define CONFIG_CONS_INDEX	        1
+#define CONFIG_SYS_NS16550_REG_SIZE     (-4)
+#define CONFIG_BAUDRATE		        115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_SYS_NS16550_COM1         0x101F1000
+#define CONFIG_SYS_NS16550_COM2         0x101F2000
+
+/* i2c */
+#define CONFIG_ORION_I2C
+#define CONFIG_CMD_I2C
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED	100000
+#define CONFIG_SYS_I2C_SLAVE    0x7f
+#define CONFIG_SYS_I2C_BASE     0x10170000
+#define CONFIG_SYS_I2C_CLK      CONFIG_SYS_PCLK_FREQ
+
+#define CONFIG_CMD_GPIO
+#define CONFIG_ORION_GPIO
+#define ORION_GPIO_BASE      0x10260000
+#define REG_GPIO_SWPORTA_DDR 0x24
+#define REG_GPIO_SWPORTB_DDR 0x38
+#define REG_GPIO_EXT_PORTA   0x60
+#define REG_GPIO_EXT_PORTB   0x64
+#define REG_GPIO_SWPORTA_DR  0x20
+#define REG_GPIO_SWPORTB_DR  0x34
+
+/* eeprom */
+#if defined(CONFIG_CMD_EEPROM)
+#define CONFIG_SYS_I2C_EEPROM_ADDR            0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN        2
+#define CONFIG_ORION_ETHADDR_EEPROM_OFFSET    0x114
+#endif
+
+#define CONFIG_DRIVER_CN100
+#define CN100_BASEADDRESS			0x41400000
+#define CONFIG_BOOTFILE		"uImage"
+
+#define CONFIG_IP_DEFRAG	/* Allows faster download, TFTP and NFS */
+//#define CONFIG_TFTP_BLOCKSIZE	4096
+#define CONFIG_NFS_READ_SIZE	4096
+
+//#define CONFIG_CMD_NAND
+//#define CONFIG_SYS_MAX_NAND_DEVICE	1
+//#define CONFIG_SYS_NAND_BASE		0x40000000 /* SMPS0n */
+
+#define CONFIG_CMD_SAVEENV
+
+#if defined (CONFIG_ARCH_CSM_NAND_BOOT)
+
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800) */
+#define CONFIG_ENV_OFFSET        0x00060000 /* environment starts here/aligned with 128KB                         */
+#define CONFIG_ENV_SECT_SIZE     0x00020000 /* 64 KB sectors                                                      */
+
+#else
+
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_SIZE          0x00010000 /* Total Size of Environment Sector 64KB */
+#define CONFIG_ENV_OFFSET        0x00050000 /* environment starts here               */
+#define CONFIG_ENV_SECT_SIZE     0x00010000 /* 64 KB sectors                         */
+
+#endif
+
+
+//#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_ORION
+#define CONFIG_CMD_SF
+
+//#define CONFIG_CMD_SPI
+//#define CONFIG_ORION_SPI
+//#define CONFIG_SYS_SPI_BASE             0x10150000
+
+/* this is needed to make hello_world.c and other stuff happy */
+#define CONFIG_SYS_MAX_FLASH_SECT	512
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+
+#define CONFIG_CSM1800H_XPORT
+#define CONFIG_XPORT_BASE (0x41400000) 
+#define CONFIG_CSM1800H_TUNER
+#endif /* __CONFIG_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_target_names.h u-boot-2011.06/include/config_target_names.h
--- u-boot-2011.06_original/include/config_target_names.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/config_target_names.h	2015-03-16 11:19:40.877878000 +0800
@@ -0,0 +1,14 @@
+#ifndef _CONFIG_TARGET_NAMES_
+#define _CONFIG_TARGET_NAMES_
+
+#define CNC1900_EVB           0
+#define CNC1900_HDK           1
+#define CNC1900_FJ_RX         2
+#define CNC1900_FPGA          3
+#define CNC1900_ZINWELL       4
+#define CNW83XX_OTT_EMMC      5
+#define CNW83XX_VMS_MINI      6
+#define CNW83XX_SONY          7
+#define CNW83XX_SONY_VEDETT   8
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_target_specific.h u-boot-2011.06/include/config_target_specific.h
--- u-boot-2011.06_original/include/config_target_specific.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/config_target_specific.h	2015-03-16 11:19:40.877878000 +0800
@@ -0,0 +1,415 @@
+#ifndef _CONFIG_TARGET_SPECIFIC_
+#define _CONFIG_TARGET_SPECIFIC_
+
+#include <config_target_names.h>
+#if (SECURE == 1 )
+	#define CONFIG_CMD_SEC1900_MEM_PROTECT
+#else
+	#undef CONFIG_CMD_SEC1900_MEM_PROTECT
+#endif
+
+#if (CONFIG_TARGET_NAME == CNC1900_EVB)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_CMD_EEPROM /* There is EEPROM storage */
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+
+	#define CONFIG_TVOUT_YPBPR
+	#define CONFIG_TVOUT_CVBS
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNW83XX_OTT_EMMC)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+	#define CONFIG_CNC1900_SD1
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_DRIVER_CN100_MULTI
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "emmc"
+
+	#define CONFIG_ENV_IS_IN_MMC
+	#define CONFIG_SYS_MMC_ENV_DEV 0
+	#define CONFIG_ENV_SIZE            0x00100000 /* Total Size of Environment Sector 1MB  */
+	#define CONFIG_ENV_OFFSET          0x00200000 /* environment starts here               */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                        */
+
+	#define CONFIG_CMD_SEC_NVEDIT
+	#define CONFIG_SEC_ENV_IS_IN_MMC
+	#define CONFIG_SYS_MMC_SEC_ENV_DEV 0
+	#define CONFIG_ENV_F_SIZE          0x00100000 /* Total Size of Environment Sector 1MB  */
+	#define CONFIG_ENV_F_OFFSET        0x00300000 /* Fail safe environment starts here     */
+
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNW83XX_SONY_VEDETT)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+	#define CONFIG_CNC1900_SD1
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_DRIVER_CN100_MULTI
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "emmc"
+
+	#define CONFIG_ENV_IS_IN_MMC
+	#define CONFIG_SYS_MMC_ENV_DEV 0
+	#define CONFIG_ENV_SIZE            0x00100000 /* Total Size of Environment Sector 1MB  */
+	#define CONFIG_ENV_OFFSET          0x00200000 /* environment starts here               */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                        */
+
+	#define CONFIG_CMD_SEC_NVEDIT
+	#define CONFIG_SEC_ENV_IS_IN_MMC
+	#define CONFIG_SYS_MMC_SEC_ENV_DEV 0
+	#define CONFIG_ENV_F_SIZE          0x00100000 /* Total Size of Environment Sector 1MB  */
+	#define CONFIG_ENV_F_OFFSET        0x00300000 /* Fail safe environment starts here     */
+
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNW83XX_SONY)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+	
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+	#define CONFIG_CMD_UPDATE_SOURCE 2
+
+#elif (CONFIG_TARGET_NAME == CNC1900_HDK)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+	#define CONFIG_CNC1900_SD1
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+
+	#define CONFIG_TVOUT_CVBS
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNW83XX_VMS_MINI)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+	
+	#define CONFIG_USB_HOST_ETHER
+	#define CONFIG_USB_ETHER_ASIX
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNC1900_ZINWELL)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+
+#elif (CONFIG_TARGET_NAME == CNC1900_FJ_RX)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_256M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+#if 0
+	#define CONFIG_INPUT_WHITELIST char *input_whitelist[] = { \
+		"reset\r\n", \
+		"\r\n", \
+		"ver\r\n", \
+		"setenv FACTORY_DIAGS\r\n", \
+		"saveenv\r\n", \
+		"reset\n", \
+		"\n", \
+		"ver\n", \
+		"setenv FACTORY_DIAGS\n", \
+		"saveenv\n", \
+		NULL \
+	};
+#endif
+
+#elif (CONFIG_TARGET_NAME == CNC1900_FPGA)
+	#define CONFIG_SYS_CPU_CLK          27000000
+	#define CONFIG_SYS_NS16550_CLK      CONFIG_SYS_PCLK_FREQ
+
+	/*hardware parameters*/
+	#define DDR_SIZE_256M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"bootm 0x7FC0 0x3000000"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+
+#elif (CONFIG_TARGET_NAME == CNC1900_HDK)
+	#define CONFIG_SYS_CPU_CLK          810000000
+	#define CONFIG_SYS_NS16550_CLK      45000000
+
+	/*hardware parameters*/
+	#define DDR_SIZE_512M
+
+	/*environment variables*/
+	#define CONFIG_BOOTARGS 	"root=/dev/ram0 console=ttyS0,115200"
+	#define CONFIG_BOOTCOMMAND	"tftp 100000 uImage; bootm"
+
+	/*logo format*/
+	#define CONFIG_LOGO_FORMAT 8888
+	#define CONFIG_LOGO_WIDTH 1920
+	#define CONFIG_LOGO_HEIGHT 1080
+
+	/*miscellaneous target specific macros*/
+	#define CONFIG_DRIVER_CN100
+	#define CONFIG_BOOTFILE 	"uImage"
+	#define CONFIG_CMD_UNZIP
+
+	#define CONFIG_CNC_BOOTM_MTDID "cnc-nand"
+
+	#define CONFIG_ENV_IS_IN_NAND
+	#define CONFIG_CMD_SEC_NVEDIT
+
+	#define CONFIG_ENV_F_SIZE          0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)    */
+	#define CONFIG_ENV_F_RANGE         0x00040000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE */
+	#define CONFIG_ENV_F_OFFSET        0x00020000 /* environment starts here/aligned with 128KB                            */
+	#define CONFIG_ENV_F_SECT_SIZE     0x00020000 /* 128 KB sectors                                                        */
+
+	#define CONFIG_ENV_SIZE            0x00020000 /* Total Size of Environment Sector 128KB(for 2k pagesize of csm1800)     */
+	#define CONFIG_ENV_RANGE           0x00080000 /* saveenv can skip bad block, but it only write env in CONFIG_ENV_RANGE  */
+	#define CONFIG_ENV_OFFSET          0x000e0000 /* environment starts here/aligned with 128KB                             */
+	#define CONFIG_ENV_SECT_SIZE       0x00020000 /* 128 KB sectors                                                         */
+
+	#define CONFIG_TVOUT_CVBS
+	#define CONFIG_CMD_UPDATE_SOURCE 1
+#else
+	#error "Invalid target!"
+#endif
+
+
+#endif
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/config_xyssl.h u-boot-2011.06/include/config_xyssl.h
--- u-boot-2011.06_original/include/config_xyssl.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/config_xyssl.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,86 @@
+/**
+ * \file config.h
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+#ifndef XYSSL_CONFIG_H
+#define XYSSL_CONFIG_H
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/*
+ * Uncomment if native integers are 8-bit wide.
+ *
+#define XYSSL_HAVE_INT8
+ */
+
+/*
+ * Uncomment if native integers are 16-bit wide.
+ *
+#define XYSSL_HAVE_INT16
+ */
+
+/*
+ * Uncomment if the compiler supports long long.
+ *
+#define XYSSL_HAVE_LONGLONG
+ */
+
+/*
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ *
+#define XYSSL_HAVE_SSE2
+ */
+
+
+/*
+ * Enable the checkup functions (*_self_test).
+ */
+//#define XYSSL_SELF_TEST
+
+/*
+ * Enable the prime-number generation code.
+ */
+//#define XYSSL_GENPRIME
+
+
+/*
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/rsa.c
+ *          library/ssl_tls.c
+ *          library/x509parse.c
+ *
+ * This module is required for RSA and DHM support.
+ */
+#define XYSSL_BIGNUM_C
+
+
+
+/*
+ * Module:  library/rsa.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is required for SSL/TLS and X.509.
+ */
+#define XYSSL_RSA_C
+
+
+/*
+ * Module:  library/sha2.c
+ * Caller:
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ */
+#define XYSSL_SHA2_C
+
+//#define BIGNUM_FILE_FUNC_ENA
+
+#endif /* config.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/c_stdlib.h u-boot-2011.06/include/c_stdlib.h
--- u-boot-2011.06_original/include/c_stdlib.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/c_stdlib.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#ifndef _C_STDLIB_H_
+#define _C_STDLIB_H_
+
+//#define USE_C_STD_LIB
+
+#if defined(__CC_ARM)	//USE_C_STD_LIB
+#include "x_clib.h"
+#include <string.h>
+//#include <string.h>
+//#include <stdio.h>
+//#include <assert.h>
+//#include <stdlib.h>
+
+#elif defined(__GNUC__)
+
+#include "x_clib.h"
+
+#define memcpy(s1, s2, n) x_memcpy(s1, s2, n)
+#define memcmp(s1, s2, n) x_memcmp(s1, s2, n)
+#define memset(s ,  c, n) x_memset(s ,  c, n)
+
+#endif
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/customer_specific_definitions.h u-boot-2011.06/include/customer_specific_definitions.h
--- u-boot-2011.06_original/include/customer_specific_definitions.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/customer_specific_definitions.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,33 @@
+#if !defined(__CUSTOMER_SPECIFIC_DEFINITIONS_H__)
+#define __CUSTOMER_SPECIFIC_DEFINITIONS_H__ 1
+
+/* These are customer-specific definitions for U-Boot.  Currently, this includes
+   only the addresses in flash memory where certain interesting things may be
+   found. This version of the header file contains definitions specific to the
+   following customer: cavium */
+
+/* Where the blob header can be found in flash. */
+#define CAVM18_BLOB_HDR_FLSH_ADDR          (0xa00000)
+
+/* Where the factory kernel header is in flash. */
+#define CAVM18_FACT_HDR_FLSH_ADDR           (0x003c0000)
+
+/* Where the field kernel header is in flash. */
+#define CAVM18_FIELD_KENREL_HDR_FLSH_ADDR	(0x057c0000)
+
+/* Location of the factory kernel */
+#define FACTORY_KERNEL_FLASH_ADDR           (0x00400000)
+
+/* Location of the field kernel */
+#define FIELD_KERNEL_FLASH_ADDR             (0x02400000)
+
+/* Location of the factory u-boot */
+#define FACTORY_UBOOT_FLASH_ADDR            (0x00020000)
+
+/* Location of the field u-boot */
+#define FIELD_UBOOT_FLASH_ADDR              (0x05b00000)
+
+/* Location (PHYSICAL, not virtual) where the decrypted secure blob is stored. */
+#define CRYPTO_OUT_BLOB_LINUX_ADDR          (PHYS_SDRAM_1_SIZE - 0X4001000)
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/dwmmc.h u-boot-2011.06/include/dwmmc.h
--- u-boot-2011.06_original/include/dwmmc.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/dwmmc.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,181 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DWMMC_HW_H
+#define __DWMMC_HW_H
+
+#include <asm/io.h>
+#include <mmc.h>
+
+#define DWMCI_CTRL		0x000
+#define	DWMCI_PWREN		0x004
+#define DWMCI_CLKDIV		0x008
+#define DWMCI_CLKSRC		0x00C
+#define DWMCI_CLKENA		0x010
+#define DWMCI_TMOUT		0x014
+#define DWMCI_CTYPE		0x018
+#define DWMCI_BLKSIZ		0x01C
+#define DWMCI_BYTCNT		0x020
+#define DWMCI_INTMASK		0x024
+#define DWMCI_CMDARG		0x028
+#define DWMCI_CMD		0x02C
+#define DWMCI_RESP0		0x030
+#define DWMCI_RESP1		0x034
+#define DWMCI_RESP2		0x038
+#define DWMCI_RESP3		0x03C
+#define DWMCI_MINTSTS		0x040
+#define DWMCI_RINTSTS		0x044
+#define DWMCI_STATUS		0x048
+#define DWMCI_FIFOTH		0x04C
+#define DWMCI_CDETECT		0x050
+#define DWMCI_WRTPRT		0x054
+#define DWMCI_GPIO		0x058
+#define DWMCI_TCMCNT		0x05C
+#define DWMCI_TBBCNT		0x060
+#define DWMCI_DEBNCE		0x064
+#define DWMCI_USRID		0x068
+#define DWMCI_VERID		0x06C
+#define DWMCI_HCON		0x070
+#define DWMCI_UHS_REG		0x074
+#define DWMCI_BMOD		0x080
+#define DWMCI_PLDMND		0x084
+#define DWMCI_DBADDR		0x088
+#define DWMCI_IDSTS		0x08C
+#define DWMCI_IDINTEN		0x090
+#define DWMCI_DSCADDR		0x094
+#define DWMCI_BUFADDR		0x098
+#define DWMCI_DATA		0x200
+
+/* Interrupt Mask register */
+#define DWMCI_INTMSK_ALL	0xffffffff
+#define DWMCI_INTMSK_RE		(1 << 1)
+#define DWMCI_INTMSK_CDONE	(1 << 2)
+#define DWMCI_INTMSK_DTO	(1 << 3)
+#define DWMCI_INTMSK_TXDR	(1 << 4)
+#define DWMCI_INTMSK_RXDR	(1 << 5)
+#define DWMCI_INTMSK_DCRC	(1 << 7)
+#define DWMCI_INTMSK_RTO	(1 << 8)
+#define DWMCI_INTMSK_DRTO	(1 << 9)
+#define DWMCI_INTMSK_HTO	(1 << 10)
+#define DWMCI_INTMSK_FRUN	(1 << 11)
+#define DWMCI_INTMSK_HLE	(1 << 12)
+#define DWMCI_INTMSK_SBE	(1 << 13)
+#define DWMCI_INTMSK_ACD	(1 << 14)
+#define DWMCI_INTMSK_EBE	(1 << 15)
+
+/* Raw interrupt Regsiter */
+#define DWMCI_DATA_ERR	(DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\
+			DWMCI_INTMSK_FRUN | DWMCI_INTMSK_EBE | DWMCI_INTMSK_DCRC)
+#define DWMCI_DATA_TOUT	(DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO)
+/* CTRL register */
+#define DWMCI_CTRL_RESET	(1 << 0)
+#define DWMCI_CTRL_FIFO_RESET	(1 << 1)
+#define DWMCI_CTRL_DMA_RESET	(1 << 2)
+#define DWMCI_DMA_EN		(1 << 5)
+#define DWMCI_CTRL_SEND_AS_CCSD	(1 << 10)
+#define DWMCI_IDMAC_EN		(1 << 25)
+#define DWMCI_RESET_ALL		(DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET |\
+				DWMCI_CTRL_DMA_RESET)
+
+/* CMD register */
+#define DWMCI_CMD_RESP_EXP	(1 << 6)
+#define DWMCI_CMD_RESP_LENGTH	(1 << 7)
+#define DWMCI_CMD_CHECK_CRC	(1 << 8)
+#define DWMCI_CMD_DATA_EXP	(1 << 9)
+#define DWMCI_CMD_RW		(1 << 10)
+#define DWMCI_CMD_SEND_STOP	(1 << 12)
+#define DWMCI_CMD_ABORT_STOP	(1 << 14)
+#define DWMCI_CMD_PRV_DAT_WAIT	(1 << 13)
+#define DWMCI_CMD_UPD_CLK	(1 << 21)
+#define DWMCI_CMD_USE_HOLD_REG	(1 << 29)
+#define DWMCI_CMD_START		(1 << 31)
+
+/* CLKENA register */
+#define DWMCI_CLKEN_ENABLE	(1 << 0)
+#define DWMCI_CLKEN_LOW_PWR	(1 << 16)
+
+/* Card-type registe */
+#define DWMCI_CTYPE_1BIT	0
+#define DWMCI_CTYPE_4BIT	(1 << 0)
+#define DWMCI_CTYPE_8BIT	(1 << 16)
+
+/* Status Register */
+#define DWMCI_BUSY		(1 << 9)
+
+/* FIFOTH Register */
+#define MSIZE(x)		((x) << 28)
+#define RX_WMARK(x)		((x) << 16)
+#define TX_WMARK(x)		(x)
+#define RX_WMARK_SHIFT		16
+#define RX_WMARK_MASK		(0xfff << RX_WMARK_SHIFT)
+
+#define DWMCI_IDMAC_OWN		(1 << 31)
+#define DWMCI_IDMAC_CH		(1 << 4)
+#define DWMCI_IDMAC_FS		(1 << 3)
+#define DWMCI_IDMAC_LD		(1 << 2)
+
+/*  Bus Mode Register */
+#define DWMCI_BMOD_IDMAC_RESET	(1 << 0)
+#define DWMCI_BMOD_IDMAC_FB	(1 << 1)
+#define DWMCI_BMOD_IDMAC_EN	(1 << 7)
+
+struct dwmci_host {
+	char *name;
+	void *ioaddr;
+	unsigned int quirks;
+	unsigned int caps;
+	unsigned int version;
+	unsigned int clock;
+	unsigned int bus_hz;
+	int dev_index;
+	int buswidth;
+	u32 clksel_val;
+	u32 fifoth_val;
+	struct mmc *mmc;
+
+	void (*clksel)(struct dwmci_host *host);
+	unsigned int (*mmc_clk)(int dev_index);
+};
+
+struct dwmci_idmac {
+	u32 flags;
+	u32 cnt;
+	u32 addr;
+	u32 next_addr;
+};
+
+static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val)
+{
+	writel(val, host->ioaddr + reg);
+}
+
+static inline void dwmci_writew(struct dwmci_host *host, int reg, u16 val)
+{
+	writew(val, host->ioaddr + reg);
+}
+
+static inline void dwmci_writeb(struct dwmci_host *host, int reg, u8 val)
+{
+	writeb(val, host->ioaddr + reg);
+}
+static inline u32 dwmci_readl(struct dwmci_host *host, int reg)
+{
+	return readl(host->ioaddr + reg);
+}
+
+static inline u16 dwmci_readw(struct dwmci_host *host, int reg)
+{
+	return readw(host->ioaddr + reg);
+}
+
+static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
+{
+	return readb(host->ioaddr + reg);
+}
+
+int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
+#endif	/* __DWMMC_HW_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/_exports.h u-boot-2011.06/include/_exports.h
--- u-boot-2011.06_original/include/_exports.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/_exports.h	2014-07-29 17:28:38.819972000 +0800
@@ -30,3 +30,21 @@
 EXPORT_FUNC(spi_claim_bus)
 EXPORT_FUNC(spi_release_bus)
 EXPORT_FUNC(spi_xfer)
+EXPORT_FUNC(memcpy)
+EXPORT_FUNC(memset)
+EXPORT_FUNC(cnc_NandErase)
+EXPORT_FUNC(cnc_NandVerify)
+EXPORT_FUNC(cnc_NandRead)
+EXPORT_FUNC(cnc_NandWrite)
+EXPORT_FUNC(cnc_SpiErase)
+EXPORT_FUNC(cnc_SpiVerify)
+EXPORT_FUNC(cnc_SpiRead)
+EXPORT_FUNC(cnc_SpiWrite)
+EXPORT_FUNC(ProgramAndVerify2Spi)
+EXPORT_FUNC(ProgramAndVerify2Nand)
+EXPORT_FUNC(ProgramAndVerify2EMMC)
+EXPORT_FUNC(sprintf)
+EXPORT_FUNC(memcmp)
+EXPORT_FUNC(strcat)
+EXPORT_FUNC(strlen)
+EXPORT_FUNC(cnc_EMMCRead)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/exports.h u-boot-2011.06/include/exports.h
--- u-boot-2011.06_original/include/exports.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/exports.h	2014-07-29 17:28:38.819972000 +0800
@@ -25,7 +25,8 @@
 int setenv (char *varname, char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
-int ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
 #if defined(CONFIG_CMD_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/fat.h u-boot-2011.06/include/fat.h
--- u-boot-2011.06_original/include/fat.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/fat.h	2014-07-29 17:28:38.819972000 +0800
@@ -181,7 +181,7 @@
  * (see FAT32 accesses)
  */
 typedef struct {
-	__u8	fatbuf[FATBUFSIZE]; /* Current FAT buffer */
+	__u8	*fatbuf; /* Current FAT buffer */
 	int	fatsize;	/* Size of FAT in bits */
 	__u16	fatlength;	/* Length of FAT in sectors */
 	__u16	fat_sect;	/* Starting sector of the FAT */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/ide.h u-boot-2011.06/include/ide.h
--- u-boot-2011.06_original/include/ide.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/ide.h	2014-07-29 17:28:38.819972000 +0800
@@ -24,9 +24,10 @@
 #ifndef	_IDE_H
 #define _IDE_H
 
-#define	IDE_BUS(dev)	(dev >> 1)
+#define IDE_BUS(dev)	(dev / (CONFIG_SYS_IDE_MAXDEVICE / CONFIG_SYS_IDE_MAXBUS))
 
 #define	ATA_CURR_BASE(dev)	(CONFIG_SYS_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
+extern ulong ide_bus_offset[];
 
 #ifdef CONFIG_IDE_LED
 
@@ -42,8 +43,10 @@
 
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
+#define LBAF "%llx"
 #else
 typedef ulong lbaint_t;
+#define LBAF "%lx"
 #endif
 
 /*
@@ -51,8 +54,17 @@
  */
 
 void ide_init(void);
-ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer);
-ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer);
+ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer);
+ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt,
+		const void *buffer);
+
+#ifdef CONFIG_IDE_PREINIT
+int ide_preinit(void);
+#endif
+
+#ifdef CONFIG_IDE_INIT_POSTRESET
+int ide_init_postreset(void);
+#endif
 
 #if defined(CONFIG_OF_IDE_FIXUP)
 int ide_device_present(int dev);
@@ -64,4 +76,21 @@
 void ide_read_data(int dev, ulong *sect_buf, int words);
 void ide_write_data(int dev, ulong *sect_buf, int words);
 #endif
+
+/*
+ * I/O function overrides
+ */
+void ide_input_swap_data(int dev, ulong *sect_buf, int words);
+void ide_input_data(int dev, ulong *sect_buf, int words);
+void ide_output_data(int dev, const ulong *sect_buf, int words);
+void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts);
+void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts);
+
+/**
+ * board_start_ide() - Start up the board IDE interfac
+ *
+ * @return 0 if ok
+ */
+int board_start_ide(void);
+
 #endif /* _IDE_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/image.h u-boot-2011.06/include/image.h
--- u-boot-2011.06_original/include/image.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/image.h	2014-10-23 14:13:09.830008000 +0800
@@ -168,7 +168,7 @@
 #define IH_COMP_LZO		4	/* lzo   Compression Used	*/
 
 #define IH_MAGIC	0x27051956	/* Image Magic Number		*/
-#define IH_NMLEN		32	/* Image Name Length		*/
+#define IH_NMLEN		30	/* Image Name Length		*/
 
 /*
  * Legacy format image header,
@@ -187,6 +187,7 @@
 	uint8_t		ih_type;	/* Image Type			*/
 	uint8_t		ih_comp;	/* Compression Type		*/
 	uint8_t		ih_name[IH_NMLEN];	/* Image Name		*/
+    uint16_t    ih_ver;     /* Image version number, 256 max */
 } image_header_t;
 
 typedef struct image_info {
@@ -373,6 +374,13 @@
 image_get_hdr_l (ep)		/* image_get_ep */
 image_get_hdr_l (dcrc)		/* image_get_dcrc */
 
+#define image_get_hdr_s(f) \
+	static inline uint16_t image_get_##f(const image_header_t *hdr) \
+	{ \
+		return be16_to_cpu (hdr->ih_##f); \
+	}
+image_get_hdr_s (ver)       /* image_get_ver */
+
 #define image_get_hdr_b(f) \
 	static inline uint8_t image_get_##f(const image_header_t *hdr) \
 	{ \
@@ -431,6 +439,13 @@
 image_set_hdr_l (ep)		/* image_set_ep */
 image_set_hdr_l (dcrc)		/* image_set_dcrc */
 
+#define image_set_hdr_s(f) \
+	static inline void image_set_##f(image_header_t *hdr, uint16_t val) \
+	{ \
+		hdr->ih_##f = cpu_to_be16 (val); \
+	}
+image_set_hdr_s (ver)      /* image_set_ver */
+
 #define image_set_hdr_b(f) \
 	static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
 	{ \
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/linux/usb/ch9.h u-boot-2011.06/include/linux/usb/ch9.h
--- u-boot-2011.06_original/include/linux/usb/ch9.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/linux/usb/ch9.h	2014-07-29 17:28:38.819972000 +0800
@@ -28,15 +28,14 @@
  * [c] for consistency, removing all doubt even when it appears to
  *     someone that the two other points are non-issues for that
  *     particular descriptor type.
- *
- * Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and
- *                      Remy Bohmer <linux@bohmer.net>
  */
 
 #ifndef __LINUX_USB_CH9_H
 #define __LINUX_USB_CH9_H
 
 #include <linux/types.h>	/* __u8 etc */
+#include <asm/byteorder.h>	/* le16_to_cpu */
+#include <asm/unaligned.h>	/* get_unaligned() */
 
 /*-------------------------------------------------------------------------*/
 
@@ -70,7 +69,7 @@
 #define USB_RECIP_OTHER			0x03
 /* From Wireless USB 1.0 */
 #define USB_RECIP_PORT			0x04
-#define USB_RECIP_RPIPE			0x05
+#define USB_RECIP_RPIPE		0x05
 
 /*
  * Standard requests, for the bRequest field of a SETUP packet.
@@ -90,6 +89,8 @@
 #define USB_REQ_GET_INTERFACE		0x0A
 #define USB_REQ_SET_INTERFACE		0x0B
 #define USB_REQ_SYNCH_FRAME		0x0C
+#define USB_REQ_SET_SEL			0x30
+#define USB_REQ_SET_ISOCH_DELAY		0x31
 
 #define USB_REQ_SET_ENCRYPTION		0x0D	/* Wireless USB */
 #define USB_REQ_GET_ENCRYPTION		0x0E
@@ -105,10 +106,16 @@
 #define USB_REQ_LOOPBACK_DATA_READ	0x16
 #define USB_REQ_SET_INTERFACE_DS	0x17
 
+/* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command,
+ * used by hubs to put ports into a new L1 suspend state, except that it
+ * forgot to define its number ...
+ */
+
 /*
  * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
  * are read as a bit array returned by USB_REQ_GET_STATUS.  (So there
- * are at most sixteen features of each type.)
+ * are at most sixteen features of each type.)  Hubs may also support a
+ * new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend.
  */
 #define USB_DEVICE_SELF_POWERED		0	/* (read only) */
 #define USB_DEVICE_REMOTE_WAKEUP	1	/* dev may initiate wakeup */
@@ -120,8 +127,38 @@
 #define USB_DEVICE_A_ALT_HNP_SUPPORT	5	/* (otg) other RH port does */
 #define USB_DEVICE_DEBUG_MODE		6	/* (special devices only) */
 
+/*
+ * Test Mode Selectors
+ * See USB 2.0 spec Table 9-7
+ */
+#define	TEST_J		1
+#define	TEST_K		2
+#define	TEST_SE0_NAK	3
+#define	TEST_PACKET	4
+#define	TEST_FORCE_EN	5
+
+/*
+ * New Feature Selectors as added by USB 3.0
+ * See USB 3.0 spec Table 9-6
+ */
+#define USB_DEVICE_U1_ENABLE	48	/* dev may initiate U1 transition */
+#define USB_DEVICE_U2_ENABLE	49	/* dev may initiate U2 transition */
+#define USB_DEVICE_LTM_ENABLE	50	/* dev may send LTM */
+#define USB_INTRF_FUNC_SUSPEND	0	/* function suspend */
+
+#define USB_INTR_FUNC_SUSPEND_OPT_MASK	0xFF00
+/*
+ * Suspend Options, Table 9-7 USB 3.0 spec
+ */
+#define USB_INTRF_FUNC_SUSPEND_LP	(1 << (8 + 0))
+#define USB_INTRF_FUNC_SUSPEND_RW	(1 << (8 + 1))
+
 #define USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */
 
+/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
+#define USB_DEV_STAT_U1_ENABLED		2	/* transition into U1 state */
+#define USB_DEV_STAT_U2_ENABLED		3	/* transition into U2 state */
+#define USB_DEV_STAT_LTM_ENABLED	4	/* Latency tolerance messages */
 
 /**
  * struct usb_ctrlrequest - SETUP data for a USB device control request
@@ -140,10 +177,6 @@
  * For most devices, interfaces don't coordinate with each other, so
  * such requests may be made at any time.
  */
-#if defined(__BIG_ENDIAN) || defined(__ARMEB__)
-#error (functionality not verified for big endian targets, todo...)
-#endif
-
 struct usb_ctrlrequest {
 	__u8 bRequestType;
 	__u8 bRequest;
@@ -159,8 +192,12 @@
  * (rarely) accepted by SET_DESCRIPTOR.
  *
  * Note that all multi-byte values here are encoded in little endian
- * byte order "on the wire".  But when exposed through Linux-USB APIs,
- * they've been converted to cpu byte order.
+ * byte order "on the wire".  Within the kernel and when exposed
+ * through the Linux-USB APIs, they are not converted to cpu byte
+ * order; it is the responsibility of the client code to do this.
+ * The single exception is when device and configuration descriptors (but
+ * not other descriptors) are read from usbfs (i.e. /proc/bus/usb/BBB/DDD);
+ * in this case the fields are converted to host endianness by the kernel.
  */
 
 /*
@@ -187,6 +224,11 @@
 #define USB_DT_WIRELESS_ENDPOINT_COMP	0x11
 #define USB_DT_WIRE_ADAPTER		0x21
 #define USB_DT_RPIPE			0x22
+#define USB_DT_CS_RADIO_CONTROL		0x23
+/* From the T10 UAS specification */
+#define USB_DT_PIPE_USAGE		0x24
+/* From the USB 3.0 spec */
+#define	USB_DT_SS_ENDPOINT_COMP		0x30
 
 /* Conventional codes for class-specific descriptors.  The convention is
  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
@@ -252,6 +294,8 @@
 #define USB_CLASS_APP_SPEC		0xfe
 #define USB_CLASS_VENDOR_SPEC		0xff
 
+#define USB_SUBCLASS_VENDOR_SPEC	0xff
+
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_CONFIG: Configuration descriptor information.
@@ -349,6 +393,254 @@
 #define USB_ENDPOINT_XFER_INT		3
 #define USB_ENDPOINT_MAX_ADJUSTABLE	0x80
 
+/* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep type. */
+#define USB_ENDPOINT_INTRTYPE		0x30
+#define USB_ENDPOINT_INTR_PERIODIC	(0 << 4)
+#define USB_ENDPOINT_INTR_NOTIFICATION	(1 << 4)
+
+#define USB_ENDPOINT_SYNCTYPE		0x0c
+#define USB_ENDPOINT_SYNC_NONE		(0 << 2)
+#define USB_ENDPOINT_SYNC_ASYNC		(1 << 2)
+#define USB_ENDPOINT_SYNC_ADAPTIVE	(2 << 2)
+#define USB_ENDPOINT_SYNC_SYNC		(3 << 2)
+
+#define USB_ENDPOINT_USAGE_MASK		0x30
+#define USB_ENDPOINT_USAGE_DATA		0x00
+#define USB_ENDPOINT_USAGE_FEEDBACK	0x10
+#define USB_ENDPOINT_USAGE_IMPLICIT_FB	0x20	/* Implicit feedback Data endpoint */
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_endpoint_num - get the endpoint's number
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's number: 0 to 15.
+ */
+static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
+{
+	return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+}
+
+/**
+ * usb_endpoint_type - get the endpoint's transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
+ * to @epd's transfer type.
+ */
+static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
+{
+	return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+/**
+ * usb_endpoint_dir_in - check if the endpoint has IN direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type IN, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
+}
+
+/**
+ * usb_endpoint_dir_out - check if the endpoint has OUT direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type OUT, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_out(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
+}
+
+/**
+ * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type bulk, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_bulk(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_BULK);
+}
+
+/**
+ * usb_endpoint_xfer_control - check if the endpoint has control transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type control, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_control(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_CONTROL);
+}
+
+/**
+ * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type interrupt, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_int(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_INT);
+}
+
+/**
+ * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type isochronous, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_isoc(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_ISOC);
+}
+
+/**
+ * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_in(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_out(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_in(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_out(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_in(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_out(
+				const struct usb_endpoint_descriptor *epd)
+{
+	return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_maxp - get endpoint's max packet size
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's max packet
+ */
+static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
+{
+	return __le16_to_cpu(get_unaligned(&epd->wMaxPacketSize));
+}
+
+static inline int usb_endpoint_interrupt_type(
+		const struct usb_endpoint_descriptor *epd)
+{
+	return epd->bmAttributes & USB_ENDPOINT_INTRTYPE;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */
+struct usb_ss_ep_comp_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bMaxBurst;
+	__u8  bmAttributes;
+	__le16 wBytesPerInterval;
+} __attribute__ ((packed));
+
+#define USB_DT_SS_EP_COMP_SIZE		6
+
+/* Bits 4:0 of bmAttributes if this is a bulk endpoint */
+static inline int
+usb_ss_max_streams(const struct usb_ss_ep_comp_descriptor *comp)
+{
+	int		max_streams;
+
+	if (!comp)
+		return 0;
+
+	max_streams = comp->bmAttributes & 0x1f;
+
+	if (!max_streams)
+		return 0;
+
+	max_streams = 1 << max_streams;
+
+	return max_streams;
+}
+
+/* Bits 1:0 of bmAttributes if this is an isoc endpoint */
+#define USB_SS_MULT(p)			(1 + ((p) & 0x3))
 
 /*-------------------------------------------------------------------------*/
 
@@ -455,7 +747,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* USB_DT_BOS:  group of wireless capabilities */
+/* USB_DT_BOS:  group of device-level capabilities */
 struct usb_bos_descriptor {
 	__u8  bLength;
 	__u8  bDescriptorType;
@@ -464,6 +756,7 @@
 	__u8  bNumDeviceCaps;
 } __attribute__((packed));
 
+#define USB_DT_BOS_SIZE		5
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_DEVICE_CAPABILITY:  grouped with BOS */
@@ -501,6 +794,61 @@
 	__u8  bReserved;
 } __attribute__((packed));
 
+/* USB 2.0 Extension descriptor */
+#define	USB_CAP_TYPE_EXT		2
+
+struct usb_ext_cap_descriptor {		/* Link Power Management */
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+	__le32 bmAttributes;
+#define USB_LPM_SUPPORT			(1 << 1)	/* supports LPM */
+#define USB_BESL_SUPPORT		(1 << 2)	/* supports BESL */
+#define USB_BESL_BASELINE_VALID		(1 << 3)	/* Baseline BESL valid*/
+#define USB_BESL_DEEP_VALID		(1 << 4)	/* Deep BESL valid */
+#define USB_GET_BESL_BASELINE(p)	(((p) & (0xf << 8)) >> 8)
+#define USB_GET_BESL_DEEP(p)		(((p) & (0xf << 12)) >> 12)
+} __attribute__((packed));
+
+#define USB_DT_USB_EXT_CAP_SIZE	7
+
+/*
+ * SuperSpeed USB Capability descriptor: Defines the set of SuperSpeed USB
+ * specific device level capabilities
+ */
+#define		USB_SS_CAP_TYPE		3
+struct usb_ss_cap_descriptor {		/* Link Power Management */
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+	__u8  bmAttributes;
+#define USB_LTM_SUPPORT			(1 << 1) /* supports LTM */
+	__le16 wSpeedSupported;
+#define USB_LOW_SPEED_OPERATION		(1)	 /* Low speed operation */
+#define USB_FULL_SPEED_OPERATION	(1 << 1) /* Full speed operation */
+#define USB_HIGH_SPEED_OPERATION	(1 << 2) /* High speed operation */
+#define USB_5GBPS_OPERATION		(1 << 3) /* Operation at 5Gbps */
+	__u8  bFunctionalitySupport;
+	__u8  bU1devExitLat;
+	__le16 bU2DevExitLat;
+} __attribute__((packed));
+
+#define USB_DT_USB_SS_CAP_SIZE	10
+
+/*
+ * Container ID Capability descriptor: Defines the instance unique ID used to
+ * identify the instance across all operating modes
+ */
+#define	CONTAINER_ID_TYPE	4
+struct usb_ss_container_id_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+	__u8  bReserved;
+	__u8  ContainerID[16]; /* 128-bit number */
+} __attribute__((packed));
+
+#define USB_DT_USB_SS_CONTN_ID_SIZE	20
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
@@ -558,9 +906,22 @@
 	USB_SPEED_UNKNOWN = 0,			/* enumerating */
 	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
 	USB_SPEED_HIGH,				/* usb 2.0 */
-	USB_SPEED_VARIABLE,			/* wireless (usb 2.5) */
+	USB_SPEED_WIRELESS,			/* wireless (usb 2.5) */
+	USB_SPEED_SUPER,			/* usb 3.0 */
 };
 
+#ifdef __KERNEL__
+
+/**
+ * usb_speed_string() - Returns human readable-name of the speed.
+ * @speed: The speed to return human-readable name for.  If it's not
+ *   any of the speeds defined in usb_device_speed enum, string for
+ *   USB_SPEED_UNKNOWN will be returned.
+ */
+extern const char *usb_speed_string(enum usb_device_speed speed);
+
+#endif
+
 enum usb_device_state {
 	/* NOTATTACHED isn't in the USB spec, and this state acts
 	 * the same as ATTACHED ... but it's clearer this way.
@@ -570,8 +931,8 @@
 	/* chapter 9 and authentication (wireless) device states */
 	USB_STATE_ATTACHED,
 	USB_STATE_POWERED,			/* wired */
-	USB_STATE_UNAUTHENTICATED,		/* auth */
 	USB_STATE_RECONNECTING,			/* auth */
+	USB_STATE_UNAUTHENTICATED,		/* auth */
 	USB_STATE_DEFAULT,			/* limited function */
 	USB_STATE_ADDRESS,
 	USB_STATE_CONFIGURED,			/* most functions */
@@ -581,7 +942,64 @@
 	/* NOTE:  there are actually four different SUSPENDED
 	 * states, returning to POWERED, DEFAULT, ADDRESS, or
 	 * CONFIGURED respectively when SOF tokens flow again.
+	 * At this level there's no difference between L1 and L2
+	 * suspend states.  (L2 being original USB 1.1 suspend.)
 	 */
 };
 
-#endif	/* __LINUX_USB_CH9_H */
+enum usb3_link_state {
+	USB3_LPM_U0 = 0,
+	USB3_LPM_U1,
+	USB3_LPM_U2,
+	USB3_LPM_U3
+};
+
+/*
+ * A U1 timeout of 0x0 means the parent hub will reject any transitions to U1.
+ * 0xff means the parent hub will accept transitions to U1, but will not
+ * initiate a transition.
+ *
+ * A U1 timeout of 0x1 to 0x7F also causes the hub to initiate a transition to
+ * U1 after that many microseconds.  Timeouts of 0x80 to 0xFE are reserved
+ * values.
+ *
+ * A U2 timeout of 0x0 means the parent hub will reject any transitions to U2.
+ * 0xff means the parent hub will accept transitions to U2, but will not
+ * initiate a transition.
+ *
+ * A U2 timeout of 0x1 to 0xFE also causes the hub to initiate a transition to
+ * U2 after N*256 microseconds.  Therefore a U2 timeout value of 0x1 means a U2
+ * idle timer of 256 microseconds, 0x2 means 512 microseconds, 0xFE means
+ * 65.024ms.
+ */
+#define USB3_LPM_DISABLED		0x0
+#define USB3_LPM_U1_MAX_TIMEOUT		0x7F
+#define USB3_LPM_U2_MAX_TIMEOUT		0xFE
+#define USB3_LPM_DEVICE_INITIATED	0xFF
+
+struct usb_set_sel_req {
+	__u8	u1_sel;
+	__u8	u1_pel;
+	__le16	u2_sel;
+	__le16	u2_pel;
+} __attribute__ ((packed));
+
+/*
+ * The Set System Exit Latency control transfer provides one byte each for
+ * U1 SEL and U1 PEL, so the max exit latency is 0xFF.  U2 SEL and U2 PEL each
+ * are two bytes long.
+ */
+#define USB3_LPM_MAX_U1_SEL_PEL		0xFF
+#define USB3_LPM_MAX_U2_SEL_PEL		0xFFFF
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * As per USB compliance update, a device that is actively drawing
+ * more than 100mA from USB must report itself as bus-powered in
+ * the GetStatus(DEVICE) call.
+ * http://compliance.usb.org/index.asp?UpdateFile=Electrical&Format=Standard#34
+ */
+#define USB_SELF_POWER_VBUS_MAX_DRAW		100
+
+#endif /* __LINUX_USB_CH9_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/md.h u-boot-2011.06/include/md.h
--- u-boot-2011.06_original/include/md.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/md.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,378 @@
+/**
+ * \file md.h
+ *
+ * \brief Generic message digest wrapper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_MD_H
+#define POLARSSL_MD_H
+
+#include <linux/string.h>
+
+#if defined(_MSC_VER) && !defined(inline)
+#define inline _inline
+#else
+#if defined(__ARMCC_VERSION) && !defined(inline)
+#define inline __inline
+#endif /* __ARMCC_VERSION */
+#endif /*_MSC_VER */
+
+#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE                -0x5080  /**< The selected feature is not available. */
+#define POLARSSL_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
+#define POLARSSL_ERR_MD_ALLOC_FAILED                       -0x5180  /**< Failed to allocate memory. */
+#define POLARSSL_ERR_MD_FILE_IO_ERROR                      -0x5200  /**< Opening or reading of file failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    POLARSSL_MD_NONE=0,
+    POLARSSL_MD_MD2,
+    POLARSSL_MD_MD4,
+    POLARSSL_MD_MD5,
+    POLARSSL_MD_SHA1,
+    POLARSSL_MD_SHA224,
+    POLARSSL_MD_SHA256,
+    POLARSSL_MD_SHA384,
+    POLARSSL_MD_SHA512,
+    POLARSSL_MD_RIPEMD160,
+} md_type_t;
+
+#if defined(POLARSSL_SHA512_C)
+#define POLARSSL_MD_MAX_SIZE         64  /* longest known is SHA512 */
+#else
+#define POLARSSL_MD_MAX_SIZE         32  /* longest known is SHA256 or less */
+#endif
+
+/**
+ * Message digest information. Allows message digest functions to be called
+ * in a generic way.
+ */
+typedef struct {
+    /** Digest identifier */
+    md_type_t type;
+
+    /** Name of the message digest */
+    const char * name;
+
+    /** Output length of the digest function */
+    int size;
+
+    /** Digest initialisation function */
+    void (*starts_func)( void *ctx );
+
+    /** Digest update function */
+    void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
+
+    /** Digest finalisation function */
+    void (*finish_func)( void *ctx, unsigned char *output );
+
+    /** Generic digest function */
+    void (*digest_func)( const unsigned char *input, size_t ilen,
+                         unsigned char *output );
+
+    /** Generic file digest function */
+    int (*file_func)( const char *path, unsigned char *output );
+
+    /** HMAC Initialisation function */
+    void (*hmac_starts_func)( void *ctx, const unsigned char *key,
+                              size_t keylen );
+
+    /** HMAC update function */
+    void (*hmac_update_func)( void *ctx, const unsigned char *input,
+                              size_t ilen );
+
+    /** HMAC finalisation function */
+    void (*hmac_finish_func)( void *ctx, unsigned char *output);
+
+    /** HMAC context reset function */
+    void (*hmac_reset_func)( void *ctx );
+
+    /** Generic HMAC function */
+    void (*hmac_func)( const unsigned char *key, size_t keylen,
+                       const unsigned char *input, size_t ilen,
+                       unsigned char *output );
+
+    /** Allocate a new context */
+    void * (*ctx_alloc_func)( void );
+
+    /** Free the given context */
+    void (*ctx_free_func)( void *ctx );
+
+    /** Internal use only */
+    void (*process_func)( void *ctx, const unsigned char *input );
+} md_info_t;
+
+/**
+ * Generic message digest context.
+ */
+typedef struct {
+    /** Information about the associated message digest */
+    const md_info_t *md_info;
+
+    /** Digest-specific context */
+    void *md_ctx;
+} md_context_t;
+
+#define MD_CONTEXT_T_INIT { \
+    NULL, /* md_info */ \
+    NULL, /* md_ctx */ \
+}
+
+/**
+ * \brief Returns the list of digests supported by the generic digest module.
+ *
+ * \return          a statically allocated array of digests, the last entry
+ *                  is 0.
+ */
+const int *md_list( void );
+
+/**
+ * \brief           Returns the message digest information associated with the
+ *                  given digest name.
+ *
+ * \param md_name   Name of the digest to search for.
+ *
+ * \return          The message digest information associated with md_name or
+ *                  NULL if not found.
+ */
+const md_info_t *md_info_from_string( const char *md_name );
+
+/**
+ * \brief           Returns the message digest information associated with the
+ *                  given digest type.
+ *
+ * \param md_type   type of digest to search for.
+ *
+ * \return          The message digest information associated with md_type or
+ *                  NULL if not found.
+ */
+const md_info_t *md_info_from_type( md_type_t md_type );
+
+/**
+ * \brief          Initialises and fills the message digest context structure
+ *                 with the appropriate values.
+ *
+ * \param ctx      context to initialise. May not be NULL. The
+ *                 digest-specific context (ctx->md_ctx) must be NULL. It will
+ *                 be allocated, and must be freed using md_free_ctx() later.
+ * \param md_info  message digest to use.
+ *
+ * \returns        \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on
+ *                 parameter failure, \c POLARSSL_ERR_MD_ALLOC_FAILED if
+ *                 allocation of the digest-specific context failed.
+ */
+int md_init_ctx( md_context_t *ctx, const md_info_t *md_info );
+
+/**
+ * \brief          Free the message-specific context of ctx. Freeing ctx itself
+ *                 remains the responsibility of the caller.
+ *
+ * \param ctx      Free the message-specific context
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_free_ctx( md_context_t *ctx );
+
+/**
+ * \brief           Returns the size of the message digest output.
+ *
+ * \param md_info   message digest info
+ *
+ * \return          size of the message digest output.
+ */
+static inline unsigned char md_get_size( const md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( 0 );
+
+    return md_info->size;
+}
+
+/**
+ * \brief           Returns the type of the message digest output.
+ *
+ * \param md_info   message digest info
+ *
+ * \return          type of the message digest output.
+ */
+static inline md_type_t md_get_type( const md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( POLARSSL_MD_NONE );
+
+    return md_info->type;
+}
+
+/**
+ * \brief           Returns the name of the message digest output.
+ *
+ * \param md_info   message digest info
+ *
+ * \return          name of the message digest output.
+ */
+static inline const char *md_get_name( const md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( NULL );
+
+    return md_info->name;
+}
+
+/**
+ * \brief          Set-up the given context for a new message digest
+ *
+ * \param ctx      generic message digest context.
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_starts( md_context_t *ctx );
+
+/**
+ * \brief          Generic message digest process buffer
+ *
+ * \param ctx      Generic message digest context
+ * \param input    buffer holding the  datal
+ * \param ilen     length of the input data
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
+
+/**
+ * \brief          Generic message digest final digest
+ *
+ * \param ctx      Generic message digest context
+ * \param output   Generic message digest checksum result
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_finish( md_context_t *ctx, unsigned char *output );
+
+/**
+ * \brief          Output = message_digest( input buffer )
+ *
+ * \param md_info  message digest info
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   Generic message digest checksum result
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
+        unsigned char *output );
+
+/**
+ * \brief          Output = message_digest( file contents )
+ *
+ * \param md_info  message digest info
+ * \param path     input file name
+ * \param output   generic message digest checksum result
+ *
+ * \return         0 if successful, POLARSSL_ERR_MD_FILE_OPEN_FAILED if fopen
+ *                 failed, POLARSSL_ERR_MD_FILE_READ_FAILED if fread failed,
+ *                 POLARSSL_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
+ */
+int md_file( const md_info_t *md_info, const char *path,
+             unsigned char *output );
+
+/**
+ * \brief          Generic HMAC context setup
+ *
+ * \param ctx      HMAC context to be initialized
+ * \param key      HMAC secret key
+ * \param keylen   length of the HMAC key
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_hmac_starts( md_context_t *ctx, const unsigned char *key,
+                    size_t keylen );
+
+/**
+ * \brief          Generic HMAC process buffer
+ *
+ * \param ctx      HMAC context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_hmac_update( md_context_t *ctx, const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief          Generic HMAC final digest
+ *
+ * \param ctx      HMAC context
+ * \param output   Generic HMAC checksum result
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_hmac_finish( md_context_t *ctx, unsigned char *output);
+
+/**
+ * \brief          Generic HMAC context reset
+ *
+ * \param ctx      HMAC context to be reset
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_hmac_reset( md_context_t *ctx );
+
+/**
+ * \brief          Output = Generic_HMAC( hmac key, input buffer )
+ *
+ * \param md_info  message digest info
+ * \param key      HMAC secret key
+ * \param keylen   length of the HMAC key
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   Generic HMAC-result
+ *
+ * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                 verification fails.
+ */
+int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output );
+
+/* Internal use */
+int md_process( md_context_t *ctx, const unsigned char *data );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* POLARSSL_MD_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/md_wrap.h u-boot-2011.06/include/md_wrap.h
--- u-boot-2011.06_original/include/md_wrap.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/md_wrap.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,71 @@
+/**
+ * \file md_wrap.h
+ *
+ * \brief Message digest wrappers.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2011, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_MD_WRAP_H
+#define POLARSSL_MD_WRAP_H
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(POLARSSL_MD2_C)
+extern const md_info_t md2_info;
+#endif
+#if defined(POLARSSL_MD4_C)
+extern const md_info_t md4_info;
+#endif
+#if defined(POLARSSL_MD5_C)
+extern const md_info_t md5_info;
+#endif
+#if defined(POLARSSL_RIPEMD160_C)
+extern const md_info_t ripemd160_info;
+#endif
+#if defined(POLARSSL_SHA1_C)
+extern const md_info_t sha1_info;
+#endif
+#if defined(POLARSSL_SHA256_C)
+extern const md_info_t sha224_info;
+extern const md_info_t sha256_info;
+#endif
+#if defined(POLARSSL_SHA512_C)
+extern const md_info_t sha384_info;
+extern const md_info_t sha512_info;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* POLARSSL_MD_WRAP_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/mmc.h u-boot-2011.06/include/mmc.h
--- u-boot-2011.06_original/include/mmc.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/mmc.h	2014-07-29 17:28:38.819972000 +0800
@@ -27,24 +27,35 @@
 #define _MMC_H_
 
 #include <linux/list.h>
+#include <linux/compiler.h>
 
 #define SD_VERSION_SD	0x20000
-#define SD_VERSION_2	(SD_VERSION_SD | 0x20)
-#define SD_VERSION_1_0	(SD_VERSION_SD | 0x10)
-#define SD_VERSION_1_10	(SD_VERSION_SD | 0x1a)
+#define SD_VERSION_3	(SD_VERSION_SD | 0x300)
+#define SD_VERSION_2	(SD_VERSION_SD | 0x200)
+#define SD_VERSION_1_0	(SD_VERSION_SD | 0x100)
+#define SD_VERSION_1_10	(SD_VERSION_SD | 0x10a)
 #define MMC_VERSION_MMC		0x10000
 #define MMC_VERSION_UNKNOWN	(MMC_VERSION_MMC)
-#define MMC_VERSION_1_2		(MMC_VERSION_MMC | 0x12)
-#define MMC_VERSION_1_4		(MMC_VERSION_MMC | 0x14)
-#define MMC_VERSION_2_2		(MMC_VERSION_MMC | 0x22)
-#define MMC_VERSION_3		(MMC_VERSION_MMC | 0x30)
-#define MMC_VERSION_4		(MMC_VERSION_MMC | 0x40)
+#define MMC_VERSION_1_2		(MMC_VERSION_MMC | 0x102)
+#define MMC_VERSION_1_4		(MMC_VERSION_MMC | 0x104)
+#define MMC_VERSION_2_2		(MMC_VERSION_MMC | 0x202)
+#define MMC_VERSION_3		(MMC_VERSION_MMC | 0x300)
+#define MMC_VERSION_4		(MMC_VERSION_MMC | 0x400)
+#define MMC_VERSION_4_1		(MMC_VERSION_MMC | 0x401)
+#define MMC_VERSION_4_2		(MMC_VERSION_MMC | 0x402)
+#define MMC_VERSION_4_3		(MMC_VERSION_MMC | 0x403)
+#define MMC_VERSION_4_41	(MMC_VERSION_MMC | 0x429)
+#define MMC_VERSION_4_5		(MMC_VERSION_MMC | 0x405)
 
 #define MMC_MODE_HS		0x001
 #define MMC_MODE_HS_52MHz	0x010
 #define MMC_MODE_4BIT		0x100
 #define MMC_MODE_8BIT		0x200
 #define MMC_MODE_SPI		0x400
+#define MMC_MODE_HC		0x800
+
+#define MMC_MODE_MASK_WIDTH_BITS (MMC_MODE_4BIT | MMC_MODE_8BIT)
+#define MMC_MODE_WIDTH_BITS_SHIFT 8
 
 #define SD_DATA_4BIT	0x00040000
 
@@ -57,6 +68,7 @@
 #define UNUSABLE_ERR		-17 /* Unusable Card */
 #define COMM_ERR		-18 /* Communications Error */
 #define TIMEOUT			-19
+#define IN_PROGRESS		-20 /* operation is in progress */
 
 #define MMC_CMD_GO_IDLE_STATE		0
 #define MMC_CMD_SEND_OP_COND		1
@@ -75,15 +87,25 @@
 #define MMC_CMD_READ_MULTIPLE_BLOCK	18
 #define MMC_CMD_WRITE_SINGLE_BLOCK	24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
+#define MMC_CMD_ERASE_GROUP_START	35
+#define MMC_CMD_ERASE_GROUP_END		36
+#define MMC_CMD_ERASE			38
 #define MMC_CMD_APP_CMD			55
 #define MMC_CMD_SPI_READ_OCR		58
 #define MMC_CMD_SPI_CRC_ON_OFF		59
+#define MMC_CMD_RES_MAN			62
+
+#define MMC_CMD62_ARG1			0xefac62ec
+#define MMC_CMD62_ARG2			0xcbaea7
+
 
 #define SD_CMD_SEND_RELATIVE_ADDR	3
 #define SD_CMD_SWITCH_FUNC		6
 #define SD_CMD_SEND_IF_COND		8
 
 #define SD_CMD_APP_SET_BUS_WIDTH	6
+#define SD_CMD_ERASE_WR_BLK_START	32
+#define SD_CMD_ERASE_WR_BLK_END		33
 #define SD_CMD_APP_SEND_OP_COND		41
 #define SD_CMD_APP_SEND_SCR		51
 
@@ -99,11 +121,15 @@
 #define OCR_VOLTAGE_MASK	0x007FFF80
 #define OCR_ACCESS_MODE		0x60000000
 
+#define SECURE_ERASE		0x80000000
+
 #define MMC_STATUS_MASK		(~0x0206BF7F)
 #define MMC_STATUS_RDY_FOR_DATA (1 << 8)
 #define MMC_STATUS_CURR_STATE	(0xf << 9)
 #define MMC_STATUS_ERROR	(1 << 19)
 
+#define MMC_STATE_PRG		(7 << 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 */
 #define MMC_VDD_21_22		0x00000200	/* VDD voltage 2.1 ~ 2.2 */
@@ -137,13 +163,20 @@
 /*
  * EXT_CSD fields
  */
-
-#define EXT_CSD_PART_CONF	179	/* R/W */
-#define EXT_CSD_BUS_WIDTH	183	/* R/W */
-#define EXT_CSD_HS_TIMING	185	/* R/W */
-#define EXT_CSD_CARD_TYPE	196	/* RO */
-#define EXT_CSD_REV		192	/* RO */
-#define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
+#define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
+#define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_RPMB_MULT		168	/* RO */
+#define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
+#define EXT_CSD_BOOT_BUS_WIDTH		177
+#define EXT_CSD_PART_CONF		179	/* R/W */
+#define EXT_CSD_BUS_WIDTH		183	/* R/W */
+#define EXT_CSD_HS_TIMING		185	/* R/W */
+#define EXT_CSD_REV			192	/* RO */
+#define EXT_CSD_CARD_TYPE		196	/* RO */
+#define EXT_CSD_SEC_CNT			212	/* RO, 4 bytes */
+#define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
+#define EXT_CSD_BOOT_MULT		226	/* RO */
 
 /*
  * EXT_CSD field definitions
@@ -160,6 +193,16 @@
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
 
+#define EXT_CSD_BOOT_ACK_ENABLE			(1 << 6)
+#define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
+#define EXT_CSD_PARTITION_ACCESS_ENABLE		(1 << 0)
+#define EXT_CSD_PARTITION_ACCESS_DISABLE	(0 << 0)
+
+#define EXT_CSD_BOOT_ACK(x)		(x << 6)
+#define EXT_CSD_BOOT_PART_NUM(x)	(x << 3)
+#define EXT_CSD_PARTITION_ACCESS(x)	(x << 0)
+
+
 #define R1_ILLEGAL_COMMAND		(1 << 22)
 #define R1_APP_CMD			(1 << 5)
 
@@ -184,6 +227,14 @@
 #define PART_ACCESS_MASK	(0x7)
 #define PART_SUPPORT		(0x1)
 
+/* Maximum block size for MMC */
+#define MMC_MAX_BLOCK_LEN	512
+
+/* The number of MMC physical partitions.  These consist of:
+ * boot partitions (2), general purpose partitions (4) in MMC v4.4.
+ */
+#define MMC_NUM_BOOT_PARTITION	2
+
 struct mmc_cid {
 	unsigned long psn;
 	unsigned short oid;
@@ -193,62 +244,11 @@
 	char pnm[7];
 };
 
-/*
- * WARNING!
- *
- * This structure is used by atmel_mci.c only.
- * It works for the AVR32 architecture but NOT
- * for ARM/AT91 architectures.
- * Its use is highly depreciated.
- * After the atmel_mci.c driver for AVR32 has
- * been replaced this structure will be removed.
- */
-struct mmc_csd
-{
-	u8	csd_structure:2,
-		spec_vers:4,
-		rsvd1:2;
-	u8	taac;
-	u8	nsac;
-	u8	tran_speed;
-	u16	ccc:12,
-		read_bl_len:4;
-	u64	read_bl_partial:1,
-		write_blk_misalign:1,
-		read_blk_misalign:1,
-		dsr_imp:1,
-		rsvd2:2,
-		c_size:12,
-		vdd_r_curr_min:3,
-		vdd_r_curr_max:3,
-		vdd_w_curr_min:3,
-		vdd_w_curr_max:3,
-		c_size_mult:3,
-		sector_size:5,
-		erase_grp_size:5,
-		wp_grp_size:5,
-		wp_grp_enable:1,
-		default_ecc:2,
-		r2w_factor:3,
-		write_bl_len:4,
-		write_bl_partial:1,
-		rsvd3:5;
-	u8	file_format_grp:1,
-		copy:1,
-		perm_write_protect:1,
-		tmp_write_protect:1,
-		file_format:2,
-		ecc:2;
-	u8	crc:7;
-	u8	one:1;
-};
-
 struct mmc_cmd {
 	ushort cmdidx;
 	uint resp_type;
 	uint cmdarg;
 	uint response[4];
-	uint flags;
 };
 
 struct mmc_data {
@@ -285,13 +285,24 @@
 	uint tran_speed;
 	uint read_bl_len;
 	uint write_bl_len;
+	uint erase_grp_size;
 	u64 capacity;
+	u64 capacity_user;
+	u64 capacity_boot;
+	u64 capacity_rpmb;
+	u64 capacity_gp[4];
 	block_dev_desc_t block_dev;
 	int (*send_cmd)(struct mmc *mmc,
 			struct mmc_cmd *cmd, struct mmc_data *data);
 	void (*set_ios)(struct mmc *mmc);
 	int (*init)(struct mmc *mmc);
+	int (*getcd)(struct mmc *mmc);
+	int (*getwp)(struct mmc *mmc);
 	uint b_max;
+	char op_cond_pending;	/* 1 if we are waiting on an op_cond command */
+	char init_in_progress;	/* 1 if we have done mmc_start_init() */
+	char preinit;		/* start init as early as possible */
+	uint op_cond_response;	/* the response byte from the last op_cond */
 };
 
 int mmc_register(struct mmc *mmc);
@@ -303,11 +314,43 @@
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
-int board_mmc_getcd(u8 *cd, struct mmc *mmc);
+int board_mmc_getcd(struct mmc *mmc);
 int mmc_switch_part(int dev_num, unsigned int part_num);
+int mmc_getcd(struct mmc *mmc);
+int mmc_getwp(struct mmc *mmc);
+void spl_mmc_load(void) __noreturn;
+/* Function to change the size of boot partition and rpmb partitions */
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+					unsigned long rpmbsize);
+/* Function to send commands to open/close the specified boot partition */
+int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access);
+
+/**
+ * Start device initialization and return immediately; it does not block on
+ * polling OCR (operation condition register) status.  Then you should call
+ * mmc_init, which would block on polling OCR status and complete the device
+ * initializatin.
+ *
+ * @param mmc	Pointer to a MMC device struct
+ * @return 0 on success, IN_PROGRESS on waiting for OCR status, <0 on error.
+ */
+int mmc_start_init(struct mmc *mmc);
+
+/**
+ * Set preinit flag of mmc device.
+ *
+ * This will cause the device to be pre-inited during mmc_initialize(),
+ * which may save boot time if the device is not accessed until later.
+ * Some eMMC devices take 200-300ms to init, but unfortunately they
+ * must be sent a series of commands to even get them to start preparing
+ * for operation.
+ *
+ * @param mmc		Pointer to a MMC device struct
+ * @param preinit	preinit flag value
+ */
+void mmc_set_preinit(struct mmc *mmc, int preinit);
 
 #ifdef CONFIG_GENERIC_MMC
-int atmel_mci_init(void *regs);
 #define mmc_host_is_spi(mmc)	((mmc)->host_caps & MMC_MODE_SPI)
 struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
 #else
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/net.h u-boot-2011.06/include/net.h
--- u-boot-2011.06_original/include/net.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/net.h	2014-07-29 17:28:38.819972000 +0800
@@ -117,6 +117,7 @@
 
 extern int eth_initialize(bd_t *bis);	/* Initialize network subsystem */
 extern int eth_register(struct eth_device* dev);/* Register network device */
+extern int eth_unregister(struct eth_device *dev);/* Remove network device */
 extern void eth_try_another(int first_restart);	/* Change the device */
 #ifdef CONFIG_NET_MULTI
 extern void eth_set_current(void);		/* set nterface to ethcur var */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/ns16550.h u-boot-2011.06/include/ns16550.h
--- u-boot-2011.06_original/include/ns16550.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/ns16550.h	2014-07-29 17:28:38.819972000 +0800
@@ -20,7 +20,17 @@
  * Note that the following macro magic uses the fact that the compiler
  * will not allocate storage for arrays of size 0
  */
-
+#ifdef CONFIG_ARCH_CNC1900  
+#if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
+#error "Please define NS16550 registers size."
+#elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
+#define UART_REG(x)						   \
+	volatile unsigned int x;
+#elif (CONFIG_SYS_NS16550_REG_SIZE < 0)
+#define UART_REG(x)							\
+	volatile unsigned int x;
+#endif
+#else
 #if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
 #error "Please define NS16550 registers size."
 #elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
@@ -32,6 +42,7 @@
 	unsigned char x;						\
 	unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
 #endif
+#endif
 
 struct NS16550 {
 	UART_REG(rbr);		/* 0 */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/oid.h u-boot-2011.06/include/oid.h
--- u-boot-2011.06_original/include/oid.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/oid.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,553 @@
+/**
+ * \file oid.h
+ *
+ * \brief Object Identifier (OID) database
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_OID_H
+#define POLARSSL_OID_H
+
+#include <linux/string.h>
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+#include "asn1.h"
+#include "pk.h"
+#if defined(POLARSSL_CIPHER_C)
+#include "cipher.h"
+#endif
+
+#if defined(POLARSSL_MD_C)
+#include "md.h"
+#endif
+
+#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
+#include "x509.h"
+#endif
+
+#define POLARSSL_ERR_OID_NOT_FOUND                         -0x002E  /**< OID is not found. */
+#define POLARSSL_ERR_OID_BUF_TOO_SMALL                     -0x000B  /**< output buffer is too small */
+
+/*
+ * Top level OID tuples
+ */
+#define OID_ISO_MEMBER_BODIES           "\x2a"          /* {iso(1) member-body(2)} */
+#define OID_ISO_IDENTIFIED_ORG          "\x2b"          /* {iso(1) identified-organization(3)} */
+#define OID_ISO_CCITT_DS                "\x55"          /* {joint-iso-ccitt(2) ds(5)} */
+#define OID_ISO_ITU_COUNTRY             "\x60"          /* {joint-iso-itu-t(2) country(16)} */
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define OID_COUNTRY_US                  "\x86\x48"      /* {us(840)} */
+#define OID_ORG_RSA_DATA_SECURITY       "\x86\xf7\x0d"  /* {rsadsi(113549)} */
+#define OID_RSA_COMPANY                 OID_ISO_MEMBER_BODIES OID_COUNTRY_US \
+                                        OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
+#define OID_ORG_ANSI_X9_62              "\xce\x3d" /* ansi-X9-62(10045) */
+#define OID_ANSI_X9_62                  OID_ISO_MEMBER_BODIES OID_COUNTRY_US \
+                                        OID_ORG_ANSI_X9_62
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define OID_ORG_DOD                     "\x06"          /* {dod(6)} */
+#define OID_ORG_OIW                     "\x0e"
+#define OID_OIW_SECSIG                  OID_ORG_OIW "\x03"
+#define OID_OIW_SECSIG_ALG              OID_OIW_SECSIG "\x02"
+#define OID_OIW_SECSIG_SHA1             OID_OIW_SECSIG_ALG "\x1a"
+#define OID_ORG_CERTICOM                "\x81\x04"  /* certicom(132) */
+#define OID_CERTICOM                    OID_ISO_IDENTIFIED_ORG OID_ORG_CERTICOM
+#define OID_ORG_TELETRUST               "\x24" /* teletrust(36) */
+#define OID_TELETRUST                   OID_ISO_IDENTIFIED_ORG OID_ORG_TELETRUST
+
+/*
+ * ISO ITU OID parts
+ */
+#define OID_ORGANIZATION                "\x01"          /* {organization(1)} */
+#define OID_ISO_ITU_US_ORG              OID_ISO_ITU_COUNTRY OID_COUNTRY_US OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */
+
+#define OID_ORG_GOV                     "\x65"          /* {gov(101)} */
+#define OID_GOV                         OID_ISO_ITU_US_ORG OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */
+
+#define OID_ORG_NETSCAPE                "\x86\xF8\x42"  /* {netscape(113730)} */
+#define OID_NETSCAPE                    OID_ISO_ITU_US_ORG OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */
+
+/* ISO arc for standard certificate and CRL extensions */
+#define OID_ID_CE                       OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER  ::=  {joint-iso-ccitt(2) ds(5) 29} */
+
+/**
+ * Private Internet Extensions
+ * { iso(1) identified-organization(3) dod(6) internet(1)
+ *                      security(5) mechanisms(5) pkix(7) }
+ */
+#define OID_PKIX                        OID_ISO_IDENTIFIED_ORG OID_ORG_DOD "\x01\x05\x05\x07"
+
+/*
+ * Arc for standard naming attributes
+ */
+#define OID_AT                          OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */
+#define OID_AT_CN                       OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */
+#define OID_AT_SUR_NAME                 OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */
+#define OID_AT_SERIAL_NUMBER            OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */
+#define OID_AT_COUNTRY                  OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */
+#define OID_AT_LOCALITY                 OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */
+#define OID_AT_STATE                    OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */
+#define OID_AT_ORGANIZATION             OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */
+#define OID_AT_ORG_UNIT                 OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */
+#define OID_AT_TITLE                    OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */
+#define OID_AT_POSTAL_ADDRESS           OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */
+#define OID_AT_POSTAL_CODE              OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */
+#define OID_AT_GIVEN_NAME               OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
+#define OID_AT_INITIALS                 OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
+#define OID_AT_GENERATION_QUALIFIER     OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
+#define OID_AT_DN_QUALIFIER             OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
+#define OID_AT_PSEUDONYM                OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
+
+#define OID_DOMAIN_COMPONENT            "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
+
+/*
+ * OIDs for standard certificate extensions
+ */
+#define OID_AUTHORITY_KEY_IDENTIFIER    OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 } */
+#define OID_SUBJECT_KEY_IDENTIFIER      OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 } */
+#define OID_KEY_USAGE                   OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 } */
+#define OID_CERTIFICATE_POLICIES        OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 } */
+#define OID_POLICY_MAPPINGS             OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 } */
+#define OID_SUBJECT_ALT_NAME            OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 } */
+#define OID_ISSUER_ALT_NAME             OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 } */
+#define OID_SUBJECT_DIRECTORY_ATTRS     OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 } */
+#define OID_BASIC_CONSTRAINTS           OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 } */
+#define OID_NAME_CONSTRAINTS            OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 } */
+#define OID_POLICY_CONSTRAINTS          OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 } */
+#define OID_EXTENDED_KEY_USAGE          OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
+#define OID_CRL_DISTRIBUTION_POINTS     OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 } */
+#define OID_INIHIBIT_ANYPOLICY          OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 } */
+#define OID_FRESHEST_CRL                OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 } */
+
+/*
+ * Netscape certificate extensions
+ */
+#define OID_NS_CERT                 OID_NETSCAPE "\x01"
+#define OID_NS_CERT_TYPE            OID_NS_CERT  "\x01"
+#define OID_NS_BASE_URL             OID_NS_CERT  "\x02"
+#define OID_NS_REVOCATION_URL       OID_NS_CERT  "\x03"
+#define OID_NS_CA_REVOCATION_URL    OID_NS_CERT  "\x04"
+#define OID_NS_RENEWAL_URL          OID_NS_CERT  "\x07"
+#define OID_NS_CA_POLICY_URL        OID_NS_CERT  "\x08"
+#define OID_NS_SSL_SERVER_NAME      OID_NS_CERT  "\x0C"
+#define OID_NS_COMMENT              OID_NS_CERT  "\x0D"
+#define OID_NS_DATA_TYPE            OID_NETSCAPE "\x02"
+#define OID_NS_CERT_SEQUENCE        OID_NS_DATA_TYPE "\x05"
+
+/*
+ * OIDs for CRL extensions
+ */
+#define OID_PRIVATE_KEY_USAGE_PERIOD    OID_ID_CE "\x10"
+#define OID_CRL_NUMBER                  OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
+
+/*
+ * X.509 v3 Extended key usage OIDs
+ */
+#define OID_ANY_EXTENDED_KEY_USAGE      OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
+
+#define OID_KP                          OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
+#define OID_SERVER_AUTH                 OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
+#define OID_CLIENT_AUTH                 OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
+#define OID_CODE_SIGNING                OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
+#define OID_EMAIL_PROTECTION            OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
+#define OID_TIME_STAMPING               OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
+#define OID_OCSP_SIGNING                OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
+
+/*
+ * PKCS definition OIDs
+ */
+
+#define OID_PKCS                OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
+#define OID_PKCS1               OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
+#define OID_PKCS5               OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
+#define OID_PKCS9               OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
+#define OID_PKCS12              OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
+
+/*
+ * PKCS#1 OIDs
+ */
+#define OID_PKCS1_RSA           OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
+#define OID_PKCS1_MD2           OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */
+#define OID_PKCS1_MD4           OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */
+#define OID_PKCS1_MD5           OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
+#define OID_PKCS1_SHA1          OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
+#define OID_PKCS1_SHA224        OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
+#define OID_PKCS1_SHA256        OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */
+#define OID_PKCS1_SHA384        OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */
+#define OID_PKCS1_SHA512        OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */
+
+#define OID_RSA_SHA_OBS         "\x2B\x0E\x03\x02\x1D"
+
+#define OID_PKCS9_EMAIL         OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */
+
+/*
+ * Digest algorithms
+ */
+#define OID_DIGEST_ALG_MD2              OID_RSA_COMPANY "\x02\x02" /**< id-md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */
+#define OID_DIGEST_ALG_MD4              OID_RSA_COMPANY "\x02\x04" /**< id-md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
+#define OID_DIGEST_ALG_MD5              OID_RSA_COMPANY "\x02\x05" /**< id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
+#define OID_DIGEST_ALG_SHA1             OID_ISO_IDENTIFIED_ORG OID_OIW_SECSIG_SHA1 /**< id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
+#define OID_DIGEST_ALG_SHA224           OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
+#define OID_DIGEST_ALG_SHA256           OID_GOV "\x03\x04\x02\x01" /**< id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
+
+#define OID_DIGEST_ALG_SHA384           OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
+
+#define OID_DIGEST_ALG_SHA512           OID_GOV "\x03\x04\x02\x03" /**< id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+
+#define OID_HMAC_SHA1                   OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+
+/*
+ * Encryption algorithms
+ */
+#define OID_DES_CBC                     OID_ISO_IDENTIFIED_ORG OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
+#define OID_DES_EDE3_CBC                OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
+
+/*
+ * PKCS#5 OIDs
+ */
+#define OID_PKCS5_PBKDF2                OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
+#define OID_PKCS5_PBES2                 OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */
+#define OID_PKCS5_PBMAC1                OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */
+
+/*
+ * PKCS#5 PBES1 algorithms
+ */
+#define OID_PKCS5_PBE_MD2_DES_CBC       OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */
+#define OID_PKCS5_PBE_MD2_RC2_CBC       OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */
+#define OID_PKCS5_PBE_MD5_DES_CBC       OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
+#define OID_PKCS5_PBE_MD5_RC2_CBC       OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
+#define OID_PKCS5_PBE_SHA1_DES_CBC      OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
+#define OID_PKCS5_PBE_SHA1_RC2_CBC      OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
+
+/*
+ * PKCS#8 OIDs
+ */
+#define OID_PKCS9_CSR_EXT_REQ           OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
+
+/*
+ * PKCS#12 PBE OIDs
+ */
+#define OID_PKCS12_PBE                      OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
+
+#define OID_PKCS12_PBE_SHA1_RC4_128         OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */
+#define OID_PKCS12_PBE_SHA1_RC4_40          OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */
+#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC    OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
+#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC    OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
+#define OID_PKCS12_PBE_SHA1_RC2_128_CBC     OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
+#define OID_PKCS12_PBE_SHA1_RC2_40_CBC      OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */
+
+/*
+ * EC key algorithms from RFC 5480
+ */
+
+/* id-ecPublicKey OBJECT IDENTIFIER ::= {
+ *       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */
+#define OID_EC_ALG_UNRESTRICTED         OID_ANSI_X9_62 "\x02\01"
+
+/*   id-ecDH OBJECT IDENTIFIER ::= {
+ *     iso(1) identified-organization(3) certicom(132)
+ *     schemes(1) ecdh(12) } */
+#define OID_EC_ALG_ECDH                 OID_CERTICOM "\x01\x0c"
+
+/*
+ * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
+ */
+
+/* secp192r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */
+#define OID_EC_GRP_SECP192R1        OID_ANSI_X9_62 "\x03\x01\x01"
+
+/* secp224r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 33 } */
+#define OID_EC_GRP_SECP224R1        OID_CERTICOM "\x00\x21"
+
+/* secp256r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */
+#define OID_EC_GRP_SECP256R1        OID_ANSI_X9_62 "\x03\x01\x07"
+
+/* secp384r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 34 } */
+#define OID_EC_GRP_SECP384R1        OID_CERTICOM "\x00\x22"
+
+/* secp521r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
+#define OID_EC_GRP_SECP521R1        OID_CERTICOM "\x00\x23"
+
+/* secp192k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
+#define OID_EC_GRP_SECP192K1        OID_CERTICOM "\x00\x1f"
+
+/* secp224k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
+#define OID_EC_GRP_SECP224K1        OID_CERTICOM "\x00\x20"
+
+/* secp256k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
+#define OID_EC_GRP_SECP256K1        OID_CERTICOM "\x00\x0a"
+
+/* RFC 5639 4.1
+ * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
+ * identified-organization(3) teletrust(36) algorithm(3) signature-
+ * algorithm(3) ecSign(2) 8}
+ * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1}
+ * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */
+#define OID_EC_BRAINPOOL_V1         OID_TELETRUST "\x03\x03\x02\x08\x01\x01"
+
+/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */
+#define OID_EC_GRP_BP256R1          OID_EC_BRAINPOOL_V1 "\x07"
+
+/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */
+#define OID_EC_GRP_BP384R1          OID_EC_BRAINPOOL_V1 "\x0B"
+
+/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */
+#define OID_EC_GRP_BP512R1          OID_EC_BRAINPOOL_V1 "\x0D"
+
+/*
+ * SEC1 C.1
+ *
+ * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
+ * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)}
+ */
+#define OID_ANSI_X9_62_FIELD_TYPE   OID_ANSI_X9_62 "\x01"
+#define OID_ANSI_X9_62_PRIME_FIELD  OID_ANSI_X9_62_FIELD_TYPE "\x01"
+
+/*
+ * ECDSA signature identifiers, from RFC 5480
+ */
+#define OID_ANSI_X9_62_SIG          OID_ANSI_X9_62 "\x04" /* signatures(4) */
+#define OID_ANSI_X9_62_SIG_SHA2     OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */
+
+/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */
+#define OID_ECDSA_SHA1              OID_ANSI_X9_62_SIG "\x01"
+
+/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 1 } */
+#define OID_ECDSA_SHA224            OID_ANSI_X9_62_SIG_SHA2 "\x01"
+
+/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 2 } */
+#define OID_ECDSA_SHA256            OID_ANSI_X9_62_SIG_SHA2 "\x02"
+
+/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 3 } */
+#define OID_ECDSA_SHA384            OID_ANSI_X9_62_SIG_SHA2 "\x03"
+
+/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 4 } */
+#define OID_ECDSA_SHA512            OID_ANSI_X9_62_SIG_SHA2 "\x04"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Base OID descriptor structure
+ */
+typedef struct {
+    const char *asn1;               /*!< OID ASN.1 representation       */
+    size_t asn1_len;                /*!< length of asn1                 */
+    const char *name;               /*!< official name (e.g. from RFC)  */
+    const char *description;        /*!< human friendly description     */
+} oid_descriptor_t;
+
+#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
+/**
+ * \brief          Translate an X.509 extension OID into local values
+ *
+ * \param oid      OID to use
+ * \param ext_type place to store the extension type
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_x509_ext_type( const asn1_buf *oid, int *ext_type );
+#endif
+
+/**
+ * \brief          Translate an X.509 attribute type OID into the short name
+ *                 (e.g. the OID for an X520 Common Name into "CN")
+ *
+ * \param oid      OID to use
+ * \param short_name    place to store the string pointer
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_attr_short_name( const asn1_buf *oid, const char **short_name );
+
+/**
+ * \brief          Translate PublicKeyAlgorithm OID into pk_type
+ *
+ * \param oid      OID to use
+ * \param pk_alg   place to store public key algorithm
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg );
+
+/**
+ * \brief          Translate pk_type into PublicKeyAlgorithm OID
+ *
+ * \param pk_alg   Public key type to look for
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_oid_by_pk_alg( pk_type_t pk_alg,
+                           const char **oid, size_t *olen );
+
+#if defined(POLARSSL_ECP_C)
+/**
+ * \brief          Translate NamedCurve OID into an EC group identifier
+ *
+ * \param oid      OID to use
+ * \param grp_id   place to store group id
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_ec_grp( const asn1_buf *oid, ecp_group_id *grp_id );
+
+/**
+ * \brief          Translate EC group identifier into NamedCurve OID
+ *
+ * \param grp_id   EC group identifier
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_oid_by_ec_grp( ecp_group_id grp_id,
+                           const char **oid, size_t *olen );
+#endif /* POLARSSL_ECP_C */
+
+#if defined(POLARSSL_MD_C)
+/**
+ * \brief          Translate SignatureAlgorithm OID into md_type and pk_type
+ *
+ * \param oid      OID to use
+ * \param md_alg   place to store message digest algorithm
+ * \param pk_alg   place to store public key algorithm
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_sig_alg( const asn1_buf *oid,
+                     md_type_t *md_alg, pk_type_t *pk_alg );
+
+/**
+ * \brief          Translate SignatureAlgorithm OID into description
+ *
+ * \param oid      OID to use
+ * \param desc     place to store string pointer
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_sig_alg_desc( const asn1_buf *oid, const char **desc );
+
+/**
+ * \brief          Translate md_type and pk_type into SignatureAlgorithm OID
+ *
+ * \param md_alg   message digest algorithm
+ * \param pk_alg   public key algorithm
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_oid_by_sig_alg( pk_type_t pk_alg, md_type_t md_alg,
+                            const char **oid, size_t *olen );
+
+/**
+ * \brief          Translate hash algorithm OID into md_type
+ *
+ * \param oid      OID to use
+ * \param md_alg   place to store message digest algorithm
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_md_alg( const asn1_buf *oid, md_type_t *md_alg );
+#endif /* POLARSSL_MD_C */
+
+/**
+ * \brief          Translate Extended Key Usage OID into description
+ *
+ * \param oid      OID to use
+ * \param desc     place to store string pointer
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_extended_key_usage( const asn1_buf *oid, const char **desc );
+
+/**
+ * \brief          Translate md_type into hash algorithm OID
+ *
+ * \param md_alg   message digest algorithm
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_oid_by_md( md_type_t md_alg, const char **oid, size_t *olen );
+
+#if defined(POLARSSL_CIPHER_C)
+/**
+ * \brief          Translate encryption algorithm OID into cipher_type
+ *
+ * \param oid           OID to use
+ * \param cipher_alg    place to store cipher algorithm
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_cipher_alg( const asn1_buf *oid, cipher_type_t *cipher_alg );
+#endif /* POLARSSL_CIPHER_C */
+
+#if defined(POLARSSL_PKCS12_C)
+/**
+ * \brief          Translate PKCS#12 PBE algorithm OID into md_type and
+ *                 cipher_type
+ *
+ * \param oid           OID to use
+ * \param md_alg        place to store message digest algorithm
+ * \param cipher_alg    place to store cipher algorithm
+ *
+ * \return         0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
+ */
+int oid_get_pkcs12_pbe_alg( const asn1_buf *oid, md_type_t *md_alg,
+                            cipher_type_t *cipher_alg );
+#endif /* POLARSSL_PKCS12_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* oid.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/part_efi.h u-boot-2011.06/include/part_efi.h
--- u-boot-2011.06_original/include/part_efi.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/part_efi.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 RuggedCom, Inc.
+ * Richard Retanubun <RichardRetanubun@RuggedCom.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * See also linux/fs/partitions/efi.h
+ *
+ * EFI GUID Partition Table
+ * Per Intel EFI Specification v1.02
+ * http://developer.intel.com/technology/efi/efi.htm
+*/
+
+#include <linux/compiler.h>
+
+#ifndef _DISK_PART_EFI_H
+#define _DISK_PART_EFI_H
+
+#define MSDOS_MBR_SIGNATURE 0xAA55
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+
+#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
+#define GPT_HEADER_REVISION_V1 0x00010000
+#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
+#define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS		128
+#define GPT_ENTRY_SIZE			128
+
+#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+	((efi_guid_t) \
+	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+		(b) & 0xff, ((b) >> 8) & 0xff, \
+		(c) & 0xff, ((c) >> 8) & 0xff, \
+		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
+#define PARTITION_SYSTEM_GUID \
+	EFI_GUID( 0xC12A7328, 0xF81F, 0x11d2, \
+		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
+#define LEGACY_MBR_PARTITION_GUID \
+	EFI_GUID( 0x024DEE41, 0x33E7, 0x11d3, \
+		0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
+#define PARTITION_MSFT_RESERVED_GUID \
+	EFI_GUID( 0xE3C9E316, 0x0B5C, 0x4DB8, \
+		0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
+#define PARTITION_BASIC_DATA_GUID \
+	EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \
+		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
+#define PARTITION_LINUX_RAID_GUID \
+	EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \
+		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
+#define PARTITION_LINUX_SWAP_GUID \
+	EFI_GUID( 0x0657fd6d, 0xa4ab, 0x43c4, \
+		0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
+#define PARTITION_LINUX_LVM_GUID \
+	EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
+		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+
+/* linux/include/efi.h */
+typedef u16 efi_char16_t;
+
+typedef struct {
+	u8 b[16];
+} efi_guid_t;
+
+/* based on linux/include/genhd.h */
+struct partition {
+	u8 boot_ind;		/* 0x80 - active */
+	u8 head;		/* starting head */
+	u8 sector;		/* starting sector */
+	u8 cyl;			/* starting cylinder */
+	u8 sys_ind;		/* What partition type */
+	u8 end_head;		/* end head */
+	u8 end_sector;		/* end sector */
+	u8 end_cyl;		/* end cylinder */
+	__le32 start_sect;	/* starting sector counting from 0 */
+	__le32 nr_sects;	/* nr of sectors in partition */
+} __packed;
+
+/* based on linux/fs/partitions/efi.h */
+typedef struct _gpt_header {
+	__le64 signature;
+	__le32 revision;
+	__le32 header_size;
+	__le32 header_crc32;
+	__le32 reserved1;
+	__le64 my_lba;
+	__le64 alternate_lba;
+	__le64 first_usable_lba;
+	__le64 last_usable_lba;
+	efi_guid_t disk_guid;
+	__le64 partition_entry_lba;
+	__le32 num_partition_entries;
+	__le32 sizeof_partition_entry;
+	__le32 partition_entry_array_crc32;
+} __packed gpt_header;
+
+typedef union _gpt_entry_attributes {
+	struct {
+		u64 required_to_function:1;
+		u64 no_block_io_protocol:1;
+		u64 legacy_bios_bootable:1;
+		u64 reserved:45;
+		u64 type_guid_specific:16;
+	} fields;
+	unsigned long long raw;
+} __packed gpt_entry_attributes;
+
+#define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
+typedef struct _gpt_entry {
+	efi_guid_t partition_type_guid;
+	efi_guid_t unique_partition_guid;
+	__le64 starting_lba;
+	__le64 ending_lba;
+	gpt_entry_attributes attributes;
+	efi_char16_t partition_name[PARTNAME_SZ];
+} __packed gpt_entry;
+
+typedef struct _legacy_mbr {
+	u8 boot_code[440];
+	__le32 unique_mbr_signature;
+	__le16 unknown;
+	struct partition partition_record[4];
+	__le16 signature;
+} __packed legacy_mbr;
+
+#endif	/* _DISK_PART_EFI_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/part.h u-boot-2011.06/include/part.h
--- u-boot-2011.06_original/include/part.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/part.h	2014-07-29 17:28:38.819972000 +0800
@@ -36,22 +36,34 @@
 #ifdef CONFIG_LBA48
 	unsigned char	lba48;		/* device can use 48bit addr (ATA/ATAPI v7) */
 #endif
-	lbaint_t		lba;		/* number of blocks */
+	lbaint_t	lba;		/* number of blocks */
 	unsigned long	blksz;		/* block size */
+	int		log2blksz;	/* for convenience: log2(blksz) */
 	char		vendor [40+1];	/* IDE model, SCSI Vendor */
 	char		product[20+1];	/* IDE Serial no, SCSI product */
 	char		revision[8+1];	/* firmware revision */
 	unsigned long	(*block_read)(int dev,
-				      unsigned long start,
+				      lbaint_t start,
 				      lbaint_t blkcnt,
 				      void *buffer);
 	unsigned long	(*block_write)(int dev,
-				       unsigned long start,
+				       lbaint_t start,
 				       lbaint_t blkcnt,
 				       const void *buffer);
+	unsigned long   (*block_erase)(int dev,
+				       lbaint_t start,
+				       lbaint_t blkcnt);
 	void		*priv;		/* driver private struct pointer */
 }block_dev_desc_t;
 
+#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz))
+#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \
+	(PAD_SIZE(size, block_dev_desc->blksz))
+#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
+		 ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
+		 ((x & 0xffff0000) ? 16 : 0))
+#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
+
 /* Interface types: */
 #define IF_TYPE_UNKNOWN		0
 #define IF_TYPE_IDE		1
@@ -90,10 +102,15 @@
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
+	int	bootable;	/* Active/Bootable flag is set		*/
+#ifdef CONFIG_PARTITION_UUIDS
+	char	uuid[37];	/* filesystem UUID as string, if exists	*/
+#endif
 } disk_partition_t;
 
 /* Misc _get_dev functions */
-block_dev_desc_t* get_dev(char* ifname, int dev);
+#ifdef CONFIG_PARTITIONS
+block_dev_desc_t *get_dev(const char *ifname, int dev);
 block_dev_desc_t* ide_get_dev(int dev);
 block_dev_desc_t* sata_get_dev(int dev);
 block_dev_desc_t* scsi_get_dev(int dev);
@@ -107,7 +124,37 @@
 void print_part (block_dev_desc_t *dev_desc);
 void  init_part (block_dev_desc_t *dev_desc);
 void dev_print(block_dev_desc_t *dev_desc);
-
+int get_device(const char *ifname, const char *dev_str,
+	       block_dev_desc_t **dev_desc);
+int get_device_and_partition(const char *ifname, const char *dev_part_str,
+			     block_dev_desc_t **dev_desc,
+			     disk_partition_t *info, int allow_whole_dev);
+#else
+static inline block_dev_desc_t *get_dev(const char *ifname, int dev)
+{ return NULL; }
+static inline block_dev_desc_t* ide_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* sata_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* scsi_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* usb_stor_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* mmc_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* systemace_get_dev(int dev) { return NULL; }
+static inline block_dev_desc_t* mg_disk_get_dev(int dev) { return NULL; }
+
+static inline int get_partition_info (block_dev_desc_t * dev_desc, int part,
+	disk_partition_t *info) { return -1; }
+static inline void print_part (block_dev_desc_t *dev_desc) {}
+static inline void  init_part (block_dev_desc_t *dev_desc) {}
+static inline void dev_print(block_dev_desc_t *dev_desc) {}
+static inline int get_device(const char *ifname, const char *dev_str,
+	       block_dev_desc_t **dev_desc)
+{ return -1; }
+static inline int get_device_and_partition(const char *ifname,
+					   const char *dev_part_str,
+					   block_dev_desc_t **dev_desc,
+					   disk_partition_t *info,
+					   int allow_whole_dev)
+{ *dev_desc = NULL; return -1; }
+#endif
 
 #ifdef CONFIG_MAC_PARTITION
 /* disk/part_mac.c */
@@ -138,10 +185,62 @@
 #endif
 
 #ifdef CONFIG_EFI_PARTITION
+#include <part_efi.h>
 /* disk/part_efi.c */
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+
+/**
+ * write_gpt_table() - Write the GUID Partition Table to disk
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - pointer to GPT header representation
+ * @param gpt_e - pointer to GPT partition table entries
+ *
+ * @return - zero on success, otherwise error
+ */
+int write_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e);
+
+/**
+ * gpt_fill_pte(): Fill the GPT partition table entry
+ *
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ *
+ * @return zero on success
+ */
+int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+		disk_partition_t *partitions, int parts);
+
+/**
+ * gpt_fill_header(): Fill the GPT header
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ * @param str_guid - disk guid string representation
+ * @param parts_count - number of partitions
+ *
+ * @return - error on str_guid conversion error
+ */
+int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+		char *str_guid, int parts_count);
+
+/**
+ * gpt_restore(): Restore GPT partition table
+ *
+ * @param dev_desc - block device descriptor
+ * @param str_disk_guid - disk GUID
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ *
+ * @return zero on success
+ */
+int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
+		disk_partition_t *partitions, const int parts_count);
 #endif
 
 #endif /* _PART_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/pk.h u-boot-2011.06/include/pk.h
--- u-boot-2011.06_original/include/pk.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/pk.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,574 @@
+/**
+ * \file pk.h
+ *
+ * \brief Public Key abstraction layer
+ *
+ *  Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+
+#ifndef POLARSSL_PK_H
+#define POLARSSL_PK_H
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#if defined(POLARSSL_RSA_C)
+#include "rsa.h"
+#endif
+
+#if defined(POLARSSL_ECP_C)
+#include "ecp.h"
+#endif
+
+#if defined(POLARSSL_ECDSA_C)
+#include "ecdsa.h"
+#endif
+
+#define POLARSSL_ERR_PK_MALLOC_FAILED       -0x2F80  /**< Memory alloation failed. */
+#define POLARSSL_ERR_PK_TYPE_MISMATCH       -0x2F00  /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
+#define POLARSSL_ERR_PK_BAD_INPUT_DATA      -0x2E80  /**< Bad input parameters to function. */
+#define POLARSSL_ERR_PK_FILE_IO_ERROR       -0x2E00  /**< Read/write of file failed. */
+#define POLARSSL_ERR_PK_KEY_INVALID_VERSION -0x2D80  /**< Unsupported key version */
+#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT  -0x2D00  /**< Invalid key tag or value. */
+#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG      -0x2C80  /**< Key algorithm is unsupported (only RSA and EC are supported). */
+#define POLARSSL_ERR_PK_PASSWORD_REQUIRED   -0x2C00  /**< Private key password can't be empty. */
+#define POLARSSL_ERR_PK_PASSWORD_MISMATCH   -0x2B80  /**< Given private key password does not allow for correct decryption. */
+#define POLARSSL_ERR_PK_INVALID_PUBKEY      -0x2B00  /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
+#define POLARSSL_ERR_PK_INVALID_ALG         -0x2A80  /**< The algorithm tag or value is invalid. */
+#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE -0x2A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
+#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE -0x2980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
+#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH    -0x2000  /**< The signature is valid but its length is less than expected. */
+
+
+#if defined(POLARSSL_RSA_C)
+/**
+ * Quick access to an RSA context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an RSA context
+ * before using this macro!
+ */
+#define pk_rsa( pk )        ( (rsa_context *) (pk).pk_ctx )
+#endif /* POLARSSL_RSA_C */
+
+#if defined(POLARSSL_ECP_C)
+/**
+ * Quick access to an EC context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an EC context
+ * before using this macro!
+ */
+#define pk_ec( pk )         ( (ecp_keypair *) (pk).pk_ctx )
+#endif /* POLARSSL_ECP_C */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Public key types
+ */
+typedef enum {
+    POLARSSL_PK_NONE=0,
+    POLARSSL_PK_RSA,
+    POLARSSL_PK_ECKEY,
+    POLARSSL_PK_ECKEY_DH,
+    POLARSSL_PK_ECDSA,
+    POLARSSL_PK_RSA_ALT,
+} pk_type_t;
+
+/**
+ * \brief           Types for interfacing with the debug module
+ */
+typedef enum
+{
+    POLARSSL_PK_DEBUG_NONE = 0,
+    POLARSSL_PK_DEBUG_MPI,
+    POLARSSL_PK_DEBUG_ECP,
+} pk_debug_type;
+
+/**
+ * \brief           Item to send to the debug module
+ */
+typedef struct
+{
+    pk_debug_type type;
+    const char *name;
+    void *value;
+} pk_debug_item;
+
+/** Maximum number of item send for debugging, plus 1 */
+#define POLARSSL_PK_DEBUG_MAX_ITEMS 3
+
+/**
+ * \brief           Public key information and operations
+ */
+typedef struct
+{
+    /** Public key type */
+    pk_type_t type;
+
+    /** Type name */
+    const char *name;
+
+    /** Get key size in bits */
+    size_t (*get_size)( const void * );
+
+    /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
+    int (*can_do)( pk_type_t type );
+
+    /** Verify signature */
+    int (*verify_func)( void *ctx, md_type_t md_alg,
+                        const unsigned char *hash, size_t hash_len,
+                        const unsigned char *sig, size_t sig_len );
+
+    /** Make signature */
+    int (*sign_func)( void *ctx, md_type_t md_alg,
+                      const unsigned char *hash, size_t hash_len,
+                      unsigned char *sig, size_t *sig_len,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+    /** Decrypt message */
+    int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen, size_t osize,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+    /** Encrypt message */
+    int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen, size_t osize,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+    /** Allocate a new context */
+    void * (*ctx_alloc_func)( void );
+
+    /** Free the given context */
+    void (*ctx_free_func)( void *ctx );
+
+    /** Interface with the debug module */
+    void (*debug_func)( const void *ctx, pk_debug_item *items );
+
+} pk_info_t;
+
+/**
+ * \brief           Public key container
+ */
+typedef struct
+{
+    const pk_info_t *   pk_info;    /**< Public key informations        */
+    void *              pk_ctx;     /**< Underlying public key context  */
+} pk_context;
+
+/**
+ * \brief           Types for RSA-alt abstraction
+ */
+typedef int (*pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
+                    const unsigned char *input, unsigned char *output,
+                    size_t output_max_len );
+typedef int (*pk_rsa_alt_sign_func)( void *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                    int mode, md_type_t md_alg, unsigned int hashlen,
+                    const unsigned char *hash, unsigned char *sig );
+typedef size_t (*pk_rsa_alt_key_len_func)( void *ctx );
+
+/**
+ * \brief           Return information associated with the given PK type
+ *
+ * \param pk_type   PK type to search for.
+ *
+ * \return          The PK info associated with the type or NULL if not found.
+ */
+const pk_info_t *pk_info_from_type( pk_type_t pk_type );
+
+/**
+ * \brief           Initialize a pk_context (as NONE)
+ */
+void pk_init( pk_context *ctx );
+
+/**
+ * \brief           Free a pk_context
+ */
+void pk_free( pk_context *ctx );
+
+/**
+ * \brief           Initialize a PK context with the information given
+ *                  and allocates the type-specific PK subcontext.
+ *
+ * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param info      Information to use
+ *
+ * \return          0 on success,
+ *                  POLARSSL_ERR_PK_BAD_INPUT_DATA on invalid input,
+ *                  POLARSSL_ERR_PK_MALLOC_FAILED on allocation failure.
+ *
+ * \note            For contexts holding an RSA-alt key, use
+ *                  \c pk_init_ctx_rsa_alt() instead.
+ */
+int pk_init_ctx( pk_context *ctx, const pk_info_t *info );
+
+/**
+ * \brief           Initialize an RSA-alt context
+ *
+ * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param key       RSA key pointer
+ * \param decrypt_func  Decryption function
+ * \param sign_func     Signing function
+ * \param key_len_func  Function returning key length in bytes
+ *
+ * \return          0 on success, or POLARSSL_ERR_PK_BAD_INPUT_DATA if the
+ *                  context wasn't already initialized as RSA_ALT.
+ *
+ * \note            This function replaces \c pk_init_ctx() for RSA-alt.
+ */
+int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
+                         pk_rsa_alt_decrypt_func decrypt_func,
+                         pk_rsa_alt_sign_func sign_func,
+                         pk_rsa_alt_key_len_func key_len_func );
+
+/**
+ * \brief           Get the size in bits of the underlying key
+ *
+ * \param ctx       Context to use
+ *
+ * \return          Key size in bits, or 0 on error
+ */
+size_t pk_get_size( const pk_context *ctx );
+
+/**
+ * \brief           Get the length in bytes of the underlying key
+ * \param ctx       Context to use
+ *
+ * \return          Key length in bytes, or 0 on error
+ */
+static inline size_t pk_get_len( const pk_context *ctx )
+{
+    return( ( pk_get_size( ctx ) + 7 ) / 8 );
+}
+
+/**
+ * \brief           Tell if a context can do the operation given by type
+ *
+ * \param ctx       Context to test
+ * \param type      Target type
+ *
+ * \return          0 if context can't do the operations,
+ *                  1 otherwise.
+ */
+int pk_can_do( pk_context *ctx, pk_type_t type );
+
+/**
+ * \brief           Verify signature
+ *
+ * \param ctx       PK context to use
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Signature to verify
+ * \param sig_len   Signature length
+ *
+ * \return          0 on success (signature is valid),
+ *                  POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is
+ *                  valid but its actual length is less than sig_len,
+ *                  or a specific error code.
+ *
+ * \note            If hash_len is 0, then the length associated with md_alg
+ *                  is used instead, or an error returned if it is invalid.
+ *
+ * \note            md_alg may be POLARSSL_MD_NONE, only if hash_len != 0
+ */
+int pk_verify( pk_context *ctx, md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len );
+
+/**
+ * \brief           Make signature
+ *
+ * \param ctx       PK context to use
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Place to write the signature
+ * \param sig_len   Number of bytes written
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 on success, or a specific error code.
+ *
+ * \note            If hash_len is 0, then the length associated with md_alg
+ *                  is used instead, or an error returned if it is invalid.
+ *
+ * \note            md_alg may be POLARSSL_MD_NONE, only if hash_len != 0
+ */
+int pk_sign( pk_context *ctx, md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Decrypt message
+ *
+ * \param ctx       PK context to use
+ * \param input     Input to decrypt
+ * \param ilen      Input size
+ * \param output    Decrypted output
+ * \param olen      Decrypted message length
+ * \param osize     Size of the output buffer
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 on success, or a specific error code.
+ */
+int pk_decrypt( pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Encrypt message
+ *
+ * \param ctx       PK context to use
+ * \param input     Message to encrypt
+ * \param ilen      Message size
+ * \param output    Encrypted output
+ * \param olen      Encrypted output length
+ * \param osize     Size of the output buffer
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 on success, or a specific error code.
+ */
+int pk_encrypt( pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Export debug information
+ *
+ * \param ctx       Context to use
+ * \param items     Place to write debug items
+ *
+ * \return          0 on success or POLARSSL_ERR_PK_BAD_INPUT_DATA
+ */
+int pk_debug( const pk_context *ctx, pk_debug_item *items );
+
+/**
+ * \brief           Access the type name
+ *
+ * \param ctx       Context to use
+ *
+ * \return          Type name on success, or "invalid PK"
+ */
+const char * pk_get_name( const pk_context *ctx );
+
+/**
+ * \brief           Get the key type
+ *
+ * \param ctx       Context to use
+ *
+ * \return          Type on success, or POLARSSL_PK_NONE
+ */
+pk_type_t pk_get_type( const pk_context *ctx );
+
+#if defined(POLARSSL_PK_PARSE_C)
+/** \ingroup pk_module */
+/**
+ * \brief           Parse a private key
+ *
+ * \param ctx       key to be initialized
+ * \param key       input buffer
+ * \param keylen    size of the buffer
+ * \param pwd       password for decryption (optional)
+ * \param pwdlen    size of the password
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with pk_init() or reset with pk_free(). If you need a
+ *                  specific key type, check the result with pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int pk_parse_key( pk_context *ctx,
+                  const unsigned char *key, size_t keylen,
+                  const unsigned char *pwd, size_t pwdlen );
+
+/** \ingroup pk_module */
+/**
+ * \brief           Parse a public key
+ *
+ * \param ctx       key to be initialized
+ * \param key       input buffer
+ * \param keylen    size of the buffer
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with pk_init() or reset with pk_free(). If you need a
+ *                  specific key type, check the result with pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int pk_parse_public_key( pk_context *ctx,
+                         const unsigned char *key, size_t keylen );
+
+#if defined(POLARSSL_FS_IO)
+/** \ingroup pk_module */
+/**
+ * \brief           Load and parse a private key
+ *
+ * \param ctx       key to be initialized
+ * \param path      filename to read the private key from
+ * \param password  password to decrypt the file (can be NULL)
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with pk_init() or reset with pk_free(). If you need a
+ *                  specific key type, check the result with pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int pk_parse_keyfile( pk_context *ctx,
+                      const char *path, const char *password );
+
+/** \ingroup pk_module */
+/**
+ * \brief           Load and parse a public key
+ *
+ * \param ctx       key to be initialized
+ * \param path      filename to read the private key from
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with pk_init() or reset with pk_free(). If you need a
+ *                  specific key type, check the result with pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int pk_parse_public_keyfile( pk_context *ctx, const char *path );
+#endif /* POLARSSL_FS_IO */
+#endif /* POLARSSL_PK_PARSE_C */
+
+#if defined(POLARSSL_PK_WRITE_C)
+/**
+ * \brief           Write a private key to a PKCS#1 or SEC1 DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       private to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ */
+int pk_write_key_der( pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief           Write a public key to a SubjectPublicKeyInfo DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       public key to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ */
+int pk_write_pubkey_der( pk_context *ctx, unsigned char *buf, size_t size );
+
+#if defined(POLARSSL_PEM_WRITE_C)
+/**
+ * \brief           Write a public key to a PEM string
+ *
+ * \param ctx       public key to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          0 successful, or a specific error code
+ */
+int pk_write_pubkey_pem( pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief           Write a private key to a PKCS#1 or SEC1 PEM string
+ *
+ * \param ctx       private to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          0 successful, or a specific error code
+ */
+int pk_write_key_pem( pk_context *ctx, unsigned char *buf, size_t size );
+#endif /* POLARSSL_PEM_WRITE_C */
+#endif /* POLARSSL_PK_WRITE_C */
+
+/*
+ * WARNING: Low-level functions. You probably do not want to use these unless
+ *          you are certain you do ;)
+ */
+
+#if defined(POLARSSL_PK_PARSE_C)
+/**
+ * \brief           Parse a SubjectPublicKeyInfo DER structure
+ *
+ * \param p         the position in the ASN.1 data
+ * \param end       end of the buffer
+ * \param pk        the key to fill
+ *
+ * \return          0 if successful, or a specific PK error code
+ */
+int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
+                        pk_context *pk );
+#endif /* POLARSSL_PK_PARSE_C */
+
+#if defined(POLARSSL_PK_WRITE_C)
+/**
+ * \brief           Write a subjectPublicKey to ASN.1 data
+ *                  Note: function works backwards in data buffer
+ *
+ * \param p         reference to current position pointer
+ * \param start     start of the buffer (for bounds-checking)
+ * \param key       public key to write away
+ *
+ * \return          the length written or a negative error code
+ */
+int pk_write_pubkey( unsigned char **p, unsigned char *start,
+                     const pk_context *key );
+#endif /* POLARSSL_PK_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* POLARSSL_PK_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/rsa.h u-boot-2011.06/include/rsa.h
--- u-boot-2011.06_original/include/rsa.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/rsa.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,610 @@
+/**
+ * \file rsa.h
+ *
+ * \brief The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_RSA_H
+#define POLARSSL_RSA_H
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+#include "md.h"
+
+#if defined(POLARSSL_THREADING_C)
+#include "threading.h"
+#endif
+
+/*
+ * RSA Error codes
+ */
+#define POLARSSL_ERR_RSA_BAD_INPUT_DATA                    -0x4080  /**< Bad input parameters to function. */
+#define POLARSSL_ERR_RSA_INVALID_PADDING                   -0x4100  /**< Input data contains invalid padding and is rejected. */
+#define POLARSSL_ERR_RSA_KEY_GEN_FAILED                    -0x4180  /**< Something failed during generation of a key. */
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the libraries validity check. */
+#define POLARSSL_ERR_RSA_PUBLIC_FAILED                     -0x4280  /**< The public key operation failed. */
+#define POLARSSL_ERR_RSA_PRIVATE_FAILED                    -0x4300  /**< The private key operation failed. */
+#define POLARSSL_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
+#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400  /**< The output buffer for decryption is not large enough. */
+#define POLARSSL_ERR_RSA_RNG_FAILED                        -0x4480  /**< The random generator failed to generate non-zeros. */
+
+/*
+ * RSA constants
+ */
+#define RSA_PUBLIC      0
+#define RSA_PRIVATE     1
+
+#define RSA_PKCS_V15    0
+#define RSA_PKCS_V21    1
+
+#define RSA_SIGN        1
+#define RSA_CRYPT       2
+
+/*
+ * The above constants may be used even if the RSA module is compile out,
+ * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ */
+#if defined(POLARSSL_RSA_C)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          RSA context structure
+ */
+typedef struct
+{
+    int ver;                    /*!<  always 0          */
+    size_t len;                 /*!<  size(N) in chars  */
+
+    mpi N;                      /*!<  public modulus    */
+    mpi E;                      /*!<  public exponent   */
+
+    mpi D;                      /*!<  private exponent  */
+    mpi P;                      /*!<  1st prime factor  */
+    mpi Q;                      /*!<  2nd prime factor  */
+    mpi DP;                     /*!<  D % (P - 1)       */
+    mpi DQ;                     /*!<  D % (Q - 1)       */
+    mpi QP;                     /*!<  1 / (Q % P)       */
+
+    mpi RN;                     /*!<  cached R^2 mod N  */
+    mpi RP;                     /*!<  cached R^2 mod P  */
+    mpi RQ;                     /*!<  cached R^2 mod Q  */
+
+#if !defined(POLARSSL_RSA_NO_CRT)
+    mpi Vi;                     /*!<  cached blinding value     */
+    mpi Vf;                     /*!<  cached un-blinding value  */
+#endif
+
+    int padding;                /*!<  RSA_PKCS_V15 for 1.5 padding and
+                                      RSA_PKCS_v21 for OAEP/PSS         */
+    int hash_id;                /*!<  Hash identifier of md_type_t as
+                                      specified in the md.h header file
+                                      for the EME-OAEP and EMSA-PSS
+                                      encoding                          */
+#if defined(POLARSSL_THREADING_C)
+    threading_mutex_t mutex;    /*!<  Thread-safety mutex       */
+#endif
+}
+rsa_context;
+
+/**
+ * \brief          Initialize an RSA context
+ *
+ *                 Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
+ *                 encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \param ctx      RSA context to be initialized
+ * \param padding  RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id  RSA_PKCS_V21 hash identifier
+ *
+ * \note           The hash_id parameter is actually ignored
+ *                 when using RSA_PKCS_V15 padding.
+ */
+void rsa_init( rsa_context *ctx,
+               int padding,
+               int hash_id);
+
+/**
+ * \brief          Set padding for an already initialized RSA context
+ *
+ *                 Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
+ *                 encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \param ctx      RSA context to be set
+ * \param padding  RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id  RSA_PKCS_V21 hash identifier
+ *
+ * \note           The hash_id parameter is actually ignored
+ *                 when using RSA_PKCS_V15 padding.
+ */
+void rsa_set_padding( rsa_context *ctx, int padding, int hash_id);
+
+/**
+ * \brief          Generate an RSA keypair
+ *
+ * \param ctx      RSA context that will hold the key
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ * \param nbits    size of the public key in bits
+ * \param exponent public exponent (e.g., 65537)
+ *
+ * \note           rsa_init() must be called beforehand to setup
+ *                 the RSA context.
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_gen_key( rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 unsigned int nbits, int exponent );
+
+/**
+ * \brief          Check a public RSA key
+ *
+ * \param ctx      RSA context to be checked
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_pubkey( const rsa_context *ctx );
+
+/**
+ * \brief          Check a private RSA key
+ *
+ * \param ctx      RSA context to be checked
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_privkey( const rsa_context *ctx );
+
+/**
+ * \brief          Do an RSA public key operation
+ *
+ * \param ctx      RSA context
+ * \param input    input buffer
+ * \param output   output buffer
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           This function does NOT take care of message
+ *                 padding. Also, be sure to set input[0] = 0 or assure that
+ *                 input is smaller than N.
+ *
+ * \note           The input and output buffers must be large
+ *                 enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_public( rsa_context *ctx,
+                const unsigned char *input,
+                unsigned char *output );
+
+/**
+ * \brief          Do an RSA private key operation
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for blinding)
+ * \param p_rng    RNG parameter
+ * \param input    input buffer
+ * \param output   output buffer
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The input and output buffers must be large
+ *                 enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_private( rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 const unsigned char *input,
+                 unsigned char *output );
+
+/**
+ * \brief          Generic wrapper to perform a PKCS#1 encryption using the
+ *                 mode from the context. Add the message padding, then do an
+ *                 RSA operation.
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for padding and PKCS#1 v2.1 encoding
+ *                               and RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen     contains the plaintext length
+ * \param input    buffer holding the data to be encrypted
+ * \param output   buffer that will hold the ciphertext
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t ilen,
+                       const unsigned char *input,
+                       unsigned char *output );
+
+/**
+ * \brief          Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for padding and RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen     contains the plaintext length
+ * \param input    buffer holding the data to be encrypted
+ * \param output   buffer that will hold the ciphertext
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t ilen,
+                                 const unsigned char *input,
+                                 unsigned char *output );
+
+/**
+ * \brief          Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for padding and PKCS#1 v2.1 encoding
+ *                               and RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param label    buffer holding the custom label to use
+ * \param label_len contains the label length
+ * \param ilen     contains the plaintext length
+ * \param input    buffer holding the data to be encrypted
+ * \param output   buffer that will hold the ciphertext
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t ilen,
+                            const unsigned char *input,
+                            unsigned char *output );
+
+/**
+ * \brief          Generic wrapper to perform a PKCS#1 decryption using the
+ *                 mode from the context. Do an RSA operation, then remove
+ *                 the message padding
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param olen     will contain the plaintext length
+ * \param input    buffer holding the encrypted data
+ * \param output   buffer that will hold the plaintext
+ * \param output_max_len    maximum length of the output buffer
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ *                 an error is thrown.
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len );
+
+/**
+ * \brief          Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param olen     will contain the plaintext length
+ * \param input    buffer holding the encrypted data
+ * \param output   buffer that will hold the plaintext
+ * \param output_max_len    maximum length of the output buffer
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ *                 an error is thrown.
+ */
+int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t *olen,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 size_t output_max_len );
+
+/**
+ * \brief          Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param label    buffer holding the custom label to use
+ * \param label_len contains the label length
+ * \param olen     will contain the plaintext length
+ * \param input    buffer holding the encrypted data
+ * \param output   buffer that will hold the plaintext
+ * \param output_max_len    maximum length of the output buffer
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ *                 an error is thrown.
+ */
+int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t *olen,
+                            const unsigned char *input,
+                            unsigned char *output,
+                            size_t output_max_len );
+
+/**
+ * \brief          Generic wrapper to perform a PKCS#1 signature using the
+ *                 mode from the context. Do a private RSA operation to sign
+ *                 a message digest
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for PKCS#1 v2.1 encoding and for
+ *                               RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer that will hold the ciphertext
+ *
+ * \return         0 if the signing operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note           In case of PKCS#1 v2.1 encoding keep in mind that
+ *                 the hash_id in the RSA context is the one used for the
+ *                 encoding. hash_id in the function call is the type of hash
+ *                 that is encoded. According to RFC 3447 it is advised to
+ *                 keep both hashes the same.
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    int mode,
+                    md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig );
+
+/**
+ * \brief          Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer that will hold the ciphertext
+ *
+ * \return         0 if the signing operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               unsigned char *sig );
+
+/**
+ * \brief          Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
+ *
+ * \param ctx      RSA context
+ * \param f_rng    RNG function (Needed for PKCS#1 v2.1 encoding and for
+ *                               RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer that will hold the ciphertext
+ *
+ * \return         0 if the signing operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note           In case of PKCS#1 v2.1 encoding keep in mind that
+ *                 the hash_id in the RSA context is the one used for the
+ *                 encoding. hash_id in the function call is the type of hash
+ *                 that is encoded. According to RFC 3447 it is advised to
+ *                 keep both hashes the same.
+ */
+int rsa_rsassa_pss_sign( rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         int mode,
+                         md_type_t md_alg,
+                         unsigned int hashlen,
+                         const unsigned char *hash,
+                         unsigned char *sig );
+
+/**
+ * \brief          Generic wrapper to perform a PKCS#1 verification using the
+ *                 mode from the context. Do a public RSA operation and check
+ *                 the message digest
+ *
+ * \param ctx      points to an RSA public key
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer holding the ciphertext
+ *
+ * \return         0 if the verify operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note           In case of PKCS#1 v2.1 encoding keep in mind that
+ *                 the hash_id in the RSA context is the one used for the
+ *                 verification. hash_id in the function call is the type of
+ *                 hash that is verified. According to RFC 3447 it is advised to
+ *                 keep both hashes the same.
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng,
+                      int mode,
+                      md_type_t md_alg,
+                      unsigned int hashlen,
+                      const unsigned char *hash,
+                      const unsigned char *sig );
+
+/**
+ * \brief          Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
+ *
+ * \param ctx      points to an RSA public key
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer holding the ciphertext
+ *
+ * \return         0 if the verify operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode,
+                                 md_type_t md_alg,
+                                 unsigned int hashlen,
+                                 const unsigned char *hash,
+                                 const unsigned char *sig );
+
+/**
+ * \brief          Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
+ *
+ * \param ctx      points to an RSA public key
+ * \param f_rng    RNG function (Only needed for RSA_PRIVATE)
+ * \param p_rng    RNG parameter
+ * \param mode     RSA_PUBLIC or RSA_PRIVATE
+ * \param md_alg   a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for POLARSSL_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer holding the ciphertext
+ *
+ * \return         0 if the verify operation was successful,
+ *                 or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note           In case of PKCS#1 v2.1 encoding keep in mind that
+ *                 the hash_id in the RSA context is the one used for the
+ *                 verification. hash_id in the function call is the type of
+ *                 hash that is verified. According to RFC 3447 it is advised to
+ *                 keep both hashes the same.
+ */
+int rsa_rsassa_pss_verify( rsa_context *ctx,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           int mode,
+                           md_type_t md_alg,
+                           unsigned int hashlen,
+                           const unsigned char *hash,
+                           const unsigned char *sig );
+
+/**
+ * \brief          Copy the components of an RSA context
+ *
+ * \param dst      Destination context
+ * \param src      Source context
+ *
+ * \return         O on success,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED on memory allocation failure
+ */
+int rsa_copy( rsa_context *dst, const rsa_context *src );
+
+/**
+ * \brief          Free the components of an RSA key
+ *
+ * \param ctx      RSA Context to free
+ */
+void rsa_free( rsa_context *ctx );
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int rsa_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* POLARSSL_RSA_C */
+
+#endif /* rsa.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/rsa_verify.h u-boot-2011.06/include/rsa_verify.h
--- u-boot-2011.06_original/include/rsa_verify.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/rsa_verify.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,19 @@
+#ifndef _SECU_BOOT_H_
+#define _SECU_BOOT_H_
+
+void UpdateExternalRSAKey(unsigned char *InputBuf);
+
+int SignatureVerify(unsigned char *InputBuf,
+                    int Size,
+                    unsigned char *SigBuf,
+                    unsigned char *Hash,
+                    unsigned int PkcsVersion);
+
+int SHAVerify(unsigned char *InputBuf,
+              int Size,
+              unsigned char *SigBuf);
+
+int HybridSignatureVerify( unsigned char hash[32], unsigned char *SigBuf, unsigned int PkcsVersion);
+
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/scsi.h u-boot-2011.06/include/scsi.h
--- u-boot-2011.06_original/include/scsi.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/scsi.h	2014-08-28 12:01:57.591471000 +0800
@@ -2,31 +2,16 @@
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
- * 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
- *
+ * SPDX-License-Identifier:	GPL-2.0+
  */
  #ifndef _SCSI_H
  #define _SCSI_H
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
@@ -148,6 +133,8 @@
 #define SCSI_READ6		0x08		/* Read 6-byte (MANDATORY) */
 #define SCSI_READ10		0x28		/* Read 10-byte (MANDATORY) */
 #define SCSI_RD_CAPAC	0x25		/* Read Capacity (MANDATORY) */
+#define SCSI_RD_CAPAC10	SCSI_RD_CAPAC	/* Read Capacity (10) */
+#define SCSI_RD_CAPAC16	0x9e		/* Read Capacity (16) */
 #define SCSI_RD_DEFECT	0x37		/* Read Defect Data (O) */
 #define SCSI_READ_LONG	0x3E		/* Read Long (O) */
 #define SCSI_REASS_BLK	0x07		/* Reassign Blocks (O) */
@@ -185,7 +172,10 @@
  * functions residing inside cmd_scsi.c
  */
 void scsi_init(void);
+void scsi_scan(int mode);
 
+/** @return the number of scsi disks */
+int scsi_get_disk_count(void);
 
 #define SCSI_IDENTIFY					0xC0  /* not used */
 
@@ -197,12 +187,4 @@
 
 #define SCSI_INT_STATE				 0x00010000  /* unknown Interrupt number is stored in 16 LSB */
 
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
 #endif /* _SCSI_H */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/sha256.h u-boot-2011.06/include/sha256.h
--- u-boot-2011.06_original/include/sha256.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/sha256.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,16 +1,194 @@
-#ifndef _SHA256_H
-#define _SHA256_H
+/**
+ * \file sha256.h
+ *
+ * \brief SHA-224 and SHA-256 cryptographic hash function
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+#ifndef POLARSSL_SHA256_H
+#define POLARSSL_SHA256_H
 
-#define SHA256_SUM_LEN	32
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
 
-typedef struct {
-	uint32_t total[2];
-	uint32_t state[8];
-	uint8_t buffer[64];
-} sha256_context;
-
-void sha256_starts(sha256_context * ctx);
-void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length);
-void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]);
+#include <linux/string.h>
 
-#endif /* _SHA256_H */
+#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
+#include <basetsd.h>
+typedef UINT32 uint32_t;
+#else
+#include <linux/types.h>
+#endif
+
+#define POLARSSL_ERR_SHA256_FILE_IO_ERROR              -0x0078  /**< Read/write error in file. */
+
+#if !defined(POLARSSL_SHA256_ALT)
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          SHA-256 context structure
+ */
+typedef struct
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[8];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+
+    unsigned char ipad[64];     /*!< HMAC: inner padding        */
+    unsigned char opad[64];     /*!< HMAC: outer padding        */
+    int is224;                  /*!< 0 => SHA-256, else SHA-224 */
+}
+sha256_context;
+
+/**
+ * \brief          SHA-256 context setup
+ *
+ * \param ctx      context to be initialized
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+void sha256_starts( sha256_context *ctx, int is224 );
+
+/**
+ * \brief          SHA-256 process buffer
+ *
+ * \param ctx      SHA-256 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void sha256_update( sha256_context *ctx, const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief          SHA-256 final digest
+ *
+ * \param ctx      SHA-256 context
+ * \param output   SHA-224/256 checksum result
+ */
+void sha256_finish( sha256_context *ctx, unsigned char output[32] );
+
+/* Internal use */
+void sha256_process( sha256_context *ctx, const unsigned char data[64] );
+
+#ifdef __cplusplus
+}
+#endif
+
+#else  /* POLARSSL_SHA256_ALT */
+#include "sha256_alt.h"
+#endif /* POLARSSL_SHA256_ALT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Output = SHA-256( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   SHA-224/256 checksum result
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+void sha256( const unsigned char *input, size_t ilen,
+           unsigned char output[32], int is224 );
+
+/**
+ * \brief          Output = SHA-256( file contents )
+ *
+ * \param path     input file name
+ * \param output   SHA-224/256 checksum result
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ *
+ * \return         0 if successful, or POLARSSL_ERR_SHA256_FILE_IO_ERROR
+ */
+int sha256_file( const char *path, unsigned char output[32], int is224 );
+
+/**
+ * \brief          SHA-256 HMAC context setup
+ *
+ * \param ctx      HMAC context to be initialized
+ * \param key      HMAC secret key
+ * \param keylen   length of the HMAC key
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key,
+                         size_t keylen, int is224 );
+
+/**
+ * \brief          SHA-256 HMAC process buffer
+ *
+ * \param ctx      HMAC context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void sha256_hmac_update( sha256_context *ctx, const unsigned char *input,
+                         size_t ilen );
+
+/**
+ * \brief          SHA-256 HMAC final digest
+ *
+ * \param ctx      HMAC context
+ * \param output   SHA-224/256 HMAC checksum result
+ */
+void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] );
+
+/**
+ * \brief          SHA-256 HMAC context reset
+ *
+ * \param ctx      HMAC context to be reset
+ */
+void sha256_hmac_reset( sha256_context *ctx );
+
+/**
+ * \brief          Output = HMAC-SHA-256( hmac key, input buffer )
+ *
+ * \param key      HMAC secret key
+ * \param keylen   length of the HMAC key
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   HMAC-SHA-224/256 result
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+void sha256_hmac( const unsigned char *key, size_t keylen,
+                  const unsigned char *input, size_t ilen,
+                  unsigned char output[32], int is224 );
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int sha256_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha256.h */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/u-boot/md5.h u-boot-2011.06/include/u-boot/md5.h
--- u-boot-2011.06_original/include/u-boot/md5.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/u-boot/md5.h	2014-07-29 17:28:38.819972000 +0800
@@ -11,7 +11,11 @@
 struct MD5Context {
 	__u32 buf[4];
 	__u32 bits[2];
-	unsigned char in[64];
+	union {
+		unsigned char in[64];
+		__u32 in32[16];
+	};
+
 };
 
 /*
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/usb_defs.h u-boot-2011.06/include/usb_defs.h
--- u-boot-2011.06_original/include/usb_defs.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/usb_defs.h	2014-08-28 18:12:18.974057000 +0800
@@ -2,26 +2,9 @@
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
- * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  *
  * Note: Part of this code has been derived from linux
- *
  */
 #ifndef _USB_DEFS_H_
 #define _USB_DEFS_H_
@@ -80,11 +63,24 @@
 #define USB_DIR_OUT           0
 #define USB_DIR_IN            0x80
 
-/* USB device speeds */
-#define USB_SPEED_FULL		0x0	/* 12Mbps */
-#define USB_SPEED_LOW		0x1	/* 1.5Mbps */
-#define USB_SPEED_HIGH		0x2	/* 480Mbps */
-#define USB_SPEED_RESERVED	0x3
+/*
+ * bmRequestType: USB Device Requests, table 9.2 USB 2.0 spec.
+ * (shifted) direction/type/recipient.
+ */
+#define DeviceRequest \
+	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
+
+#define DeviceOutRequest \
+	((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
+
+#define InterfaceRequest \
+	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
+
+#define EndpointRequest \
+	((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
+
+#define EndpointOutRequest \
+	((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
 
 /* Descriptor types */
 #define USB_DT_DEVICE        0x01
@@ -156,6 +152,18 @@
 #define USB_REQ_SET_IDLE            0x0A
 #define USB_REQ_SET_PROTOCOL        0x0B
 
+/* Device features */
+#define USB_FEAT_HALT               0x00
+#define USB_FEAT_WAKEUP             0x01
+#define USB_FEAT_TEST               0x02
+
+/* Test modes */
+#define USB_TEST_MODE_J             0x01
+#define USB_TEST_MODE_K             0x02
+#define USB_TEST_MODE_SE0_NAK       0x03
+#define USB_TEST_MODE_PACKET        0x04
+#define USB_TEST_MODE_FORCE_ENABLE  0x05
+
 
 /* "pipe" definitions */
 
@@ -214,6 +222,18 @@
 #define USB_PORT_FEAT_C_SUSPEND      18
 #define USB_PORT_FEAT_C_OVER_CURRENT 19
 #define USB_PORT_FEAT_C_RESET        20
+#define USB_PORT_FEAT_TEST           21
+
+/*
+ * Changes to Port feature numbers for Super speed,
+ * from USB 3.0 spec Table 10-8
+ */
+#define USB_SS_PORT_FEAT_U1_TIMEOUT	23
+#define USB_SS_PORT_FEAT_U2_TIMEOUT	24
+#define USB_SS_PORT_FEAT_C_LINK_STATE	25
+#define USB_SS_PORT_FEAT_C_CONFIG_ERROR	26
+#define USB_SS_PORT_FEAT_BH_RESET	28
+#define USB_SS_PORT_FEAT_C_BH_RESET	29
 
 /* wPortStatus bits */
 #define USB_PORT_STAT_CONNECTION    0x0001
@@ -224,9 +244,19 @@
 #define USB_PORT_STAT_POWER         0x0100
 #define USB_PORT_STAT_LOW_SPEED     0x0200
 #define USB_PORT_STAT_HIGH_SPEED    0x0400	/* support for EHCI */
-#define USB_PORT_STAT_SPEED	\
+#define USB_PORT_STAT_SUPER_SPEED   0x0600	/* faking support to XHCI */
+#define USB_PORT_STAT_SPEED_MASK	\
 	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
 
+/*
+ * Changes to wPortStatus bit field in USB 3.0
+ * See USB 3.0 spec Table 10-11
+ */
+#define USB_SS_PORT_STAT_LINK_STATE	0x01e0
+#define USB_SS_PORT_STAT_POWER		0x0200
+#define USB_SS_PORT_STAT_SPEED		0x1c00
+#define USB_SS_PORT_STAT_SPEED_5GBPS	0x0000
+
 /* wPortChange bits */
 #define USB_PORT_STAT_C_CONNECTION  0x0001
 #define USB_PORT_STAT_C_ENABLE      0x0002
@@ -234,13 +264,21 @@
 #define USB_PORT_STAT_C_OVERCURRENT 0x0008
 #define USB_PORT_STAT_C_RESET       0x0010
 
+/*
+ * Changes to wPortChange bit fields in USB 3.0
+ * See USB 3.0 spec Table 10-12
+ */
+#define USB_SS_PORT_STAT_C_BH_RESET	0x0020
+#define USB_SS_PORT_STAT_C_LINK_STATE	0x0040
+#define USB_SS_PORT_STAT_C_CONFIG_ERROR	0x0080
+
 /* wHubCharacteristics (masks) */
 #define HUB_CHAR_LPSM               0x0003
 #define HUB_CHAR_COMPOUND           0x0004
 #define HUB_CHAR_OCPM               0x0018
 
 /*
- *Hub Status & Hub Change bit masks
+ * Hub Status & Hub Change bit masks
  */
 #define HUB_STATUS_LOCAL_POWER	0x0001
 #define HUB_STATUS_OVERCURRENT	0x0002
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/usb_ether.h u-boot-2011.06/include/usb_ether.h
--- u-boot-2011.06_original/include/usb_ether.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/usb_ether.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,22 +1,7 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
- * 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
+ * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #ifndef __USB_ETHER_H__
@@ -50,7 +35,8 @@
 	unsigned char	protocol;		/* .............. */
 	unsigned char	irqinterval;	/* Intervall for IRQ Pipe */
 
-	/* private fields for each driver can go here if needed */
+	/* driver private */
+	void *dev_priv;
 };
 
 /*
@@ -65,4 +51,12 @@
 		      struct eth_device *eth);
 #endif
 
+#ifdef CONFIG_USB_ETHER_SMSC95XX
+void smsc95xx_eth_before_probe(void);
+int smsc95xx_eth_probe(struct usb_device *dev, unsigned int ifnum,
+			struct ueth_data *ss);
+int smsc95xx_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
+			struct eth_device *eth);
+#endif
+
 #endif /* __USB_ETHER_H__ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/usb.h u-boot-2011.06/include/usb.h
--- u-boot-2011.06_original/include/usb.h	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/include/usb.h	2014-07-29 17:28:38.819972000 +0800
@@ -2,24 +2,7 @@
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
- * 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
- *
+ * SPDX-License-Identifier:	GPL-2.0+
  * Note: Part of this code has been derived from linux
  *
  */
@@ -27,7 +10,17 @@
 #define _USB_H_
 
 #include <usb_defs.h>
-#include <usbdescriptors.h>
+#include <linux/usb/ch9.h>
+
+/*
+ * The EHCI spec says that we must align to at least 32 bytes.  However,
+ * some platforms require larger alignment.
+ */
+#if ARCH_DMA_MINALIGN > 32
+#define USB_DMA_MINALIGN	ARCH_DMA_MINALIGN
+#else
+#define USB_DMA_MINALIGN	32
+#endif
 
 /* Everything is aribtrary */
 #define USB_ALTSETTINGALLOC		4
@@ -46,7 +39,7 @@
  * This is the timeout to allow for submitting an urb in ms. We allow more
  * time for a BULK device to react - some are slow.
  */
-#define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 100)
+#define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
 /* device request (setup) */
 struct devrequest {
@@ -57,12 +50,6 @@
 	unsigned short	length;
 } __attribute__ ((packed));
 
-/* All standard descriptors have these 2 fields in common */
-struct usb_descriptor_header {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-} __attribute__ ((packed));
-
 /* Interface */
 struct usb_interface {
 	struct usb_interface_descriptor desc;
@@ -72,11 +59,17 @@
 	unsigned char	act_altsetting;
 
 	struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
+	/*
+	 * Super Speed Device will have Super Speed Endpoint
+	 * Companion Descriptor  (section 9.6.7 of usb 3.0 spec)
+	 * Revision 1.0 June 6th 2011
+	 */
+	struct usb_ss_ep_comp_descriptor ss_ep_comp_desc[USB_MAXENDPOINTS];
 } __attribute__ ((packed));
 
 /* Configuration information.. */
 struct usb_config {
-	struct usb_configuration_descriptor desc;
+	struct usb_config_descriptor desc;
 
 	unsigned char	no_of_if;	/* number of interfaces */
 	struct usb_interface if_desc[USB_MAXINTERFACES];
@@ -109,7 +102,9 @@
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	/* Device Descriptor */
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
@@ -128,6 +123,8 @@
 	int portnr;
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
+
+	void *controller;		/* hardware controller private data */
 };
 
 /**********************************************************************
@@ -139,22 +136,35 @@
 	defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
 	defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
 	defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
-	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X)
+	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
+	defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
+	defined(CONFIG_USB_MUSB_OMAP2PLUS)
+
+int usb_lowlevel_init(int index, void **controller);
+int usb_lowlevel_stop(int index);
 
-int usb_lowlevel_init(void);
-int usb_lowlevel_stop(void);
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len);
 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int transfer_len, struct devrequest *setup);
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int transfer_len, int interval);
-void usb_event_poll(void);
 
 /* Defines */
 #define USB_UHCI_VEND_ID	0x8086
 #define USB_UHCI_DEV_ID		0x7112
 
+/*
+ * PXA25x can only act as USB device. There are drivers
+ * which works with USB CDC gadgets implementations.
+ * Some of them have common routines which can be used
+ * in boards init functions e.g. udc_disconnect() used for
+ * forced device disconnection from host.
+ */
+#elif defined(CONFIG_USB_GADGET_PXA2XX)
+
+extern void udc_disconnect(void);
+
 #else
 #error USB Lowlevel not defined
 #endif
@@ -200,7 +210,6 @@
 			void *buffer, int transfer_len, int interval);
 int usb_disable_asynch(int disable);
 int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
-inline void wait_ms(unsigned long ms);
 int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
 				int cfgno);
 int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
@@ -261,7 +270,6 @@
  *  - device:		bits 8-14
  *  - endpoint:		bits 15-18
  *  - Data0/1:		bit 19
- *  - speed:		bit 26		(0 = Full, 1 = Low Speed, 2 = High)
  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt,
  *					 10 = control, 11 = bulk)
  *
@@ -273,7 +281,7 @@
 /* Create various pipes... */
 #define create_pipe(dev,endpoint) \
 		(((dev)->devnum << 8) | ((endpoint) << 15) | \
-		((dev)->speed << 26) | (dev)->maxpacketsize)
+		(dev)->maxpacketsize)
 #define default_pipe(dev) ((dev)->speed << 26)
 
 #define usb_sndctrlpipe(dev, endpoint)	((PIPE_CONTROL << 30) | \
@@ -324,8 +332,6 @@
 #define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
 #define usb_pipedata(pipe)	(((pipe) >> 19) & 1)
-#define usb_pipespeed(pipe)	(((pipe) >> 26) & 3)
-#define usb_pipeslow(pipe)	(usb_pipespeed(pipe) == USB_SPEED_LOW)
 #define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
 #define usb_pipeint(pipe)	(usb_pipetype((pipe)) == PIPE_INTERRUPT)
@@ -367,4 +373,14 @@
 	struct usb_hub_descriptor desc;
 };
 
+int usb_hub_probe(struct usb_device *dev, int ifnum);
+void usb_hub_reset(void);
+int hub_port_reset(struct usb_device *dev, int port,
+			  unsigned short *portstat);
+
+struct usb_device *usb_alloc_new_device(void *controller);
+
+int usb_new_device(struct usb_device *dev);
+void usb_free_device(void);
+
 #endif /*_USB_H_ */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/usb_update.h u-boot-2011.06/include/usb_update.h
--- u-boot-2011.06_original/include/usb_update.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/usb_update.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,698 @@
+#ifndef __USB_DEFS_H__
+#define __USB_DEFS_H__
+
+// musbmhdrc_cfg
+// This file contains configuration constants for the musbmhdrc.
+
+// ** Number of Tx endpoints **
+// Legal values are 1 - 16 (this value includes EP0)
+// ide, mouse, keyboard, 
+#define C_NUM_EPT 4
+
+// ** Number of Rx endpoints **
+// Legal values are 1 - 16 (this value includes EP0)
+#define C_NUM_EPR 4
+
+// ** Endpoint 1 to 15 direction types **
+// C_EP1_DEF is defined if either Tx endpoint 1 or Rx endpoint 1 are used
+#define C_EP1_DEF
+
+// C_EP1_TX_DEF is defined if Tx endpoint 1 is used
+#define C_EP1_TX_DEF
+
+// C_EP1_RX_DEF is defined if Rx endpoint 1 is used
+#define C_EP1_RX_DEF
+
+// C_EP1_TOR_DEF is defined if Tx endpoint 1 and Rx endpoint 1 share a FIFO
+//#define C_EP1_TOR_DEF
+
+// C_EP1_TAR_DEF is defined if both Tx endpoint 1 and Rx endpoint 1 are used
+// and do not share a FIFO
+#define C_EP1_TAR_DEF
+
+// Similarly for all other used endpoints
+#define C_EP2_DEF
+#define C_EP2_TX_DEF
+#define C_EP2_RX_DEF
+#define C_EP2_TAR_DEF
+
+#define C_EP3_DEF
+#define C_EP3_TX_DEF
+#define C_EP3_RX_DEF
+#define C_EP3_TAR_DEF
+
+// ** Endpoint 1 to 15 FIFO address bits **
+// Legal values are 3 to 13 - corresponding to FIFO sizes of 8 to 8192 bytes.
+// If an Tx endpoint shares a FIFO with an Rx endpoint then the Rx FIFO size
+// must be the same as the Tx FIFO size.
+// All endpoints 1 to 15 must be defined, unused endpoints should be set to 2.
+#define C_EP1T_BITS 10
+#define C_EP1R_BITS 10
+#define C_EP2T_BITS 10
+#define C_EP2R_BITS 10
+#define C_EP3T_BITS 10
+#define C_EP3R_BITS 10
+#define C_EP4T_BITS 2
+#define C_EP4R_BITS 2
+#define C_EP5T_BITS 2
+#define C_EP5R_BITS 2
+#define C_EP6T_BITS 2
+#define C_EP6R_BITS 2
+#define C_EP7T_BITS 2
+#define C_EP7R_BITS 2
+#define C_EP8T_BITS 2
+#define C_EP8R_BITS 2
+#define C_EP9T_BITS 2
+#define C_EP9R_BITS 2
+#define C_EP10T_BITS 2
+#define C_EP10R_BITS 2
+#define C_EP11T_BITS 2
+#define C_EP11R_BITS 2
+#define C_EP12T_BITS 2
+#define C_EP12R_BITS 2
+#define C_EP13T_BITS 2
+#define C_EP13R_BITS 2
+#define C_EP14T_BITS 2
+#define C_EP14R_BITS 2
+#define C_EP15T_BITS 2
+#define C_EP15R_BITS 2
+
+// Define the following constants for ULPI PHY interface width.
+#define C_LPI_WIDTH 7
+
+// added by yan@10-25-2006 11:45 
+#define C_LPI
+
+// Define the following constant if software connect/disconnect control is required.
+#define C_SOFT_CON
+
+// Vendor control register widths.
+#define C_VCTL_BITS 4
+#define C_VSTAT_BITS 8
+
+// Define the following constant to include a DMA controller.
+#define C_DMA
+
+// Define the following constant if 2 or more DMA channels are required.
+#define C_DMA2
+
+// ** Enable Dynamic FIFO Sizing **
+#define C_DYNFIFO_DEF
+
+// ** Derived constants **
+// The following constants are derived from the previous configuration constants
+
+// Total number of endpoints
+// Legal values are 2 - 16
+// This must be equal to the larger of C_NUM_EPT, C_NUM_EPR
+#define C_NUM_EPS 4
+
+// C_EPMAX_BITS is equal to the largest endpoint FIFO word address bits
+#define C_EPMAX_BITS 9
+
+// C_RAM_BITS is the number of address bits required to address the RAM (32-bit addresses)
+// It is defined as log2 of the sum of 2** of all the endpoint FIFO dword address bits (rounded up).
+// 2 x 1024 to support any possible ep(max bulk 512'B, max iso = 1024'B)
+#define C_RAM_BITS 9
+
+#define SOF 0Xa5
+#define SETUP 0X2d
+#define DATA0 0Xc3
+#define DATA1 0X4b
+#define DATA2 0X87
+#define MDATA 0X0f
+#define ACK 0Xd2
+#define NAK 0X5a
+#define STALL 0X1e
+#define PING 0Xb4
+#define NYET 0X96
+#define SPLIT 0X78
+#define ERR 0X3c
+#define PRE 0X3c
+
+// MCU registers
+#define REG_FADDR	 0X00
+#define REG_POWER	 0X01
+#define REG_INTRTX	 0X02
+#define REG_INTRRX	 0X04
+#define REG_INTRTXE	 0X06
+#define REG_INTRRXE	 0X08
+#define REG_INTRUSB	 0X0A
+#define REG_INTRUSBE	 0X0B
+#define REG_FRAME        0X0C
+#define REG_INDEX        0X0E
+#define REG_TESTMODE     0X0F
+#define REG_EP0_CSR	 0X12
+#define REG_EP0_COUNT	 0X18
+#define REG_EP0_INTV     0X1B
+#define REG_EP_TXMAXP	 0X10
+#define REG_EP_TXCSR	 0X12
+#define REG_EP_RXMAXP    0X14
+#define REG_EP_RXCSR	 0X16
+#define REG_EP_COUNT	 0X18
+#define REG_EP_TXTYPE    0X1A
+#define REG_EP_TXINTV    0X1B
+#define REG_EP_RXTYPE    0X1C
+#define REG_EP_RXINTV    0X1D
+#define REG_EP_FIFOBITS  0X1F
+#define REG_EP0_FIFO	 0X20
+#define REG_EP1_FIFO	 0X24
+#define REG_EP2_FIFO	 0X28
+#define REG_EP3_FIFO	 0X2C
+#define REG_EP4_FIFO	 0X30
+#define REG_EP5_FIFO	 0X34
+#define REG_EP6_FIFO	 0X38
+#define REG_EP7_FIFO	 0X3C
+#define REG_EP8_FIFO	 0X40
+#define REG_EP9_FIFO	 0X44
+#define REG_EP10_FIFO    0X48
+#define REG_EP11_FIFO    0X4C
+#define REG_EP12_FIFO    0X50
+#define REG_EP13_FIFO    0X54
+#define REG_EP14_FIFO	 0X58
+#define REG_EP15_FIFO    0X5C
+#define REG_DEVCTL	 0X60
+#define REG_EP_TXFIFOS   0X62
+#define REG_EP_RXFIFOS   0X63
+#define REG_EP_TXFIFOA   0X64
+#define REG_EP_RXFIFOA   0X66
+#define REG_VCNTRL	 0X68
+#define REG_VSTAT	 0X68
+#define REG_HWVERS	 0X6C
+#define REG_LPI_VBUS     0X70
+#define REG_LPI_CARCTRL  0X71
+#define REG_LPI_IMASK    0X72
+#define REG_LPI_ISTAT    0X73
+#define REG_LPI_DATA     0X74
+#define REG_LPI_ADDR     0X75
+#define REG_LPI_CTRL     0X76
+#define REG_LPI_RXDATA   0X77
+#define REG_ENDCOUNT   	 0X78
+#define REG_RAMSIZE	     0X79
+#define REG_PHYWT        0X7A
+#define REG_PHYTMVBUS    0X7B
+#define REG_TMHSEOF1     0X7C
+#define REG_TMFSEOF1     0X7D
+#define REG_TMLSEOF1     0X7E
+
+// Endpoint target address off
+#define REG_TXTFADDR_OFF 0
+#define REG_TXTHADDR_OFF 2
+#define REG_TXTHPORT_OFF 3
+#define REG_RXTFADDR_OFF 4
+#define REG_RXTHADDR_OFF 6
+#define REG_RXTHPORT_OFF 7
+
+// Endpoint register offsets
+#define REG_EP0_OFF    0X0100
+#define REG_EP1_OFF    0X0110
+#define REG_EP2_OFF    0X0120
+#define REG_EP3_OFF    0X0130
+#define REG_EP4_OFF    0X0140
+#define REG_EP5_OFF    0X0150
+#define REG_EP6_OFF    0X0160
+#define REG_EP7_OFF    0X0170
+#define REG_EP8_OFF    0X0180
+#define REG_EP9_OFF    0X0190
+#define REG_EP10_OFF   0X01A0
+#define REG_EP11_OFF   0X01B0
+#define REG_EP12_OFF   0X01C0
+#define REG_EP13_OFF   0X01D0
+#define REG_EP14_OFF   0X01E0
+#define REG_EP15_OFF   0X01F0
+
+// DMA controller registers
+#define REG_DMA_INTR   0x200
+#define REG_DMA_CNTRL 0x20C
+#define REG_DMA_ADDR   0x208
+#define REG_DMA_COUNT  0x204
+
+// Interrupt status bits
+#define INTR_EP0	0X0001
+#define INTR_EP1	0X0002
+#define INTR_EP2	0X0004
+#define INTR_EP3	0X0008
+#define INTR_EP4	0X0010
+#define INTR_EP5	0X0020
+#define INTR_EP6	0X0040
+#define INTR_EP7	0X0080
+#define INTR_EP8	0X0100
+#define INTR_EP9	0X0200
+#define INTR_EP10	0X0400
+#define INTR_EP11	0X0800
+#define INTR_EP12	0X1000
+#define INTR_EP13	0X2000
+#define INTR_EP14	0X4000
+#define INTR_EP15	0X8000
+#define INTR_SUS	0X01
+#define INTR_RES	0X02
+#define INTR_RST	0X04
+#define INTR_SOF	0X08
+#define INTR_CONN	0X10
+#define INTR_DISCON	0X20
+#define INTR_SREQ	0X40
+#define INTR_VBERR	0X80
+
+// CSR0 bits
+#define CSR0_NULL	0X00
+#define CSR0_OPR	0X01
+#define CSR0_IPR	0X02
+#define CSR0_SNTS	0X04
+#define CSR0_DE		0X08
+#define CSR0_SE		0X10
+#define CSR0_SS		0X20
+#define CSR0_SVDOPR	0X40
+#define CSR0_SVDSE	0X80
+#define CSR0_RPR	0X01
+#define CSR0_TPR	0X02
+#define CSR0_RSTALL	0X04
+#define CSR0_SETUP	0X08
+#define CSR0_ERR	0X10
+#define CSR0_REQP	0X20
+#define CSR0_STATP	0X40
+#define CSR0_NAKL	0X80
+#define CSR0H_FF	0X01
+#define CSR0H_DISPING	0X08
+
+// TXCSR1 bits
+#define TXCSR1_NULL	0X00
+#define TXCSR1_STALL	0X20
+#define TXCSR1_TPR	0X01
+#define TXCSR1_IPR	0X01
+#define TXCSR1_FNE	0X02
+#define TXCSR1_UR	0X04
+#define TXCSR1_ERR	0X04
+#define TXCSR1_FF	0X08
+#define TXCSR1_SDS	0X10
+#define TXCSR1_SETUP 0X10
+#define TXCSR1_STS	0X20
+#define TXCSR1_RSTL	0X20
+#define TXCSR1_CDT	0X40
+#define TXCSR1_ITX	0X80
+#define TXCSR1_NAKL	0X80
+#define TXCSR1_TPRX	0	//8'b0000000X
+#define TXCSR1_IPRX	0	//8'b0000000X
+#define TXCSR1_FNEX	2	//8'b0000001X
+
+// TXCSR2 bits
+#define TXCSR2_NULL	0X00
+#define TXCSR2_DTOG 	0X01
+#define TXCSR2_DTOGWRE 	0X02
+#define TXCSR2_DMAMODE	0X04
+#define TXCSR2_FDT	0X08
+#define TXCSR2_DMA	0X10
+#define TXCSR2_MODE	0X20
+#define TXCSR2_ISO	0X40
+#define TXCSR2_AUTO	0X80
+#define TXCSR2_DTX 	0	//8'b0000000X
+
+// RXCSR1 bits
+#define RXCSR1_NULL	0X00
+#define RXCSR1_RPR	0X01
+#define RXCSR1_OPR	0X01
+#define RXCSR1_FULL	0X02
+#define RXCSR1_OR	0X04
+#define RXCSR1_ERR	0X04
+#define RXCSR1_DE	0X08
+#define RXCSR1_NAKL	0X08
+#define RXCSR1_FF	0X10
+#define RXCSR1_SDS	0X20
+#define RXCSR1_REQP	0X20
+#define RXCSR1_STS	0X40
+#define RXCSR1_RSTL	0X40
+#define RXCSR1_CDT	0X80
+#define RXCSR1_RPRX	1	//8'b000000X1
+#define RXCSR1_OPRX	1	//8'b000000X1
+#define RXCSR1_INCMPRX	0	//8'bXXXXXXX0
+
+// RXCSR2 bits
+#define RXCSR2_NULL	0X00
+#define RXCSR2_IRX	0X01
+#define RXCSR2_DTOG	0X02
+#define RXCSR2_DTOGWRE 0X04
+#define RXCSR2_DMAMODE 0X08
+#define RXCSR2_DISNYET 0X10
+#define RXCSR2_PIDERR  0X10
+#define RXCSR2_DMA	0X20
+#define RXCSR2_ISO	0X40
+#define RXCSR2_AREQ 0X40
+#define RXCSR2_AUTO	0X80
+
+// Protocol type bits
+#define TYPE_CNTRL 0X00
+#define TYPE_ISOC	0X10
+#define TYPE_BULK	0X20
+#define TYPE_INTR	0X30
+#define TYPE_HS 0X40
+#define TYPE_FS 0X80
+#define TYPE_LS 0Xc0
+
+#define DFIFODPB 0X10
+#define REG_NULL 0X00
+
+// Power register bits
+#define PWR_NULL        0X00
+#define PWR_SUSE        0X01
+#define PWR_SUSM        0X02
+#define PWR_RSM         0X04
+#define PWR_RST         0X08
+#define PWR_HSMOD       0X10
+#define PWR_HSEN        0X20
+#define PWR_SFTCON      0X40
+
+// DEVCTL bits
+#define DVC_NULL       0X00
+#define DVC_SESS       0X01
+#define DVC_HREQ       0X02
+#define DVC_HMODE      0X04
+#define DVC_VBUS       0X18
+#define DVC_LSDEV      0X20
+#define DVC_FSDEV      0X40
+#define DVC_CID        0X80
+#define DVC_CIDX      0	// 8'bX0000000
+
+// TESTMODE bits
+#define TEST_SE0_NAK    0X01
+#define TEST_J          0X02
+#define TEST_K          0X04
+#define TEST_PACKET     0X08
+#define TEST_FORCE_HS   0X10
+#define TEST_FORCE_FS   0X20
+#define TEST_FIFO_ACC   0X40
+#define TEST_FORCE_HOST 0X80
+
+// ULPI VBUS control bits
+#define LPI_VBUS_NULL   0X00
+#define LPI_VBUS_EXT    0X01
+#define LPI_VBUS_IND    0X02
+
+// Define ULPI Function control register bits
+#define LPI_FC_SUSPENDM  0X40
+
+// Define ULPI Interface control register bits
+#define LPI_IF_FSLSMODE6  0X01
+#define LPI_IF_FSLSMODE3  0X02
+#define LPI_IF_CARKIT     0X04
+#define LPI_IF_CLKSUPSEND 0X08
+
+// ULPI register bits and internal addresses
+#define LPI_NULL          0X00
+#define LPI_REQ           0X01
+#define LPI_COMPLT        0X02
+#define LPI_RD            0X04
+
+// Car Kit Control Bits.
+#define LPI_C_DISABLE     0X01
+#define LPI_C_ACTIVE      0X02
+#define LPI_C_ALTINT      0X04
+#define LPI_C_WAKEUP      0X08
+#define LPI_C_RXCMD       0X10
+#define LPI_C_ACTIVEEND   0X20
+// Car Kit IMASK Register
+#define LPI_I_MCU_DONE    0X01
+#define LPI_I_ALTINT      0X02
+#define LPI_I_CAREXIT     0X04
+#define LPI_I_RXCMD       0X08
+
+#define ULPI_VEND_LO      0X00
+#define ULPI_VEND_HI      0X01
+#define ULPI_PROD_LO      0X02
+#define ULPI_PROD_HI      0X03
+#define ULPI_FUN_CTL      0X04
+#define ULPI_IF_CTL       0X07
+#define ULPI_OTG_CTL      0X0A
+#define ULPI_INT_STA     0x13
+#define ULPI_INT_LATCH 0x14
+#define ULPI_DEBUG      0x15
+#define ULPI_SCRATCH      0X16
+#define ULPI_CAR_CTL      0X19
+#define ULPI_CAR_INT_DEL  0X1C
+#define ULPI_CAR_INT_EN   0X1D
+#define ULPI_CAR_INT_ST   0X20
+#define ULPI_CAR_INT_LA   0X21
+#define ULPI_CAR_PULSE    0X22
+#define ULPI_TX_POS_WID   0X25
+#define ULPI_TX_NEG_WID   0X26
+#define ULPI_RX_POLARITY  0X27
+
+
+
+#define ULPI_POW_CTRL     0x3D
+
+// Reset values for timers
+#define RST_REG_PHYWT     0X5C
+#define RST_REG_PHYTMVBUS 0X3C
+#define RST_REG_TMHSEOF1  0X80
+#define RST_REG_TMFSEOF1  0X77
+#define RST_REG_TMLSEOF1  0X72
+
+// Packet Buffer bits
+#define SINGLE          0
+#define DOUBLE          1
+#define EP0_OFFSET     0X040       // Initial 64 offset for EP0
+#define FIFOEIGHT       0      // Size bits for 8 byte FIFO
+#define FIFOSIXTEEN     1      // Size bits for 16 byte FIFO
+#define FIFOTHREETWO    2      // Size bits for 32 byte FIFO
+#define FIFOSIXFOUR     3      // Size bits for 64 byte FIFO
+#define EIGHT           0X08
+#define SIXTEEN         0X10
+#define THREETWO        0X20
+#define SIXFOUR         0X40
+
+// DMA Controller bits
+#define DMACNTRL_ENAB   0X0001
+#define DMACNTRL_DIR    0X0002
+#define DMACNTRL_MODE   0X0004
+#define DMACNTRL_INTE   0X0008
+#define DMACNTRL_ERR    0X0100
+#define DMACNTRL_INCR16 0X0600
+#define DMACNTRL_INCR8  0X0400
+#define DMACNTRL_INCR4  0X0200
+
+// MCU byte enables
+#define BE_8_0          1	// byte 0
+#define BE_8_1          2	// byte 1
+#define BE_8_2          4	// byte 2
+#define BE_8_3          8	// byte 3
+#define BE_16L		3	// lower word
+#define BE_16H		12	// upper word
+#define BE_32		15	// full 32-bits
+
+// MCU access sizes
+#define SIZE8		0
+#define SIZE16	1
+#define SIZE32	2
+
+// FIFO load modes
+
+#define FIFO_8LOW    0	// 8-bit low byte of bus
+#define FIFO_8CYC    1	// 8-bit cycle through bytes on bus
+#define FIFO_16LOW   2	// 16-bit low word of bus
+#define FIFO_16CYC   3	// 16-bit cycle through words on bus
+#define FIFO_32      4	// 32-bit
+#define FIFO_32IDLEs 5 // 32-bit with interleaving IDLE cycles
+
+// DMA burst modes
+#define DMABURST_INCR   0
+#define DMABURST_INCR4  1
+#define DMABURST_INCR8  2
+#define DMABURST_INCR16 3
+
+//Split token fields
+#define SPT_SSPLIT 0
+#define SPT_CSPLIT 1
+#define SPT_FS 0
+#define SPT_LS 1
+#define SPT_ALL 3
+#define SPT_BEG 1
+#define SPT_MID 0
+#define SPT_END 2
+
+// AHB address of MCUTxBuff
+#define AHB_ADDR_TXBUF  0X00010000
+
+// AHB address of MCURxBuff
+#define AHB_ADDR_RXBUF  0X00020000
+#define CYC (HCYC*2)		// Period of USB system clock
+#define HOLDDELAY (HCYC*5)	// Delay for gate level simulations
+#define AUTOACKDELAY 0.100  	// Delay for checking AutoAckEnab1 in wait_till_ack_sent task
+#define CHKCNTSDELAY 130.000 // Delay used in task CheckContinuous
+#define HCLK (HCLK0_CYC / 2)	
+
+#define HDEL (HCLK/2)           // AHB bus 'delay'
+#define CLK (HCLK*2)		// Period of CPU clock
+#define HSBIT (HCYC*2)		// USB high-speed bit period
+#define FSBIT (HCYC*80)	// USB full-speed bit period
+#define LSBIT (HCYC*640)	// USB low-speed bit period
+#define CHIRP (HSBIT*1216)	// HS detection chirp length (from host)
+#define DISPPER (HCYC*2)	// Output file sample period
+#define STROBE 0.0009		// Strobe period (offset from system clock)
+#define MICROSEC (HCYC*960)    // 1 micro second
+#define TBCHIRP (16*MICROSEC)  // Testbench auto chirp time
+#define MAX_WAIT_LNST (600*FSBIT) // Maximum time to wait for Linestate change from phy
+#define MAX_WAIT_FOR_INT (200 * HCLK)  // maximum time to wait for MCU interrupt
+#define MAX_TO_MC_NINT (200 * HCLK)  // maximum time to wait for MCU interrupt
+#define MAX_CORE_REG_UPDATE (UTM_CLK*8)  // maximum time for core to update it's registers
+
+#define CORE_ACTION_TIME (CLK*30)// Max time for register update to trigger request
+
+#define MAX_LS_NOTO (LSBIT*16)   // Max ip delay for no time out
+#define MIN_LS_TO (LSBIT*18)     // Minimum ip delay to give timeout
+#define MIN_LSIP_DEL (LSBIT*2)   // Minimum low-speed inter-packet delay
+#define TYP_LSIP_DEL (LSBIT*4)   // Typical low-speed inter-packet delay
+#define MAX_LSIP_DEL (LSBIT*7.5) // Maximum low-speed inter-packet delay (don't use!)
+#define MAX_LSHIP_DEL (LSBIT*7.5)// Maximum low-speed inter-packet delay for host response
+#define MAX_LSDIP_DEL (LSBIT*6.5)// Maximum low-speed inter-packet delay for device response
+#define LS_HNDSK_LEN (LSBIT*18)  // low speed handshake length (sync+pid+EOP)
+#define LS_TOKEN_LEN (LSBIT*36)  // low speed token length (sync+3 bytes+max 2 bits stuff+EOP)
+#define FS_PREAMBLE_LEN (FSBIT*21)  // Full speed preamble length (sync+1 + HSU)
+#define MAX_LS_PKT_LEN_TO (LSBIT*8*15) // Timeout from start of packet to end of packet
+
+
+#define MAX_FS_NOTO (FSBIT*16)   // Max ip delay for no time out
+#define MIN_FS_TO (FSBIT*18)     // Minimum ip delay to give timeout
+#define MIN_FSIP_DEL (FSBIT*2)   // Minimum full-speed inter-packet delay
+#define TYP_FSIP_DEL (FSBIT*4)   // Typical full-speed inter-packet delay
+#define MAX_FSIP_DEL (FSBIT*7.5) // Maximum full-speed inter-packet delay (don't use!)
+#define MAX_FSHIP_DEL (FSBIT*7.5)// Maximum full-speed inter-packet delay for host response
+#define MAX_FSDIP_DEL (FSBIT*6.5)// Maximum full-speed inter-packet delay for device response
+#define FS_HNDSK_LEN (FSBIT*18)  // Full speed handshake length (sync+pid+EOP)
+#define FS_TOKEN_LEN (FSBIT*36)  // Full speed token length (sync+3 bytes+max 2 bits stuff+EOP)
+#define MAX_FS_PKT_LEN_TO (FSBIT*8*1500) // Timeout from start of packet to end of packet
+
+#define MAX_HS_NOTO (HSBIT*734)   // Max ip delay for no time out
+#define MIN_HS_TO (HSBIT*816)     // Minimum ip delay to give timeout
+#define MIN_HSIP_DEL (HSBIT*8)   // Minimum high-speed inter-packet delay (different direction)
+#define MIN_HSIP_DEL_TX_TX (HSBIT*88)  // Minimum high-speed inter-packet delay (same direction)
+#define MIN_HSIT_DEL (HSBIT*32)  // Minimum high-speed inter-transaction delay
+#define TYP_HSIP_DEL (HSBIT*176) // Typical high-speed inter-packet delay
+#define MAX_HSIP_DEL (HSBIT*192) // Maximum high-speed inter-packet delay
+#define HS_HNDSK_LEN (HSBIT*48)  // High speed handshake length (32 bits sync+pid+EOP)
+#define HS_TOKEN_LEN (HSBIT*66)  // High speed token length (32 bits sync+3 bytes+max 2 bits stuff+EOP)
+#define HS_SOF_LEN (HSBIT*98)  // High speed token length (32 bits sync+3 bytes+max 2 bits stuff+long EOP)
+#define MAX_HS_PKT_LEN_TO (HSBIT*8*1500) // Timeout from start of packet to end of packet
+
+#define IDPULLUP_DEL (HSBIT*7500) // Delay for IDDIG to be valid (>15 us)
+
+// Speed of target device
+#define SPEED_HIGH 0X40
+#define SPEED_FULL 0X80
+#define SPEED_LOW 0Xc0
+
+#define TXCSR_MODE 0X2000
+#define TXCSR_TXPKTRDY 0X0001
+#define DFIFODPB 0X10
+#define REG_NULL 0X00
+
+#define REG_TXFUNCADDR_EP0 0X80
+#define REG_RXFUNCADDR_EP0 0X84
+#define REG_TXFUNCADDR_EP1 0X88
+#define REG_RXFUNCADDR_EP1 0X8c
+
+#define REG_TXFUNCADDR_EP2 0X90
+#define REG_RXFUNCADDR_EP2 0X94
+#define REG_TXFUNCADDR_EP3 0X98
+#define REG_RXFUNCADDR_EP3 0X9c
+
+#define REG_TXFUNCADDR_EP4 0Xa0
+#define REG_RXFUNCADDR_EP4 0Xa4
+#define REG_TXFUNCADDR_EP5 0Xa8
+#define REG_RXFUNCADDR_EP5 0Xac
+
+#define REG_TXFUNCADDR_EP6 0Xb0
+#define REG_RXFUNCADDR_EP6 0Xb4
+#define REG_TXFUNCADDR_EP7 0Xb8
+#define REG_RXFUNCADDR_EP7 0Xbc
+
+#define REG_TXFUNCADDR_EP8 0Xc0
+#define REG_RXFUNCADDR_EP8 0Xc4
+#define REG_TXFUNCADDR_EP9 0Xc8
+#define REG_RXFUNCADDR_EP9 0Xcc
+
+#define REG_TXFUNCADDR_EP10 0Xd0
+#define REG_RXFUNCADDR_EP10 0Xd4
+#define REG_TXFUNCADDR_EP11 0Xd8
+#define REG_RXFUNCADDR_EP11 0Xdc
+
+#define REG_TXFUNCADDR_EP12 0Xe0
+#define REG_RXFUNCADDR_EP12 0Xe4
+#define REG_TXFUNCADDR_EP13 0Xe8
+#define REG_RXFUNCADDR_EP13 0Xec
+
+#define REG_TXFUNCADDR_EP14 0Xf0
+#define REG_RXFUNCADDR_EP14 0Xf4
+#define REG_TXFUNCADDR_EP15 0Xf8
+#define REG_RXFUNCADDR_EP15 0Xfc
+
+#define REG_RXHUBADDR_EP0 0X86
+#define REG_RXHUBADDR_EP1 0X8e
+#define REG_RXHUBADDR_EP2 0X96
+#define REG_RXHUBADDR_EP3 0X9e
+#define REG_RXHUBADDR_EP4 0Xa6
+#define REG_RXHUBADDR_EP5 0Xae
+#define REG_RXHUBADDR_EP6 0Xb6
+#define REG_RXHUBADDR_EP7 0Xbe
+#define REG_RXHUBADDR_EP8 0Xc6
+#define REG_RXHUBADDR_EP9 0Xce
+#define REG_RXHUBADDR_EP10 0Xd6
+#define REG_RXHUBADDR_EP11 0Xde
+#define REG_RXHUBADDR_EP12 0Xe6
+#define REG_RXHUBADDR_EP13 0Xee
+#define REG_RXHUBADDR_EP14 0Xf6
+#define REG_RXHUBADDR_EP15 0Xfe
+
+#define REG_TXHUBADDR_EP0 0X82
+#define REG_TXHUBADDR_EP1 0X8a
+#define REG_TXHUBADDR_EP2 0X92
+#define REG_TXHUBADDR_EP3 0X9a
+#define REG_TXHUBADDR_EP4 0Xa2
+#define REG_TXHUBADDR_EP5 0Xaa
+#define REG_TXHUBADDR_EP6 0Xb2
+#define REG_TXHUBADDR_EP7 0Xba
+#define REG_TXHUBADDR_EP8 0Xc2
+#define REG_TXHUBADDR_EP9 0Xca
+#define REG_TXHUBADDR_EP10 0Xd2
+#define REG_TXHUBADDR_EP11 0Xda
+#define REG_TXHUBADDR_EP12 0Xe2
+#define REG_TXHUBADDR_EP13 0Xea
+#define REG_TXHUBADDR_EP14 0Xf2
+#define REG_TXHUBADDR_EP15 0Xfa
+
+#define REG_TXHUBPORT_EP0 0X83
+#define REG_TXHUBPORT_EP1 0X8b
+#define REG_TXHUBPORT_EP2 0X93
+#define REG_TXHUBPORT_EP3 0X9b
+#define REG_TXHUBPORT_EP4 0Xa3
+#define REG_TXHUBPORT_EP5 0Xab
+#define REG_TXHUBPORT_EP6 0Xb3
+#define REG_TXHUBPORT_EP7 0Xbb
+#define REG_TXHUBPORT_EP8 0Xc3
+#define REG_TXHUBPORT_EP9 0Xcb
+#define REG_TXHUBPORT_EP10 0Xd3
+#define REG_TXHUBPORT_EP11 0Xdb
+#define REG_TXHUBPORT_EP12 0Xe3
+#define REG_TXHUBPORT_EP13 0Xeb
+#define REG_TXHUBPORT_EP14 0Xf3
+#define REG_TXHUBPORT_EP15 0Xfb
+
+#define REG_RXHUBPORT_EP0 0X87
+#define REG_RXHUBPORT_EP1 0X8f
+#define REG_RXHUBPORT_EP2 0X97
+#define REG_RXHUBPORT_EP3 0X9f
+#define REG_RXHUBPORT_EP4 0Xa7
+#define REG_RXHUBPORT_EP5 0Xaf
+#define REG_RXHUBPORT_EP6 0Xb7
+#define REG_RXHUBPORT_EP7 0Xbf
+#define REG_RXHUBPORT_EP8 0Xc7
+#define REG_RXHUBPORT_EP9 0Xcf
+#define REG_RXHUBPORT_EP10 0Xd7
+#define REG_RXHUBPORT_EP11 0Xdf
+#define REG_RXHUBPORT_EP12 0Xe7
+#define REG_RXHUBPORT_EP13 0Xef
+#define REG_RXHUBPORT_EP14 0Xf7
+#define REG_RXHUBPORT_EP15 0Xff
+
+#define EP_NUM_EP0  0x0		/* Endpoint number */
+
+#endif /* end of __USB_DEFS_H__ */
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/version_svn.h u-boot-2011.06/include/version_svn.h
--- u-boot-2011.06_original/include/version_svn.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/version_svn.h	2016-03-24 10:30:50.193185969 +0800
@@ -0,0 +1 @@
+-svn17913
\ No newline at end of file
diff '--exclude=.svn' -Naur u-boot-2011.06_original/include/x_clib.h u-boot-2011.06/include/x_clib.h
--- u-boot-2011.06_original/include/x_clib.h	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/include/x_clib.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,18 @@
+#ifndef _X_CLIB_H_
+#define _X_CLIB_H_
+
+/* Define NULL pointer value */
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+void* x_memcpy(void *s1, const void *s2, int n);
+int  x_memcmp(const void* s1, const void* s2, int n);
+void* x_memset(void *s, int c, int n);
+unsigned int udivsi3(unsigned int num, unsigned int den);
+
+#endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/asn1parse.c u-boot-2011.06/lib/asn1parse.c
--- u-boot-2011.06_original/lib/asn1parse.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/asn1parse.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,392 @@
+/*
+ *  Generic ASN.1 parsing
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_ASN1_PARSE_C)
+
+#include "asn1.h"
+
+#if defined(POLARSSL_BIGNUM_C)
+#include "bignum.h"
+#endif
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "platform.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
+#include <linux/string.h>
+#include <common.h>
+#include <malloc.h>
+
+/*
+ * ASN.1 DER decoding routines
+ */
+int asn1_get_len( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len )
+{
+    if( ( end - *p ) < 1 )
+        return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+    if( ( **p & 0x80 ) == 0 )
+        *len = *(*p)++;
+    else
+    {
+        switch( **p & 0x7F )
+        {
+        case 1:
+            if( ( end - *p ) < 2 )
+                return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+            *len = (*p)[1];
+            (*p) += 2;
+            break;
+
+        case 2:
+            if( ( end - *p ) < 3 )
+                return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (*p)[1] << 8 ) | (*p)[2];
+            (*p) += 3;
+            break;
+
+        case 3:
+            if( ( end - *p ) < 4 )
+                return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
+            (*p) += 4;
+            break;
+
+        case 4:
+            if( ( end - *p ) < 5 )
+                return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
+                   (*p)[4];
+            (*p) += 5;
+            break;
+
+        default:
+            return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+        }
+    }
+
+    if( *len > (size_t) ( end - *p ) )
+        return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+    return( 0 );
+}
+
+int asn1_get_tag( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len, int tag )
+{
+    if( ( end - *p ) < 1 )
+        return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+    if( **p != tag )
+        return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
+
+    (*p)++;
+
+    return( asn1_get_len( p, end, len ) );
+}
+
+int asn1_get_bool( unsigned char **p,
+                   const unsigned char *end,
+                   int *val )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
+        return( ret );
+
+    if( len != 1 )
+        return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+
+    *val = ( **p != 0 ) ? 1 : 0;
+    (*p)++;
+
+    return( 0 );
+}
+
+int asn1_get_int( unsigned char **p,
+                  const unsigned char *end,
+                  int *val )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
+        return( ret );
+
+    if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+        return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+
+    *val = 0;
+
+    while( len-- > 0 )
+    {
+        *val = ( *val << 8 ) | **p;
+        (*p)++;
+    }
+
+    return( 0 );
+}
+
+#if defined(POLARSSL_BIGNUM_C)
+int asn1_get_mpi( unsigned char **p,
+                  const unsigned char *end,
+                  mpi *X )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
+        return( ret );
+
+    ret = mpi_read_binary( X, *p, len );
+
+    *p += len;
+
+    return( ret );
+}
+#endif /* POLARSSL_BIGNUM_C */
+
+int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
+                        asn1_bitstring *bs)
+{
+    int ret;
+
+    /* Certificate type is a single byte bitstring */
+    if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
+        return( ret );
+
+    /* Check length, subtract one for actual bit string length */
+    if ( bs->len < 1 )
+        return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+    bs->len -= 1;
+
+    /* Get number of unused bits, ensure unused bits <= 7 */
+    bs->unused_bits = **p;
+    if( bs->unused_bits > 7 )
+        return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+    (*p)++;
+
+    /* Get actual bitstring */
+    bs->p = *p;
+    *p += bs->len;
+
+    if( *p != end )
+        return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+
+    return 0;
+}
+
+/*
+ * Get a bit string without unused bits
+ */
+int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+                             size_t *len )
+{
+    int ret;
+
+    if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
+        return( ret );
+
+    if( (*len)-- < 2 || *(*p)++ != 0 )
+        return( POLARSSL_ERR_ASN1_INVALID_DATA );
+
+    return( 0 );
+}
+
+
+
+/*
+ *  Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ */
+int asn1_get_sequence_of( unsigned char **p,
+                          const unsigned char *end,
+                          asn1_sequence *cur,
+                          int tag)
+{
+    int ret;
+    size_t len;
+    asn1_buf *buf;
+
+    /* Get main sequence tag */
+    if( ( ret = asn1_get_tag( p, end, &len,
+            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    if( *p + len != end )
+        return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+
+    while( *p < end )
+    {
+        buf = &(cur->buf);
+        buf->tag = **p;
+
+        if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
+            return( ret );
+
+        buf->p = *p;
+        *p += buf->len;
+
+        /* Allocate and assign next pointer */
+        if (*p < end)
+        {
+            cur->next = (asn1_sequence *) polarssl_malloc(
+                 sizeof( asn1_sequence ) );
+
+            if( cur->next == NULL )
+                return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
+
+            cur = cur->next;
+        }
+    }
+
+    /* Set final sequence entry's next pointer to NULL */
+    cur->next = NULL;
+
+    if( *p != end )
+        return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+int asn1_get_alg( unsigned char **p,
+                  const unsigned char *end,
+                  asn1_buf *alg, asn1_buf *params )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = asn1_get_tag( p, end, &len,
+            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    if( ( end - *p ) < 1 )
+        return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+    alg->tag = **p;
+    end = *p + len;
+
+    if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
+        return( ret );
+
+    alg->p = *p;
+    *p += alg->len;
+
+    if( *p == end )
+    {
+        memset( params, 0, sizeof(asn1_buf) );
+        return( 0 );
+    }
+
+    params->tag = **p;
+    (*p)++;
+
+    if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
+        return( ret );
+
+    params->p = *p;
+    *p += params->len;
+
+    if( *p != end )
+        return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+int asn1_get_alg_null( unsigned char **p,
+                       const unsigned char *end,
+                       asn1_buf *alg )
+{
+    int ret;
+    asn1_buf params;
+
+    memset( &params, 0, sizeof(asn1_buf) );
+
+    if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
+        return( ret );
+
+    if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
+        return( POLARSSL_ERR_ASN1_INVALID_DATA );
+
+    return( 0 );
+}
+
+void asn1_free_named_data( asn1_named_data *cur )
+{
+    if( cur == NULL )
+        return;
+
+    polarssl_free( cur->oid.p );
+    polarssl_free( cur->val.p );
+
+    memset( cur, 0, sizeof( asn1_named_data ) );
+}
+
+void asn1_free_named_data_list( asn1_named_data **head )
+{
+    asn1_named_data *cur;
+
+    while( ( cur = *head ) != NULL )
+    {
+        *head = cur->next;
+        asn1_free_named_data( cur );
+        polarssl_free( cur );
+    }
+}
+
+asn1_named_data *asn1_find_named_data( asn1_named_data *list,
+                                       const char *oid, size_t len )
+{
+    while( list != NULL )
+    {
+        if( list->oid.len == len &&
+            memcmp( list->oid.p, oid, len ) == 0 )
+        {
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return( list );
+}
+
+#endif /* POLARSSL_ASN1_PARSE_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/bignum.c u-boot-2011.06/lib/bignum.c
--- u-boot-2011.06_original/lib/bignum.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/bignum.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,2341 @@
+/*
+ *  Multi-precision integer library
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+/*
+ *  This MPI implementation is based on:
+ *
+ *  http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ *  http://www.stillhq.com/extracted/gnupg-api/mpi/
+ *  http://math.libtomcrypt.com/files/tommath.pdf
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_BIGNUM_C)
+
+#include <common.h>
+#include <malloc.h>
+#include "bignum.h"
+#include "bn_mul.h"
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "platform.h"
+#else
+#define polarssl_printf     printf
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
+//#include <stdlib.h>
+
+#define ciL    (sizeof(t_uint))         /* chars in limb  */
+#define biL    (ciL << 3)               /* bits  in limb  */
+#define biH    (ciL << 2)               /* half limb size */
+
+/*
+ * Convert between bits/chars and number of limbs
+ */
+#define BITS_TO_LIMBS(i)  (((i) + biL - 1) / biL)
+#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
+
+/*
+ * Initialize one MPI
+ */
+void mpi_init( mpi *X )
+{
+    if( X == NULL )
+        return;
+
+    X->s = 1;
+    X->n = 0;
+    X->p = NULL;
+}
+
+/*
+ * Unallocate one MPI
+ */
+void mpi_free( mpi *X )
+{
+    if( X == NULL )
+        return;
+
+    if( X->p != NULL )
+    {
+        memset( X->p, 0, X->n * ciL );
+        polarssl_free( X->p );
+    }
+
+    X->s = 1;
+    X->n = 0;
+    X->p = NULL;
+}
+
+/*
+ * Enlarge to the specified number of limbs
+ */
+int mpi_grow( mpi *X, size_t nblimbs )
+{
+    t_uint *p;
+
+    if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
+        return( POLARSSL_ERR_MPI_MALLOC_FAILED );
+
+    if( X->n < nblimbs )
+    {
+        if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
+            return( POLARSSL_ERR_MPI_MALLOC_FAILED );
+
+        memset( p, 0, nblimbs * ciL );
+
+        if( X->p != NULL )
+        {
+            memcpy( p, X->p, X->n * ciL );
+            memset( X->p, 0, X->n * ciL );
+            polarssl_free( X->p );
+        }
+
+        X->n = nblimbs;
+        X->p = p;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Resize down as much as possible,
+ * while keeping at least the specified number of limbs
+ */
+int mpi_shrink( mpi *X, size_t nblimbs )
+{
+    t_uint *p;
+    size_t i;
+
+    /* Actually resize up in this case */
+    if( X->n <= nblimbs )
+        return( mpi_grow( X, nblimbs ) );
+
+    for( i = X->n - 1; i > 0; i-- )
+        if( X->p[i] != 0 )
+            break;
+    i++;
+
+    if( i < nblimbs )
+        i = nblimbs;
+
+    if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
+        return( POLARSSL_ERR_MPI_MALLOC_FAILED );
+
+    memset( p, 0, i * ciL );
+
+    if( X->p != NULL )
+    {
+        memcpy( p, X->p, i * ciL );
+        memset( X->p, 0, X->n * ciL );
+        polarssl_free( X->p );
+    }
+
+    X->n = i;
+    X->p = p;
+
+    return( 0 );
+}
+
+/*
+ * Copy the contents of Y into X
+ */
+int mpi_copy( mpi *X, const mpi *Y )
+{
+    int ret;
+    size_t i;
+
+    if( X == Y )
+        return( 0 );
+
+    if( Y->p == NULL )
+    {
+        mpi_free( X );
+        return( 0 );
+    }
+
+    for( i = Y->n - 1; i > 0; i-- )
+        if( Y->p[i] != 0 )
+            break;
+    i++;
+
+    X->s = Y->s;
+
+    MPI_CHK( mpi_grow( X, i ) );
+
+    memset( X->p, 0, X->n * ciL );
+    memcpy( X->p, Y->p, i * ciL );
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Swap the contents of X and Y
+ */
+void mpi_swap( mpi *X, mpi *Y )
+{
+    mpi T;
+
+    memcpy( &T,  X, sizeof( mpi ) );
+    memcpy(  X,  Y, sizeof( mpi ) );
+    memcpy(  Y, &T, sizeof( mpi ) );
+}
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
+{
+    int ret = 0;
+    size_t i;
+
+    /* make sure assign is 0 or 1 */
+    assign = ( assign != 0 );
+
+    MPI_CHK( mpi_grow( X, Y->n ) );
+
+    X->s = X->s * (1 - assign) + Y->s * assign;
+
+    for( i = 0; i < Y->n; i++ )
+        X->p[i] = X->p[i] * (1 - assign) + Y->p[i] * assign;
+
+    for( ; i < X->n; i++ )
+        X->p[i] *= (1 - assign);
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which whould lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
+{
+    int ret, s;
+    size_t i;
+    t_uint tmp;
+
+    if( X == Y )
+        return( 0 );
+
+    /* make sure swap is 0 or 1 */
+    swap = ( swap != 0 );
+
+    MPI_CHK( mpi_grow( X, Y->n ) );
+    MPI_CHK( mpi_grow( Y, X->n ) );
+
+    s = X->s;
+    X->s = X->s * (1 - swap) + Y->s * swap;
+    Y->s = Y->s * (1 - swap) +    s * swap;
+
+
+    for( i = 0; i < X->n; i++ )
+    {
+        tmp = X->p[i];
+        X->p[i] = X->p[i] * (1 - swap) + Y->p[i] * swap;
+        Y->p[i] = Y->p[i] * (1 - swap) +     tmp * swap;
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Set value from integer
+ */
+int mpi_lset( mpi *X, t_sint z )
+{
+    int ret;
+
+    MPI_CHK( mpi_grow( X, 1 ) );
+    memset( X->p, 0, X->n * ciL );
+
+    X->p[0] = ( z < 0 ) ? -z : z;
+    X->s    = ( z < 0 ) ? -1 : 1;
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Get a specific bit
+ */
+int mpi_get_bit( const mpi *X, size_t pos )
+{
+    if( X->n * biL <= pos )
+        return( 0 );
+
+    return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
+}
+
+/*
+ * Set a bit to a specific value of 0 or 1
+ */
+int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
+{
+    int ret = 0;
+    size_t off = pos / biL;
+    size_t idx = pos % biL;
+
+    if( val != 0 && val != 1 )
+        return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
+
+    if( X->n * biL <= pos )
+    {
+        if( val == 0 )
+            return ( 0 );
+
+        MPI_CHK( mpi_grow( X, off + 1 ) );
+    }
+
+    X->p[off] &= ~( (t_uint) 0x01 << idx );
+    X->p[off] |= (t_uint) val << idx;
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Return the number of least significant bits
+ */
+size_t mpi_lsb( const mpi *X )
+{
+    size_t i, j, count = 0;
+
+    for( i = 0; i < X->n; i++ )
+        for( j = 0; j < biL; j++, count++ )
+            if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+                return( count );
+
+    return( 0 );
+}
+
+/*
+ * Return the number of most significant bits
+ */
+size_t mpi_msb( const mpi *X )
+{
+    size_t i, j;
+
+    for( i = X->n - 1; i > 0; i-- )
+        if( X->p[i] != 0 )
+            break;
+
+    for( j = biL; j > 0; j-- )
+        if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
+            break;
+
+    return( ( i * biL ) + j );
+}
+
+/*
+ * Return the total size in bytes
+ */
+size_t mpi_size( const mpi *X )
+{
+    return( ( mpi_msb( X ) + 7 ) >> 3 );
+}
+
+/*
+ * Convert an ASCII character to digit value
+ */
+static int mpi_get_digit( t_uint *d, int radix, char c )
+{
+    *d = 255;
+
+    if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
+    if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
+    if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
+
+    if( *d >= (t_uint) radix )
+        return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
+
+    return( 0 );
+}
+
+/*
+ * Import from an ASCII string
+ */
+int mpi_read_string( mpi *X, int radix, const char *s )
+{
+    int ret;
+    size_t i, j, slen, n;
+    t_uint d;
+    mpi T;
+
+    if( radix < 2 || radix > 16 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    mpi_init( &T );
+
+    slen = strlen( s );
+
+    if( radix == 16 )
+    {
+        n = BITS_TO_LIMBS( slen << 2 );
+
+        MPI_CHK( mpi_grow( X, n ) );
+        MPI_CHK( mpi_lset( X, 0 ) );
+
+        for( i = slen, j = 0; i > 0; i--, j++ )
+        {
+            if( i == 1 && s[i - 1] == '-' )
+            {
+                X->s = -1;
+                break;
+            }
+
+            MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
+            X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
+        }
+    }
+    else
+    {
+        MPI_CHK( mpi_lset( X, 0 ) );
+
+        for( i = 0; i < slen; i++ )
+        {
+            if( i == 0 && s[i] == '-' )
+            {
+                X->s = -1;
+                continue;
+            }
+
+            MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+            MPI_CHK( mpi_mul_int( &T, X, radix ) );
+
+            if( X->s == 1 )
+            {
+                MPI_CHK( mpi_add_int( X, &T, d ) );
+            }
+            else
+            {
+                MPI_CHK( mpi_sub_int( X, &T, d ) );
+            }
+        }
+    }
+
+cleanup:
+
+    mpi_free( &T );
+
+    return( ret );
+}
+
+/*
+ * Helper to write the digits high-order first
+ */
+static int mpi_write_hlp( mpi *X, int radix, char **p )
+{
+    int ret;
+    t_uint r;
+
+    if( radix < 2 || radix > 16 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    MPI_CHK( mpi_mod_int( &r, X, radix ) );
+    MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
+
+    if( mpi_cmp_int( X, 0 ) != 0 )
+        MPI_CHK( mpi_write_hlp( X, radix, p ) );
+
+    if( r < 10 )
+        *(*p)++ = (char)( r + 0x30 );
+    else
+        *(*p)++ = (char)( r + 0x37 );
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Export into an ASCII string
+ */
+int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
+{
+    int ret = 0;
+    size_t n;
+    char *p;
+    mpi T;
+
+    if( radix < 2 || radix > 16 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    n = mpi_msb( X );
+    if( radix >=  4 ) n >>= 1;
+    if( radix >= 16 ) n >>= 1;
+    n += 3;
+
+    if( *slen < n )
+    {
+        *slen = n;
+        return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+    }
+
+    p = s;
+    mpi_init( &T );
+
+    if( X->s == -1 )
+        *p++ = '-';
+
+    if( radix == 16 )
+    {
+        int c;
+        size_t i, j, k;
+
+        for( i = X->n, k = 0; i > 0; i-- )
+        {
+            for( j = ciL; j > 0; j-- )
+            {
+                c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
+
+                if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
+                    continue;
+
+                *(p++) = "0123456789ABCDEF" [c / 16];
+                *(p++) = "0123456789ABCDEF" [c % 16];
+                k = 1;
+            }
+        }
+    }
+    else
+    {
+        MPI_CHK( mpi_copy( &T, X ) );
+
+        if( T.s == -1 )
+            T.s = 1;
+
+        MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
+    }
+
+    *p++ = '\0';
+    *slen = p - s;
+
+cleanup:
+
+    mpi_free( &T );
+
+    return( ret );
+}
+
+#if defined(POLARSSL_FS_IO)
+/*
+ * Read X from an opened file
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin )
+{
+    t_uint d;
+    size_t slen;
+    char *p;
+    /*
+     * Buffer should have space for (short) label and decimal formatted MPI,
+     * newline characters and '\0'
+     */
+    char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
+
+    memset( s, 0, sizeof( s ) );
+    if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
+        return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+
+    slen = strlen( s );
+    if( slen == sizeof( s ) - 2 )
+        return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+
+    if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
+    if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
+
+    p = s + slen;
+    while( --p >= s )
+        if( mpi_get_digit( &d, radix, *p ) != 0 )
+            break;
+
+    return( mpi_read_string( X, radix, p + 1 ) );
+}
+
+/*
+ * Write X into an opened file (or stdout if fout == NULL)
+ */
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
+{
+    int ret;
+    size_t n, slen, plen;
+    /*
+     * Buffer should have space for (short) label and decimal formatted MPI,
+     * newline characters and '\0'
+     */
+    char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
+
+    n = sizeof( s );
+    memset( s, 0, n );
+    n -= 2;
+
+    MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
+
+    if( p == NULL ) p = "";
+
+    plen = strlen( p );
+    slen = strlen( s );
+    s[slen++] = '\r';
+    s[slen++] = '\n';
+
+    if( fout != NULL )
+    {
+        if( fwrite( p, 1, plen, fout ) != plen ||
+            fwrite( s, 1, slen, fout ) != slen )
+            return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+    }
+    else
+        polarssl_printf( "%s%s", p, s );
+
+cleanup:
+
+    return( ret );
+}
+#endif /* POLARSSL_FS_IO */
+
+/*
+ * Import X from unsigned binary data, big endian
+ */
+int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
+{
+    int ret;
+    size_t i, j, n;
+
+    for( n = 0; n < buflen; n++ )
+        if( buf[n] != 0 )
+            break;
+
+    MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
+    MPI_CHK( mpi_lset( X, 0 ) );
+
+    for( i = buflen, j = 0; i > n; i--, j++ )
+        X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Export X into unsigned binary data, big endian
+ */
+int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
+{
+    size_t i, j, n;
+
+    n = mpi_size( X );
+
+    if( buflen < n )
+        return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+
+    memset( buf, 0, buflen );
+
+    for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
+        buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
+
+    return( 0 );
+}
+
+/*
+ * Left-shift: X <<= count
+ */
+int mpi_shift_l( mpi *X, size_t count )
+{
+    int ret;
+    size_t i, v0, t1;
+    t_uint r0 = 0, r1;
+
+    v0 = count / (biL    );
+    t1 = count & (biL - 1);
+
+    i = mpi_msb( X ) + count;
+
+    if( X->n * biL < i )
+        MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
+
+    ret = 0;
+
+    /*
+     * shift by count / limb_size
+     */
+    if( v0 > 0 )
+    {
+        for( i = X->n; i > v0; i-- )
+            X->p[i - 1] = X->p[i - v0 - 1];
+
+        for( ; i > 0; i-- )
+            X->p[i - 1] = 0;
+    }
+
+    /*
+     * shift by count % limb_size
+     */
+    if( t1 > 0 )
+    {
+        for( i = v0; i < X->n; i++ )
+        {
+            r1 = X->p[i] >> (biL - t1);
+            X->p[i] <<= t1;
+            X->p[i] |= r0;
+            r0 = r1;
+        }
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Right-shift: X >>= count
+ */
+int mpi_shift_r( mpi *X, size_t count )
+{
+    size_t i, v0, v1;
+    t_uint r0 = 0, r1;
+
+    v0 = count /  biL;
+    v1 = count & (biL - 1);
+
+    if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
+        return mpi_lset( X, 0 );
+
+    /*
+     * shift by count / limb_size
+     */
+    if( v0 > 0 )
+    {
+        for( i = 0; i < X->n - v0; i++ )
+            X->p[i] = X->p[i + v0];
+
+        for( ; i < X->n; i++ )
+            X->p[i] = 0;
+    }
+
+    /*
+     * shift by count % limb_size
+     */
+    if( v1 > 0 )
+    {
+        for( i = X->n; i > 0; i-- )
+        {
+            r1 = X->p[i - 1] << (biL - v1);
+            X->p[i - 1] >>= v1;
+            X->p[i - 1] |= r0;
+            r0 = r1;
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare unsigned values
+ */
+int mpi_cmp_abs( const mpi *X, const mpi *Y )
+{
+    size_t i, j;
+
+    for( i = X->n; i > 0; i-- )
+        if( X->p[i - 1] != 0 )
+            break;
+
+    for( j = Y->n; j > 0; j-- )
+        if( Y->p[j - 1] != 0 )
+            break;
+
+    if( i == 0 && j == 0 )
+        return( 0 );
+
+    if( i > j ) return(  1 );
+    if( j > i ) return( -1 );
+
+    for( ; i > 0; i-- )
+    {
+        if( X->p[i - 1] > Y->p[i - 1] ) return(  1 );
+        if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_mpi( const mpi *X, const mpi *Y )
+{
+    size_t i, j;
+
+    for( i = X->n; i > 0; i-- )
+        if( X->p[i - 1] != 0 )
+            break;
+
+    for( j = Y->n; j > 0; j-- )
+        if( Y->p[j - 1] != 0 )
+            break;
+
+    if( i == 0 && j == 0 )
+        return( 0 );
+
+    if( i > j ) return(  X->s );
+    if( j > i ) return( -Y->s );
+
+    if( X->s > 0 && Y->s < 0 ) return(  1 );
+    if( Y->s > 0 && X->s < 0 ) return( -1 );
+
+    for( ; i > 0; i-- )
+    {
+        if( X->p[i - 1] > Y->p[i - 1] ) return(  X->s );
+        if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_int( const mpi *X, t_sint z )
+{
+    mpi Y;
+    t_uint p[1];
+
+    *p  = ( z < 0 ) ? -z : z;
+    Y.s = ( z < 0 ) ? -1 : 1;
+    Y.n = 1;
+    Y.p = p;
+
+    return( mpi_cmp_mpi( X, &Y ) );
+}
+
+/*
+ * Unsigned addition: X = |A| + |B|  (HAC 14.7)
+ */
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
+{
+    int ret;
+    size_t i, j;
+    t_uint *o, *p, c;
+
+    if( X == B )
+    {
+        const mpi *T = A; A = X; B = T;
+    }
+
+    if( X != A )
+        MPI_CHK( mpi_copy( X, A ) );
+
+    /*
+     * X should always be positive as a result of unsigned additions.
+     */
+    X->s = 1;
+
+    for( j = B->n; j > 0; j-- )
+        if( B->p[j - 1] != 0 )
+            break;
+
+    MPI_CHK( mpi_grow( X, j ) );
+
+    o = B->p; p = X->p; c = 0;
+
+    for( i = 0; i < j; i++, o++, p++ )
+    {
+        *p +=  c; c  = ( *p <  c );
+        *p += *o; c += ( *p < *o );
+    }
+
+    while( c != 0 )
+    {
+        if( i >= X->n )
+        {
+            MPI_CHK( mpi_grow( X, i + 1 ) );
+            p = X->p + i;
+        }
+
+        *p += c; c = ( *p < c ); i++; p++;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Helper for mpi subtraction
+ */
+static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
+{
+    size_t i;
+    t_uint c, z;
+
+    for( i = c = 0; i < n; i++, s++, d++ )
+    {
+        z = ( *d <  c );     *d -=  c;
+        c = ( *d < *s ) + z; *d -= *s;
+    }
+
+    while( c != 0 )
+    {
+        z = ( *d < c ); *d -= c;
+        c = z; i++; d++;
+    }
+}
+
+/*
+ * Unsigned subtraction: X = |A| - |B|  (HAC 14.9)
+ */
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
+{
+    mpi TB;
+    int ret;
+    size_t n;
+
+    if( mpi_cmp_abs( A, B ) < 0 )
+        return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
+
+    mpi_init( &TB );
+
+    if( X == B )
+    {
+        MPI_CHK( mpi_copy( &TB, B ) );
+        B = &TB;
+    }
+
+    if( X != A )
+        MPI_CHK( mpi_copy( X, A ) );
+
+    /*
+     * X should always be positive as a result of unsigned subtractions.
+     */
+    X->s = 1;
+
+    ret = 0;
+
+    for( n = B->n; n > 0; n-- )
+        if( B->p[n - 1] != 0 )
+            break;
+
+    mpi_sub_hlp( n, B->p, X->p );
+
+cleanup:
+
+    mpi_free( &TB );
+
+    return( ret );
+}
+
+/*
+ * Signed addition: X = A + B
+ */
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+    int ret, s = A->s;
+
+    if( A->s * B->s < 0 )
+    {
+        if( mpi_cmp_abs( A, B ) >= 0 )
+        {
+            MPI_CHK( mpi_sub_abs( X, A, B ) );
+            X->s =  s;
+        }
+        else
+        {
+            MPI_CHK( mpi_sub_abs( X, B, A ) );
+            X->s = -s;
+        }
+    }
+    else
+    {
+        MPI_CHK( mpi_add_abs( X, A, B ) );
+        X->s = s;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Signed subtraction: X = A - B
+ */
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+    int ret, s = A->s;
+
+    if( A->s * B->s > 0 )
+    {
+        if( mpi_cmp_abs( A, B ) >= 0 )
+        {
+            MPI_CHK( mpi_sub_abs( X, A, B ) );
+            X->s =  s;
+        }
+        else
+        {
+            MPI_CHK( mpi_sub_abs( X, B, A ) );
+            X->s = -s;
+        }
+    }
+    else
+    {
+        MPI_CHK( mpi_add_abs( X, A, B ) );
+        X->s = s;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Signed addition: X = A + b
+ */
+int mpi_add_int( mpi *X, const mpi *A, t_sint b )
+{
+    mpi _B;
+    t_uint p[1];
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mpi_add_mpi( X, A, &_B ) );
+}
+
+/*
+ * Signed subtraction: X = A - b
+ */
+int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
+{
+    mpi _B;
+    t_uint p[1];
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mpi_sub_mpi( X, A, &_B ) );
+}
+
+/*
+ * Helper for mpi multiplication
+ */
+static
+#if defined(__APPLE__) && defined(__arm__)
+/*
+ * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
+ * appears to need this to prevent bad ARM code generation at -O3.
+ */
+__attribute__ ((noinline))
+#endif
+void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
+{
+    t_uint c = 0, t = 0;
+
+#if defined(MULADDC_HUIT)
+    for( ; i >= 8; i -= 8 )
+    {
+        MULADDC_INIT
+        MULADDC_HUIT
+        MULADDC_STOP
+    }
+
+    for( ; i > 0; i-- )
+    {
+        MULADDC_INIT
+        MULADDC_CORE
+        MULADDC_STOP
+    }
+#else /* MULADDC_HUIT */
+    for( ; i >= 16; i -= 16 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    for( ; i >= 8; i -= 8 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    for( ; i > 0; i-- )
+    {
+        MULADDC_INIT
+        MULADDC_CORE
+        MULADDC_STOP
+    }
+#endif /* MULADDC_HUIT */
+
+    t++;
+
+    do {
+        *d += c; c = ( *d < c ); d++;
+    }
+    while( c != 0 );
+}
+
+/*
+ * Baseline multiplication: X = A * B  (HAC 14.12)
+ */
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+    int ret;
+    size_t i, j;
+    mpi TA, TB;
+
+    mpi_init( &TA ); mpi_init( &TB );
+
+    if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
+    if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
+
+    for( i = A->n; i > 0; i-- )
+        if( A->p[i - 1] != 0 )
+            break;
+
+    for( j = B->n; j > 0; j-- )
+        if( B->p[j - 1] != 0 )
+            break;
+
+    MPI_CHK( mpi_grow( X, i + j ) );
+    MPI_CHK( mpi_lset( X, 0 ) );
+
+    for( i++; j > 0; j-- )
+        mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
+
+    X->s = A->s * B->s;
+
+cleanup:
+
+    mpi_free( &TB ); mpi_free( &TA );
+
+    return( ret );
+}
+
+/*
+ * Baseline multiplication: X = A * b
+ */
+int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
+{
+    mpi _B;
+    t_uint p[1];
+
+    _B.s = 1;
+    _B.n = 1;
+    _B.p = p;
+    p[0] = b;
+
+    return( mpi_mul_mpi( X, A, &_B ) );
+}
+
+/*
+ * Division by mpi: A = Q * B + R  (HAC 14.20)
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
+{
+    int ret;
+    size_t i, n, t, k;
+    mpi X, Y, Z, T1, T2;
+
+    if( mpi_cmp_int( B, 0 ) == 0 )
+        return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+    mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
+    mpi_init( &T1 ); mpi_init( &T2 );
+
+    if( mpi_cmp_abs( A, B ) < 0 )
+    {
+        if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
+        if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
+        return( 0 );
+    }
+
+    MPI_CHK( mpi_copy( &X, A ) );
+    MPI_CHK( mpi_copy( &Y, B ) );
+    X.s = Y.s = 1;
+
+    MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
+    MPI_CHK( mpi_lset( &Z,  0 ) );
+    MPI_CHK( mpi_grow( &T1, 2 ) );
+    MPI_CHK( mpi_grow( &T2, 3 ) );
+
+    k = mpi_msb( &Y ) % biL;
+    if( k < biL - 1 )
+    {
+        k = biL - 1 - k;
+        MPI_CHK( mpi_shift_l( &X, k ) );
+        MPI_CHK( mpi_shift_l( &Y, k ) );
+    }
+    else k = 0;
+
+    n = X.n - 1;
+    t = Y.n - 1;
+    MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
+
+    while( mpi_cmp_mpi( &X, &Y ) >= 0 )
+    {
+        Z.p[n - t]++;
+        MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
+    }
+    MPI_CHK( mpi_shift_r( &Y, biL * (n - t) ) );
+
+    for( i = n; i > t ; i-- )
+    {
+        if( X.p[i] >= Y.p[t] )
+            Z.p[i - t - 1] = ~0;
+        else
+        {
+            /*
+             * The version of Clang shipped by Apple with Mavericks around
+             * 2014-03 can't handle 128-bit division properly. Disable
+             * 128-bits division for this version. Let's be optimistic and
+             * assume it'll be fixed in the next minor version (next
+             * patchlevel is probably a bit too optimistic).
+             */
+#if defined(POLARSSL_HAVE_UDBL) &&                          \
+    ! ( defined(__x86_64__) && defined(__APPLE__) &&        \
+        defined(__clang_major__) && __clang_major__ == 5 && \
+        defined(__clang_minor__) && __clang_minor__ == 0 )
+            t_udbl r;
+
+            r  = (t_udbl) X.p[i] << biL;
+            r |= (t_udbl) X.p[i - 1];
+            r /= Y.p[t];
+            if( r > ((t_udbl) 1 << biL) - 1)
+                r = ((t_udbl) 1 << biL) - 1;
+
+            Z.p[i - t - 1] = (t_uint) r;
+#else
+            /*
+             * __udiv_qrnnd_c, from gmp/longlong.h
+             */
+            t_uint q0, q1, r0, r1;
+            t_uint d0, d1, d, m;
+
+            d  = Y.p[t];
+            d0 = ( d << biH ) >> biH;
+            d1 = ( d >> biH );
+
+            q1 = X.p[i] / d1;
+            r1 = X.p[i] - d1 * q1;
+            r1 <<= biH;
+            r1 |= ( X.p[i - 1] >> biH );
+
+            m = q1 * d0;
+            if( r1 < m )
+            {
+                q1--, r1 += d;
+                while( r1 >= d && r1 < m )
+                    q1--, r1 += d;
+            }
+            r1 -= m;
+
+            q0 = r1 / d1;
+            r0 = r1 - d1 * q0;
+            r0 <<= biH;
+            r0 |= ( X.p[i - 1] << biH ) >> biH;
+
+            m = q0 * d0;
+            if( r0 < m )
+            {
+                q0--, r0 += d;
+                while( r0 >= d && r0 < m )
+                    q0--, r0 += d;
+            }
+            r0 -= m;
+
+            Z.p[i - t - 1] = ( q1 << biH ) | q0;
+#endif
+        }
+
+        Z.p[i - t - 1]++;
+        do
+        {
+            Z.p[i - t - 1]--;
+
+            MPI_CHK( mpi_lset( &T1, 0 ) );
+            T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
+            T1.p[1] = Y.p[t];
+            MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
+
+            MPI_CHK( mpi_lset( &T2, 0 ) );
+            T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
+            T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
+            T2.p[2] = X.p[i];
+        }
+        while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
+
+        MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
+        MPI_CHK( mpi_shift_l( &T1,  biL * (i - t - 1) ) );
+        MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
+
+        if( mpi_cmp_int( &X, 0 ) < 0 )
+        {
+            MPI_CHK( mpi_copy( &T1, &Y ) );
+            MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
+            MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
+            Z.p[i - t - 1]--;
+        }
+    }
+
+    if( Q != NULL )
+    {
+        MPI_CHK( mpi_copy( Q, &Z ) );
+        Q->s = A->s * B->s;
+    }
+
+    if( R != NULL )
+    {
+        MPI_CHK( mpi_shift_r( &X, k ) );
+        X.s = A->s;
+        MPI_CHK( mpi_copy( R, &X ) );
+
+        if( mpi_cmp_int( R, 0 ) == 0 )
+            R->s = 1;
+    }
+
+cleanup:
+
+    mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
+    mpi_free( &T1 ); mpi_free( &T2 );
+
+    return( ret );
+}
+
+/*
+ * Division by int: A = Q * b + R
+ */
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
+{
+    mpi _B;
+    t_uint p[1];
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mpi_div_mpi( Q, R, A, &_B ) );
+}
+
+/*
+ * Modulo: R = A mod B
+ */
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
+{
+    int ret;
+
+    if( mpi_cmp_int( B, 0 ) < 0 )
+        return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
+
+    MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
+
+    while( mpi_cmp_int( R, 0 ) < 0 )
+      MPI_CHK( mpi_add_mpi( R, R, B ) );
+
+    while( mpi_cmp_mpi( R, B ) >= 0 )
+      MPI_CHK( mpi_sub_mpi( R, R, B ) );
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Modulo: r = A mod b
+ */
+int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
+{
+    size_t i;
+    t_uint x, y, z;
+
+    if( b == 0 )
+        return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+    if( b < 0 )
+        return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
+
+    /*
+     * handle trivial cases
+     */
+    if( b == 1 )
+    {
+        *r = 0;
+        return( 0 );
+    }
+
+    if( b == 2 )
+    {
+        *r = A->p[0] & 1;
+        return( 0 );
+    }
+
+    /*
+     * general case
+     */
+    for( i = A->n, y = 0; i > 0; i-- )
+    {
+        x  = A->p[i - 1];
+        y  = ( y << biH ) | ( x >> biH );
+        z  = y / b;
+        y -= z * b;
+
+        x <<= biH;
+        y  = ( y << biH ) | ( x >> biH );
+        z  = y / b;
+        y -= z * b;
+    }
+
+    /*
+     * If A is negative, then the current y represents a negative value.
+     * Flipping it to the positive side.
+     */
+    if( A->s < 0 && y != 0 )
+        y = b - y;
+
+    *r = y;
+
+    return( 0 );
+}
+
+/*
+ * Fast Montgomery initialization (thanks to Tom St Denis)
+ */
+static void mpi_montg_init( t_uint *mm, const mpi *N )
+{
+    t_uint x, m0 = N->p[0];
+    unsigned int i;
+
+    x  = m0;
+    x += ( ( m0 + 2 ) & 4 ) << 1;
+
+    for( i = biL; i >= 8; i /= 2 )
+        x *= ( 2 - ( m0 * x ) );
+
+    *mm = ~x + 1;
+}
+
+/*
+ * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
+ */
+static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
+                         const mpi *T )
+{
+    size_t i, n, m;
+    t_uint u0, u1, *d;
+
+    memset( T->p, 0, T->n * ciL );
+
+    d = T->p;
+    n = N->n;
+    m = ( B->n < n ) ? B->n : n;
+
+    for( i = 0; i < n; i++ )
+    {
+        /*
+         * T = (T + u0*B + u1*N) / 2^biL
+         */
+        u0 = A->p[i];
+        u1 = ( d[0] + u0 * B->p[0] ) * mm;
+
+        mpi_mul_hlp( m, B->p, d, u0 );
+        mpi_mul_hlp( n, N->p, d, u1 );
+
+        *d++ = u0; d[n + 1] = 0;
+    }
+
+    memcpy( A->p, d, (n + 1) * ciL );
+
+    if( mpi_cmp_abs( A, N ) >= 0 )
+        mpi_sub_hlp( n, N->p, A->p );
+    else
+        /* prevent timing attacks */
+        mpi_sub_hlp( n, A->p, T->p );
+}
+
+/*
+ * Montgomery reduction: A = A * R^-1 mod N
+ */
+static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
+{
+    t_uint z = 1;
+    mpi U;
+
+    U.n = U.s = (int) z;
+    U.p = &z;
+
+    mpi_montmul( A, &U, N, mm, T );
+}
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ */
+int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
+{
+    int ret;
+    size_t wbits, wsize, one = 1;
+    size_t i, j, nblimbs;
+    size_t bufsize, nbits;
+    t_uint ei, mm, state;
+    mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
+    int neg;
+
+    if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    if( mpi_cmp_int( E, 0 ) < 0 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    /*
+     * Init temps and window size
+     */
+    mpi_montg_init( &mm, N );
+    mpi_init( &RR ); mpi_init( &T );
+    mpi_init( &Apos );
+    memset( W, 0, sizeof( W ) );
+
+    i = mpi_msb( E );
+
+    wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+            ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;
+
+    if( wsize > POLARSSL_MPI_WINDOW_SIZE )
+        wsize = POLARSSL_MPI_WINDOW_SIZE;
+
+    j = N->n + 1;
+    MPI_CHK( mpi_grow( X, j ) );
+    MPI_CHK( mpi_grow( &W[1],  j ) );
+    MPI_CHK( mpi_grow( &T, j * 2 ) );
+
+    /*
+     * Compensate for negative A (and correct at the end)
+     */
+    neg = ( A->s == -1 );
+    if( neg )
+    {
+        MPI_CHK( mpi_copy( &Apos, A ) );
+        Apos.s = 1;
+        A = &Apos;
+    }
+
+    /*
+     * If 1st call, pre-compute R^2 mod N
+     */
+    if( _RR == NULL || _RR->p == NULL )
+    {
+        MPI_CHK( mpi_lset( &RR, 1 ) );
+        MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
+        MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
+
+        if( _RR != NULL )
+            memcpy( _RR, &RR, sizeof( mpi ) );
+    }
+    else
+        memcpy( &RR, _RR, sizeof( mpi ) );
+
+    /*
+     * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+     */
+    if( mpi_cmp_mpi( A, N ) >= 0 )
+        MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
+    else
+        MPI_CHK( mpi_copy( &W[1], A ) );
+
+    mpi_montmul( &W[1], &RR, N, mm, &T );
+
+    /*
+     * X = R^2 * R^-1 mod N = R mod N
+     */
+    MPI_CHK( mpi_copy( X, &RR ) );
+    mpi_montred( X, N, mm, &T );
+
+    if( wsize > 1 )
+    {
+        /*
+         * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+         */
+        j =  one << (wsize - 1);
+
+        MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
+        MPI_CHK( mpi_copy( &W[j], &W[1]    ) );
+
+        for( i = 0; i < wsize - 1; i++ )
+            mpi_montmul( &W[j], &W[j], N, mm, &T );
+
+        /*
+         * W[i] = W[i - 1] * W[1]
+         */
+        for( i = j + 1; i < (one << wsize); i++ )
+        {
+            MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
+            MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
+
+            mpi_montmul( &W[i], &W[1], N, mm, &T );
+        }
+    }
+
+    nblimbs = E->n;
+    bufsize = 0;
+    nbits   = 0;
+    wbits   = 0;
+    state   = 0;
+
+    while( 1 )
+    {
+        if( bufsize == 0 )
+        {
+            if( nblimbs == 0 )
+                break;
+
+            nblimbs--;
+
+            bufsize = sizeof( t_uint ) << 3;
+        }
+
+        bufsize--;
+
+        ei = (E->p[nblimbs] >> bufsize) & 1;
+
+        /*
+         * skip leading 0s
+         */
+        if( ei == 0 && state == 0 )
+            continue;
+
+        if( ei == 0 && state == 1 )
+        {
+            /*
+             * out of window, square X
+             */
+            mpi_montmul( X, X, N, mm, &T );
+            continue;
+        }
+
+        /*
+         * add ei to current window
+         */
+        state = 2;
+
+        nbits++;
+        wbits |= (ei << (wsize - nbits));
+
+        if( nbits == wsize )
+        {
+            /*
+             * X = X^wsize R^-1 mod N
+             */
+            for( i = 0; i < wsize; i++ )
+                mpi_montmul( X, X, N, mm, &T );
+
+            /*
+             * X = X * W[wbits] R^-1 mod N
+             */
+            mpi_montmul( X, &W[wbits], N, mm, &T );
+
+            state--;
+            nbits = 0;
+            wbits = 0;
+        }
+    }
+
+    /*
+     * process the remaining bits
+     */
+    for( i = 0; i < nbits; i++ )
+    {
+        mpi_montmul( X, X, N, mm, &T );
+
+        wbits <<= 1;
+
+        if( (wbits & (one << wsize)) != 0 )
+            mpi_montmul( X, &W[1], N, mm, &T );
+    }
+
+    /*
+     * X = A^E * R * R^-1 mod N = A^E mod N
+     */
+    mpi_montred( X, N, mm, &T );
+
+    if( neg )
+    {
+        X->s = -1;
+        MPI_CHK( mpi_add_mpi( X, N, X ) );
+    }
+
+cleanup:
+
+    for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
+        mpi_free( &W[i] );
+
+    mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
+
+    if( _RR == NULL || _RR->p == NULL )
+        mpi_free( &RR );
+
+    return( ret );
+}
+
+/*
+ * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
+ */
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
+{
+    int ret;
+    size_t lz, lzt;
+    mpi TG, TA, TB;
+
+    mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
+
+    MPI_CHK( mpi_copy( &TA, A ) );
+    MPI_CHK( mpi_copy( &TB, B ) );
+
+    lz = mpi_lsb( &TA );
+    lzt = mpi_lsb( &TB );
+
+    if ( lzt < lz )
+        lz = lzt;
+
+    MPI_CHK( mpi_shift_r( &TA, lz ) );
+    MPI_CHK( mpi_shift_r( &TB, lz ) );
+
+    TA.s = TB.s = 1;
+
+    while( mpi_cmp_int( &TA, 0 ) != 0 )
+    {
+        MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
+        MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
+
+        if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
+        {
+            MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
+            MPI_CHK( mpi_shift_r( &TA, 1 ) );
+        }
+        else
+        {
+            MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
+            MPI_CHK( mpi_shift_r( &TB, 1 ) );
+        }
+    }
+
+    MPI_CHK( mpi_shift_l( &TB, lz ) );
+    MPI_CHK( mpi_copy( G, &TB ) );
+
+cleanup:
+
+    mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
+
+    return( ret );
+}
+
+/*
+ * Fill X with size bytes of random.
+ *
+ * Use a temporary bytes representation to make sure the result is the same
+ * regardless of the platform endianness (useful when f_rng is actually
+ * deterministic, eg for tests).
+ */
+int mpi_fill_random( mpi *X, size_t size,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+
+    if( size > POLARSSL_MPI_MAX_SIZE )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    MPI_CHK( f_rng( p_rng, buf, size ) );
+    MPI_CHK( mpi_read_binary( X, buf, size ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
+ */
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
+{
+    int ret;
+    mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+
+    if( mpi_cmp_int( N, 0 ) <= 0 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
+    mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
+    mpi_init( &V1 ); mpi_init( &V2 );
+
+    MPI_CHK( mpi_gcd( &G, A, N ) );
+
+    if( mpi_cmp_int( &G, 1 ) != 0 )
+    {
+        ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+        goto cleanup;
+    }
+
+    MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
+    MPI_CHK( mpi_copy( &TU, &TA ) );
+    MPI_CHK( mpi_copy( &TB, N ) );
+    MPI_CHK( mpi_copy( &TV, N ) );
+
+    MPI_CHK( mpi_lset( &U1, 1 ) );
+    MPI_CHK( mpi_lset( &U2, 0 ) );
+    MPI_CHK( mpi_lset( &V1, 0 ) );
+    MPI_CHK( mpi_lset( &V2, 1 ) );
+
+    do
+    {
+        while( ( TU.p[0] & 1 ) == 0 )
+        {
+            MPI_CHK( mpi_shift_r( &TU, 1 ) );
+
+            if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
+            {
+                MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
+                MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
+            }
+
+            MPI_CHK( mpi_shift_r( &U1, 1 ) );
+            MPI_CHK( mpi_shift_r( &U2, 1 ) );
+        }
+
+        while( ( TV.p[0] & 1 ) == 0 )
+        {
+            MPI_CHK( mpi_shift_r( &TV, 1 ) );
+
+            if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
+            {
+                MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
+                MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
+            }
+
+            MPI_CHK( mpi_shift_r( &V1, 1 ) );
+            MPI_CHK( mpi_shift_r( &V2, 1 ) );
+        }
+
+        if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
+        {
+            MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
+            MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
+            MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
+        }
+        else
+        {
+            MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
+            MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
+            MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
+        }
+    }
+    while( mpi_cmp_int( &TU, 0 ) != 0 );
+
+    while( mpi_cmp_int( &V1, 0 ) < 0 )
+        MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
+
+    while( mpi_cmp_mpi( &V1, N ) >= 0 )
+        MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
+
+    MPI_CHK( mpi_copy( X, &V1 ) );
+
+cleanup:
+
+    mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
+    mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
+    mpi_free( &V1 ); mpi_free( &V2 );
+
+    return( ret );
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+static const int small_prime[] =
+{
+        3,    5,    7,   11,   13,   17,   19,   23,
+       29,   31,   37,   41,   43,   47,   53,   59,
+       61,   67,   71,   73,   79,   83,   89,   97,
+      101,  103,  107,  109,  113,  127,  131,  137,
+      139,  149,  151,  157,  163,  167,  173,  179,
+      181,  191,  193,  197,  199,  211,  223,  227,
+      229,  233,  239,  241,  251,  257,  263,  269,
+      271,  277,  281,  283,  293,  307,  311,  313,
+      317,  331,  337,  347,  349,  353,  359,  367,
+      373,  379,  383,  389,  397,  401,  409,  419,
+      421,  431,  433,  439,  443,  449,  457,  461,
+      463,  467,  479,  487,  491,  499,  503,  509,
+      521,  523,  541,  547,  557,  563,  569,  571,
+      577,  587,  593,  599,  601,  607,  613,  617,
+      619,  631,  641,  643,  647,  653,  659,  661,
+      673,  677,  683,  691,  701,  709,  719,  727,
+      733,  739,  743,  751,  757,  761,  769,  773,
+      787,  797,  809,  811,  821,  823,  827,  829,
+      839,  853,  857,  859,  863,  877,  881,  883,
+      887,  907,  911,  919,  929,  937,  941,  947,
+      953,  967,  971,  977,  983,  991,  997, -103
+};
+
+/*
+ * Small divisors test (X must be positive)
+ *
+ * Return values:
+ * 0: no small factor (possible prime, more tests needed)
+ * 1: certain prime
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
+ * other negative: error
+ */
+static int mpi_check_small_factors( const mpi *X )
+{
+    int ret = 0;
+    size_t i;
+    t_uint r;
+
+    if( ( X->p[0] & 1 ) == 0 )
+        return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+
+    for( i = 0; small_prime[i] > 0; i++ )
+    {
+        if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
+            return( 1 );
+
+        MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
+
+        if( r == 0 )
+            return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Miller-Rabin pseudo-primality test  (HAC 4.24)
+ */
+static int mpi_miller_rabin( const mpi *X,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
+{
+    int ret;
+    size_t i, j, n, s;
+    mpi W, R, T, A, RR;
+
+    mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
+    mpi_init( &RR );
+
+    /*
+     * W = |X| - 1
+     * R = W >> lsb( W )
+     */
+    MPI_CHK( mpi_sub_int( &W, X, 1 ) );
+    s = mpi_lsb( &W );
+    MPI_CHK( mpi_copy( &R, &W ) );
+    MPI_CHK( mpi_shift_r( &R, s ) );
+
+    i = mpi_msb( X );
+    /*
+     * HAC, table 4.4
+     */
+    n = ( ( i >= 1300 ) ?  2 : ( i >=  850 ) ?  3 :
+          ( i >=  650 ) ?  4 : ( i >=  350 ) ?  8 :
+          ( i >=  250 ) ? 12 : ( i >=  150 ) ? 18 : 27 );
+
+    for( i = 0; i < n; i++ )
+    {
+        /*
+         * pick a random A, 1 < A < |X| - 1
+         */
+        MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
+
+        if( mpi_cmp_mpi( &A, &W ) >= 0 )
+        {
+            j = mpi_msb( &A ) - mpi_msb( &W );
+            MPI_CHK( mpi_shift_r( &A, j + 1 ) );
+        }
+        A.p[0] |= 3;
+
+        /*
+         * A = A^R mod |X|
+         */
+        MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
+
+        if( mpi_cmp_mpi( &A, &W ) == 0 ||
+            mpi_cmp_int( &A,  1 ) == 0 )
+            continue;
+
+        j = 1;
+        while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
+        {
+            /*
+             * A = A * A mod |X|
+             */
+            MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
+            MPI_CHK( mpi_mod_mpi( &A, &T, X  ) );
+
+            if( mpi_cmp_int( &A, 1 ) == 0 )
+                break;
+
+            j++;
+        }
+
+        /*
+         * not prime if A != |X| - 1 or A == 1
+         */
+        if( mpi_cmp_mpi( &A, &W ) != 0 ||
+            mpi_cmp_int( &A,  1 ) == 0 )
+        {
+            ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+            break;
+        }
+    }
+
+cleanup:
+    mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
+    mpi_free( &RR );
+
+    return( ret );
+}
+
+/*
+ * Pseudo-primality test: small factors, then Miller-Rabin
+ */
+int mpi_is_prime( mpi *X,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng )
+{
+    int ret;
+    const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
+
+    if( mpi_cmp_int( &XX, 0 ) == 0 ||
+        mpi_cmp_int( &XX, 1 ) == 0 )
+        return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+
+    if( mpi_cmp_int( &XX, 2 ) == 0 )
+        return( 0 );
+
+    if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
+    {
+        if( ret == 1 )
+            return( 0 );
+
+        return( ret );
+    }
+
+    return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
+}
+
+/*
+ * Prime number generation
+ */
+int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
+                   int (*f_rng)(void *, unsigned char *, size_t),
+                   void *p_rng )
+{
+    int ret;
+    size_t k, n;
+    t_uint r;
+    mpi Y;
+
+    if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    mpi_init( &Y );
+
+    n = BITS_TO_LIMBS( nbits );
+
+    MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
+
+    k = mpi_msb( X );
+    if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
+    if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
+
+    X->p[0] |= 3;
+
+    if( dh_flag == 0 )
+    {
+        while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+        {
+            if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+                goto cleanup;
+
+            MPI_CHK( mpi_add_int( X, X, 2 ) );
+        }
+    }
+    else
+    {
+        /*
+         * An necessary condition for Y and X = 2Y + 1 to be prime
+         * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
+         * Make sure it is satisfied, while keeping X = 3 mod 4
+         */
+        MPI_CHK( mpi_mod_int( &r, X, 3 ) );
+        if( r == 0 )
+            MPI_CHK( mpi_add_int( X, X, 8 ) );
+        else if( r == 1 )
+            MPI_CHK( mpi_add_int( X, X, 4 ) );
+
+        /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
+        MPI_CHK( mpi_copy( &Y, X ) );
+        MPI_CHK( mpi_shift_r( &Y, 1 ) );
+
+        while( 1 )
+        {
+            /*
+             * First, check small factors for X and Y
+             * before doing Miller-Rabin on any of them
+             */
+            if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
+                ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
+                ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
+                ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
+            {
+                break;
+            }
+
+            if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+                goto cleanup;
+
+            /*
+             * Next candidates. We want to preserve Y = (X-1) / 2 and
+             * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
+             * so up Y by 6 and X by 12.
+             */
+            MPI_CHK( mpi_add_int(  X,  X, 12 ) );
+            MPI_CHK( mpi_add_int( &Y, &Y, 6  ) );
+        }
+    }
+
+cleanup:
+
+    mpi_free( &Y );
+
+    return( ret );
+}
+
+#endif /* POLARSSL_GENPRIME */
+
+#if defined(POLARSSL_SELF_TEST)
+
+#define GCD_PAIR_COUNT  3
+
+static const int gcd_pairs[GCD_PAIR_COUNT][3] =
+{
+    { 693, 609, 21 },
+    { 1764, 868, 28 },
+    { 768454923, 542167814, 1 }
+};
+
+/*
+ * Checkup routine
+ */
+int mpi_self_test( int verbose )
+{
+    int ret, i;
+    mpi A, E, N, X, Y, U, V;
+
+    mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
+    mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
+
+    MPI_CHK( mpi_read_string( &A, 16,
+        "EFE021C2645FD1DC586E69184AF4A31E" \
+        "D5F53E93B5F123FA41680867BA110131" \
+        "944FE7952E2517337780CB0DB80E61AA" \
+        "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
+
+    MPI_CHK( mpi_read_string( &E, 16,
+        "B2E7EFD37075B9F03FF989C7C5051C20" \
+        "34D2A323810251127E7BF8625A4F49A5" \
+        "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
+        "5B5C25763222FEFCCFC38B832366C29E" ) );
+
+    MPI_CHK( mpi_read_string( &N, 16,
+        "0066A198186C18C10B2F5ED9B522752A" \
+        "9830B69916E535C8F047518A889A43A5" \
+        "94B6BED27A168D31D4A52F88925AA8F5" ) );
+
+    MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
+
+    MPI_CHK( mpi_read_string( &U, 16,
+        "602AB7ECA597A3D6B56FF9829A5E8B85" \
+        "9E857EA95A03512E2BAE7391688D264A" \
+        "A5663B0341DB9CCFD2C4C5F421FEC814" \
+        "8001B72E848A38CAE1C65F78E56ABDEF" \
+        "E12D3C039B8A02D6BE593F0BBBDA56F1" \
+        "ECF677152EF804370C1A305CAF3B5BF1" \
+        "30879B56C61DE584A0F53A2447A51E" ) );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MPI test #1 (mul_mpi): " );
+
+    if( mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
+
+    MPI_CHK( mpi_read_string( &U, 16,
+        "256567336059E52CAE22925474705F39A94" ) );
+
+    MPI_CHK( mpi_read_string( &V, 16,
+        "6613F26162223DF488E9CD48CC132C7A" \
+        "0AC93C701B001B092E4E5B9F73BCD27B" \
+        "9EE50D0657C77F374E903CDFA4C642" ) );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MPI test #2 (div_mpi): " );
+
+    if( mpi_cmp_mpi( &X, &U ) != 0 ||
+        mpi_cmp_mpi( &Y, &V ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
+
+    MPI_CHK( mpi_read_string( &U, 16,
+        "36E139AEA55215609D2816998ED020BB" \
+        "BD96C37890F65171D948E9BC7CBAA4D9" \
+        "325D24D6A3C12710F10A09FA08AB87" ) );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MPI test #3 (exp_mod): " );
+
+    if( mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
+
+    MPI_CHK( mpi_read_string( &U, 16,
+        "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
+        "C3DBA76456363A10869622EAC2DD84EC" \
+        "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MPI test #4 (inv_mod): " );
+
+    if( mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MPI test #5 (simple gcd): " );
+
+    for ( i = 0; i < GCD_PAIR_COUNT; i++)
+    {
+        MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
+        MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
+
+        MPI_CHK( mpi_gcd( &A, &X, &Y ) );
+
+        if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+        {
+            if( verbose != 0 )
+                polarssl_printf( "failed at %d\n", i );
+
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+cleanup:
+
+    if( ret != 0 && verbose != 0 )
+        polarssl_printf( "Unexpected error, return code = %08X\n", ret );
+
+    mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
+    mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
+
+    if( verbose != 0 )
+        polarssl_printf( "\n" );
+
+    return( ret );
+}
+
+#endif /* POLARSSL_SELF_TEST */
+
+#endif /* POLARSSL_BIGNUM_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/Makefile u-boot-2011.06/lib/Makefile
--- u-boot-2011.06_original/lib/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/lib/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -48,6 +48,7 @@
 COBJS-y += qsort.o
 COBJS-$(CONFIG_SHA1) += sha1.o
 COBJS-$(CONFIG_SHA256) += sha256.o
+COBJS-$(CONFIG_RSAVERIFY) += bignum.o oid.o x_clib.o md.o md_wrap.o asn1parse.o rsa.o rsa_verify.o
 COBJS-y += string.o
 COBJS-y	+= strmhz.o
 COBJS-y += time.o
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/md5.c u-boot-2011.06/lib/md5.c
--- u-boot-2011.06_original/lib/md5.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/lib/md5.c	2014-07-29 17:28:38.819972000 +0800
@@ -153,8 +153,8 @@
 	byteReverse(ctx->in, 14);
 
 	/* Append length in bits and transform */
-	((__u32 *) ctx->in)[14] = ctx->bits[0];
-	((__u32 *) ctx->in)[15] = ctx->bits[1];
+	ctx->in32[14] = ctx->bits[0];
+	ctx->in32[15] = ctx->bits[1];
 
 	MD5Transform(ctx->buf, (__u32 *) ctx->in);
 	byteReverse((unsigned char *) ctx->buf, 4);
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/md.c u-boot-2011.06/lib/md.c
--- u-boot-2011.06_original/lib/md.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/md.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,322 @@
+/**
+ * \file md.c
+ *
+ * \brief Generic message digest wrapper for PolarSSL
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_MD_C)
+
+#include "md.h"
+#include "md_wrap.h"
+
+#include <common.h>
+#include <linux/string.h>
+
+#define strcasecmp  strcmp
+
+static const int supported_digests[] = {
+
+#if defined(POLARSSL_MD2_C)
+        POLARSSL_MD_MD2,
+#endif
+
+#if defined(POLARSSL_MD4_C)
+        POLARSSL_MD_MD4,
+#endif
+
+#if defined(POLARSSL_MD5_C)
+        POLARSSL_MD_MD5,
+#endif
+
+#if defined(POLARSSL_RIPEMD160_C)
+        POLARSSL_MD_RIPEMD160,
+#endif
+
+#if defined(POLARSSL_SHA1_C)
+        POLARSSL_MD_SHA1,
+#endif
+
+#if defined(POLARSSL_SHA256_C)
+        POLARSSL_MD_SHA224,
+        POLARSSL_MD_SHA256,
+#endif
+
+#if defined(POLARSSL_SHA512_C)
+        POLARSSL_MD_SHA384,
+        POLARSSL_MD_SHA512,
+#endif
+
+        0
+};
+
+const int *md_list( void )
+{
+    return supported_digests;
+}
+
+const md_info_t *md_info_from_string( const char *md_name )
+{
+    if( NULL == md_name )
+        return NULL;
+
+    /* Get the appropriate digest information */
+#if defined(POLARSSL_MD2_C)
+    if( !strcasecmp( "MD2", md_name ) )
+        return md_info_from_type( POLARSSL_MD_MD2 );
+#endif
+#if defined(POLARSSL_MD4_C)
+    if( !strcasecmp( "MD4", md_name ) )
+        return md_info_from_type( POLARSSL_MD_MD4 );
+#endif
+#if defined(POLARSSL_MD5_C)
+    if( !strcasecmp( "MD5", md_name ) )
+        return md_info_from_type( POLARSSL_MD_MD5 );
+#endif
+#if defined(POLARSSL_RIPEMD160_C)
+    if( !strcasecmp( "RIPEMD160", md_name ) )
+        return md_info_from_type( POLARSSL_MD_RIPEMD160 );
+#endif
+#if defined(POLARSSL_SHA1_C)
+    if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
+        return md_info_from_type( POLARSSL_MD_SHA1 );
+#endif
+#if defined(POLARSSL_SHA256_C)
+    if( !strcasecmp( "SHA224", md_name ) )
+        return md_info_from_type( POLARSSL_MD_SHA224 );
+    if( !strcasecmp( "SHA256", md_name ) )
+        return md_info_from_type( POLARSSL_MD_SHA256 );
+#endif
+#if defined(POLARSSL_SHA512_C)
+    if( !strcasecmp( "SHA384", md_name ) )
+        return md_info_from_type( POLARSSL_MD_SHA384 );
+    if( !strcasecmp( "SHA512", md_name ) )
+        return md_info_from_type( POLARSSL_MD_SHA512 );
+#endif
+    return NULL;
+}
+
+const md_info_t *md_info_from_type( md_type_t md_type )
+{
+    switch( md_type )
+    {
+#if defined(POLARSSL_MD2_C)
+        case POLARSSL_MD_MD2:
+            return &md2_info;
+#endif
+#if defined(POLARSSL_MD4_C)
+        case POLARSSL_MD_MD4:
+            return &md4_info;
+#endif
+#if defined(POLARSSL_MD5_C)
+        case POLARSSL_MD_MD5:
+            return &md5_info;
+#endif
+#if defined(POLARSSL_RIPEMD160_C)
+        case POLARSSL_MD_RIPEMD160:
+            return &ripemd160_info;
+#endif
+#if defined(POLARSSL_SHA1_C)
+        case POLARSSL_MD_SHA1:
+            return &sha1_info;
+#endif
+#if defined(POLARSSL_SHA256_C)
+        case POLARSSL_MD_SHA224:
+            return &sha224_info;
+        case POLARSSL_MD_SHA256:
+            return &sha256_info;
+#endif
+#if defined(POLARSSL_SHA512_C)
+        case POLARSSL_MD_SHA384:
+            return &sha384_info;
+        case POLARSSL_MD_SHA512:
+            return &sha512_info;
+#endif
+        default:
+            return NULL;
+    }
+}
+
+int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
+{
+    if( md_info == NULL || ctx == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    memset( ctx, 0, sizeof( md_context_t ) );
+
+    if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
+        return POLARSSL_ERR_MD_ALLOC_FAILED;
+
+    ctx->md_info = md_info;
+
+    md_info->starts_func( ctx->md_ctx );
+
+    return 0;
+}
+
+int md_free_ctx( md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->ctx_free_func( ctx->md_ctx );
+    ctx->md_ctx = NULL;
+
+    return 0;
+}
+
+int md_starts( md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->starts_func( ctx->md_ctx );
+
+    return 0;
+}
+
+int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->update_func( ctx->md_ctx, input, ilen );
+
+    return 0;
+}
+
+int md_finish( md_context_t *ctx, unsigned char *output )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->finish_func( ctx->md_ctx, output );
+
+    return 0;
+}
+
+int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
+            unsigned char *output )
+{
+    if ( md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    md_info->digest_func( input, ilen, output );
+
+    return 0;
+}
+
+int md_file( const md_info_t *md_info, const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    int ret;
+#endif
+
+    if( md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+#if defined(POLARSSL_FS_IO)
+    ret = md_info->file_func( path, output );
+    if( ret != 0 )
+        return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret );
+
+    return( ret );
+#else
+    ((void) path);
+    ((void) output);
+
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif /* POLARSSL_FS_IO */
+}
+
+int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen);
+
+    return 0;
+}
+
+int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
+
+    return 0;
+}
+
+int md_hmac_finish( md_context_t *ctx, unsigned char *output)
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->hmac_finish_func( ctx->md_ctx, output);
+
+    return 0;
+}
+
+int md_hmac_reset( md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->hmac_reset_func( ctx->md_ctx);
+
+    return 0;
+}
+
+int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output )
+{
+    if( md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    md_info->hmac_func( key, keylen, input, ilen, output );
+
+    return 0;
+}
+
+int md_process( md_context_t *ctx, const unsigned char *data )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+    ctx->md_info->process_func( ctx->md_ctx, data );
+
+    return 0;
+}
+
+#endif /* POLARSSL_MD_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/md_wrap.c u-boot-2011.06/lib/md_wrap.c
--- u-boot-2011.06_original/lib/md_wrap.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/md_wrap.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,910 @@
+/**
+ * \file md_wrap.c
+
+ * \brief Generic message digest wrapper for PolarSSL
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_MD_C)
+
+#include "md_wrap.h"
+
+#if defined(POLARSSL_MD2_C)
+#include "md2.h"
+#endif
+
+#if defined(POLARSSL_MD4_C)
+#include "md4.h"
+#endif
+
+#if defined(POLARSSL_MD5_C)
+#include "md5.h"
+#endif
+
+#if defined(POLARSSL_RIPEMD160_C)
+#include "ripemd160.h"
+#endif
+
+#if defined(POLARSSL_SHA1_C)
+#include "sha1.h"
+#endif
+
+#if defined(POLARSSL_SHA256_C)
+#include "sha256.h"
+#endif
+
+#if defined(POLARSSL_SHA512_C)
+#include "sha512.h"
+#endif
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "platform.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
+#include <common.h>
+#include <malloc.h>
+
+#if defined(POLARSSL_MD2_C)
+
+static void md2_starts_wrap( void *ctx )
+{
+    md2_starts( (md2_context *) ctx );
+}
+
+static void md2_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    md2_update( (md2_context *) ctx, input, ilen );
+}
+
+static void md2_finish_wrap( void *ctx, unsigned char *output )
+{
+    md2_finish( (md2_context *) ctx, output );
+}
+
+static int md2_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return md2_file( path, output );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                  size_t keylen )
+{
+    md2_hmac_starts( (md2_context *) ctx, key, keylen );
+}
+
+static void md2_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                  size_t ilen )
+{
+    md2_hmac_update( (md2_context *) ctx, input, ilen );
+}
+
+static void md2_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    md2_hmac_finish( (md2_context *) ctx, output );
+}
+
+static void md2_hmac_reset_wrap( void *ctx )
+{
+    md2_hmac_reset( (md2_context *) ctx );
+}
+
+static void * md2_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( md2_context ) );
+}
+
+static void md2_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void md2_process_wrap( void *ctx, const unsigned char *data )
+{
+    ((void) data);
+
+    md2_process( (md2_context *) ctx );
+}
+
+const md_info_t md2_info = {
+    POLARSSL_MD_MD2,
+    "MD2",
+    16,
+    md2_starts_wrap,
+    md2_update_wrap,
+    md2_finish_wrap,
+    md2,
+    md2_file_wrap,
+    md2_hmac_starts_wrap,
+    md2_hmac_update_wrap,
+    md2_hmac_finish_wrap,
+    md2_hmac_reset_wrap,
+    md2_hmac,
+    md2_ctx_alloc,
+    md2_ctx_free,
+    md2_process_wrap,
+};
+
+#endif /* POLARSSL_MD2_C */
+
+#if defined(POLARSSL_MD4_C)
+
+static void md4_starts_wrap( void *ctx )
+{
+    md4_starts( (md4_context *) ctx );
+}
+
+static void md4_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    md4_update( (md4_context *) ctx, input, ilen );
+}
+
+static void md4_finish_wrap( void *ctx, unsigned char *output )
+{
+    md4_finish( (md4_context *) ctx, output );
+}
+
+static int md4_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return md4_file( path, output );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                  size_t keylen )
+{
+    md4_hmac_starts( (md4_context *) ctx, key, keylen );
+}
+
+static void md4_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                  size_t ilen )
+{
+    md4_hmac_update( (md4_context *) ctx, input, ilen );
+}
+
+static void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    md4_hmac_finish( (md4_context *) ctx, output );
+}
+
+static void md4_hmac_reset_wrap( void *ctx )
+{
+    md4_hmac_reset( (md4_context *) ctx );
+}
+
+static void *md4_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( md4_context ) );
+}
+
+static void md4_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void md4_process_wrap( void *ctx, const unsigned char *data )
+{
+    md4_process( (md4_context *) ctx, data );
+}
+
+const md_info_t md4_info = {
+    POLARSSL_MD_MD4,
+    "MD4",
+    16,
+    md4_starts_wrap,
+    md4_update_wrap,
+    md4_finish_wrap,
+    md4,
+    md4_file_wrap,
+    md4_hmac_starts_wrap,
+    md4_hmac_update_wrap,
+    md4_hmac_finish_wrap,
+    md4_hmac_reset_wrap,
+    md4_hmac,
+    md4_ctx_alloc,
+    md4_ctx_free,
+    md4_process_wrap,
+};
+
+#endif /* POLARSSL_MD4_C */
+
+#if defined(POLARSSL_MD5_C)
+
+static void md5_starts_wrap( void *ctx )
+{
+    md5_starts( (md5_context *) ctx );
+}
+
+static void md5_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    md5_update( (md5_context *) ctx, input, ilen );
+}
+
+static void md5_finish_wrap( void *ctx, unsigned char *output )
+{
+    md5_finish( (md5_context *) ctx, output );
+}
+
+static int md5_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return md5_file( path, output );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                  size_t keylen )
+{
+    md5_hmac_starts( (md5_context *) ctx, key, keylen );
+}
+
+static void md5_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                  size_t ilen )
+{
+    md5_hmac_update( (md5_context *) ctx, input, ilen );
+}
+
+static void md5_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    md5_hmac_finish( (md5_context *) ctx, output );
+}
+
+static void md5_hmac_reset_wrap( void *ctx )
+{
+    md5_hmac_reset( (md5_context *) ctx );
+}
+
+static void * md5_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( md5_context ) );
+}
+
+static void md5_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void md5_process_wrap( void *ctx, const unsigned char *data )
+{
+    md5_process( (md5_context *) ctx, data );
+}
+
+const md_info_t md5_info = {
+    POLARSSL_MD_MD5,
+    "MD5",
+    16,
+    md5_starts_wrap,
+    md5_update_wrap,
+    md5_finish_wrap,
+    md5,
+    md5_file_wrap,
+    md5_hmac_starts_wrap,
+    md5_hmac_update_wrap,
+    md5_hmac_finish_wrap,
+    md5_hmac_reset_wrap,
+    md5_hmac,
+    md5_ctx_alloc,
+    md5_ctx_free,
+    md5_process_wrap,
+};
+
+#endif /* POLARSSL_MD5_C */
+
+#if defined(POLARSSL_RIPEMD160_C)
+
+static void ripemd160_starts_wrap( void *ctx )
+{
+    ripemd160_starts( (ripemd160_context *) ctx );
+}
+
+static void ripemd160_update_wrap( void *ctx, const unsigned char *input,
+                                   size_t ilen )
+{
+    ripemd160_update( (ripemd160_context *) ctx, input, ilen );
+}
+
+static void ripemd160_finish_wrap( void *ctx, unsigned char *output )
+{
+    ripemd160_finish( (ripemd160_context *) ctx, output );
+}
+
+static int ripemd160_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return ripemd160_file( path, output );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void ripemd160_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                        size_t keylen )
+{
+    ripemd160_hmac_starts( (ripemd160_context *) ctx, key, keylen );
+}
+
+static void ripemd160_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                        size_t ilen )
+{
+    ripemd160_hmac_update( (ripemd160_context *) ctx, input, ilen );
+}
+
+static void ripemd160_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    ripemd160_hmac_finish( (ripemd160_context *) ctx, output );
+}
+
+static void ripemd160_hmac_reset_wrap( void *ctx )
+{
+    ripemd160_hmac_reset( (ripemd160_context *) ctx );
+}
+
+static void * ripemd160_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( ripemd160_context ) );
+}
+
+static void ripemd160_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void ripemd160_process_wrap( void *ctx, const unsigned char *data )
+{
+    ripemd160_process( (ripemd160_context *) ctx, data );
+}
+
+const md_info_t ripemd160_info = {
+    POLARSSL_MD_RIPEMD160,
+    "RIPEMD160",
+    20,
+    ripemd160_starts_wrap,
+    ripemd160_update_wrap,
+    ripemd160_finish_wrap,
+    ripemd160,
+    ripemd160_file_wrap,
+    ripemd160_hmac_starts_wrap,
+    ripemd160_hmac_update_wrap,
+    ripemd160_hmac_finish_wrap,
+    ripemd160_hmac_reset_wrap,
+    ripemd160_hmac,
+    ripemd160_ctx_alloc,
+    ripemd160_ctx_free,
+    ripemd160_process_wrap,
+};
+
+#endif /* POLARSSL_RIPEMD160_C */
+
+#if defined(POLARSSL_SHA1_C)
+
+static void sha1_starts_wrap( void *ctx )
+{
+    sha1_starts( (sha1_context *) ctx );
+}
+
+static void sha1_update_wrap( void *ctx, const unsigned char *input,
+                              size_t ilen )
+{
+    sha1_update( (sha1_context *) ctx, input, ilen );
+}
+
+static void sha1_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha1_finish( (sha1_context *) ctx, output );
+}
+
+static int sha1_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return sha1_file( path, output );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                   size_t keylen )
+{
+    sha1_hmac_starts( (sha1_context *) ctx, key, keylen );
+}
+
+static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                   size_t ilen )
+{
+    sha1_hmac_update( (sha1_context *) ctx, input, ilen );
+}
+
+static void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha1_hmac_finish( (sha1_context *) ctx, output );
+}
+
+static void sha1_hmac_reset_wrap( void *ctx )
+{
+    sha1_hmac_reset( (sha1_context *) ctx );
+}
+
+static void * sha1_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( sha1_context ) );
+}
+
+static void sha1_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void sha1_process_wrap( void *ctx, const unsigned char *data )
+{
+    sha1_process( (sha1_context *) ctx, data );
+}
+
+const md_info_t sha1_info = {
+    POLARSSL_MD_SHA1,
+    "SHA1",
+    20,
+    sha1_starts_wrap,
+    sha1_update_wrap,
+    sha1_finish_wrap,
+    sha1,
+    sha1_file_wrap,
+    sha1_hmac_starts_wrap,
+    sha1_hmac_update_wrap,
+    sha1_hmac_finish_wrap,
+    sha1_hmac_reset_wrap,
+    sha1_hmac,
+    sha1_ctx_alloc,
+    sha1_ctx_free,
+    sha1_process_wrap,
+};
+
+#endif /* POLARSSL_SHA1_C */
+
+/*
+ * Wrappers for generic message digests
+ */
+#if defined(POLARSSL_SHA256_C)
+
+static void sha224_starts_wrap( void *ctx )
+{
+    sha256_starts( (sha256_context *) ctx, 1 );
+}
+
+static void sha224_update_wrap( void *ctx, const unsigned char *input,
+                                size_t ilen )
+{
+    sha256_update( (sha256_context *) ctx, input, ilen );
+}
+
+static void sha224_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha256_finish( (sha256_context *) ctx, output );
+}
+
+static void sha224_wrap( const unsigned char *input, size_t ilen,
+                    unsigned char *output )
+{
+    sha256( input, ilen, output, 1 );
+}
+
+static int sha224_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return sha256_file( path, output, 1 );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                     size_t keylen )
+{
+    sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 1 );
+}
+
+static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                     size_t ilen )
+{
+    sha256_hmac_update( (sha256_context *) ctx, input, ilen );
+}
+
+static void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha256_hmac_finish( (sha256_context *) ctx, output );
+}
+
+static void sha224_hmac_reset_wrap( void *ctx )
+{
+    sha256_hmac_reset( (sha256_context *) ctx );
+}
+
+static void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
+        const unsigned char *input, size_t ilen,
+        unsigned char *output )
+{
+    sha256_hmac( key, keylen, input, ilen, output, 1 );
+}
+
+static void * sha224_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( sha256_context ) );
+}
+
+static void sha224_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void sha224_process_wrap( void *ctx, const unsigned char *data )
+{
+    sha256_process( (sha256_context *) ctx, data );
+}
+
+const md_info_t sha224_info = {
+    POLARSSL_MD_SHA224,
+    "SHA224",
+    28,
+    sha224_starts_wrap,
+    sha224_update_wrap,
+    sha224_finish_wrap,
+    sha224_wrap,
+    sha224_file_wrap,
+    sha224_hmac_starts_wrap,
+    sha224_hmac_update_wrap,
+    sha224_hmac_finish_wrap,
+    sha224_hmac_reset_wrap,
+    sha224_hmac_wrap,
+    sha224_ctx_alloc,
+    sha224_ctx_free,
+    sha224_process_wrap,
+};
+
+static void sha256_starts_wrap( void *ctx )
+{
+    sha256_starts( (sha256_context *) ctx, 0 );
+}
+
+static void sha256_update_wrap( void *ctx, const unsigned char *input,
+                                size_t ilen )
+{
+    sha256_update( (sha256_context *) ctx, input, ilen );
+}
+
+static void sha256_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha256_finish( (sha256_context *) ctx, output );
+}
+
+static void sha256_wrap( const unsigned char *input, size_t ilen,
+                    unsigned char *output )
+{
+    sha256( input, ilen, output, 0 );
+}
+
+static int sha256_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return sha256_file( path, output, 0 );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                     size_t keylen )
+{
+    sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 0 );
+}
+
+static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                     size_t ilen )
+{
+    sha256_hmac_update( (sha256_context *) ctx, input, ilen );
+}
+
+static void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha256_hmac_finish( (sha256_context *) ctx, output );
+}
+
+static void sha256_hmac_reset_wrap( void *ctx )
+{
+    sha256_hmac_reset( (sha256_context *) ctx );
+}
+
+static void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
+        const unsigned char *input, size_t ilen,
+        unsigned char *output )
+{
+    sha256_hmac( key, keylen, input, ilen, output, 0 );
+}
+
+static void * sha256_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( sha256_context ) );
+}
+
+static void sha256_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void sha256_process_wrap( void *ctx, const unsigned char *data )
+{
+    sha256_process( (sha256_context *) ctx, data );
+}
+
+const md_info_t sha256_info = {
+    POLARSSL_MD_SHA256,
+    "SHA256",
+    32,
+    sha256_starts_wrap,
+    sha256_update_wrap,
+    sha256_finish_wrap,
+    sha256_wrap,
+    sha256_file_wrap,
+    sha256_hmac_starts_wrap,
+    sha256_hmac_update_wrap,
+    sha256_hmac_finish_wrap,
+    sha256_hmac_reset_wrap,
+    sha256_hmac_wrap,
+    sha256_ctx_alloc,
+    sha256_ctx_free,
+    sha256_process_wrap,
+};
+
+#endif /* POLARSSL_SHA256_C */
+
+#if defined(POLARSSL_SHA512_C)
+
+static void sha384_starts_wrap( void *ctx )
+{
+    sha512_starts( (sha512_context *) ctx, 1 );
+}
+
+static void sha384_update_wrap( void *ctx, const unsigned char *input,
+                                size_t ilen )
+{
+    sha512_update( (sha512_context *) ctx, input, ilen );
+}
+
+static void sha384_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha512_finish( (sha512_context *) ctx, output );
+}
+
+static void sha384_wrap( const unsigned char *input, size_t ilen,
+                    unsigned char *output )
+{
+    sha512( input, ilen, output, 1 );
+}
+
+static int sha384_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return sha512_file( path, output, 1 );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                     size_t keylen )
+{
+    sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 1 );
+}
+
+static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                     size_t ilen )
+{
+    sha512_hmac_update( (sha512_context *) ctx, input, ilen );
+}
+
+static void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha512_hmac_finish( (sha512_context *) ctx, output );
+}
+
+static void sha384_hmac_reset_wrap( void *ctx )
+{
+    sha512_hmac_reset( (sha512_context *) ctx );
+}
+
+static void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
+        const unsigned char *input, size_t ilen,
+        unsigned char *output )
+{
+    sha512_hmac( key, keylen, input, ilen, output, 1 );
+}
+
+static void * sha384_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( sha512_context ) );
+}
+
+static void sha384_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void sha384_process_wrap( void *ctx, const unsigned char *data )
+{
+    sha512_process( (sha512_context *) ctx, data );
+}
+
+const md_info_t sha384_info = {
+    POLARSSL_MD_SHA384,
+    "SHA384",
+    48,
+    sha384_starts_wrap,
+    sha384_update_wrap,
+    sha384_finish_wrap,
+    sha384_wrap,
+    sha384_file_wrap,
+    sha384_hmac_starts_wrap,
+    sha384_hmac_update_wrap,
+    sha384_hmac_finish_wrap,
+    sha384_hmac_reset_wrap,
+    sha384_hmac_wrap,
+    sha384_ctx_alloc,
+    sha384_ctx_free,
+    sha384_process_wrap,
+};
+
+static void sha512_starts_wrap( void *ctx )
+{
+    sha512_starts( (sha512_context *) ctx, 0 );
+}
+
+static void sha512_update_wrap( void *ctx, const unsigned char *input,
+                                size_t ilen )
+{
+    sha512_update( (sha512_context *) ctx, input, ilen );
+}
+
+static void sha512_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha512_finish( (sha512_context *) ctx, output );
+}
+
+static void sha512_wrap( const unsigned char *input, size_t ilen,
+                    unsigned char *output )
+{
+    sha512( input, ilen, output, 0 );
+}
+
+static int sha512_file_wrap( const char *path, unsigned char *output )
+{
+#if defined(POLARSSL_FS_IO)
+    return sha512_file( path, output, 0 );
+#else
+    ((void) path);
+    ((void) output);
+    return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
+#endif
+}
+
+static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key,
+                                     size_t keylen )
+{
+    sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 0 );
+}
+
+static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input,
+                                     size_t ilen )
+{
+    sha512_hmac_update( (sha512_context *) ctx, input, ilen );
+}
+
+static void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
+{
+    sha512_hmac_finish( (sha512_context *) ctx, output );
+}
+
+static void sha512_hmac_reset_wrap( void *ctx )
+{
+    sha512_hmac_reset( (sha512_context *) ctx );
+}
+
+static void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
+        const unsigned char *input, size_t ilen,
+        unsigned char *output )
+{
+    sha512_hmac( key, keylen, input, ilen, output, 0 );
+}
+
+static void * sha512_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( sha512_context ) );
+}
+
+static void sha512_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static void sha512_process_wrap( void *ctx, const unsigned char *data )
+{
+    sha512_process( (sha512_context *) ctx, data );
+}
+
+const md_info_t sha512_info = {
+    POLARSSL_MD_SHA512,
+    "SHA512",
+    64,
+    sha512_starts_wrap,
+    sha512_update_wrap,
+    sha512_finish_wrap,
+    sha512_wrap,
+    sha512_file_wrap,
+    sha512_hmac_starts_wrap,
+    sha512_hmac_update_wrap,
+    sha512_hmac_finish_wrap,
+    sha512_hmac_reset_wrap,
+    sha512_hmac_wrap,
+    sha512_ctx_alloc,
+    sha512_ctx_free,
+    sha512_process_wrap,
+};
+
+#endif /* POLARSSL_SHA512_C */
+
+#endif /* POLARSSL_MD_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/oid.c u-boot-2011.06/lib/oid.c
--- u-boot-2011.06_original/lib/oid.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/oid.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,607 @@
+/**
+ * \file oid.c
+ *
+ * \brief Object Identifier (OID) database
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_OID_C)
+
+#include "oid.h"
+#include "rsa.h"
+
+#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
+#include "x509.h"
+#endif
+
+#include <common.h>
+
+/*
+ * Macro to automatically add the size of #define'd OIDs
+ */
+#define ADD_LEN(s)      s, OID_SIZE(s)
+
+/*
+ * Macro to generate an internal function for oid_XXX_from_asn1() (used by
+ * the other functions)
+ */
+#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST )                        \
+static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid )     \
+{                                                                           \
+    const TYPE_T *p = LIST;                                                 \
+    const oid_descriptor_t *cur = (const oid_descriptor_t *) p;             \
+    if( p == NULL || oid == NULL ) return( NULL );                          \
+    while( cur->asn1 != NULL ) {                                            \
+        if( cur->asn1_len == oid->len &&                                    \
+            memcmp( cur->asn1, oid->p, oid->len ) == 0 ) {                  \
+            return( p );                                                    \
+        }                                                                   \
+        p++;                                                                \
+        cur = (const oid_descriptor_t *) p;                                 \
+    }                                                                       \
+    return( NULL );                                                         \
+}
+
+/*
+ * Macro to generate a function for retrieving a single attribute from the
+ * descriptor of an oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
+int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 )                  \
+{                                                                       \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );        \
+    if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND );           \
+    *ATTR1 = data->descriptor.ATTR1;                                    \
+    return( 0 );                                                        \
+}
+
+/*
+ * Macro to generate a function for retrieving a single attribute from an
+ * oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
+int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 )                  \
+{                                                                       \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );        \
+    if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND );           \
+    *ATTR1 = data->ATTR1;                                               \
+    return( 0 );                                                        \
+}
+
+/*
+ * Macro to generate a function for retrieving two attributes from an
+ * oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1,     \
+                         ATTR2_TYPE, ATTR2)                                 \
+int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 )  \
+{                                                                           \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );            \
+    if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND );               \
+    *ATTR1 = data->ATTR1;                                                   \
+    *ATTR2 = data->ATTR2;                                                   \
+    return( 0 );                                                            \
+}
+
+/*
+ * Macro to generate a function for retrieving the OID based on a single
+ * attribute from a oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1)   \
+int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen )             \
+{                                                                           \
+    const TYPE_T *cur = LIST;                                               \
+    while( cur->descriptor.asn1 != NULL ) {                                 \
+        if( cur->ATTR1 == ATTR1 ) {                                         \
+            *oid = cur->descriptor.asn1;                                    \
+            *olen = cur->descriptor.asn1_len;                               \
+            return( 0 );                                                    \
+        }                                                                   \
+        cur++;                                                              \
+    }                                                                       \
+    return( POLARSSL_ERR_OID_NOT_FOUND );                                   \
+}
+
+/*
+ * Macro to generate a function for retrieving the OID based on two
+ * attributes from a oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1,   \
+                                ATTR2_TYPE, ATTR2)                          \
+int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid ,         \
+             size_t *olen )                                                 \
+{                                                                           \
+    const TYPE_T *cur = LIST;                                               \
+    while( cur->descriptor.asn1 != NULL ) {                                 \
+        if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) {                  \
+            *oid = cur->descriptor.asn1;                                    \
+            *olen = cur->descriptor.asn1_len;                               \
+            return( 0 );                                                    \
+        }                                                                   \
+        cur++;                                                              \
+    }                                                                       \
+    return( POLARSSL_ERR_OID_NOT_FOUND );                                   \
+}
+
+/*
+ * For X520 attribute types
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    const char          *short_name;
+} oid_x520_attr_t;
+
+static const oid_x520_attr_t oid_x520_attr_type[] =
+{
+    {
+        { ADD_LEN( OID_AT_CN ),          "id-at-commonName",               "Common Name" },
+        "CN",
+    },
+    {
+        { ADD_LEN( OID_AT_COUNTRY ),     "id-at-countryName",              "Country" },
+        "C",
+    },
+    {
+        { ADD_LEN( OID_AT_LOCALITY ),    "id-at-locality",                 "Locality" },
+        "L",
+    },
+    {
+        { ADD_LEN( OID_AT_STATE ),       "id-at-state",                    "State" },
+        "ST",
+    },
+    {
+        { ADD_LEN( OID_AT_ORGANIZATION ),"id-at-organizationName",         "Organization" },
+        "O",
+    },
+    {
+        { ADD_LEN( OID_AT_ORG_UNIT ),    "id-at-organizationalUnitName",   "Org Unit" },
+        "OU",
+    },
+    {
+        { ADD_LEN( OID_PKCS9_EMAIL ),    "emailAddress",                   "E-mail address" },
+        "emailAddress",
+    },
+    {
+        { ADD_LEN( OID_AT_SERIAL_NUMBER ),"id-at-serialNumber",            "Serial number" },
+        "serialNumber",
+    },
+    {
+        { ADD_LEN( OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress",          "Postal address" },
+        "postalAddress",
+    },
+    {
+        { ADD_LEN( OID_AT_POSTAL_CODE ), "id-at-postalCode",               "Postal code" },
+        "postalCode",
+    },
+    {
+        { ADD_LEN( OID_AT_SUR_NAME ),    "id-at-surName",                  "Surname" },
+        "SN",
+    },
+    {
+        { ADD_LEN( OID_AT_GIVEN_NAME ),  "id-at-givenName",                "Given name" },
+        "GN",
+    },
+    {
+        { ADD_LEN( OID_AT_INITIALS ),    "id-at-initials",                 "Initials" },
+        "initials",
+    },
+    {
+        { ADD_LEN( OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" },
+        "generationQualifier",
+    },
+    {
+        { ADD_LEN( OID_AT_TITLE ),       "id-at-title",                    "Title" },
+        "title",
+    },
+    {
+        { ADD_LEN( OID_AT_DN_QUALIFIER ),"id-at-dnQualifier",              "Distinguished Name qualifier" },
+        "dnQualifier",
+    },
+    {
+        { ADD_LEN( OID_AT_PSEUDONYM ),   "id-at-pseudonym",                "Pseudonym" },
+        "pseudonym",
+    },
+    {
+        { ADD_LEN( OID_DOMAIN_COMPONENT ), "id-domainComponent",           "Domain component" },
+        "DC",
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        NULL,
+    }
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type);
+FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name);
+
+#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
+/*
+ * For X509 extensions
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    int                 ext_type;
+} oid_x509_ext_t;
+
+static const oid_x509_ext_t oid_x509_ext[] =
+{
+    {
+        { ADD_LEN( OID_BASIC_CONSTRAINTS ),    "id-ce-basicConstraints",   "Basic Constraints" },
+        EXT_BASIC_CONSTRAINTS,
+    },
+    {
+        { ADD_LEN( OID_KEY_USAGE ),            "id-ce-keyUsage",           "Key Usage" },
+        EXT_KEY_USAGE,
+    },
+    {
+        { ADD_LEN( OID_EXTENDED_KEY_USAGE ),   "id-ce-keyUsage",           "Extended Key Usage" },
+        EXT_EXTENDED_KEY_USAGE,
+    },
+    {
+        { ADD_LEN( OID_SUBJECT_ALT_NAME ),     "id-ce-subjectAltName",     "Subject Alt Name" },
+        EXT_SUBJECT_ALT_NAME,
+    },
+    {
+        { ADD_LEN( OID_NS_CERT_TYPE ),         "id-netscape-certtype",     "Netscape Certificate Type" },
+        EXT_NS_CERT_TYPE,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext);
+FN_OID_GET_ATTR1(oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type);
+
+static const oid_descriptor_t oid_ext_key_usage[] =
+{
+    { ADD_LEN( OID_SERVER_AUTH ),      "id-kp-serverAuth",      "TLS Web Server Authentication" },
+    { ADD_LEN( OID_CLIENT_AUTH ),      "id-kp-clientAuth",      "TLS Web Client Authentication" },
+    { ADD_LEN( OID_CODE_SIGNING ),     "id-kp-codeSigning",     "Code Signing" },
+    { ADD_LEN( OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
+    { ADD_LEN( OID_TIME_STAMPING ),    "id-kp-timeStamping",    "Time Stamping" },
+    { ADD_LEN( OID_OCSP_SIGNING ),     "id-kp-OCSPSigning",     "OCSP Signing" },
+    { NULL, 0, NULL, NULL },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage);
+FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description);
+#endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */
+
+#if defined(POLARSSL_MD_C)
+/*
+ * For SignatureAlgorithmIdentifier
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    md_type_t           md_alg;
+    pk_type_t           pk_alg;
+} oid_sig_alg_t;
+
+static const oid_sig_alg_t oid_sig_alg[] =
+{
+    {
+        { ADD_LEN( OID_PKCS1_MD2 ),        "md2WithRSAEncryption",     "RSA with MD2" },
+        POLARSSL_MD_MD2,      POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_MD4 ),        "md4WithRSAEncryption",     "RSA with MD4" },
+        POLARSSL_MD_MD4,      POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_MD5 ),        "md5WithRSAEncryption",     "RSA with MD5" },
+        POLARSSL_MD_MD5,      POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_SHA1 ),       "sha-1WithRSAEncryption",   "RSA with SHA1" },
+        POLARSSL_MD_SHA1,     POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_SHA224 ),     "sha224WithRSAEncryption",  "RSA with SHA-224" },
+        POLARSSL_MD_SHA224,   POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_SHA256 ),     "sha256WithRSAEncryption",  "RSA with SHA-256" },
+        POLARSSL_MD_SHA256,   POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_SHA384 ),     "sha384WithRSAEncryption",  "RSA with SHA-384" },
+        POLARSSL_MD_SHA384,   POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_PKCS1_SHA512 ),     "sha512WithRSAEncryption",  "RSA with SHA-512" },
+        POLARSSL_MD_SHA512,   POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_RSA_SHA_OBS ),      "sha-1WithRSAEncryption",   "RSA with SHA1" },
+        POLARSSL_MD_SHA1,     POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_ECDSA_SHA1 ),       "ecdsa-with-SHA1",      "ECDSA with SHA1" },
+        POLARSSL_MD_SHA1,     POLARSSL_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( OID_ECDSA_SHA224 ),     "ecdsa-with-SHA224",    "ECDSA with SHA224" },
+        POLARSSL_MD_SHA224,   POLARSSL_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( OID_ECDSA_SHA256 ),     "ecdsa-with-SHA256",    "ECDSA with SHA256" },
+        POLARSSL_MD_SHA256,   POLARSSL_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( OID_ECDSA_SHA384 ),     "ecdsa-with-SHA384",    "ECDSA with SHA384" },
+        POLARSSL_MD_SHA384,   POLARSSL_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( OID_ECDSA_SHA512 ),     "ecdsa-with-SHA512",    "ECDSA with SHA512" },
+        POLARSSL_MD_SHA512,   POLARSSL_PK_ECDSA,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0, 0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg);
+FN_OID_GET_DESCRIPTOR_ATTR1(oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description);
+FN_OID_GET_ATTR2(oid_get_sig_alg, oid_sig_alg_t, sig_alg, md_type_t, md_alg, pk_type_t, pk_alg);
+FN_OID_GET_OID_BY_ATTR2(oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, pk_type_t, pk_alg, md_type_t, md_alg);
+#endif /* POLARSSL_MD_C */
+
+/*
+ * For PublicKeyInfo (PKCS1, RFC 5480)
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    pk_type_t           pk_alg;
+} oid_pk_alg_t;
+
+static const oid_pk_alg_t oid_pk_alg[] =
+{
+    {
+        { ADD_LEN( OID_PKCS1_RSA ),      "rsaEncryption",   "RSA" },
+        POLARSSL_PK_RSA,
+    },
+    {
+        { ADD_LEN( OID_EC_ALG_UNRESTRICTED ),  "id-ecPublicKey",   "Generic EC key" },
+        POLARSSL_PK_ECKEY,
+    },
+    {
+        { ADD_LEN( OID_EC_ALG_ECDH ),          "id-ecDH",          "EC key for ECDH" },
+        POLARSSL_PK_ECKEY_DH,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg);
+FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg);
+FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, pk_type_t, pk_alg);
+
+#if defined(POLARSSL_ECP_C)
+/*
+ * For namedCurve (RFC 5480)
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    ecp_group_id        grp_id;
+} oid_ecp_grp_t;
+
+static const oid_ecp_grp_t oid_ecp_grp[] =
+{
+    {
+        { ADD_LEN( OID_EC_GRP_SECP192R1 ), "secp192r1",    "secp192r1" },
+        POLARSSL_ECP_DP_SECP192R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP224R1 ), "secp224r1",    "secp224r1" },
+        POLARSSL_ECP_DP_SECP224R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP256R1 ), "secp256r1",    "secp256r1" },
+        POLARSSL_ECP_DP_SECP256R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP384R1 ), "secp384r1",    "secp384r1" },
+        POLARSSL_ECP_DP_SECP384R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP521R1 ), "secp521r1",    "secp521r1" },
+        POLARSSL_ECP_DP_SECP521R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP192K1 ), "secp192k1",    "secp192k1" },
+        POLARSSL_ECP_DP_SECP192K1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP224K1 ), "secp224k1",    "secp224k1" },
+        POLARSSL_ECP_DP_SECP224K1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP256K1 ), "secp256k1",    "secp256k1" },
+        POLARSSL_ECP_DP_SECP256K1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_BP256R1 ),   "brainpoolP256r1","brainpool256r1" },
+        POLARSSL_ECP_DP_BP256R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_BP384R1 ),   "brainpoolP384r1","brainpool384r1" },
+        POLARSSL_ECP_DP_BP384R1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_BP512R1 ),   "brainpoolP512r1","brainpool512r1" },
+        POLARSSL_ECP_DP_BP512R1,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp);
+FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id);
+FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, ecp_group_id, grp_id);
+#endif /* POLARSSL_ECP_C */
+
+#if defined(POLARSSL_CIPHER_C)
+/*
+ * For PKCS#5 PBES2 encryption algorithm
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    cipher_type_t       cipher_alg;
+} oid_cipher_alg_t;
+
+static const oid_cipher_alg_t oid_cipher_alg[] =
+{
+    {
+        { ADD_LEN( OID_DES_CBC ),              "desCBC",       "DES-CBC" },
+        POLARSSL_CIPHER_DES_CBC,
+    },
+    {
+        { ADD_LEN( OID_DES_EDE3_CBC ),         "des-ede3-cbc", "DES-EDE3-CBC" },
+        POLARSSL_CIPHER_DES_EDE3_CBC,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg);
+FN_OID_GET_ATTR1(oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, cipher_type_t, cipher_alg);
+#endif /* POLARSSL_CIPHER_C */
+
+#if defined(POLARSSL_MD_C)
+/*
+ * For digestAlgorithm
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    md_type_t           md_alg;
+} oid_md_alg_t;
+
+static const oid_md_alg_t oid_md_alg[] =
+{
+    {
+        { ADD_LEN( OID_DIGEST_ALG_MD2 ),       "id-md2",       "MD2" },
+        POLARSSL_MD_MD2,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_MD4 ),       "id-md4",       "MD4" },
+        POLARSSL_MD_MD4,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_MD5 ),       "id-md5",       "MD5" },
+        POLARSSL_MD_MD5,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA1 ),      "id-sha1",      "SHA-1" },
+        POLARSSL_MD_SHA1,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA1 ),      "id-sha1",      "SHA-1" },
+        POLARSSL_MD_SHA1,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA224 ),    "id-sha224",    "SHA-224" },
+        POLARSSL_MD_SHA224,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA256 ),    "id-sha256",    "SHA-256" },
+        POLARSSL_MD_SHA256,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA384 ),    "id-sha384",    "SHA-384" },
+        POLARSSL_MD_SHA384,
+    },
+    {
+        { ADD_LEN( OID_DIGEST_ALG_SHA512 ),    "id-sha512",    "SHA-512" },
+        POLARSSL_MD_SHA512,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg);
+FN_OID_GET_ATTR1(oid_get_md_alg, oid_md_alg_t, md_alg, md_type_t, md_alg);
+FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, md_type_t, md_alg);
+#endif /* POLARSSL_MD_C */
+
+#if defined(POLARSSL_PKCS12_C)
+/*
+ * For PKCS#12 PBEs
+ */
+typedef struct {
+    oid_descriptor_t    descriptor;
+    md_type_t           md_alg;
+    cipher_type_t       cipher_alg;
+} oid_pkcs12_pbe_alg_t;
+
+static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
+{
+    {
+        { ADD_LEN( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
+        POLARSSL_MD_SHA1,      POLARSSL_CIPHER_DES_EDE3_CBC,
+    },
+    {
+        { ADD_LEN( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
+        POLARSSL_MD_SHA1,      POLARSSL_CIPHER_DES_EDE_CBC,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0, 0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg);
+FN_OID_GET_ATTR2(oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, md_type_t, md_alg, cipher_type_t, cipher_alg);
+#endif /* POLARSSL_PKCS12_C */
+
+#define SAFE_SNPRINTF()                         \
+{                                               \
+    if( ret == -1 )                             \
+        return POLARSSL_ERR_OID_BUF_TOO_SMALL;  \
+                                                \
+    if ( (unsigned int) ret >= n ) {            \
+        p[n - 1] = '\0';                        \
+        return POLARSSL_ERR_OID_BUF_TOO_SMALL;  \
+    }                                           \
+                                                \
+    n -= (unsigned int) ret;                    \
+    p += (unsigned int) ret;                    \
+}
+
+#endif /* POLARSSL_OID_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/rsa.c u-boot-2011.06/lib/rsa.c
--- u-boot-2011.06_original/lib/rsa.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/rsa.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1610 @@
+/*
+ *  The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  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.
+ */
+/*
+ *  RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *
+ *  http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
+ *  http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_RSA_C)
+
+#include "rsa.h"
+#include "oid.h"
+
+#if defined(POLARSSL_PKCS1_V21)
+#include "md.h"
+#endif
+
+#include <common.h>
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "platform.h"
+#else
+#define polarssl_printf printf
+#endif
+
+/*
+ * Initialize an RSA context
+ */
+void rsa_init( rsa_context *ctx,
+               int padding,
+               int hash_id )
+{
+    memset( ctx, 0, sizeof( rsa_context ) );
+
+    rsa_set_padding( ctx, padding, hash_id );
+
+#if defined(POLARSSL_THREADING_C)
+    polarssl_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * Set padding for an existing RSA context
+ */
+void rsa_set_padding( rsa_context *ctx, int padding, int hash_id )
+{
+    ctx->padding = padding;
+    ctx->hash_id = hash_id;
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ */
+int rsa_gen_key( rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 unsigned int nbits, int exponent )
+{
+    int ret;
+    mpi P1, Q1, H, G;
+
+    if( f_rng == NULL || nbits < 128 || exponent < 3 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &G );
+
+    /*
+     * find primes P and Q with Q < P so that:
+     * GCD( E, (P-1)*(Q-1) ) == 1
+     */
+    MPI_CHK( mpi_lset( &ctx->E, exponent ) );
+
+    do
+    {
+        MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+                                f_rng, p_rng ) );
+
+        MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
+                                f_rng, p_rng ) );
+
+        if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
+            mpi_swap( &ctx->P, &ctx->Q );
+
+        if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
+            continue;
+
+        MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+        if( mpi_msb( &ctx->N ) != nbits )
+            continue;
+
+        MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+        MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+        MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+        MPI_CHK( mpi_gcd( &G, &ctx->E, &H  ) );
+    }
+    while( mpi_cmp_int( &G, 1 ) != 0 );
+
+    /*
+     * D  = E^-1 mod ((P-1)*(Q-1))
+     * DP = D mod (P - 1)
+     * DQ = D mod (Q - 1)
+     * QP = Q^-1 mod P
+     */
+    MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H  ) );
+    MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
+    MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
+    MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
+
+    ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
+
+cleanup:
+
+    mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &G );
+
+    if( ret != 0 )
+    {
+        rsa_free( ctx );
+        return( POLARSSL_ERR_RSA_KEY_GEN_FAILED + ret );
+    }
+
+    return( 0 );
+}
+
+#endif /* POLARSSL_GENPRIME */
+
+/*
+ * Check a public RSA key
+ */
+int rsa_check_pubkey( const rsa_context *ctx )
+{
+    if( !ctx->N.p || !ctx->E.p )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( ( ctx->N.p[0] & 1 ) == 0 ||
+        ( ctx->E.p[0] & 1 ) == 0 )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( mpi_msb( &ctx->N ) < 128 ||
+        mpi_msb( &ctx->N ) > POLARSSL_MPI_MAX_BITS )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( mpi_msb( &ctx->E ) < 2 ||
+        mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    return( 0 );
+}
+
+/*
+ * Check a private RSA key
+ */
+int rsa_check_privkey( const rsa_context *ctx )
+{
+    int ret;
+    mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;
+
+    if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
+        return( ret );
+
+    if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 );
+    mpi_init( &H  ); mpi_init( &I  ); mpi_init( &G  ); mpi_init( &G2 );
+    mpi_init( &L1 ); mpi_init( &L2 ); mpi_init( &DP ); mpi_init( &DQ );
+    mpi_init( &QP );
+
+    MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
+    MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
+    MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+    MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+    MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+    MPI_CHK( mpi_gcd( &G, &ctx->E, &H  ) );
+
+    MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
+    MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
+    MPI_CHK( mpi_mod_mpi( &I, &DE, &L1  ) );
+
+    MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
+    MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
+    MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
+    /*
+     * Check for a valid PKCS1v2 private key
+     */
+    if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
+        mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
+        mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
+        mpi_cmp_mpi( &QP, &ctx->QP ) != 0 ||
+        mpi_cmp_int( &L2, 0 ) != 0 ||
+        mpi_cmp_int( &I, 1 ) != 0 ||
+        mpi_cmp_int( &G, 1 ) != 0 )
+    {
+        ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+cleanup:
+    mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 );
+    mpi_free( &H  ); mpi_free( &I  ); mpi_free( &G  ); mpi_free( &G2 );
+    mpi_free( &L1 ); mpi_free( &L2 ); mpi_free( &DP ); mpi_free( &DQ );
+    mpi_free( &QP );
+
+    if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED )
+        return( ret );
+
+    if( ret != 0 )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Do an RSA public key operation
+ */
+int rsa_public( rsa_context *ctx,
+                const unsigned char *input,
+                unsigned char *output )
+{
+    int ret;
+    size_t olen;
+    mpi T;
+
+    mpi_init( &T );
+
+    MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        mpi_free( &T );
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    olen = ctx->len;
+    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+    MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+    mpi_free( &T );
+
+    if( ret != 0 )
+        return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+#if !defined(POLARSSL_RSA_NO_CRT)
+/*
+ * Generate or update blinding values, see section 10 of:
+ *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
+ *  DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer
+ *  Berlin Heidelberg, 1996. p. 104-113.
+ */
+static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf,
+                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret, count = 0;
+
+#if defined(POLARSSL_THREADING_C)
+    polarssl_mutex_lock( &ctx->mutex );
+#endif
+
+    if( ctx->Vf.p != NULL )
+    {
+        /* We already have blinding values, just update them by squaring */
+        MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
+        MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
+        MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
+        MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
+
+        goto done;
+    }
+
+    /* Unblinding value: Vf = random number, invertible mod N */
+    do {
+        if( count++ > 10 )
+            return( POLARSSL_ERR_RSA_RNG_FAILED );
+
+        MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
+        MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
+
+    /* Blinding value: Vi =  Vf^(-e) mod N */
+    MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
+
+done:
+    if( Vi != &ctx->Vi )
+    {
+        MPI_CHK( mpi_copy( Vi, &ctx->Vi ) );
+        MPI_CHK( mpi_copy( Vf, &ctx->Vf ) );
+    }
+
+cleanup:
+#if defined(POLARSSL_THREADING_C)
+    polarssl_mutex_unlock( &ctx->mutex );
+#endif
+
+    return( ret );
+}
+#endif /* !POLARSSL_RSA_NO_CRT */
+
+/*
+ * Do an RSA private key operation
+ */
+int rsa_private( rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 const unsigned char *input,
+                 unsigned char *output )
+{
+    int ret;
+    size_t olen;
+    mpi T, T1, T2;
+#if !defined(POLARSSL_RSA_NO_CRT)
+    mpi *Vi, *Vf;
+
+    /*
+     * When using the Chinese Remainder Theorem, we use blinding values.
+     * Without threading, we just read them directly from the context,
+     * otherwise we make a local copy in order to reduce locking contention.
+     */
+#if defined(POLARSSL_THREADING_C)
+    mpi Vi_copy, Vf_copy;
+
+    mpi_init( &Vi_copy ); mpi_init( &Vf_copy );
+    Vi = &Vi_copy;
+    Vf = &Vf_copy;
+#else
+    Vi = &ctx->Vi;
+    Vf = &ctx->Vf;
+#endif
+#endif /* !POLARSSL_RSA_NO_CRT */
+
+    mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
+
+    MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        mpi_free( &T );
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if defined(POLARSSL_RSA_NO_CRT)
+    ((void) f_rng);
+    ((void) p_rng);
+    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
+#else
+    if( f_rng != NULL )
+    {
+        /*
+         * Blinding
+         * T = T * Vi mod N
+         */
+        MPI_CHK( rsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) );
+        MPI_CHK( mpi_mul_mpi( &T, &T, Vi ) );
+        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
+    }
+
+    /*
+     * faster decryption using the CRT
+     *
+     * T1 = input ^ dP mod P
+     * T2 = input ^ dQ mod Q
+     */
+    MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
+    MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
+
+    /*
+     * T = (T1 - T2) * (Q^-1 mod P) mod P
+     */
+    MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
+    MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
+    MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
+
+    /*
+     * T = T2 + T * Q
+     */
+    MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
+    MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
+
+    if( f_rng != NULL )
+    {
+        /*
+         * Unblind
+         * T = T * Vf mod N
+         */
+        MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) );
+        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
+    }
+#endif /* POLARSSL_RSA_NO_CRT */
+
+    olen = ctx->len;
+    MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+    mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
+#if !defined(POLARSSL_RSA_NO_CRT) && defined(POLARSSL_THREADING_C)
+    mpi_free( &Vi_copy ); mpi_free( &Vf_copy );
+#endif
+
+    if( ret != 0 )
+        return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret );
+
+    return( 0 );
+}
+
+#if defined(POLARSSL_PKCS1_V21)
+/**
+ * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
+ *
+ * \param dst       buffer to mask
+ * \param dlen      length of destination buffer
+ * \param src       source of the mask generation
+ * \param slen      length of the source buffer
+ * \param md_ctx    message digest context to use
+ */
+static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
+                      size_t slen, md_context_t *md_ctx )
+{
+    unsigned char mask[POLARSSL_MD_MAX_SIZE];
+    unsigned char counter[4];
+    unsigned char *p;
+    unsigned int hlen;
+    size_t i, use_len;
+
+    memset( mask, 0, POLARSSL_MD_MAX_SIZE );
+    memset( counter, 0, 4 );
+
+    hlen = md_ctx->md_info->size;
+
+    // Generate and apply dbMask
+    //
+    p = dst;
+
+    while( dlen > 0 )
+    {
+        use_len = hlen;
+        if( dlen < hlen )
+            use_len = dlen;
+
+        md_starts( md_ctx );
+        md_update( md_ctx, src, slen );
+        md_update( md_ctx, counter, 4 );
+        md_finish( md_ctx, mask );
+
+        for( i = 0; i < use_len; ++i )
+            *p++ ^= mask[i];
+
+        counter[3]++;
+
+        dlen -= use_len;
+    }
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
+ */
+int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t ilen,
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    size_t olen;
+    int ret;
+    unsigned char *p = output;
+    unsigned int hlen;
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+
+    if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = md_info_from_type( ctx->hash_id );
+    if( md_info == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+    hlen = md_get_size( md_info );
+
+    if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    memset( output, 0, olen );
+
+    *p++ = 0;
+
+    // Generate a random octet string seed
+    //
+    if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
+        return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
+
+    p += hlen;
+
+    // Construct DB
+    //
+    md( md_info, label, label_len, p );
+    p += hlen;
+    p += olen - 2 * hlen - 2 - ilen;
+    *p++ = 1;
+    memcpy( p, input, ilen );
+
+    md_init_ctx( &md_ctx, md_info );
+
+    // maskedDB: Apply dbMask to DB
+    //
+    mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
+               &md_ctx );
+
+    // maskedSeed: Apply seedMask to seed
+    //
+    mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
+               &md_ctx );
+
+    md_free_ctx( &md_ctx );
+
+    return( ( mode == RSA_PUBLIC )
+            ? rsa_public(  ctx, output, output )
+            : rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+#if defined(POLARSSL_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
+ */
+int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t ilen,
+                                 const unsigned char *input,
+                                 unsigned char *output )
+{
+    size_t nb_pad, olen;
+    int ret;
+    unsigned char *p = output;
+
+    if( ctx->padding != RSA_PKCS_V15 || f_rng == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    if( olen < ilen + 11 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    nb_pad = olen - 3 - ilen;
+
+    *p++ = 0;
+    if( mode == RSA_PUBLIC )
+    {
+        *p++ = RSA_CRYPT;
+
+        while( nb_pad-- > 0 )
+        {
+            int rng_dl = 100;
+
+            do {
+                ret = f_rng( p_rng, p, 1 );
+            } while( *p == 0 && --rng_dl && ret == 0 );
+
+            // Check if RNG failed to generate data
+            //
+            if( rng_dl == 0 || ret != 0)
+                return POLARSSL_ERR_RSA_RNG_FAILED + ret;
+
+            p++;
+        }
+    }
+    else
+    {
+        *p++ = RSA_SIGN;
+
+        while( nb_pad-- > 0 )
+            *p++ = 0xFF;
+    }
+
+    *p++ = 0;
+    memcpy( p, input, ilen );
+
+    return( ( mode == RSA_PUBLIC )
+            ? rsa_public(  ctx, output, output )
+            : rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* POLARSSL_PKCS1_V15 */
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t ilen,
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    switch( ctx->padding )
+    {
+#if defined(POLARSSL_PKCS1_V15)
+        case RSA_PKCS_V15:
+            return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
+                                                input, output );
+#endif
+
+#if defined(POLARSSL_PKCS1_V21)
+        case RSA_PKCS_V21:
+            return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           ilen, input, output );
+#endif
+
+        default:
+            return( POLARSSL_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
+ */
+int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t *olen,
+                            const unsigned char *input,
+                            unsigned char *output,
+                            size_t output_max_len )
+{
+    int ret;
+    size_t ilen, i, pad_len;
+    unsigned char *p, bad, pad_done;
+    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+    unsigned char lhash[POLARSSL_MD_MAX_SIZE];
+    unsigned int hlen;
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+
+    /*
+     * Parameters sanity checks
+     */
+    if( ctx->padding != RSA_PKCS_V21 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    ilen = ctx->len;
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = md_info_from_type( ctx->hash_id );
+    if( md_info == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * RSA operation
+     */
+    ret = ( mode == RSA_PUBLIC )
+          ? rsa_public(  ctx, input, buf )
+          : rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    /*
+     * Unmask data and generate lHash
+     */
+    hlen = md_get_size( md_info );
+
+    md_init_ctx( &md_ctx, md_info );
+
+    /* Generate lHash */
+    md( md_info, label, label_len, lhash );
+
+    /* seed: Apply seedMask to maskedSeed */
+    mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
+               &md_ctx );
+
+    /* DB: Apply dbMask to maskedDB */
+    mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
+               &md_ctx );
+
+    md_free_ctx( &md_ctx );
+
+    /*
+     * Check contents, in "constant-time"
+     */
+    p = buf;
+    bad = 0;
+
+    bad |= *p++; /* First byte must be 0 */
+
+    p += hlen; /* Skip seed */
+
+    /* Check lHash */
+    for( i = 0; i < hlen; i++ )
+        bad |= lhash[i] ^ *p++;
+
+    /* Get zero-padding len, but always read till end of buffer
+     * (minus one, for the 01 byte) */
+    pad_len = 0;
+    pad_done = 0;
+    for( i = 0; i < ilen - 2 * hlen - 2; i++ )
+    {
+        pad_done |= p[i];
+        pad_len += ( pad_done == 0 );
+    }
+
+    p += pad_len;
+    bad |= *p++ ^ 0x01;
+
+    /*
+     * The only information "leaked" is whether the padding was correct or not
+     * (eg, no data is copied if it was not correct). This meets the
+     * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
+     * the different error conditions.
+     */
+    if( bad != 0 )
+        return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+    if (ilen - (p - buf) > output_max_len)
+        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+
+    *olen = ilen - (p - buf);
+    memcpy( output, p, *olen );
+
+    return( 0 );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+#if defined(POLARSSL_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
+ */
+int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t *olen,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 size_t output_max_len)
+{
+    int ret;
+    size_t ilen, pad_count = 0, i;
+    unsigned char *p, bad, pad_done = 0;
+    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+
+    if( ctx->padding != RSA_PKCS_V15 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    ilen = ctx->len;
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == RSA_PUBLIC )
+          ? rsa_public(  ctx, input, buf )
+          : rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    p = buf;
+    bad = 0;
+
+    /*
+     * Check and get padding len in "constant-time"
+     */
+    bad |= *p++; /* First byte must be 0 */
+
+    /* This test does not depend on secret data */
+    if( mode == RSA_PRIVATE )
+    {
+        bad |= *p++ ^ RSA_CRYPT;
+
+        /* Get padding len, but always read till end of buffer
+         * (minus one, for the 00 byte) */
+        for( i = 0; i < ilen - 3; i++ )
+        {
+            pad_done |= ( p[i] == 0 );
+            pad_count += ( pad_done == 0 );
+        }
+
+        p += pad_count;
+        bad |= *p++; /* Must be zero */
+    }
+    else
+    {
+        bad |= *p++ ^ RSA_SIGN;
+
+        /* Get padding len, but always read till end of buffer
+         * (minus one, for the 00 byte) */
+        for( i = 0; i < ilen - 3; i++ )
+        {
+            pad_done |= ( p[i] != 0xFF );
+            pad_count += ( pad_done == 0 );
+        }
+
+        p += pad_count;
+        bad |= *p++; /* Must be zero */
+    }
+
+    if( bad )
+        return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+    if (ilen - (p - buf) > output_max_len)
+        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+
+    *olen = ilen - (p - buf);
+    memcpy( output, p, *olen );
+
+    return( 0 );
+}
+#endif /* POLARSSL_PKCS1_V15 */
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len)
+{
+    switch( ctx->padding )
+    {
+#if defined(POLARSSL_PKCS1_V15)
+        case RSA_PKCS_V15:
+            return rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
+                                                input, output, output_max_len );
+#endif
+
+#if defined(POLARSSL_PKCS1_V21)
+        case RSA_PKCS_V21:
+            return rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           olen, input, output,
+                                           output_max_len );
+#endif
+
+        default:
+            return( POLARSSL_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int rsa_rsassa_pss_sign( rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         int mode,
+                         md_type_t md_alg,
+                         unsigned int hashlen,
+                         const unsigned char *hash,
+                         unsigned char *sig )
+{
+    size_t olen;
+    unsigned char *p = sig;
+    unsigned char salt[POLARSSL_MD_MAX_SIZE];
+    unsigned int slen, hlen, offset = 0;
+    int ret;
+    size_t msb;
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+
+    if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    if( md_alg != POLARSSL_MD_NONE )
+    {
+        // Gather length of hash to sign
+        //
+        md_info = md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = md_get_size( md_info );
+    }
+
+    md_info = md_info_from_type( ctx->hash_id );
+    if( md_info == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = md_get_size( md_info );
+    slen = hlen;
+
+    if( olen < hlen + slen + 2 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    memset( sig, 0, olen );
+
+    // Generate salt of length slen
+    //
+    if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+        return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
+
+    // Note: EMSA-PSS encoding is over the length of N - 1 bits
+    //
+    msb = mpi_msb( &ctx->N ) - 1;
+    p += olen - hlen * 2 - 2;
+    *p++ = 0x01;
+    memcpy( p, salt, slen );
+    p += slen;
+
+    md_init_ctx( &md_ctx, md_info );
+
+    // Generate H = Hash( M' )
+    //
+    md_starts( &md_ctx );
+    md_update( &md_ctx, p, 8 );
+    md_update( &md_ctx, hash, hashlen );
+    md_update( &md_ctx, salt, slen );
+    md_finish( &md_ctx, p );
+
+    // Compensate for boundary condition when applying mask
+    //
+    if( msb % 8 == 0 )
+        offset = 1;
+
+    // maskedDB: Apply dbMask to DB
+    //
+    mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
+
+    md_free_ctx( &md_ctx );
+
+    msb = mpi_msb( &ctx->N ) - 1;
+    sig[0] &= 0xFF >> ( olen * 8 - msb );
+
+    p += hlen;
+    *p++ = 0xBC;
+
+    return( ( mode == RSA_PUBLIC )
+            ? rsa_public(  ctx, sig, sig )
+            : rsa_private( ctx, f_rng, p_rng, sig, sig ) );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+#if defined(POLARSSL_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
+ */
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               unsigned char *sig )
+{
+    size_t nb_pad, olen, oid_size = 0;
+    unsigned char *p = sig;
+    const char *oid;
+
+    if( ctx->padding != RSA_PKCS_V15 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+    nb_pad = olen - 3;
+
+    if( md_alg != POLARSSL_MD_NONE )
+    {
+        const md_info_t *md_info = md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+        if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
+            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+        nb_pad -= 10 + oid_size;
+
+        hashlen = md_get_size( md_info );
+    }
+
+    nb_pad -= hashlen;
+
+    if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    *p++ = 0;
+    *p++ = RSA_SIGN;
+    memset( p, 0xFF, nb_pad );
+    p += nb_pad;
+    *p++ = 0;
+
+    if( md_alg == POLARSSL_MD_NONE )
+    {
+        memcpy( p, hash, hashlen );
+    }
+    else
+    {
+        /*
+         * DigestInfo ::= SEQUENCE {
+         *   digestAlgorithm DigestAlgorithmIdentifier,
+         *   digest Digest }
+         *
+         * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+         *
+         * Digest ::= OCTET STRING
+         */
+        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+        *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
+        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+        *p++ = (unsigned char) ( 0x04 + oid_size );
+        *p++ = ASN1_OID;
+        *p++ = oid_size & 0xFF;
+        memcpy( p, oid, oid_size );
+        p += oid_size;
+        *p++ = ASN1_NULL;
+        *p++ = 0x00;
+        *p++ = ASN1_OCTET_STRING;
+        *p++ = hashlen;
+        memcpy( p, hash, hashlen );
+    }
+
+    return( ( mode == RSA_PUBLIC )
+            ? rsa_public(  ctx, sig, sig )
+            : rsa_private( ctx, f_rng, p_rng, sig, sig ) );
+}
+#endif /* POLARSSL_PKCS1_V15 */
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    int mode,
+                    md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig )
+{
+    switch( ctx->padding )
+    {
+#if defined(POLARSSL_PKCS1_V15)
+        case RSA_PKCS_V15:
+            return rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                              hashlen, hash, sig );
+#endif
+
+#if defined(POLARSSL_PKCS1_V21)
+        case RSA_PKCS_V21:
+            return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                        hashlen, hash, sig );
+#endif
+
+        default:
+            return( POLARSSL_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int rsa_rsassa_pss_verify( rsa_context *ctx,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           int mode,
+                           md_type_t md_alg,
+                           unsigned int hashlen,
+                           const unsigned char *hash,
+                           const unsigned char *sig )
+{
+    int ret;
+    size_t siglen;
+    unsigned char *p;
+    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+    unsigned char result[POLARSSL_MD_MAX_SIZE];
+    unsigned char zeros[8];
+    unsigned int hlen;
+    size_t slen, msb;
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+
+    if( ctx->padding != RSA_PKCS_V21 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    siglen = ctx->len;
+
+    if( siglen < 16 || siglen > sizeof( buf ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == RSA_PUBLIC )
+          ? rsa_public(  ctx, sig, buf )
+          : rsa_private( ctx, f_rng, p_rng, sig, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    p = buf;
+
+    if( buf[siglen - 1] != 0xBC )
+        return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+    if( md_alg != POLARSSL_MD_NONE )
+    {
+        // Gather length of hash to sign
+        //
+        md_info = md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = md_get_size( md_info );
+    }
+
+    md_info = md_info_from_type( ctx->hash_id );
+    if( md_info == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = md_get_size( md_info );
+    slen = siglen - hlen - 1;
+
+    memset( zeros, 0, 8 );
+
+    // Note: EMSA-PSS verification is over the length of N - 1 bits
+    //
+    msb = mpi_msb( &ctx->N ) - 1;
+
+    // Compensate for boundary condition when applying mask
+    //
+    if( msb % 8 == 0 )
+    {
+        p++;
+        siglen -= 1;
+    }
+    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    md_init_ctx( &md_ctx, md_info );
+
+    mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
+
+    buf[0] &= 0xFF >> ( siglen * 8 - msb );
+
+    while( p < buf + siglen && *p == 0 )
+        p++;
+
+    if( p == buf + siglen ||
+        *p++ != 0x01 )
+    {
+        md_free_ctx( &md_ctx );
+        return( POLARSSL_ERR_RSA_INVALID_PADDING );
+    }
+
+    slen -= p - buf;
+
+    // Generate H = Hash( M' )
+    //
+    md_starts( &md_ctx );
+    md_update( &md_ctx, zeros, 8 );
+    md_update( &md_ctx, hash, hashlen );
+    md_update( &md_ctx, p, slen );
+    md_finish( &md_ctx, result );
+
+    md_free_ctx( &md_ctx );
+
+    if( memcmp( p + slen, result, hlen ) == 0 )
+        return( 0 );
+    else
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+#if defined(POLARSSL_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
+ */
+int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode,
+                                 md_type_t md_alg,
+                                 unsigned int hashlen,
+                                 const unsigned char *hash,
+                                 const unsigned char *sig )
+{
+    int ret;
+    size_t len, siglen, asn1_len;
+    unsigned char *p, *end;
+    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+    md_type_t msg_md_alg;
+    const md_info_t *md_info;
+    asn1_buf oid;
+
+    if( ctx->padding != RSA_PKCS_V15 )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    siglen = ctx->len;
+
+    if( siglen < 16 || siglen > sizeof( buf ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == RSA_PUBLIC )
+          ? rsa_public(  ctx, sig, buf )
+          : rsa_private( ctx, f_rng, p_rng, sig, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    p = buf;
+
+    if( *p++ != 0 || *p++ != RSA_SIGN )
+        return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+    while( *p != 0 )
+    {
+        if( p >= buf + siglen - 1 || *p != 0xFF )
+            return( POLARSSL_ERR_RSA_INVALID_PADDING );
+        p++;
+    }
+    p++;
+
+    len = siglen - ( p - buf );
+
+    if( len == hashlen && md_alg == POLARSSL_MD_NONE )
+    {
+        if( memcmp( p, hash, hashlen ) == 0 )
+            return( 0 );
+        else
+            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+    }
+
+    md_info = md_info_from_type( md_alg );
+    if( md_info == NULL )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+    hashlen = md_get_size( md_info );
+
+    end = p + len;
+
+    // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
+    //
+    if( ( ret = asn1_get_tag( &p, end, &asn1_len,
+            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( asn1_len + 2 != len )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( ( ret = asn1_get_tag( &p, end, &asn1_len,
+            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( asn1_len + 6 + hashlen != len )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    oid.p = p;
+    p += oid.len;
+
+    if( oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( md_alg != msg_md_alg )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    /*
+     * assume the algorithm parameters must be NULL
+     */
+    if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( asn1_len != hashlen )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    if( memcmp( p, hash, hashlen ) != 0 )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    p += hashlen;
+
+    if( p != end )
+        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+    return( 0 );
+}
+#endif /* POLARSSL_PKCS1_V15 */
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng,
+                      int mode,
+                      md_type_t md_alg,
+                      unsigned int hashlen,
+                      const unsigned char *hash,
+                      const unsigned char *sig )
+{
+    switch( ctx->padding )
+    {
+#if defined(POLARSSL_PKCS1_V15)
+        case RSA_PKCS_V15:
+            return rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                                hashlen, hash, sig );
+#endif
+
+#if defined(POLARSSL_PKCS1_V21)
+        case RSA_PKCS_V21:
+            return rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                          hashlen, hash, sig );
+#endif
+
+        default:
+            return( POLARSSL_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+/*
+ * Copy the components of an RSA key
+ */
+int rsa_copy( rsa_context *dst, const rsa_context *src )
+{
+    int ret;
+
+    dst->ver = src->ver;
+    dst->len = src->len;
+
+    MPI_CHK( mpi_copy( &dst->N, &src->N ) );
+    MPI_CHK( mpi_copy( &dst->E, &src->E ) );
+
+    MPI_CHK( mpi_copy( &dst->D, &src->D ) );
+    MPI_CHK( mpi_copy( &dst->P, &src->P ) );
+    MPI_CHK( mpi_copy( &dst->Q, &src->Q ) );
+    MPI_CHK( mpi_copy( &dst->DP, &src->DP ) );
+    MPI_CHK( mpi_copy( &dst->DQ, &src->DQ ) );
+    MPI_CHK( mpi_copy( &dst->QP, &src->QP ) );
+
+    MPI_CHK( mpi_copy( &dst->RN, &src->RN ) );
+    MPI_CHK( mpi_copy( &dst->RP, &src->RP ) );
+    MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) );
+
+#if !defined(POLARSSL_RSA_NO_CRT)
+    MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) );
+    MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) );
+#endif
+
+    dst->padding = src->padding;
+    dst->hash_id = src->hash_id;
+
+cleanup:
+    if( ret != 0 )
+        rsa_free( dst );
+
+    return( ret );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void rsa_free( rsa_context *ctx )
+{
+#if !defined(POLARSSL_RSA_NO_CRT)
+    mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf );
+#endif
+    mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
+    mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
+    mpi_free( &ctx->Q  ); mpi_free( &ctx->P  ); mpi_free( &ctx->D );
+    mpi_free( &ctx->E  ); mpi_free( &ctx->N  );
+
+#if defined(POLARSSL_THREADING_C)
+    polarssl_mutex_free( &ctx->mutex );
+#endif
+}
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include "polarssl/sha1.h"
+
+/*
+ * Example RSA-1024 keypair, for test purposes
+ */
+#define KEY_LEN 128
+
+#define RSA_N   "9292758453063D803DD603D5E777D788" \
+                "8ED1D5BF35786190FA2F23EBC0848AEA" \
+                "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
+                "7130B9CED7ACDF54CFC7555AC14EEBAB" \
+                "93A89813FBF3C4F8066D2D800F7C38A8" \
+                "1AE31942917403FF4946B0A83D3D3E05" \
+                "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
+                "5E94BB77B07507233A0BC7BAC8F90F79"
+
+#define RSA_E   "10001"
+
+#define RSA_D   "24BF6185468786FDD303083D25E64EFC" \
+                "66CA472BC44D253102F8B4A9D3BFA750" \
+                "91386C0077937FE33FA3252D28855837" \
+                "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
+                "DF79C5CE07EE72C7F123142198164234" \
+                "CABB724CF78B8173B9F880FC86322407" \
+                "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
+                "071513A1E85B5DFA031F21ECAE91A34D"
+
+#define RSA_P   "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
+                "2C01CAD19EA484A87EA4377637E75500" \
+                "FCB2005C5C7DD6EC4AC023CDA285D796" \
+                "C3D9E75E1EFC42488BB4F1D13AC30A57"
+
+#define RSA_Q   "C000DF51A7C77AE8D7C7370C1FF55B69" \
+                "E211C2B9E5DB1ED0BF61D0D9899620F4" \
+                "910E4168387E3C30AA1E00C339A79508" \
+                "8452DD96A9A5EA5D9DCA68DA636032AF"
+
+#define RSA_DP  "C1ACF567564274FB07A0BBAD5D26E298" \
+                "3C94D22288ACD763FD8E5600ED4A702D" \
+                "F84198A5F06C2E72236AE490C93F07F8" \
+                "3CC559CD27BC2D1CA488811730BB5725"
+
+#define RSA_DQ  "4959CBF6F8FEF750AEE6977C155579C7" \
+                "D8AAEA56749EA28623272E4F7D0592AF" \
+                "7C1F1313CAC9471B5C523BFE592F517B" \
+                "407A1BD76C164B93DA2D32A383E58357"
+
+#define RSA_QP  "9AE7FBC99546432DF71896FC239EADAE" \
+                "F38D18D2B2F0E2DD275AA977E2BF4411" \
+                "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
+                "A74206CEC169D74BF5A8C50D6F48EA08"
+
+#define PT_LEN  24
+#define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
+                "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
+
+#if defined(POLARSSL_PKCS1_V15)
+static int myrand( void *rng_state, unsigned char *output, size_t len )
+{
+#if !defined(__OpenBSD__)
+    size_t i;
+
+    if( rng_state != NULL )
+        rng_state  = NULL;
+
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+#else
+    if( rng_state != NULL )
+        rng_state = NULL;
+
+    arc4random_buf( output, len );
+#endif /* !OpenBSD */
+
+    return( 0 );
+}
+#endif /* POLARSSL_PKCS1_V15 */
+
+/*
+ * Checkup routine
+ */
+int rsa_self_test( int verbose )
+{
+    int ret = 0;
+#if defined(POLARSSL_PKCS1_V15)
+    size_t len;
+    rsa_context rsa;
+    unsigned char rsa_plaintext[PT_LEN];
+    unsigned char rsa_decrypted[PT_LEN];
+    unsigned char rsa_ciphertext[KEY_LEN];
+#if defined(POLARSSL_SHA1_C)
+    unsigned char sha1sum[20];
+#endif
+
+    rsa_init( &rsa, RSA_PKCS_V15, 0 );
+
+    rsa.len = KEY_LEN;
+    MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N  ) );
+    MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E  ) );
+    MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D  ) );
+    MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P  ) );
+    MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q  ) );
+    MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) );
+    MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) );
+    MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) );
+
+    if( verbose != 0 )
+        polarssl_printf( "  RSA key validation: " );
+
+    if( rsa_check_pubkey(  &rsa ) != 0 ||
+        rsa_check_privkey( &rsa ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n  PKCS#1 encryption : " );
+
+    memcpy( rsa_plaintext, RSA_PT, PT_LEN );
+
+    if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN,
+                           rsa_plaintext, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n  PKCS#1 decryption : " );
+
+    if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len,
+                           rsa_ciphertext, rsa_decrypted,
+                           sizeof(rsa_decrypted) ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+#if defined(POLARSSL_SHA1_C)
+    if( verbose != 0 )
+        polarssl_printf( "passed\n  PKCS#1 data sign  : " );
+
+    sha1( rsa_plaintext, PT_LEN, sha1sum );
+
+    if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0,
+                        sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n  PKCS#1 sig. verify: " );
+
+    if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0,
+                          sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            polarssl_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n\n" );
+#endif /* POLARSSL_SHA1_C */
+
+cleanup:
+    rsa_free( &rsa );
+#else /* POLARSSL_PKCS1_V15 */
+    ((void) verbose);
+#endif /* POLARSSL_PKCS1_V15 */
+    return( ret );
+}
+
+#endif /* POLARSSL_SELF_TEST */
+
+#endif /* POLARSSL_RSA_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/rsa_verify.c u-boot-2011.06/lib/rsa_verify.c
--- u-boot-2011.06_original/lib/rsa_verify.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/rsa_verify.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,226 @@
+/*
+// Author: Jiasheng.chen@celestialsemi.com
+// Version0.1 Inital @2008.02.14
+// Ported by Santosh Shukla in u-boot
+*/
+
+#include <common.h>
+#include <rsa_verify.h>
+/*#include "sha2.h"*/
+#include <sha256.h>
+#include <rsa.h>
+#include <c_stdlib.h>
+//#include "secu_hw_if.h" // commented due to compilation issue
+
+enum _SECU_BOOT_CONST_
+{
+	SECU_SHA256_LEN    = 32,
+	SECU_RSA_KEY_N_LEN = 2048/8,
+	SECU_RSA_SIG_LEN   = SECU_RSA_KEY_N_LEN,
+	SECU_RSA_KEY_E_LEN = 4,
+};
+
+static unsigned char ExternalRSAKeyN[SECU_RSA_KEY_N_LEN];
+static unsigned char ExternalRSAKeyE[SECU_RSA_KEY_E_LEN] = {0x00, 0x1, 0x00, 0x1};
+
+static int BlockHashImg(unsigned char *InputImg, int Size, unsigned char *Hash);
+static int RsaVerifySig(unsigned char *hash,
+		unsigned char *SigBuf,
+		unsigned int RsaPkcsVersion);
+
+void UpdateExternalRSAKey(unsigned char *InputBuf)
+{
+	memcpy(ExternalRSAKeyN, InputBuf, SECU_RSA_KEY_N_LEN);
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \Fn			    SHAVerify
+/// \Brief		    signature verification
+///				    1. hash the image
+///                 2. compare signature
+/// \Param[in]
+///                 InputBuf - input data
+///                 Size     - data size
+///                 SigBuf   - signature data
+/// \Param[in/out]
+/// \Param[out]
+/// \Exception
+/// \Return
+///                 0 - success, others are failed
+///
+////////////////////////////////////////////////////////////////////////////////
+int SHAVerify(unsigned char *InputBuf,
+		int Size,
+		unsigned char *SigBuf)
+{
+	int rt = -1;
+	volatile unsigned int step = 0;
+	unsigned char Hash[SECU_SHA256_LEN];
+
+	rt = BlockHashImg(InputBuf, Size, Hash);
+	step = (step << 1) | 0x1;
+	if (rt != 0)
+		return rt;
+
+	/* verify SHA256 */
+	rt = memcmp( Hash, SigBuf, SECU_SHA256_LEN );
+	step = (step << 1) | 0x1;
+	if (rt != 0)
+		return rt;
+
+	if (step == 0x3)
+		return rt;
+	else
+		return -1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \Fn		    SignatureVerify
+/// \Brief	    RSA decryption and signature verification
+///		    1. hash the image
+///                 2. RSA decrypt signature
+///                 3. compare signature
+/// \Param[in]
+///                 InputBuf - input data
+///                 Size     - data size
+///                 SigBuf   - signature data
+/// \Param[in/out]
+/// \Param[out]
+/// \Exception
+/// \Return
+///                 0 - success, others are failed
+///
+////////////////////////////////////////////////////////////////////////////////
+int SignatureVerify(unsigned char *InputBuf,
+		int Size,
+		unsigned char *SigBuf, unsigned char *Hash, unsigned int PkcsVersion)
+{
+	/* stack 8704 bytes*/
+	int rt = -1;
+	volatile unsigned int step = 0;
+
+	rt = BlockHashImg(InputBuf, Size, Hash);
+
+	step = (step << 1) | 0x1;
+	if (rt != 0)
+		return rt;
+
+	rt = RsaVerifySig(Hash, SigBuf, PkcsVersion);
+	step = (step << 1) | 0x1;
+	if (rt != 0)
+		return rt;
+
+	if (step == 0x3)
+		return rt;
+	else
+		return -1;
+}
+
+/* hybrid hash rsa verification method API */
+int HybridSignatureVerify( unsigned char hash[32], unsigned char *SigBuf, unsigned int PkcsVersion)
+{
+	/* stack 8704 bytes*/
+	int rt = -1;
+	volatile unsigned int step = 0;
+
+	/* dummy hashing approval method */
+	step = (step << 1) | 0x1;
+
+	/* rsa verify */
+	rt = RsaVerifySig(hash, SigBuf, PkcsVersion);
+	step = (step << 1) | 0x1;
+	if (rt != 0)
+		return rt;
+
+	if (step == 0x3)
+		return rt;
+	else
+		return -1;
+}
+
+static int BlockHashImg(unsigned char *InputImg, int Size, unsigned char *Hash)
+	/*
+	 * Hash calculation for memory block
+	 * Return True or False
+	 */
+{
+	sha256(InputImg, Size, Hash, 0);
+
+	return 0;
+}
+
+static int RsaVerifySig(unsigned char *hash,
+		unsigned char *SigBuf,
+		unsigned int RsaPkcsVersion)
+{
+	/* stack 8664 bytes */
+	int ret = -1;
+	volatile unsigned int step = 0;
+
+	rsa_context rsa;
+	// 0 Initial
+	rsa_init( &rsa, RsaPkcsVersion, POLARSSL_MD_SHA256 );
+	step = (step << 1) | 0x1;       // step 1 done
+	// 1 Read PubKey
+	{
+		unsigned char *KeyNBuf;
+		unsigned char *KeyEBuf;
+		int KeyNBufLen = 0;
+		int KeyEBufLen = 0;
+
+		KeyNBuf = ExternalRSAKeyN;
+		KeyNBufLen = sizeof(ExternalRSAKeyN) / sizeof(unsigned char);
+
+		KeyEBuf = ExternalRSAKeyE;
+		KeyEBufLen = sizeof(ExternalRSAKeyE) / sizeof(unsigned char);
+
+		if (KeyNBufLen != SECU_RSA_KEY_N_LEN ||
+				KeyEBufLen != SECU_RSA_KEY_E_LEN)
+		{
+			ret = -1;
+			goto exit;
+		}
+
+		if( ( ret = mpi_read_binary( &rsa.N, KeyNBuf, KeyNBufLen ))||
+				( ret = mpi_read_binary( &rsa.E, KeyEBuf, KeyEBufLen )))
+		{
+			ret = -1;
+			goto exit;
+		}
+		rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
+	}
+	step = (step << 1) | 0x1;           // step 2 done
+	// 2 check rsa key
+	{
+		if ( ( ret = rsa_check_pubkey(&rsa) ) != 0 )
+		{
+			ret = -1;
+			goto exit;
+		}
+	}
+	step = (step << 1) | 0x1;           // step 3 done
+
+	// 3  Do Verify
+	{
+		ret = rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA256,
+				SECU_SHA256_LEN, hash, SigBuf);
+
+		if( ret != 0 )
+		{
+			ret = -1;
+			goto exit;
+		}
+	}
+	step = (step << 1) | 0x1;           // step 4 done
+
+exit:
+	rsa_free(&rsa);
+	if (step == 0xf)   	            // step check
+		return ret;
+	else
+		return -1;
+}
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/sha256.c u-boot-2011.06/lib/sha256.c
--- u-boot-2011.06_original/lib/sha256.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/lib/sha256.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,93 +1,141 @@
 /*
- * FIPS-180-2 compliant SHA-256 implementation
+ *  FIPS-180-2 compliant SHA-256 implementation
  *
- * Copyright (C) 2001-2003  Christophe Devine
+ *  Copyright (C) 2006-2014, Brainspark B.V.
  *
- * 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 file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
  *
- * 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.
+ *  All rights reserved.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  This 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.
+ */
+/*
+ *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
+ *
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
  */
 
-#ifndef USE_HOSTCC
-#include <common.h>
-#endif /* USE_HOSTCC */
-#include <watchdog.h>
-#include <linux/string.h>
-#include <sha256.h>
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config_polarssl.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_SHA256_C)
+
+#include "sha256.h"
+
+#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
+#include <stdio.h>
+#endif
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "platform.h"
+#else
+#define polarssl_printf printf
+#endif
+
+#if !defined(POLARSSL_SHA256_ALT)
 
 /*
  * 32-bit integer manipulation macros (big endian)
  */
 #ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) {				\
-	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
-	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
-	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
-	    | ( (unsigned long) (b)[(i) + 3]       );	\
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
 }
 #endif
+
 #ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) {				\
-	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
-	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
-	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
-	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
 }
 #endif
 
-void sha256_starts(sha256_context * ctx)
+/*
+ * SHA-256 context setup
+ */
+void sha256_starts( sha256_context *ctx, int is224 )
 {
-	ctx->total[0] = 0;
-	ctx->total[1] = 0;
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is224 == 0 )
+    {
+        /* SHA-256 */
+        ctx->state[0] = 0x6A09E667;
+        ctx->state[1] = 0xBB67AE85;
+        ctx->state[2] = 0x3C6EF372;
+        ctx->state[3] = 0xA54FF53A;
+        ctx->state[4] = 0x510E527F;
+        ctx->state[5] = 0x9B05688C;
+        ctx->state[6] = 0x1F83D9AB;
+        ctx->state[7] = 0x5BE0CD19;
+    }
+    else
+    {
+        /* SHA-224 */
+        ctx->state[0] = 0xC1059ED8;
+        ctx->state[1] = 0x367CD507;
+        ctx->state[2] = 0x3070DD17;
+        ctx->state[3] = 0xF70E5939;
+        ctx->state[4] = 0xFFC00B31;
+        ctx->state[5] = 0x68581511;
+        ctx->state[6] = 0x64F98FA7;
+        ctx->state[7] = 0xBEFA4FA4;
+    }
 
-	ctx->state[0] = 0x6A09E667;
-	ctx->state[1] = 0xBB67AE85;
-	ctx->state[2] = 0x3C6EF372;
-	ctx->state[3] = 0xA54FF53A;
-	ctx->state[4] = 0x510E527F;
-	ctx->state[5] = 0x9B05688C;
-	ctx->state[6] = 0x1F83D9AB;
-	ctx->state[7] = 0x5BE0CD19;
-}
-
-void sha256_process(sha256_context * ctx, uint8_t data[64])
-{
-	uint32_t temp1, temp2;
-	uint32_t W[64];
-	uint32_t A, B, C, D, E, F, G, H;
-
-	GET_UINT32_BE(W[0], data, 0);
-	GET_UINT32_BE(W[1], data, 4);
-	GET_UINT32_BE(W[2], data, 8);
-	GET_UINT32_BE(W[3], data, 12);
-	GET_UINT32_BE(W[4], data, 16);
-	GET_UINT32_BE(W[5], data, 20);
-	GET_UINT32_BE(W[6], data, 24);
-	GET_UINT32_BE(W[7], data, 28);
-	GET_UINT32_BE(W[8], data, 32);
-	GET_UINT32_BE(W[9], data, 36);
-	GET_UINT32_BE(W[10], data, 40);
-	GET_UINT32_BE(W[11], data, 44);
-	GET_UINT32_BE(W[12], data, 48);
-	GET_UINT32_BE(W[13], data, 52);
-	GET_UINT32_BE(W[14], data, 56);
-	GET_UINT32_BE(W[15], data, 60);
+    ctx->is224 = is224;
+}
 
-#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+void sha256_process( sha256_context *ctx, const unsigned char data[64] )
+{
+    uint32_t temp1, temp2, W[64];
+    uint32_t A, B, C, D, E, F, G, H;
+
+    GET_UINT32_BE( W[ 0], data,  0 );
+    GET_UINT32_BE( W[ 1], data,  4 );
+    GET_UINT32_BE( W[ 2], data,  8 );
+    GET_UINT32_BE( W[ 3], data, 12 );
+    GET_UINT32_BE( W[ 4], data, 16 );
+    GET_UINT32_BE( W[ 5], data, 20 );
+    GET_UINT32_BE( W[ 6], data, 24 );
+    GET_UINT32_BE( W[ 7], data, 28 );
+    GET_UINT32_BE( W[ 8], data, 32 );
+    GET_UINT32_BE( W[ 9], data, 36 );
+    GET_UINT32_BE( W[10], data, 40 );
+    GET_UINT32_BE( W[11], data, 44 );
+    GET_UINT32_BE( W[12], data, 48 );
+    GET_UINT32_BE( W[13], data, 52 );
+    GET_UINT32_BE( W[14], data, 56 );
+    GET_UINT32_BE( W[15], data, 60 );
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
 
-#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
-#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
 
 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
@@ -95,168 +143,575 @@
 #define F0(x,y,z) ((x & y) | (z & (x | y)))
 #define F1(x,y,z) (z ^ (x & (y ^ z)))
 
-#define R(t)					\
-(						\
-	W[t] = S1(W[t - 2]) + W[t - 7] +	\
-		S0(W[t - 15]) + W[t - 16]	\
+#define R(t)                                    \
+(                                               \
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \
+           S0(W[t - 15]) + W[t - 16]            \
 )
 
-#define P(a,b,c,d,e,f,g,h,x,K) {		\
-	temp1 = h + S3(e) + F1(e,f,g) + K + x;	\
-	temp2 = S2(a) + F0(a,b,c);		\
-	d += temp1; h = temp1 + temp2;		\
-}
-
-	A = ctx->state[0];
-	B = ctx->state[1];
-	C = ctx->state[2];
-	D = ctx->state[3];
-	E = ctx->state[4];
-	F = ctx->state[5];
-	G = ctx->state[6];
-	H = ctx->state[7];
-
-	P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
-	P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
-	P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
-	P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
-	P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
-	P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
-	P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
-	P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
-	P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
-	P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
-	P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
-	P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
-	P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
-	P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
-	P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
-	P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
-	P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
-	P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
-	P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
-	P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
-	P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
-	P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
-	P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
-	P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
-	P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
-	P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
-	P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
-	P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
-	P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
-	P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
-	P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
-	P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
-	P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
-	P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
-	P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
-	P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
-	P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
-	P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
-	P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
-	P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
-	P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
-	P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
-	P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
-	P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
-	P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
-	P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
-	P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
-	P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
-	P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
-	P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
-	P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
-	P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
-	P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
-	P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
-	P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
-	P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
-	P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
-	P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
-	P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
-	P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
-	P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
-	P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
-	P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
-	P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
-
-	ctx->state[0] += A;
-	ctx->state[1] += B;
-	ctx->state[2] += C;
-	ctx->state[3] += D;
-	ctx->state[4] += E;
-	ctx->state[5] += F;
-	ctx->state[6] += G;
-	ctx->state[7] += H;
-}
-
-void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length)
-{
-	uint32_t left, fill;
-
-	if (!length)
-		return;
-
-	left = ctx->total[0] & 0x3F;
-	fill = 64 - left;
-
-	ctx->total[0] += length;
-	ctx->total[0] &= 0xFFFFFFFF;
-
-	if (ctx->total[0] < length)
-		ctx->total[1]++;
-
-	if (left && length >= fill) {
-		memcpy((void *) (ctx->buffer + left), (void *) input, fill);
-		sha256_process(ctx, ctx->buffer);
-		length -= fill;
-		input += fill;
-		left = 0;
-	}
-
-	while (length >= 64) {
-		sha256_process(ctx, input);
-		length -= 64;
-		input += 64;
-	}
-
-	if (length)
-		memcpy((void *) (ctx->buffer + left), (void *) input, length);
-}
-
-static uint8_t sha256_padding[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+    F = ctx->state[5];
+    G = ctx->state[6];
+    H = ctx->state[7];
+
+    P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
+    P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
+    P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
+    P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
+    P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
+    P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
+    P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
+    P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
+    P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
+    P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
+    P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
+    P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
+    P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
+    P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
+    P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
+    P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
+    P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
+    P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
+    P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
+    P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
+    P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
+    P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
+    P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
+    P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
+    P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
+    P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
+    P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
+    P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
+    P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
+    P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
+    P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
+    P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
+    P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
+    P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
+    P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
+    P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
+    P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
+    P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
+    P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
+    P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
+    P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
+    P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
+    P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
+    P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
+    P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
+    P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
+    P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
+    P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
+    P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
+    P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
+    P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
+    P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
+    P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
+    P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
+    P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
+    P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
+    P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
+    P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
+    P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
+    P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
+    P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
+    P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
+    P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
+    P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+    ctx->state[5] += F;
+    ctx->state[6] += G;
+    ctx->state[7] += H;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+void sha256_update( sha256_context *ctx, const unsigned char *input,
+                    size_t ilen )
+{
+    size_t fill;
+    uint32_t left;
+
+    if( ilen <= 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        sha256_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        sha256_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+}
+
+static const unsigned char sha256_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-void sha256_finish(sha256_context * ctx, uint8_t digest[32])
+/*
+ * SHA-256 final digest
+ */
+void sha256_finish( sha256_context *ctx, unsigned char output[32] )
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, msglen, 0 );
+    PUT_UINT32_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    sha256_update( ctx, sha256_padding, padn );
+    sha256_update( ctx, msglen, 8 );
+
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+    PUT_UINT32_BE( ctx->state[5], output, 20 );
+    PUT_UINT32_BE( ctx->state[6], output, 24 );
+
+    if( ctx->is224 == 0 )
+        PUT_UINT32_BE( ctx->state[7], output, 28 );
+}
+
+#endif /* !POLARSSL_SHA256_ALT */
+
+/*
+ * output = SHA-256( input buffer )
+ */
+void sha256( const unsigned char *input, size_t ilen,
+             unsigned char output[32], int is224 )
 {
-	uint32_t last, padn;
-	uint32_t high, low;
-	uint8_t msglen[8];
-
-	high = ((ctx->total[0] >> 29)
-		| (ctx->total[1] << 3));
-	low = (ctx->total[0] << 3);
-
-	PUT_UINT32_BE(high, msglen, 0);
-	PUT_UINT32_BE(low, msglen, 4);
-
-	last = ctx->total[0] & 0x3F;
-	padn = (last < 56) ? (56 - last) : (120 - last);
-
-	sha256_update(ctx, sha256_padding, padn);
-	sha256_update(ctx, msglen, 8);
-
-	PUT_UINT32_BE(ctx->state[0], digest, 0);
-	PUT_UINT32_BE(ctx->state[1], digest, 4);
-	PUT_UINT32_BE(ctx->state[2], digest, 8);
-	PUT_UINT32_BE(ctx->state[3], digest, 12);
-	PUT_UINT32_BE(ctx->state[4], digest, 16);
-	PUT_UINT32_BE(ctx->state[5], digest, 20);
-	PUT_UINT32_BE(ctx->state[6], digest, 24);
-	PUT_UINT32_BE(ctx->state[7], digest, 28);
+    sha256_context ctx;
+
+    sha256_starts( &ctx, is224 );
+    sha256_update( &ctx, input, ilen );
+    sha256_finish( &ctx, output );
+
+    memset( &ctx, 0, sizeof( sha256_context ) );
 }
+
+#if defined(POLARSSL_FS_IO)
+/*
+ * output = SHA-256( file contents )
+ */
+int sha256_file( const char *path, unsigned char output[32], int is224 )
+{
+    FILE *f;
+    size_t n;
+    sha256_context ctx;
+    unsigned char buf[1024];
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( POLARSSL_ERR_SHA256_FILE_IO_ERROR );
+
+    sha256_starts( &ctx, is224 );
+
+    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
+        sha256_update( &ctx, buf, n );
+
+    sha256_finish( &ctx, output );
+
+    memset( &ctx, 0, sizeof( sha256_context ) );
+
+    if( ferror( f ) != 0 )
+    {
+        fclose( f );
+        return( POLARSSL_ERR_SHA256_FILE_IO_ERROR );
+    }
+
+    fclose( f );
+    return( 0 );
+}
+#endif /* POLARSSL_FS_IO */
+
+/*
+ * SHA-256 HMAC context setup
+ */
+void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key,
+                         size_t keylen, int is224 )
+{
+    size_t i;
+    unsigned char sum[32];
+
+    if( keylen > 64 )
+    {
+        sha256( key, keylen, sum, is224 );
+        keylen = ( is224 ) ? 28 : 32;
+        key = sum;
+    }
+
+    memset( ctx->ipad, 0x36, 64 );
+    memset( ctx->opad, 0x5C, 64 );
+
+    for( i = 0; i < keylen; i++ )
+    {
+        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
+        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
+    }
+
+    sha256_starts( ctx, is224 );
+    sha256_update( ctx, ctx->ipad, 64 );
+
+    memset( sum, 0, sizeof( sum ) );
+}
+
+/*
+ * SHA-256 HMAC process buffer
+ */
+void sha256_hmac_update( sha256_context *ctx, const unsigned char *input,
+                         size_t ilen )
+{
+    sha256_update( ctx, input, ilen );
+}
+
+/*
+ * SHA-256 HMAC final digest
+ */
+void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] )
+{
+    int is224, hlen;
+    unsigned char tmpbuf[32];
+
+    is224 = ctx->is224;
+    hlen = ( is224 == 0 ) ? 32 : 28;
+
+    sha256_finish( ctx, tmpbuf );
+    sha256_starts( ctx, is224 );
+    sha256_update( ctx, ctx->opad, 64 );
+    sha256_update( ctx, tmpbuf, hlen );
+    sha256_finish( ctx, output );
+
+    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+}
+
+/*
+ * SHA-256 HMAC context reset
+ */
+void sha256_hmac_reset( sha256_context *ctx )
+{
+    sha256_starts( ctx, ctx->is224 );
+    sha256_update( ctx, ctx->ipad, 64 );
+}
+
+/*
+ * output = HMAC-SHA-256( hmac key, input buffer )
+ */
+void sha256_hmac( const unsigned char *key, size_t keylen,
+                  const unsigned char *input, size_t ilen,
+                  unsigned char output[32], int is224 )
+{
+    sha256_context ctx;
+
+    sha256_hmac_starts( &ctx, key, keylen, is224 );
+    sha256_hmac_update( &ctx, input, ilen );
+    sha256_hmac_finish( &ctx, output );
+
+    memset( &ctx, 0, sizeof( sha256_context ) );
+}
+
+#if defined(POLARSSL_SELF_TEST)
+/*
+ * FIPS-180-2 test vectors
+ */
+static unsigned char sha256_test_buf[3][57] =
+{
+    { "abc" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "" }
+};
+
+static const int sha256_test_buflen[3] =
+{
+    3, 56, 1000
+};
+
+static const unsigned char sha256_test_sum[6][32] =
+{
+    /*
+     * SHA-224 test vectors
+     */
+    { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
+      0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
+      0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
+      0xE3, 0x6C, 0x9D, 0xA7 },
+    { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
+      0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
+      0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
+      0x52, 0x52, 0x25, 0x25 },
+    { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
+      0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
+      0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
+      0x4E, 0xE7, 0xAD, 0x67 },
+
+    /*
+     * SHA-256 test vectors
+     */
+    { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
+      0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
+      0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
+      0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
+    { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
+      0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
+      0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
+      0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
+    { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
+      0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
+      0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
+      0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
+};
+
+/*
+ * RFC 4231 test vectors
+ */
+static unsigned char sha256_hmac_test_key[7][26] =
+{
+    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
+      "\x0B\x0B\x0B\x0B" },
+    { "Jefe" },
+    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+      "\xAA\xAA\xAA\xAA" },
+    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
+      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
+    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
+      "\x0C\x0C\x0C\x0C" },
+    { "" }, /* 0xAA 131 times */
+    { "" }
+};
+
+static const int sha256_hmac_test_keylen[7] =
+{
+    20, 4, 20, 25, 20, 131, 131
+};
+
+static unsigned char sha256_hmac_test_buf[7][153] =
+{
+    { "Hi There" },
+    { "what do ya want for nothing?" },
+    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
+    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
+    { "Test With Truncation" },
+    { "Test Using Larger Than Block-Size Key - Hash Key First" },
+    { "This is a test using a larger than block-size key "
+      "and a larger than block-size data. The key needs to "
+      "be hashed before being used by the HMAC algorithm." }
+};
+
+static const int sha256_hmac_test_buflen[7] =
+{
+    8, 28, 50, 50, 20, 54, 152
+};
+
+static const unsigned char sha256_hmac_test_sum[14][32] =
+{
+    /*
+     * HMAC-SHA-224 test vectors
+     */
+    { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
+      0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
+      0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
+      0x53, 0x68, 0x4B, 0x22 },
+    { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
+      0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
+      0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
+      0x8F, 0xD0, 0x5E, 0x44 },
+    { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
+      0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
+      0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
+      0xEC, 0x83, 0x33, 0xEA },
+    { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
+      0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
+      0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
+      0xE7, 0xAF, 0xEC, 0x5A },
+    { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
+      0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
+    { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
+      0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
+      0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
+      0x3F, 0xA6, 0x87, 0x0E },
+    { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
+      0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
+      0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
+      0xF6, 0xF5, 0x65, 0xD1 },
+
+    /*
+     * HMAC-SHA-256 test vectors
+     */
+    { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
+      0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
+      0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
+      0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
+    { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
+      0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
+      0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
+      0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
+    { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
+      0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
+      0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
+      0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
+    { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
+      0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
+      0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
+      0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
+    { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
+      0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
+    { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
+      0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
+      0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
+      0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
+    { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
+      0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
+      0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
+      0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
+};
+
+/*
+ * Checkup routine
+ */
+int sha256_self_test( int verbose )
+{
+    int i, j, k, buflen;
+    unsigned char buf[1024];
+    unsigned char sha256sum[32];
+    sha256_context ctx;
+
+    for( i = 0; i < 6; i++ )
+    {
+        j = i % 3;
+        k = i < 3;
+
+        if( verbose != 0 )
+            polarssl_printf( "  SHA-%d test #%d: ", 256 - k * 32, j + 1 );
+
+        sha256_starts( &ctx, k );
+
+        if( j == 2 )
+        {
+            memset( buf, 'a', buflen = 1000 );
+
+            for( j = 0; j < 1000; j++ )
+                sha256_update( &ctx, buf, buflen );
+        }
+        else
+            sha256_update( &ctx, sha256_test_buf[j],
+                                 sha256_test_buflen[j] );
+
+        sha256_finish( &ctx, sha256sum );
+
+        if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
+        {
+            if( verbose != 0 )
+                polarssl_printf( "failed\n" );
+
+            return( 1 );
+        }
+
+        if( verbose != 0 )
+            polarssl_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "\n" );
+
+    for( i = 0; i < 14; i++ )
+    {
+        j = i % 7;
+        k = i < 7;
+
+        if( verbose != 0 )
+            polarssl_printf( "  HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
+
+        if( j == 5 || j == 6 )
+        {
+            memset( buf, '\xAA', buflen = 131 );
+            sha256_hmac_starts( &ctx, buf, buflen, k );
+        }
+        else
+            sha256_hmac_starts( &ctx, sha256_hmac_test_key[j],
+                                      sha256_hmac_test_keylen[j], k );
+
+        sha256_hmac_update( &ctx, sha256_hmac_test_buf[j],
+                                  sha256_hmac_test_buflen[j] );
+
+        sha256_hmac_finish( &ctx, sha256sum );
+
+        buflen = ( j == 4 ) ? 16 : 32 - k * 4;
+
+        if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 )
+        {
+            if( verbose != 0 )
+                polarssl_printf( "failed\n" );
+
+            return( 1 );
+        }
+
+        if( verbose != 0 )
+            polarssl_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        polarssl_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* POLARSSL_SELF_TEST */
+
+#endif /* POLARSSL_SHA256_C */
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/time.c u-boot-2011.06/lib/time.c
--- u-boot-2011.06_original/lib/time.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/lib/time.c	2015-05-29 14:14:51.790650000 +0800
@@ -41,3 +41,10 @@
 		usec -= kv;
 	} while(usec);
 }
+
+void mdelay(unsigned long msec)
+{
+	while (msec--)
+		udelay(1000);
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/vsprintf.c u-boot-2011.06/lib/vsprintf.c
--- u-boot-2011.06_original/lib/vsprintf.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/lib/vsprintf.c	2014-07-29 17:28:38.819972000 +0800
@@ -119,11 +119,34 @@
 	return simple_strtoul(cp,endp,base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
 	unsigned long result = simple_strtoul(cp, endp, base);
 	switch (**endp) {
-	case 'G' :
+	case 'G':
+		result *= 1024;
+		/* fall through */
+	case 'M':
+		result *= 1024;
+		/* fall through */
+	case 'K':
+	case 'k':
+		result *= 1024;
+		if ((*endp)[1] == 'i') {
+			if ((*endp)[2] == 'B')
+				(*endp) += 3;
+			else
+				(*endp) += 2;
+		}
+	}
+	return result;
+}
+
+unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long long result = simple_strtoull(cp, endp, base);
+	switch (**endp) {
+	case 'G':
 		result *= 1024;
 		/* fall through */
 	case 'M':
diff '--exclude=.svn' -Naur u-boot-2011.06_original/lib/x_clib.c u-boot-2011.06/lib/x_clib.c
--- u-boot-2011.06_original/lib/x_clib.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/lib/x_clib.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,84 @@
+/*
+// Author: Jiasheng.chen@celestialsemi.com
+// Version0.1 Inital @2008.02.15
+*/
+
+#include <x_clib.h>
+
+void *x_memset(
+   void* dest,
+   int c, 
+   int count )
+{
+	int i = 0;
+	if (dest == NULL || count <=0)
+	{
+		return NULL;
+	}
+	while (i < count)
+	{
+		*((char *)dest + i) = (char)c;
+		i++;
+	}
+	return dest;
+}
+
+void *x_memcpy(
+   void *dest,
+   const void *src,
+   int count 
+)
+{
+	int i = 0;
+	if (count <=0)
+	{
+		return NULL;
+	}
+	for (i = 0; i < count ; i++)
+	{
+		*((char *)dest + i) = *((char *)src + i); 
+	}
+	return dest;
+}
+
+int  x_memcmp(const void* str1, const void* str2, int n)
+{
+    register unsigned char *s1 = (unsigned char*)str1;
+    register unsigned char *s2 = (unsigned char*)str2;
+	if (s1 == NULL || s2 == NULL)
+		return -1;
+    while (n-- > 0) {
+        if (*s1++ != *s2++)
+            return s1[-1] < s2[-1] ? -1 : 1;
+    }
+    return 0;
+}
+
+unsigned int udivsi3(unsigned int num, unsigned int den)
+{
+    unsigned int quot = 0, qbit = 1;
+
+    if ( den == 0 ) {
+        ///__divide_error();
+        return 0;			/* If trap returns... */
+    }
+
+    /* Left-justify denominator and count shift */
+    while ( (int)den >= 0 ) {
+        den <<= 1;
+        qbit <<= 1;
+    }
+
+    while ( qbit ) {
+        if ( den <= num ) {
+            num -= den;
+            quot += qbit;
+        }
+        
+        den >>= 1;
+        qbit >>= 1;
+    }
+
+    return quot;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/Makefile u-boot-2011.06/Makefile
--- u-boot-2011.06_original/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -20,11 +20,15 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 # MA 02111-1307 USA
 #
-
+Q=@
 VERSION = 2011
 PATCHLEVEL = 06
 SUBLEVEL =
 EXTRAVERSION =
+																					
+KERNEL_PEM_KEY_2_C_FILE_NAME=$(CNC_PLATFORM)/security/resources/$(CUSTOMER_NAME)/CNC83xx_$(CUSTOMER_NAME)_kernel_public_key.c
+BLOB_PEM_KEY_2_C_FILE_NAME=$(CNC_PLATFORM)/security/resources/$(CUSTOMER_NAME)/CNC83xx_$(CUSTOMER_NAME)_blob_public_key.c
+
 ifneq "$(SUBLEVEL)" ""
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
@@ -33,6 +37,14 @@
 TIMESTAMP_FILE = $(obj)include/timestamp_autogenerated.h
 VERSION_FILE = $(obj)include/version_autogenerated.h
 
+localvers=$(shell tools/setlocalversion $(TOPDIR))
+ifneq ($(localvers),)
+$(shell echo $(localvers)>include/version_svn.h)	
+else
+localvers=$(shell cat include/version_svn.h)
+endif	
+
+
 HOSTARCH := $(shell uname -m | \
 	sed -e s/i.86/x86/ \
 	    -e s/sun4u/sparc64/ \
@@ -147,7 +159,7 @@
 # Include autoconf.mk before config.mk so that the config options are available
 # to all top level build files.  We need the dummy all: target to prevent the
 # dependency target in autoconf.mk.dep from being the default.
-all:
+all: chk_cnc_env
 sinclude $(obj)include/autoconf.mk.dep
 sinclude $(obj)include/autoconf.mk
 
@@ -159,6 +171,8 @@
 ifeq ($(HOSTARCH),$(ARCH))
 CROSS_COMPILE ?=
 endif
+#for 83XX we are going to use arm-none-linux-gnueabi-gcc compiler from codesourcery.
+CROSS_COMPILE=arm-linux-gnueabihf-
 
 # load other configuration
 include $(TOPDIR)/config.mk
@@ -273,6 +287,11 @@
 LIBS += drivers/usb/phy/libusb_phy.o
 LIBS += drivers/video/libvideo.o
 LIBS += drivers/watchdog/libwatchdog.o
+ifeq ($(SOC), cnc1900)
+LIBS += drivers/cnc1900/crypto/libcrypto.o
+LIBS += drivers/cnc1900/cncedid/libedid.o
+LIBS += drivers/cnc1900/df/libdf.o
+endif
 LIBS += common/libcommon.o
 LIBS += lib/libfdt/libfdt.o
 LIBS += api/libapi.o
@@ -341,7 +360,7 @@
 endif
 
 # Always append ALL so that arch config.mk's can add custom ones
-ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map
+ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(obj)u-boot.dis
 
 ifeq ($(CONFIG_NAND_U_BOOT),y)
 ALL += $(obj)u-boot-nand.bin
@@ -359,46 +378,46 @@
 all:		$(ALL)
 
 $(obj)u-boot.hex:	$(obj)u-boot
-		$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
+		$(Q)$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
 
 $(obj)u-boot.srec:	$(obj)u-boot
-		$(OBJCOPY) -O srec $< $@
+		$(Q)$(OBJCOPY) -O srec $< $@
 
-$(obj)u-boot.bin:	$(obj)u-boot
-		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
-		$(BOARD_SIZE_CHECK)
+$(obj)u-boot.bin:	$(obj)u-boot 
+		$(Q)$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+		$(Q)$(BOARD_SIZE_CHECK)
 
 $(obj)u-boot.ldr:	$(obj)u-boot
-		$(CREATE_LDR_ENV)
-		$(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
-		$(BOARD_SIZE_CHECK)
+		$(Q)$(CREATE_LDR_ENV)
+		$(Q)$(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
+		$(Q)$(BOARD_SIZE_CHECK)
 
 $(obj)u-boot.ldr.hex:	$(obj)u-boot.ldr
-		$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
+		$(Q)$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
 
 $(obj)u-boot.ldr.srec:	$(obj)u-boot.ldr
-		$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
+		$(Q)$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
 
 $(obj)u-boot.img:	$(obj)u-boot.bin
-		$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
+		$(Q)$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
 		-a $(CONFIG_SYS_TEXT_BASE) -e 0 \
 		-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
 			sed -e 's/"[	 ]*$$/ for $(BOARD) board"/') \
 		-d $< $@
 
 $(obj)u-boot.imx:       $(obj)u-boot.bin
-		$(obj)tools/mkimage -n  $(CONFIG_IMX_CONFIG) -T imximage \
+		$(Q)$(obj)tools/mkimage -n  $(CONFIG_IMX_CONFIG) -T imximage \
 		-e $(CONFIG_SYS_TEXT_BASE) -d $< $@
 
 $(obj)u-boot.kwb:       $(obj)u-boot.bin
-		$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
+		$(Q)$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
 		-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@
 
 $(obj)u-boot.sha1:	$(obj)u-boot.bin
-		$(obj)tools/ubsha1 $(obj)u-boot.bin
+		$(Q)$(obj)tools/ubsha1 $(obj)u-boot.bin
 
 $(obj)u-boot.dis:	$(obj)u-boot
-		$(OBJDUMP) -d $< > $@
+		$(Q)$(OBJDUMP) -d $< > $@
 
 GEN_UBOOT = \
 		UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
@@ -412,43 +431,43 @@
 ifeq ($(CONFIG_KALLSYMS),y)
 		smap=`$(call SYSTEM_MAP,u-boot) | \
 			awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \
-		$(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \
+		$(Q)$(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \
 			-c common/system_map.c -o $(obj)common/system_map.o
-		$(GEN_UBOOT) $(obj)common/system_map.o
+		$(Q)$(GEN_UBOOT) $(obj)common/system_map.o
 endif
 
 $(OBJS):	depend
-		$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
+		$(Q)$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
 
 $(LIBS):	depend $(SUBDIRS)
-		$(MAKE) -C $(dir $(subst $(obj),,$@))
+		$(Q)$(MAKE) -C $(dir $(subst $(obj),,$@))
 
 $(LIBBOARD):	depend $(LIBS)
-		$(MAKE) -C $(dir $(subst $(obj),,$@))
+		$(Q)$(MAKE) -C $(dir $(subst $(obj),,$@))
 
 $(SUBDIRS):	depend
-		$(MAKE) -C $@ all
+		$(Q)$(MAKE) -C $@ all
 
 $(LDSCRIPT):	depend
-		$(MAKE) -C $(dir $@) $(notdir $@)
+		$(Q)$(MAKE) -C $(dir $@) $(notdir $@)
 
 $(obj)u-boot.lds: $(LDSCRIPT)
-		$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
+		$(Q)$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
 
 nand_spl:	$(TIMESTAMP_FILE) $(VERSION_FILE) depend
-		$(MAKE) -C nand_spl/board/$(BOARDDIR) all
+		$(Q)$(MAKE) -C nand_spl/board/$(BOARDDIR) all
 
 $(obj)u-boot-nand.bin:	nand_spl $(obj)u-boot.bin
-		cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
+		$(Q)cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
 
 onenand_ipl:	$(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk
-		$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
+		$(Q)$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
 
 $(obj)u-boot-onenand.bin:	onenand_ipl $(obj)u-boot.bin
-		cat $(ONENAND_BIN) $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
+		$(Q)cat $(ONENAND_BIN) $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
 
 mmc_spl:	$(TIMESTAMP_FILE) $(VERSION_FILE) depend
-		$(MAKE) -C mmc_spl/board/$(BOARDDIR) all
+		$(Q)$(MAKE) -C mmc_spl/board/$(BOARDDIR) all
 
 $(obj)mmc_spl/u-boot-mmc-spl.bin:	mmc_spl
 
@@ -470,6 +489,7 @@
 TAG_SUBDIRS = $(SUBDIRS)
 TAG_SUBDIRS += $(dir $(__LIBS))
 TAG_SUBDIRS += include
+TAG_SUBDIRS += sldr
 
 tags ctags:
 		ctags -w -o $(obj)ctags `find $(TAG_SUBDIRS) \
@@ -479,7 +499,7 @@
 		etags -a -o $(obj)etags `find $(TAG_SUBDIRS) \
 						-name '*.[chS]' -print`
 cscope:
-		find $(TAG_SUBDIRS) -name '*.[chS]' -print > cscope.files
+		find $(TAG_SUBDIRS) -name '*.[chS]' -print | uniq > cscope.files
 		cscope -b -q -k
 
 SYSTEM_MAP = \
@@ -536,16 +556,17 @@
 endif	# config.mk
 
 $(VERSION_FILE):
-		@( localvers='$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ; \
+		@( \
 		   printf '#define PLAIN_VERSION "%s%s"\n' \
-			"$(U_BOOT_VERSION)" "$${localvers}" ; \
-		   printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' \
-			"$(U_BOOT_VERSION)" "$${localvers}" ; \
+			"$(U_BOOT_VERSION)" "${localvers}" ; \
+		   printf '#define U_BOOT_VERSION "$(CUSTOMER_NAME) $(CNC_PLATFORM_NAME) U-Boot %s%s"\n' \
+			"$(U_BOOT_VERSION)" "${localvers}" ; \
 		) > $@.tmp
 		@( printf '#define CC_VERSION_STRING "%s"\n' \
 		 '$(shell $(CC) --version | head -n 1)' )>>  $@.tmp
 		@( printf '#define LD_VERSION_STRING "%s"\n' \
 		 '$(shell $(LD) -v | head -n 1)' )>>  $@.tmp
+		@( printf '#define TARGET_CONFIGURATION_NAME $(CONFIG_TARGET_NAME)' )>>  $@.tmp
 		@cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@
 
 easylogo env gdb:
@@ -1104,7 +1125,7 @@
 		| xargs rm -f
 
 clobber:	clean
-	@find $(OBJTREE) -type f \( -name '*.depend' \
+	@find $(OBJTREE) -type f \( -name '.depend' -o -name '*.depend' \
 		-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
 		-print0 \
 		| xargs -0 rm -f
@@ -1127,7 +1148,7 @@
 else
 mrproper \
 distclean:	clobber unconfig
-	rm -rf $(obj)*
+	$(Q)rm -rf $(obj)*
 endif
 
 backup:
@@ -1135,3 +1156,25 @@
 	gtar --force-local -zcvf `LC_ALL=C date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
 
 #########################################################################
+
+chk_cnc_env:
+#check CNC_PLATFORM, and CUSTOMER_NAME are defined?
+ifndef CNC_PLATFORM
+    $(error ERROR: CNC_PLATFORM is not defined, To build image, please export/specify CNC_PLATFORM)
+endif
+ifndef CUSTOMER_NAME
+    $(error ERROR: CUSTOMER_NAME is not defined, To build image, please export/specify CUSTOMER_NAME)
+endif
+	$(Q)test -s $(KERNEL_PEM_KEY_2_C_FILE_NAME) || \
+	{ echo "$(KERNEL_PEM_KEY_2_C_FILE_NAME) file does not exist! Exiting..."; \
+	  echo "Please create $(KERNEL_PEM_KEY_2_C_FILE_NAME) please contact vendor"; \
+	  false; }
+	$(Q)test -s $(BLOB_PEM_KEY_2_C_FILE_NAME) || \
+	{ echo "$(BLOB_PEM_KEY_2_C_FILE_NAME) file does not exist! Exiting..."; \
+	  echo "Please create $(BLOB_PEM_KEY_2_C_FILE_NAME) please contact vendor"; \
+	  false; }
+	$(Q)echo "Copying User defined public key files for kernel and blob"
+	$(Q)cp $(KERNEL_PEM_KEY_2_C_FILE_NAME) common/pkey.c
+	$(Q)cp $(BLOB_PEM_KEY_2_C_FILE_NAME)   common/blob_pkey.c
+
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/net/eth.c u-boot-2011.06/net/eth.c
--- u-boot-2011.06_original/net/eth.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/net/eth.c	2014-07-29 17:28:38.819972000 +0800
@@ -27,6 +27,8 @@
 #include <miiphy.h>
 #include <phy.h>
 
+extern int cn100_eth_readmac(bd_t *bd);
+
 void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
 {
 	char *end;
@@ -206,6 +208,36 @@
 	return 0;
 }
 
+int eth_unregister(struct eth_device *dev)
+{
+	struct eth_device *cur;
+
+	/* No device */
+	if (!eth_devices)
+		return -1;
+
+	for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
+	     cur = cur->next)
+		;
+
+	/* Device not found */
+	if (cur->next != dev)
+		return -1;
+
+	cur->next = dev->next;
+
+	if (eth_devices == dev)
+		eth_devices = dev->next == eth_devices ? NULL : dev->next;
+
+	if (eth_current == dev) {
+		eth_current = eth_devices;
+		eth_current_changed();
+	}
+
+	return 0;
+}
+
+
 int eth_initialize(bd_t *bis)
 {
 	unsigned char env_enetaddr[6];
@@ -519,7 +551,7 @@
 
 #else /* !CONFIG_NET_MULTI */
 
-#warning Ethernet driver is deprecated.  Please update to use CONFIG_NET_MULTI
+//#warning Ethernet driver is deprecated.  Please update to use CONFIG_NET_MULTI
 
 extern int at91rm9200_miiphy_initialize(bd_t *bis);
 extern int mcf52x2_miiphy_initialize(bd_t *bis);
@@ -541,6 +573,9 @@
 #if defined(CONFIG_DRIVER_NS7520_ETHERNET)
 	ns7520_miiphy_initialize(bis);
 #endif
+#if defined(CONFIG_DRIVER_CN100)
+    cn100_eth_readmac(bis);
+#endif
 	return 0;
 }
 #endif
diff '--exclude=.svn' -Naur u-boot-2011.06_original/net/nfs.c u-boot-2011.06/net/nfs.c
--- u-boot-2011.06_original/net/nfs.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/net/nfs.c	2014-07-29 17:28:38.819972000 +0800
@@ -61,6 +61,10 @@
 static char *nfs_path;
 static char nfs_path_buff[2048];
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+extern int check_write_to_code_area (unsigned long addr, unsigned long size);
+#endif
+
 static __inline__ int
 store_block (uchar * src, unsigned offset, unsigned len)
 {
@@ -85,6 +89,10 @@
 	} else
 #endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
 	{
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+		if (check_write_to_code_area ((unsigned long) (load_addr + offset), len))
+			return -1;
+#endif
 		(void)memcpy ((void *)(load_addr + offset), src, len);
 	}
 
diff '--exclude=.svn' -Naur u-boot-2011.06_original/net/tftp.c u-boot-2011.06/net/tftp.c
--- u-boot-2011.06_original/net/tftp.c	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/net/tftp.c	2014-07-29 17:28:38.819972000 +0800
@@ -150,6 +150,10 @@
 
 #endif	/* CONFIG_MCAST_TFTP */
 
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+extern int check_write_to_code_area (unsigned long addr, unsigned long size);
+#endif
+
 static __inline__ void
 store_block(unsigned block, uchar *src, unsigned len)
 {
@@ -179,6 +183,12 @@
 	else
 #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
 	{
+#ifdef CONFIG_CMD_SEC1900_MEM_PROTECT
+		if (check_write_to_code_area ((unsigned long) (load_addr + offset), len)) {
+			NetState = NETLOOP_FAIL;
+			return;
+		}
+#endif
 		(void)memcpy((void *)(load_addr + offset), src, len);
 	}
 #ifdef CONFIG_MCAST_TFTP
diff '--exclude=.svn' -Naur u-boot-2011.06_original/onenand_ipl/board/apollon/low_levelinit.S u-boot-2011.06/onenand_ipl/board/apollon/low_levelinit.S
--- u-boot-2011.06_original/onenand_ipl/board/apollon/low_levelinit.S	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/onenand_ipl/board/apollon/low_levelinit.S	1970-01-01 08:00:00.000000000 +0800
@@ -1,205 +0,0 @@
-/*
- * Board specific setup info
- *
- * (C) Copyright 2005-2008 Samsung Electronics
- * Kyungmin Park <kyungmin.park@samsung.com>
- *
- * Derived from board/omap2420h4/platform.S
- *
- * 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 <config.h>
-#include <asm/arch/omap2420.h>
-#include <asm/arch/mem.h>
-#include <asm/arch/clocks.h>
-
-#define APOLLON_CS0_BASE	0x00000000
-
-#ifdef PRCM_CONFIG_I
-#define SDRC_ACTIM_CTRLA_0_VAL	0x7BA35907
-#define SDRC_ACTIM_CTRLB_0_VAL	0x00000013
-#define SDRC_RFR_CTRL_0_VAL	0x00044C01
-
-/* GPMC */
-#define APOLLON_GPMC_CONFIG1_0	0xe30d1201
-#define APOLLON_GPMC_CONFIG2_0	0x000c1000
-#define APOLLON_GPMC_CONFIG3_0	0x00030400
-#define APOLLON_GPMC_CONFIG4_0	0x0B841006
-#define APOLLON_GPMC_CONFIG5_0	0x020F0C11
-#define APOLLON_GPMC_CONFIG6_0	0x00000000
-#define APOLLON_GPMC_CONFIG7_0	(0x00000e40 | (APOLLON_CS0_BASE >> 24))
-
-#elif defined(PRCM_CONFIG_II)
-#define SDRC_ACTIM_CTRLA_0_VAL	0x4A59B485
-#define SDRC_ACTIM_CTRLB_0_VAL	0x0000000C
-#define SDRC_RFR_CTRL_0_VAL	0x00030001
-
-/* GPMC */
-#define APOLLON_GPMC_CONFIG1_0	0xe30d1201
-#define APOLLON_GPMC_CONFIG2_0	0x00080E81
-#define APOLLON_GPMC_CONFIG3_0	0x00030400
-#define APOLLON_GPMC_CONFIG4_0	0x08041586
-#define APOLLON_GPMC_CONFIG5_0	0x020C090E
-#define APOLLON_GPMC_CONFIG6_0	0x00000000
-#define APOLLON_GPMC_CONFIG7_0	(0x00000e40 | (APOLLON_CS0_BASE >> 24))
-
-#else
-#error "Please configure PRCM schecm"
-#endif
-
-_TEXT_BASE:
-	.word	CONFIG_SYS_TEXT_BASE	/* sdram load addr from config.mk */
-
-.globl lowlevel_init
-lowlevel_init:
-	mov r3, r0     /* save skip information */
-
-	/* Disable watchdog */
-	ldr	r0, =WD2_BASE
-	ldr	r1, =WD_UNLOCK1
-	str	r1, [r0, #WSPR]
-
-	ldr	r1, =WD_UNLOCK2
-	str	r1, [r0, #WSPR]
-
-#ifdef DEBUG_LED
-	/* LED0 OFF */
-	ldr	r0, =0x480000E5		/* ball AA10, mode 3 */
-	mov	r1, #0x0b
-	strb	r1, [r0]
-#endif
-
-	/* Pin muxing for SDRC */
-	mov	r1, #0x00
-	ldr	r0, =0x480000A1		/* ball C12, mode 0 */
-	strb	r1, [r0]
-
-	ldr	r0, =0x48000032		/* ball D11, mode 0 */
-	strb	r1, [r0]
-
-	ldr	r0, =0x480000A3		/* ball B13, mode 0 */
-	strb	r1, [r0]
-
-	/* SDRC setting */
-	ldr	r0, =OMAP2420_SDRC_BASE
-	ldr	r1, =0x00000010
-	str	r1, [r0, #0x10]
-
-	ldr	r1, =0x00000100
-	str	r1, [r0, #0x44]
-
-	/* SDRC CS0 configuration */
-#ifdef CONFIG_APOLLON_PLUS
-	ldr	r1, =0x01702011
-#else
-	ldr	r1, =0x00d04011
-#endif
-	str	r1, [r0, #0x80]
-
-	ldr	r1, =SDRC_ACTIM_CTRLA_0_VAL
-	str	r1, [r0, #0x9C]
-
-	ldr	r1, =SDRC_ACTIM_CTRLB_0_VAL
-	str	r1, [r0, #0xA0]
-
-	ldr	r1, =SDRC_RFR_CTRL_0_VAL
-	str	r1, [r0, #0xA4]
-
-	ldr	r1, =0x00000041
-	str	r1, [r0, #0x70]
-
-	/* Manual command sequence */
-	ldr	r1, =0x00000007
-	str	r1, [r0, #0xA8]
-
-	ldr	r1, =0x00000000
-	str	r1, [r0, #0xA8]
-
-	ldr	r1, =0x00000001
-	str	r1, [r0, #0xA8]
-
-	ldr	r1, =0x00000002
-	str	r1, [r0, #0xA8]
-	str	r1, [r0, #0xA8]
-
-	/*
-	 * CS0 SDRC Mode register
-	 *   Burst length = 4 - DDR memory
-	 *   Serial mode
-	 *   CAS latency = 3
-	 */
-	ldr	r1, =0x00000032
-	str	r1, [r0, #0x84]
-
-	/* Note: You MUST set EMR values */
-	/* EMR1 & EMR2 */
-	ldr	r1, =0x00000000
-	str	r1, [r0, #0x88]
-	str	r1, [r0, #0x8C]
-
-#ifdef OLD_SDRC_DLLA_CTRL
-	/* SDRC_DLLA_CTRL */
-	ldr	r1, =0x00007306
-	str	r1, [r0, #0x60]
-
-	ldr	r1, =0x00007303
-	str	r1, [r0, #0x60]
-#else
-	/* SDRC_DLLA_CTRL */
-	ldr	r1, =0x00000506
-	str	r1, [r0, #0x60]
-
-	ldr	r1, =0x00000503
-	str	r1, [r0, #0x60]
-#endif
-
-#ifdef __BROKEN_FEATURE__
-	/* SDRC_DLLB_CTRL */
-	ldr	r1, =0x00000506
-	str	r1, [r0, #0x68]
-
-	ldr	r1, =0x00000503
-	str	r1, [r0, #0x68]
-#endif
-
-	/* little delay after init */
-	mov	r2, #0x1800
-1:
-	subs	r2, r2, #0x1
-	bne	1b
-
-	ldr	sp, SRAM_STACK
-	str	ip, [sp]	/* stash old link register */
-	mov	ip, lr		/* save link reg across call */
-	mov	r0, r3		/* pass skip info to s_init */
-
-	bl	s_init		/* go setup pll,mux,memory */
-
-	ldr	ip, [sp]	/* restore save ip */
-	mov	lr, ip		/* restore link reg */
-
-	/* back to arch calling code */
-	mov	pc,	lr
-
-	/* the literal pools origin */
-	.ltorg
-
-SRAM_STACK:
-	.word LOW_LEVEL_SRAM_STACK
diff '--exclude=.svn' -Naur u-boot-2011.06_original/tools/env/Makefile u-boot-2011.06/tools/env/Makefile
--- u-boot-2011.06_original/tools/env/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/tools/env/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -40,7 +40,7 @@
 
 # Some files complain if compiled with -pedantic, use HOSTCFLAGS_NOPED
 $(obj)fw_printenv:	$(HOSTSRCS) $(HEADERS)
-	$(HOSTCC) $(HOSTCFLAGS_NOPED) $(HOSTLDFLAGS) -o $@ $(HOSTSRCS)
+	 arm-linux-gnueabihf-gcc $(HOSTCFLAGS_NOPED) $(HOSTLDFLAGS) -o $@ $(HOSTSRCS)
 
 clean:
 	rm -f $(obj)fw_printenv $(obj)crc32.c
diff '--exclude=.svn' -Naur u-boot-2011.06_original/tools/Makefile u-boot-2011.06/tools/Makefile
--- u-boot-2011.06_original/tools/Makefile	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/tools/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -67,6 +67,7 @@
 BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
 BIN_FILES-$(CONFIG_INCA_IP) += inca-swap-bytes$(SFX)
 BIN_FILES-y += mkimage$(SFX)
+BIN_FILES-y += mkenvimage$(SFX)
 BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
 BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
 
@@ -89,6 +90,7 @@
 NOPED_OBJ_FILES-y += kwbimage.o
 NOPED_OBJ_FILES-y += imximage.o
 NOPED_OBJ_FILES-y += mkimage.o
+NOPED_OBJ_FILES-y += mkenvimage.o
 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
 NOPED_OBJ_FILES-y += os_support.o
 OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
@@ -157,27 +159,27 @@
 all:	$(obj).depend $(BINS) $(LOGO-y) subdirs
 
 $(obj)bin2header$(SFX): $(obj)bin2header.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)bmp_logo$(SFX):	$(obj)bmp_logo.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)envcrc$(SFX):	$(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 
 $(obj)gen_eth_addr$(SFX):	$(obj)gen_eth_addr.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)img2srec$(SFX):	$(obj)img2srec.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)inca-swap-bytes$(SFX):	$(obj)inca-swap-bytes.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)mkimage$(SFX):	$(obj)crc32.o \
 			$(obj)default_image.o \
@@ -190,29 +192,35 @@
 			$(obj)os_support.o \
 			$(obj)sha1.o \
 			$(LIBFDT_OBJS)
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
+	
+$(obj)mkenvimage$(SFX): $(obj)crc32.o \
+			$(obj)mkenvimage.o \
+			$(LIBFDT_OBJS)
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)mpc86x_clk$(SFX):	$(obj)mpc86x_clk.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)ncb$(SFX):	$(obj)ncb.o
-	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
-	$(HOSTSTRIP) $@
+	$(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(Q)$(HOSTSTRIP) $@
 
 $(obj)ubsha1$(SFX):	$(obj)os_support.o $(obj)sha1.o $(obj)ubsha1.o
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 
 # Some of the tool objects need to be accessed from outside the tools directory
 $(obj)%.o: $(SRCTREE)/common/%.c
-	$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
+	$(Q)$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
 
 $(obj)%.o: $(SRCTREE)/lib/%.c
-	$(HOSTCC) -g $(HOSTCFLAGS) -c -o $@ $<
+	$(Q)$(HOSTCC) -g $(HOSTCFLAGS) -c -o $@ $<
 
 $(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
-	$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
+	$(Q)$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
 
 subdirs:
 ifeq ($(TOOLSUBDIRS),)
diff '--exclude=.svn' -Naur u-boot-2011.06_original/tools/mkenvimage.c u-boot-2011.06/tools/mkenvimage.c
--- u-boot-2011.06_original/tools/mkenvimage.c	1970-01-01 08:00:00.000000000 +0800
+++ u-boot-2011.06/tools/mkenvimage.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,314 @@
+/*
+ * (C) Copyright 2011 Free Electrons
+ * David Wagner <david.wagner@free-electrons.com>
+ *
+ * Inspired from envcrc.c:
+ * (C) Copyright 2001
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ *
+ * 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
+ */
+
+/* We want the GNU version of basename() */
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "compiler.h"
+#include <u-boot/crc.h>
+#include <version.h>
+
+#define CRC_SIZE sizeof(uint32_t)
+
+static void usage(const char *exec_name)
+{
+        fprintf(stderr, "%s [-h] [-r] [-b] [-p <byte>] -s <environment partition size> -o <output> <input file>\n"
+               "\n"
+               "This tool takes a key=value input file (same as would a `printenv' show) and generates the corresponding environment image, ready to be flashed.\n"
+               "\n"
+               "\tThe input file is in format:\n"
+               "\t\tkey1=value1\n"
+               "\t\tkey2=value2\n"
+               "\t\t...\n"
+               "\t-r : the environment has multiple copies in flash\n"
+               "\t-b : the target is big endian (default is little endian)\n"
+               "\t-p <byte> : fill the image with <byte> bytes instead of 0xff bytes\n"
+               "\t-V : print version information and exit\n"
+               "\n"
+               "If the input file is \"-\", data is read from standard input\n",
+               exec_name);
+}
+
+long int xstrtol(const char *s)
+{
+        long int tmp;
+
+        errno = 0;
+        tmp = strtol(s, NULL, 0);
+        if (!errno)
+                return tmp;
+
+        if (errno == ERANGE)
+                fprintf(stderr, "Bad integer format: %s\n",  s);
+        else
+                fprintf(stderr, "Error while parsing %s: %s\n", s,
+                                strerror(errno));
+
+        exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+        uint32_t crc, targetendian_crc;
+        const char *txt_filename = NULL, *bin_filename = NULL;
+        int txt_fd, bin_fd;
+        unsigned char *dataptr, *envptr;
+        unsigned char *filebuf = NULL;
+        unsigned int filesize = 0, envsize = 0, datasize = 0;
+        int bigendian = 0;
+        int redundant = 0;
+        unsigned char padbyte = 0xff;
+
+        int option;
+        int ret = EXIT_SUCCESS;
+
+        struct stat txt_file_stat;
+
+        int fp, ep;
+        const char *prg;
+
+        prg = basename(argv[0]);
+
+        /* Turn off getopt()'s internal error message */
+        opterr = 0;
+
+        /* Parse the cmdline */
+        while ((option = getopt(argc, argv, ":s:o:rbp:hV")) != -1) {
+                switch (option) {
+                case 's':
+                        datasize = xstrtol(optarg);
+                        break;
+                case 'o':
+                        bin_filename = strdup(optarg);
+                        if (!bin_filename) {
+                                fprintf(stderr, "Can't strdup() the output filename\n");
+                                return EXIT_FAILURE;
+                        }
+                        break;
+                case 'r':
+                        redundant = 1;
+                        break;
+                case 'b':
+                        bigendian = 1;
+                        break;
+                case 'p':
+                        padbyte = xstrtol(optarg);
+                        break;
+                case 'h':
+                        usage(prg);
+                        return EXIT_SUCCESS;
+                case 'V':
+                        printf("%s version %s\n", prg, PLAIN_VERSION);
+                        return EXIT_SUCCESS;
+                case ':':
+                        fprintf(stderr, "Missing argument for option -%c\n",
+                                optopt);
+                        usage(prg);
+                        return EXIT_FAILURE;
+                default:
+                        fprintf(stderr, "Wrong option -%c\n", optopt);
+                        usage(prg);
+                        return EXIT_FAILURE;
+                }
+        }
+
+        /* Check datasize and allocate the data */
+        if (datasize == 0) {
+                fprintf(stderr, "Please specify the size of the environment partition.\n");
+                usage(prg);
+                return EXIT_FAILURE;
+        }
+
+        dataptr = malloc(datasize * sizeof(*dataptr));
+        if (!dataptr) {
+                fprintf(stderr, "Can't alloc %d bytes for dataptr.\n",
+                                datasize);
+                return EXIT_FAILURE;
+        }
+
+        /*
+         * envptr points to the beginning of the actual environment (after the
+         * crc and possible `redundant' byte
+         */
+        envsize = datasize - (CRC_SIZE + redundant);
+        envptr = dataptr + CRC_SIZE + redundant;
+
+        /* Pad the environment with the padding byte */
+        memset(envptr, padbyte, envsize);
+
+        /* Open the input file ... */
+        if (optind >= argc || strcmp(argv[optind], "-") == 0) {
+                int readbytes = 0;
+                int readlen = sizeof(*envptr) * 4096;
+                txt_fd = STDIN_FILENO;
+
+                do {
+                        filebuf = realloc(filebuf, readlen);
+                        if (!filebuf) {
+                                fprintf(stderr, "Can't realloc memory for the input file buffer\n");
+                                return EXIT_FAILURE;
+                        }
+                        readbytes = read(txt_fd, filebuf + filesize, readlen);
+                        if (errno) {
+                                fprintf(stderr, "Error while reading stdin: %s\n",
+                                                strerror(errno));
+                                return EXIT_FAILURE;
+                        }
+                        filesize += readbytes;
+                } while (readbytes == readlen);
+
+        } else {
+                txt_filename = argv[optind];
+                txt_fd = open(txt_filename, O_RDONLY);
+                if (txt_fd == -1) {
+                        fprintf(stderr, "Can't open \"%s\": %s\n",
+                                        txt_filename, strerror(errno));
+                        return EXIT_FAILURE;
+                }
+                /* ... and check it */
+                ret = fstat(txt_fd, &txt_file_stat);
+                if (ret == -1) {
+                        fprintf(stderr, "Can't stat() on \"%s\": %s\n",
+                                        txt_filename, strerror(errno));
+                        return EXIT_FAILURE;
+                }
+
+                filesize = txt_file_stat.st_size;
+
+                filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
+                               MAP_PRIVATE, txt_fd, 0);
+                if (filebuf == MAP_FAILED) {
+                        fprintf(stderr, "mmap (%zu bytes) failed: %s\n",
+                                        sizeof(*envptr) * filesize,
+                                        strerror(errno));
+                        fprintf(stderr, "Falling back to read()\n");
+
+                        filebuf = malloc(sizeof(*envptr) * filesize);
+                        ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
+                        if (ret != sizeof(*envptr) * filesize) {
+                                fprintf(stderr, "Can't read the whole input file (%zu bytes): %s\n",
+                                        sizeof(*envptr) * filesize,
+                                        strerror(errno));
+
+                                return EXIT_FAILURE;
+                        }
+                }
+                ret = close(txt_fd);
+        }
+        /* The +1 is for the additionnal ending \0. See below. */
+        if (filesize + 1 > envsize) {
+                fprintf(stderr, "The input file is larger than the environment partition size\n");
+                return EXIT_FAILURE;
+        }
+
+        /* Replace newlines separating variables with \0 */
+        for (fp = 0, ep = 0 ; fp < filesize ; fp++) {
+                if (filebuf[fp] == '\n') {
+                        if (ep == 0) {
+                                /*
+                                 * Newlines at the beginning of the file ?
+                                 * Ignore them.
+                                 */
+                                continue;
+                        } else if (filebuf[fp-1] == '\\') {
+                                /*
+                                 * Embedded newline in a variable.
+                                 *
+                                 * The backslash was added to the envptr; rewind
+                                 * and replace it with a newline
+                                 */
+                                ep--;
+                                envptr[ep++] = '\n';
+                        } else {
+                                /* End of a variable */
+                                envptr[ep++] = '\0';
+                        }
+                } else {
+                        envptr[ep++] = filebuf[fp];
+                }
+        }
+        /*
+         * Make sure there is a final '\0'
+         * And do it again on the next byte to mark the end of the environment.
+         */
+        if (envptr[ep-1] != '\0') {
+                envptr[ep++] = '\0';
+                /*
+                 * The text file doesn't have an ending newline.  We need to
+                 * check the env size again to make sure we have room for two \0
+                 */
+                if (ep >= envsize) {
+                        fprintf(stderr, "The environment file is too large for the target environment storage\n");
+                        return EXIT_FAILURE;
+                }
+                envptr[ep] = '\0';
+        } else {
+                envptr[ep] = '\0';
+        }
+
+        /* Computes the CRC and put it at the beginning of the data */
+        crc = crc32(0, envptr, envsize);
+        targetendian_crc = bigendian ? cpu_to_be32(crc) : cpu_to_le32(crc);
+
+        memcpy(dataptr, &targetendian_crc, sizeof(targetendian_crc));
+        if (redundant)
+                dataptr[sizeof(targetendian_crc)] = 1;
+
+        if (!bin_filename || strcmp(bin_filename, "-") == 0) {
+                bin_fd = STDOUT_FILENO;
+        } else {
+                bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP |
+                                             S_IWGRP);
+                if (bin_fd == -1) {
+                        fprintf(stderr, "Can't open output file \"%s\": %s\n",
+                                        bin_filename, strerror(errno));
+                        return EXIT_FAILURE;
+                }
+        }
+
+        if (write(bin_fd, dataptr, sizeof(*dataptr) * datasize) !=
+                        sizeof(*dataptr) * datasize) {
+                fprintf(stderr, "write() failed: %s\n", strerror(errno));
+                return EXIT_FAILURE;
+        }
+
+        ret = close(bin_fd);
+
+        return ret;
+}
+
diff '--exclude=.svn' -Naur u-boot-2011.06_original/tools/setlocalversion u-boot-2011.06/tools/setlocalversion
--- u-boot-2011.06_original/tools/setlocalversion	2011-06-28 04:22:42.000000000 +0800
+++ u-boot-2011.06/tools/setlocalversion	2014-07-29 17:28:38.819972000 +0800
@@ -32,7 +32,8 @@
 
 # Check for svn and a svn repo.
 if rev=`svn info 2>/dev/null` ; then
-	rev=`echo "${rev}" | grep '^Revision' | awk '{print $NF}'`
+	#rev=`echo "${rev}" | grep '^Revision' | awk '{print $NF}'`
+	rev=`svnversion -n`
 	printf -- '-svn%s' $rev
 fi
 
