Merge remote-tracking branch 'gfiber-internal/vendor_drops'

Merge Marvell patches-u-boot-2013.01-2015_T1.0p16 patchset.

Change-Id: Ice925c8accb490118d501a47f02651275deaf20c
diff --git a/.gitignore b/.gitignore
index c4607ee..b10e919 100755
--- a/.gitignore
+++ b/.gitignore
@@ -83,3 +83,7 @@
 
 # spl ais files
 /spl/*.ais
+
+# build output
+/output
+output.*.tar
diff --git a/Makefile.gfiber b/Makefile.gfiber
new file mode 100644
index 0000000..583ea3c
--- /dev/null
+++ b/Makefile.gfiber
@@ -0,0 +1,79 @@
+#
+# Google makefile to build uboot for armada products
+#
+
+export CROSS_COMPILE_BH=$(PWD)/../../toolchains/armada/bin/arm-marvell-linux-uclibcgnueabi-
+export CROSS_COMPILE=$(PWD)/../../toolchains/armada/bin/arm-marvell-linux-uclibcgnueabi-
+
+version = $(shell ./version)
+
+LOADERBIN_GFCH100 = ../../loader-bin/marvell/gfch100
+
+GFCH100 = gfch100-dev gfch100-prod gfch100-openbox
+UART1 = gfch100_uart1
+MARVELL = marvell-spi marvell-nand
+
+MV_BOARD = armada_38x
+GF_BOARD = armada_38x_gfch100
+
+all:		clean $(GFCH100) extract
+uart1:		clean $(UART1) extract
+marvell:	clean $(MARVELL) extract
+
+# don't run parallel, the several builds would mix .o files
+.NOTPARALLEL:
+
+clean:
+	make clean
+	rm -rf output.*
+
+clobber: clean
+	-make distclean
+	rm -rf output
+
+extract:
+	rm -rf output
+	for n in output.*.tar; do tar xf $$n; done
+
+gfiber_private.pem:
+	@echo "$@ is required to sign binaries. Get a copy and put it next to Makefile.gfiber"
+	exit 1
+
+#
+# GENERATE_DIGEST(DIR, NAME)
+#
+define GENERATE_DIGEST
+	@echo "Generating digest for $(1)/$(2)"
+	openssl dgst -sign gfiber_private.pem -sha512 -binary -keyform \
+		PEM $(1)/$(2).bin > $(1)/$(2).sig
+endef
+
+install: gfiber_private.pem
+	# TODO(cgibson): Add signing support.
+	mkdir -p $(LOADERBIN_GFCH100)
+	cp output/gfch100-dev/le/spi/*dev-spi.bin $(LOADERBIN_GFCH100)/u-boot-spi-dev.bin
+	cp output/gfch100-dev/le/spi/*dev-spi-uart.bin $(LOADERBIN_GFCH100)/u-boot-spi-uart-dev.bin
+	cp output/gfch100-prod/le/spi/*prod-spi.bin $(LOADERBIN_GFCH100)/u-boot-spi-prod.bin
+	cp output/gfch100-openbox/le/spi/*openbox-spi.bin $(LOADERBIN_GFCH100)/u-boot-spi-openbox.bin
+	$(call GENERATE_DIGEST,$(LOADERBIN_GFCH100),u-boot-spi-dev)
+	$(call GENERATE_DIGEST,$(LOADERBIN_GFCH100),u-boot-spi-uart-dev)
+	$(call GENERATE_DIGEST,$(LOADERBIN_GFCH100),u-boot-spi-prod)
+	$(call GENERATE_DIGEST,$(LOADERBIN_GFCH100),u-boot-spi-openbox)
+
+#
+# BUILDPL(NAME, BOARD, BOOT, ARGS)
+#
+define BUILDPL
+	rm -rf output
+	./build.pl -b $(2) -f $(3) -v $(1)-$(version)-$(5) -i nand:spi -c -o output/$(1) $(4) -s $(5)
+	tar cf output.$(1).tar output
+endef
+
+marvell-%:
+	$(call BUILDPL,$@,$(MV_BOARD),$*,-i nand:spi,dev)
+
+gfch100-%:
+	$(call BUILDPL,$@,$(GF_BOARD),spi,-i spi,$*)
+
+gfch100_uart1:
+	$(call BUILDPL,$@,$(GF_BOARD),spi,-i spi -u 1,dev)
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c
index eb6f5bf..766ec4d 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c
@@ -74,6 +74,10 @@
 #include "pci/mvPci.h"
 #include "device/mvDevice.h"
 
+#ifdef CONFIG_GFCH100
+#include "eth-phy/mvEthPhy.h"
+#endif
+
 #if defined(CONFIG_MV_ETH_NETA)
 #include "neta/gbe/mvEthRegs.h"
 #elif defined(CONFIG_MV_ETH_PP2)
@@ -197,6 +201,20 @@
 	mvGppTypeSet(1, 0xFFFFFFFF, board->gppOutEnValMid);
 	mvGppTypeSet(2, 0xFFFFFFFF, board->gppOutEnValHigh);
 
+#ifdef CONFIG_GFCH100
+	/* show SAR register */
+	mvOsPrintf("SAR: 0x%08x\n", MV_REG_READ(MPP_SAMPLE_AT_RESET));
+
+	/* take PHYs & MMC out of reset */
+	udelay(1000);
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(0), BIT12);	// PCIe0_RESET_n
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(0), BIT17);	// 88E1322_RST_L
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(0), BIT20);	// MCU_RST#
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(0), BIT29);	// 88x3220_RST_n
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), BIT0);	// 88x2011_RST_n
+	MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), BIT15);	// SD_RST_n
+#endif
+
 	/* Call callback function for board specific post GPP configuration */
 	if (board->gppPostConfigCallBack)
 		board->gppPostConfigCallBack(board);
@@ -2224,6 +2242,8 @@
 		gBoardId = CUSTOMER_BOARD_ID1;
 	#elif CONFIG_CLEARFOG_BOARD
 		gBoardId = A38X_CLEARFOG_BOARD_ID;
+	#elif CONFIG_GFCH100
+		gBoardId = GFCH100_ID;
 	#endif
 #else /* !CONFIG_CUSTOMER_BOARD_SUPPORT */
 	/* Temporarily set generic board struct pointer, to set/get EEPROM i2c address, and read board ID */
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h
index 86983ee..a6920a5 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h
@@ -84,7 +84,8 @@
 #define A38X_CUSTOMER_BOARD_ID0			(A38X_CUTOMER_BOARD_ID_BASE + 0)
 #define A38X_CUSTOMER_BOARD_ID1			(A38X_CUTOMER_BOARD_ID_BASE + 1)
 #define A38X_CLEARFOG_BOARD_ID			(A38X_CUTOMER_BOARD_ID_BASE + 2)
-#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUTOMER_BOARD_ID_BASE + 3)
+#define A38X_GFCH100_ID				(A38X_CUTOMER_BOARD_ID_BASE + 3)
+#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUTOMER_BOARD_ID_BASE + 4)
 #define A38X_MV_CUSTOMER_BOARD_NUM		(A38X_MV_MAX_CUSTOMER_BOARD_ID - A38X_CUTOMER_BOARD_ID_BASE)
 
 /* Armada-38x Marvell boards */
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c
index 97f0587..a5e1e4d 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c
@@ -523,13 +523,128 @@
 	.switchInfoNum				= ARRSZ(armada_38x_clearfog_InfoSwitchInfo)
 };
 
+/*******************************************************************************
+ * A38x GFCH100
+ *******************************************************************************/
+#define A38x_GFCH100_NAND_READ_PARAMS		0x000C0282
+#define A38x_GFCH100_NAND_WRITE_PARAMS		0x00010305
+/*NAND care support for small page chips*/
+#define A38x_GFCH100_NAND_CONTROL		0x01c00543
+
+#define A38x_GFCH100_NOR_READ_PARAMS		0x403E07CF
+#define A38x_GFCH100_NOR_WRITE_PARAMS		0x000F0F0F
+
+MV_BOARD_MAC_INFO armada_38x_gfch100_BoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_1000M, -1, -1, MV_TRUE},	/* switch, no phy, no addr */
+	{ BOARD_MAC_SPEED_AUTO, 0x3, 0x0, MV_TRUE},	/* craft, phy port 3, no addr */
+};
+
+MV_DEV_CS_INFO armada_38x_gfch100_BoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
+	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_TRUE },	/* SPI0 DEV */
+};
+
+MV_BOARD_MPP_INFO armada_38x_gfch100_BoardMppConfigValue[] = {
+	{ {
+		A38x_GFCH100_MPP0_7,
+		A38x_GFCH100_MPP8_15,
+		A38x_GFCH100_MPP16_23,
+		A38x_GFCH100_MPP24_31,
+		A38x_GFCH100_MPP32_39,
+		A38x_GFCH100_MPP40_47,
+		A38x_GFCH100_MPP48_55,
+		A38x_GFCH100_MPP56_63,
+	} }
+};
+
+struct MV_BOARD_IO_EXPANDER armada_38x_gfch100_IoExpanderInfo[] = {
+	{0, 6, 0xF4}, /* Configuration registers: Bit on --> Input bits  */
+	{0, 7, 0xC3}, /* Configuration registers: Bit on --> Input bits  */
+	{0, 2, 0x0B}, /* Output Data, register#0 */
+	{0, 3, 0x18}, /* Output Data, register#1 */
+	{1, 6, 0xE7}, /* Configuration registers: Bit on --> Input bits  */
+	{1, 7, 0xF9}, /* Configuration registers: Bit on --> Input bits  */
+	{1, 2, 0x08}, /* Output Data, register#0 */
+	{1, 3, 0x00}  /* Output Data, register#1 */
+};
+
+MV_BOARD_USB_INFO armada_38x_gfch100_UsbInfo[] = {
+/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
+	{ USB_UNIT_ID,  0, MV_TRUE},
+	{ USB_UNIT_ID,  1, MV_TRUE},
+};
+
+MV_BOARD_INFO armada_38x_gfch100_info = {
+	.boardName			= "A38x-gfch100",
+	.numBoardNetComplexValue	= 0,
+	.pBoardNetComplexInfo		= NULL,
+	.pBoardMppConfigValue		= armada_38x_gfch100_BoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(armada_38x_gfch100_BoardDeCsInfo),
+	.pDevCsInfo				= armada_38x_gfch100_BoardDeCsInfo,
+	.numBoardTwsiDev		= 0,
+	.pBoardTwsiDev			= NULL,
+	.numBoardMacInfo		= ARRSZ(armada_38x_gfch100_BoardMacInfo),
+	.pBoardMacInfo			= armada_38x_gfch100_BoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= 0,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* PMU Power */
+	.pmuPwrUpPolarity		= 0,
+	.pmuPwrUpDelay			= 80000,
+
+	/* GPP values */
+	.gppOutEnValLow			= A38x_GFCH100_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= A38x_GFCH100_GPP_OUT_ENA_MID,
+	.gppOutValLow			= A38x_GFCH100_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= A38x_GFCH100_GPP_OUT_VAL_MID,
+	.gppPolarityValLow		= A38x_GFCH100_GPP_POL_LOW,
+	.gppPolarityValMid		= A38x_GFCH100_GPP_POL_MID,
+
+	/* TDM */
+	.numBoardTdmInfo		= {},
+	.pBoardTdmInt2CsInfo		= {},
+	.boardTdmInfoIndex		= -1,
+
+	.pBoardSpecInit			= NULL,
+
+	/* USB */
+	.numBoardUsbInfo		= ARRSZ(armada_38x_gfch100_UsbInfo),
+	.pBoardUsbInfo			= armada_38x_gfch100_UsbInfo,
+
+	/* NAND init params */
+	.nandFlashReadParams		= A38x_GFCH100_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= A38x_GFCH100_NAND_WRITE_PARAMS,
+	.nandFlashControl		= A38x_GFCH100_NAND_CONTROL,
+	.nandIfMode			= NAND_IF_NFC,
+
+	.isSdMmcConnected		= MV_TRUE,
+
+	/* NOR init params */
+	.norFlashReadParams		= A38x_GFCH100_NOR_READ_PARAMS,
+	.norFlashWriteParams		= A38x_GFCH100_NOR_WRITE_PARAMS,
+	/* Enable modules auto-detection. */
+	.configAutoDetect		= MV_FALSE,
+	.numIoExp			= ARRSZ(armada_38x_gfch100_IoExpanderInfo),
+	.pIoExp				= armada_38x_gfch100_IoExpanderInfo,
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+};
+
 /*
  * All supported A380 customer boards
  */
 MV_BOARD_INFO *customerBoardInfoTbl[] = {
 	&armada_38x_customer_board_0_info,
 	&armada_38x_customer_board_1_info,
-	&armada_38x_clearfog_board_info
+	&armada_38x_clearfog_board_info,
+	&armada_38x_gfch100_info,
 };
 
 
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h
index 45bab59..eeb5868 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h
@@ -66,6 +66,7 @@
 #define CUTOMER_BOARD_ID_BASE                   A38X_CUTOMER_BOARD_ID_BASE
 #define CUSTOMER_BOARD_ID0			A38X_CUSTOMER_BOARD_ID0
 #define CUSTOMER_BOARD_ID1			A38X_CUSTOMER_BOARD_ID1
+#define GFCH100_ID				A38X_GFCH100_ID
 #define MV_MAX_CUSTOMER_BOARD_ID                A38X_MV_MAX_CUSTOMER_BOARD_ID
 #define MV_CUSTOMER_BOARD_NUM                   A38X_MV_CUSTOMER_BOARD_NUM
 
@@ -141,6 +142,26 @@
 #define A38x_CLEARFOG_BOARD_GPP_POL_LOW		0x0
 #define A38x_CLEARFOG_BOARD_GPP_POL_MID		0x0
 
+/*******************************************************************************
+ * A38x GFCH100
+ *******************************************************************************/
+/* see 88F6810_MPP_information.xls */
+/* see https://goto.google.com/chimerampp */
+#define A38x_GFCH100_MPP0_7		0x00111111
+#define A38x_GFCH100_MPP8_15		0x00000000
+#define A38x_GFCH100_MPP16_23		0x11100000
+#define A38x_GFCH100_MPP24_31		0x00003311
+#define A38x_GFCH100_MPP32_39		0x00000000
+#define A38x_GFCH100_MPP40_47		0x00000110
+#define A38x_GFCH100_MPP48_55		0x55550555
+#define A38x_GFCH100_MPP56_63		0x00005550
+
+#define A38x_GFCH100_GPP_OUT_ENA_LOW	(~(BIT12|BIT17|BIT18|BIT20|BIT29|BIT30|BIT31))	/*0-31*/
+#define A38x_GFCH100_GPP_OUT_ENA_MID	(~(BIT0|BIT6|BIT12|BIT15))			/* 32-59 */
+#define A38x_GFCH100_GPP_OUT_VAL_LOW	(BIT30)						/* 0-31 */
+#define A38x_GFCH100_GPP_OUT_VAL_MID	(BIT12)						/* 32-59 */
+#define A38x_GFCH100_GPP_POL_LOW	0x0
+#define A38x_GFCH100_GPP_POL_MID	0x0
 
 /******************************* Marvell Boards *******************************/
 
diff --git a/board/mv_ebu/a38x/mv_main_a38x.c b/board/mv_ebu/a38x/mv_main_a38x.c
index 0dce7f6..5f5f58c 100755
--- a/board/mv_ebu/a38x/mv_main_a38x.c
+++ b/board/mv_ebu/a38x/mv_main_a38x.c
@@ -355,7 +355,11 @@
 				"pxa3xx_nand-0:8m(boot)ro,8m@8m(kernel),-(rootfs)");
 		setenv("mtdparts_lgcy", getenv("mtdparts"));
 #elif defined(MV_INCLUDE_SPI)
+#ifdef CONFIG_GFCH100
+		setenv("mtdparts", "mtdparts=spi_flash:1m(boot),64k@1m(env),-(reserved)");
+#else
 		setenv("mtdparts", "mtdparts=spi0.0:4m(boot),-(spi-rootfs)");
+#endif
 		setenv("mtdparts_lgcy", "mtdparts=spi_flash:4m(boot),-(spi-rootfs)");
 #endif
 	}
@@ -532,6 +536,19 @@
 	env = getenv("initrd_name");
 	if (!env)
 		setenv("initrd_name", "uInitrd");
+#ifdef CONFIG_GFCH100
+	/* load hnvram */
+	do_hnvram();
+
+	/* where to load initrd.  Default is top of memory @ 0x3fxxxxxx, too high */
+	env = getenv("initrd_high");
+	if (!env)
+		setenv("initrd_high", "20000000");
+	/* debug boot arguments */
+	env = getenv("bootargs_debug");
+	if (!env)
+		setenv("bootargs_debug", "debug=1 login=1 earlyprintk");
+#endif
 
 #ifdef CONFIG_CMD_SOURCE
 	env = getenv("run_script");
@@ -680,6 +697,9 @@
 #endif
 
 	/* Flatten Device Tree environment setup */
+#ifdef CONFIG_GFCH100
+	fdt_env_setup("gfch100.dtb", MV_FALSE);
+#else
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 	#ifdef CONFIG_ARMADA_38X
 		fdt_env_setup("armada-38x.dtb", MV_FALSE); /* static setup: Skip DT update for customer */
@@ -693,14 +713,47 @@
 		fdt_env_setup("armada-39x.dtb", MV_FALSE); /* static setup: Skip DT update */
 	#endif
 #endif
+#endif
+
+#ifdef CONFIG_GFCH100
+	/* use 'run gpt_init' to initialize the GPT table on the eMMC */
+	env = getenv("gpt_init");
+	if (!env) {
+		/* note: no trailing ; on last partition.  gpt write counts semicolons */
+		/* ,,,, is used for readability */
+		setenv("gpt_uu", "00010781-6583-40b2-ba24-3c6463921004");
+		setenv("gpt_p1", "name=hnvram,,,,start=0x00008000,size=0x00200000,uuid=010edf82-9cbc-4dbe-9846-271ef1610186;");
+		setenv("gpt_p2", "name=kernel0,,,start=0x00208000,size=0x01000000,uuid=020bec7c-37fe-4759-b17c-ff18ea44604c;");
+		setenv("gpt_p3", "name=kernel1,,,start=0x01208000,size=0x01000000,uuid=03018a36-3831-4723-a505-106730944b98;");
+		setenv("gpt_p4", "name=rootfs0,,,start=0x02208000,size=0x12000000,uuid=04099b1f-3111-434a-8bff-41390a0f6439;");
+		setenv("gpt_p5", "name=rootfs1,,,start=0x14208000,size=0x12000000,uuid=050a3ab3-f12a-4f59-9888-625f5d3703c4;");
+		setenv("gpt_p6", "name=emergency,start=0x26208000,size=0x02000000,uuid=06019156-6921-44c5-9b42-00e75743f5d4;");
+		setenv("gpt_p7", "name=data+ext4,start=0x28208000,size=-1,,,,,,,,,uuid=0701c4ef-9921-4479-991e-0652069373b7");
+		setenv("gpt_init", "mmc rescan && gpt write mmc 0 \"uuid_disk=$gpt_uu;$gpt_p1$gpt_p2$gpt_p3$gpt_p4$gpt_p5$gpt_p6$gpt_p7\"");
+	}
+#endif
 
 #if (CONFIG_BOOTDELAY >= 0)
 	env = getenv("bootcmd");
 	if (!env)
+#if defined(CONFIG_GFCH100)
+		setenv("gfparams",
+			"if test $HNV_ACTIVATED_KERNEL_NAME = kernel1; "
+			"then gfkernel=0x9048 gfroot=root=rootfs1; "
+			"else gfkernel=0x1048 gfroot=root=rootfs0; fi");
+		setenv("bootcmd",
+			"run gfparams; "
+			"mmc rescan; "
+			"mmc read $loadaddr $gfkernel 0x8000; "
+			"setenv bootargs $console $mtdparts $gfroot $bootargs_extra; "
+			"bootm $loadaddr; "
+		);
+#else
 		setenv("bootcmd", "tftpboot 0x2000000 $image_name;tftpboot $fdtaddr $fdtfile;"
 		"setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath "
 		"ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params "
 		"clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel; bootz 0x2000000 - $fdtaddr;");
+#endif
 #endif  /* (CONFIG_BOOTDELAY >= 0) */
 
 	env = getenv("standalone");
diff --git a/board/mv_ebu/common/USP/mv_cmd.c b/board/mv_ebu/common/USP/mv_cmd.c
index 7f55aeb..96610d1 100644
--- a/board/mv_ebu/common/USP/mv_cmd.c
+++ b/board/mv_ebu/common/USP/mv_cmd.c
@@ -895,6 +895,76 @@
 
 #include "eth-phy/mvEthPhy.h"
 
+int phy_dump_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	/* bitmask of registers we print */
+	static unsigned int page_regs[] = {
+		/*32222222222211111111110000000000*/	/* reg 31->0 */
+		/*10987654321098765432109876543210*/
+
+		0b00000100101111111000011111111111,	/* page 0 */
+		0b00000111101011111000000111111111,
+		0b00000000001111010000000000000000,
+		0b00000000000011110000000000000000,
+		0b00001111101111110000000001110011,
+		0b00011111101111110000000000000000,
+		0b00000111100101110000000000000000,
+		0b00011110001111110000000000000000,
+		0b00000000000000001111111100000111,
+		0b00000000000000000000000000101111,
+		0b00000000000000000000000000000000,
+		0b00000000000000000000000000000000,
+		0b00000000000000001111111100111111,
+		0b00000000000000000000000000000000,
+		0b00000000000000001100000100001111,	/* page 14 */
+
+	};
+
+	MV_U16 phyReg;
+	int phy = simple_strtoul( argv[1], NULL, 16 );
+
+	int i, j;
+	int num_pages = sizeof page_regs / sizeof *page_regs;
+	unsigned int* pp;
+
+	printf("   ");	// %2d:
+	for (i = 0; i < num_pages; i++) {
+		printf(" %4d", i);
+	}
+	printf("\n");
+
+	for (i = 0; i < 32; i++) {
+		unsigned int todo = 0;
+		printf("%2d:", i);
+		for (j = 0, pp = page_regs; j < num_pages; j++, pp++) {
+			unsigned int p = *pp;
+			p >>= i;
+
+			if (!(p & 1)) {
+				printf(" %4s", "-");
+			} else {
+				mvEthPhyRegWrite(phy, 0x16, j);	// page
+				mvEthPhyRegRead(phy, i, &phyReg);
+				printf(" %04x", phyReg);
+			}
+
+			p >>= 1;
+			todo |= p;
+		}
+		printf("\n");
+		if (todo == 0)
+			break;
+	}
+	return 1;
+}
+
+U_BOOT_CMD(
+	phydump,      2,     2,      phy_dump_cmd,
+	"phydump	- dump all Phy registers\n",
+	" Phy_address. \n"
+	"\tDump the Phy registers. \n"
+);
+
 int phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	MV_U16 phyReg;
diff --git a/board/mv_ebu/common/USP/mv_fdt.c b/board/mv_ebu/common/USP/mv_fdt.c
index b17c4d5..ad57143 100644
--- a/board/mv_ebu/common/USP/mv_fdt.c
+++ b/board/mv_ebu/common/USP/mv_fdt.c
@@ -90,6 +90,16 @@
 	if (!env)
 		setenv("bootcmd", bootcmd_fdt);
 #endif /* (CONFIG_OF_LIBFDT_IS_DEFAULT) */
+
+#ifdef CONFIG_GFCH100
+	env = getenv("fdtcontinueonerror");
+	if (!env)
+		setenv("fdtcontinueonerror", "yes");
+
+	env = getenv("enaFDTdebug");
+	if (!env)
+		setenv("enaFDTdebug", "yes");
+#endif
 #endif
 }
 
@@ -214,6 +224,15 @@
 		}							\
 	} while (0)
 
+#define report_error(counter, continue, ...)	\
+	do {					\
+		mv_fdt_dprintf(__VA_ARGS__);	\
+		(*(counter))++;			\
+		if (!continue) {		\
+			goto bs_fail;		\
+		}				\
+	} while (0)
+
 /*******************************************************************************
 * ft_board_setup
 *
@@ -232,9 +251,11 @@
 *******************************************************************************/
 void ft_board_setup(void *blob, bd_t *bd)
 {
-	int err;			/* error number */
-	char *env;			/* env value */
+	int err;		/* error number */
+	char *env;		/* env value */
 	update_fnc_t **update_fnc_ptr;
+	int counter = 0;	/* error counter */
+	int force = 0;		/* continue on error if set */
 
 	/* Debug information will be printed if variable enaFDTdebug=yes */
 	env = getenv("enaFDTdebug");
@@ -243,20 +264,24 @@
 	else
 		mv_fdt_debug = 0;
 
+	env = getenv("fdtcontinueonerror");
+	if (env && ((strncmp(env, "yes", 3) == 0)))
+		force = 1;
+
 	/* Update dt information for all SoCs */
 	/* Update dt bootargs from commandline */
 	fdt_resize(blob);
 	mv_fdt_modify(blob, err, fdt_chosen(blob, 1));
-	if (err < 0) {
-		mv_fdt_dprintf("Updating DT bootargs failed\n");
-		goto bs_fail;
-	}
+	if (err < 0)
+		report_error(&counter, force, "Updating DT bootargs failed\n");
+
 	mv_fdt_dprintf("DT bootargs updated from commandline\n");
 
 	/* Update ethernet aliases with nodes' names and update mac addresses */
 	err = mv_fdt_scan_and_set_alias(blob, "ethernet@", "ethernet");
 	if (err < 0)
-		goto bs_fail;
+		report_error(&counter, force, "Updating ethernet aliases failed\n");
+
 	fdt_fixup_ethernet(blob);
 	mv_fdt_dprintf("DT ethernet MAC addresses updated from environment\n");
 
@@ -267,8 +292,11 @@
 	/* Make updates of functions in update_sequence */
 	for (update_fnc_ptr = update_sequence; *update_fnc_ptr; ++update_fnc_ptr) {
 		err = (*update_fnc_ptr)(blob);
-		if (err < 0)
-			goto bs_fail;
+		if (err < 0) {
+			report_error(&counter, force,
+				"Updating function 0x%08x failed\n", update_fnc_ptr);
+			/* report_error will "goto bs_fail" on !force */
+		}
 	}
 
 	printf("Updating device tree successful\n");
@@ -980,7 +1008,11 @@
 {
 	char propval[128];				/* property value */
 	const char *prop = "compatible";		/* property name */
+#ifdef CONFIG_GFCH100
+	const char *node = "pinctrl@18000";		/* node name */
+#else
 	const char *node = "pinctrl";			/* node name */
+#endif
 
 	/* update pinctrl driver 'compatible' property, according to device model type */
 	sprintf(propval, "marvell,mv88f%x-pinctrl", mvCtrlModelGet());
@@ -1030,6 +1062,7 @@
 	const char *node;		/* node name */
 	int depth = 1;
 	int err;
+	char* rgmiitype = NULL;
 
 	/* Get number of ethernet nodes */
 	aliasesoffset = mv_fdt_find_node(fdt, "aliases");
@@ -1110,7 +1143,8 @@
 				sprintf(propval, "sgmii");
 				break;
 			case MV_PORT_TYPE_RGMII:
-				sprintf(propval, "rgmii");
+				rgmiitype = getenv("rgmiitype");
+				snprintf(propval, sizeof propval, "%s", rgmiitype == NULL ? "rgmii" : rgmiitype);
 				break;
 			default:
 				mv_fdt_dprintf("Bad port type received for interface %d\n", port);
@@ -1218,7 +1252,11 @@
 	else
 		sprintf(propval, "disabled"); /* disable NAND interface if NOT found active devices */
 
+#ifdef CONFIG_GFCH100
+	sprintf(node, "flash@%x", MV_NFC_REGS_OFFSET);
+#else
 	sprintf(node, "nand@%x", MV_NFC_REGS_OFFSET);
+#endif
 	if (mv_fdt_set_node_prop(fdt, node, prop, propval) < 0) {
 		mv_fdt_dprintf("Failed to set property '%s' of node '%s' in device tree\n", prop, node);
 		return 0;
diff --git a/board/mv_ebu/common/mv_hal/eth-phy/mvEthPhy.c b/board/mv_ebu/common/mv_hal/eth-phy/mvEthPhy.c
index 0276da2..593efff 100644
--- a/board/mv_ebu/common/mv_hal/eth-phy/mvEthPhy.c
+++ b/board/mv_ebu/common/mv_hal/eth-phy/mvEthPhy.c
@@ -1798,7 +1798,7 @@
 	mvEthPhyRegWrite(i, 0x10, reg);
 	mvEthPhyRegWrite(i, 0x16, 0x0);
 
-	DB2(printf("%s: configure jumbo QuadPhyPort=0x%x offset = 0x%x\n", __func__, port0, offs));
+	//DB2(printf("%s: configure jumbo QuadPhyPort=0x%x offset = 0x%x\n", __func__, port0, offs));
 	if (0 == initJumboPackets) {
 		int j;
 		initJumboPackets = 1;
@@ -1959,7 +1959,7 @@
 	mvEthPhyRegWrite(i, 0x10, reg);
 	mvEthPhyRegWrite(i, 0x16, 0x0);
 
-	DB2(printf("%s: configure jumbo QuadPhyPort=0x%x offset = 0x%x\n", __func__, port0, offs));
+	//DB2(printf("%s: configure jumbo QuadPhyPort=0x%x offset = 0x%x\n", __func__, port0, offs));
 	if (0 == initJumboPackets) {
 		int j;
 		initJumboPackets = 1;
@@ -2031,18 +2031,33 @@
 	int i;
 	MV_U16 reg;
 
-
+	/* RN says to add this bit of setup */
 	for (i = 0; i < 4; i++) {
+#ifdef CONFIG_GFCH100
+		mvEthPhyRegWrite(i, 0x16, 0x00ff);
+		mvEthPhyRegWrite(i, 0x18, 0x2800);
+		mvEthPhyRegWrite(i, 0x17, 0x2001);
+		mvEthPhyRegWrite(i, 0x16, 0x0000);
+#endif
 		mvEthPhyRegWrite(i, 0x16, 0);
 		mvEthPhyRegWrite(i, 0x1d, 3);
 		mvEthPhyRegWrite(i, 0x1e, 2);
 		mvEthPhyRegWrite(i, 0x1d, 0);
+	}
 
+	for (i = 0; i < 4; i++) {
 		/* Power up the phy */
 		/* mvEthPhyRegRead(i,ETH_PHY_CTRL_REG, &reg); */
 		/* reg |= ETH_PHY_CTRL_RESET_MASK; */
 		/* mvEthPhyRegWrite(i,ETH_PHY_CTRL_REG, reg);   software reset */
 
+#ifdef CONFIG_GFCH100
+		/* add auto-neg for older boards strapped to 1g only */
+		mvEthPhyRegWrite(i, 0x16, 0);		/* page 0 */
+		mvEthPhyRegWrite(i, 0x04, 0x01e1);	/* 10/100 adverts */
+		mvEthPhyRegWrite(i, 0x09, 0x0300);	/* 1G adverts */
+#endif
+
 		/* Enable QSGMII AN */
 		/* Set page to 4. */
 		mvEthPhyRegWrite(i, 0x16, 4);
@@ -2056,6 +2071,7 @@
 		mvEthPhyRegWrite(i, ETH_PHY_CTRL_REG, reg);
 	}
 }
+
 /*******************************************************************************
 * mvEthE1512PhyBasicInit -
 *
diff --git a/boards.cfg b/boards.cfg
index a2159f8..4a01430 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -55,6 +55,7 @@
 armada_38x_customer0         arm         armv7       a38x                mv_ebu         mvca9        armada_38x:CUSTOMER_BOARD_0,ARMADA_38X
 armada_38x_customer1         arm         armv7       a38x                mv_ebu         mvca9        armada_38x:CUSTOMER_BOARD_1,ARMADA_38X
 armada_38x_clearfog          arm         armv7       a38x                mv_ebu         mvca9        armada_38x:CLEARFOG_BOARD,ARMADA_38X
+armada_38x_gfch100           arm         armv7       a38x                mv_ebu         mvca9        armada_38x:GFCH100,ARMADA_38X
 armada_39x                   arm         armv7       a38x                mv_ebu         mvca9        armada_38x:ARMADA_39X
 armada_39x_customer0         arm         armv7       a38x                mv_ebu         mvca9        armada_38x:CUSTOMER_BOARD_0,ARMADA_39X
 armada_39x_customer1         arm         armv7       a38x                mv_ebu         mvca9        armada_38x:CUSTOMER_BOARD_1,ARMADA_39X
diff --git a/build.pl b/build.pl
index 0c64c3f..d786ee1 100755
--- a/build.pl
+++ b/build.pl
@@ -30,6 +30,7 @@
 	print "\t\t\t\t\t2400, 4800, 9600, 19200, 38400, 57600, 115200\n";
 	print "\t-u\tChange the default BootROM UART debug port number. Suported ports 0 - 3\n";
 	print "\t-g\tSelect BootROM debug port MPPs configuration value = 0-7 (BootROM-specific)\n";
+	print "\t-s\tStyle of build, accepts: dev, prod, openbox\n";
 	print "\n";
 	print "Secure boot options:\n";
 	print "\tNOTE: \tAll secure options except \"j\" are mandatory once one of them is selected\n";
@@ -52,7 +53,7 @@
 # Main
 use Getopt::Std;
 
-getopt('f:b:o:i:v:d:m:r:u:g:z:a:k:j:x:l:');
+getopt('f:b:o:i:v:d:m:r:u:g:z:a:k:j:x:l:s:');
 
 if((!defined $opt_b) or
 	(!defined $opt_f)) {
@@ -96,6 +97,7 @@
 	($opt_b eq "armada_38x_clearfog") or
 	($opt_b eq "armada_38x_customer0") or
 	($opt_b eq "armada_38x_customer1") or
+	($opt_b eq "armada_38x_gfch100") or
 	($opt_b eq "armada_39x") or
 	($opt_b eq "armada_39x_customer0") or
 	($opt_b eq "armada_39x_customer1") or
@@ -144,8 +146,9 @@
 		$targetBoard = substr $board, 8;
 	}
 	# if board string contains "customer" (Or A38x-SolidRun Clear fog board), use customer define for binary_header
-	if ((index($board, "customer") != -1) or (index($board, "clearfog") != -1)) {
-		system("echo \"#define CONFIG_CUSTOMER_BOARD_SUPPORT 1\" >> include/config.h");
+	if ((index($board, "customer") != -1) or (index($board, "clearfog") != -1)
+		or (index($board, "gfch100") != -1)) {
+			system("echo \"#define CONFIG_CUSTOMER_BOARD_SUPPORT 1\" >> include/config.h");
 	}
 
 }
@@ -388,6 +391,26 @@
 	}
 }
 
+if(!defined $opt_s){
+	printf " *** Error: Unspecified build style!\n";
+	HELP_MESSAGE();
+	exit 1;
+} elsif ($opt_s eq "prod") {
+	printf("style=prod, console will be disabled.\n");
+	system("echo \"#define CONFIG_DISABLE_INPUT\" >> include/config.h");
+	system("echo \"#define CONFIG_BOOT_DELAY 0\" >> include/config.h");
+} elsif ($opt_s eq "dev") {
+	printf("style=dev, console will be enabled.\n");
+	system("echo \"#undef CONFIG_DISABLE_INPUT\" >> include/config.h");
+} elsif ($opt_s eq "openbox") {
+	printf("style=openbox, console will be enabled.\n");
+	system("echo \"#undef CONFIG_DISABLE_INPUT\" >> include/config.h");
+} else {
+	printf(" *** Error: Unknown build style was set: $opt_s\n");
+	HELP_MESSAGE();
+	exit 1;
+}
+
 if(defined $opt_p)
 {
 	$extra_opt = " -p";
diff --git a/common/Makefile b/common/Makefile
index 54fcc81..22f1fc1 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -32,6 +32,7 @@
 COBJS-y += exports.o
 COBJS-y += hash.o
 COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o
+COBJS-$(CONFIG_CMD_HNVRAM) += cmd_hnvram.o
 COBJS-y += s_record.o
 COBJS-y += xyzModem.o
 COBJS-y += cmd_disk.o
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
index da7705d..39fc021 100644
--- a/common/cmd_gpt.c
+++ b/common/cmd_gpt.c
@@ -135,6 +135,12 @@
 	debug("%s: MMC lba num: 0x%x %d\n", __func__,
 	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
 
+	/* avoid divide by 0 */
+	if (dev_desc->blksz == 0) {
+		printf("blksz == 0, run mmc rescan or similar first.\n");
+		return -2;
+	}
+
 	if (str_part == NULL)
 		return -1;
 
diff --git a/common/cmd_hnvram.c b/common/cmd_hnvram.c
new file mode 100644
index 0000000..2ef80f7
--- /dev/null
+++ b/common/cmd_hnvram.c
@@ -0,0 +1,272 @@
+/*
+ * cmd_hnvram.c -- makes hnvram contents available in uboot.
+ *      Loads contents of hnvram from mmc and saves it to
+ *      environment variables named HNV_<name>.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Author: Chris Gibson <cgibson@google.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <command.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+
+/* local debug macro */
+#undef HNVRAM_DEBUG
+
+#ifdef HNVRAM_DEBUG
+#define DEBUG(fmt, args...)  printf(fmt, ##args)
+#else
+#define DEBUG(fmt, args...)
+#endif  /* HNVRAM_DEBUG */
+
+#define HNVRAM_DEV          0
+#define HNVRAM_BLK          0x00000040
+#define HNVRAM_CNT          0x00001000
+
+#define HNVRAM_BLOCKSIZE    0x00020000
+#define HNVRAM_B1_OFFSET    0x00100000
+#define HNVRAM_B2_OFFSET    0x00140000
+
+/* these keys are stored in binary format for historical reasons */
+const char *hnvram_binary_keys[] = {
+	"LOADER_VERSION",
+	"HDCP_KEY",
+	"DTCP_KEY",
+};
+
+static void *xmalloc(size_t size)
+{
+	void *p = NULL;
+	if (!(p = malloc(size))) {
+		printf("error: memory not allocated\n");
+		return 0;
+	}
+	memset(p, 0xAB, size);
+	return p;
+}
+
+int read_u8(const char **p)
+{
+	int v = *(const unsigned char *)(*p);
+	*p += 1;
+	return v;
+}
+
+int read_s32_be(const char **p)
+{
+	const unsigned char *vp = (const unsigned char *)*p;
+	*p += 4;
+	return (vp[0]<<24) + (vp[1]<<16) + (vp[2]<<8) + vp[3];
+}
+
+int read_u16_le(const char **p)
+{
+	const unsigned char *up = (const unsigned char *)(*p);
+	*p += 2;
+	return up[0] + (up[1] << 8);
+}
+
+int is_hnvram_binary(const char *name, int namelen)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(hnvram_binary_keys); i++) {
+		const char *k = hnvram_binary_keys[i];
+		if ((int)strlen(k) == namelen && strncmp(k, name, namelen) == 0) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+char *encode_hex(const char *s, int len)
+{
+	char *optr, *out = xmalloc(len * 2 + 1);
+	for (optr = out; len > 0; len--) {
+		sprintf(optr, "%02x", read_u8(&s));
+		optr += 2;
+	}
+	return out;
+}
+
+char *encode_macaddr(const char *mac)
+{
+	int i;
+	char *out = xmalloc(6 * 2 + 5 + 2);
+	for (i = 0; i < 6; i++) {
+		sprintf(out + i * 3, "%02X:", read_u8(&mac));
+	}
+	out[6*2 + 5] = '\0';
+	return out;
+}
+
+static void _copy_setenv(const char *name, int namelen,
+		const char *val, int vallen)
+{
+	char *n, *v;
+	if (namelen + vallen < 128) {
+		n = xmalloc(4 + namelen + 1);
+		v = xmalloc(vallen + 1);
+		memcpy(n, "HNV_", 4);
+		memcpy(n + 4, name, namelen);
+		memcpy(v, val, vallen);
+		n[namelen+4] = 0;
+		v[vallen] = 0;
+		setenv(n, v);
+		free(n);
+		free(v);
+	} else {
+		DEBUG("ignoring oversized val: %.15s, vallen: %d\n", val, vallen);
+	}
+}
+
+static int _parse_hnvram(const char *buf, int len)
+{
+	// An hnvram structure. Format is a tag-length-value sequence of:
+	//    [1 byte]   type (1 for notdone, 0 for done)
+	//    [4 bytes]  record length
+	//    [1 byte]   key length
+	//    [x bytes]  key
+	//    [4 bytes]  value length
+	//    [y bytes]  value
+	int rectype, reclen, namelen, vallen;
+        int done = 0;
+	const char *name, *val, *p = buf;
+	while (p - buf <= len + 11) {
+		rectype = read_u8(&p);
+		if (rectype == 0x00) {
+			DEBUG("done processing hnvram block");
+                        done = 1;
+			break;
+		}
+		if (rectype != 0x01) {
+			DEBUG("error: hnvram invalid rectype %x\n", rectype);
+			return -1;
+		}
+
+		reclen = read_s32_be(&p);
+		if (reclen <= 6 || (p - buf) + reclen >= len) {
+			DEBUG("error: hnvram invalid reclen %d\n", reclen);
+			return -1;
+		}
+		namelen = read_u8(&p);
+		if (namelen < 1 || (p - buf) + namelen >= len) {
+			DEBUG("error: hnvram invalid namelen %d\n", namelen);
+			return -1;
+		}
+		name = p;
+		p += namelen;
+		vallen = read_s32_be(&p);
+		if (vallen < 0 || (p - buf) + vallen >= len) {
+			DEBUG("error: hnvram invalid vallen %d\n", vallen);
+			return -1;
+		}
+		val = p;
+		p += vallen;
+		if (vallen == 6 && namelen >= 8 &&
+				strncmp("MAC_ADDR", name, 8) == 0) {
+			char *macstr = encode_macaddr(val);
+			_copy_setenv(name, namelen, macstr, strlen(macstr));
+			free(macstr);
+		} else if (is_hnvram_binary(name, namelen)) {
+			char *hexstr = encode_hex(val, vallen);
+			_copy_setenv(name, namelen, hexstr, strlen(hexstr));
+			free(hexstr);
+		} else {
+			_copy_setenv(name, namelen, val, vallen);
+		}
+	}
+	if (!done) {
+		printf("failed to find final hnvram record\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int _read_parse_hnvram(struct mmc *mmc, char *buf)
+{
+	int n;
+
+	DEBUG("reading mmc: dev: %d, blk: 0x%x, cnt: 0x%x\n",
+		HNVRAM_DEV, HNVRAM_BLK, HNVRAM_CNT);
+	n = mmc->block_dev.block_read(
+		HNVRAM_DEV, HNVRAM_BLK, HNVRAM_CNT, (void *)buf);
+	if (n < 1) {
+		printf("failed to load hnvram from mmc\n");
+		return -1;
+	}
+        /* flush cache after read */
+	flush_cache((ulong)buf, HNVRAM_CNT * mmc->read_bl_len);
+
+	if (_parse_hnvram(buf, HNVRAM_BLOCKSIZE) != 0) {
+		printf("failed parsing hnvram at offset: 0\n");
+		return -1;
+	}
+	if (_parse_hnvram(buf+HNVRAM_B1_OFFSET, HNVRAM_BLOCKSIZE) != 0) {
+		printf("failed parsing hnvram at offset: %x\n", HNVRAM_B1_OFFSET);
+		return -1;
+	}
+	if (_parse_hnvram(buf+HNVRAM_B2_OFFSET, HNVRAM_BLOCKSIZE) != 0) {
+		printf("failed parsing hnvram at offset: %x\n", HNVRAM_B2_OFFSET);
+		return -1;
+	}
+	return 0;
+}
+
+#if defined(CONFIG_CMD_HNVRAM)
+int do_hnvram(void) {
+	struct mmc *mmc;
+	char *buf;
+
+	mmc = find_mmc_device(HNVRAM_DEV);
+	if (!mmc) {
+		printf("no mmc device found in slot %d\n", HNVRAM_DEV);
+		return CMD_RET_FAILURE;
+	}
+	mmc_init(mmc);
+
+	/* HNVRAM_CNT is the number of blocks and the mmc block size is
+         * mmc->read_bl_len (512) */
+	buf = (char *)xmalloc(HNVRAM_CNT * mmc->read_bl_len);
+	if (!buf) {
+		printf("failed to allocate memory for hnvram\n");
+		return CMD_RET_FAILURE;
+	}
+	DEBUG("malloc'd new hnvram buffer at 0x%p\n", buf);
+	if (_read_parse_hnvram(mmc, buf) != 0) {
+		printf("failed to parse hnvram contents\n");
+		free(buf);
+		return CMD_RET_FAILURE;
+	}
+	free(buf);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_hnvram_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
+		char * const argv[]) {
+	return do_hnvram();
+}
+
+U_BOOT_CMD(
+	hnvram, 1, 0, do_hnvram_cmd,
+	"load hnvram from mmc",
+        "\n"
+	"load hnvram from mmc into environment vars named HNV_<name>\n"
+	);
+#endif  /* CONFIG_CMD_HNVRAM */
diff --git a/common/console.c b/common/console.c
index bf73178..e442d8d 100644
--- a/common/console.c
+++ b/common/console.c
@@ -360,6 +360,10 @@
 
 int getc(void)
 {
+#ifdef CONFIG_DISABLE_INPUT
+	return 0;
+#endif
+
 #ifdef CONFIG_DISABLE_CONSOLE
 	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
 		return 0;
@@ -379,6 +383,10 @@
 
 int tstc(void)
 {
+#ifdef CONFIG_DISABLE_INPUT
+	return 0;
+#endif
+
 #ifdef CONFIG_DISABLE_CONSOLE
 	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
 		return 0;
diff --git a/common/main.c b/common/main.c
index d23b98a..a87d3ab 100755
--- a/common/main.c
+++ b/common/main.c
@@ -405,6 +405,10 @@
 	}
 #endif /* CONFIG_VERSION_VARIABLE */
 
+	{
+		setenv ("q", "'");  /* setenv foo ${q}this is quoted${q} */
+	}
+
 #ifdef CONFIG_SYS_HUSH_PARSER
 	u_boot_hush_start ();
 #endif
diff --git a/config.mk b/config.mk
index b7cd481..bd72da5 100644
--- a/config.mk
+++ b/config.mk
@@ -235,6 +235,7 @@
 
 ifdef BUILD_TAG
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
+
 	-DBUILD_TAG='"$(BUILD_TAG)"'
 else
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
diff --git a/disk/part_efi.c b/disk/part_efi.c
index df75fca..6fb5d46 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -245,8 +245,8 @@
 	/* 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;
+	put_unaligned_le32(1, &p_mbr->partition_record[0].start_sect);
+	put_unaligned_le32(dev_desc->lba, &p_mbr->partition_record[0].nr_sects);
 
 	/* Write MBR sector to the MMC device */
 	if (dev_desc->block_write(dev_desc->dev, 0, 1, p_mbr) != 1) {
@@ -382,12 +382,21 @@
 #ifdef CONFIG_PARTITION_UUIDS
 	char *str_uuid;
 #endif
-
+	printf("first_usable_lba=0x%08x\n", offset);
+	printf("%2s: %-10s %-10s %-10s %-16s %-16s %s\n",
+		"#", "start", "size", "blksz", "name", "type", "uuid");
+	for (i = 0; i < parts; i++) {
+		disk_partition_t* p = &partitions[i];
+		printf("%2d: 0x%08lx 0x%08lx 0x%08lx %-16s %-16s %s\n",
+			i, p->start, p->size, p->blksz, p->name, p->type, p->uuid);
+	}
+	
 	for (i = 0; i < parts; i++) {
 		/* partition starting lba */
 		start = partitions[i].start;
 		if (start && (start < offset)) {
-			printf("Partition overlap\n");
+			printf("Partition overlap: i=%d start=0x%08lx offset=0x%08x\n",
+				i, start, offset);
 			return -1;
 		}
 		if (start) {
@@ -409,8 +418,9 @@
 			gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
 
 		/* partition type GUID */
+		static efi_guid_t basic = PARTITION_BASIC_DATA_GUID;
 		memcpy(gpt_e[i].partition_type_guid.b,
-			&PARTITION_BASIC_DATA_GUID, 16);
+			&basic, 16);
 
 #ifdef CONFIG_PARTITION_UUIDS
 		str_uuid = partitions[i].uuid;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5a93d61..d25a0cc 100755
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -139,7 +139,7 @@
 			for (i = 0; i < 4; i++) {
 				int j;
 				printf("\t\t\t\t\t%03d - ", i*4);
-				ptr = (u8 *)&cmd->response[i];
+				ptr = (char *)&cmd->response[i];
 				ptr += 3;
 				for (j = 0; j < 4; j++)
 					printf("%02X ", *ptr--);
diff --git a/examples/api/marvell/mon_ext/.gitignore b/examples/api/marvell/mon_ext/.gitignore
new file mode 100644
index 0000000..6db5c94
--- /dev/null
+++ b/examples/api/marvell/mon_ext/.gitignore
@@ -0,0 +1 @@
+monext
diff --git a/include/common.h b/include/common.h
index e11daed..f3fa6c9 100755
--- a/include/common.h
+++ b/include/common.h
@@ -1000,4 +1000,9 @@
 # include <environment.h>
 #endif
 
+/* Include hnvram functions. */
+#if defined(CONFIG_CMD_HNVRAM)
+int do_hnvram(void);
+#endif
+
 #endif	/* __COMMON_H_ */
diff --git a/include/configs/armada_38x.h b/include/configs/armada_38x.h
index a7b1624..16238bd 100644
--- a/include/configs/armada_38x.h
+++ b/include/configs/armada_38x.h
@@ -68,7 +68,7 @@
 #define MV_DDR_64BIT
 #define MV_BOOTROM
 
-#if defined (CONFIG_CUSTOMER_BOARD_0) || defined (CONFIG_CUSTOMER_BOARD_1) || defined (CONFIG_CLEARFOG_BOARD)
+#if defined (CONFIG_CUSTOMER_BOARD_0) || defined (CONFIG_CUSTOMER_BOARD_1) || defined (CONFIG_CLEARFOG_BOARD) || defined (CONFIG_GFCH100)
 #define CONFIG_CUSTOMER_BOARD_SUPPORT
 #endif
 
@@ -163,6 +163,7 @@
 #define CONFIG_CMD_RCVR
 #define CONFIG_CMD_BOOT_MENU
 #define CONFIG_CMD_SYS_RESTORE
+#define CONFIG_CMD_HNVRAM
 
 /* Open this define for enabling Secure Boot Mode eFuses modification
 #define CONFIG_CMD_EFUSE
@@ -489,6 +490,21 @@
 #define ETH1ADDR		"00:00:00:00:51:82"
 #define ENV_ETH_PRIME		"egiga0"
 
+#ifdef CONFIG_GFCH100
+#undef CONFIG_IPADDR
+#define CONFIG_IPADDR		192.168.1.99
+#undef CONFIG_SERVERIP
+#define CONFIG_SERVERIP		192.168.1.160
+#undef ENV_ETH_PRIME
+#define ENV_ETH_PRIME		"egiga1"
+
+#define CONFIG_1G_PHY_PORT	3
+
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_GPT
+//#define CONFIG_MMC_TRACE
+#endif
+
 /*
  * PCI and PCIe
  */
@@ -513,7 +529,7 @@
 	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
 #else
 	#define ENV_USB_ACTIVE        "0"
-	#define ENV_USB_MODE          "2"	/* 3 = USB3.0 | 2 = USB2.0 */
+	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
 #endif
 
 	#define CONFIG_USB_HOST_ETHER
diff --git a/tools/marvell/bin_hdr/base.mk b/tools/marvell/bin_hdr/base.mk
index 9f8404b..607b236 100755
--- a/tools/marvell/bin_hdr/base.mk
+++ b/tools/marvell/bin_hdr/base.mk
@@ -86,6 +86,9 @@
 ifeq "$(CONFIG_CLEARFOG_BOARD)"  "y"
   CFLAGS += -DCONFIG_CLEARFOG_BOARD
 endif
+ifeq "$(CONFIG_GFCH100)"  "y"
+  CFLAGS += -DCONFIG_GFCH100
+endif
 
 # AXP
 ifeq "$(CONFIG_DB_78x60_BP_REV2)"  "y"
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_topology.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_topology.h
index bbea7ec..3ac5580 100755
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_topology.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_topology.h
@@ -127,6 +127,13 @@
     /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_device_width  mem_size     frequency  casL casWL      temperature */
 	{{{{0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}}, SPEED_BIN_DDR_CLEARFOG_BOARD, BUS_WIDTH_CLEARFOG_BOARD , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
     INTERFACE_BUS_MASK_32BIT  /* Buses mask */
+    },
+    /* GFCH100 */
+    {
+    0x1, /* active interfaces */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_device_width  mem_size     frequency  casL casWL      temperature */
+	{{{{0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}, {0x1,0,0,0}}, SPEED_BIN_DDR_1600K, BUS_WIDTH_8 , MEM_2G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
+    INTERFACE_BUS_MASK_32BIT_ECC  /* Buses mask */
     }
 };
 
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_vars.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_vars.h
index 38c7b60..7b51135 100755
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_vars.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x_vars.h
@@ -87,6 +87,7 @@
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 	{"a38x_customer_0_800",	DDR_FREQ_800,	0,	0x0,	A38X_CUSTOMER_BOARD_ID0,	ddr3_customer_800},
 	{"a38x_customer_1_800",	DDR_FREQ_800,	0,	0x0,	A38X_CUSTOMER_BOARD_ID1,	ddr3_customer_800},
+	{"gfch100",		DDR_FREQ_800,	0,	0x0,	GFCH100_ID,			ddr3_customer_800},
 #else
 	{"a38x_533",		DDR_FREQ_533,	0,	0x0,		MARVELL_BOARD,		ddr3_a38x_533},
 	{"a38x_667",		DDR_FREQ_667,	0,	0x0,		MARVELL_BOARD,		ddr3_a38x_667},
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
index f92887c..0b6a6d3 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
@@ -331,6 +331,8 @@
 		gBoardId = CUSTOMER_BOARD_ID1;
 	#elif CONFIG_CLEARFOG_BOARD
 		gBoardId = A38X_CLEARFOG_BOARD_ID;
+	#elif CONFIG_GFCH100
+		gBoardId = GFCH100_ID;
 	#endif
 #else
 	/* For Marvell Boards: read board ID from TWSI*/
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
index d5a7406..5829e32 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
@@ -298,7 +298,8 @@
 #define A38X_CUSTOMER_BOARD_ID0			(A38X_CUSTOMER_BOARD_ID_BASE + 0)
 #define A38X_CUSTOMER_BOARD_ID1			(A38X_CUSTOMER_BOARD_ID_BASE + 1)
 #define A38X_CLEARFOG_BOARD_ID			(A38X_CUSTOMER_BOARD_ID_BASE + 2)
-#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUSTOMER_BOARD_ID_BASE + 3)
+#define A38X_GFCH100_ID				(A38X_CUSTOMER_BOARD_ID_BASE + 3)
+#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUSTOMER_BOARD_ID_BASE + 4)
 #define A38X_MV_CUSTOMER_BOARD_NUM		(A38X_MV_MAX_CUSTOMER_BOARD_ID - A38X_CUSTOMER_BOARD_ID_BASE)
 
 /* Marvell boards for A38x*/
@@ -331,6 +332,7 @@
 #define CUTOMER_BOARD_ID_BASE			A38X_CUSTOMER_BOARD_ID_BASE
 #define CUSTOMER_BOARD_ID0			A38X_CUSTOMER_BOARD_ID0
 #define CUSTOMER_BOARD_ID1			A38X_CUSTOMER_BOARD_ID1
+#define GFCH100_ID				A38X_GFCH100_ID
 #define MV_MAX_CUSTOMER_BOARD_ID		A38X_MV_MAX_CUSTOMER_BOARD_ID
 #define MV_CUSTOMER_BOARD_NUM			A38X_MV_CUSTOMER_BOARD_NUM
 #define MARVELL_BOARD_ID_BASE			A38X_MARVELL_BOARD_ID_BASE
@@ -494,12 +496,14 @@
 {A38X_CUSTOMER_BOARD_ID0,	-1 },\
 {A38X_CUSTOMER_BOARD_ID0,	-1 },\
 {A38X_CLEARFOG_BOARD_ID,	-1 },\
+{A38X_GFCH100_ID,		-1 },\
 };
 
 #define MV_BOARD_USB_VBUS_GPIO_INFO {\
 {A38X_CUSTOMER_BOARD_ID0, {-1, -1} },\
 {A38X_CUSTOMER_BOARD_ID0, {-1, -1} },\
 {A38X_CLEARFOG_BOARD_ID, {-1, -1} },\
+{A38X_GFCH100_ID, {-1, -1} },\
 };
 #else
 #define MV_BOARD_WAKEUP_GPIO_INFO {\
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a38x.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a38x.lib
deleted file mode 100644
index 84906b3..0000000
--- a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a38x.lib
+++ /dev/null
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
index b012ca7..03e8573 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
@@ -1330,12 +1330,12 @@
 
 	/* per Serdes Power Up */
 	for (serdesId = 0; serdesId < mvHwsSerdesGetMaxLane(); serdesId++) {
+		serdesLaneNum = mvHwsGetPhysicalSerdesNum(serdesId);
+
 		DEBUG_INIT_FULL_S("calling serdesPowerUpCtrl: serdes lane number ");
 		DEBUG_INIT_FULL_D_10(serdesLaneNum, 1);
 		DEBUG_INIT_FULL_S("\n");
 
-		serdesLaneNum = mvHwsGetPhysicalSerdesNum(serdesId);
-
 		serdesType = serdesConfigMap[serdesId].serdesType;
 		serdesSpeed = serdesConfigMap[serdesId].serdesSpeed;
 		serdesMode = serdesConfigMap[serdesId].serdesMode;
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c
index ec2c65f..c267219 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c
@@ -101,6 +101,19 @@
 	{ USB3_HOST1,	__5Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ PEX2,	  	__5Gbps,	PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ SGMII2,	__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
+},
+{
+	/* GFCH100 Topology */
+	{ SGMII0,		__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ PEX0,			__2_5Gbps,	PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+	{ SGMII1,		__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+#if TODO_EDJAMES_PEX3_IS_WORKING
+	{ PEX3,			__2_5Gbps,	PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+#else
+	{ DEFAULT_SERDES,	__2_5Gbps,	PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+#endif
+	{ DEFAULT_SERDES,	__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ DEFAULT_SERDES,	__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 }};
 
 
@@ -134,6 +147,7 @@
 	loadTopologyCustomer,   	  /* Customer Board 0 */
 	loadTopologyCustomer,   	  /* Customer Board 1*/
 	loadTopologyCustomer,   	  /* SolidRun ClearFog Board */
+	loadTopologyCustomer,   	  /* GFCH100 */
 };
 
 #else /* CONFIG_CUSTOMER_BOARD_SUPPORT */
diff --git a/version b/version
new file mode 100755
index 0000000..f3b8321
--- /dev/null
+++ b/version
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+#
+# Lifted from Avery's code in buildroot/support/scripts/postbuild.sh
+#
+
+PLATFORM_PREFIX=gfiber
+
+tagname=$(git describe)
+tagabbrev=$(git describe --abbrev=0)
+count=$(git rev-list '$tagabbrev'..HEAD 2>/dev/null | wc -l)
+if [ "$count" -gt 0 ]; then
+  # Tree has commits since last tag, rebuild the image name
+  version="$PLATFORM_PREFIX-${tagabbrev#*-}-$count-${tagname##*-}"
+else
+  version="$PLATFORM_PREFIX-${tagname#*-}"
+fi
+echo -n "$version"
+
+if [ "$PROD" != "y" ]; then
+  (echo -n '-'; whoami | cut -c1-2)
+fi