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 df3f234..b10e919 100755
--- a/.gitignore
+++ b/.gitignore
@@ -3,10 +3,8 @@
 # subdirectories here. Add them in the ".gitignore" file
 # in that subdirectory instead.
 #
-# Normal rules
+# 	Normal rules
 #
-omri.pl
-comri.pl
 .gitignore
 *.rej
 *.orig
diff --git a/Makefile b/Makefile
index 4d412d7..07debc4 100755
--- a/Makefile
+++ b/Makefile
@@ -178,7 +178,7 @@
 
 # load ARCH, BOARD, and CPU configuration
 include $(obj)include/config.mk
-export	ARCH CPU BOARD VENDOR SOC DDR3LIB DDRTYPE
+export	ARCH CPU BOARD VENDOR SOC DDR3LIB DDRTYPE DDR4SUBLIB
 
 # set default to nothing for native builds
 ifeq ($(HOSTARCH),$(ARCH))
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 5ff7719..c0a81e3 100755
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -91,13 +91,14 @@
 }
 
 #if defined (CONFIG_OF_LIBFDT) || defined (MV_DDR_L2_ALIGNMENT)
-u64 l2_base = (_4G - _1G);	/* used for memory node update in Device tree or for memory tags */
+u64 l2_base = (_4G - _1G);	/* used for memory node update in Device tree, or for memory tags */
 #endif
 
 #ifdef CONFIG_OF_LIBFDT
 extern void mvCpuIfMbusWindowSet(u32 base, u32 size);
 int fixup_memory_node(void *blob)
 {
+	char *env;
 #ifndef CONFIG_MARVELL
 	bd_t	*bd = gd->bd;
 #endif
@@ -105,23 +106,30 @@
 	u64 start[CONFIG_NR_DRAM_BANKS];
 	u64 size[CONFIG_NR_DRAM_BANKS];
 
+	/* - Binary header prioritize IO memory space via L2 filtering at 3.0GB, in order
+	 *   to ensure 'hit' on internal registers IO access (located at 0xd0000000 by default)
+	 * - Although U-Boot updates internal register base to 0xf1000000 (3.75GB), Address
+	 *   decoding supports only windows size aligned to power of 2.
+	 */
+	env = getenv("limit_dram_size");
+	if (env && ((strcmp(env, "yes") == 0) ||  (strcmp(env, "Yes") == 0)))
+	{
+		printf("\nLimit DDR size at 3GB due to power of 2 requirement of Address decoding\n");
+		l2_base = (_4G - _1G);
+	} else
+		l2_base = (_4G - _256M);
 
 #ifdef CONFIG_MARVELL
 	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
 		start[bank] = gd->dram_hw_info[bank].start;
 		size[bank] = gd->dram_hw_info[bank].size;
 
-		/* - Binary header preserves IO memory space via L2 filtering at 3.25GB, in order
-		 *   to avoid conflict with internal registers IO located 0xd0000000.
-		 * - U-Boot updates internal register base to 0xf1000000 (3.75GB)
-		 * - if DRAM CS size reaches 4G --> also limit CS memory node to 3.75GB */
-
-		/* due to LSP issue with unaligned window sizes to power of 2 (3.75GB),
-		 * L2 is temporary set to 3GB: update DT memory node accordingly */
+		 /* - If memory size reached 4GB, limit last CS size according to highest power of 2.
+		 *   (when using 2x2GB, last CS will be limited to 1GB) */
 		if ((start[bank] + size[bank]) == _4G) {
 			size[bank] = (l2_base - start[bank]);
-			/* LSP is temporarily wrongly deriving DRAM windows limitation from MBus.
-			 * as a temp WA, align Mbus bridge with L2 base */
+			/* set IO area to higher priority than DRAM window, by aligning MBUS bridge with L2 base.
+			 * (Linux mainline MBUS driver uses MBUS configuration to derive L2 filtering) */
 			mvCpuIfMbusWindowSet(l2_base, _4G - l2_base);
 		}
 	}
@@ -221,15 +229,15 @@
 			if ((start - 1 + size) == 0xFFFFFFFF) {
 				params->u.mem.start = start;
 #ifdef MV_DDR_L2_ALIGNMENT
-/* - Binary header preserves IO memory space via L2 filtering at 3.25GB, in order
- *   to avoid conflict with internal registers IO located 0xd0000000.
- * - U-Boot updates internal register base to 0xf1000000 (3.75GB)
- * - if DRAM CS size reaches 4G --> also limit memory tags to 3.75GB */
-
-/* Temporary: due to LSP (3.10) issue with unaligned window sizes to power of 2 (3.75GB),
- * L2 is set to 3GB: update memory tags accordingly */
+			/* - Binary header prioritize IO memory space via L2 filtering at 3.0GB, in order
+			 *   to ensure 'hit' on internal registers IO access (located at 0xd0000000 by default)
+			 * - Although U-Boot updates internal register base to 0xf1000000 (3.75GB), Address
+			 *   decoding supports only windows size aligned to power of 2.
+			 * - If memory size reached 4GB, limit last CS size according to highest power of 2.
+			 *   (when using 2x2GB, last CS will be limited to 1GB) */
 				params->u.mem.size = (l2_base - start);
-/* align Mbus bridge with L2 base */
+
+				/* set IO area to higher priority than DRAM window, by aligning MBUS bridge with L2 base*/
 				mvCpuIfMbusWindowSet(l2_base, _4G - l2_base);
 #else
 				params->u.mem.size = (0xF0000000 - start);
diff --git a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.c b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.c
index c708e03..8282375 100644
--- a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.c
+++ b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.c
@@ -1487,6 +1487,28 @@
 }
 
 /*******************************************************************************
+* mvBoardIsSwitchConnected
+*
+* DESCRIPTION:
+*       This routine returns port's connection status, this route provide a unified inerface
+*       for other modules to call without care of the switch conntection mode - external or internal
+*       if the switch is connected
+* INPUT:
+*       ethPortNum - Ethernet port number.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       1 - if ethPortNum is connected to switch, 0 otherwise
+*
+*******************************************************************************/
+MV_STATUS mvBoardIsSwitchConnected(void)
+{
+	return mvBoardIsInternalSwitchConnected();
+}
+
+/*******************************************************************************
 * mvBoardFreqModesNumGet
 *
 * DESCRIPTION:
@@ -3050,7 +3072,8 @@
 MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber)
 {
 	MV_U32 i;
-
+	if (usbPortNumber >= mvCtrlUsbMaxGet())
+		return MV_FALSE;
 	/* Go over existing USB ports in board structures: test existence of requested USB Type/port */
 	for (i = 0; i < board->numBoardUsbInfo; i++)
 		if (board->pBoardUsbInfo[i].isActive && board->pBoardUsbInfo[i].usbType == usbTypeID &&
@@ -3085,3 +3108,40 @@
 
 	return board->numPicGpioInfo;
 }
+/*******************************************************************************
+* mvBoardIsTdmConnected
+*
+* DESCRIPTION:
+*       This routine returns MV_TRUE if TDM module is connected
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       MV_TRUE - TDM is connected
+*       MV_FALSE - otherwise.
+*
+*******************************************************************************/
+MV_BOOL mvBoardIsTdmConnected()
+{
+	/* TDM is not supported on a375 */
+	return MV_FALSE;
+}
+
+/*******************************************************************************
+* mvBoardIsUsb3PortDevice
+* DESCRIPTION: return true USB3 port is in device mode
+*
+* INPUT:  port		- port number
+* OUTPUT: None.
+* RETURN: MV_TRUE: if port is set to device mode
+*         MV_FALSE: otherwise
+*******************************************************************************/
+MV_BOOL mvBoardIsUsb3PortDevice(MV_U32 port)
+{
+	/* Since usb3 device is not supported on current board return false */
+	return MV_FALSE;
+}
diff --git a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.h b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.h
index 1f20e8a..e1739de 100644
--- a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.h
+++ b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvLib.h
@@ -493,6 +493,7 @@
 MV_STATUS mvBoardIsInternalSwitchConnectedToPort(MV_U32 ethPortNum);
 MV_STATUS mvBoardIsInternalSwitchConnected(void);
 MV_U32 mvBoardSwitchPortForceLinkGet(MV_U32 switchIdx);
+MV_STATUS mvBoardIsSwitchConnected(void);
 MV_BOOL mvBoardIsLvdsModuleConnected(void);
 MV_BOOL mvBoardIsLcdDviModuleConnected(void);
 MV_STATUS mvBoardTwsiMuxChannelSet(MV_U8 muxChNum);
@@ -520,6 +521,8 @@
 MV_NAND_IF_MODE mvBoardNandIfGet(void);
 MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber);
 MV_U8 mvBoardPICGpioGet(MV_U32 *picGpioMppInfo);
+MV_BOOL mvBoardIsTdmConnected(void);
+MV_BOOL mvBoardIsUsb3PortDevice(MV_U32 port);
 
 #ifdef __cplusplus
 }
diff --git a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvSpec.h b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvSpec.h
index b01b973..9494171 100644
--- a/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvSpec.h
+++ b/board/mv_ebu/a375/armada_375_family/boardEnv/mvBoardEnvSpec.h
@@ -148,7 +148,7 @@
 #define DB_88F6720_GPP_POL_MID		0x0
 #define DB_88F6720_GPP_POL_HIGH		0x0
 
-
+#define MV_TDM_OFFSET				(0xB0000)
 #endif  /* MV_ASMLANGUAGE */
 
 #endif  /* __INCmvBoardEnvSpech */
diff --git a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.c b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.c
index 0ca1cea..3484236 100644
--- a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.c
+++ b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.c
@@ -228,7 +228,30 @@
 
 	boardPexInfo->boardPexIfNum = pexIfNum;
 }
-
+/******************************************************************************
+* mvCtrlIsUsbSerDesConnected
+*
+* DESCRIPTION:detect usb3 port if connected to serdes.
+*       check if SerDes lane is connected to USB3 host
+*
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:return true if usb physical port is connected , false otherwise.
+*
+*
+*******************************************************************************/
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort)
+{
+        int usb3HostNum = mvCtrlUsb3HostMaxGet();
+        int maxSerDesLanes = mvCtrlUsb3MaxGet();
+        if (usbPort >= maxSerDesLanes && usb3HostNum > maxSerDesLanes){
+                return MV_FALSE;
+        }
+        return MV_TRUE;
+}
 
 MV_UNIT_ID mvCtrlSocUnitNums[MAX_UNITS_ID][MV_67xx_INDEX_MAX] = {
 /*                          6720 */
diff --git a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.h b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.h
index 5ad1090..1282dc0 100644
--- a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.h
+++ b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvLib.h
@@ -282,6 +282,7 @@
 MV_VOID mvCtrlSysConfigInit(MV_VOID);
 MV_U32 mvCtrlSysConfigGet(MV_CONFIG_TYPE_ID configField);
 MV_U32 mvCtrlGetCpuNum(MV_VOID);
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort);
 MV_U32 mvCtrlGetQuadNum(MV_VOID);
 MV_STATUS mvCtrlUpdatePexId(MV_VOID);
 MV_BOOL mvCtrlIsValidSatR(MV_VOID);
diff --git a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvSpec.h b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvSpec.h
index 5fbd31a..420deda 100644
--- a/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvSpec.h
+++ b/board/mv_ebu/a375/armada_375_family/ctrlEnv/mvCtrlEnvSpec.h
@@ -130,6 +130,8 @@
 #define MV_USB3_PHYS_OFFSET(dev)                (0x58000)
 #define MV_USB2_USB3_REGS_OFFSET(unitType, dev) (unitType == USB_UNIT_ID ? \
 							MV_USB_REGS_OFFSET(dev) : MV_USB3_PHYS_OFFSET(dev))
+#define MV_USB3_DEVICE_REGS_OFFSET		MV_USB_REGS_OFFSET(0)
+#define MV_USB3_DEVICE_USB2_REGS_OFFSET		(0x54100)
 #define MV_XOR_REGS_OFFSET(unit)                (0x60800)
 #define MV_CESA_TDMA_REGS_OFFSET(chanNum)       (0x90000 + (chanNum * 0x2000))
 #define MV_CESA_REGS_OFFSET(chanNum)            (0x9D000 + (chanNum * 0x2000))
diff --git a/board/mv_ebu/a375/mv_main_a375.c b/board/mv_ebu/a375/mv_main_a375.c
index b5f2a3e..3840113 100755
--- a/board/mv_ebu/a375/mv_main_a375.c
+++ b/board/mv_ebu/a375/mv_main_a375.c
@@ -294,7 +294,6 @@
 			*(unsigned int*)(CONFIG_SYS_TEXT_BASE + i);
 
 	mvBoardDebugLed(4);
-	mv_print_map();
 	return 0;
 }
 
@@ -311,7 +310,7 @@
 	env = getenv("mtdids");
 	if (!env) {
 #if defined(MV_NAND) && defined(MV_INCLUDE_SPI)
-		setenv("mtdids", "nand0=armada-nand;spi0=spi_flash");
+		setenv("mtdids", "nand0=armada-nand,spi0=spi_flash");
 #elif defined(MV_NAND)
 		setenv("mtdids", "nand0=armada-nand");
 #elif defined(MV_INCLUDE_SPI)
@@ -492,6 +491,12 @@
 	if (!env)
 		setenv("initrd_name", "uInitrd");
 
+#ifdef CONFIG_CMD_SOURCE
+	env = getenv("run_script");
+	if (!env)
+		setenv("run_script", "no");
+#endif
+
 	/* netbsd boot arguments */
 	env = getenv("netbsd_en");
 	if ( !env || ( ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0) )))
@@ -1024,6 +1029,7 @@
 #endif
 	/* init the units decode windows */
 	misc_init_r_dec_win();
+	mv_print_map();
 	memset((void*)CONFIG_SYS_LOAD_ADDR, 0, CONFIG_SYS_MIN_HDR_DEL_SIZE);
 	mvBoardDebugLed(6);
 
@@ -1044,7 +1050,12 @@
 #if defined(MV_INCLUDE_UNM_ETH) || defined(MV_INCLUDE_GIG_ETH)
 	mvBoardEgigaPhyInit();
 #endif
-
+#ifdef CONFIG_CMD_SOURCE
+	/* run saved script */
+	env = getenv("run_script");
+	if (env && strcmp(env, "yes") == 0)
+		run_command("mvsource run", 0);
+#endif
 	return 0;
 }
 
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 ddb356e..766ec4d 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c
@@ -214,6 +214,10 @@
 	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);
 }
 
 /*******************************************************************************
@@ -570,7 +574,10 @@
 	tclk = ((tclk & (1 << 15)) >> 15);
 	switch (tclk) {
 	case 0:
-		return MV_BOARD_TCLK_250MHZ;
+		if (mvCtrlModelGet() == MV_6811_DEV_ID)
+			return MV_BOARD_TCLK_166MHZ;	/* device 381/2 (6811/21) use 166MHz instead of 250MHz */
+		else
+			return MV_BOARD_TCLK_250MHZ;
 	case 1:
 		return MV_BOARD_TCLK_200MHZ;
 	default:
@@ -664,7 +671,7 @@
 
 	for (i = 0; i < board->numBoardGppInfo; i++) {
 		if (board->pBoardGppInfo[i].devClass == gppClass) {
-			if (indexFound == index)
+			if (indexFound == index && (MV_U32)board->pBoardGppInfo[i].gppPinNum != -1)
 				return (MV_U32)board->pBoardGppInfo[i].gppPinNum;
 			else
 				indexFound++;
@@ -725,6 +732,110 @@
 	return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
 }
 
+#ifdef MV_USB_VBUS_CYCLE
+/*******************************************************************************
+* mvBoardIoExpanderTypeGet
+*
+* DESCRIPTION:
+*	Return the Config type fields information for a given Config type class.
+*
+* INPUT:
+*	configClass - The Config type field to return the information for.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*	MV_BOARD_CONFIG_TYPE_INFO struct with mask, offset and register number.
+*
+*******************************************************************************/
+MV_STATUS mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_TYPE_ID ioClass,
+		MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo)
+{
+	MV_U32 i;
+
+	/* verify existence of requested config type, pull its data */
+	for (i = 0; i < board->numBoardIoExpPinInfo; i++)
+		if (board->pBoardIoExpPinInfo[i].ioFieldid == ioClass) {
+			*ioInfo = board->pBoardIoExpPinInfo[i];
+			return MV_OK;
+		}
+
+	DB(mvOsPrintf("%s: Error: requested IO expander ID was not found (%d)\n",
+			__func__, ioClass));
+	return MV_ERROR;
+}
+
+/*******************************************************************************
+* mvBoardIoExpValSet - write a specified value to IO Expanders
+*
+* DESCRIPTION:
+*       This function writes specified value to IO Expanders
+*
+* INPUT:
+*       ioInfo  - relevant IO Expander information
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       MV_U8  :return requested value , if TWSI read was succesfull, else 0xFF.
+*
+*******************************************************************************/
+MV_STATUS mvBoardIoExpValSet(MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo, MV_U8 value, MV_BOOL isOutput)
+{
+	MV_U8 readVal, configVal;
+
+	if (ioInfo == NULL) {
+		mvOsPrintf("%s: Error: Write to IO Expander failed (invalid Expander info)\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* Read direction (output/input) Value */
+	if (mvBoardTwsiGet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum,
+					ioInfo->regNum + 4, &configVal, 1) != MV_OK) {
+		mvOsPrintf("%s: Error: Read Configuration from IO Expander failed\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* Modify direction (output/input) value of requested pin */
+	if (isOutput)
+		configVal &= ~(1 << ioInfo->offset);	/* output marked as 0: clean bit of old value  */
+	else
+		configVal |= (1 << ioInfo->offset);	/* input marked as 1: set bit of old value  */
+	if (mvBoardTwsiSet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum,
+					ioInfo->regNum + 4, &configVal, 1) != MV_OK) {
+		mvOsPrintf("%s: Error: Enable Write to IO Expander at 0x%x failed\n", __func__
+			   , mvBoardTwsiAddrGet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum));
+		return MV_ERROR;
+	}
+
+	/* configure output value, only for output directed IO */
+	if (!isOutput)
+		return MV_OK;
+
+	/* Read Output Value */
+	if (mvBoardTwsiGet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum,
+					ioInfo->regNum, &readVal, 1) != MV_OK) {
+		mvOsPrintf("%s: Error: Read Output value from IO Expander failed\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* Modify */
+	readVal &= ~(1 << ioInfo->offset);	/* clean bit of old value  */
+	readVal |= (value << ioInfo->offset);
+
+	/* Write output value*/
+	if (mvBoardTwsiSet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum,
+					ioInfo->regNum, &readVal, 1) != MV_OK) {
+		mvOsPrintf("%s: Error: Write to IO Expander at 0x%x failed\n", __func__
+			   , mvBoardTwsiAddrGet(BOARD_TWSI_IO_EXPANDER, ioInfo->expanderNum));
+		return MV_ERROR;
+	}
+
+	return MV_OK;
+}
+
 /*******************************************************************************
 * mvBoardUSBVbusGpioPinGet - return Vbus input GPP
 *
@@ -746,26 +857,68 @@
 }
 
 /*******************************************************************************
-* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
+* mvUsbVbusGppSet - SET USB VBUS signal via GPIO
 *
 * DESCRIPTION:
-*
-* INPUT:
-*		int  devNo.
-*
-* OUTPUT:
-*		None.
-*
-* RETURN:
-*       GPIO pin number. The function return -1 for bad parameters.
-*
+** INPUT:	gppNo - gpp pin Number.
+** OUTPUT:	None.
+** RETURN:	None.
 *******************************************************************************/
-MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
+MV_VOID mvUsbVbusGppSet(int gppNo)
 {
-	return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
+	MV_U32 regVal;
+
+	/* MPP Control Register - set mpp as GPP (value = 0)*/
+	regVal = MV_REG_READ(mvCtrlMppRegGet((unsigned int)(gppNo / 8)));
+	regVal &= ~(0xf << ((gppNo % 8) * 4));
+	MV_REG_WRITE(mvCtrlMppRegGet((unsigned int)(gppNo / 8)), regVal);
+
+	if (gppNo < 32) {
+		/* GPIO Data Out Enable Control Register - set to output */
+		mvGppTypeSet(0, (1 << gppNo), MV_GPP_OUT & (1 << gppNo));
+		/* GPIO output Data Value Register - set as high */
+		mvGppValueSet(0, (1 << gppNo), (1 << gppNo));
+	} else {
+		/* GPIO Data Out Enable Control Register - set to output */
+		mvGppTypeSet(1, (1 << (gppNo - 32)), MV_GPP_OUT & (1 << (gppNo - 32)));
+		/* GPIO output Data Value Register - set as high */
+		mvGppValueSet(1, (1 << (gppNo - 32)), (1 << (gppNo - 32)));
+	}
 }
 
 /*******************************************************************************
+* mvBoardUsbVbusSet - Set USB VBUS signal before detection
+*
+* DESCRIPTION:
+* this routine sets VBUS signal via GPIO or via I2C IO expander
+*
+** INPUT:	int  dev - USB Host number
+** OUTPUT:	None.
+** RETURN:	None.
+*******************************************************************************/
+MV_VOID mvBoardUsbVbusSet(int dev)
+{
+	MV_32 gppNo = mvBoardUSBVbusGpioPinGet(dev);
+
+	/* Some of Marvell boards control VBUS signal via I2C IO expander unit */
+#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+	MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo;
+
+	/* if VBUS signal is Controlled via I2C IO Expander on board*/
+	if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_USB_VBUS, &ioInfo) != MV_ERROR) {
+		mvBoardIoExpValSet(&ioInfo, 1, MV_TRUE);
+		return;
+	}
+#endif
+
+	/* else if VBUS signal is Controlled via GPIO on board*/
+	if (gppNo != MV_ERROR)
+		mvUsbVbusGppSet(gppNo);
+
+}
+#endif /* MV_USB_VBUS_CYCLE */
+
+/*******************************************************************************
 * mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
 *
 * DESCRIPTION:
@@ -931,8 +1084,14 @@
 	bootSrc = mvBoardBootDeviceGroupSet();
 	if (MSAR_0_BOOT_NAND_NEW == bootSrc)
 		mvBoardModuleConfigSet(MV_MODULE_NAND_ON_BOARD);
-	else if (MSAR_0_BOOT_SDIO == bootSrc)
+	else if (MSAR_0_BOOT_SDIO == bootSrc) {
 		mvBoardModuleConfigSet(MV_MODULE_DB381_MMC_8BIT_ON_BOARD);
+		/* Enable NAND access if the SDIO is not using NAND MPPs.
+		   The SDIO MPPs overlap NAND ones in SDIO-8bit access mode,
+		   when boot attr2 == 40 */
+		if (mvBoardBootAttrGet(mvBoardBootDeviceGet(), 2) != 40)
+			mvBoardModuleConfigSet(MV_MODULE_NAND_ON_BOARD);
+	}
 }
 
 /*******************************************************************************
@@ -1009,8 +1168,7 @@
 	struct _mvBoardMppModule nandModule[6] = MPP_NAND_MODULE;
 	struct _mvBoardMppModule sdioModule[4] = MPP_SDIO_MODULE;
 	struct _mvBoardMppModule tdmModule[2] = MPP_TDM_MODULE;
-	struct _mvBoardMppModule i2sModule = MPP_I2S_MODULE;
-	struct _mvBoardMppModule spdifModule = MPP_SPDIF_MODULE;
+	struct _mvBoardMppModule audioModule = MPP_AUDIO_MODULE;
 	struct _mvBoardMppModule nandOnBoard[4] = MPP_NAND_ON_BOARD;
 	struct _mvBoardMppModule mini_pcie0_OnBoard = MPP_GP_MINI_PCIE0;
 	struct _mvBoardMppModule mini_pcie1_OnBoard = MPP_GP_MINI_PCIE1;
@@ -1038,17 +1196,20 @@
 		if (mvBoardIsModuleConnected(MV_MODULE_SDIO))
 			mvModuleMppUpdate(4, sdioModule);
 
+		/* Microsemi LE88266DLC (VE880 series) */
 		if (mvBoardIsModuleConnected(MV_MODULE_SLIC_TDM_DEVICE))
 			mvModuleMppUpdate(2, tdmModule);
 
-		if (mvBoardIsModuleConnected(MV_MODULE_I2S_DEVICE))
-			mvModuleMppUpdate(1, &i2sModule);
-
-		if (mvBoardIsModuleConnected(MV_MODULE_SPDIF_DEVICE))
-			mvModuleMppUpdate(1, &spdifModule);
+		if (mvBoardIsModuleConnected(MV_MODULE_I2S_DEVICE) ||
+				mvBoardIsModuleConnected(MV_MODULE_SPDIF_DEVICE))
+			mvModuleMppUpdate(1, &audioModule);
 
 		if (mvBoardIsModuleConnected(MV_MODULE_NAND_ON_BOARD))
 			mvModuleMppUpdate(4, nandOnBoard);
+
+		/* Sillab SI32261-F */
+		if (mvBoardIsTdmConnected() == MV_TRUE)
+			mvModuleMppUpdate(2, tdmModule);
 		break;
 	case DB_GP_68XX_ID:
 		miniPcie0_sata0_selector = mvBoardSatRRead(MV_SATR_GP_SERDES1_CFG); /* 0 = SATA0 , 1 = PCIe0 */
@@ -1281,7 +1442,7 @@
 }
 
 /*******************************************************************************
-* mvBoardIsInternalSwitchConnected
+* mvBoardIsSwitchConnected
 *
 * DESCRIPTION:
 *       This routine returns port's connection status
@@ -1296,9 +1457,12 @@
 *       1 - if ethPortNum is connected to switch, 0 otherwise
 *
 *******************************************************************************/
-MV_STATUS mvBoardIsInternalSwitchConnected(void)
+MV_STATUS mvBoardIsSwitchConnected(void)
 {
-	return MV_FALSE;
+	if ((board == ((MV_BOARD_INFO *)-1)) || (board->switchInfoNum == 0) || (board->pSwitchInfo == NULL))
+		return MV_FALSE;
+
+	return board->pSwitchInfo[0].isEnabled;
 }
 
 /*******************************************************************************
@@ -1402,10 +1566,11 @@
 *******************************************************************************/
 MV_BOOL mvBoardIsGbEPortConnected(MV_U32 ethPortNum)
 {
-	/* port is connected, if it's identified as R/SGMII, and has a valid corresponding MAC info entry */
+	/* port is connected, if it's enabled, identified as R/SGMII, and has a valid corresponding MAC info entry */
 
 
 	if ((ethPortNum <= board->numBoardMacInfo) &&
+		(board->pBoardMacInfo[ethPortNum].boardMacEnabled == MV_TRUE) &&
 		((mvCtrlPortIsSerdesSgmii(ethPortNum) ||
 		(mvCtrlPortIsRgmii(ethPortNum) && mvBoardPhyAddrGet(ethPortNum) != -1)) ||
 		(mvCtrlPortIsSerdesRxaui(ethPortNum) && mvBoardPhyAddrGet(ethPortNum) != -1)))
@@ -2075,6 +2240,8 @@
 		gBoardId = CUSTOMER_BOARD_ID0;
 	#elif CONFIG_CUSTOMER_BOARD_1
 		gBoardId = CUSTOMER_BOARD_ID1;
+	#elif CONFIG_CLEARFOG_BOARD
+		gBoardId = A38X_CLEARFOG_BOARD_ID;
 	#elif CONFIG_GFCH100
 		gBoardId = GFCH100_ID;
 	#endif
@@ -2325,7 +2492,10 @@
 *******************************************************************************/
 MV_32 mvBoardSmiScanModeGet(MV_U32 switchIdx)
 {
-	return BOARD_ETH_SWITCH_SMI_SCAN_MODE;
+	if (!mvBoardIsSwitchConnected())
+		return -1;
+
+	return board->pSwitchInfo[switchIdx].smiScanMode;
 }
 
 /*******************************************************************************
@@ -2346,7 +2516,119 @@
 *******************************************************************************/
 MV_U32 mvBoardSwitchCpuPortGet(MV_U32 switchIdx)
 {
-	return -1;
+	if (!mvBoardIsSwitchConnected())
+		return -1;
+
+	return board->pSwitchInfo[switchIdx].cpuPort;
+}
+
+/*******************************************************************************
+* mvBoardSwitchIsRgmii - Check if the Switch connected to RGMII port
+*
+* DESCRIPTION:
+*       This routine returns if the switch connected to RGMII port
+*
+* INPUT:
+*       switchIdx - index of the switch. Only 0 is supported.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       Status of switch type
+*
+*******************************************************************************/
+MV_BOOL mvBoardSwitchCpuPortIsRgmii(MV_U32 switchIdx)
+{
+	if (!mvBoardIsSwitchConnected())
+		return MV_FALSE;
+
+	return board->pSwitchInfo[switchIdx].isCpuPortRgmii;
+}
+
+/*******************************************************************************
+* mvBoardSwitchPhyAddrGet - Get the the Ethernet Switch PHY address
+*
+* DESCRIPTION:
+*	This routine returns the Switch PHY address, -1 else.
+*
+* INPUT:
+*	switchIdx - index of the switch. Only 0 is supported.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	the Switch PHY address, -1 if the switch is not connected.
+*
+*******************************************************************************/
+MV_32 mvBoardSwitchPhyAddrGet(MV_U32 switchIdx)
+{
+	if (!mvBoardIsSwitchConnected())
+		return -1;
+
+	return board->pSwitchInfo[switchIdx].quadPhyAddr;
+}
+
+/*******************************************************************************
+* mvBoardSwitchConnectedPortGet -
+*
+* DESCRIPTION:
+*       This routine returns the switch port connected to the ethPort
+*
+* INPUT:
+*       ethPortNum - Ethernet port number.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*
+*******************************************************************************/
+MV_32 mvBoardSwitchConnectedPortGet(MV_U32 ethPort)
+{
+	if (!mvBoardIsSwitchConnected())
+		return -1;
+
+	return board->pSwitchInfo[0].connectedPort[ethPort];
+}
+
+/*******************************************************************************
+* mvBoardModuleSwitchInfoUpdate - Update Board information switch module structures
+*
+* DESCRIPTION:
+*	Update board information switch module structures according to switch detection
+*
+* INPUT:
+*	switchDetected - switch module is detected or not
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*	None.
+*
+*******************************************************************************/
+MV_VOID mvBoardModuleSwitchInfoUpdate(MV_BOOL switchDetected)
+{
+	int i = 0;
+
+	if ((board == ((MV_BOARD_INFO *)-1))) {
+		mvOsPrintf("%s %d:Board unknown.\n", __func__, __LINE__);
+		return;
+	}
+
+	if (switchDetected) {
+		for (i = 0; i < board->switchInfoNum; i++)
+			if (board->pSwitchInfo != NULL)
+				board->pSwitchInfo[i].isEnabled = MV_TRUE;
+	} else {
+		for (i = 0; i < board->switchInfoNum; i++)
+			if (board->pSwitchInfo != NULL)
+				board->pSwitchInfo[i].isEnabled = MV_FALSE;
+
+		board->switchInfoNum = 0;
+	}
 }
 
 /*******************************************************************************
@@ -3384,8 +3666,49 @@
 		return board->nandIfMode;
 	}
 }
+/*******************************************************************************
+* mvBoardIsTdmConnected
+*
+* DESCRIPTION:
+*       This routine returns MV_TRUE if TDM module is connected
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       MV_TRUE - TDM is connected
+*       MV_FALSE - otherwise.
+*
+*******************************************************************************/
+MV_BOOL mvBoardIsTdmConnected()
+{
+	return board->isTdmConnected;
+}
 
 /*******************************************************************************
+* mvBoardTdmConnectionSet
+*
+* DESCRIPTION:
+*       This routine sets if TDM module is connected or not.
+*
+* INPUT:
+*	isConnected - indicated if TDM module is connected.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       None.
+*
+*******************************************************************************/
+void mvBoardTdmConnectionSet(MV_BOOL isConnected)
+{
+	board->isTdmConnected = isConnected;
+}
+/*******************************************************************************
 * mvBoardisSdioConnected
 * DESCRIPTION: return true if SDIO connected on board
 *
@@ -3452,3 +3775,45 @@
 
 	return MV_FALSE;
 }
+/*******************************************************************************
+* mvBoardAudioConnectionGet
+*
+* DESCRIPTION:
+*       This routine returns MV_TRUE if SPDIF/I2S is connected
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       MV_TRUE - SPDIF/I2S is connected
+*       MV_FALSE - otherwise.
+*
+*******************************************************************************/
+MV_BOOL mvBoardIsAudioConnected()
+{
+	return board->isAudioConnected;
+}
+
+/*******************************************************************************
+* mvBoardAudioConnectionSet
+*
+* DESCRIPTION:
+*       This routine sets if SPDIF/I2S module is connected or not.
+*
+* INPUT:
+*	isConnected - indicated if SPDIF/I2S is connected.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       None.
+*
+*******************************************************************************/
+void mvBoardAudioConnectionSet(MV_BOOL isConnected)
+{
+	board->isAudioConnected = isConnected;
+}
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.h b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.h
index 68ed322..9225f33 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.h
@@ -175,10 +175,11 @@
 	MV_MODULE_SDIO				= BIT6,	/* SDIO board SLM 1361	*/
 	MV_MODULE_SGMII				= BIT7,	/* SGMII board SLM 1364	*/
 	MV_MODULE_DB381_SGMII			= BIT8,	/* DB-381 SGMII SLM 1426 */
-	MV_MODULE_NAND_ON_BOARD			= BIT9,	/* ON board nand - detected via S@R bootsrc */
-	MV_MODULE_DB381_MMC_8BIT_ON_BOARD	= BIT10,/* ON board MMC 8bit - detected via S@R bootsrc */
-	MV_MODULE_TYPE_MAX_MODULE		= 9,
-	MV_MODULE_TYPE_MAX_OPTION		= 10
+	MV_MODULE_SWITCH			= BIT9,/* SWITCH board SLM 1375	*/
+	MV_MODULE_NAND_ON_BOARD			= BIT10,	/* ON board nand - detected via S@R bootsrc */
+	MV_MODULE_DB381_MMC_8BIT_ON_BOARD	= BIT11,/* ON board MMC 8bit - detected via S@R bootsrc */
+	MV_MODULE_TYPE_MAX_MODULE		= 10,
+	MV_MODULE_TYPE_MAX_OPTION		= 11
 } MV_MODULE_TYPE_ID;
 
 typedef struct _devCsInfo {
@@ -191,6 +192,18 @@
 	MV_BOOL active;
 } MV_DEV_CS_INFO;
 
+struct MV_BOARD_SWITCH_INFO {
+	MV_BOOL isEnabled;
+	MV_BOOL isCpuPortRgmii;
+	MV_32 switchIrq;
+	MV_32 switchPort[BOARD_ETH_SWITCH_PORT_NUM];
+	MV_32 cpuPort;
+	MV_32 connectedPort[MV_ETH_MAX_PORTS];
+	MV_32 smiScanMode;
+	MV_32 quadPhyAddr;
+	MV_U32 forceLinkMask; /* Bitmask of switch ports to have force link (1Gbps) */
+};
+
 typedef enum _SatRstatus {
 	SATR_READ_ONLY = 0x01,
 	SATR_SWAP_BIT  = 0x02,
@@ -207,6 +220,18 @@
 	MV_U8 gppPinNum;
 } MV_BOARD_GPP_INFO;
 
+typedef enum _mvIoExpanderTypeID {
+	MV_IO_EXPANDER_USB_VBUS,
+	MV_IO_EXPANDER_MAX_OPTION
+} MV_IO_EXPANDER_TYPE_ID;
+
+typedef struct _boardIoExapnderTypesInfo {
+	MV_IO_EXPANDER_TYPE_ID ioFieldid;
+	MV_U32 offset;
+	MV_U32 expanderNum;
+	MV_U32 regNum;
+} MV_BOARD_IO_EXPANDER_TYPE_INFO;
+
 typedef struct _boardTwsiInfo {
 	MV_BOARD_TWSI_CLASS devClass;
 	MV_U8 devClassId;
@@ -324,6 +349,9 @@
 	MV_BOARD_MAC_INFO *pBoardMacInfo;
 	MV_U8 numBoardGppInfo;
 	MV_BOARD_GPP_INFO *pBoardGppInfo;
+	MV_U8 numBoardIoExpPinInfo;
+	MV_BOARD_IO_EXPANDER_TYPE_INFO *pBoardIoExpPinInfo;
+
 	MV_U8 activeLedsNumber;
 	MV_U8 *pLedGppPin;
 	MV_U8 ledsPolarity;     /* '0' or '1' to turn on led */
@@ -340,6 +368,7 @@
 	MV_U32 gppPolarityValLow;
 	MV_U32 gppPolarityValMid;
 	MV_U32 gppPolarityValHigh;
+	MV_VOID (*gppPostConfigCallBack) (struct _boardInfo *);
 
 	MV_BOARD_USB_INFO *pBoardUsbInfo;	/* usb2.0 and usb3.0 physical port mapping on board */
 	MV_U8 numBoardUsbInfo;
@@ -386,6 +415,12 @@
 	MV_U32	numIoExp;
 	struct MV_BOARD_IO_EXPANDER *pIoExp;
 	MV_U32  boardOptionsModule;
+	MV_BOOL isAmc;			/* AMC active: used for DT update & switching services */
+	MV_BOOL isAudioConnected;	/* indicates if SPDIF/I2S is connected */
+	MV_BOOL isTdmConnected;		/* indicates if TDM module is connected */
+	/* External Switch Configuration */
+	struct MV_BOARD_SWITCH_INFO *pSwitchInfo;
+	MV_U32 switchInfoNum;
 } MV_BOARD_INFO;
 
 struct _mvBoardMppModule {
@@ -395,9 +430,8 @@
 
 
 #define MPP_MII_MODULE		{ {0, 0x10111111}, {1, 0x11111111}, {2, 0x11211111} }
-#define MPP_TDM_MODULE		{ {6, 0x45333333}, {7, 0x00004444} }
-#define MPP_I2S_MODULE		{6, 0x55544554}
-#define MPP_SPDIF_MODULE	{6, 0x55444444}
+#define MPP_TDM_MODULE		{ {6, 0x55333333}, {7, 0x00004444} }
+#define MPP_AUDIO_MODULE	{6, 0x55444444}
 #define MPP_NOR_MODULE		{ {0, 0x55111111}, {1, 0x15555555}, {2, 0x55566011}, \
 				  {3, 0x55555055}, {4, 0x55555555}, {5, 0x40045525 } }
 #define MPP_NAND_MODULE		{ {0, 0x55111111}, {1, 0x15555555}, {2, 0x55266011}, \
@@ -436,6 +470,11 @@
 #define MSAR_0_SPI0                             0
 #define MSAR_0_SPI1                             1
 
+/* definition for switch device scan mode */
+#define MV_SWITCH_SMI_AUTO_SCAN_MODE         0    /* Scan 0 or 0x10 base address to find the QD */
+#define MV_SWITCH_SMI_MANUAL_MODE            1    /* Use QD located at manually defined base addr */
+#define MV_SWITCH_SMI_MULTI_ADDR_MODE        2    /* Use QD at base addr and use indirect access */
+
 MV_VOID mvBoardEnvInit(MV_VOID);
 MV_U16 mvBoardModelGet(MV_VOID);
 MV_U32 mvBoardRevGet(MV_VOID);
@@ -466,8 +505,11 @@
 MV_VOID mvBoardReset(MV_VOID);
 MV_BOARD_PEX_INFO *mvBoardPexInfoGet(void);
 MV_32 mvBoardResetGpioPinGet(MV_VOID);
+#ifdef MV_USB_VBUS_CYCLE
 MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId);
-MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId);
+MV_STATUS mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_TYPE_ID ioClass, MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo);
+MV_VOID mvBoardUsbVbusSet(int dev);
+#endif
 MV_BOOL mvBoardIsOurPciSlot(MV_U32 busNum, MV_U32 slotNum);
 MV_U32 mvBoardGpioIntMaskGet(MV_U32 gppGrp);
 MV_U32 mvBoardSlicUnitTypeGet(MV_VOID);
@@ -509,7 +551,7 @@
 MV_STATUS mvBoardTwsiSet(MV_BOARD_TWSI_CLASS twsiClass, MV_U8 devNum, MV_U8 regNum, MV_U8 *regVal, MV_U32 len);
 MV_U8 mvBoardCpuFreqGet(MV_VOID);
 MV_STATUS mvBoardCpuFreqSet(MV_U8 freqVal);
-MV_STATUS mvBoardIsInternalSwitchConnected(void);
+MV_STATUS mvBoardIsSwitchConnected(void);
 MV_U32 mvBoardSwitchPortForceLinkGet(MV_U32 switchIdx);
 MV_U32 mvBoardFreqModesNumGet(void);
 MV_32 mvBoardSmiScanModeGet(MV_U32 switchIdx);
@@ -517,6 +559,10 @@
 MV_VOID mvBoardMacSpeedSet(MV_U32 ethPortNum, MV_BOARD_MAC_SPEED speed);
 MV_VOID mvBoardMacSpeedSet(MV_U32 ethPortNum, MV_BOARD_MAC_SPEED macSpeed);
 MV_U32 mvBoardSwitchCpuPortGet(MV_U32 switchIdx);
+MV_32 mvBoardSwitchPhyAddrGet(MV_U32 switchIdx);
+MV_32 mvBoardSwitchConnectedPortGet(MV_U32 ethPort);
+MV_BOOL mvBoardSwitchCpuPortIsRgmii(MV_U32 switchIdx);
+MV_VOID mvBoardModuleSwitchInfoUpdate(MV_BOOL switchDetected);
 MV_U32 mvBoardMacCpuPortGet(MV_VOID);
 MV_BOOL mvBoardIsEthConnected(MV_U32 ethNum);
 MV_BOOL mvBoardIsEthActive(MV_U32 ethNum);
@@ -569,11 +615,20 @@
 MV_STATUS mvBoardSysConfigSet(MV_CONFIG_TYPE_ID configField, MV_U8 value);
 void mvBoardEepromValidSet(void);
 #endif /* CONFIG_CMD_BOARDCFG */
+MV_BOOL mvBoardIsTdmConnected(void);
+void mvBoardTdmConnectionSet(MV_BOOL isConnected);
 MV_NAND_IF_MODE mvBoardNandIfGet(void);
 MV_BOOL mvBoardisSdioConnected(void);
 MV_VOID mvBoardSdioConnectionSet(MV_BOOL status);
 MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber);
 MV_BOARD_INFO *mvBoardInfoStructureGet(MV_VOID);
+MV_BOOL mvBoardIsAudioConnected(void);
+void mvBoardAudioConnectionSet(MV_BOOL isConnected);
+MV_BOOL mvBoardIsUsb3PortDevice(MV_U32 port);
+
+#ifdef CONFIG_SWITCHING_SERVICES
+MV_BOOL mvBoardisAmc(void);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.c b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.c
index fb27751..4c2ed94 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.c
@@ -99,6 +99,56 @@
 	return MV_PORT_TYPE_UNKNOWN;
 }
 
+#ifdef CONFIG_SWITCHING_SERVICES
+/*******************************************************************************
+* mvBoardisAmc
+* DESCRIPTION: return true if board is AMC
+*
+* INPUT:  None
+* OUTPUT: None.
+* RETURN: MV_TRUE: if board is AMC
+*         MV_FALSE: else
+*******************************************************************************/
+MV_BOOL mvBoardisAmc(void)
+{
+	MV_BOARD_INFO *board = mvBoardInfoStructureGet();
+	if (board)
+		return board->isAmc;
+
+	DB(mvOsPrintf("%s: Error: board structure not initialized\n", __func__));
+	return MV_FALSE;
+}
+#endif
+
+/*******************************************************************************
+* mvBoardIsUsb3PortDevice
+* DESCRIPTION: return true USB3 port is in device mode
+*
+* INPUT:  port		- port number
+* OUTPUT: None.
+* RETURN: MV_TRUE: if port is set to device mode
+*         MV_FALSE: otherwise
+*******************************************************************************/
+MV_BOOL mvBoardIsUsb3PortDevice(MV_U32 port)
+{
+	MV_U32 boardId, satrReadResult;
+
+	if (port < 0 || port >= MV_USB3_MAX_HOST_PORTS)
+		return MV_FALSE;
+
+	boardId = mvBoardIdGet();
+	/* since 'usb3port0' and 'usb3port1' are only supported on
+	 * DB-BP and DB-6821-BP, return MV_FALSE if we are not on these boards */
+	if (!(boardId == DB_68XX_ID || boardId == DB_BP_6821_ID))
+		return MV_FALSE;
+
+	satrReadResult = mvBoardSatRRead((MV_U32)MV_SATR_DB_USB3_PORT0 + port);
+	if (satrReadResult != MV_ERROR && satrReadResult)
+		return MV_TRUE;
+
+	return MV_FALSE;
+}
+
 /*******************************************************************************
 * mvBoardIsPortInSgmii -
 *
@@ -328,8 +378,6 @@
 
 		if ((mvBoardIsModuleConnected(MV_MODULE_DB381_MMC_8BIT_ON_BOARD)))
 			mvBoardSdioConnectionSet(MV_TRUE);
-		else
-			mvBoardSdioConnectionSet(MV_FALSE);
 
 		mvBoardIoExpanderUpdate();
 		mvBoardPcieModulesInfoUpdate();	/* if PCIe modules are configured (via 'SatR') */
@@ -353,6 +401,25 @@
 		if ((mvBoardIsModuleConnected(MV_MODULE_MII)))	/* MII Module uses different PHY address */
 			mvBoardPhyAddrSet(0, 8);	/*set SMI address 8 for port 0*/
 
+		if (mvBoardIsModuleConnected(MV_MODULE_SPDIF_DEVICE) ||
+				mvBoardIsModuleConnected(MV_MODULE_I2S_DEVICE)) {
+			/* TDM, Audio and Sdio have mpp's conflict
+			 * --> disable Sdio and TDM when SPDIF is connected */
+			mvBoardAudioConnectionSet(MV_TRUE);
+			mvBoardSdioConnectionSet(MV_FALSE);
+			mvBoardTdmConnectionSet(MV_FALSE);
+		} else if (mvBoardSatRRead(MV_SATR_TDM_CONNECTED) == 0) {
+			/* if Audio modules detected, skip reading TDM from SatR */
+
+			/* TDM, Audio and Sdio have mpp's conflict
+			 * --> disable Audio and Sdio when TDM is connected */
+			mvBoardTdmConnectionSet(MV_TRUE);
+			mvBoardAudioConnectionSet(MV_FALSE);
+			mvBoardSdioConnectionSet(MV_FALSE);
+			/* update DT: used for Linux only */
+			mvBoardSetDevState(1, BOARD_DEV_SPI_FLASH, MV_TRUE);
+		}
+
 		/* Update MPP group types and values according to board configuration */
 		mvBoardMppIdUpdate();
 		/* board on test mode  */
@@ -366,6 +433,8 @@
 
 		mvBoardPcieModulesInfoUpdate();	/* if PCIe modules are configured (via 'SatR') */
 		mvBoardFlashDeviceUpdate();
+		mvBoardModuleSwitchInfoUpdate(mvBoardIsModuleConnected(MV_MODULE_SWITCH));
+		mvBoardIoExpanderUpdate();
 		break;
 	case DB_AMC_6820_ID:
 		/* nothing to be updated at run-time for AMC board */
@@ -425,12 +494,13 @@
 		"SDIO 4bit",                                 \
 		"SGMII",                                 \
 		"DB-381 SLM-1426 (SGMII-2)",                        \
+		"SWITCH",			\
 	};
 	mvOsOutput("Board configuration detected:\n");
 
 	for (i = 0; i < MV_MODULE_TYPE_MAX_MODULE; i++) {
 		if (mvBoardIsModuleConnected(1 << i))
 			mvOsOutput("       %s module.\n", moduleStr[i]);
-
 	}
 }
+
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.h b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.h
index f22067b..ab8b420 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib38x.h
@@ -79,6 +79,7 @@
 	MV_BOARD_MAC_SPEED boardMacSpeed;
 	MV_32 boardEthSmiAddr;
 	MV_32 boardEthSmiAddr0;
+	MV_BOOL boardMacEnabled;
 } MV_BOARD_MAC_INFO;
 
 enum {
@@ -99,6 +100,7 @@
 { MV_MODULE_SDIO,		0x4,	0,	 0x2,	{ 0, 1, 0, 0, 0, 0, 0} }, \
 { MV_MODULE_SGMII,		0x2,	0,	 0xF,	{ 0, 1, 0, 0, 0, 0, 0} }, \
 { MV_MODULE_DB381_SGMII,	0x0,	0,	 0x2,	{ 0, 0, 0, 0, 0, 1, 0} }, \
+{ MV_MODULE_SWITCH,		0x5,	0,	 0xE,	{ 0, 1, 0, 0, 0, 0, 0} }, \
 };
 
 typedef enum _mvSatRTypeID {
@@ -128,6 +130,11 @@
 	MV_SATR_DEVICE_ID2,
 	MV_SATR_GP_SERDES1_CFG,
 	MV_SATR_GP_SERDES2_CFG,
+	MV_SATR_FULL_FLAVOR,
+	MV_SATR_TDM_CONNECTED,
+	MV_SATR_TDM_PLACE_HOLDER,
+	MV_SATR_BOARD_SPEED,
+	MV_SATR_AVS_SKIP,
 	MV_SATR_MAX_OPTION,
 } MV_SATR_TYPE_ID;
 
@@ -142,7 +149,7 @@
 {"ddrbuswidth",	MV_SATR_DDR_BUS_WIDTH,		0x08,	3,	0,	0,	{1, 1, 1, 1, 1, 0, 1}, 0},\
 {"ddreccenable",	MV_SATR_DDR_ECC_ENABLE,	0x10,	4,	0,	0,	{1, 1, 1, 1, 1, 1, 1}, 0},\
 {"ddreccpupselect",	MV_SATR_DDR_ECC_PUP_SEL, 0x20,	5,	0,	0,	{0, 1, 0, 0, 0, 0, 1}, 0},\
-{"sgmiispeed", MV_SATR_SGMII_SPEED,		0x40,	6,	0,	0,	{1, 1, 1, 1, 1, 1, 1}, 0},\
+{"sgmiispeed", MV_SATR_SGMII_SPEED,		0x40,	6,	0,	0,	{1, 1, 1, 1, 1, 1, 0}, 0},\
 {"bootsrc",	MV_SATR_BOOT_DEVICE,		0x3,	0,	3,	0,	{0, 1, 0, 0, 0, 1, 0}, SATR_SWAP_BIT},\
 {"boarsrc2",	MV_SATR_BOOT2_DEVICE,		0x1E,	1,	2,	0,	{0, 1, 0, 0, 0, 1, 0}, SATR_SWAP_BIT},\
 {"boardid",	MV_SATR_BOARD_ID,		0x7,	0,	0,	0,	{1, 1, 1, 1, 1, 1, 1}, 0},\
@@ -158,8 +165,16 @@
 {"sgmiimode",	MV_SATR_SGMII_MODE,		0x40,	6,	0,	1,	{0, 1, 0, 0, 1, 1, 1}, 0},\
 {"devid",	MV_SATR_DEVICE_ID,		0x1,	0,	2,	0,	{0, 1, 0, 0, 0, 0, 0}, 0},\
 {"devid2",	MV_SATR_DEVICE_ID2,		0x10,	4,	3,	0,	{0, 1, 0, 0, 0, 0, 0}, 0},\
+{"flavor",	MV_SATR_FULL_FLAVOR,		0x10,	4,	0,	2,	{0, 1, 0, 1, 1, 1, 0}, 0},\
+{"tdm",		MV_SATR_TDM_CONNECTED,		0x20,	5,	0,	2,	{0, 1, 0, 0, 0, 0, 0}, 0},\
+{"tdmplaceholder",	MV_SATR_TDM_PLACE_HOLDER,	0x40,	6,	0,	2,	{0, 0, 0, 0, 0, 0, 0}, 0},\
+{"avsskip",	MV_SATR_AVS_SKIP,		0x80,	7,	0,	2,	{0, 1, 0, 1, 1, 1, 1}, 0},\
+{"boardspeed",	MV_SATR_BOARD_SPEED,		0x3,	0,	0,	3,	{0, 1, 0, 1, 1, 0, 1}, SATR_READ_ONLY},\
 {"max_option",	MV_SATR_MAX_OPTION,		0x0,	0,	0,	0,	{0, 0, 0, 0, 0, 0, 0}, 0},\
 };
+/* tdm place holder is used for future support for multiple tdm devices */
+/* avsskip is used to skip selecting AVS from EFUSE:
+ *	- used in binary header by Marvell boards only*/
 
 /* extra SAR table, for different board implementations:
  * in case a field is used on 2 boards with different i2c mapping */
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.c b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.c
index 1928edf..7de1ac1 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.c
@@ -625,3 +625,18 @@
 			mvOsOutput("|     In-Band  |\n");
 	}
 }
+
+/*******************************************************************************
+* mvBoardIsUsb3PortDevice
+* DESCRIPTION: return true USB3 port is in device mode
+*
+* INPUT:  port		- port number
+* OUTPUT: None.
+* RETURN: MV_TRUE: if port is set to device mode
+*         MV_FALSE: otherwise
+*******************************************************************************/
+MV_BOOL mvBoardIsUsb3PortDevice(MV_U32 port)
+{
+	/* Since usb3 device is not supported on current board return false */
+	return MV_FALSE;
+}
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.h b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.h
index 12d43ef..a5a2b90 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib39x.h
@@ -88,6 +88,7 @@
 	MV_32 boardEthSmiAddr;
 	MV_32 boardEthSmiAddr0;
 	MV_PHY_NEGOTIATION_PORT_TYPE negType;
+	MV_BOOL boardMacEnabled;
 } MV_BOARD_MAC_INFO;
 
 typedef enum {
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 45de9b4..a6920a5 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec.h
@@ -83,8 +83,9 @@
 #define A38X_CUTOMER_BOARD_ID_BASE		0x0
 #define A38X_CUSTOMER_BOARD_ID0			(A38X_CUTOMER_BOARD_ID_BASE + 0)
 #define A38X_CUSTOMER_BOARD_ID1			(A38X_CUTOMER_BOARD_ID_BASE + 1)
-#define A38X_GFCH100_ID				(A38X_CUTOMER_BOARD_ID_BASE + 2)
-#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUTOMER_BOARD_ID_BASE + 3)
+#define A38X_CLEARFOG_BOARD_ID			(A38X_CUTOMER_BOARD_ID_BASE + 2)
+#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 fc534f7..a5e1e4d 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c
@@ -66,6 +66,7 @@
 #include "boardEnv/mvBoardEnvSpec.h"
 #include "twsi/mvTwsi.h"
 #include "pex/mvPexRegs.h"
+#include "gpp/mvGppRegs.h"
 
 /***************************************** Customer Boards *****************************************/
 /*******************************************************************************
@@ -81,15 +82,17 @@
 
 MV_BOARD_TWSI_INFO armada_38x_customer_0_BoardTwsiDev[] = {
 	/* {{MV_BOARD_DEV_CLASS devClass, MV_U8 devClassId,  MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
-	{ BOARD_DEV_TWSI_SATR,	0,	0x57, ADDR7_BIT, MV_TRUE},  /* read only for HW configuration */
-	{ BOARD_DEV_TWSI_SATR,	1,	0x4C, ADDR7_BIT, MV_FALSE},
-	{ BOARD_TWSI_IO_EXPANDER,	0,	0x20, ADDR7_BIT, MV_FALSE},
-	{ BOARD_TWSI_IO_EXPANDER,	1,	0x21, ADDR7_BIT, MV_FALSE},
+	{ BOARD_DEV_TWSI_SATR,		0,	0x57,	ADDR7_BIT, MV_TRUE},  /* read only for HW configuration */
+	{ BOARD_DEV_TWSI_SATR,		1,	0x4C,	ADDR7_BIT, MV_FALSE},
+	{ BOARD_TWSI_IO_EXPANDER,	0,	0x21,	ADDR7_BIT, MV_FALSE},
 };
+
 MV_BOARD_MAC_INFO armada_38x_customer_0_BoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_FALSE},
 };
 
 MV_DEV_CS_INFO armada_38x_customer_0_BoardDeCsInfo[] = {
@@ -123,16 +126,32 @@
 };
 
 struct MV_BOARD_IO_EXPANDER armada_38x_customer_0_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 */
+	{0, 6, 0xFF}, /* Config reg#0: all bits as input (BIT on = Input) */
+	{0, 7, 0xFC}, /* Config reg#1: BIT0(USB3.0 current limit), BIT1(USB3.1 current limit)*/
+	{0, 2, 0xFF}, /* Output Data, reg#0  - no output bits*/
+	{0, 3, 0xFF}, /* Output Data, reg#1:  BIT0,USB3.0_CURRENT=1, BIT1,USB3.1_CURRENT=1 */
 };
 
+MV_BOARD_GPP_INFO armada_38x_customer_0_GppInfo[] = {
+	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */
+/* USB_Host0 */ /* {BOARD_GPP_USB_VBUS,    44}, */ /* from MPP map */
+};
+
+MV_BOARD_USB_INFO armada_38x_customer_0_InfoBoardUsbInfo[] = {
+/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOLEAN isActive} */
+	{ USB3_UNIT_ID, 0, MV_TRUE},
+	{ USB3_UNIT_ID, 1, MV_TRUE},
+	{ USB_UNIT_ID, 0, MV_TRUE},
+};
+
+/* gpp_callback is a generic place holder routine for special GPIO pull-up/sown sequence
+ * this routine is called as the final step of mvBoardEnvInit flow
+ * for example see implementation for SolidRun's clearFog board: A38x_CLEARFOG_BOARD_gpp_callback*/
+void A38x_CUSTOMER_BOARD_0_gpp_callback(MV_BOARD_INFO *board) {
+
+	/* implement special GPIO/MPP post configuration here */
+}
+
 MV_BOARD_INFO armada_38x_customer_board_0_info = {
 	.boardName			= "A38x-Customer-Board-0",
 	.numBoardNetComplexValue		= 0,
@@ -147,8 +166,10 @@
 	.pBoardTwsiDev			= armada_38x_customer_0_BoardTwsiDev,
 	.numBoardMacInfo		= ARRSZ(armada_38x_customer_0_BoardMacInfo),
 	.pBoardMacInfo			= armada_38x_customer_0_BoardMacInfo,
-	.numBoardGppInfo		= 0,
-	.pBoardGppInfo			= 0,
+	.numBoardGppInfo		= ARRSZ(armada_38x_customer_0_GppInfo),
+	.pBoardGppInfo			= armada_38x_customer_0_GppInfo,
+	.numBoardIoExpPinInfo		= 0,
+	.pBoardIoExpPinInfo		= 0,
 	.activeLedsNumber		= 0,
 	.pLedGppPin			= NULL,
 	.ledsPolarity			= 0,
@@ -164,12 +185,16 @@
 	.gppOutValMid			= A38x_CUSTOMER_BOARD_0_GPP_OUT_VAL_MID,
 	.gppPolarityValLow		= A38x_CUSTOMER_BOARD_0_GPP_POL_LOW,
 	.gppPolarityValMid		= A38x_CUSTOMER_BOARD_0_GPP_POL_MID,
+	.gppPostConfigCallBack		= A38x_CUSTOMER_BOARD_0_gpp_callback,
 
 	/* TDM */
 	.numBoardTdmInfo		= {},
 	.pBoardTdmInt2CsInfo		= {},
 	.boardTdmInfoIndex		= -1,
 
+	.pBoardUsbInfo                  = armada_38x_customer_0_InfoBoardUsbInfo,
+	.numBoardUsbInfo                = ARRSZ(armada_38x_customer_0_InfoBoardUsbInfo),
+
 	.pBoardSpecInit			= NULL,
 
 	/* NAND init params */
@@ -187,7 +212,10 @@
 	.configAutoDetect		= MV_FALSE,
 	.numIoExp			= ARRSZ(armada_38x_customer_0_IoExpanderInfo),
 	.pIoExp				= armada_38x_customer_0_IoExpanderInfo,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 /*******************************************************************************
@@ -202,10 +230,11 @@
 	{ BOARD_TWSI_IO_EXPANDER,	1,	0x21, ADDR7_BIT, MV_FALSE},
 };
 MV_BOARD_MAC_INFO armada_38x_customer_1_BoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO,  -1,  -1}
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO,  -1,  -1, MV_TRUE}
 };
 
 MV_DEV_CS_INFO armada_38x_customer_1_BoardDeCsInfo[] = {
@@ -249,6 +278,24 @@
 	{1, 3, 0xC0}  /* Output Data, register#1 */
 };
 
+
+MV_BOARD_GPP_INFO armada_38x_customer_1_GppInfo[] = {
+	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */
+/* USB_Host0 *//* //{BOARD_GPP_USB_VBUS,    44},*/ /* from MPP map */
+};
+
+MV_BOARD_USB_INFO armada_38x_customer_1_InfoBoardUsbInfo[] = {
+/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
+	{ USB3_UNIT_ID, 0, MV_TRUE},
+	{ USB3_UNIT_ID, 1, MV_TRUE},    /* xHCI port#1 connected only via USB2.0 UTMI (not via USB3.0 SerDes lane) */
+	{ USB_UNIT_ID,  0, MV_TRUE},
+};
+
+MV_BOARD_IO_EXPANDER_TYPE_INFO armada_38x_customer_1_ioExpPinInfo[] = {
+/*	{ IO Type enum,			bit offset, Io.exp num,		reg Num */
+	{ MV_IO_EXPANDER_USB_VBUS,	7,		1,		3} /* VBUS_EN: IO.exp#1 (0x21), reg #3, bit 7 */
+};
+
 MV_BOARD_INFO armada_38x_customer_board_1_info = {
 	.boardName			= "A38x-Customer-Board-1",
 	.numBoardNetComplexValue	= 0,
@@ -263,8 +310,10 @@
 	.pBoardTwsiDev			= armada_38x_customer_1_BoardTwsiDev,
 	.numBoardMacInfo		= ARRSZ(armada_38x_customer_1_BoardMacInfo),
 	.pBoardMacInfo			= armada_38x_customer_1_BoardMacInfo,
-	.numBoardGppInfo		= 0,
-	.pBoardGppInfo			= 0,
+	.numBoardGppInfo		= ARRSZ(armada_38x_customer_1_GppInfo),
+	.pBoardGppInfo			= armada_38x_customer_1_GppInfo,
+	.numBoardIoExpPinInfo		= ARRSZ(armada_38x_customer_1_ioExpPinInfo),
+	.pBoardIoExpPinInfo		= armada_38x_customer_1_ioExpPinInfo,
 	.activeLedsNumber		= 0,
 	.pLedGppPin			= NULL,
 	.ledsPolarity			= 0,
@@ -288,6 +337,9 @@
 
 	.pBoardSpecInit			= NULL,
 
+	.pBoardUsbInfo			= armada_38x_customer_1_InfoBoardUsbInfo,
+	.numBoardUsbInfo		= ARRSZ(armada_38x_customer_1_InfoBoardUsbInfo),
+
 	/* NAND init params */
 	.nandFlashReadParams		= A38x_CUSTOMER_BOARD_0_NAND_READ_PARAMS,
 	.nandFlashWriteParams		= A38x_CUSTOMER_BOARD_0_NAND_WRITE_PARAMS,
@@ -303,7 +355,172 @@
 	.configAutoDetect		= MV_FALSE,
 	.numIoExp			= ARRSZ(armada_38x_customer_1_IoExpanderInfo),
 	.pIoExp				= armada_38x_customer_1_IoExpanderInfo,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
+};
+
+/*******************************************************************************
+ * A38x SolidRun ClearFog
+ *******************************************************************************/
+MV_BOARD_TWSI_INFO armada_38x_clearfog_BoardTwsiDev[] = {
+	/* {{MV_BOARD_DEV_CLASS devClass, MV_U8 devClassId,  MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{ BOARD_TWSI_IO_EXPANDER,	0,	0x20, ADDR7_BIT, MV_FALSE},
+};
+MV_BOARD_MAC_INFO armada_38x_clearfog_BoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_1000M, -1, -1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO,  -1,  -1, MV_TRUE}
+};
+
+MV_DEV_CS_INFO armada_38x_clearfog_BoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
+	{ DEVICE_CS0,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
+	{ DEVICE_CS1,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
+	{ DEVICE_CS2,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
+	{ DEVICE_CS3,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
+	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE },	/* NOR DEV */
+	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
+	{ SPI0_CS1,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
+	{ SPI0_CS2,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
+	{ SPI0_CS3,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
+	{ SPI1_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_TRUE },	/* SPI1 DEV */
+	{ SPI1_CS1,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_FALSE },	/* SPI1 DEV */
+	{ SPI1_CS2,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_FALSE },	/* SPI1 DEV */
+	{ SPI1_CS3,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_FALSE }	/* SPI1 DEV */
+};
+
+MV_BOARD_MPP_INFO armada_38x_clearfog_BoardMppConfigValue[] = {
+	{ {
+		A38x_CLEARFOG_BOARD_MPP0_7,
+		A38x_CLEARFOG_BOARD_MPP8_15,
+		A38x_CLEARFOG_BOARD_MPP16_23,
+		A38x_CLEARFOG_BOARD_MPP24_31,
+		A38x_CLEARFOG_BOARD_MPP32_39,
+		A38x_CLEARFOG_BOARD_MPP40_47,
+		A38x_CLEARFOG_BOARD_MPP48_55,
+		A38x_CLEARFOG_BOARD_MPP56_63,
+	} }
+};
+
+struct MV_BOARD_IO_EXPANDER armada_38x_clearfog_IoExpanderInfo[] = {
+	{0, 2, 0x40}, /* Deassert both mini pcie reset signals */
+	{0, 6, 0xf9},
+	{0, 2, 0x46}, /* Assert reset signals and enable USB3 current limiter */
+	{0, 6, 0xb9},
+	{0, 3, 0x0}, /* Set SFP_TX_DIS to zero */
+	{0, 7, 0xbf}, /* Drive SFP_TX_DIS to zero */
+};
+
+MV_BOARD_USB_INFO armada_38x_clearfog_InfoBoardUsbInfo[] = {
+/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
+	{ USB3_UNIT_ID, 0, MV_TRUE},
+	{ USB3_UNIT_ID, 1, MV_TRUE},    /* xHCI port#1 connected only via USB2.0 UTMI (not via USB3.0 SerDes lane) */
+	{ USB_UNIT_ID,  0, MV_TRUE},
+};
+
+struct MV_BOARD_SWITCH_INFO armada_38x_clearfog_InfoSwitchInfo[] = {
+	{
+		.isEnabled = MV_TRUE,
+		.isCpuPortRgmii = MV_FALSE,
+		.switchIrq = -1,	/* set to -1 for using PPU*/
+		.switchPort = {0, 1, 2, 3, 4, 5, 6},
+		.cpuPort = 5,
+		.connectedPort = {-1, 5, -1},
+		.smiScanMode = MV_SWITCH_SMI_MULTI_ADDR_MODE,
+		.quadPhyAddr = 4,
+		.forceLinkMask = 0x60
+	}
+};
+
+MV_BOARD_IO_EXPANDER_TYPE_INFO armada_38x_clearfog_ioExpPinInfo[] = {
+/*	{ IO Type enum,			bit offset, Io.exp num,		reg Num */
+	{ MV_IO_EXPANDER_USB_VBUS,	6,		0,		2} /* VBUS_EN: IO.exp#1 (0x21), reg #3, bit 7 */
+};
+
+void A38x_CLEARFOG_BOARD_gpp_callback(MV_BOARD_INFO *board) {
+	/* Toggle GPIO41 to reset on-board switch and phy */
+	/* Set GPIO41 as output enabled */
+	MV_REG_BIT_RESET (GPP_DATA_OUT_REG(1), BIT9);
+	/* reset output value */
+	MV_REG_BIT_RESET (GPP_DATA_OUT_EN_REG(1), BIT9);
+	/* set output value */
+	mvOsDelay(1);
+	MV_REG_BIT_SET (GPP_DATA_OUT_EN_REG(1), BIT9);
+	mvOsDelay(10);
+
+	/* update on-Board IO expander with pre-defined values:
+	 * USB3 current limiter, and SFP_TX_DIS, Deassert and assert 2*mini PCIe reset signals, */
+	mvBoardIoExpanderUpdate();
+}
+
+MV_BOARD_INFO armada_38x_clearfog_board_info = {
+	.boardName				= "SolidRun ClearFog-A1 REV2.0",
+	.numBoardNetComplexValue		= 0,
+	.pBoardNetComplexInfo			= NULL,
+	.pBoardMppConfigValue			= armada_38x_clearfog_BoardMppConfigValue,
+	.intsGppMaskLow				= 0,
+	.intsGppMaskMid				= 0,
+	.intsGppMaskHigh			= 0,
+	.numBoardDeviceIf			= ARRSZ(armada_38x_clearfog_BoardDeCsInfo),
+	.pDevCsInfo					= armada_38x_clearfog_BoardDeCsInfo,
+	.numBoardTwsiDev			= ARRSZ(armada_38x_clearfog_BoardTwsiDev),
+	.pBoardTwsiDev				= armada_38x_clearfog_BoardTwsiDev,
+	.numBoardMacInfo			= ARRSZ(armada_38x_clearfog_BoardMacInfo),
+	.pBoardMacInfo				= armada_38x_clearfog_BoardMacInfo,
+	.numBoardGppInfo			= 0,
+	.pBoardGppInfo				= 0,
+	.numBoardIoExpPinInfo			= ARRSZ(armada_38x_clearfog_ioExpPinInfo),
+	.pBoardIoExpPinInfo			= armada_38x_clearfog_ioExpPinInfo,
+	.activeLedsNumber			= 0,
+	.pLedGppPin				= NULL,
+	.ledsPolarity				= 0,
+
+	/* PMU Power */
+	.pmuPwrUpPolarity			= 0,
+	.pmuPwrUpDelay				= 80000,
+
+	/* GPP values */
+	.gppOutEnValLow				= A38x_CLEARFOG_BOARD_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid				= A38x_CLEARFOG_BOARD_GPP_OUT_ENA_MID,
+	.gppOutValLow				= A38x_CLEARFOG_BOARD_GPP_OUT_VAL_LOW,
+	.gppOutValMid				= A38x_CLEARFOG_BOARD_GPP_OUT_VAL_MID,
+	.gppPolarityValLow			= A38x_CLEARFOG_BOARD_GPP_POL_LOW,
+	.gppPolarityValMid			= A38x_CLEARFOG_BOARD_GPP_POL_MID,
+	.gppPostConfigCallBack			= A38x_CLEARFOG_BOARD_gpp_callback,
+
+	/* TDM */
+	.numBoardTdmInfo			= {},
+	.pBoardTdmInt2CsInfo			= {},
+	.boardTdmInfoIndex			= -1,
+
+	.pBoardSpecInit				= NULL,
+
+	.pBoardUsbInfo				= armada_38x_clearfog_InfoBoardUsbInfo,
+	.numBoardUsbInfo			= ARRSZ(armada_38x_clearfog_InfoBoardUsbInfo),
+
+	/* NAND init params */
+	.nandFlashReadParams			= 0,
+	.nandFlashWriteParams			= 0,
+	.nandFlashControl			= 0,
+	.nandIfMode					= NAND_IF_NFC,
+
+	.isSdMmcConnected			= MV_TRUE,
+
+	/* NOR init params */
+	.norFlashReadParams			= 0,
+	.norFlashWriteParams			= 0,
+	/* Enable modules auto-detection. */
+	.configAutoDetect			= MV_FALSE,
+	.numIoExp				= ARRSZ(armada_38x_clearfog_IoExpanderInfo),
+	.pIoExp					= armada_38x_clearfog_IoExpanderInfo,
+	.boardOptionsModule			= MV_MODULE_NO_MODULE,
+	.isAmc					= MV_FALSE,
+	.pSwitchInfo				= armada_38x_clearfog_InfoSwitchInfo,
+	.switchInfoNum				= ARRSZ(armada_38x_clearfog_InfoSwitchInfo)
 };
 
 /*******************************************************************************
@@ -318,9 +535,10 @@
 #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;}} */
-	{ BOARD_MAC_SPEED_1000M, 0xff, 0x0},	/* switch, no phy, no addr */
-	{ BOARD_MAC_SPEED_AUTO, 0x3, 0x0},	/* craft, phy port 3, no addr */
+	/* {{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[] = {
@@ -397,6 +615,10 @@
 
 	.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,
@@ -413,10 +635,6 @@
 	.numIoExp			= ARRSZ(armada_38x_gfch100_IoExpanderInfo),
 	.pIoExp				= armada_38x_gfch100_IoExpanderInfo,
 	.boardOptionsModule		= MV_MODULE_NO_MODULE,
-
-	/* USB */
-	.numBoardUsbInfo		= ARRSZ(armada_38x_gfch100_UsbInfo),
-	.pBoardUsbInfo			= armada_38x_gfch100_UsbInfo,
 };
 
 /*
@@ -425,6 +643,7 @@
 MV_BOARD_INFO *customerBoardInfoTbl[] = {
 	&armada_38x_customer_board_0_info,
 	&armada_38x_customer_board_1_info,
+	&armada_38x_clearfog_board_info,
 	&armada_38x_gfch100_info,
 };
 
@@ -460,7 +679,7 @@
 	{ BOARD_DEV_TWSI_SATR,		1,	0x4c,	   ADDR7_BIT, MV_FALSE},
 	{ BOARD_DEV_TWSI_SATR,		2,	0x4d,	   ADDR7_BIT, MV_FALSE},
 	{ BOARD_DEV_TWSI_SATR,		3,	0x4e,	   ADDR7_BIT, MV_FALSE},
-	{ BOARD_DEV_TWSI_SATR,		4,	0x21,	   ADDR7_BIT, MV_FALSE},
+	{ BOARD_TWSI_IO_EXPANDER,	0,	0x21,	   ADDR7_BIT, MV_FALSE},
 	{ BOARD_TWSI_MODULE_DETECT,	0,	0x20,	   ADDR7_BIT, MV_FALSE},   /* modules */
 	{ BOARD_TWSI_MODULE_DETECT,	1,	0x23,	   ADDR7_BIT, MV_FALSE},
 	{ BOARD_TWSI_MODULE_DETECT,	2,	0x24,	   ADDR7_BIT, MV_FALSE},
@@ -469,10 +688,11 @@
 	{ BOARD_TWSI_MODULE_DETECT,	5,	0x27,	   ADDR7_BIT, MV_FALSE},
 };
 MV_BOARD_MAC_INFO db88f68xxInfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0, MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
 };
 
 MV_BOARD_USB_INFO db88f68xxInfoBoardUsbInfo[] = {
@@ -487,13 +707,34 @@
 	{ DEVICE_CS0,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
 	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE },	/* NOR DEV */
 	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_TRUE },	/* SPI0 DEV */
-	{ SPI0_CS1,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE }	/* SPI0 DEV */
+	{ SPI1_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_FALSE }	/* SPI1 DEV */
 };
 
 MV_BOARD_TDM_INFO db88f68xxTdm880[] = { {0} };
 
 MV_BOARD_TDM_SPI_INFO db88f68xxTdmSpiInfo[] = { {1} };
 
+struct MV_BOARD_SWITCH_INFO db88f68xxSwitchInfo[] = {
+	{
+		.isEnabled = MV_FALSE,
+		.isCpuPortRgmii = MV_TRUE,
+		.switchIrq = -1,	/* set to -1 for using PPU*/
+		.switchPort = {0, 1, 2, 3, 4, 5, 6},
+		.cpuPort = 6,
+		.connectedPort = {5, 6, -1},
+		.smiScanMode = MV_SWITCH_SMI_MULTI_ADDR_MODE,
+		.quadPhyAddr = 2,
+		.forceLinkMask = 0x60
+	}
+};
+
+struct MV_BOARD_IO_EXPANDER db88f68xxInfoBoardioExpValue[] = {
+	{0, 6, 0xFF}, /* Config reg#0: all bits as input (BIT on = Input) */
+	{0, 7, 0xFC}, /* Config reg#1: BIT0(USB3.0 current limit), BIT1(USB3.1 current limit)*/
+	{0, 2, 0xFF}, /* Output Data, reg#0  - no output bits*/
+	{0, 3, 0xFF}, /* Output Data, reg#1:  BIT0,USB3.0_CURRENT=1, BIT1,USB3.1_CURRENT=1 */
+};
+
 MV_BOARD_INFO db88f68xx_board_info = {
 	.boardName		= "DB-88F6820-BP",
 	.compatibleDTName	= "a385-db",
@@ -511,6 +752,8 @@
 	.pBoardMacInfo		= db88f68xxInfoBoardMacInfo,
 	.numBoardGppInfo	= 0,
 	.pBoardGppInfo		= 0,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber	= 0,
 	.pLedGppPin		= NULL,
 	.ledsPolarity		= 0,
@@ -557,9 +800,14 @@
 
 	/* Enable modules auto-detection. */
 	.configAutoDetect		= MV_TRUE,
-	.numIoExp			= 0,
-	.pIoExp				= NULL,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.numIoExp			= ARRSZ(db88f68xxInfoBoardioExpValue),
+	.pIoExp				= db88f68xxInfoBoardioExpValue,
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= db88f68xxSwitchInfo,
+	.switchInfoNum			= ARRSZ(db88f68xxSwitchInfo)
 };
 
 /*******************************************************************************
@@ -573,9 +821,10 @@
 	{ BOARD_TWSI_IO_EXPANDER,	1,	0x21, ADDR7_BIT, MV_FALSE},
 };
 MV_BOARD_MAC_INFO rd88F68XXInfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0}
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0, MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE}
 };
 
 MV_DEV_CS_INFO rd88F68XXInfoBoardDeCsInfo[] = {
@@ -623,6 +872,8 @@
 	.pBoardMacInfo			= rd88F68XXInfoBoardMacInfo,
 	.numBoardGppInfo		= 0,
 	.pBoardGppInfo			= 0,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber		= 0,
 	.pLedGppPin			= NULL,
 	.ledsPolarity			= 0,
@@ -662,7 +913,12 @@
 	.configAutoDetect		= MV_TRUE,
 	.numIoExp			= ARRSZ(ioExpNas),
 	.pIoExp				= ioExpNas,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 /*******************************************************************************
  * A380 RD-WAP-88F68XX board */
@@ -706,6 +962,8 @@
 	.pBoardMacInfo			= rd88F68XXInfoBoardMacInfo,
 	.numBoardGppInfo		= 0,
 	.pBoardGppInfo			= 0,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber		= 0,
 	.pLedGppPin			= NULL,
 	.ledsPolarity			= 0,
@@ -745,7 +1003,12 @@
 	.configAutoDetect		= MV_TRUE,
 	.numIoExp			= ARRSZ(ioExpWap),
 	.pIoExp				= ioExpWap,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 /*******************************************************************************
@@ -785,10 +1048,11 @@
 };
 
 MV_BOARD_MAC_INFO dbAP88f68xxInfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x6, 0x4},
-	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4},
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x6, 0x4, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4, MV_TRUE},
 };
 
 MV_BOARD_USB_INFO dbAP88f68xxInfoBoardUsbInfo[] = {
@@ -800,9 +1064,12 @@
 MV_DEV_CS_INFO dbAP88f68xxInfoBoardDeCsInfo[] = {
 	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 	{ DEVICE_CS0,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_TRUE },	/* NAND DEV */
-	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE },	/* NOR DEV */
-	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
-	{ SPI0_CS1,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE }	/* SPI0 DEV */
+	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE }	/* NOR DEV */
+};
+
+MV_BOARD_GPP_INFO dbAP88f68xxInfoBoardGppInfo[] = {
+	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */
+/* USB_Host0 */	{BOARD_GPP_USB_VBUS,    44}, /* from MPP map */
 };
 
 MV_BOARD_TDM_INFO dbAP88f68xxTdm880[] = { {0} };
@@ -826,8 +1093,10 @@
 	.pBoardTwsiDev          = dbAP88f68xxInfoBoardTwsiDev,
 	.numBoardMacInfo        = ARRSZ(dbAP88f68xxInfoBoardMacInfo),
 	.pBoardMacInfo          = dbAP88f68xxInfoBoardMacInfo,
-	.numBoardGppInfo        = 0,
-	.pBoardGppInfo          = 0,
+	.numBoardGppInfo	= ARRSZ(dbAP88f68xxInfoBoardGppInfo),
+	.pBoardGppInfo		= dbAP88f68xxInfoBoardGppInfo,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber       = 0,
 	.pLedGppPin             = NULL,
 	.ledsPolarity           = 0,	/* PMU Power */
@@ -863,7 +1132,12 @@
 	.configAutoDetect               = MV_FALSE,
 	.numIoExp                       = 0,
 	.pIoExp                         = NULL,
-	.boardOptionsModule             = MV_MODULE_NO_MODULE
+	.boardOptionsModule             = MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 /*******************************************************************************
@@ -878,10 +1152,11 @@
 	{ BOARD_TWSI_IO_EXPANDER,	1,	0x21, ADDR7_BIT, MV_FALSE},
 };
 MV_BOARD_MAC_INFO dbGP88F68XXInfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO,  -1,  -1}
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO,  -1,  -1, MV_TRUE}
 };
 
 MV_BOARD_USB_INFO dbGP88f68xxInfoBoardUsbInfo[] = {
@@ -917,7 +1192,12 @@
 	{1, 6, 0xC3}, /* Configuration registers: Bit on --> Input bits  */
 	{1, 7, 0x31}, /* Configuration registers: Bit on --> Input bits  */
 	{1, 2, 0x08}, /* Output Data, register#0 */
-	{1, 3, 0xC0}  /* Output Data, register#1 */
+	{1, 3, 0x40}  /* Output Data, register#1 */
+};
+
+MV_BOARD_IO_EXPANDER_TYPE_INFO dbGP88f68XXInfoBoardioExpPinInfo[] = {
+/*	{ IO Type enum,			bit offset, Io.exp num,		reg Num */
+	{ MV_IO_EXPANDER_USB_VBUS,	7,		1,		3} /* VBUS_EN: IO.exp#1 (0x21), reg #3, bit 7 */
 };
 
 MV_U8 dbGP88f68XXInfoBoardPicGpio[] = {33, 34, 35};
@@ -939,6 +1219,8 @@
 	.pBoardMacInfo			= dbGP88F68XXInfoBoardMacInfo,
 	.numBoardGppInfo		= 0,
 	.pBoardGppInfo			= 0,
+	.numBoardIoExpPinInfo		= ARRSZ(dbGP88f68XXInfoBoardioExpPinInfo),
+	.pBoardIoExpPinInfo		= dbGP88f68XXInfoBoardioExpPinInfo,
 	.activeLedsNumber		= 0,
 	.pLedGppPin			= NULL,
 	.ledsPolarity			= 0,
@@ -984,7 +1266,12 @@
 	.configAutoDetect		= MV_TRUE,
 	.numIoExp			= ARRSZ(dbGP88f68XXInfoBoardioExpValue),
 	.pIoExp				= dbGP88f68XXInfoBoardioExpValue,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.isAmc				= MV_FALSE,
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 /*******************************************************************************
@@ -1011,10 +1298,11 @@
 	{ BOARD_TWSI_MODULE_DETECT,	0,	0x56,	ADDR7_BIT, MV_TRUE},   /* SLM 1426/1427 module */
 };
 MV_BOARD_MAC_INFO db88f6821InfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
 };
 
 MV_BOARD_USB_INFO db88f6821InfoBoardUsbInfo[] = {
@@ -1026,8 +1314,7 @@
 	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 	{ DEVICE_CS0,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_FALSE },	/* NAND DEV */
 	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE },	/* NOR DEV */
-	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_TRUE },	/* SPI0 DEV */
-	{ SPI0_CS1,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE }	/* SPI0 DEV */
+	{ SPI0_CS0,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_TRUE }	/* SPI0 DEV */
 };
 
 struct MV_BOARD_IO_EXPANDER db88f6821InfoBoardioExpValue[] = {
@@ -1054,6 +1341,8 @@
 	.pBoardMacInfo		= db88f6821InfoBoardMacInfo,
 	.numBoardGppInfo	= 0,
 	.pBoardGppInfo		= 0,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber	= 0,
 	.pLedGppPin		= NULL,
 	.ledsPolarity		= 0,
@@ -1081,7 +1370,7 @@
 	.nandFlashControl	= DB_88F68XX_BOARD_NAND_CONTROL,
 	.nandIfMode		= NAND_IF_NFC,
 
-	.isSdMmcConnected	= MV_FALSE,
+	.isSdMmcConnected	= MV_TRUE,
 	.isSdMmc_1_8v_Connected	= MV_FALSE,
 
 	/* NOR init params */
@@ -1092,7 +1381,12 @@
 	.configAutoDetect	= MV_TRUE,
 	.numIoExp		= ARRSZ(db88f6821InfoBoardioExpValue),
 	.pIoExp			= db88f6821InfoBoardioExpValue,
-	.boardOptionsModule	= MV_MODULE_NO_MODULE
+	.boardOptionsModule	= MV_MODULE_NO_MODULE,
+	.isAmc			= MV_FALSE,
+	.isAudioConnected	= MV_FALSE,
+	.isTdmConnected		= MV_FALSE,
+	.pSwitchInfo		= NULL,
+	.switchInfoNum		= 0
 };
 
 /*******************************************************************************
@@ -1117,28 +1411,28 @@
 	{ BOARD_DEV_TWSI_SATR,		1,	0x4c,	ADDR7_BIT, MV_FALSE},
 };
 MV_BOARD_MAC_INFO dbAmc88f68xxInfoBoardMacInfo[] = {
-	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0},
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr ,
+	   MV_32 boardEthSmiAddr0 , MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_FALSE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
 };
 
 MV_BOARD_USB_INFO dbAmc88f68xxInfoBoardUsbInfo[] = {
 /* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
-	{ USB_UNIT_ID, 1, MV_TRUE},
+	{ USB_UNIT_ID, 0, MV_TRUE},
 };
 
 MV_DEV_CS_INFO dbAmc88f68xxInfoBoardDeCsInfo[] = {
 	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 	{ DEVICE_CS0,	N_A, BOARD_DEV_NAND_FLASH,	8,	8,	0,	MV_TRUE },	/* NAND DEV */
 	{ DEV_BOOCS,	N_A, BOARD_DEV_NOR_FLASH,	16,	16,	0,	MV_FALSE },	/* NOR DEV */
-	{ SPI0_CS0,	N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_FALSE },	/* SPI0 DEV */
-	{ SPI0_CS1,	N_A, BOARD_DEV_SPI_FLASH,	8,	8,	0,	MV_TRUE }	/* SPI0 DEV */
+	{ SPI1_CS0,	N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_TRUE }	/* SPI0 DEV */
 };
 
 MV_BOARD_INFO dbAmc88f68xx_board_info = {
 	.boardName		= "DB-88F6820-AMC",
-	.compatibleDTName	= "a385-amc",
+	.compatibleDTName	= "a385-db-amc",
 	.numBoardNetComplexValue = 0,
 	.pBoardNetComplexInfo	= NULL,
 	.pBoardMppConfigValue	= dbAmc88f68xxInfoBoardMppConfigValue,
@@ -1153,6 +1447,8 @@
 	.pBoardMacInfo		= dbAmc88f68xxInfoBoardMacInfo,
 	.numBoardGppInfo	= 0,
 	.pBoardGppInfo		= 0,
+	.numBoardIoExpPinInfo	= 0,
+	.pBoardIoExpPinInfo	= 0,
 	.activeLedsNumber	= 0,
 	.pLedGppPin		= NULL,
 	.ledsPolarity		= 0,
@@ -1191,7 +1487,12 @@
 	.configAutoDetect	= MV_TRUE,
 	.numIoExp		= 0,
 	.pIoExp			= NULL,
-	.boardOptionsModule	= MV_MODULE_NO_MODULE
+	.boardOptionsModule	= MV_MODULE_NO_MODULE,
+	.isAmc			= MV_TRUE,	/* for DT update and switching services */
+	.isAudioConnected	= MV_FALSE,
+	.isTdmConnected		= MV_FALSE,
+	.pSwitchInfo		= NULL,
+	.switchInfoNum		= 0
 };
 
 MV_BOARD_INFO *marvellBoardInfoTbl[] = {
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 1a4fb93..eeb5868 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.h
@@ -120,6 +120,28 @@
 #define A38x_CUSTOMER_BOARD_1_GPP_POL_LOW		0x0
 #define A38x_CUSTOMER_BOARD_1_GPP_POL_MID		0x0
 
+
+/******************************* SolidRun Board *******************************/
+/*******************************************************************************
+ * SolidRun ClearFog-A1 REV2.0 */
+/******************************************************************************/
+#define A38x_CLEARFOG_BOARD_MPP0_7			0x11111111
+#define A38x_CLEARFOG_BOARD_MPP8_15			0x11111111
+#define A38x_CLEARFOG_BOARD_MPP16_23		0x10460011
+#define A38x_CLEARFOG_BOARD_MPP24_31		0x22043333
+#define A38x_CLEARFOG_BOARD_MPP32_39		0x44400002
+#define A38x_CLEARFOG_BOARD_MPP40_47		0x41144004
+#define A38x_CLEARFOG_BOARD_MPP48_55		0x45333333
+#define A38x_CLEARFOG_BOARD_MPP56_63		0x00004444
+
+#define A38x_CLEARFOG_BOARD_GPP_OUT_ENA_LOW	0xFFFFFFFF
+#define A38x_CLEARFOG_BOARD_GPP_OUT_ENA_MID	0xFFFFFFFF
+
+#define A38x_CLEARFOG_BOARD_GPP_OUT_VAL_LOW	0x0
+#define A38x_CLEARFOG_BOARD_GPP_OUT_VAL_MID	0x0
+#define A38x_CLEARFOG_BOARD_GPP_POL_LOW		0x0
+#define A38x_CLEARFOG_BOARD_GPP_POL_MID		0x0
+
 /*******************************************************************************
  * A38x GFCH100
  *******************************************************************************/
@@ -252,17 +274,18 @@
 #define DB_AP_88F68XX_MPP0_7            0x11111111
 #define DB_AP_88F68XX_MPP8_15           0x11111111
 #define DB_AP_88F68XX_MPP16_23          0x55066011
-#define DB_AP_88F68XX_MPP24_31          0x05050050
+#define DB_AP_88F68XX_MPP24_31          0x05050050 /* 37: USB3_CfgCurrentLim(out1) */
 #define DB_AP_88F68XX_MPP32_39          0x05055555
-#define DB_AP_88F68XX_MPP40_47          0x01100565
+#define DB_AP_88F68XX_MPP40_47          0x01100565 /* 43: USB3_OCSn(in), 44: USB3_VBUS_EN(out1) */
 #define DB_AP_88F68XX_MPP48_55          0x00000000
 #define DB_AP_88F68XX_MPP56_63          0x00004444
 
 #define DB_AP_88F68XX_GPP_OUT_ENA_LOW	(~(BIT21)) /* PIC (STR) GPIO = 21, 47 */
-#define DB_AP_88F68XX_GPP_OUT_ENA_MID	(~(BIT1 | BIT2 | BIT3 | BIT15))
+#define DB_AP_88F68XX_GPP_OUT_ENA_MID	(~(BIT1 | BIT2 | BIT3 | BIT5 | BIT15))
+	       /*GPP_OUT_ENA_MID: BIT5(37):USB3_Cfg = High, BIT12(44):USB3_VBUS_EN = Low */
 #define DB_AP_88F68XX_GPP_OUT_ENA_HIGH	(~(BIT1))
 #define DB_AP_88F68XX_GPP_OUT_VAL_LOW	0x0
-#define DB_AP_88F68XX_GPP_OUT_VAL_MID	0x0
+#define DB_AP_88F68XX_GPP_OUT_VAL_MID	(BIT5)
 #define DB_AP_88F68XX_GPP_OUT_VAL_HIGH	0x0
 #define DB_AP_88F68XX_GPP_POL_LOW	0x0
 #define DB_AP_88F68XX_GPP_POL_MID	0x0
@@ -324,7 +347,7 @@
 #define DB_AMC_88F68XX_GPP_OUT_ENA_MID	(~(BIT12 | BIT17 | BIT18 | BIT20 | BIT21)) /* 44:I2C_EXT_EN, 49,50,52,53:Leds*/
 #define DB_AMC_88F68XX_GPP_OUT_ENA_HIGH	0xFFFFFFFF
 #define DB_AMC_88F68XX_GPP_OUT_VAL_LOW	(BIT29) /* GPIO29: QS_SMI_ENA = OUT VAL High */
-#define DB_AMC_88F68XX_GPP_OUT_VAL_MID	(BIT12) /* GPIO44: I2C_EXT_EN = OUT VAL High */
+#define DB_AMC_88F68XX_GPP_OUT_VAL_MID	(BIT12) /* (was BIT12): GPIO44 I2C_EXT_EN = FALSE (False = OUT VAL High) */
 #define DB_AMC_88F68XX_GPP_OUT_VAL_HIGH	0x0
 #define DB_AMC_88F68XX_GPP_POL_LOW	0x0
 #define DB_AMC_88F68XX_GPP_POL_MID	0x0
diff --git a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec39x.c b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec39x.c
index b90ba63..b186bfe 100644
--- a/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec39x.c
+++ b/board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec39x.c
@@ -88,11 +88,11 @@
 
 MV_BOARD_MAC_INFO armada_39x_customer_0_BoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_8 boardEthSmiAddr, MV_8
-	 * boardEthSmiAddr0, MV_PHY_PORT_TYPE portType}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x5, 0x5, SMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4, SMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI}
+	 * boardEthSmiAddr0, MV_PHY_PORT_TYPE portType, MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x5, 0x5, SMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4, SMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI, MV_TRUE}
 };
 
 MV_BOARD_NET_COMPLEX_INFO armada_39x_customer_0_InfoBoardNetComplexInfo[] = {
@@ -120,6 +120,14 @@
 	{ SPI1_CS3,		N_A, BOARD_DEV_SPI_FLASH,	8,	8,	1,	MV_FALSE }	/* SPI1 DEV */
 };
 
+MV_BOARD_USB_INFO armada_39x_customer_0_BoardUsbInfo[] = {
+/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
+	{ USB3_UNIT_ID, 0, MV_FALSE},
+	{ USB3_UNIT_ID, 1, MV_TRUE},
+	{ USB_UNIT_ID,  0, MV_FALSE},
+};
+
+
 MV_BOARD_MPP_INFO armada_39x_customer_0_BoardMppConfigValue[] = {
 	{ {
 		A39X_CUSTOMER_BOARD_0_MPP0_7,
@@ -133,6 +141,14 @@
 	} }
 };
 
+/* gpp_callback is a generic place holder routine for special GPIO pull-up/sown sequence
+ * this routine is called as the final step of mvBoardEnvInit flow
+ * for example see implementation for SolidRun's clearFog board: A38x_CLEARFOG_BOARD_gpp_callback*/
+void A39x_CUSTOMER_BOARD_0_gpp_callback(MV_BOARD_INFO *board) {
+
+	/* implement special GPIO/MPP post configuration here */
+}
+
 MV_BOARD_INFO armada_39x_customer_board_0_info = {
 	.boardName			= "A39x-Customer-Board-0",
 	.numBoardNetComplexValue	= ARRSZ(armada_39x_customer_0_InfoBoardNetComplexInfo),
@@ -164,7 +180,10 @@
 	.gppOutValMid			= A39X_CUSTOMER_BOARD_0_GPP_OUT_VAL_MID,
 	.gppPolarityValLow		= A39X_CUSTOMER_BOARD_0_GPP_POL_LOW,
 	.gppPolarityValMid		= A39X_CUSTOMER_BOARD_0_GPP_POL_MID,
+	.gppPostConfigCallBack		= A39x_CUSTOMER_BOARD_0_gpp_callback,
 
+	.pBoardUsbInfo		= armada_39x_customer_0_BoardUsbInfo,
+	.numBoardUsbInfo	= ARRSZ(armada_39x_customer_0_BoardUsbInfo),
 	/* TDM */
 	.numBoardTdmInfo		= {},
 	.pBoardTdmInt2CsInfo		= {},
@@ -184,7 +203,9 @@
 	.configAutoDetect		= MV_FALSE,
 	.numIoExp			= 0,
 	.pIoExp				= NULL,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 /*
@@ -239,11 +260,11 @@
 
 MV_BOARD_MAC_INFO db88f69xxInfoBoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_8 boardEthSmiAddr, MV_8
-	 * boardEthSmiAddr0, MV_PHY_PORT_TYPE portType}} */
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x5, 0x5, SMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4, SMI},
-	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI}
+	 * boardEthSmiAddr0, MV_PHY_PORT_TYPE portType, MV_BOOL boardMacEnabled;}} */
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x5, 0x5, SMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x4, 0x4, SMI, MV_TRUE},
+	{ BOARD_MAC_SPEED_AUTO, 0x0, 0x0, XSMI, MV_TRUE}
 };
 
 MV_BOARD_NET_COMPLEX_INFO db88f69xxInfoBoarNetComplexInfo[] = {
@@ -331,7 +352,12 @@
 	.configAutoDetect		= MV_TRUE,
 	.numIoExp			= 0,
 	.pIoExp				= NULL,
-	.boardOptionsModule		= MV_MODULE_NO_MODULE
+	.boardOptionsModule		= MV_MODULE_NO_MODULE,
+	/* Audio */
+	.isAudioConnected		= MV_FALSE,
+	.isTdmConnected			= MV_FALSE,
+	.pSwitchInfo			= NULL,
+	.switchInfoNum			= 0
 };
 
 MV_BOARD_INFO *marvellBoardInfoTbl[] = {
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.c b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.c
index c94b287..6e77d41 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.c
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.c
@@ -117,38 +117,45 @@
 #define MV_6810_INDEX		1
 #define MV_6811_INDEX		2
 #define MV_6828_INDEX		3
+#define MV_6W22_INDEX		4 /* 6W22=A383 */
+#define MV_6W23_INDEX		5 /* 6W23=A384 */
 
 #define MV_6920_INDEX		0
 #define MV_6928_INDEX		1
 
-#define MAX_DEV_ID_NUM		4
+#define MAX_DEV_ID_NUM		6
 
 #ifdef CONFIG_ARMADA_38X
 MV_UNIT_ID mvCtrlSocUnitNums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
-/*				6820	6810	6811	6828	*/
-/* DRAM_UNIT_ID     */		{ 1,	1,	1,	1},
-/* PEX_UNIT_ID      */		{ 4,	3,	3,	4},
-/* ETH_GIG_UNIT_ID  */		{ 3,	2,	2,	3},	/* total SoC MAC unit count (Not updated) */
-/* ETH_GIG_ACTIVE_UNIT_ID */	{ 3,	2,	2,	3},	/* active MAC unit count (updated by ethComPhy) */
-/* USB_UNIT_ID      */		{ 1,	1,	0,	1},
-/* USB3_UNIT_ID     */		{ 2,	2,	2,	2},
-/* IDMA_UNIT_ID     */		{ 0,	0,	0,	0},
-/* XOR_UNIT_ID      */		{ 2,	2,	2,	2},
-/* SATA_UNIT_ID     */		{ 2,	2,	2,	4},
-/* TDM_32CH_UNIT_ID */		{ 1,	1,	0,	1},
-/* UART_UNIT_ID     */		{ 4,	4,	4,	4},
-/* CESA_UNIT_ID     */		{ 2,	2,	2,	2},
-/* SPI_UNIT_ID      */		{ 2,	2,	2,	2},
-/* AUDIO_UNIT_ID    */		{ 1,	1,	0,	1},
-/* SDIO_UNIT_ID     */		{ 1,	1,	1,	1},
-/* TS_UNIT_ID       */		{ 0,	0,	0,	0},
-/* XPON_UNIT_ID     */		{ 0,	0,	0,	0},
-/* BM_UNIT_ID       */		{ 0,	0,	0,	0},
-/* PNC_UNIT_ID      */		{ 0,	0,	0,	0},
-/* I2C_UNIT_ID      */		{ 2,	2,	2,	2},
-/* QSGMII_UNIT_ID   */		{ 1,	0,	0,	1},
-/* XAUI_UNIT_ID     */		{ 0,	0,	0,	0},
-/* USB3_HOST_UNIT_ID*/		{ 2,	2,	2,	2},
+/*				6820	6810	6811	6828	6W22	6W23 */
+/*				A385	A380	A381/2	A388	A383	A384 */
+/*				|======= HW Flavors =======|	|==Virtual==|*/
+/* DRAM_UNIT_ID     */		{ 1,	1,	1,	1,	1,	1},
+/* PEX_UNIT_ID      */		{ 4,	3,	3,	4,	2,	2},
+/* ETH_GIG_UNIT_ID  */		{ 3,	2,	2,	3,	2,	2},
+/*	ETH_GIG_UNIT_ID -> total SoC MAC unit count (Not updated) */
+/* ETH_GIG_ACTIVE_UNIT_ID */	{ 3,	2,	2,	3,	2,	2},
+/*	ETH_GIG_ACTIVE_UNIT_ID -> active MAC unit count (updated by ethComPhy) */
+/* USB_UNIT_ID      */		{ 1,	1,	0,	1,	1,	1},
+/* USB3_UNIT_ID     */		{ 2,	2,	2,	2,	1,	1},
+/* IDMA_UNIT_ID     */		{ 0,	0,	0,	0,	0,	0},
+/* XOR_UNIT_ID      */		{ 2,	2,	2,	2,	2,	2},
+/* SATA_UNIT_ID     */		{ 2,	2,	2,	4,	1,	1},
+/* TDM_32CH_UNIT_ID */		{ 1,	1,	0,	1,	0,	1},
+/* UART_UNIT_ID     */		{ 4,	4,	4,	4,	1,	1},
+/* CESA_UNIT_ID     */		{ 2,	2,	2,	2,	2,	2},
+/* SPI_UNIT_ID      */		{ 2,	2,	2,	2,	2,	2},
+/* AUDIO_UNIT_ID    */		{ 1,	1,	0,	1,	0,	1},
+/* SDIO_UNIT_ID     */		{ 1,	1,	1,	1,	1,	1},
+/* TS_UNIT_ID       */		{ 0,	0,	0,	0,	0,	0},
+/* XPON_UNIT_ID     */		{ 0,	0,	0,	0,	0,	0},
+/* BM_UNIT_ID       */		{ 0,	0,	0,	0,	0,	0},
+/* PNC_UNIT_ID      */		{ 0,	0,	0,	0,	0,	0},
+/* I2C_UNIT_ID      */		{ 2,	2,	2,	2,	1,	1},
+/* QSGMII_UNIT_ID   */		{ 1,	0,	0,	1,	0,	0},
+/* XAUI_UNIT_ID     */		{ 0,	0,	0,	0,	0,	0},
+/* USB3_HOST_UNIT_ID*/		{ 2,	2,	2,	2,	1,	1},
+/* SERDES_UNIT_ID   */		{ 6,	5,	4,	6,	4,	4},
 };
 #else  /* if (CONFIG_ARMADA_39X) */
 MV_UNIT_ID mvCtrlSocUnitNums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
@@ -176,6 +183,7 @@
 /* QSGMII_UNIT_ID		*/ { 0,	1},
 /* XAUI_UNIT_ID			*/ { 1,	1},
 /* USB3_HOST_UNIT_ID		*/ { 1,	2},
+/* SERDES_UNIT_ID		*/ { 7,	7},
 };
 #endif
 
@@ -189,6 +197,10 @@
 #define SERDES_RXAUI(x)		(0x100 << x)	/* bits 8       : RXAUI port 0 indication */
 static MV_U32 ethComPhy;
 
+/* usbComPhy: bit description for USB port per SerDes Lane,
+   if SerDes lane connected to USB host #X, enable bit #X usbComPhy */
+static MV_U32 usbComPhy;
+
 /* Only the first unit, only the second unit or both can be active on the specific board */
 static MV_BOOL sataUnitActive[MV_SATA_MAX_UNIT] = {MV_FALSE, MV_FALSE};
 
@@ -300,6 +312,7 @@
 MV_U32 mvCtrlDevIdIndexGet(MV_U32 ctrlModel)
 {
 	switch (ctrlModel) {
+	/* HW flavors */
 	case MV_6820_DEV_ID:
 		return MV_6820_INDEX;
 	case MV_6810_DEV_ID:
@@ -312,6 +325,11 @@
 		return MV_6920_INDEX;
 	case MV_6928_DEV_ID:
 		return MV_6928_INDEX;
+	/* Virtual flavors */
+	case MV_6W22_DEV_ID: /* 6W22=A383 */
+		return MV_6W22_INDEX;
+	case MV_6W23_DEV_ID: /* 6W23=A384 */
+		return MV_6W23_INDEX;
 	default:
 		return MV_6820_INDEX;
 	}
@@ -412,7 +430,26 @@
 	} else
 		return serdesNum;
 }
-
+/******************************************************************************
+* mvCtrlIsUsbSerDesConnected
+*
+* DESCRIPTION: check if SerDes lane is connected to USB3 host.
+*
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:return true if SerDes lane is connected to USB3 host, false otherwise.
+*
+*
+*******************************************************************************/
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort)
+{
+	if (((usbComPhy >> usbPort) & 0X1) == 1)
+		return MV_TRUE;
+	return MV_FALSE;
+}
 /*******************************************************************************
 * mvCtrlSerdesConfigDetect
 *
@@ -440,10 +477,8 @@
 
 	MV_BOARD_PEX_INFO *boardPexInfo = mvBoardPexInfoGet();
 
-	maxSerdesLane = MV_SERDES_MAX_LANES;
-	if (MV_6810_DEV_ID == mvCtrlModelGet())
-		maxSerdesLane = MV_SERDES_MAX_LANES_6810;
-
+	maxSerdesLane = mvCtrlSocUnitInfoNumGet(SERDES_UNIT_ID);
+	usbComPhy = 0;
 	memset(boardPexInfo, 0, sizeof(MV_BOARD_PEX_INFO));
 	commPhyCfgReg = MV_REG_READ(COMM_PHY_SELECTOR_REG);
 	DB(printf("mvCtrlSerdesConfig: commPhyCfgReg=0x%x\n", commPhyCfgReg));
@@ -456,12 +491,17 @@
 		ifNo = comPhyCfg & 0x0f;
 		switch (comPhyCfg & 0xF0) {
 		case SERDES_UNIT_PEX:
-			if ((ifNo == PEX0_IF) && (commPhyCfgReg & PCIE0_X4_EN_MASK))
-				boardPexInfo->pexUnitCfg[ifNo] = PEX_BUS_MODE_X4;
-			else
+			if ((ifNo == PEX0_IF) && (commPhyCfgReg & PCIE0_X4_EN_MASK)) {
+				if (serdesNum == 0) {
+					boardPexInfo->pexUnitCfg[ifNo] = PEX_BUS_MODE_X4;
+					boardPexInfo->pexMapping[boardPexInfo->boardPexIfNum] = ifNo;
+					boardPexInfo->boardPexIfNum++;
+				}
+			} else {
 				boardPexInfo->pexUnitCfg[ifNo] = PEX_BUS_MODE_X1;
-			boardPexInfo->pexMapping[boardPexInfo->boardPexIfNum] = ifNo;
-			boardPexInfo->boardPexIfNum++;
+				boardPexInfo->pexMapping[boardPexInfo->boardPexIfNum] = ifNo;
+				boardPexInfo->boardPexIfNum++;
+			}
 			DB(printf("PEX, if=%d\n", ifNo));
 			break;
 		case SERDES_UNIT_SATA:
@@ -494,6 +534,7 @@
 			break;
 		case SERDES_UNIT_USB_H:
 			DB(printf("USB_H, if=%d\n", ifNo));
+			usbComPhy |= 0X1 << ifNo;
 			usbHIfCount++;
 			break;
 		case SERDES_UNIT_USB:
@@ -594,8 +635,10 @@
 	if (!(mvBoardIsModuleConnected(MV_MODULE_NOR) ||
 	    mvBoardIsModuleConnected(MV_MODULE_NAND) ||
 		mvBoardIsModuleConnected(MV_MODULE_NAND_ON_BOARD) ||
-		mvCtrlModelGet() == MV_6811_DEV_ID))
-		ethComPhy |= ON_BOARD_RGMII(1); /* NOR/NAND modules overides RGMII-1 MPP's */
+		mvCtrlModelGet() == MV_6811_DEV_ID ||
+		(mvCtrlModelGet() == MV_6W22_DEV_ID && mvBoardIdGet() == DB_BP_6821_ID))) {
+			ethComPhy |= ON_BOARD_RGMII(1); /* NOR/NAND modules overides RGMII-1 MPP's */
+		}
 
 	mvCtrlSerdesConfigDetect();
 
@@ -640,9 +683,14 @@
 	/*SDIO PUP Enable (BIT6) */
 	MV_REG_BIT_SET(PUP_EN_REG, BIT6);
 
+	/*SDIO Clk PUP Enable (BIT7) */
+	MV_REG_BIT_SET(PUP_EN_REG, BIT7);
+
 	/* Sdio_jtag_cell_oe_smp_en */
 	MV_REG_BIT_SET(PUP_EN_REG, BIT14);
 
+	/* Sdio Clk jtag cell oe smp en */
+	MV_REG_BIT_SET(PUP_EN_REG, BIT15);
 
 	/* XXX: Following setting should be configured by u-boot */
 	MV_REG_BIT_SET(SOC_DEV_MUX_REG, BIT0); /* Configure NAND flush enabled */
@@ -707,11 +755,23 @@
 MV_U32 mvCtrlbootSrcGet(void)
 {
 	MV_U32 satrVal, bootSrc;
+	MV_U32 secBootCtrl = MV_REG_READ(SECURE_BOOT_REG);
 
-	satrVal = MV_REG_READ(MPP_SAMPLE_AT_RESET);
-	bootSrc = (satrVal & SATR_BOOT_SRC_MASK) >> SATR_BOOT_SRC_OFFS;
+	if ((secBootCtrl & SECURE_BOOT_ENA_MASK) != 0) {
+		/* Secure mode
+		 Once the secure mode activated by efuse, the actual
+		 boot device is always taken from the efuse by the HW
+		 and any other boot device configured by SatR is ignored.
+		*/
+		bootSrc = (secBootCtrl & SECURE_BOOT_DEVICE_MASK) >> SECURE_BOOT_DEVICE_OFFS;
+	} else {
 
-	DB(mvOsPrintf("%s: Read from S@R BOOTSRC = 0x%X\n", __func__, bootSrc));
+		satrVal = MV_REG_READ(MPP_SAMPLE_AT_RESET);
+		bootSrc = (satrVal & SATR_BOOT_SRC_MASK) >> SATR_BOOT_SRC_OFFS;
+
+		DB(mvOsPrintf("%s: Read from S@R BOOTSRC = 0x%X\n", __func__, bootSrc));
+	}
+
 	return bootSrc;
 }
 
@@ -1296,12 +1356,16 @@
 	MV_U32 defaultCtrlId, ctrlId = (MV_REG_READ(DEV_ID_REG) & (DEVICE_ID_MASK)) >> DEVICE_ID_OFFS;
 
 	switch (ctrlId) {
+	/* HW flavors */
 	case MV_6820_DEV_ID:
 	case MV_6810_DEV_ID:
 	case MV_6811_DEV_ID:
 	case MV_6828_DEV_ID:
 	case MV_6920_DEV_ID:
 	case MV_6928_DEV_ID:
+	/* Virtual flavors */
+	case MV_6W22_DEV_ID: /* 6W22=A383 */
+	case MV_6W23_DEV_ID: /* 6W23=A384 */
 		return ctrlId;
 	default:
 		/*Device ID Default for A38x: 6820 , for A39x: 6920 */
@@ -1332,6 +1396,7 @@
 MV_U16 mvCtrlDeviceIdGet(MV_VOID)
 {
 	switch (mvCtrlModelGet()) {
+	/* HW flavors */
 	case MV_6810_DEV_ID:
 		return 0x380;
 	case MV_6811_DEV_ID:
@@ -1340,6 +1405,11 @@
 		return 0x385;
 	case MV_6828_DEV_ID:
 		return 0x388;
+	/* Virtual flavors */
+	case MV_6W22_DEV_ID: /* 6W22=A383 */
+		return 0x383;
+	case MV_6W23_DEV_ID: /* 6W23=A384 */
+		return 0x384;
 	default:
 		return 0x380;	/* use lower device as default in case of error */
 	}
@@ -1388,7 +1458,16 @@
 *******************************************************************************/
 MV_STATUS mvCtrlNameGet(char *pNameBuff)
 {
-	mvOsSPrintf(pNameBuff, "%s%x", SOC_NAME_PREFIX, mvCtrlModelGet());
+	MV_U16 ctrlModel = mvCtrlModelGet();
+	/* Virtual Flavors has different ctrlModel values than
+	 * it's Controller names: 6W22: 0x6823 | 6W23: 0x6824 */
+	if (ctrlModel == MV_6W22_DEV_ID)
+		mvOsSPrintf(pNameBuff, "%s%s", SOC_NAME_PREFIX, MV_6W22_DEV_NAME);
+	else if (ctrlModel == MV_6W23_DEV_ID)
+		mvOsSPrintf(pNameBuff, "%s%s", SOC_NAME_PREFIX, MV_6W23_DEV_NAME);
+	else
+		mvOsSPrintf(pNameBuff, "%s%x", SOC_NAME_PREFIX, ctrlModel);
+
 	return MV_OK;
 }
 
@@ -2146,8 +2225,14 @@
 	MV_32 reg = 0;
 
 	/* Initiates TSEN hardware reset once */
-	if ((MV_REG_READ(TSEN_CONF_REG) & TSEN_CONF_RST_MASK) == 0)
-		MV_REG_BIT_SET(TSEN_CONF_REG, TSEN_CONF_RST_MASK);
+	if ((MV_REG_READ(TSEN_CONTROL_MSB_REG) & TSEN_CONTROL_MSB_RST_MASK) == 0) {
+		MV_REG_BIT_SET(TSEN_CONTROL_MSB_REG, TSEN_CONTROL_MSB_RST_MASK);
+		/* set Tsen Tc Trim to correct default value (errata #132698) */
+		reg = MV_REG_READ(TSEN_CONTROL_LSB_REG);
+		reg &= ~TSEN_CONTROL_LSB_TC_TRIM_MASK;
+		reg |= 0x3 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET;
+		MV_REG_WRITE(TSEN_CONTROL_LSB_REG, reg);
+	}
 	mvOsDelay(10);
 
 	/* Check if the readout field is valid */
@@ -2158,8 +2243,9 @@
 	reg = MV_REG_READ(TSEN_STATUS_REG);
 	reg = (reg & TSEN_STATUS_TEMP_OUT_MASK) >> TSEN_STATUS_TEMP_OUT_OFFSET;
 
-	return ((((10000 * reg) / 21445) * 1000) - 272674) / 1000;
+	return ((4761 * reg) - 2791000) / 10000;
 }
+
 /*******************************************************************************
 * mvCtrlNandClkSet
 *
@@ -2218,66 +2304,21 @@
 * mvCtrlUsbMapGet
 *
 * DESCRIPTION:
-*       Get the map of USB ports if exists
+*	Controller USB mapping is not valid for A38x/a39x Port are mapped per board via mvBoardIsUsbPortConnected.
 *
 * INPUT:
 *	the current USB unit(USB3.0 or USB2.0)
 *	the current usbActive(not used, relevant for other SoC)
 *
 * OUTPUT:
-*       Mapped usbActive.
+*	Mapped usbActive.
 *
 * RETURN:
 *       None
 *******************************************************************************/
 MV_U32 mvCtrlUsbMapGet(MV_U32 usbUnitId, MV_U32 usbActive)
 {
-	MV_U32 lane5Cfg, lane3Cfg, phySelector;
-
-	/* On A39x and A38x A0 revision, there are 2 USB3.0 MACs, and the connectivity of the
-	   USB3.0 depends on the SerDes configuration:
-		2 SerDes lanes for USB3.0:
-		| usbActive	|  USB port		|
-		-----------------------------------------
-		|	0	| USB3.0 Host Port #0	|
-		|	1	| USB3.0 Host Port #1	|
-
-		single SerDes lane#5 Or single SerDes lane#3 for USB3.0
-		| usbActive	|  USB port				|
-		---------------------------------------------------------
-		|	0	| USB3.0 Host Port #1			|
-		|	1	| USB2.0 via USB3.0  Host Port #0	|
-
-		When only single USB3.0 Host port #1 is connected via SerDes Lane 3 or 5,
-		map the USB port #1 to be usbActive=0
-		*/
-
-	/* if a38x Z0 rev, return original mapping */
-	if (mvCtrlDevFamilyIdGet(0) == MV_88F68XX && mvCtrlRevGet() == MV_88F68XX_Z1_ID)
-		return usbActive;
-
-	/* if only single USB3.0 SerDes, via Lane5 or via lane3 */
-	if (usbUnitId == USB3_UNIT_ID && mvCtrlUsb3MaxGet() == 1) {
-		phySelector = MV_REG_READ(COMM_PHY_SELECTOR_REG);
-		lane5Cfg = (phySelector & COMPHY_SELECT_MASK(5)) >> COMPHY_SELECT_OFFS(5);
-		lane3Cfg = (phySelector & COMPHY_SELECT_MASK(3)) >> COMPHY_SELECT_OFFS(3);
-		if (lane5Cfg == COMPHY_SELECT_LANE5_USB3_VAL ||
-			lane3Cfg == COMPHY_SELECT_LANE3_USB3_VAL)
-			return 1 - usbActive;
-	}
-#ifdef CONFIG_ARMADA_39X
-	/* temporery fix for A39x:
-	   In order to keep the same USB mapping for xHCI usage,
-	   nevermind if port is connected with SerDes lane, or without,
-	   return the same mapping for all xHCI/USB3.0 usage.
-	TODO: remove USB mapping and use USB board structre information */
-	if (usbUnitId == USB3_UNIT_ID)
-		return 1 - usbActive;
-#endif
-	/* If A39x or A38x A0 rev, but the no mapping needed:
-	 * - single USB#0 in use
-	 * - both USB units are in use */
-
+	/*No controller port mapping for a38x/a39x*/
 	return usbActive;
 }
 
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.h b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.h
index f22a9be..140b24c 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.h
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvLib.h
@@ -126,13 +126,13 @@
 /* Lane 0 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_SATA | 0,	SERDES_UNIT_GBE  | 0,\
 	      SERDES_UNIT_GBE,		SERDES_UNIT_NA,		   SERDES_UNIT_NA,		SERDES_UNIT_NA,\
 	      SERDES_UNIT_NA,		SERDES_UNIT_NA,		   SERDES_UNIT_NA},     \
-/* Lane 1 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_PEX | PEX1_IF,	SERDES_UNIT_SATA | 0,\
+/* Lane 1 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_PEX | PEX0_IF,	SERDES_UNIT_SATA | 0,\
 	      SERDES_UNIT_GBE | 0,	SERDES_UNIT_GBE | 1,	   SERDES_UNIT_USB_H | 0,	SERDES_UNIT_QSGMII | 0,\
 	      SERDES_UNIT_GBE | 0,	SERDES_UNIT_GBE | 0,	   SERDES_UNIT_NA},     \
-/* Lane 2 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_PEX | PEX2_IF,	SERDES_UNIT_SATA | 1,\
+/* Lane 2 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_PEX | PEX0_IF,	SERDES_UNIT_SATA | 1,\
 	      SERDES_UNIT_GBE | 1,	SERDES_UNIT_GBE | 1,	   SERDES_UNIT_NA,		SERDES_UNIT_NA,\
 	      SERDES_UNIT_NA,		SERDES_UNIT_NA,            SERDES_UNIT_NA},     \
-/* Lane 3 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX3_IF, SERDES_UNIT_PEX | PEX3_IF,  SERDES_UNIT_SATA | 3,\
+/* Lane 3 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX3_IF, SERDES_UNIT_PEX | PEX0_IF,  SERDES_UNIT_SATA | 3,\
 	      SERDES_UNIT_GBE | 2,	SERDES_UNIT_USB_H | 1,     SERDES_UNIT_USB,            SERDES_UNIT_GBE | 2,\
 	      SERDES_UNIT_NA,		SERDES_UNIT_NA,            SERDES_UNIT_NA},     \
 /* Lane 4 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_NA,             SERDES_UNIT_GBE  | 1,\
@@ -147,13 +147,13 @@
 /* Lane 0 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_SATA | 0,	SERDES_UNIT_GBE  | 0,\
 	      SERDES_UNIT_GBE,		SERDES_UNIT_NA,		   SERDES_UNIT_NA,		SERDES_UNIT_NA,\
 	      SERDES_UNIT_NA,		SERDES_UNIT_NA,		   SERDES_UNIT_NA},     \
-/* Lane 1 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_PEX | PEX1_IF,	SERDES_UNIT_SATA | 0,\
+/* Lane 1 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX0_IF, SERDES_UNIT_PEX | PEX0_IF,	SERDES_UNIT_SATA | 0,\
 	      SERDES_UNIT_GBE | 0,	SERDES_UNIT_GBE | 1,	   SERDES_UNIT_USB_H | 0,	SERDES_UNIT_QSGMII | 0,\
 	      SERDES_UNIT_GBE | 0,	SERDES_UNIT_GBE | 0,	   SERDES_UNIT_NA},     \
-/* Lane 2 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_PEX | PEX2_IF,	SERDES_UNIT_SATA | 1,\
+/* Lane 2 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_PEX | PEX0_IF,	SERDES_UNIT_SATA | 1,\
 	      SERDES_UNIT_GBE | 1,	SERDES_UNIT_GBE | 1,	   SERDES_UNIT_NA,		SERDES_UNIT_NA,\
 	      SERDES_UNIT_NA,		SERDES_UNIT_NA,            SERDES_UNIT_NA},     \
-/* Lane 3 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX3_IF, SERDES_UNIT_PEX | PEX3_IF,  SERDES_UNIT_SATA | 3,\
+/* Lane 3 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX3_IF, SERDES_UNIT_PEX | PEX0_IF,  SERDES_UNIT_SATA | 3,\
 	      SERDES_UNIT_GBE | 2,	SERDES_UNIT_USB_H | 1,     SERDES_UNIT_USB,            SERDES_UNIT_GBE | 2,\
 	      SERDES_UNIT_XAUI | 3,	SERDES_UNIT_NA,            SERDES_UNIT_NA},     \
 /* Lane 4 */ {SERDES_UNIT_NA,		SERDES_UNIT_PEX | PEX1_IF, SERDES_UNIT_NA,             SERDES_UNIT_GBE  | 1,\
@@ -170,13 +170,13 @@
 
 
 /* Termal Sensor Registers */
-#define TSEN_STATE_REG						0xE4070
-#define TSEN_STATE_OFFSET					31
-#define TSEN_STATE_MASK						(0x1 << TSEN_STATE_OFFSET)
+#define TSEN_CONTROL_LSB_REG					0xE4070
+#define TSEN_CONTROL_LSB_TC_TRIM_OFFSET				0
+#define TSEN_CONTROL_LSB_TC_TRIM_MASK				(0x7 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET)
 
-#define TSEN_CONF_REG						0xE4074
-#define TSEN_CONF_RST_OFFSET					8
-#define TSEN_CONF_RST_MASK					(0x1 << TSEN_CONF_RST_OFFSET)
+#define TSEN_CONTROL_MSB_REG					0xE4074
+#define TSEN_CONTROL_MSB_RST_OFFSET				8
+#define TSEN_CONTROL_MSB_RST_MASK				(0x1 << TSEN_CONTROL_MSB_RST_OFFSET)
 
 #define TSEN_STATUS_REG						0xE4078
 #define TSEN_STATUS_READOUT_VALID_OFFSET			10
@@ -209,6 +209,7 @@
 MV_BOOL mvCtrlSSCGInit(void);
 MV_BOOL mvCtrlPortIsSerdesSgmii(MV_U32 ethPort);
 MV_BOOL mvCtrlPortIsSerdesRxaui(MV_U32 ethPort);
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort);
 MV_BOOL mvCtrlPortIsRgmii(MV_U32 ethPort);
 MV_U32 mvCtrlGetCpuNum(MV_VOID);
 MV_U32 mvCtrlDevIdIndexGet(MV_U32 ctrlModel);
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvRegs.h b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvRegs.h
index a30eb3c..2b4c94a 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvRegs.h
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvRegs.h
@@ -228,6 +228,15 @@
 #define GENERAL_PURPOSE_RESERVED1_REG		0x182E4
 #define GENERAL_PURPOSE_RESERVED1_DEFAULT_VALUE	(~BIT17)
 
+/*****************/
+/* Secure boot */
+/*****************/
+#define SECURE_BOOT_REG				0x18280
+#define SECURE_BOOT_ENA_OFFS			0
+#define SECURE_BOOT_ENA_MASK			(1 << SECURE_BOOT_ENA_OFFS)
+#define SECURE_BOOT_DEVICE_OFFS			8
+#define SECURE_BOOT_DEVICE_MASK			(0xFF << SECURE_BOOT_DEVICE_OFFS)
+
 /* USB3 registers */
 #define MV_USB3_WIN_BASE(dev)		(MV_USB3_REGS_BASE(dev) + 0x4000)
 
@@ -369,6 +378,7 @@
 	MV_U32 ddrFreq;
 	MV_U32 l2Freq;
 	MV_BOOL	isDisplay;
+	MV_BOOL isLimited;
 } MV_FREQ_MODE;
 
 /* End of Table indicator - Should be in the last line of the SAR Table */
@@ -379,31 +389,37 @@
 
 #ifdef CONFIG_DDR4
 #define MV_SAR_FREQ_MODES { \
-		{ 0x6,   1200, 600, 600, MV_TRUE  }, \
-		{ 0x8,   1332, 666, 666, MV_TRUE  }, \
-		{ 0xC,   1600, 800, 800, MV_TRUE  }, \
-		{ 0x12,  1800, 900, 900, MV_TRUE  }, \
-		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE } \
+		/*ID,	 CPU,  DDR,  L@,  isDisaply?, isLimited? */\
+		{ 0x6,   1200, 600,  600,  MV_TRUE  , MV_FALSE}, \
+		{ 0x8,   1332, 666,  666,  MV_TRUE  , MV_FALSE}, \
+		{ 0xC,   1600, 800,  800,  MV_TRUE  , MV_FALSE}, \
+		{ 0x10,  1866, 933,  933,  MV_TRUE  , MV_TRUE}, \
+		{ 0x13,  2000, 933,  1000,  MV_TRUE  , MV_TRUE}, \
+		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE, MV_FALSE } \
 };
 
 #else
 #ifdef CONFIG_ARMADA_38X
 #define MV_SAR_FREQ_MODES { \
-		{ 0x0,   666,  333, 333, MV_TRUE  }, \
-		{ 0x2,   800,  400, 400, MV_TRUE  }, \
-		{ 0x4,   1066, 533, 533, MV_TRUE  }, \
-		{ 0x6,   1200, 600, 600, MV_TRUE  }, \
-		{ 0x8,   1332, 666, 666, MV_TRUE  }, \
-		{ 0xC,   1600, 800, 800, MV_TRUE  }, \
-		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE } \
+		/*ID,	 CPU,  DDR,  L2,  isDisaply?, isLimited? */\
+		{ 0x0,   666,  333,  333,  MV_TRUE  , MV_FALSE}, \
+		{ 0x2,   800,  400,  400,  MV_TRUE  , MV_FALSE}, \
+		{ 0x4,   1066, 533,  533,  MV_TRUE  , MV_FALSE}, \
+		{ 0x6,   1200, 600,  600,  MV_TRUE  , MV_FALSE}, \
+		{ 0x8,   1332, 666,  666,  MV_TRUE  , MV_FALSE}, \
+		{ 0xC,   1600, 800,  800,  MV_TRUE  , MV_FALSE}, \
+		{ 0x10,  1866, 933,  933,  MV_TRUE  , MV_TRUE}, \
+		{ 0x13,  2000, 933,  1000,  MV_TRUE  , MV_TRUE}, \
+		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE, MV_FALSE } \
 };
 #else
 #define MV_SAR_FREQ_MODES { \
-		{ 0x4,   1066, 533, 533, MV_TRUE  }, \
-		{ 0x6,   1200, 600, 600, MV_TRUE  }, \
-		{ 0x8,   1332, 666, 666, MV_TRUE  }, \
-		{ 0xC,   1600, 800, 800, MV_TRUE  }, \
-		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE } \
+		/*ID,	 CPU,  DDR,  L@, isDisaply?,isLimited? */\
+		{ 0x4,   1066, 533, 533, MV_TRUE  , MV_FALSE}, \
+		{ 0x6,   1200, 600, 600, MV_TRUE  , MV_FALSE}, \
+		{ 0x8,   1332, 666, 666, MV_TRUE  , MV_FALSE}, \
+		{ 0xC,   1600, 800, 800, MV_TRUE  , MV_FALSE}, \
+		{ MV_SAR_FREQ_MODES_EOT,  0,    0,   0, MV_FALSE, MV_FALSE} \
 };
 #endif
 
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvSpec.h b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvSpec.h
index 41e75b7..e1f0d4c 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvSpec.h
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/mvCtrlEnvSpec.h
@@ -118,11 +118,14 @@
 						(MV_ETH_BASE_ADDR_PORT1_2 + (((p) - 1) * 0x4000)))
 #define MV_ETH_SGMII_PHY_REGS_OFFSET(p)		(MV_ETH_REGS_OFFSET(p)+0x2000)
 
+#define MV_TDM_OFFSET				(0xB0000)
 #define MV_PEX_IF_REGS_OFFSET(pexIf)            (((pexIf) == 0) ? 0x80000 : (0x40000 + ((pexIf-1) * 0x4000)))
 #define MV_USB_REGS_OFFSET(dev)                 (0x58000)
 #define MV_USB3_REGS_OFFSET(dev)                (0xF0000 + (dev * 0x8000))
 #define MV_USB2_USB3_REGS_OFFSET(unitType, dev) (unitType == USB_UNIT_ID ? \
 							MV_USB_REGS_OFFSET(dev) : MV_USB3_REGS_OFFSET(dev))
+#define MV_USB3_DEVICE_REGS_OFFSET		(0x50000)
+#define MV_USB3_DEVICE_USB2_REGS_OFFSET		(0x54100)
 #define MV_XOR_REGS_OFFSET(unit)                (0x60800 + (unit)*0x100)
 #define MV_CESA_TDMA_REGS_OFFSET(chanNum)       (0x90000 + (chanNum * 0x2000))
 #define MV_CESA_REGS_OFFSET(chanNum)            (0x9D000 + (chanNum * 0x2000))
@@ -133,6 +136,7 @@
 #define MV_NFC_REGS_OFFSET                      (0xD0000)
 #define MV_SDMMC_REGS_OFFSET			(0xD8000)
 #define MV_SDMMC_WINDOWS_REGS_OFFSET		(0xDC000)
+#define MV_AUDIO_OFFSET				(0xE8000)
 
 #define SATA3_NUM_OF_PORTS			2
 #define SATA3_MAX_PORTS_PER_UNIT		2
@@ -239,6 +243,7 @@
 #define MV_ETH_MAX_RXQ				8
 #define MV_ETH_MAX_TXQ				8
 #define MV_ETH_TX_CSUM_MAX_SIZE			9800
+#define MV_ETH_TX_CSUM_MIN_SIZE			2048
 #define MV_ETH_TX_CSUM_MAX_SIZE_SMALL		2048
 #define MV_PNC_TCAM_LINES			1024	/* TCAM num of entries */
 
@@ -306,6 +311,7 @@
 	QSGMII_UNIT_ID,
 	XAUI_UNIT_ID,
 	USB3_HOST_UNIT_ID,	/* USB3.0 HOST ports */
+	SERDES_UNIT_ID,
 	MAX_UNITS_ID
 } MV_UNIT_ID;
 
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvAhbToMbusRegs.h b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvAhbToMbusRegs.h
index 4660c50..35b3710 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvAhbToMbusRegs.h
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvAhbToMbusRegs.h
@@ -131,7 +131,7 @@
 #define SRAMWCR_SIZE_MASK			(0x7 << SRAMWCR_SIZE_OFFS)
 #define SRAMWCR_BASE_OFFS			16
 #define SRAMWCR_BASE_MASK			(0xFFFF << SRAMWCR_BASE_OFFS)
-
+#define L2_FILTER_BASE_REG			0x8c04
 /**********************/
 /* MBUS BRIDGE WINDOW */
 /**********************/
@@ -141,4 +141,6 @@
 #define BRIDGWCR_SIZE_MASK			(0xFFFF << BRIDGWCR_SIZE_OFFS)
 #define MBUS_BRIDGE_WIN_BASE_REG		(MV_MBUS_REGS_OFFSET + 0x254)
 
+
+
 #endif /* __INCmvAhbToMbusRegsh */
diff --git a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvCpuIf.c b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvCpuIf.c
index f5ebb2d..73e8f90 100644
--- a/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvCpuIf.c
+++ b/board/mv_ebu/a38x/armada_38x_family/ctrlEnv/sys/mvCpuIf.c
@@ -957,6 +957,33 @@
 }
 
 /*******************************************************************************
+* mvCpuIfL2FilterSet
+*
+* DESCRIPTION:
+*	Set L2 Filter base - IO prioritization filter
+*
+* INPUT:
+*	L2 base value
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       None.
+*
+*******************************************************************************/
+MV_VOID mvCpuIfL2FilterSet(MV_U32 base)
+{
+	/* 0.25GB reserved for IO - verify no collision with IO @ 3.75GB (0xf000000) */
+	if (base > 0xf0000000) {
+		mvOsPrintf("Error: Requested L2 base (%x) overlaps with IO at 3.75GB\n", base);
+		return;
+	}
+
+	MV_REG_WRITE(L2_FILTER_BASE_REG, base);
+}
+
+/*******************************************************************************
 * mvCpuIfMbusWindowSet
 *
 * DESCRIPTION:
@@ -976,6 +1003,9 @@
 {
 	MV_U32 reg;
 
+	/* Align L2 (IO) filter with MBUS base */
+	mvCpuIfL2FilterSet(base);
+
 	MV_REG_WRITE(MBUS_BRIDGE_WIN_BASE_REG, base);
 	/* Align window size to 64KB */
 	size = ((size / _64K) - 1) << BRIDGWCR_SIZE_OFFS;
diff --git a/board/mv_ebu/a38x/cmd_efuse.c b/board/mv_ebu/a38x/cmd_efuse.c
index b70fb7d..fafeec0 100644
--- a/board/mv_ebu/a38x/cmd_efuse.c
+++ b/board/mv_ebu/a38x/cmd_efuse.c
@@ -251,13 +251,19 @@
 				val[2] = MV_EFUSE_REG_READ(EFUSE_BIT_64_ADDR(line));
 				DBPR("Read from %08X: [%08X]\n", EFUSE_BIT_64_ADDR(line), val[2]);
 
-				MV_EFUSE_REG_WRITE(EFUSE_BIT_31_0_ADDR(line), val[0]);
-				DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_31_0_ADDR(line), val[0]);
-				MV_EFUSE_REG_WRITE(EFUSE_BIT_63_32_ADDR(line), val[1]);
-				DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_63_32_ADDR(line), val[1]);
-				MV_EFUSE_REG_BIT_SET(EFUSE_BIT_64_ADDR(line), 0x1);
-				DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_64_ADDR(line), 0x1);
-				mvOsDelay(5);
+				if (val[2] == 0) { /* If the eFuse not yet burned by tester */
+					/* invalidate eFuse data before validating the row */
+					val[0] = 0xFFFFFFFF;
+					val[1] = 0x00FFFFFF;
+
+					MV_EFUSE_REG_WRITE(EFUSE_BIT_31_0_ADDR(line), val[0]);
+					DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_31_0_ADDR(line), val[0]);
+					MV_EFUSE_REG_WRITE(EFUSE_BIT_63_32_ADDR(line), val[1]);
+					DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_63_32_ADDR(line), val[1]);
+					MV_EFUSE_REG_BIT_SET(EFUSE_BIT_64_ADDR(line), 0x1);
+					DBPR("Write to  %08X: [%08X]\n", EFUSE_BIT_64_ADDR(line), 0x1);
+					mvOsDelay(5);
+				}
 			}
 		}
 
diff --git a/board/mv_ebu/a38x/cmd_sar38x.c b/board/mv_ebu/a38x/cmd_sar38x.c
index ef514f9..ff36066 100755
--- a/board/mv_ebu/a38x/cmd_sar38x.c
+++ b/board/mv_ebu/a38x/cmd_sar38x.c
@@ -23,12 +23,13 @@
 #include "ctrlEnv/mvCtrlEnvRegs.h"
 #include "ctrlEnv/mvCtrlEnvLib.h"
 #include "boardEnv/mvBoardEnvLib.h"
+#include "switchingServices/switchingServices.h"
 
 enum {
 	CMD_DUMP = MV_SATR_MAX_OPTION+1,
 	CMD_DEFAULT,
 	CMD_UNKNOWN,
-	CMD_NOT_ACTIVE	// Command that requests valid but not active field on current board 
+	CMD_NOT_ACTIVE	// Command that requests valid but not active field on current board
 };
 
 MV_FREQ_MODE cpuDdrClkTbl[] = MV_SAR_FREQ_MODES;
@@ -46,7 +47,7 @@
 	MV_SATR_TYPE_ID satrId;
 	MV_U32 defauleValueForBoard[MV_MARVELL_BOARD_NUM];
 } MV_BOARD_SATR_DEFAULT;
-#define MAX_DEFAULT_ENTRY	16
+#define MAX_DEFAULT_ENTRY	23
 MV_BOARD_SATR_DEFAULT boardSatrDefault[MAX_DEFAULT_ENTRY] = {
 /* 	defauleValueForBoard[] = RD_NAS_68xx,	DB_BP_68xx,	RD_WAP_68xx,	DB_AP_68xx , DB_GP_68xx,  DB_BP_6821,	DB-AMC */
 { MV_SATR_CPU_DDR_L2_FREQ,	{0x0c,		0x0c,		0x0c,		0x0c,		0x0c,	  0x4,		0x0c}},
@@ -65,6 +66,13 @@
 { MV_SATR_DB_USB3_PORT1,	{0,		0,		0,		0,		0,	  0,		0}},
 { MV_SATR_DDR_ECC_ENABLE,	{0,		0,		0,		0,		0,	  0,		1}},
 { MV_SATR_DDR_ECC_PUP_SEL,	{0,		0,		0,		0,		0,	  0,		1}},
+{ MV_SATR_FULL_FLAVOR,		{0,		1,		0,		1,		1,	  1,		0} },
+{ MV_SATR_TDM_CONNECTED,	{0,		1,		0,		0,		0,	  0,		0} },
+{ MV_SATR_TDM_PLACE_HOLDER,	{0,		1,		0,		0,		0,	  0,		0} },
+{ MV_SATR_BOARD_SPEED,		{0,		0x1,		0,		0x1,		0x1,	  0,		0x1} },
+{ MV_SATR_AVS_SKIP,		{0,		0x1,		0,		0x1,		0x1,	  0x1,		0x1} },
+{MV_SATR_BOOT_DEVICE,           {0,             0,              0,		0,		0,	  0,		0} },/* Dummy entry: default value taken from S@R register */
+{MV_SATR_BOOT2_DEVICE,          {0,             0,              0,		0,		0,	  0,		0} },/* Dummy entry: default value taken from S@R register */
 };
 
 char *lane1Arr[7] = {	"Unconnected" ,
@@ -83,17 +91,49 @@
 char *devIdArr[4] = {
 			"6810 (A380)",
 			"6820 (A385)",
-			"6811 (A381/2)",
+			"N/A",
 			"6828 (A388)" };
 
-MV_BOOL mvVerifyRequest(void)
+static MV_U32 getBoardSpeed(MV_U32 boardspeed)
 {
-	readline(" ");
-	if(strlen(console_buffer) == 0 || /* if pressed Enter */
-		strcmp(console_buffer,"n") == 0 ||
-		strcmp(console_buffer,"N") == 0 ) {
-		printf("\n");
-		return MV_FALSE;
+	switch (boardspeed) {
+	case 1:
+		return 2000;
+	case 2:
+		return 1866;
+	case 3:
+		return 1600;
+	default:
+		return 0;
+	}
+}
+/*
+ * when each CPU is checked, max CPU speed is determined for each board
+ * To enable the speed limitation for each board, the according value is written
+ * in SatR field 'boardspeed':
+ * -0x1 for max value 2000Mhz
+ * -0x2 for max value 1866MHz
+ * -0x3 for max value 1600MHz
+ *
+ * The function returns MV_TRUE if the cpuMode is not limited on this board
+ * by checking the 'boardspeed' field, otherwise returns MV_FALSE
+ */
+static MV_BOOL isCpuModeSupportedForBoard(int index, MV_BOOL printError)
+{
+	MV_U32 tmp;
+
+	if (cpuDdrClkTbl[index].isLimited == MV_TRUE) {
+		tmp = mvBoardSatRRead(MV_SATR_BOARD_SPEED);
+		if (tmp == MV_ERROR) {
+			mvOsPrintf("Failed reading 'boardspeed' SatR field\n");
+			return MV_FALSE;
+		}
+
+		if (cpuDdrClkTbl[index].cpuFreq > getBoardSpeed(tmp)) {
+			if (printError == MV_TRUE)
+				mvOsPrintf("Maximum supported CPU speed is %uMHz\n", getBoardSpeed(tmp));
+			return MV_FALSE;
+		}
 	}
 	return MV_TRUE;
 }
@@ -103,11 +143,17 @@
 	MV_U32 i, rc, defaultValue, boardId = mvBoardIdIndexGet(mvBoardIdGet());
 	MV_SATR_TYPE_ID satrClassId;
 	MV_BOARD_SATR_INFO satrInfo;
-
+	MV_U32 satrBootDeviceValue = mvCtrlbootSrcGet(), tmp;
 	for (i = 0; i < MAX_DEFAULT_ENTRY; i++) {
 		satrClassId = boardSatrDefault[i].satrId;
 		if (mvBoardSatrInfoConfig(satrClassId, &satrInfo) != MV_OK)
 			continue;
+		if (satrClassId == MV_SATR_BOOT_DEVICE)
+			boardSatrDefault[i].defauleValueForBoard[boardId] = satrBootDeviceValue & satrInfo.mask;
+		if (satrClassId == MV_SATR_BOOT2_DEVICE) {
+			tmp = satrBootDeviceValue >> MV_SATR_BOOT2_VALUE_OFFSET;
+			boardSatrDefault[i].defauleValueForBoard[boardId] = tmp & MV_SATR_BOOT2_VALUE_MASK;
+		}
 		defaultValue = boardSatrDefault[i].defauleValueForBoard[boardId];
 		rc = mvBoardSatRWrite(satrClassId, defaultValue);
 		if (rc == MV_ERROR) {
@@ -116,11 +162,16 @@
 	}
 
 	/* set default Device ID - if MV_SATR_DEVICE_ID field is relevant on board */
-	if (mvBoardSatrInfoConfig(MV_SATR_DEVICE_ID, &satrInfo) == MV_OK) {
-		if (mvBoardSatRWrite(MV_SATR_DEVICE_ID, mvCtrlDevIdIndexGet(mvCtrlModelGet())) == MV_ERROR)
-			mvOsPrintf("Error writing default Device ID ('devid') =%d\n", i);
-	}
+	/* A383/A384 are virtual device ID's - not represented as HW device ID values in S@R@0x18600.
+	A383/A384 are configured in SW EEPROM with FULL_FLAVOR field: if false override device ID */
 
+	if (!(mvCtrlModelGet() == MV_6W22_DEV_ID
+			|| mvCtrlModelGet() ==  MV_6W23_DEV_ID)) { /* 6W22=A383, 6W23=A384 */
+		if (mvBoardSatrInfoConfig(MV_SATR_DEVICE_ID, &satrInfo) == MV_OK) {
+			if (mvBoardSatRWrite(MV_SATR_DEVICE_ID, mvCtrlDevIdIndexGet(mvCtrlModelGet())) == MV_ERROR)
+				mvOsPrintf("Error writing default Device ID ('devid') =%d\n", i);
+		}
+	}
 	printf("\nSample at Reset values were restored to default.\n");
 	return 0;
 }
@@ -156,23 +207,26 @@
 	switch (satrInfo->satrId) {
 	case MV_SATR_CPU_DDR_L2_FREQ:
 		mvOsPrintf("cpufreq options - Determines the frequency of CPU/DDR/L2:\n\n");
-		mvOsPrintf("| ID | CPU Freq (MHz) | L2 Freq (MHz)   | SDRAM Freq (MHz)  |\n");
-		mvOsPrintf("|----|----------------|-----------------|-------------------|\n");
+		mvOsPrintf("| ID | CPU Freq (MHz) | DDR Freq (MHz)   |  L2 freq(MHz)  |\n");
+		mvOsPrintf("|----|----------------|------------------|----------------|\n");
 		for (i=0; i <= MV_SAR_FREQ_MODES_EOT; i++) {
 			if (cpuDdrClkTbl[i].id == MV_SAR_FREQ_MODES_EOT)
 				break;
-			if (cpuDdrClkTbl[i].isDisplay)
-				mvOsPrintf("| %2d |      %4d      |      %4d       |      %4d         | \n",
+			if (cpuDdrClkTbl[i].isDisplay && isCpuModeSupportedForBoard(i, MV_FALSE) == MV_TRUE)
+				mvOsPrintf("| %2d |      %4d      |      %4d        |      %4d      | \n",
 					   cpuDdrClkTbl[i].id,
 					   cpuDdrClkTbl[i].cpuFreq,
 					   cpuDdrClkTbl[i].ddrFreq,
 					   cpuDdrClkTbl[i].l2Freq);
 		}
-		mvOsPrintf("-------------------------------------------------------------\n");
+		mvOsPrintf("-----------------------------------------------------------\n");
 		break;
 	case MV_SATR_CORE_CLK_SELECT:
 		mvOsPrintf("Determines the Core clock frequency:\n");
-		mvOsPrintf("\t0 = 250MHz\n");
+		if (mvCtrlModelGet() == MV_6811_DEV_ID)
+			mvOsPrintf("\t0 = 166MHz\n");	/* device 381/2 (6811/21) use 166MHz instead of 250MHz */
+		else
+			mvOsPrintf("\t0 = 250MHz\n");
 		mvOsPrintf("\t1 = 200MHz\n");
 		break;
 	case MV_SATR_CPU1_ENABLE:
@@ -280,6 +334,27 @@
 		for (i = 0; i < ARRAY_SIZE(devIdArr); i++)
 			mvOsPrintf("\t %d = %s\n", i, devIdArr[i]);
 		break;
+	case MV_SATR_FULL_FLAVOR:
+		mvOsPrintf("Determines whether to use full flavor capabilites:\n");
+		mvOsPrintf("\t0 = Reduced Flavor\n");
+		mvOsPrintf("\t1 = Full Flavor\n ");
+		break;
+	case MV_SATR_TDM_CONNECTED:
+		mvOsPrintf("Indicates whether TDM module is connected or not:\n");
+		mvOsPrintf("\t0 = Connected\n");
+		mvOsPrintf("\t1 = Not connected\n ");
+		break;
+	case MV_SATR_AVS_SKIP:
+		mvOsPrintf("Indicates whether to skip AVS update from EFUSE or not:\n");
+		mvOsPrintf("\t0 = Do not skip AVS update from EFUSE\n");
+		mvOsPrintf("\t1 = Skip AVS update from EFUSE\n");
+		break;
+	case MV_SATR_BOARD_SPEED:
+		mvOsPrintf("Determines the max supported CPU speed:\n");
+		mvOsPrintf("\t1 = %uMHz\n", getBoardSpeed(1));
+		mvOsPrintf("\t2 = %uMHz\n", getBoardSpeed(2));
+		mvOsPrintf("\t3 = %uMHz\n", getBoardSpeed(3));
+		break;
 	default:
 		mvOsPrintf("Usage: sar list [options] (see help)\n");
 		return 1;
@@ -290,6 +365,7 @@
 int do_sar_read(MV_U32 mode, MV_BOARD_SATR_INFO *satrInfo)
 {
 	MV_U32 i, tmp;
+	char core_clk_value0[4];
 
 	if (mode != CMD_DUMP) {
 	    tmp = mvBoardSatRRead(satrInfo->satrId);
@@ -305,20 +381,22 @@
 				break;
 			if (cpuDdrClkTbl[i].id == tmp) {
 				mvOsPrintf("\nCurrent freq configuration:\n");
-				mvOsPrintf("| ID | CPU Freq (MHz) | L2 Freq (MHz)   | SDRAM Freq (MHz)  |\n");
-				mvOsPrintf("|----|----------------|-----------------|-------------------|\n");
-				mvOsPrintf("| %2d |      %4d      |      %4d       |      %4d         |\n",
+				mvOsPrintf("| ID | CPU Freq (MHz) | DDR Freq (MHz)   |  L2 freq(MHz)  |\n");
+				mvOsPrintf("|----|----------------|------------------|----------------|\n");
+				mvOsPrintf("| %2d |      %4d      |      %4d        |      %4d      |\n",
 					   cpuDdrClkTbl[i].id,
 					   cpuDdrClkTbl[i].cpuFreq,
 					   cpuDdrClkTbl[i].ddrFreq,
 					   cpuDdrClkTbl[i].l2Freq);
-				mvOsPrintf("-------------------------------------------------------------\n");
+				mvOsPrintf("-----------------------------------------------------------\n");
 				break;
 			}
 		}
 		break;
 	case MV_SATR_CORE_CLK_SELECT:
-		mvOsPrintf("\ncoreclock\t= %d  ==> %sMhz\n", tmp, (tmp == 0x0) ? "250" : "200");
+		/* device 381/2 (6811/21) use 166MHz instead of 250MHz */
+		sprintf(core_clk_value0, mvCtrlModelGet() == MV_6811_DEV_ID ? "166" : "250");
+		mvOsPrintf("\ncoreclock\t= %d  ==> %sMhz\n", tmp, (tmp == 0x0) ? core_clk_value0 : "200");
 		break;
 	case MV_SATR_CPU1_ENABLE:
 		mvOsPrintf("cpusnum\t\t= %d  ==> %s CPU\n", tmp, (tmp == 0) ? "Single" : "Dual");
@@ -380,6 +458,25 @@
 	case MV_SATR_DEVICE_ID:
 		mvOsPrintf("devid\t\t= %d  ==> Device ID: %s\n", tmp, devIdArr[tmp]);
 		break;
+	case MV_SATR_FULL_FLAVOR:
+		mvOsPrintf("flavor\t\t= %d  ==> %s Flavor", tmp, (tmp == 0) ? "Reduced" : "Full");
+		if (!tmp) {
+			if (mvBoardIdGet() == DB_GP_68XX_ID)
+				mvOsPrintf(" (A384 on DB-GP)");
+			else if (mvBoardIdGet() == DB_BP_6821_ID)
+				mvOsPrintf(" (A383 on DB-88F6821-BP)");
+		}
+		mvOsPrintf("\n");
+		break;
+	case MV_SATR_TDM_CONNECTED:
+		mvOsPrintf("tdm\t\t= %d  ==> TDM module is %s\n", tmp, (tmp == 0) ? "connected" : "not connected");
+		break;
+	case MV_SATR_AVS_SKIP:
+		mvOsPrintf("avsskip\t\t= %d  ==> %sskip AVS update from EFUSE\n", tmp, (tmp == 0) ? "Do not " : "");
+		break;
+	case MV_SATR_BOARD_SPEED:
+		mvOsPrintf("boardspeed\t\t= %d  ==> Max CPU speed is %uMHz\n", tmp, getBoardSpeed(tmp));
+		break;
 	case CMD_DUMP:
 		{
 			MV_BOARD_SATR_INFO satrInfo;
@@ -427,6 +524,11 @@
 	}
 
 	if (satrInfo->satrId == MV_SATR_CPU_DDR_L2_FREQ) {
+		/* DB-6821-BP maximum CPU/DDR frequency mode is 8 : 1332/666 MHz */
+		if (boardId == DB_BP_6821_ID && value > 0x8) {
+			mvOsPrintf("Maximum supported CPU/DDR mode for DB-6821-BP is 0x8\n");
+			return 1;
+		}
 		freqValueInvalid = 1;
 		for (i=0; i <= MV_SAR_FREQ_MODES_EOT; i++) {
 			if (cpuDdrClkTbl[i].id == MV_SAR_FREQ_MODES_EOT)
@@ -441,12 +543,14 @@
 			mvOsPrintf("Write S@R failed!\n");
 			return 1;
 		}
+		if (isCpuModeSupportedForBoard(i, MV_TRUE) == MV_FALSE)
+			return 1;
 	}
 
 	/* verify requested entry is valid and map it's ID value */
 	if (satrInfo->satrId == MV_SATR_DEVICE_ID) {
-		if (value > ARRAY_SIZE(devIdArr)) {
-			printf("%s: Error: requested invalid DEVICE_ID value (%x)\n", __func__, value);
+		if (value > ARRAY_SIZE(devIdArr) || value == 2) { /* devid = 2 (6811/21) : not supported via SatR */
+			printf("%s: Error: requested invalid Device ID value (%x)\n", __func__, value);
 			return 1;
 		}
 	}
@@ -460,7 +564,10 @@
 	if (MV_SATR_BOARD_ID == satrInfo->satrId) {
 		mvOsPrintf("\nBoard ID update requires new default environment variables.\n");
 		mvOsPrintf(" Reset environment for %s ? [y/N]" ,marvellBoardInfoTbl[value]->boardName);
-		if (mvVerifyRequest() == MV_TRUE)
+		readline(" ");
+		if(strlen(console_buffer) != 0 && /* if pressed Enter */
+			strcmp(console_buffer,"n") != 0 &&
+			strcmp(console_buffer,"N") != 0 )
 			run_command("resetenv", 0);
 	}
 	return 0;
@@ -481,6 +588,16 @@
 		return 1;
 	}
 
+	/* Check if switch is connected to AMC board */
+	if (boardId == DB_AMC_6820_ID) {
+		static SILICON_TYPE silt = SILT_NOT_DETECT;
+
+		if (silt == SILT_NOT_DETECT)
+			silt = get_attached_silicon_type();
+		if (silt == SILT_BC2)
+			return do_sar_bc2(cmdtp, flag, argc, argv);
+	}
+
 	/* is requested 'SatR read' --> Dump all */
 	if (argc > 1 && argc < 3 && strcmp(cmd, "read") == 0)
 		mode = CMD_DUMP;
@@ -552,6 +669,8 @@
 "ddr4select		   - DB-88F6820-BP: DDR3/4		(read only)\n"
 "ecoversion		   - DB-88F6820-BP: ECO version	(read only)\n"
 "boardid			   - board ID		(read only)\n"
+"boardspeed			   - MAX validated CPU mode for current chip		(read only)\n"
+"avsskip			   - Skip AVS from EFUSE update\n"
 
 "\n\t Board Specific SW fields\n"
 "\t------------------------\n"
@@ -561,7 +680,10 @@
 "dbserdes1		   - DB-GP, DB-88F6821-BP:	SerDes lane #1\n"
 "dbserdes2		   - DB-GP, DB-88F6821-BP:	SerDes lane #2\n"
 "usb3port0		   - DB-GP, DB-88F6821-BP:	USB3-Port0 mode\n"
-"usb3port1		   - DB-GP, DB-88F6821-BP:	USB3-Port1 mode\n\n"
+"usb3port1		   - DB-GP, DB-88F6821-BP:	USB3-Port1 mode\n"
+"flavor			   - DB-GP, DB-88F6821-BP: Is full flavor (for A383/4 simulation)\n"
+"tdm			   - DB-BP:			is TDM module connected\n\n"
+
 
 );
 #endif /*defined(CONFIG_CMD_SAR)*/
diff --git a/board/mv_ebu/a38x/cmd_sar39x.c b/board/mv_ebu/a38x/cmd_sar39x.c
index 2710284..a7185e2 100644
--- a/board/mv_ebu/a38x/cmd_sar39x.c
+++ b/board/mv_ebu/a38x/cmd_sar39x.c
@@ -45,12 +45,14 @@
 	MV_SATR_TYPE_ID satrId;
 	MV_U32 defauleValueForBoard[MV_MARVELL_BOARD_NUM];
 } MV_BOARD_SATR_DEFAULT;
-#define MAX_DEFAULT_ENTRY	2
+#define MAX_DEFAULT_ENTRY	4
 
 MV_BOARD_SATR_DEFAULT boardSatrDefault[MAX_DEFAULT_ENTRY] = {
 /* 	defauleValueForBoard[] = RD_69xx,	DB_68xx */
-{ MV_SATR_CPU_DDR_L2_FREQ,	{0x0c,		0x0c,		} },
-{ MV_SATR_CORE_CLK_SELECT,	{0,		0,		} },
+{MV_SATR_CPU_DDR_L2_FREQ,	{0x0c,		0x0c,		} },
+{MV_SATR_CORE_CLK_SELECT,	{0,		0,		} },
+{MV_SATR_BOOT_DEVICE,		{0,		0,		} },/* Dummy entry: default value taken from S@R register */
+{MV_SATR_BOOT2_DEVICE,		{0,		0,		} },/* Dummy entry: default value taken from S@R register */
 };
 
 typedef struct _deviceIdEntry {
@@ -65,28 +67,22 @@
 { "6928 (A398)",	0x6928,		0x6 },
 };
 
-MV_BOOL mvVerifyRequest(void)
-{
-	readline(" ");
-	if(strlen(console_buffer) == 0 || /* if pressed Enter */
-		strcmp(console_buffer,"n") == 0 ||
-		strcmp(console_buffer,"N") == 0 ) {
-		printf("\n");
-		return MV_FALSE;
-	}
-	return MV_TRUE;
-}
-
 int do_sar_default(void)
 {
 	MV_U32 i, rc, defaultValue, boardId = mvBoardIdIndexGet(mvBoardIdGet());
 	MV_SATR_TYPE_ID satrClassId;
 	MV_BOARD_SATR_INFO satrInfo;
-
+	MV_U32 satrBootDeviceValue = mvCtrlbootSrcGet(), tmp;
 	for (i = 0; i < MAX_DEFAULT_ENTRY; i++) {
 		satrClassId = boardSatrDefault[i].satrId;
 		if (mvBoardSatrInfoConfig(satrClassId, &satrInfo) != MV_OK)
 			continue;
+		if (satrClassId == MV_SATR_BOOT_DEVICE)
+			boardSatrDefault[i].defauleValueForBoard[boardId] = satrBootDeviceValue & satrInfo.mask;
+		if (satrClassId == MV_SATR_BOOT2_DEVICE) {
+			tmp = satrBootDeviceValue >> MV_SATR_BOOT2_VALUE_OFFSET;
+			boardSatrDefault[i].defauleValueForBoard[boardId] = tmp & MV_SATR_BOOT2_VALUE_MASK;
+		}
 		defaultValue = boardSatrDefault[i].defauleValueForBoard[boardId];
 		rc = mvBoardSatRWrite(satrClassId, defaultValue);
 		if (rc == MV_ERROR) {
diff --git a/board/mv_ebu/a38x/mvSysHwConfig.h b/board/mv_ebu/a38x/mvSysHwConfig.h
index e6f704c..9cdc713 100644
--- a/board/mv_ebu/a38x/mvSysHwConfig.h
+++ b/board/mv_ebu/a38x/mvSysHwConfig.h
@@ -33,6 +33,7 @@
 #define MV_INCLUDE_TWSI
 #define MV_INCLUDE_UART
 #define MV_INCLUDE_TDM
+#define MV_INCLUDE_AUDIO
 #define MV_INCLUDE_XOR
 #define CONFIG_SATA_AHCI_MV /* shared for u-boot and linux*/
 #define MV_INCLUDE_SATA /* only on u-boot */
@@ -40,6 +41,7 @@
 #define MV_INCLUDE_RTC
 
 #define MV_INCLUDE_CLK_PWR_CNTRL
+#define MV_INCLUDE_SWITCH
 
 /*
  * Board devices
diff --git a/board/mv_ebu/a38x/mv_main_a38x.c b/board/mv_ebu/a38x/mv_main_a38x.c
index 6c1fc3d..5f5f58c 100755
--- a/board/mv_ebu/a38x/mv_main_a38x.c
+++ b/board/mv_ebu/a38x/mv_main_a38x.c
@@ -103,6 +103,11 @@
 #include <sdhci.h>
 int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks);
 #endif
+
+#ifdef CONFIG_SWITCHING_SERVICES
+#include "switchingServices/switchingServices.h"
+#endif
+
 /* #define MV_DEBUG */
 #ifdef MV_DEBUG
 #define DB(x) x
@@ -306,7 +311,6 @@
 			*(unsigned int*)(CONFIG_SYS_TEXT_BASE + i);
 
 	mvBoardDebugLed(4);
-	mv_print_map();
 #if defined(CONFIG_CMD_BOARDCFG)
 	mvBoardEepromValidSet();
 #endif
@@ -319,6 +323,10 @@
 	char tmp_buf[10];
 	unsigned int malloc_len;
 
+	env = getenv("limit_dram_size");
+	if (!env)
+		setenv("limit_dram_size", "yes");
+
 	env = getenv("console");
 	if (!env)
 		setenv("console", "console=ttyS0,115200");
@@ -326,7 +334,7 @@
 	env = getenv("mtdids");
 	if (!env) {
 #if defined(MV_NAND) && defined(MV_INCLUDE_SPI)
-		setenv("mtdids", "nand0=armada-nand;spi0=spi_flash");
+		setenv("mtdids", "nand0=armada-nand,spi0=spi_flash");
 #elif defined(MV_NAND)
 		setenv("mtdids", "nand0=armada-nand");
 #elif defined(MV_INCLUDE_SPI)
@@ -336,15 +344,23 @@
 	env = getenv("mtdparts");
 	if (!env) {
 #if defined(MV_NAND) && defined(MV_INCLUDE_SPI)
-		setenv("mtdparts", "'mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);mtdparts=spi_flash:4m(boot),-(spi-rootfs)'");
+		/* Since only AMC board supports both NAND and SPI, and it uses SPI1
+		 * "spi1.0" is used in mtdparts instead of "spi0.0" */
+		setenv("mtdparts", "'mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);spi1.0:4m(boot),-(spi-rootfs);"
+				"pxa3xx_nand-0:8m(boot)ro,8m@8m(kernel),-(rootfs)'");
+		setenv("mtdparts_lgcy", "'mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);spi_flash:4m(boot),-(spi-rootfs);"
+				"pxa3xx_nand-0:8m(boot)ro,8m@8m(kernel),-(rootfs)'");
 #elif defined(MV_NAND)
-		setenv("mtdparts", "mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs)");
+		setenv("mtdparts", "mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);"
+				"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=spi_flash:4m(boot),-(spi-rootfs)");
+		setenv("mtdparts", "mtdparts=spi0.0:4m(boot),-(spi-rootfs)");
 #endif
+		setenv("mtdparts_lgcy", "mtdparts=spi_flash:4m(boot),-(spi-rootfs)");
 #endif
 	}
 
@@ -492,11 +508,11 @@
 	env = getenv("bootargs_dflt");
 	if (!env)
 #if defined(CONFIG_ARMADA_39X)
-		setenv("bootargs_dflt", "$console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath "
+		setenv("bootargs_dflt", "$console $nandEcc $mtdparts_lgcy $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 $nss_emac_map");
 #else
-		setenv("bootargs_dflt", "$console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath "
+		setenv("bootargs_dflt", "$console $nandEcc $mtdparts_lgcy $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");
 #endif
@@ -505,7 +521,11 @@
 		setenv("bootcmd_auto", "stage_boot $boot_order");
 	env = getenv("bootcmd_lgcy");
 	if (!env)
-		setenv("bootcmd_lgcy", "tftpboot 0x2000000 $image_name; setenv bootargs $bootargs_dflt; bootm 0x2000000; ");
+		setenv("bootcmd_lgcy", "tftpboot 0x2000000 $image_name;"
+			   "setenv bootargs $console $nandEcc $mtdparts_lgcy"
+			   " $bootargs_root nfsroot=$serverip:$rootpath "
+			   "ip=$ipaddr:$serverip$bootargs_end  video=dovefb:lcd0:$lcd0_params "
+			   "clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel;  bootm $loadaddr; ");
 #endif
 	env = getenv("pxe_files_load");
 	if (!env)
@@ -530,6 +550,22 @@
 		setenv("bootargs_debug", "debug=1 login=1 earlyprintk");
 #endif
 
+#ifdef CONFIG_CMD_SOURCE
+	env = getenv("run_script");
+	if (!env)
+		setenv("run_script", "no");
+#endif
+	env = getenv("sd_detection_dat3");
+	if (!env) {
+		/* by default DB-GP is the only marvell board with DAT3 detection method support.
+			This support was added in ECO 1.5 and above, so added env.
+			variable to control detection method according to ECO ver. */
+		if (mvBoardIdGet() == DB_GP_68XX_ID)
+			setenv("sd_detection_dat3", "yes");
+		else
+			setenv("sd_detection_dat3", "no");
+	}
+
 	/* netbsd boot arguments */
 	env = getenv("netbsd_en");
 	if ( !env || ( ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0) )))
@@ -624,11 +660,7 @@
 	} else {
 		env = getenv("bootargs_end");
 		if (!env)
-#if defined(MV_INC_BOARD_QD_SWITCH)
-			setenv("bootargs_end", MV_BOOTARGS_END_SWITCH);
-#else
 			setenv("bootargs_end", MV_BOOTARGS_END);
-#endif
 	}
 
 	env = getenv("image_name");
@@ -704,9 +736,7 @@
 #if (CONFIG_BOOTDELAY >= 0)
 	env = getenv("bootcmd");
 	if (!env)
-#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_LIBFDT_IS_DEFAULT)
-		setenv("bootcmd",bootcmd_fdt);
-#elif defined(CONFIG_GFCH100)
+#if defined(CONFIG_GFCH100)
 		setenv("gfparams",
 			"if test $HNV_ACTIVATED_KERNEL_NAME = kernel1; "
 			"then gfkernel=0x9048 gfroot=root=rootfs1; "
@@ -718,42 +748,18 @@
 			"setenv bootargs $console $mtdparts $gfroot $bootargs_extra; "
 			"bootm $loadaddr; "
 		);
-#elif defined(CONFIG_CMD_STAGE_BOOT)
-//		setenv("bootcmd","stage_boot $boot_order");
-// Temporary workaround till stage_boot gets stable.
-		setenv("bootcmd", "tftpboot 0x2000000 $image_name;"
-			   "setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath "
-			   "ip=$ipaddr:$serverip$bootargs_end  video=dovefb:lcd0:$lcd0_params "
-			   "clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel;  bootm $loadaddr; ");
-
-#elif defined(MV_INCLUDE_TDM) || defined(MV_INC_BOARD_QD_SWITCH)
-		setenv("bootcmd", "tftpboot 0x2000000 $image_name;"
-			   "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;  bootm $loadaddr; ");
 #else
-		setenv("bootcmd", "tftpboot 0x2000000 $image_name;"
-			   "setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath "
-			   "ip=$ipaddr:$serverip$bootargs_end  video=dovefb:lcd0:$lcd0_params "
-			   "clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel;  bootm $loadaddr; ");
+		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");
 	if (!env)
-#if defined(MV_INCLUDE_TDM) && defined(MV_INC_BOARD_QD_SWITCH)
-		setenv("standalone", "fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts "
-			   "root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end $mvNetConfig; bootm 0x2000000;");
-#elif defined(MV_INC_BOARD_QD_SWITCH)
-		setenv("standalone", "fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts "
-			   "root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end $mvNetConfig; bootm 0x2000000;");
-#elif defined(MV_INCLUDE_TDM)
-		setenv("standalone", "fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts "
+		setenv("standalone", "fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts_lgcy "
 			   "root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end; bootm 0x2000000;");
-#else
-		setenv("standalone", "fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts "
-			   "root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end; bootm 0x2000000;");
-#endif
 
 	/* Set boodelay to 3 sec, if Monitor extension are disabled */
 	if (!enaMonExt())
@@ -986,6 +992,11 @@
 		kick_next();
 
 	mvBoardDebugLed(0);
+#ifdef CONFIG_SWITCHING_SERVICES
+	/* Some additional tasks maybe required for slave BC2 device, like QSGMII select */
+	if (mvBoardisAmc() && (get_attached_silicon_type() == SILT_BC2))
+		hwServicesLateInit();
+#endif
 	return 0;
 }
 
@@ -1060,6 +1071,7 @@
 int late_print_cpuinfo(void)
 {
 	char name[50];
+	int ddrType = 4;
 
 	mvCtrlUpdatePexId();
 
@@ -1080,9 +1092,12 @@
 	printf("       CPU    @ %d [MHz]\n", mvCpuPclkGet()/1000000);
 	printf("       L2     @ %d [MHz]\n", mvCpuL2ClkGet()/1000000);
 	printf("       TClock @ %d [MHz]\n", mvTclkGet()/1000000);
-	printf("       DDR    @ %d [MHz]\n", CONFIG_SYS_BUS_CLK/1000000);
-	printf("       DDR %d Bit Width, %s Memory Access, DLB %s, ECC %s",
-			mvCtrlDDRBudWidth(),
+#ifdef CONFIG_DDR3/*DDR3*/
+	ddrType = 3;
+#endif
+	printf("       DDR%d    @ %d [MHz]\n", ddrType, CONFIG_SYS_BUS_CLK/1000000);
+	printf("       DDR%d %d Bit Width,%s Memory Access, DLB %s, ECC %s",
+			ddrType, mvCtrlDDRBudWidth(),
 			mvCtrlDDRThruXbar() ? "XBAR" : "FastPath",
 			mvCtrlIsDLBEnabled() ? "Enabled" : "Disabled",
 			mvCtrlDDRECC() ? "Enabled" : "Disabled");
@@ -1124,6 +1139,7 @@
 #endif
 	/* init the units decode windows */
 	misc_init_r_dec_win();
+	mv_print_map();
 	memset((void*)CONFIG_SYS_LOAD_ADDR, 0, CONFIG_SYS_MIN_HDR_DEL_SIZE);
 	mvBoardDebugLed(6);
 
@@ -1143,13 +1159,20 @@
 
 	setenv("pcieTune", "no");
 
+
+
 #if defined(MV_INCLUDE_UNM_ETH) || defined(MV_INCLUDE_GIG_ETH)
 	mvBoardEgigaPhyInit();
 #endif
 #if defined(CONFIG_CMD_DATE)
 	rtc_init(); /* Ensure the bus bridge parameters are ready for RTC access */
 #endif
-
+#ifdef CONFIG_CMD_SOURCE
+	/* run saved script */
+	env = getenv("run_script");
+	if (env && strcmp(env, "yes") == 0)
+		run_command("mvsource run", 0);
+#endif
 	return 0;
 }
 
diff --git a/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.c b/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.c
index 827db7c..a4d0307 100644
--- a/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.c
+++ b/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.c
@@ -103,6 +103,32 @@
 MV_U32 boardOptionsConfig[MV_CONFIG_TYPE_MAX_OPTION];
 
 /*******************************************************************************
+* mvBoardisUsbPortConnected
+*
+* DESCRIPTION:
+*       return True if requested USB type and port num exists on current board
+*
+* INPUT:
+*       usbTypeID       - requested USB type : USB3_UNIT_ID / USB_UNIT_ID
+*       usbPortNumbder  - requested USB port number (according to xHCI MAC port num)
+*
+* OUTPUT: None
+*
+* RETURN: MV_TRUE if requested port/type exist on board
+
+*******************************************************************************/
+MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber)
+{
+	/* USB Port board mapping is not supported by Avanta-LP
+	  Controller mapping is done via mvCtrlUsbMapGet.*/
+	if (usbPortNumber >= mvCtrlUsbMaxGet())
+		return MV_FALSE;
+	return MV_TRUE;
+}
+
+
+
+/*******************************************************************************
 * mvBoardIdIndexGet
 *
 * DESCRIPTION:
@@ -1702,6 +1728,41 @@
 }
 
 /*******************************************************************************
+* mvBoardIsSwitchConnected
+*
+* DESCRIPTION:
+*       This routine returns port's connection status, this route provide a unified inerface
+*       for other modules to call without care of the switch conntection mode - external or internal
+*       if the switch is connected
+*
+* INPUT:
+*       ethPortNum - Ethernet port number.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       1 - if ethPortNum is connected to switch, 0 otherwise
+*
+*******************************************************************************/
+MV_STATUS mvBoardIsSwitchConnected(void)
+{
+	return mvBoardIsInternalSwitchConnected();
+
+}
+
+/* this temporary functions to compile switch code.
+   mvEthE6171SwitchBasicInit is not used by alp code */
+MV_BOOL mvBoardSwitchCpuPortIsRgmii(MV_U32 switchIdx)
+{
+	return MV_FALSE;
+}
+MV_32 mvBoardSwitchPhyAddrGet(MV_U32 switchIdx)
+{
+	return -1;
+}
+
+/*******************************************************************************
 * mvBoardFreqModesNumGet
 *
 * DESCRIPTION: Return the number of supported frequency modes for this SoC
diff --git a/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.h b/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.h
index f215473..f67ca3d 100755
--- a/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.h
+++ b/board/mv_ebu/alp/avanta_lp_family/boardEnv/mvBoardEnvLib.h
@@ -613,7 +613,10 @@
 MV_U8 mvBoardCpuFreqGet(MV_VOID);
 MV_STATUS mvBoardCpuFreqSet(MV_U8 freqVal);
 MV_STATUS mvBoardIsInternalSwitchConnected(void);
+MV_BOOL mvBoardSwitchCpuPortIsRgmii(MV_U32 switchIdx);
+MV_32 mvBoardSwitchPhyAddrGet(MV_U32 switchIdx);
 MV_U32 mvBoardSwitchPortForceLinkGet(MV_U32 switchIdx);
+MV_STATUS mvBoardIsSwitchConnected(void);
 MV_U32 mvBoardFreqModesNumGet(void);
 MV_32 mvBoardSmiScanModeGet(MV_U32 switchIdx);
 MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
@@ -638,6 +641,7 @@
 MV_NFC_ECC_MODE mvBoardNandECCModeGet(void);
 MV_STATUS mvBoardEepromWriteDefaultCfg(void);
 MV_NAND_IF_MODE mvBoardNandIfGet(void);
+MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber);
 #ifdef __cplusplus
 }
 #endif  /* __cplusplus */
diff --git a/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.c b/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.c
index f0a9f1c..581da38 100644
--- a/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.c
+++ b/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.c
@@ -217,6 +217,28 @@
 
 	return MV_ERROR;
 }
+/******************************************************************************
+* mvCtrlIsUsbSerDesConnected
+*
+* DESCRIPTION:check if SerDes lane is connected to USB3 host.
+*
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:return true if SerDes lane is connected to USB3 host, false otherwise.
+*
+*
+*******************************************************************************/
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort)
+{
+	int usb3HostNum = mvCtrlUsb3HostMaxGet();
+	int maxSerDesLanes = mvCtrlUsb3MaxGet();
+	if (usbPort >= maxSerDesLanes && usb3HostNum > maxSerDesLanes)
+		return MV_FALSE;
+	return MV_TRUE;
+}
 
 #ifdef MV_INCLUDE_PEX
 MV_STATUS mvCtrlUpdatePexId(MV_VOID)
diff --git a/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.h b/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.h
index 10784cd..a2d51f1 100644
--- a/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.h
+++ b/board/mv_ebu/alp/avanta_lp_family/ctrlEnv/mvCtrlEnvLib.h
@@ -265,6 +265,7 @@
 MV_STATUS mvCtrlSatRWrite(MV_SATR_TYPE_ID satrReadField, MV_U8 val, MV_BOOL restoreDefault);
 MV_STATUS mvCtrlSatRRead(MV_SATR_TYPE_ID satrField, MV_U32 *value);
 MV_STATUS mvCtrlCpuDdrL2FreqGet(MV_FREQ_MODE *freqMode);
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort);
 MV_VOID mvCtrlSatrInit(MV_VOID);
 MV_U32 mvCtrlGetCpuNum(MV_VOID);
 MV_BOOL mvCtrlIsSscgEnabled(MV_VOID);
diff --git a/board/mv_ebu/alp/mv_main_alp.c b/board/mv_ebu/alp/mv_main_alp.c
index 7e86320..320969a 100644
--- a/board/mv_ebu/alp/mv_main_alp.c
+++ b/board/mv_ebu/alp/mv_main_alp.c
@@ -302,7 +302,6 @@
 			*(unsigned int*)(CONFIG_SYS_TEXT_BASE + i);
 
 	mvBoardDebugLed(4);
-	mv_print_map();
 	return 0;
 }
 
@@ -319,7 +318,7 @@
 	env = getenv("mtdids");
 	if (!env) {
 #if defined(MV_NAND) && defined(MV_INCLUDE_SPI)
-		setenv("mtdids", "nand0=armada-nand;spi0=spi_flash");
+		setenv("mtdids", "nand0=armada-nand,spi0=spi_flash");
 #elif defined(MV_NAND)
 		setenv("mtdids", "nand0=armada-nand");
 #elif defined(MV_INCLUDE_SPI)
@@ -495,6 +494,12 @@
 	if (!env)
 		setenv("initrd_name", "uInitrd");
 
+#ifdef CONFIG_CMD_SOURCE
+	env = getenv("run_script");
+	if (!env)
+		setenv("run_script", "no");
+#endif
+
 	/* netbsd boot arguments */
 	env = getenv("netbsd_en");
 	if ( !env || ( ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0) )))
@@ -1045,6 +1050,7 @@
 #if !defined(CONFIG_MACH_AVANTA_LP_FPGA)
 	/* init the units decode windows */
 	misc_init_r_dec_win();
+	mv_print_map();
 	memset((void*)CONFIG_SYS_LOAD_ADDR, 0, CONFIG_SYS_MIN_HDR_DEL_SIZE);
 	mvBoardDebugLed(6);
 
@@ -1069,7 +1075,12 @@
 	mvBoardEgigaPhyInit();
 #endif
 #endif
-
+#ifdef CONFIG_CMD_SOURCE
+	/* run saved script */
+	env = getenv("run_script");
+	if (env && strcmp(env, "yes") == 0)
+		run_command("mvsource run", 0);
+#endif
 	return 0;
 }
 
diff --git a/board/mv_ebu/common/Makefile b/board/mv_ebu/common/Makefile
index 9c46bf0..4f68969 100644
--- a/board/mv_ebu/common/Makefile
+++ b/board/mv_ebu/common/Makefile
@@ -17,6 +17,7 @@
 MAKE_PPV2 = yes
 MAKE_GENERAL_U_BOOT_TOOLS = yes
 MAKE_SPI_NAND = yes
+MAKE_SWITCH = yes
 endif
 
 ifeq ($(BOARD),a375)
@@ -33,6 +34,10 @@
 MAKE_GENERAL_U_BOOT_TOOLS = yes
 MAKE_SPI_NAND = yes
 MAKE_RTC2 = yes
+ifdef CONFIG_ARMADA_38X
+MAKE_SWITCH_SERVICES = yes
+endif
+MAKE_SWITCH = yes
 endif
 
 ifeq ($(BOARD),msys)
@@ -99,6 +104,7 @@
 		$(USP_DIR)/mv_cmd.o		\
 		$(USP_DIR)/mv_dram.o		\
 		$(USP_DIR)/cmd_bubt.o		\
+		$(USP_DIR)/cmd_mvsource.o	\
 		$(USP_DIR)/cmd_resetenv.o	\
 		$(USP_DIR)/mvDramScrubbing.o	\
 		$(USP_DIR)/cmd_ddr.o		\
@@ -119,12 +125,13 @@
 		$(HAL_PP2_CLS_DIR)/mvPp2Classifier.o	\
 		$(HAL_PP2_COMMON_DIR)/mvPp2Common.o	\
 		$(USP_DIR)/mv_egiga_pp2.o
-
-USP_OBJS +=	$(USP_ETH_SWITCH_DIR)/mvSwitch.o
 endif
 
 ifdef MAKE_SWITCH_SERVICES
-USP_OBJS +=     $(USP_DIR)/switchingServices/switchingServices.o
+USP_OBJS +=	$(USP_DIR)/switchingServices/switchingServices.o
+ifeq ($(BOARD),a38x)
+USP_OBJS +=	$(USP_DIR)/switchingServices/sar_bc2.o
+endif
 endif
 
 ifdef MAKE_NETA
@@ -135,6 +142,9 @@
 		$(USP_DIR)/mv_egiga_neta.o
 endif
 
+ifdef MAKE_SWITCH
+USP_OBJS +=	$(USP_ETH_SWITCH_DIR)/mvSwitch.o
+endif
 
 ifdef MAKE_USB
 HAL_IF_OBJS += 	$(HAL_IF_DIR)/mvSysUsb.o
diff --git a/board/mv_ebu/common/USP/cmd_bubt.c b/board/mv_ebu/common/USP/cmd_bubt.c
index 63852ad..6f76bf1 100755
--- a/board/mv_ebu/common/USP/cmd_bubt.c
+++ b/board/mv_ebu/common/USP/cmd_bubt.c
@@ -31,6 +31,8 @@
 
 #include <fs.h>
 
+#define	DESTINATION_STRING	10
+
 #if defined(CONFIG_CMD_NAND)
 #include <nand.h>
 extern nand_info_t nand_info[];       /* info for NAND chips */
@@ -131,11 +133,13 @@
 /*
  * Extract arguments from bubt command line
  * argc, argv are the input arguments of bubt command line
- * loadfrom is pointer to the extracted argument: from where to load the u-boot bin file
+ * loadfrom is a pointer to the extracted argument: from where to load the u-boot bin file
+ * destination_burn is a pointer to a string which denotes the bubt interface 
  */
-MV_STATUS fetch_bubt_cmd_args(int argc, char * const argv[], MV_U32 *loadfrom)
+MV_STATUS fetch_bubt_cmd_args(int argc, char * const argv[], int *loadfrom, char *destination_burn)
 {
 	*loadfrom = 0;
+	strcpy(destination_burn,"default");
 	/* bubt */
 	if (argc < 2) {
 		copy_filename (BootFile, "u-boot.bin", sizeof(BootFile));
@@ -146,6 +150,7 @@
 		if ((0 == strcmp(argv[1], "spi")) || (0 == strcmp(argv[1], "nand"))
 				|| (0 == strcmp(argv[1], "nor")))
 		{
+			strcpy(destination_burn, argv[1]);
 			copy_filename (BootFile, "u-boot.bin", sizeof(BootFile));
 			printf("Using default filename \"u-boot.bin\" \n");
 		}
@@ -159,6 +164,7 @@
 		if ((0 == strcmp(argv[1], "spi")) || (0 == strcmp(argv[1], "nand"))
 				|| (0 == strcmp(argv[1], "nor")))
 		{
+			strcpy(destination_burn, argv[1]);
 			copy_filename (BootFile, "u-boot.bin", sizeof(BootFile));
 			printf("Using default filename \"u-boot.bin\" \n");
 
@@ -174,12 +180,16 @@
 		}
 		else
 		{
+			strcpy(destination_burn, argv[2]);
+
 			copy_filename (BootFile, argv[1], sizeof(BootFile));
 		}
 	}
 	/* "bubt filename destination source" */
 	else
 	{
+		strcpy(destination_burn, argv[2]);
+
 		copy_filename (BootFile, argv[1], sizeof(BootFile));
 
 		if (0 == strcmp("usb", argv[3])) {
@@ -230,20 +240,19 @@
 	return filesize;
 }
 
-#if defined(MV_NAND_BOOT)
+#if defined(MV_NAND_BOOT) || defined(MV_NAND)
 /* Boot from NAND flash */
 /* Write u-boot image into the nand flash */
-int nand_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int nand_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int loadfrom, int argc, char * const argv[])
 {
 	int filesize = 0;
 	MV_U32 ret = 0;
 	extern char console_buffer[];
 	nand_info_t *nand = &nand_info[0];
 	size_t blocksize = nand_info[0].erasesize;
-	size_t env_offset = CONFIG_ENV_OFFSET;
+	size_t env_offset = CONFIG_ENV_OFFSET_NAND;
 	size_t size = CONFIG_UBOOT_SIZE;
 	size_t offset = 0;
-	MV_U32 loadfrom = 0; /* 0 - from tftp, 1 - from USB */
 
 	/* Align U-Boot size to currently used blocksize */
 	size = ((size + (blocksize - 1)) & (~(blocksize-1)));
@@ -267,9 +276,6 @@
 #endif
 
 	/* verify requested source is valid */
-	if (fetch_bubt_cmd_args(argc, argv, &loadfrom) != MV_OK)
-		return 0;
-
 	if ((filesize = fetch_uboot_file (loadfrom)) <= 0)
 		return 0;
 
@@ -284,8 +290,8 @@
 	    strcmp(console_buffer,"yes") == 0 ||
 	    strcmp(console_buffer,"y") == 0 ) {
 
-		printf("Erasing 0x%x - 0x%x:",env_offset, env_offset + CONFIG_ENV_RANGE);
-		nand_erase(nand, env_offset, CONFIG_ENV_RANGE);
+		printf("Erasing 0x%x - 0x%x:",env_offset, env_offset + CONFIG_ENV_RANGE_NAND);
+		nand_erase(nand, env_offset, CONFIG_ENV_RANGE_NAND);
 		printf("\t[Done]\n");
 	}
 
@@ -303,27 +309,18 @@
 	return 1;
 }
 
-U_BOOT_CMD(
-		bubt,      4,     1,      nand_burn_uboot_cmd,
-		"bubt	- Burn an image on the Boot Nand Flash.\n",
-		"[file-name] [destination [source]] \n"
-		"\tBurn a binary image on the Boot Flash, default file-name is u-boot.bin .\n"
-		"\tdestination is nand, spi or nor.\n"
-		"\tsource can be tftp or usb, default is tftp.\n"
-);
 #endif /* defined(CONFIG_NAND_BOOT) */
 
-#if defined(MV_SPI_BOOT)
+#if defined(MV_SPI_BOOT) || defined(MV_INCLUDE_SPI)
 
 /* Boot from SPI flash */
 /* Write u-boot image into the SPI flash */
-int spi_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int spi_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int loadfrom, int argc, char * const argv[])
 {
 	int filesize = 0;
 	MV_U32 ret = 0;
 	extern char console_buffer[];
 	load_addr = CONFIG_SYS_LOAD_ADDR;
-	MV_U32 loadfrom = 0; /* 0 - from tftp, 1 - from USB */
 
 	if(!flash) {
 		flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
@@ -336,9 +333,6 @@
 	}
 
 	/* verify requested source is valid */
-	if (fetch_bubt_cmd_args(argc, argv, &loadfrom) != MV_OK)
-		return 0;
-
 	if ((filesize = fetch_uboot_file (loadfrom)) <= 0)
 		return 0;
 
@@ -355,17 +349,17 @@
 	    strcmp(console_buffer,"yes") == 0 ||
 	    strcmp(console_buffer,"y") == 0 ) {
 
-		printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET, CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE);
-		spi_flash_erase(flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE);
+		printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET_SPI, CONFIG_ENV_OFFSET_SPI + CONFIG_ENV_SIZE_SPI);
+		spi_flash_erase(flash, CONFIG_ENV_OFFSET_SPI, CONFIG_ENV_SIZE_SPI);
 		printf("\t[Done]\n");
 	}
-	if (filesize > CONFIG_ENV_OFFSET)
+	if (filesize > CONFIG_ENV_OFFSET_SPI)
 	{
 		printf("Error: Image size (%x) exceeds environment variables offset (%x). ",filesize,CONFIG_ENV_OFFSET);
 		return 0;
 	}
-	printf("Erasing 0x%x - 0x%x: ",0, 0 + CONFIG_ENV_OFFSET);
-	spi_flash_erase(flash, 0, CONFIG_ENV_OFFSET);
+	printf("Erasing 0x%x - 0x%x: ",0, 0 + CONFIG_ENV_OFFSET_SPI);
+	spi_flash_erase(flash, 0, CONFIG_ENV_OFFSET_SPI);
 	printf("\t\t[Done]\n");
 
 	printf("Writing image to flash:");
@@ -384,22 +378,13 @@
 	return 1;
 }
 
-U_BOOT_CMD(
-		bubt,      4,     1,      spi_burn_uboot_cmd,
-		"bubt	- Burn an image on the Boot SPI Flash.\n",
-		" file-name \n"
-		"[file-name] [destination [source]] \n"
-		"\tBurn a binary image on the Boot Flash, default file-name is u-boot.bin .\n"
-		"\tdestination is nand, spi or nor.\n"
-		"\tsource can be tftp or usb, default is tftp.\n"
-);
 #endif
 
 
-#if defined(MV_NOR_BOOT)
+#if defined(MV_NOR_BOOT) || (MV_INCLUDE_NOR)
 
 /* Boot from Nor flash */
-int nor_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int nor_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int loadfrom, int argc, char * const argv[])
 {
 	int filesize = 0;
 	MV_U32 ret = 0;
@@ -414,12 +399,8 @@
 //	s_end = flash_in_which_sec(&flash_info[0], CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN -1);
 //	env_sec = flash_in_which_sec(&flash_info[0], CONFIG_ENV_ADDR);
 
-	MV_U32 loadfrom = 0; /* 0 - from tftp, 1 - from USB */
 
 	/* verify requested source is valid */
-	if (fetch_bubt_cmd_args(argc, argv, &loadfrom) != MV_OK)
-		return 0;
-
 	if ((filesize = fetch_uboot_file (loadfrom)) <= 0)
 		return 0;
 
@@ -463,27 +444,17 @@
 	return 1;
 }
 
-U_BOOT_CMD(
-		bubt,      4,     1,      nor_burn_uboot_cmd,
-		"bubt	- Burn an image on the Boot Flash.\n",
-		" file-name \n"
-		"[file-name] [destination [source]] \n"
-		"\tBurn a binary image on the Boot Flash, default file-name is u-boot.bin .\n"
-		"\tdestination is nand, spi or nor.\n"
-		"\tsource can be tftp or usb, default is tftp.\n"
-);
 #endif /* MV_NOR_BOOT */
 
 #if defined(MV_MMC_BOOT)
 
 /* Boot from SD/MMC/eMMC */
 /* Write u-boot image into SD/MMC/eMMC device */
-int mmc_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int mmc_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int loadfrom, int argc, char * const argv[])
 {
 	int filesize = 0;
 	extern char console_buffer[];
 	load_addr = CONFIG_SYS_LOAD_ADDR;
-	MV_U32 loadfrom = 0; /* 0 - from tftp, 1 - from USB */
 	lbaint_t	start_lba;
 	lbaint_t	blk_count;
 	ulong		blk_written;
@@ -514,9 +485,6 @@
 #endif
 
 	/* verify requested source is valid */
-	if (fetch_bubt_cmd_args(argc, argv, &loadfrom) != MV_OK)
-		return 0;
-
 	if ((filesize = fetch_uboot_file (loadfrom)) <= 0)
 		return 0;
 
@@ -565,12 +533,76 @@
 	return 1;
 }
 
+#endif
+
+int burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char	destination_burn[DESTINATION_STRING];
+	int	loadfrom = 0; /* 0 - from tftp, 1 - from USB */
+
+	memset(destination_burn, '\0', sizeof(destination_burn));
+
+	if(fetch_bubt_cmd_args(argc, argv, &loadfrom,destination_burn) != MV_OK)
+		return 0;
+
+#if defined(MV_CROSS_FLASH_BOOT)
+	if (0 == strcmp(destination_burn, "nand")) {
+#if defined(MV_NAND) || defined(MV_NAND_BOOT)
+		return nand_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+		printf("\t[FAIL] - u-boot does not support a write to %s interface.\n",destination_burn);
+		return 0;
+	}
+
+	if (0 == strcmp(destination_burn, "spi")) {
+#if defined(MV_INCLUDE_SPI) || defined (MV_SPI_BOOT)
+		return spi_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+		printf("\t[FAIL] - u-boot does not support a write to %s interface.\n",destination_burn);
+		return 0;
+	}
+
+	if (0 == strcmp(destination_burn, "nor")) {
+#if defined(MV_INCLUDE_NOR) || defined (MV_NOR_BOOT)
+		return nor_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+		printf("\t[FAIL] - u-boot does not support a write to %s interface.\n",destination_burn);
+		return 0;
+	}
+#endif
+
+#if defined(MV_NAND_BOOT)
+		return nand_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+#if defined(MV_SPI_BOOT)
+		return spi_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+#if defined(MV_NOR_BOOT)
+		return nor_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+#if defined(MV_MMC_BOOT)
+		return mmc_burn_uboot_cmd(cmdtp, flag, loadfrom, argc, argv);
+#endif
+
+		return 1;
+}
+
+#if defined(MV_MMC_BOOT)
 U_BOOT_CMD(
-		bubt,      3,     1,      mmc_burn_uboot_cmd,
-		"bubt	- Burn an image on the Boot SD/MMC/eMMC device.\n",
+		bubt,      3,     0,      burn_uboot_cmd,
+		"bubt	- Burn an image on the Boot device.\n",
 		" file-name \n"
 		"[file-name] [source] \n"
 		"\tBurn a binary image on the Boot Device, default file-name is u-boot.bin .\n"
 		"\tsource can be tftp or usb, default is tftp.\n"
 );
+#else
+U_BOOT_CMD(
+		bubt,      4,     0,      burn_uboot_cmd,
+		"bubt	- Burn an image on the Boot flash device.\n",
+		"[file-name] [destination [source]] \n"
+		"\tBurn a binary image on the Boot Device, default file-name is u-boot.bin .\n"
+		"\tsource can be tftp or usb, default is tftp.\n"
+		"\texample: bubt u-boot.bin nand tftp\n"
+		);
 #endif
diff --git a/board/mv_ebu/common/USP/cmd_mvsource.c b/board/mv_ebu/common/USP/cmd_mvsource.c
new file mode 100644
index 0000000..70502b0
--- /dev/null
+++ b/board/mv_ebu/common/USP/cmd_mvsource.c
@@ -0,0 +1,538 @@
+#include <config.h>
+#include <common.h>
+#include "mvCommon.h"
+#include <command.h>
+#include <net.h>
+#include <environment.h>
+
+#ifdef CONFIG_CMD_SOURCE
+#if defined(MV_INCLUDE_USB)
+#include <usb.h>
+#endif
+
+#include <fs.h>
+
+#define	DESTINATION_STRING	10
+
+#if defined(CONFIG_CMD_NAND)
+#include <nand.h>
+extern nand_info_t nand_info[];       /* info for NAND chips */
+#endif
+
+#ifdef CONFIG_CMD_SF
+#include <spi_flash.h>
+extern struct spi_flash *flash;
+#endif
+
+#ifdef CONFIG_CMD_FLASH
+#include <flash.h>
+extern flash_info_t flash_info[];       /* info for FLASH chips */
+#endif
+
+#include <image.h>
+#include <malloc.h>
+
+int dest_flash; /* destination flash to burn the script (0 = SPI, 1 = NAND) */
+
+#ifdef MV_INCLUDE_USB
+/*******************************************************************************
+* load_from_usb
+*
+* DESCRIPTION:
+* Load script file from usb device
+*
+* INPUT:
+*	file_name	- img file name.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	- file size on success
+*	- 0, otherwise
+*
+*******************************************************************************/
+static int load_from_usb(const char *file_name)
+{
+	const char *addr_str;
+	unsigned long addr;
+	int filesize = 0;
+
+	usb_stop();
+	printf("(Re)start USB...\n");
+
+	if (usb_init() < 0) {
+		printf("usb_init failed\n");
+		return 0;
+	}
+
+	/* try to recognize storage devices immediately */
+	/* the parameter '1', tells the function to reports to the
+	 * user while scanning for device */
+	if (-1 == usb_stor_scan(1)) {
+		printf("USB storage device not found\n");
+		return 0;
+	}
+
+	/* always load from usb 0 */
+	if (fs_set_blk_dev("usb", "0", FS_TYPE_ANY)) {
+		printf("USB 0 not found\n");
+		return 0;
+	}
+
+	addr_str = getenv("loadaddr");
+	if (addr_str != NULL)
+		addr = simple_strtoul(addr_str, NULL, 16);
+	else
+		addr = CONFIG_SYS_LOAD_ADDR;
+
+	filesize = fs_read(file_name, addr, 0, 0);
+	return filesize;
+}
+#endif
+
+/*******************************************************************************
+* fetch_script_file
+*
+* DESCRIPTION:
+* Load script file into ram from external device: tftp, usb
+*
+* INPUT:
+*	loadfrom	- specifies the source device:
+*			  0 - TFTP, 1 - USB
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	- file size on success
+*	- 0, otherwise
+*
+*******************************************************************************/
+static int fetch_script_file(int loadfrom)
+{
+	int filesize = 0;
+	switch (loadfrom) {
+#ifdef MV_INCLUDE_USB
+	case 1:
+		filesize = load_from_usb(BootFile);
+		if (filesize <= 0) {
+			printf("Failed to read file %s\n", BootFile);
+			return 0;
+		}
+		break;
+#endif
+	case 0:
+		filesize = NetLoop(TFTPGET);
+		printf("Checking file size:");
+		if (filesize == -1) {
+			printf("\t[Fail]\n");
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	return filesize;
+}
+
+/*******************************************************************************
+* fetch_mvsource_cmd_args
+*
+* DESCRIPTION:
+* fetch command arguments from argv and return them in variables
+*
+* INPUT:
+*	argc		- command arguments' number
+*	argv		- command arguments' values
+*
+* OUTPUT:
+*	command		- command to run (0 = burn, 1 = run)
+*	offset		- offset in flash to burn the script
+*	loadfrom	- source interface (0 = TFTP, 1 = USB)
+*	dest		- destination flash if multiple flashes supported
+*			  (0 = SPI, 1 = NAND)
+*
+* RETURN:
+*	- MV_OK on success
+*	- MV_FAIL, otherwise
+*
+*******************************************************************************/
+static MV_STATUS fetch_mvsource_cmd_args(int argc, char * const argv[],
+		int *command, MV_U32 *offset, int *loadfrom, int *dest) {
+	int i;
+	const char *default_name = "script.img";
+
+	*command = -1;		/* 0 = burn; 1 = run; -1 = invalid command */
+	*offset = 0x300000;
+	*loadfrom = 0;		/* 0 = TFTP; 1 = USB */
+	*dest = 0;		/* 0 = SPI; 1 = NAND */
+
+	/* fetch destination interface (if exists), else use SPI as default */
+	for (i = 0; i < argc; ++i) {
+		if (strcmp(argv[i], "spi") == 0) {
+			*dest = 0;
+			argc--;
+			break;
+		} else if (strcmp(argv[i], "nand") == 0) {
+			*dest = 1;
+			argc--;
+			break;
+		}
+	}
+
+	if (argc < 2) { /* empty command is unacceptable */
+		printf("Error: too few arguments\n");
+		return MV_FAIL;
+	}
+
+	/* skip main command name */
+	argc--;
+	argv++;
+	if (strcmp(argv[0], "burn") == 0) {
+		*command = 0;
+		/* only burn command have filename as 1st parameter */
+		if (argc > 1) {
+			strncpy(BootFile, argv[1], strlen(argv[1]));
+			argc--;
+			argv++;
+		} else {
+			strncpy(BootFile, default_name, strlen(default_name));
+			printf("using default filename \"%s\"\n", default_name);
+		}
+	} else if (strcmp(argv[0], "run") == 0)
+		*command = 1;
+	else {
+		printf("Error: unknown command\n");
+		return MV_FAIL;
+	}
+
+	/* skip internal command name ('burn' or 'run') */
+	argc--;
+	argv++;
+	switch (argc) {
+	case 2:
+		if (strcmp(argv[1], "tftp") == 0)
+			*loadfrom = 0;
+		else if (strcmp(argv[1], "usb") == 0)
+			*loadfrom = 1;
+		else
+			return MV_FAIL;
+	case 1:
+		*offset = simple_strtoul(argv[0], NULL, 16);
+	default:
+		break;
+	}
+	return MV_OK;
+}
+
+#if defined(MV_INCLUDE_SPI)
+/*******************************************************************************
+* init_spi
+*
+* DESCRIPTION:
+* init spi flash if not initiated
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	0	on success
+*	-1	otherwise
+*
+*******************************************************************************/
+static int init_spi(void){
+	if (!flash) {
+		flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+								CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+		if (!flash) {
+			printf("Failed to probe SPI Flash\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/*******************************************************************************
+* spi_burn_script
+*
+* DESCRIPTION:
+* burn script image to the SPI flash
+*
+* INPUT:
+*	offset		- offset in flash to burn the script
+*	loadfrom	- source interface to fetch the file (0 = TFTP, 1 = USB)
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	None.
+*
+*******************************************************************************/
+static void spi_burn_script(MV_U32 offset, int loadfrom)
+{
+	int filesize = 0;
+	MV_U32 ret = 0;
+	load_addr = CONFIG_SYS_LOAD_ADDR;
+	u32 sector_size, aligned_size;
+
+	if (init_spi())
+		return;
+
+	sector_size =  flash->sector_size;
+
+	/* verify requested source is valid */
+	filesize = fetch_script_file(loadfrom);
+	if (filesize <= 0)
+		return;
+
+	aligned_size = ((filesize + (sector_size - 1)) & (~(sector_size - 1)));
+	printf("Erasing 0x%x - 0x%x: ", offset, offset + aligned_size);
+	spi_flash_erase(flash, offset, aligned_size);
+	printf("\t\t[Done]\n");
+
+	printf("Writing image to flash:");
+	ret = spi_flash_write(flash, offset, filesize, (const void *)load_addr);
+
+	if (ret)
+		printf("\t\t[Err!]\n");
+	else
+		printf("\t\t[Done]\n");
+}
+#endif /* MV_INCLUDE_SPI */
+
+#if defined(MV_NAND)
+/*******************************************************************************
+* spi_burn_script
+*
+* DESCRIPTION:
+* burn script image to the NAND flash
+*
+* INPUT:
+*	offset		- offset in flash to burn the script
+*	loadfrom	- source interface to fetch the file (0 = TFTP, 1 = USB)
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	None.
+*
+*******************************************************************************/
+static void nand_burn_script(MV_U32 offset, int loadfrom)
+{
+	int filesize = 0;
+	MV_U32 ret = 0, aligned_size;
+	nand_info_t *nand = &nand_info[0];
+	size_t erasesize = nand_info[0].erasesize;
+
+	if (nand_block_isbad(&nand_info[0], offset)) {
+		printf("Failed to burn: Bad block at offset %X\n", offset);
+		return;
+	}
+
+	/* verify requested source is valid */
+	filesize = fetch_script_file(loadfrom);
+	if (filesize <= 0)
+		return;
+
+	aligned_size = ((filesize + (erasesize - 1)) & (~(erasesize - 1)));
+	printf("\t[Done]\n");
+	printf("Erasing 0x%x - 0x%x: ", offset, offset + aligned_size);
+	nand_erase(nand, offset, aligned_size);
+	printf("\t[Done]\n");
+
+	printf("Writing image to NAND:");
+	ret = nand_write(nand, offset, (size_t *)&filesize, (u_char *)load_addr);
+	if (ret)
+		printf("\t[Fail]\n");
+	else
+		printf("\t[Done]\n");
+}
+#endif /* defined(MV_NAND) */
+
+/*******************************************************************************
+* is_magic_valid
+*
+* DESCRIPTION:
+* checks if the magic value in script header is valid
+*
+* INPUT:
+*	header		- script header
+*
+* RETURN:
+*	MV_TRUE if magic value in header is valid
+*	MV_FALSE otherwise
+*
+*******************************************************************************/
+MV_BOOL is_magic_valid(image_header_t *header)
+{
+	/* check if image type is IMAGE_FORMAT_LEGACY */
+	if (be32_to_cpu(header->ih_magic) != IH_MAGIC)
+		return MV_FALSE;
+
+	return MV_TRUE;
+}
+
+/*******************************************************************************
+* get_image_size
+*
+* DESCRIPTION:
+* fetch script size (in bytes) from script header
+*
+* INPUT:
+*	offset		- script offset in flash
+*
+* OUTPUT:
+*	size		- script size (in bytes)
+*
+* RETURN:
+*	MV_OK on success fetching the size
+*	MV_FAIL otherwise
+*
+*******************************************************************************/
+MV_STATUS get_image_size(MV_U32 offset, MV_U32 *size)
+{
+	size_t buff_size = sizeof(image_header_t);
+	image_header_t header;
+#if defined(MV_INCLUDE_SPI)
+	if (init_spi())
+		return MV_FAIL;
+#endif
+#if defined(MV_INCLUDE_SPI) && defined(MV_NAND)
+		if (dest_flash == 0)
+			spi_flash_read(flash, offset, buff_size , &header);
+		else if (dest_flash == 1)
+			nand_read(&nand_info[0], offset, &buff_size, (u_char *)&header);
+#elif defined(MV_INCLUDE_SPI)
+	spi_flash_read(flash, offset, buff_size , &header);
+#elif defined(MV_NAND)
+	nand_read(&nand_info[0], offset, &buff_size, (u_char *)&header);
+#else
+	return MV_FAIL;
+#endif
+	if (is_magic_valid(&header) == MV_FALSE)
+		return MV_FAIL;
+
+	*size = be32_to_cpu(header.ih_size) + sizeof(image_header_t);
+	return MV_OK;
+}
+
+/*******************************************************************************
+* get_block_size
+*
+* DESCRIPTION:
+* get block size of flash
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	block size, on success
+*	0, otherwise
+*
+*******************************************************************************/
+MV_U32 get_block_size(void)
+{
+#if defined(MV_INCLUDE_SPI) && defined(MV_NAND)
+		if (dest_flash == 0)
+			return flash->sector_size;
+		else if (dest_flash == 1)
+			return nand_info[0].erasesize;
+		else
+			return 0;
+#elif defined(MV_INCLUDE_SPI)
+	return flash->sector_size;
+
+#elif defined(MV_NAND)
+	return nand_info[0].erasesize;
+#else
+	return 0;
+#endif
+}
+
+int mvsource_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int command, loadfrom;
+	MV_U32 offset;
+	char *buffer;
+	char buffer_address_str[30];	/* to pass to 'source' argument */
+	MV_U32 size;
+	char *source_argv[2];
+
+	if (fetch_mvsource_cmd_args(argc, argv, &command,
+				&offset, &loadfrom, &dest_flash) != MV_OK)
+		return 1;
+
+
+	if (command == 0) { /* 0 = burn */
+#if defined(MV_INCLUDE_SPI) && defined(MV_NAND)
+		if (dest_flash == 0)
+			spi_burn_script(offset, loadfrom);
+		else if (dest_flash == 1)
+			nand_burn_script(offset, loadfrom);
+#elif defined(MV_INCLUDE_SPI)
+		spi_burn_script(offset, loadfrom);
+#elif defined(MV_NAND)
+		nand_burn_script(offset, loadfrom);
+#endif
+	} else if (command == 1) { /* 1 = run */
+		if (get_image_size(offset, &size) != MV_OK) {
+			printf("Error: Failed to fetch script size\n");
+			return 1;
+		} else {
+			buffer = (char *)malloc(size);
+			if (!buffer) {
+				printf("Error: Failed to allocate memory\n");
+				return 1;
+			}
+		}
+#if defined(MV_INCLUDE_SPI) && defined(MV_NAND)
+		if (dest_flash == 0)
+			spi_flash_read(flash, offset, size , buffer);
+		else if (dest_flash == 1)
+			nand_read(&nand_info[0], offset, &size, (u_char *)buffer);
+#elif defined(MV_INCLUDE_SPI)
+		spi_flash_read(flash, offset, size , buffer);
+#elif defined(MV_NAND)
+		nand_read(&nand_info[0], offset, &size, (u_char *)buffer);
+#else
+		return 1;
+#endif
+		sprintf(buffer_address_str, "%lx", (unsigned long)buffer);
+		source_argv[0] = "source";
+		source_argv[1] = buffer_address_str;
+		do_source(cmdtp, 0, 2, source_argv);
+		free(buffer);
+	}
+	return 0;
+}
+
+U_BOOT_CMD(
+		mvsource,      5,     1,      mvsource_cmd,
+		"mvsource	- Burn a script image on flash device.\n",
+		"burn [file-name [offset [src_interface]]] [dst_flash]"
+		"\n\tBurn script <file-name> to flash at <offset> from <src_interface> \n"
+		"mvsource run [offset]"
+		"\n\tRun script from flash at <offset>\n"
+		"\nArguments (optional):\n"
+		"\t- file-name: script file name\t\t\t(default = script.bin)\n"
+		"\t- offset: script address in flash\t\t(default = 300000)\n"
+		"\t- src_interface: script source: tftp/usb\t(default = tftp)\n"
+		"\t- dst_flash: flash destination: spi/nand\t(default = spi)\n"
+		"Examples:\n"
+		"\tmvsource burn script.img 300000 tftp spi\n"
+		"\tmvsource burn\n"
+		"\tmvsource run 300000\n"
+		"\tmvsource run\n"
+		);
+
+#endif /* CONFIG_CMD_SOURCE */
diff --git a/board/mv_ebu/common/USP/ethSwitch/mvSwitch.c b/board/mv_ebu/common/USP/ethSwitch/mvSwitch.c
old mode 100755
new mode 100644
index 77af2ea..1b8477a
--- a/board/mv_ebu/common/USP/ethSwitch/mvSwitch.c
+++ b/board/mv_ebu/common/USP/ethSwitch/mvSwitch.c
@@ -69,12 +69,13 @@
 #include "mvCtrlEnvLib.h"
 #include "mvBoardEnvLib.h"
 
-
 static void switchVlanInit(MV_U32 ethPortNum,
 						   MV_U32 switchCpuPort,
 					   MV_U32 switchMaxPortsNum,
 					   MV_U32 switchPortsOffset,
 					   MV_U32 switchEnabledPortsMask);
+static MV_U16 mvEthSwitchGetDeviceIDInMultiorManualMode(void);
+static MV_U16 mvEthSwitchGetDeviceIDInAutoScanMode(MV_BOOL *highSmiDevAddr);
 
 void mvEthSwitchRegWrite(MV_U32 ethPortNum, MV_U32 phyAddr,
                                  MV_U32 regOffs, MV_U16 data);
@@ -84,6 +85,254 @@
 
 int switchMultiChipMode = 0xdeadbeef;
 
+static MV_32 switchDeviceID = -1;	/*-1 : initialized, 0 : no switch, other values are switch device ID*/
+static MV_U32 switchAccessMode = SMI_MANUAL_MODE;
+#ifdef MV_SWITCH_SMI_ACCESS
+static MV_32 switchPhyAddr = -1;
+#endif
+
+/*******************************************************************************
+* mvEthSwitchGetDeviceIDInMultiAddMode -
+*
+* DESCRIPTION:
+*	get switch device ID if switch is in SMI muti address access mode
+*
+* INPUT:
+*	None
+*
+* OUTPUT:
+*	None
+*
+* RETURN:   switch device ID
+*
+*******************************************************************************/
+static MV_U16 mvEthSwitchGetDeviceIDInMultiorManualMode(void)
+{
+	MV_U16 data;
+
+	/*read switch device ID, first try the case that port register offset is 8*/
+	data = 0;
+	mvEthSwitchRegRead(0, PORT_REGS_START_ADDR, QD_REG_SWITCH_ID, &data);
+
+	switch (data & 0xFF00) {
+	case 0x0200:
+	case 0x0300:
+	case 0x0500:
+	case 0x0600:
+	case 0x1500:
+	case 0xF500:
+	case 0xF900:
+	case 0x0700:	    /* Spinnaker */
+	case 0x2200:	    /* Spinnaker */
+	case 0x2500:	    /* Spinnaker */
+		return data;
+	case 0xC000:	    /* Melody, Now it could be 0xc00 - 0xc07 */
+		return data&0xFF0F;
+	default:
+	    break;
+	}
+
+	/*read switch device ID, second try the case that port register offset is 0x10*/
+	data = 0;
+	mvEthSwitchRegRead(0, PORT_REGS_START_ADDR_8PORT, QD_REG_SWITCH_ID, &data);
+
+	switch (data & 0xFF00) {
+	case 0x0800:
+	case 0x1A00:
+	case 0x1000:
+	case 0x0900:
+	case 0x0400:
+	case 0x1200:
+	case 0x1400:
+	case 0x1600:
+	case 0x3200:
+	case 0x1700:
+	case 0x3700:
+	case 0x2400:	/* Agate */
+	case 0x3500:	/* Agate */
+	case 0x1100:	/* Pearl */
+	case 0x3100:	/* Pearl */
+	case 0xc100:	/* ALP Fix */
+		return data;
+	default:
+	    break;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+* mvEthSwitchGetDevIDByPortRegStartInAuto -
+*
+* DESCRIPTION:
+*	get switch device ID by the switch port register start address if switch is in SMI auto scan access mode
+*
+* INPUT:
+*	portRegsStartAddr - switch port register start address
+*
+* OUTPUT:
+*	None
+*
+* RETURN:   switch device ID
+*
+*******************************************************************************/
+static MV_U16 mvEthSwitchGetDevIDByPortRegStartInAuto(MV_U32 portRegsStartAddr)
+{
+	MV_U16 data, data1;
+
+	/*read switch device ID from switch port 0 and 1, if the 2 values are equal and meaningful, then it's valid*/
+	data = 0;
+	mvEthSwitchRegRead(0, portRegsStartAddr, QD_REG_SWITCH_ID, &data);
+	data1 = 0;
+	mvEthSwitchRegRead(0, portRegsStartAddr + 1, QD_REG_SWITCH_ID, &data1);
+
+	switch (data & 0xFF00) {
+	case 0x0200:
+	case 0x0300:
+	case 0x0500:
+	case 0x0600:
+	case 0x1500:
+	case 0xC000:		/* Melody */
+	case 0x0700:		/* Spinnaker */
+	case 0x2200:		/* Spinnaker */
+	case 0x2500:		/* Spinnaker */
+	case 0xF500:
+	case 0xF900:
+		if (data == data1)
+			return data;
+	default:
+	    break;
+	}
+
+	return 0;
+
+}
+
+/*******************************************************************************
+* mvEthSwitchGetDeviceIDInAutoScanMode -
+*
+* DESCRIPTION:
+*	get switch device ID if switch is in SMI auto scan access mode
+*
+* INPUT:
+*	None
+*
+* OUTPUT:
+*	highSmiDevAddr - whether high SMI device address is used
+*
+* RETURN:   switch device ID
+*
+*******************************************************************************/
+static MV_U16 mvEthSwitchGetDeviceIDInAutoScanMode(MV_BOOL *highSmiDevAddr)
+{
+	MV_U16 data, data1;
+
+	/*read switch device ID, first try the case that port register offset is 8*/
+	data = mvEthSwitchGetDevIDByPortRegStartInAuto(PORT_REGS_START_ADDR);
+	if (data != 0) {
+		*highSmiDevAddr = MV_FALSE;
+		return data;
+	}
+
+	/*read switch device ID, second try the case that port register offset is 0x18*/
+	data = mvEthSwitchGetDevIDByPortRegStartInAuto(PORT_REGS_START_ADDR + 0x10);
+	if (data != 0) {
+		*highSmiDevAddr = MV_TRUE;
+		return data;
+	}
+
+	/*read switch device ID, finally try the case that port register offset is 0x10*/
+	data = 0;
+	mvEthSwitchRegRead(0, PORT_REGS_START_ADDR_8PORT, QD_REG_SWITCH_ID, &data);
+	data1 = 0;
+	mvEthSwitchRegRead(0, PORT_REGS_START_ADDR_8PORT + 1, QD_REG_SWITCH_ID, &data1);
+
+	switch (data & 0xFF00) {
+	case 0x0800:
+	case 0x1A00:
+	case 0x1000:
+	case 0x0900:
+	case 0x0400:
+	case 0x1200:
+	case 0x1400:
+	case 0x1600:
+	case 0x1700:
+	case 0x3200:
+	case 0x3700:
+	case 0x2400:    /* Agate */
+	case 0x3500:    /* Agate */
+	case 0x1100:    /* Pearl */
+	case 0x3100:    /* Pearl */
+		if (data == data1) {
+			*highSmiDevAddr = MV_FALSE;
+			return data;
+		}
+	default:
+	    break;
+	}
+
+	return 0;
+}
+
+
+/*******************************************************************************
+* mvEthSwitchGetDeviceID -
+*
+* DESCRIPTION:
+*	If switch device ID is not initialized, then detect switch device, find out switch device ID,
+*	access mode and PHY address, otherwise return switch device ID directly
+*
+* INPUT:
+*	None
+*
+* OUTPUT:
+*	highSmiDevAddr - Indicates whether to use the high device register
+*		addresses when accessing switch's registers (of all kinds)
+*		i.e, the devices registers range is 0x10 to 0x1F, or to
+*		use the low device register addresses (range 0x0 to 0xF).
+*		GT_TRUE     - use high addresses (0x10 to 0x1F).
+*		GT_FALSE    - use low addresses (0x0 to 0xF).
+*
+* RETURN:   switch device ID, 0 means no switch detected
+*
+*******************************************************************************/
+MV_U16 mvEthSwitchGetDeviceID(void)
+{
+	MV_BOOL		highSmiDevAddr;
+
+	/*if switchDeviceID has been initialized, then return it directly*/
+	if (switchDeviceID >= 0)
+		return (MV_U16)switchDeviceID;
+
+	/*if switch module is not detected, then reurn 0 - no switch detected*/
+	if (mvBoardIsSwitchConnected() == MV_FALSE) {
+		switchDeviceID = 0;
+		return (MV_U16)switchDeviceID;
+	}
+
+	switchAccessMode = mvBoardSmiScanModeGet(0);
+#ifdef MV_SWITCH_SMI_ACCESS
+	switchPhyAddr = mvBoardSwitchPhyAddrGet(0);
+	if ((switchPhyAddr == -1) && (switchAccessMode == SMI_MANUAL_MODE)) {
+		mvOsPrintf("switchPhyAddr value %d is error!\n", switchPhyAddr);
+		switchDeviceID = 0;
+		return switchDeviceID;
+	}
+#endif
+
+	if (switchAccessMode == SMI_MULTI_ADDR_MODE || switchAccessMode == SMI_MANUAL_MODE) {
+		switchDeviceID = mvEthSwitchGetDeviceIDInMultiorManualMode();
+		return (MV_U16)switchDeviceID;
+	} else if (switchAccessMode == SMI_AUTO_SCAN_MODE) {
+		switchDeviceID = mvEthSwitchGetDeviceIDInAutoScanMode(&highSmiDevAddr);
+		return (MV_U16)switchDeviceID;
+	} else {
+		switchDeviceID = 0;
+		return (MV_U16)switchDeviceID;
+	}
+}
+
+
 /*******************************************************************************
 * mvEthE6065_61PhyBasicInit -
 *
@@ -298,31 +547,43 @@
 }
 #endif /* MV88F66XX */
 
+/* This initial function is valid for E6176 switch */
 MV_VOID	mvEthE6171SwitchBasicInit(MV_U32 ethPortNum)
 {
 
 	MV_U32 prt;
 	MV_U16 reg;
 	volatile MV_U32 timeout;
-	MV_32 cpuPort =  mvBoardSwitchCpuPortGet(0);
+	MV_U32 cpuPort =  mvBoardSwitchCpuPortGet(0);
+	MV_U32 swicthPhyAddr = mvBoardSwitchPhyAddrGet(0);
 	/* The 6171 needs a delay */
 	mvOsDelay(1000);
 
 	/* Init vlan of switch 1 and enable all ports */
-	switchVlanInit(ethPortNum, MV_E6171_CPU_PORT, MV_E6171_MAX_PORTS_NUM, MV_E6171_PORTS_OFFSET,
-				   MV_E6171_ENABLED_PORTS);
+	switchVlanInit(ethPortNum, cpuPort, MV_E6171_MAX_PORTS_NUM, swicthPhyAddr, MV_E6171_ENABLED_PORTS);
 
-	/* Enable RGMII delay on Tx and Rx for port 5 switch 1 */
-	mvEthSwitchRegRead(ethPortNum, MV_E6171_PORTS_OFFSET + cpuPort, MV_E6171_SWITCH_PHIYSICAL_CTRL_REG, &reg);
-	mvEthSwitchRegWrite(ethPortNum, MV_E6171_PORTS_OFFSET + cpuPort, MV_E6171_SWITCH_PHIYSICAL_CTRL_REG,
-						 (reg|0xC000));
+	if (mvBoardSwitchCpuPortIsRgmii(0)) {
+		/* Enable RGMII delay on Tx and Rx for port 5 switch 1 */
+		mvEthSwitchRegRead(ethPortNum, swicthPhyAddr + cpuPort, MV_E6171_SWITCH_PHIYSICAL_CTRL_REG, &reg);
+		mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr + cpuPort, MV_E6171_SWITCH_PHIYSICAL_CTRL_REG,
+				(reg|0xC000));
+	} else {
+		/* If the CPU port is not connected to RGMII, so it connected
+		   to SGMII via SerDes lane, this code power-up the SerDes in switch */
+		/* Change to page #1 to access SerDes control register */
+		mvEthSwitchPhyRegWrite(ethPortNum, MV_E6171_SERDES_REG, MV_E6171_PAGE_REG, BIT0);
+		/* Read SerDes power down status of the switch */
+		mvEthSwitchPhyRegRead(ethPortNum, MV_E6171_SERDES_REG, MV_E6171_SERDES_CONTROL_REG, &reg);
+		/* Clear Bit 11 to power up the switch SerDes */
+		reg &= ~BIT11;
+		mvEthSwitchPhyRegWrite(ethPortNum, MV_E6171_SERDES_REG, MV_E6171_SERDES_CONTROL_REG, reg);
+	}
 
 	/* Power up PHYs */
-	for(prt=0; prt < MV_E6171_MAX_PORTS_NUM - 2; prt++)	{
-		if (prt != MV_E6171_CPU_PORT) {
+	for (prt = 0; prt < MV_E6171_MAX_PORTS_NUM - 2; prt++)	{
+		if (prt != cpuPort) {
 			/*Enable Phy power up for switch 1*/
-			mvEthSwitchRegWrite(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR,
-								 MV_E6171_SMI_PHY_DATA, 0x3360);
+			mvEthSwitchRegWrite(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR, MV_E6171_SMI_PHY_DATA, 0x3360);
 			mvEthSwitchRegWrite(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR, MV_E6171_SMI_PHY_COMMAND,
 								(0x9410 | (prt << 5)));
 			/*Make sure SMIBusy bit cleared before another SMI operation can take place*/
@@ -330,24 +591,23 @@
 
 			do {
 				mvEthSwitchRegRead(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR, MV_E6171_SMI_PHY_COMMAND,&reg);
-				if(timeout-- == 0) {
+				if (timeout-- == 0) {
 					mvOsPrintf("mvEthPhyRegRead: SMI busy timeout\n");
 					return;
 				}
-			} while (reg & E6171_PHY_SMI_BUSY_MASK); 
+			} while (reg & E6171_PHY_SMI_BUSY_MASK);
  
 			mvEthSwitchRegWrite(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR, MV_E6171_SMI_PHY_DATA,0x9140);
 			mvEthSwitchRegWrite(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR,
 								MV_E6171_SMI_PHY_COMMAND,(0x9400 | (prt << 5)));
 
-
 			/*Make sure SMIBusy bit cleared before another SMI operation can take place*/
 			timeout = E6171_PHY_TIMEOUT;
 
 			do {
 				mvEthSwitchRegRead(ethPortNum, MV_E6171_GLOBAL_2_REG_DEV_ADDR,
 								   MV_E6171_SMI_PHY_COMMAND,&reg);
-				if(timeout-- == 0) {
+				if (timeout-- == 0) {
 					mvOsPrintf("mvEthPhyRegRead: SMI busy timeout\n");
 					return;
 				}
@@ -355,31 +615,103 @@
 		}
 	}
 
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET + cpuPort, 0x4, 0x7f);
-	
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr + cpuPort, 0x4, 0x7f);
+
 	/* Init LEDs on RD-6282 */
 	/* Move all LEDs to special */
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET, 0x16, (BIT15|0x67));
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET, 0x16, (BIT15|BIT12|0x32));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr, MV_E6171_LED_CONTROL, (BIT15|0x67));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr, MV_E6171_LED_CONTROL, (BIT15|BIT12|0x32));
 
 	/* Port 0 LED special activity link */
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET, 0x16, (BIT15|BIT14|BIT13|BIT12|BIT0));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr, MV_E6171_LED_CONTROL, (BIT15|BIT14|BIT13|BIT12|BIT0));
 
 	/* Port 1 LED special activity link */
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET+1, 0x16, (BIT15|BIT14|BIT13|BIT12|BIT1));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr + 1, MV_E6171_LED_CONTROL, (BIT15|BIT14|BIT13|BIT12|BIT1));
 
 	/* Port 2 LED special activity link */
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET+2, 0x16, (BIT15|BIT14|BIT13|BIT12|BIT2));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr + 2, MV_E6171_LED_CONTROL, (BIT15|BIT14|BIT13|BIT12|BIT2));
 
 	/* Port 3 LED special activity link */
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET+3, 0x16, (BIT15|BIT14|BIT13|BIT12|BIT3));
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr + 3, MV_E6171_LED_CONTROL, (BIT15|BIT14|BIT13|BIT12|BIT3));
 
 #ifdef RD_88F6710
-	mvEthSwitchRegWrite(ethPortNum, MV_E6161_PORTS_OFFSET, 0x16, 0xf00f);
+	mvEthSwitchRegWrite(ethPortNum, swicthPhyAddr, MV_E6171_LED_CONTROL, 0xf00f);
 #endif
 
 }
 
+MV_VOID	mvEthE6172SwitchBasicInit(MV_U32 ethPortNum)
+{
+
+	MV_U32 prt;
+	MV_U16 reg;
+	MV_U32 timeout;
+	MV_32 cpuPort =  MV_E6172_CPU_PORT;/*mvBoardSwitchCpuPortGet(0);*/
+	MV_U16 smiReg, data;
+
+	/* The 6172 needs a delay */
+	mvOsDelay(1000);
+
+	/* Init vlan of switch 1 and enable all ports */
+	switchVlanInit(ethPortNum, MV_E6172_CPU_PORT, MV_E6172_MAX_PORTS_NUM, MV_E6172_PORTS_OFFSET,
+				   MV_E6172_ENABLED_PORTS);
+
+	/* Enable RGMII delay on Tx and Rx for cpu port, force duplex, link up,  flow control, and speed to 1Gps*/
+	mvEthSwitchRegWrite(ethPortNum, MV_E6172_PORTS_OFFSET + cpuPort, MV_E6172_SWITCH_PHIYSICAL_CTRL_REG,
+	QD_PCS_RGMII_RX_TIMING_MASK | QD_PCS_RGMII_TX_TIMING_MASK | QD_PCS_FLOW_CONTROL_VALUE_MASK
+	| QD_PCS_FORCED_FLOW_CONTROL_MASK | QD_PCS_LINK_VALUE_MASK | QD_PCS_FORCED_LINK_MASK
+	| QD_PCS_DUPLEX_VALUE_MASK | QD_PCS_FORCED_DUPLEX_MASK | QD_PCS_FORCE_SPEED_1G);
+	mvEthSwitchRegWrite(ethPortNum, MV_E6172_PORTS_OFFSET + cpuPort, MV_E6172_SWITCH_PORT_CTRL_REG,
+	QD_PC_VLAN_TUNNEL_BY_PASS | QD_PC_INITIAL_PRI_IP | QD_PC_EGRESS_FLOODS_ALL | QD_PC_PORT_STATE_FORWARDING);
+
+	/* Power up PHYs */
+	for (prt = 0; prt < MV_E6172_MAX_PORTS_NUM - 2; prt++)	{
+		if (prt != MV_E6172_CPU_PORT) {
+			/*Enable Phy power up for switch 1*/
+			data = QD_PHY_MDI_CROSS_AUTO | QD_PHY_ENERGY_DETECT_SENSE_PERIODIC_TX_NLP |
+			QD_PHY_DOWNSHIFT_COUNTER;
+			mvEthSwitchRegWrite(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR,
+								MV_E6172_SMI_PHY_DATA, data);
+			smiReg = (QD_SMI_BUSY | (prt << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_WRITE << QD_SMI_OP_BIT) |
+			(QD_PHY_SPEC_CONTROL_REG << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT));
+			mvEthSwitchRegWrite(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR,
+								MV_E6172_SMI_PHY_COMMAND, smiReg);
+			/*Make sure SMIBusy bit cleared before another SMI operation can take place*/
+			timeout = E6172_PHY_TIMEOUT;
+
+			do {
+				mvEthSwitchRegRead(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR,
+					MV_E6172_SMI_PHY_COMMAND, &reg);
+				if (timeout-- == 0) {
+					mvOsPrintf("mvEthPhyRegRead: SMI busy timeout\n");
+					return;
+				}
+			} while (reg & E6172_PHY_SMI_BUSY_MASK);
+
+			data = QD_PHY_RESET | QD_PHY_AUTONEGO | QD_PHY_DUPLEX | QD_PHY_SPEED_MSB;
+			mvEthSwitchRegWrite(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR, MV_E6172_SMI_PHY_DATA,
+				data);
+			smiReg = (QD_SMI_BUSY | (prt << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_WRITE << QD_SMI_OP_BIT) |
+			(QD_PHY_CONTROL_REG << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT));
+			mvEthSwitchRegWrite(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR,
+								MV_E6172_SMI_PHY_COMMAND, smiReg);
+
+			/*Make sure SMIBusy bit cleared before another SMI operation can take place*/
+			timeout = E6172_PHY_TIMEOUT;
+
+			do {
+				mvEthSwitchRegRead(ethPortNum, MV_E6172_GLOBAL_2_REG_DEV_ADDR,
+					MV_E6172_SMI_PHY_COMMAND, &reg);
+				if (timeout-- == 0) {
+					mvOsPrintf("mvEthPhyRegRead: SMI busy timeout\n");
+					return;
+				}
+			} while (reg & E6172_PHY_SMI_BUSY_MASK);
+		}
+	}
+
+}
+
 static void switchVlanInit(MV_U32 ethPortNum, MV_U32 switchCpuPort, MV_U32 switchMaxPortsNum,
 			   MV_U32 switchPortsOffset, MV_U32 switchEnabledPortsMask)
 {
@@ -405,12 +737,13 @@
 	}
 }
 
+#ifdef MV_SWITCH_DIRECT_ACCESS
 void mvEthSwitchRegWrite(MV_U32 ethPortNum, MV_U32 switchPort,
-                                 MV_U32 switchReg, MV_U16 data)
+				MV_U32 switchReg, MV_U16 data)
 {
 	MV_U32 offset = 0;
 
-	if (mvBoardIsInternalSwitchConnected() == MV_FALSE) {
+	if (mvBoardIsSwitchConnected() == MV_FALSE) {
 		mvOsPrintf("No Switch.\n");
 		return;
 	}
@@ -423,11 +756,11 @@
 }
 
 void mvEthSwitchRegRead(MV_U32 ethPortNum, MV_U32 switchPort,
-                             MV_U32 switchReg, MV_U16 *data)
+				MV_U32 switchReg, MV_U16 *data)
 {
 	MV_U32 result, reg = 0;
 
-	if (mvBoardIsInternalSwitchConnected() == MV_FALSE) {
+	if (mvBoardIsSwitchConnected() == MV_FALSE) {
 		mvOsPrintf("No Switch.\n");
 		return;
 	}
@@ -440,6 +773,118 @@
 	*data = result;
 }
 
+#else	/*defined(MV_SWITCH_SMI_ACCESS)*/
+/*******************************************************************************
+* mvEthSwitchWaitSMICommandRegFree -
+*
+* DESCRIPTION:
+*	wait SMI command register to be free
+*
+* INPUT:
+*	timeOut - the wait time, in 100MS units
+*
+* OUTPUT:
+*	None
+*
+* RETURN:   true - SMI command register is free, false - SMI command register is not free
+*
+*******************************************************************************/
+static MV_BOOL mvEthSwitchWaitSMICommandRegFree(MV_U32 timeOut)
+{
+	MV_U16 smiReg;
+	int i;
+
+	/* first check that it is not busy */
+	if (mvEthPhyRegRead(switchPhyAddr, (MV_U32)QD_REG_SMI_COMMAND, &smiReg) != MV_OK)
+		return MV_FALSE;
+
+	timeOut = QD_SMI_ACCESS_LOOP; /* initialize the loop count */
+
+	if (smiReg & QD_SMI_BUSY) {
+		for (i = 0; i < QD_SMI_TIMEOUT; i++)
+			;
+		do {
+			if (timeOut-- < 1)
+				return MV_FALSE;
+			if (mvEthPhyRegRead(switchPhyAddr, (MV_U32)QD_REG_SMI_COMMAND, &smiReg) != MV_OK)
+				return MV_FALSE;
+		} while (smiReg & QD_SMI_BUSY);
+	}
+
+	return MV_TRUE;
+}
+
+void mvEthSwitchRegWrite(MV_U32 ethPortNum, MV_U32 switchPort,
+				MV_U32 switchReg, MV_U16 data)
+{
+	MV_U16 smiReg;
+
+	if (mvBoardIsSwitchConnected() == MV_FALSE) {
+		mvOsPrintf("No Switch.\n");
+		return;
+	}
+
+	if (switchAccessMode != SMI_MULTI_ADDR_MODE) {
+		mvEthPhyRegWrite(switchPort, switchReg, data);
+		return;
+	}
+
+	/* wait SMI command register to be free */
+	if (mvEthSwitchWaitSMICommandRegFree(QD_SMI_ACCESS_LOOP) == MV_FALSE)
+		return;
+
+	if (mvEthPhyRegWrite(switchPhyAddr, (MV_U32)QD_REG_SMI_DATA, data) != MV_OK)
+		return;
+
+	smiReg = QD_SMI_BUSY | (switchPort << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_WRITE << QD_SMI_OP_BIT) |
+		(switchReg << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT);
+
+	if (mvEthPhyRegWrite(switchPhyAddr, (MV_U32)QD_REG_SMI_COMMAND, smiReg) != MV_OK)
+		return;
+
+	return;
+}
+
+
+void mvEthSwitchRegRead(MV_U32 ethPortNum, MV_U32 switchPort,
+				MV_U32 switchReg, MV_U16 *data)
+{
+	MV_U16 smiReg;
+
+	if (mvBoardIsSwitchConnected() == MV_FALSE) {
+		mvOsPrintf("No Switch.\n");
+		return;
+	}
+
+	if (switchAccessMode != SMI_MULTI_ADDR_MODE) {
+		mvEthPhyRegRead(switchPort, switchReg, &smiReg);
+		*data = smiReg;
+		return;
+	}
+
+	/* wait SMI command register to be free */
+	if (mvEthSwitchWaitSMICommandRegFree(QD_SMI_ACCESS_LOOP) == MV_FALSE)
+		return;
+
+	smiReg =  QD_SMI_BUSY | (switchPort << QD_SMI_DEV_ADDR_BIT) | (QD_SMI_READ << QD_SMI_OP_BIT) |
+		(switchReg << QD_SMI_REG_ADDR_BIT) | (QD_SMI_CLAUSE22 << QD_SMI_MODE_BIT);
+
+	if (mvEthPhyRegWrite(switchPhyAddr, (MV_U32)QD_REG_SMI_COMMAND, smiReg) != MV_OK)
+		return;
+
+	/* wait SMI command register to be free */
+	if (mvEthSwitchWaitSMICommandRegFree(QD_SMI_ACCESS_LOOP) == MV_FALSE)
+		return;
+
+	if (mvEthPhyRegRead(switchPhyAddr, (MV_U32)QD_REG_SMI_DATA, &smiReg) != MV_OK)
+		return;
+
+	*data = smiReg;
+
+	return;
+}
+#endif
+
 void mvEthSwitchPhyRegWrite(MV_U32 ethPortNum, MV_U16 prt,
                                  MV_U16 regOffs, MV_U16 data)
 {
diff --git a/board/mv_ebu/common/USP/ethSwitch/mvSwitch.h b/board/mv_ebu/common/USP/ethSwitch/mvSwitch.h
old mode 100755
new mode 100644
index 47ecfd9..621a843
--- a/board/mv_ebu/common/USP/ethSwitch/mvSwitch.h
+++ b/board/mv_ebu/common/USP/ethSwitch/mvSwitch.h
@@ -67,6 +67,11 @@
 
 #include "mvTypes.h"
 
+/* definition for device scan mode */
+#define SMI_AUTO_SCAN_MODE        0    /* Scan 0 or 0x10 base address to find the QD */
+#define SMI_MANUAL_MODE            1    /* Use QD located at manually defined base addr */
+#define SMI_MULTI_ADDR_MODE        2    /* Use QD at base addr and use indirect access */
+
 MV_VOID	mvEthE6063SwitchBasicInit(MV_U32 ethPortNum);
 MV_VOID	mvEthE6065_61SwitchBasicInit(MV_U32 ethPortNum);
 MV_VOID	mvEthE6131SwitchBasicInit(MV_U32 ethPortNum);
@@ -76,9 +81,10 @@
 void mvEthSwitchRegWrite(MV_U32 ethPortNum, MV_U32 phyAddr, MV_U32 regOffs, MV_U16 data);
 void mvEthSwitchPhyRegRead(MV_U32 ethPortNum, MV_U16 prt, MV_U16 regOffs, MV_U16 *data);
 void mvEthSwitchPhyRegWrite(MV_U32 ethPortNum, MV_U16 prt, MV_U16 regOffs, MV_U16 data);
-
+MV_U16 mvEthSwitchGetDeviceID(void);
 #ifdef MV88F66XX
 MV_VOID mvAlpBoardSwitchBasicInit(MV_U32 enabledPorts);
 #endif
+MV_VOID	mvEthE6172SwitchBasicInit(MV_U32 ethPortNum);
 
 #endif /* __INCETHSWITCHH */
diff --git a/board/mv_ebu/common/USP/ethSwitch/mvSwitchRegs.h b/board/mv_ebu/common/USP/ethSwitch/mvSwitchRegs.h
old mode 100755
new mode 100644
index 7529f2b..c74fb48
--- a/board/mv_ebu/common/USP/ethSwitch/mvSwitchRegs.h
+++ b/board/mv_ebu/common/USP/ethSwitch/mvSwitchRegs.h
@@ -110,18 +110,39 @@
 #define E6161_PHY_SMI_BUSY_MASK					(1 << ETH_PHY_SMI_BUSY_BIT)
 
 /* E6171 related */
-#define MV_E6171_CPU_PORT						0x6
-#define MV_E6171_PORTS_OFFSET					0x10
-#define MV_E6171_SWITCH_PHIYSICAL_CTRL_REG		0x1
-#define MV_E6171_SWITCH_PORT_CTRL_REG		    0x4
+#define MV_E6171_PRODUCT_NUM					0x171
+#define MV_E6176_PRODUCT_NUM					0x176
+#define MV_E6171_MAX_PORTS_NUM					7
+/* PHY registers */
+#define MV_E6171_SERDES_REG					0xf
+#define MV_E6171_SERDES_CONTROL_REG				0x0
+#define MV_E6171_PAGE_REG					0x16
+#define MV_E6171_SWITCH_PHIYSICAL_CTRL_REG			0x1
+/* Port registers */
+#define MV_E6171_LED_CONTROL					0x16
+#define MV_E6171_GLOBAL_2_REG_DEV_ADDR				0x1C
+/* SMI registers */
 #define MV_E6171_SMI_PHY_COMMAND				0x18
 #define MV_E6171_SMI_PHY_DATA					0x19
-#define MV_E6171_GLOBAL_2_REG_DEV_ADDR			0x1C
-#define MV_E6171_MAX_PORTS_NUM					7
-#define MV_E6171_ENABLED_PORTS					((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 6))
-#define E6171_PHY_TIMEOUT					    10000
-#define E6171_PHY_SMI_BUSY_BIT		    		15  /* Busy */
-#define E6171_PHY_SMI_BUSY_MASK		    		(1 << ETH_PHY_SMI_BUSY_BIT)
+#define E6171_PHY_SMI_BUSY_BIT		    			15  /* Busy */
+#define E6171_PHY_SMI_BUSY_MASK					(1 << E6171_PHY_SMI_BUSY_BIT)
+#define E6171_PHY_TIMEOUT					10000
+#define MV_E6171_ENABLED_PORTS					((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 6))
+
+/* E6172 related */
+#define MV_E6172_PRODUCT_NUM					0x172
+#define MV_E6172_CPU_PORT					0x6
+#define MV_E6172_PORTS_OFFSET					0x10
+#define MV_E6172_SWITCH_PHIYSICAL_CTRL_REG			0x1
+#define MV_E6172_SWITCH_PORT_CTRL_REG				0x4
+#define MV_E6172_SMI_PHY_COMMAND				0x18
+#define MV_E6172_SMI_PHY_DATA					0x19
+#define MV_E6172_GLOBAL_2_REG_DEV_ADDR				0x1C
+#define MV_E6172_MAX_PORTS_NUM					7
+#define MV_E6172_ENABLED_PORTS					((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 6))
+#define E6172_PHY_TIMEOUT					10000
+#define E6172_PHY_SMI_BUSY_BIT					15  /* Busy */
+#define E6172_PHY_SMI_BUSY_MASK					(1 << E6172_PHY_SMI_BUSY_BIT)
 
 /* Armada 370 internal related */
 #define MV_SW_CPU_PORT							0x6
@@ -155,4 +176,91 @@
 #define MV_ALP_SW_PORTS_OFFSET					0x10
 #define MV_ALP_SW_MAX_PORTS_NUM					7
 
+/* Start address of ports related register.             */
+#define PORT_REGS_START_ADDR        0x8
+#define PORT_REGS_START_ADDR_8PORT    0x10
+
+#define QD_SMI_ACCESS_LOOP        1000
+#define QD_SMI_TIMEOUT            2
+
+/* Definition for Multi Address Mode */
+#define QD_REG_SMI_COMMAND        0x0
+#define QD_REG_SMI_DATA            0x1
+
+#define QD_REG_SWITCH_ID			0x3
+#define QD_REG_SWITCH_ID_PRODUCT_NUM_OFFSET	4
+
+#define QD_PHY_CONTROL_REG		0
+#define QD_PHY_SPEC_CONTROL_REG		16
+
+/* Bit Definition for QD_PHY_CONTROL_REG */
+#define QD_PHY_RESET            0x8000
+#define QD_PHY_LOOPBACK            0x4000
+#define QD_PHY_SPEED            0x2000
+#define QD_PHY_AUTONEGO            0x1000
+#define QD_PHY_POWER            0x800
+#define QD_PHY_ISOLATE            0x400
+#define QD_PHY_RESTART_AUTONEGO        0x200
+#define QD_PHY_DUPLEX            0x100
+#define QD_PHY_SPEED_MSB        0x40
+
+/* Bit Definition for QD_PHY_SPEC_CONTROL_REG */
+#define QD_PHY_MDI_CROSS_AUTO				0x60
+#define QD_PHY_ENERGY_DETECT_SENSE_PERIODIC_TX_NLP	0x300
+#define QD_PHY_DOWNSHIFT_COUNTER			0x3000
+
+/* Bit Definition for MV_SWITCH_PHYS_CONTROL_REG(switch port 1) */
+#define QD_PCS_RGMII_RX_TIMING_OFFSET			15
+#define QD_PCS_RGMII_TX_TIMING_OFFSET			14
+#define QD_PCS_FLOW_CONTROL_VALUE_OFFSET		7
+#define QD_PCS_FORCED_FLOW_CONTROL_OFFSET		6
+#define QD_PCS_LINK_VALUE_OFFSET			5
+#define QD_PCS_FORCED_LINK_OFFSET			4
+#define QD_PCS_DUPLEX_VALUE_OFFSET			3
+#define QD_PCS_FORCED_DUPLEX_OFFSET			2
+#define QD_PCS_FORCE_SPEED_OFFSET			0
+
+#define QD_PCS_RGMII_RX_TIMING_MASK			(1 << QD_PCS_RGMII_RX_TIMING_OFFSET)
+#define QD_PCS_RGMII_TX_TIMING_MASK			(1 << QD_PCS_RGMII_TX_TIMING_OFFSET)
+#define QD_PCS_FLOW_CONTROL_VALUE_MASK			(1 << QD_PCS_FLOW_CONTROL_VALUE_OFFSET)
+#define QD_PCS_FORCED_FLOW_CONTROL_MASK			(1 << QD_PCS_FORCED_FLOW_CONTROL_OFFSET)
+#define QD_PCS_LINK_VALUE_MASK				(1 << QD_PCS_LINK_VALUE_OFFSET)
+#define QD_PCS_FORCED_LINK_MASK				(1 << QD_PCS_FORCED_LINK_OFFSET)
+#define QD_PCS_DUPLEX_VALUE_MASK			(1 << QD_PCS_DUPLEX_VALUE_OFFSET)
+#define QD_PCS_FORCED_DUPLEX_MASK			(1 << QD_PCS_FORCED_DUPLEX_OFFSET)
+
+#define QD_PCS_FORCE_SPEED_1G				(2 << QD_PCS_FORCE_SPEED_OFFSET)
+#define QD_PCS_FORCE_SPEED_NOT_FORCED			(3 << QD_PCS_FORCE_SPEED_OFFSET)
+
+/* Bit Definition for MV_SWITCH_PORT_CONTROL_REG(switch port 4) */
+#define QD_PC_PORT_STATE_OFFSET				0
+#define QD_PC_EGRESS_FLOODS_OFFSET			2
+#define QD_PC_INITIAL_PRI_OFFSET			4
+#define QD_PC_VLAN_TUNNEL_OFFSET			7
+
+#define QD_PC_PORT_STATE_FORWARDING			(3 << QD_PC_PORT_STATE_OFFSET)
+#define QD_PC_EGRESS_FLOODS_ALL				(3 << QD_PC_EGRESS_FLOODS_OFFSET)
+#define QD_PC_INITIAL_PRI_IP				(2 << QD_PC_INITIAL_PRI_OFFSET)
+#define QD_PC_VLAN_TUNNEL_BY_PASS			(1 << QD_PC_VLAN_TUNNEL_OFFSET)
+
+
+
+
+/* Bit definition for QD_REG_SMI_COMMAND */
+#define QD_SMI_BUSY                0x8000
+#define QD_SMI_MODE                0x1000
+#define QD_SMI_MODE_BIT            12
+#define QD_SMI_OP_BIT            10
+#define QD_SMI_OP_SIZE            2
+#define QD_SMI_DEV_ADDR_BIT        5
+#define QD_SMI_DEV_ADDR_SIZE    5
+#define QD_SMI_REG_ADDR_BIT        0
+#define QD_SMI_REG_ADDR_SIZE    5
+
+#define QD_SMI_CLAUSE45            0
+#define QD_SMI_CLAUSE22            1
+
+#define QD_SMI_WRITE            0x01
+#define QD_SMI_READ                0x02
+
 #endif /* __INCethswitchregsh */
diff --git a/board/mv_ebu/common/USP/mv_cmd.c b/board/mv_ebu/common/USP/mv_cmd.c
index fc9003a..96610d1 100644
--- a/board/mv_ebu/common/USP/mv_cmd.c
+++ b/board/mv_ebu/common/USP/mv_cmd.c
@@ -28,6 +28,7 @@
 #include "ctrlEnv/mvCtrlEnvLib.h"
 #include "boardEnv/mvBoardEnvLib.h"
 #include "cpu/mvCpu.h"
+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
 
 #if defined(MV_INC_BOARD_NOR_FLASH)
 #include "norflash/mvFlash.h"
@@ -992,7 +993,6 @@
 
 	return 1;
 }
-
 U_BOOT_CMD(
 	phyWrite,      4,     4,      phy_write_cmd,
 	"phyWrite	- Write Phy register\n",
@@ -1002,7 +1002,6 @@
 
 #if defined(MV_INCLUDE_SWITCH)
 #include "ethSwitch/mvSwitch.h"
-
 int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	MV_U16 phyReg;
@@ -1039,6 +1038,7 @@
 	"\tWrite to the switch register.\n"
 );
 
+
 int switch_phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	MV_U16 phyReg;
@@ -1115,7 +1115,144 @@
 	" MAC_Port. \n"
 	"\tRead the switch ports counters. \n"
 );
-#endif
+#elif defined(MV_SWITCH_ADDRESS_COMPLETION) /* MV_INCLUDE_SWITCH */
+
+#define SWITCH_REGS_BASE_ADDR_MASK		0xFC000000
+#define SWITCH_ADDR_COMPL_MSB_VAL(addr)	((addr >> 24) & 0xFF)
+#define SWITCH_ADDR_COMPL_SHIFT(addr)	(((addr >> 24) & 0x3) << 3)
+#define SWITCH_BUS_ADDR(addr)			((~SWITCH_REGS_BASE_ADDR_MASK & addr) |\
+							(SWITCH_WIN_BASE_ADDR_GET() & SWITCH_REGS_BASE_ADDR_MASK))
+
+/*******************************************************************************
+* SWITCH_WIN_BASE_ADDR_GET
+*
+* DESCRIPTION:
+* This function returns the base address of switch registers window
+*
+*
+* RETURN:
+*	base address of switch registers window
+*
+*******************************************************************************/
+static __inline MV_U32 SWITCH_WIN_BASE_ADDR_GET(MV_VOID)
+{
+	static MV_U32	baseAddr;
+	baseAddr = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(SWITCH_WIN_ID));
+	return baseAddr;
+}
+
+/*******************************************************************************
+* SWITCH_ADDR_COMPL_SET
+*
+* DESCRIPTION:
+* This function configures address completion register
+*
+* INPUT:
+*	addr	- the address to access indirectly
+*
+*******************************************************************************/
+static __inline MV_STATUS SWITCH_ADDR_COMPL_SET(MV_U32 addr)
+{
+	MV_U32	rVal;
+	/* Configure address completion region REG using SERDES memory window */
+	rVal  = MV_MEMIO32_READ(SWITCH_WIN_BASE_ADDR_GET());
+	rVal &= ~(0xFF << SWITCH_ADDR_COMPL_SHIFT(addr));
+	rVal |= SWITCH_ADDR_COMPL_MSB_VAL(addr) << SWITCH_ADDR_COMPL_SHIFT(addr);
+	MV_MEMIO32_WRITE(SWITCH_WIN_BASE_ADDR_GET(), rVal);
+	return MV_OK;
+}
+
+/*******************************************************************************
+* mvSwitchRegisterGet
+*
+* DESCRIPTION:
+* This function reads switch register with address completion
+*
+* INPUT:
+*	address		- the address to read indirectly
+*	mask		- mask of the read data
+*
+* OUTPUT:
+*	data		- the register's data value
+*
+*
+*******************************************************************************/
+void mvSwitchRegisterGet(MV_U32 address, MV_U32 *data, MV_U32 mask)
+{
+	SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
+	*data  = MV_MEMIO32_READ(SWITCH_BUS_ADDR(address)) & mask;
+}
+
+/*******************************************************************************
+* switchRegRead
+*
+* DESCRIPTION:
+* This command reads switch register with address completion
+*
+*******************************************************************************/
+int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	MV_U32 regVal;
+
+	mvSwitchRegisterGet(simple_strtoul(argv[1], NULL, 16), &regVal, 0xFFFF);
+	printf ("0x%x\n", regVal);
+
+	return 1;
+}
+U_BOOT_CMD(
+	switchRegRead,      2,     2,      switch_read_cmd,
+"switchRegRead	- Read switch register, using Address completion\n",
+" Reg_offset. \n"
+"\tRead the switch register, using Address completion. \n"
+);
+
+/*******************************************************************************
+* mvSwitchRegisterSet
+*
+* DESCRIPTION:
+* This function writes to switch register with address completion
+*
+*	address		- the address to write to indirectly
+*	data		- the data to write
+*	mask		- mask of the write data
+*
+*******************************************************************************/
+void mvSwitchRegisterSet(MV_U32 address, MV_U32 data, MV_U32 mask)
+{
+	MV_U32 regData;
+
+	if ((mask & 0xFFFF) != 0xFFFF) { /* since switch registers are 16 bits - check only the relevant bits */
+		mvSwitchRegisterGet(address, &regData, ~mask);
+		regData |= (data & mask);
+	} else
+		regData = data;
+
+	SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
+
+	MV_MEMIO32_WRITE(SWITCH_BUS_ADDR(address), regData);
+}
+
+/*******************************************************************************
+* switchRegWrite
+*
+* DESCRIPTION:
+* This command writes to switch register with address completion
+*
+*******************************************************************************/
+int switch_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	mvSwitchRegisterSet(simple_strtoul(argv[1], NULL, 16), simple_strtoul(argv[2], NULL, 16), 0xFFFF);
+
+	return 1;
+}
+
+U_BOOT_CMD(
+	switchRegWrite,      3,     3,      switch_write_cmd,
+"switchRegWrite	- Write to switch register, using Address completion\n",
+" Reg_offset Reg_data. \n"
+"\tWrite to the switch register, using Address completion. \n"
+);
+#endif /* MV_SWITCH_ADDRESS_COMPLETION */
 #endif /* #if defined(MV_INCLUDE_GIG_ETH) */
 
 #define REG_SDRAM_CONFIG_ADDR					0x1400
@@ -1123,6 +1260,8 @@
 #define REG_READ_DATA_SAMPLE_DELAYS_ADDR		0x1538
 #define REG_READ_DATA_READY_DELAYS_ADDR			0x153C
 #define REG_PHY_REGISTRY_FILE_ACCESS_ADDR		0x16A0
+#define REG_PHY_DATA		0
+#define REG_PHY_CTRL		1
 
 /******************************************************************************
 * Category     - DDR3 Training
@@ -1130,13 +1269,13 @@
 * Need modifications (Yes/No) - no
 *****************************************************************************/
 #ifdef MV_DDR_TRAINING_CMD_NEW_TIP
-unsigned int trainingReadPhyReg(int uiRegAddr, int uiPup)
+unsigned int trainingReadPhyReg(int uiRegAddr, int uiPup, int type)
 {
 	unsigned int uiReg;
     unsigned int addrLow = 0x3F & uiRegAddr;
     unsigned int addrHi = ((0xC0 & uiRegAddr) >> 6);
 
-	uiReg = (1 << 31) + (uiPup << 22) + (addrHi << 28) + (addrLow << 16);
+	uiReg = (1 << 31) + (uiPup << 22) + (type << 26) + (addrHi << 28) + (addrLow << 16);
 	MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg&0x7FFFFFFF);
 	MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR,uiReg);
 
@@ -1166,7 +1305,7 @@
 			printf("CS: %d \n", uiCs);
 			for(uiPup = 0; uiPup < uiPupNum; uiPup++) {
 
-				uiReg = trainingReadPhyReg(0 + uiCs*4,uiPup);
+				uiReg = trainingReadPhyReg(0 + uiCs*4,uiPup, REG_PHY_DATA);
 				uiPhase = (uiReg >> 6) & 0x7;
 				uiDelay = uiReg & 0x1F;
 				printf("Write Leveling: PUP: %d, Phase: %d, Delay: %d\n",uiPup,uiPhase,uiDelay);
@@ -1174,7 +1313,7 @@
 
 			for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
 
-				uiReg = trainingReadPhyReg(2 + uiCs*4,uiPup);
+				uiReg = trainingReadPhyReg(2 + uiCs*4,uiPup, REG_PHY_DATA);
 				uiPhase = (uiReg >> 6) & 0x7;
 				uiDelay = uiReg & 0x1F;
 				printf("Read Leveling: PUP: %d, Phase: %d, Delay: %d\n",uiPup, uiPhase, uiDelay);
@@ -1192,7 +1331,7 @@
 						if (uiDq == 9)
 							uiDq++;
 
-						uiReg = trainingReadPhyReg(0x10+uiDq+uiCs*0x12,uiPup);
+						uiReg = trainingReadPhyReg(0x10+uiDq+uiCs*0x12,uiPup, REG_PHY_DATA);
 						uiDelay = uiReg & 0x1F;
 
 						if (uiDq == 0)
@@ -1203,7 +1342,7 @@
 				}
 				for(uiPup=0; uiPup < uiPupNum; uiPup++) {
 					for(uiDq = 0; uiDq < 9; uiDq++) {
-						uiReg = trainingReadPhyReg(0x50+uiDq+uiCs*0x12,uiPup);
+						uiReg = trainingReadPhyReg(0x50+uiDq+uiCs*0x12,uiPup, REG_PHY_DATA);
 						uiDelay = uiReg & 0x1F;
 
 						if (uiDq == 0)
@@ -1217,7 +1356,7 @@
 			/*Read Centralization windows sizes for Scratch PHY registers*/
 			for(uiPup = 0; uiPup < uiPupNum; uiPup++)
 			{
-				uiReg = trainingReadPhyReg(0xC0+uiCs,uiPup);
+				uiReg = trainingReadPhyReg(0xC0+uiCs,uiPup, REG_PHY_DATA);
 				uiCentralRxRes = uiReg >> 5;
 				uiCentralTxRes = uiReg & 0x1F;
 				printf("Central window size for PUP %d is %d(RX) and %d(TX)\n", uiPup, uiCentralRxRes, uiCentralTxRes);
@@ -1378,11 +1517,31 @@
 * Functionality- The commands prints the row data of stability results for DDR3 Training
 * Need modifications (Yes/No) - no
 *****************************************************************************/
+MV_U32 dminPhyRegTable[20][2] = {
+					{0	,0xC0},
+					{0	,0xC1},
+					{0	,0xC2},
+					{0	,0xC3},
+					{0	,0xC4},
+					{1	,0xC0},
+					{1	,0xC1},
+					{1	,0xC2},
+					{1	,0xC3},
+					{1	,0xC4},
+					{2	,0xC0},
+					{2	,0xC1},
+					{2	,0xC2},
+					{2	,0xC3},
+					{2	,0xC4},
+					{0	,0xC5},
+					{1	,0xC5},
+					{2	,0xC5},
+					{0	,0xC6},
+					{1	,0xC6}};
 int trainingStability_cmd( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
 {
-	MV_U32 uiCsEna, interfaceId=0,csindex = 0,busId=0,padIndex=0;
-	MV_U32 regData;
-	MV_U32 readData;
+	MV_U32 uiCsEna, interfaceId=0, csindex = 0,busId=0, padIndex=0;
+	MV_U32 regData, regData1;
 
 	uiCsEna = MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & 0xF;
 
@@ -1425,12 +1584,12 @@
 	for(interfaceId = 0; interfaceId < 1; interfaceId++)
 	{
 		printf("Data: %d,%d,",interfaceId,mvCtrlGetJuncTemp());//add Junction Temperature
-		readData = MV_REG_READ(0x14C8);
-		printf("%d,%d,",((readData&0x3F0)>>4),((readData&0xFC00)>>10));
-		readData = MV_REG_READ(0x17C8);
-		printf("%d,%d,",((readData&0x3F0)>>4),((readData&0xFC00)>>10));
-		readData = MV_REG_READ(0x1DC8);
-		printf("%d,%d,",((readData&0x3F0000)>>16),((readData&0xFC00000)>>22));
+		regData = MV_REG_READ(0x14C8);
+		printf("%d,%d,",((regData&0x3F0)>>4),((regData&0xFC00)>>10));
+		regData = MV_REG_READ(0x17C8);
+		printf("%d,%d,",((regData&0x3F0)>>4),((regData&0xFC00)>>10));
+		regData = MV_REG_READ(0x1DC8);
+		printf("%d,%d,",((regData&0x3F0000)>>16),((regData&0xFC00000)>>22));
 		for(csindex = 0; csindex < 4; csindex++)
 		{
 			if (!(uiCsEna & (1 << csindex))) continue;
@@ -1438,48 +1597,52 @@
 			for(busId = 0; busId <5; busId++)
 			{
 				#ifdef CONFIG_DDR3/*DDR3*/
-				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId);
+				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId, REG_PHY_DATA);
 				printf("%d,%d,",(regData&0x1F),((regData&0x3E0)>>5));
 				#else/*DDR4*/
-				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId);
-				printf("%d,%d,",(regData&0x1F)*4,2*((regData&0xFFE0)>>5));
-				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex + 4,busId);
-				printf("%d,%d,",(regData&0x1F)*4,2*((regData&0xFFE0)>>5));
+				/*DminTx, areaTX*/
+				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex,busId, REG_PHY_DATA);
+				regData1 = trainingReadPhyReg(dminPhyRegTable[csindex*5+busId][1],dminPhyRegTable[csindex*5+busId][0], REG_PHY_CTRL);
+				printf("%d,%d,",2*(regData1&0xFF),regData);
+				/*DminRx, areaRX*/
+				regData = trainingReadPhyReg(RESULT_DB_PHY_REG_ADDR+csindex+4,busId, REG_PHY_DATA);
+				regData1 = trainingReadPhyReg(dminPhyRegTable[csindex*5+busId][1],dminPhyRegTable[csindex*5+busId][0], REG_PHY_CTRL);
+				printf("%d,%d,",2*(regData1>>8),regData);
 				#endif
 				/*WL*/
-				regData = trainingReadPhyReg(WL_PHY_REG+csindex*4,busId);
+				regData = trainingReadPhyReg(WL_PHY_REG+csindex*4,busId, REG_PHY_DATA);
 				printf("%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32,(regData&0x1F),(regData&0x1C0)>>6);
 				/*RL*/
-				readData = MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
-				readData = (readData&(0xF<<(4*csindex))) >> (4*csindex);
-				regData = trainingReadPhyReg(RL_PHY_REG+csindex*4,busId);
-				printf("%d,%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32 + readData*64,(regData&0x1F),((regData&0x1C0)>>6),readData);
+				regData1 = MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
+				regData1 = (regData1&(0xF<<(4*csindex))) >> (4*csindex);
+				regData = trainingReadPhyReg(RL_PHY_REG+csindex*4,busId, REG_PHY_DATA);
+				printf("%d,%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32 + regData1*64,(regData&0x1F),((regData&0x1C0)>>6),regData1);
 				/*Centralization*/
-				regData = trainingReadPhyReg(WRITE_CENTRALIZATION_PHY_REG+csindex*4,busId);
+				regData = trainingReadPhyReg(WRITE_CENTRALIZATION_PHY_REG+csindex*4,busId, REG_PHY_DATA);
 				printf("%d,",(regData&0x3F));
-				regData = trainingReadPhyReg(READ_CENTRALIZATION_PHY_REG+csindex*4,busId);
+				regData = trainingReadPhyReg(READ_CENTRALIZATION_PHY_REG+csindex*4,busId, REG_PHY_DATA);
 				printf("%d,",(regData&0x1F));
 				/*Vref */
-				regData = trainingReadPhyReg(PAD_CONFIG_PHY_REG+csindex,busId);
+				regData = trainingReadPhyReg(PAD_CONFIG_PHY_REG+csindex,busId, REG_PHY_DATA);
 				printf("%d,",(regData&0x7));
 				/*DQVref*/
 				/* Need to add the Read Function from device*/
 				printf("%d,",0);
 				#ifndef CONFIG_DDR3
-				for(padIndex = 0; padIndex < 10; padIndex++)
+				for(padIndex = 0; padIndex < 11; padIndex++)
 				{
-					regData = trainingReadPhyReg(0xD0+12*csindex+padIndex,busId);
+					regData = trainingReadPhyReg(0xD0+12*csindex+padIndex,busId, REG_PHY_DATA);
 					printf("%d,",(regData&0x3F));
 				}
 				#endif
-				for(padIndex = 0; padIndex < 10; padIndex++)
+				for(padIndex = 0; padIndex < 11; padIndex++)
 				{
-					regData = trainingReadPhyReg(0x10+16*csindex+padIndex,busId);
+					regData = trainingReadPhyReg(0x10+16*csindex+padIndex,busId, REG_PHY_DATA);
 					printf("%d,",(regData&0x3F));
 				}
-				for(padIndex = 0; padIndex < 10; padIndex++)
+				for(padIndex = 0; padIndex < 11; padIndex++)
 				{
-					regData = trainingReadPhyReg(0x50+16*csindex+padIndex,busId);
+					regData = trainingReadPhyReg(0x50+16*csindex+padIndex,busId, REG_PHY_DATA);
 					printf("%d,",(regData&0x3F));
 				}
 			}
diff --git a/board/mv_ebu/common/USP/mv_egiga_legacy.c b/board/mv_ebu/common/USP/mv_egiga_legacy.c
index 3827b12..0401a19 100644
--- a/board/mv_ebu/common/USP/mv_egiga_legacy.c
+++ b/board/mv_ebu/common/USP/mv_egiga_legacy.c
@@ -153,6 +153,7 @@
 	dev->halt = (void*)mvEgigaHalt;
 	dev->send = (void*)mvEgigaTx;
 	dev->recv = (void*)mvEgigaRx;
+	dev->index = port;
 	dev->priv = priv;
 	dev->iobase = 0;
 	dev->port = port;
@@ -518,4 +519,4 @@
 }
 
 #endif  /* legacy */
-#endif  /* #if defined (MV_INCLUDE_GIG_ETH) */
\ No newline at end of file
+#endif  /* #if defined (MV_INCLUDE_GIG_ETH) */
diff --git a/board/mv_ebu/common/USP/mv_egiga_neta.c b/board/mv_ebu/common/USP/mv_egiga_neta.c
index 55215e5..2ea503d 100755
--- a/board/mv_ebu/common/USP/mv_egiga_neta.c
+++ b/board/mv_ebu/common/USP/mv_egiga_neta.c
@@ -162,6 +162,7 @@
 	dev->priv = priv;
 	dev->iobase = 0;
 	dev->write_hwaddr = 0;
+	dev->index = port;
 	priv->port = port;
 	priv->devInit = MV_FALSE;
 	priv->devEnable = MV_FALSE;
diff --git a/board/mv_ebu/common/USP/mv_egiga_pp2.c b/board/mv_ebu/common/USP/mv_egiga_pp2.c
index a741930..0a9f903 100644
--- a/board/mv_ebu/common/USP/mv_egiga_pp2.c
+++ b/board/mv_ebu/common/USP/mv_egiga_pp2.c
@@ -233,7 +233,7 @@
 	egigaPriv *priv = NULL;
 
 	/* First disable GMAC */
-	mvGmacPortDisable(priv->port);
+	mvGmacPortDisable(port);
 
 	dev = malloc(sizeof(struct eth_device));
 	if (!dev) {
@@ -259,6 +259,7 @@
 	dev->priv = priv;
 	dev->iobase = 0;
 	dev->write_hwaddr = 0;
+	dev->index = port;
 	priv->port = port;
 	priv->devInit = MV_FALSE;
 	priv->devEnable = MV_FALSE;
diff --git a/board/mv_ebu/common/USP/mv_fdt.c b/board/mv_ebu/common/USP/mv_fdt.c
index 7bd0351..ad57143 100644
--- a/board/mv_ebu/common/USP/mv_fdt.c
+++ b/board/mv_ebu/common/USP/mv_fdt.c
@@ -27,6 +27,8 @@
 #include "libfdt.h"
 #include "fdt_support.h"
 #include "mvBoardEnvLib.h"
+#include "ethSwitch/mvSwitchRegs.h"
+#include "ethSwitch/mvSwitch.h"
 
 /*******************************************************************************
 * fdt_env_setup
@@ -83,6 +85,12 @@
 	if (!env)
 		setenv("bootcmd_fdt",bootcmd_fdt);
 
+#if defined (CONFIG_OF_LIBFDT_IS_DEFAULT)
+	env = getenv("bootcmd");
+	if (!env)
+		setenv("bootcmd", bootcmd_fdt);
+#endif /* (CONFIG_OF_LIBFDT_IS_DEFAULT) */
+
 #ifdef CONFIG_GFCH100
 	env = getenv("fdtcontinueonerror");
 	if (!env)
@@ -103,11 +111,19 @@
 static int mv_fdt_find_node(void *fdt, const char *name);
 static int mv_fdt_board_compatible_name_update(void *fdt);
 static int mv_fdt_update_serial(void *fdt);
+#ifdef CONFIG_PIC_GPIO
 static int mv_fdt_update_pic_gpio(void *fdt);
+#endif
 static int mv_fdt_update_cpus(void *fdt);
 static int mv_fdt_update_pex(void *fdt);
+#ifdef MV_INCLUDE_SATA
 static int mv_fdt_update_sata(void *fdt);
+#endif
+#ifdef MV_INCLUDE_USB
 static int mv_fdt_update_usb(void *fdt, MV_UNIT_ID unitType);
+static int mv_fdt_update_usb2(void *fdt);
+static int mv_fdt_update_usb3(void *fdt);
+#endif
 static int mv_fdt_update_ethnum(void *fdt);
 static int mv_fdt_update_flash(void *fdt);
 static int mv_fdt_set_node_prop(void *fdt, const char *node, const char *prop, const char *prop_val);
@@ -115,16 +131,78 @@
 static int mv_fdt_scan_and_set_alias(void *fdt, const char *name, const char *alias);
 static int mv_fdt_nand_mode_fixup(void *fdt);
 static int mv_fdt_update_pinctrl(void *fdt);
+#ifdef MV_INCLUDE_AUDIO
+static int mv_fdt_update_audio(void *fdt);
+#endif
+#ifdef MV_INCLUDE_SWITCH
+static int mv_fdt_update_switch(void *fdt);
+#endif
 static int mv_fdt_debug;
 #ifdef CONFIG_MV_SDHCI
 static int mv_fdt_update_sdhci(void *fdt);
 #endif
+#ifdef CONFIG_SWITCHING_SERVICES
+static int mv_fdt_update_prestera(void *fdt);
+#endif
+#ifdef MV_INCLUDE_TDM
+static int mv_fdt_update_tdm(void *fdt);
+#endif
+#ifdef MV_USB_VBUS_CYCLE
+static int mv_fdt_update_usb_vbus(void *fdt);
+#endif
+#ifdef MV_INCLUDE_USB_DEVICE
+static int mv_fdt_update_usb_device(void *fdt);
+#endif
 
 #if 0 /* not compiled, since this routine is currently not in use  */
 static int mv_fdt_remove_prop(void *fdt, const char *path,
 				const char *name, int nodeoff);
 #endif
 
+typedef int (update_fnc_t)(void *);
+update_fnc_t *update_sequence[] = {
+	mv_fdt_update_cpus,			/* Get number of CPUs and update dt */
+	mv_fdt_update_pex,			/* Get number of active PEX port and update DT */
+#ifdef MV_INCLUDE_SATA
+	mv_fdt_update_sata,			/* Get number of active SATA units and update DT */
+#endif
+#ifdef MV_INCLUDE_USB
+	mv_fdt_update_usb2,			/* Get number of active USB2.0 units and update DT */
+	mv_fdt_update_usb3,			/* Get number of active USB3.0 units and update DT */
+#endif
+	mv_fdt_update_ethnum,			/* Get number of active ETH port and update DT */
+#ifdef CONFIG_MV_SDHCI
+	mv_fdt_update_sdhci,			/* Update SDHCI driver settings in DT */
+#endif
+#ifdef CONFIG_SWITCHING_SERVICES
+	mv_fdt_update_prestera,			/* Update prestera driver DT settings - for AMC board */
+#endif
+#ifdef MV_INCLUDE_TDM
+	mv_fdt_update_tdm,			/* Update tdm node in DT */
+#endif
+#ifdef MV_USB_VBUS_CYCLE
+	mv_fdt_update_usb_vbus,
+#endif
+	mv_fdt_update_flash,			/* Get number of active flash devices and update DT */
+	mv_fdt_nand_mode_fixup,			/* Update NAND controller ECC settings in DT */
+	mv_fdt_update_pinctrl,			/* Update pinctrl driver settings in DT */
+	mv_fdt_board_compatible_name_update,	/* Update compatible (board name) in DT */
+	mv_fdt_update_serial,			/* Update serial/UART nodes in DT */
+#ifdef CONFIG_PIC_GPIO
+	mv_fdt_update_pic_gpio,
+#endif
+#ifdef MV_INCLUDE_AUDIO
+	mv_fdt_update_audio,			/* Update audio-controller+sound nodes in DT */
+#endif
+#ifdef MV_INCLUDE_SWITCH
+	mv_fdt_update_switch,
+#endif
+#ifdef MV_INCLUDE_USB_DEVICE
+	mv_fdt_update_usb_device,
+#endif
+	NULL,
+};
+
 enum nfc_driver_type {
 	MV_FDT_NFC_PXA3XX,	/* mainline pxa3xx-nand */
 	MV_FDT_NFC_HAL,		/* mvebu HAL-based NFC */
@@ -175,6 +253,7 @@
 {
 	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 */
 
@@ -210,75 +289,14 @@
 	fixup_memory_node(blob);
 	mv_fdt_dprintf("Memory node updated\n");
 
-	/* Get number of CPUs and update dt */
-	err = mv_fdt_update_cpus(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating cpus failed\n");
-
-	/* Get number of active PEX port and update DT */
-	err = mv_fdt_update_pex(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating pex failed\n");
-
-	/* Get number of active SATA units and update DT */
-	err = mv_fdt_update_sata(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating pex failed\n");
-
-	/* Get number of active USB2.0 units and update DT */
-	err = mv_fdt_update_usb(blob, USB_UNIT_ID);
-	if (err < 0)
-		report_error(&counter, force, "Updating usb 2.0 failed\n");
-
-	/* Get number of active USB3.0 units and update DT */
-	err = mv_fdt_update_usb(blob, USB3_UNIT_ID);
-	if (err < 0)
-		report_error(&counter, force, "Updating usb 3.0 failed\n");
-
-	/* Get number of active ETH port and update DT */
-	err = mv_fdt_update_ethnum(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating ethnum failed\n");
-
-#ifdef CONFIG_MV_SDHCI
-	/* Update SDHCI driver settings in DT */
-	err = mv_fdt_update_sdhci(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating sdhci failed\n");
-#endif
-
-	/* Get number of active flash devices and update DT */
-	err = mv_fdt_update_flash(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating flash failed\n");
-
-	/* Update NAND controller ECC settings in DT */
-	err = mv_fdt_nand_mode_fixup(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating nand mode failed\n");
-
-	/* Update pinctrl driver settings in DT */
-	err = mv_fdt_update_pinctrl(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating pinctrl failed\n");
-
-	/* Update compatible (board name) in DT */
-	err = mv_fdt_board_compatible_name_update(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating board name failed\n");
-
-	/* Update serial/UART nodes in DT */
-	err = mv_fdt_update_serial(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating serial failed\n");
-
-	err = mv_fdt_update_pic_gpio(blob);
-	if (err < 0)
-		report_error(&counter, force, "Updating pic gpio failed\n");
-
-	if (counter > 0) {
-		mv_fdt_dprintf("Encountered %d errors while updating device tree\n", counter);
-		goto bs_fail;
+	/* 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) {
+			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");
@@ -363,6 +381,9 @@
 * mv_fdt_update_cpus
 *
 * DESCRIPTION:
+* target		: remove excessice cpu nodes.
+* node			: cpus
+* dependencies		: CPU core num in SOC_COHERENCY_FABRIC_CFG_REG.
 *
 * INPUT:
 *	fdt.
@@ -424,10 +445,14 @@
 	return 0;
 }
 
+#ifdef MV_INCLUDE_SATA
 /*******************************************************************************
 * mv_fdt_update_sata
 *
 * DESCRIPTION:
+* target                : Update status field of SATA nodes.
+* node, properties      : -property status @ node SATA
+* dependencies          : sata unit status in sataUnitActive array.
 *
 * INPUT:
 *	fdt.
@@ -457,18 +482,160 @@
 		sprintf(node, "sata@%x", mvCtrlSataRegBaseGet(i));
 		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 -1;
+			return 0;
 		}
 	}
 
 	return 0;
 }
+#endif /* MV_INCLUDE_SATA */
+
+#ifdef MV_INCLUDE_TDM
+/*******************************************************************************
+* mv_fdt_update_tdm
+*
+* DESCRIPTION:
+* target		: update status field of tdm@X node.
+* node, properties	: -property status @ node tdm@x.
+* dependencies		: isTdmConnected entry in board structure.
+*
+* INPUT:
+*	fdt.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	-1 on error os 0 otherwise.
+*
+*******************************************************************************/
+static int mv_fdt_update_tdm(void *fdt)
+{
+	int err, nodeoffset;				/* nodeoffset: node offset from libfdt */
+	char propval[10];				/* property value */
+	const char *prop = "status";			/* property name */
+	char node[64];					/* node name */
+
+	if (mvBoardIsTdmConnected() == MV_TRUE)
+		sprintf(propval, "okay");
+	else
+		sprintf(propval, "disabled");
+
+	sprintf(node, "tdm@%x", MV_TDM_OFFSET);
+	nodeoffset = mv_fdt_find_node(fdt, node);
+
+	if (nodeoffset < 0) {
+		mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+		return 0;
+	}
+
+	if (strncmp(fdt_get_name(fdt, nodeoffset, NULL), node, strlen(node)) == 0) {
+		mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+						propval, strlen(propval)+1));
+		if (err < 0) {
+			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+			return 0;
+		}
+		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef MV_USB_VBUS_CYCLE
+/*******************************************************************************
+* mv_fdt_update_usb_vbus
+*
+* DESCRIPTION:
+* target		: update status field of usb3_phy and usb3-vbus-gpio/usb3-vbus-exp1 node.
+* node, properties	: -property status @ node usb3_phy and usb3-vbus-gpio/usb3-vbus-exp1 node.
+* dependencies		: BOARD_GPP_USB_VBUS entry in BoardGppInfo --> usb3-vbus-gpio node
+* 			  MV_IO_EXPANDER_USB_VBUS entry in BoardIoExpPinInfo --> usb3-vbus-exp1
+*
+* INPUT:
+*	fdt.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	-1 on error os 0 otherwise.
+*
+*******************************************************************************/
+static int mv_fdt_update_usb_vbus(void *fdt)
+{
+	int err, nodeoffset;				/* nodeoffset: node offset from libfdt */
+	char propval[10];				/* property value */
+	const char *prop = "status";			/* property name */
+	const char *node = NULL, *phy_node = NULL;	/* node name */
+	MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo;		/* empty stub - not to be used */
+
+	sprintf(propval, "okay");
+
+	if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_USB_VBUS, &ioInfo) != MV_ERROR) {
+		node = "usb3-vbus-exp1";
+		phy_node = "usb3-phy-exp1";
+	} else {
+		/* remove invalid i2c pins information, to avoid unexpected Linux behaviour*/
+		mv_fdt_remove_node(fdt, "i2c-pins-0");
+	}
+	if (mvBoardUSBVbusGpioPinGet(0) != MV_ERROR) {
+			node = "usb3-vbus-gpio";
+			phy_node = "usb3-phy-gpio";
+	} else {
+		/* remove invalid vbus gpio pins information, to avoid unexpected Linux behaviour*/
+		mv_fdt_remove_node(fdt, "xhci0-vbus-pins");
+	}
+
+	if (!node && !phy_node)
+		return 0;
+
+	nodeoffset = mv_fdt_find_node(fdt, node);
+
+	if (nodeoffset < 0) {
+		mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+		return 0;
+	}
+	if (strncmp(fdt_get_name(fdt, nodeoffset, NULL), node, strlen(node)) == 0) {
+		mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+						propval, strlen(propval)+1));
+		if (err < 0) {
+			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+			return 0;
+		}
+		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
+	}
+
+	/* enable 'usb3_phy' node - for Linux regulator usage */
+	nodeoffset = mv_fdt_find_node(fdt, phy_node);
+
+	if (nodeoffset < 0) {
+		mv_fdt_dprintf("Lack of '%s' node in device tree\n", phy_node);
+		return 0;
+	}
+
+	if (strncmp(fdt_get_name(fdt, nodeoffset, NULL), phy_node, strlen(phy_node)) == 0) {
+		mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+						propval, strlen(propval)+1));
+		if (err < 0) {
+			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, phy_node);
+			return 0;
+		}
+		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, phy_node);
+	}	return 0;
+	return 0;
+}
+#endif /* MV_USB_VBUS_CYCLE */
 
 #ifdef CONFIG_MV_SDHCI
 /*******************************************************************************
 * mv_fdt_update_sdhci
 *
 * DESCRIPTION:
+* target		: update status and dat3-cd fields of MMC node.
+* node, properties	: -property status and dat3-cd @ node sdhci@X.
+* dependencies		: status of MMC in isSdMmcConnected entry in board structure.
 *
 * INPUT:
 *	fdt.
@@ -486,6 +653,7 @@
 	char propval[10];				/* property value */
 	const char *prop = "status";			/* property name */
 	char node[64];					/* node name */
+	char *env;
 
 	if (mvBoardisSdioConnected())
 		sprintf(propval, "okay");
@@ -497,7 +665,7 @@
 
 	if (nodeoffset < 0) {
 		mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
-		return -1;
+		return 0;
 	}
 
 	if (strncmp(fdt_get_name(fdt, nodeoffset, NULL), node, strlen(node)) == 0) {
@@ -505,11 +673,122 @@
 						propval, strlen(propval)+1));
 		if (err < 0) {
 			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
-			return -1;
+			return 0;
 		}
 		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
 	}
 
+	/* add DAT3 detection */
+	env = getenv("sd_detection_dat3");
+
+	if (!env || strcmp(env, "yes") != 0)
+		return 0;
+
+	prop = "dat3-cd";
+
+	/* add empty property 'dat3-cd' */
+	if (fdt_appendprop(fdt, nodeoffset, prop, NULL, 0) < 0)
+		mv_fdt_dprintf("Failed to set property '%s' of node '%s' in device tree\n", prop, node);
+
+	return 0;
+}
+#endif
+
+#ifdef MV_INCLUDE_AUDIO
+/*******************************************************************************
+* mv_fdt_update_audio
+*
+* DESCRIPTION: update audio-controller and sound nodes (SPDIF/I2S)
+*
+* INPUT: fdt.
+* OUTPUT: None.
+* RETURN: -1 on error os 0 otherwise.
+*******************************************************************************/
+static int mv_fdt_update_audio(void *fdt)
+{
+	int err, nodeoffset, i;				/* nodeoffset: node offset from libfdt */
+	char propval[10];				/* property value */
+	const char *prop = "status";			/* property name */
+	char nodes[2][64];				/* node names */
+
+	if (mvBoardIsAudioConnected() == MV_TRUE)
+		sprintf(propval, "okay");
+	else
+		sprintf(propval, "disabled");
+
+	sprintf(nodes[0], "audio-controller@%x", MV_AUDIO_OFFSET);
+	sprintf(nodes[1], "sound");
+
+	for (i = 0; i < 2; ++i) {
+		nodeoffset = mv_fdt_find_node(fdt, nodes[i]);
+		if (nodeoffset < 0) {
+			mv_fdt_dprintf("Lack of '%s' node in device tree\n", nodes[i]);
+			return 0;
+		}
+
+		if (strncmp(fdt_get_name(fdt, nodeoffset, NULL), nodes[i], strlen(nodes[i])) == 0) {
+			mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+							propval, strlen(propval)+1));
+			if (err < 0) {
+				mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, nodes[i]);
+				return 0;
+			}
+			mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, nodes[i]);
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SWITCHING_SERVICES
+/*******************************************************************************
+* mv_fdt_update_prestera
+*
+* DESCRIPTION:
+* target		: update status field of prestera node by checking if the board is AMC.
+* node, properties	: -property status @ node prestera.
+* dependencies		: AMC status saved in isAmc entry in board structure
+*
+* INPUT:
+*	fdt.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	-1 on error os 0 otherwise.
+*
+*******************************************************************************/
+static int mv_fdt_update_prestera(void *fdt)
+{
+	int err, nodeoffset;					/* nodeoffset: node offset from libfdt */
+	char propval[10];					/* property value */
+	const char *prop = "status";				/* property name */
+	const char *node = "prestera";				/* node name */
+	MV_BOOL isAmc;
+
+	isAmc = mvBoardisAmc();
+	if (isAmc)
+		sprintf(propval, "okay");
+	else
+		sprintf(propval, "disabled");
+
+	nodeoffset = mv_fdt_find_node(fdt, node);
+
+	if (nodeoffset < 0) {
+		mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+		return 0;
+	}
+
+	mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+					propval, strlen(propval)+1));
+	if (err < 0) {
+		mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+		return -1;
+	}
+	mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
+
 	return 0;
 }
 #endif
@@ -518,6 +797,9 @@
 * mv_fdt_update_pex
 *
 * DESCRIPTION:
+* target		: update status fields of pcieX nodes.
+* node, properties	: -property status @ node pcieX.
+* dependencies		: boardPexInfo structure entry in board structure.
 *
 * INPUT:
 *	fdt.
@@ -555,7 +837,7 @@
 	nodeoffset = mv_fdt_find_node(fdt, node);
 	if (nodeoffset < 0) {
 		mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
-		return -1;
+		return 0;
 	}
 	while (strncmp(node, "pcie", 4) == 0) {
 		for (k = 0; k <= pexnum; k++)
@@ -572,7 +854,7 @@
 		if (err < 0) {
 			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n",
 				       prop, node);
-			return -1;
+			return 0;
 		}
 		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop,
 			       propval, node);
@@ -580,13 +862,13 @@
 		if (nodeoffset < 0) {
 			mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n",
 				       prop, node);
-			return -1;
+			return 0;
 		}
 		node = fdt_get_name(fdt, nodeoffset, NULL);
 	}
 	return 0;
 }
-
+#ifdef MV_INCLUDE_USB
 /*******************************************************************************
 * mv_fdt_update_usb
 *
@@ -613,7 +895,7 @@
 		sprintf(node, "usb%s@%x", unitType == USB_UNIT_ID ? "" : "3", MV_USB2_USB3_REGS_OFFSET(unitType, i));
 		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 -1;
+			return 0;
 		}
 	}
 
@@ -621,9 +903,96 @@
 }
 
 /*******************************************************************************
+* mv_fdt_update_usb2
+*
+* DESCRIPTION: update USB2.0(eHCI) status, this function is wrapper function
+* to mv_fdt_update_usb, In order to add it to update_sequence array
+*
+* INPUT: fdt.
+* OUTPUT: None.
+* RETURN: -1 on error os 0 otherwise.
+*******************************************************************************/
+static int mv_fdt_update_usb2(void *fdt)
+{
+	return mv_fdt_update_usb(fdt, USB_UNIT_ID);
+}
+
+/*******************************************************************************
+* mv_fdt_update_usb3
+*
+* DESCRIPTION: update USB3.0(xHCI) status, this function is wrapper function
+* to mv_fdt_update_usb, In order to add it to update_sequence array
+*
+* INPUT: fdt.
+* OUTPUT: None.
+* RETURN: -1 on error os 0 otherwise.
+*******************************************************************************/
+static int mv_fdt_update_usb3(void *fdt)
+{
+	return mv_fdt_update_usb(fdt, USB3_UNIT_ID);
+}
+#endif /* MV_INCLUDE_USB */
+
+#ifdef MV_INCLUDE_USB_DEVICE
+/*******************************************************************************
+* mv_fdt_update_usb_device
+*
+* DESCRIPTION: usb3 device status
+* target		: update status field of u3d and udc nodes.
+* node, properties	: property status @ nodes usb3@X, udc@X and udc@X.
+* dependencies		: S@R field 'usb3port0' or 'usb3port1'.
+*
+* INPUT: fdt.
+* OUTPUT: None.
+* RETURN: -1 on error os 0 otherwise.
+*******************************************************************************/
+static int mv_fdt_update_usb_device(void *fdt)
+{
+	char propval[10];				/* property value */
+	const char *prop = "status";			/* property name */
+	char node[64];					/* node name */
+	int i;
+	MV_BOOL isDevice = MV_FALSE;
+
+	/* disable usb3 nodes */
+	for (i = 0; i < MV_USB3_MAX_HOST_PORTS; i++) {
+		if (mvBoardIsUsb3PortDevice(i)) {
+			/* if Port is Device, disable corresponding Host node */
+			sprintf(propval, "disabled");
+			isDevice = MV_TRUE;
+			break;
+		}
+	}
+
+	if (isDevice == MV_FALSE)
+		return 0;
+
+	sprintf(node, "usb3@%x", MV_USB2_USB3_REGS_OFFSET(USB3_UNIT_ID, i));
+	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);
+
+	/* enable 'u3d' and 'udc' nodes */
+	sprintf(propval, "okay");
+	sprintf(node, "u3d@%x", MV_USB3_DEVICE_REGS_OFFSET);
+	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;
+	}
+	sprintf(node, "udc@%x", MV_USB3_DEVICE_USB2_REGS_OFFSET);
+	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;
+	}
+	return 0;
+}
+#endif /* MV_INCLUDE_USB_DEVICE */
+/*******************************************************************************
 * mv_fdt_update_pinctrl
 *
 * DESCRIPTION:
+* target		: update compatible field of pinctrl node.
+* node, properties	: -property compatible @ node pinctrl.
+* dependencies		:DEV_ID_REG value "device model type".
 *
 * INPUT:
 *	fdt.
@@ -645,11 +1014,11 @@
 	const char *node = "pinctrl";			/* node name */
 #endif
 
-	/* update pinctrl driver 'compatible' propert, according to device model type */
+	/* update pinctrl driver 'compatible' property, according to device model type */
 	sprintf(propval, "marvell,mv88f%x-pinctrl", mvCtrlModelGet());
 	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 -1;
+		return 0;
 	}
 
 	return 0;
@@ -659,6 +1028,14 @@
 * mv_fdt_update_ethnum
 *
 * DESCRIPTION:
+* target		: update ethernet nodes for PP3/Neta drivers.
+* node, properties	: PP3 Driver	: -property status @ node nic@X.
+*					  -property phy-mode and phy-id @ node macX.
+*			  Neta Driver	: -property status and phy-mode @ node ethernet@X.
+*					  -property reg @ node ethernet-phy@X.
+* dependencies		: pBoardNetComplexInfo entry in board structure.
+*			  pBoardMacInfo entry in board structure.
+*	     		  For PP3/Neta driver we get ethernet nodes via "nic@/ethernet@" aliasses.
 *
 * INPUT:
 *	fdt.
@@ -691,7 +1068,7 @@
 	aliasesoffset = mv_fdt_find_node(fdt, "aliases");
 	if (aliasesoffset < 0) {
 		mv_fdt_dprintf("Lack of 'aliases' node in device tree\n");
-		return -1;
+		return 0;
 	}
 
 	/* Walk trough all aliases and count Ethernet ports entries */
@@ -713,11 +1090,11 @@
 		node = fdt_getprop(fdt, aliasesoffset, prop, &len);
 		if (node == NULL) {
 			mv_fdt_dprintf("Lack of '%s' property in 'aliases' node\n", prop);
-			return -1;
+			return 0;
 		}
 		if (len == 0) {
 			mv_fdt_dprintf("Empty property value\n");
-			return -1;
+			return 0;
 		}
 		/* Alias points to the ETH port node using full DT path */
 		nodeoffset = fdt_path_offset(fdt, node);
@@ -738,12 +1115,12 @@
 			phandle = fdt_getprop(fdt, nodeoffset, "phy", &len);
 			if (len == 0) {
 				mv_fdt_dprintf("Empty \"phy\" property value\n");
-				return -1;
+				return 0;
 			}
 			phyoffset = fdt_node_offset_by_phandle(fdt, ntohl(*phandle));
 			if (phyoffset < 0) {
 				mv_fdt_dprintf("Failed to get PHY node by phandle %x\n", ntohl(*phandle));
-				return -1;
+				return 0;
 			}
 
 			/* Setup PHY address in DT in "reg" property of an appropriate PHY node.
@@ -754,7 +1131,7 @@
 			if (err < 0) {
 				mv_fdt_dprintf("Failed to set property '%s' of node '%s' in device tree\n",
 							   prop, fdt_get_name(fdt, phyoffset, NULL));
-				return -1;
+				return 0;
 			}
 			mv_fdt_dprintf("Set property '%s' of node '%s' to %#010x\n",
 						   prop, fdt_get_name(fdt, phyoffset, NULL), ntohl(phyAddr));
@@ -771,7 +1148,7 @@
 				break;
 			default:
 				mv_fdt_dprintf("Bad port type received for interface %d\n", port);
-				return -1;
+				return 0;
 			}
 
 			/* Setup PHY connection type in DT */
@@ -779,7 +1156,7 @@
 			mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop, propval, strlen(propval)+1));
 			if (err < 0) {
 				mv_fdt_dprintf("Failed to set property '%s' of node '%s' in device tree\n", prop, node);
-				return -1;
+				return 0;
 			}
 			mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
 
@@ -791,7 +1168,7 @@
 		mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop, propval, strlen(propval)+1));
 		if (err < 0) {
 			mv_fdt_dprintf("Failed to set property '%s' of node '%s' in device tree\n", prop, node);
-			return -1;
+			return 0;
 		}
 		mv_fdt_dprintf("Set '%s' property to '%s' in '%s' node\n", prop, propval, node);
 
@@ -855,7 +1232,7 @@
 		sprintf(node, "spi@%x", MV_SPI_REGS_OFFSET(unit));
 		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 -1;
+			return 0;
 		}
 	} /* SPI units/buses */
 
@@ -882,7 +1259,7 @@
 #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 -1;
+		return 0;
 	}
 
 	/* handle NOR flashes - there is only one NOR unit, but different CS are possible */
@@ -916,10 +1293,9 @@
 
 		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 -1;
+			return 0;
 		}
 	}
-
 	return 0;
 }
 
@@ -1072,8 +1448,8 @@
 	int err = 0;		/* error number */
 	int level = 0;		/* current fdt scanning depth */
 	char aliasname[128];	/* alias name to be stored in '/aliases' node */
-	char path[128] = "";	/* full path to current node */
-	char tmp[128];		/* auxiliary char array for extended node name*/
+	char path[256] = "";	/* full path to current node */
+	char tmp[256];		/* auxiliary char array for extended node name*/
 	char *cut;		/* auxiliary char pointer */
 	const char *node;	/* node name */
 	uint32_t tag;		/* device tree tag at given offset */
@@ -1286,7 +1662,7 @@
 		if (err < 0) {
 			mv_fdt_dprintf("NFC update: fail to modify '%s'\n",
 				       prop);
-			return -1;
+			return 0;
 		}
 		mv_fdt_dprintf("NFC update: set '%s' property to '%s'\n",
 			       prop, propval);
@@ -1343,7 +1719,7 @@
 		mv_fdt_modify(fdt, err, fdt_setprop(fdt,0 , prop, propval, len));
 	if (len <= 0 || err < 0) {
 		mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
-		return -1;
+		return 0;
 	}
 	mv_fdt_dprintf("Set '%s' property to Root node\n", prop);
 
@@ -1354,6 +1730,9 @@
 * mv_fdt_update_serial
 *
 * DESCRIPTION:
+* target		: Update status field of serial nodes.
+* node, properties:	: -property status @ node serial
+* dependencies		: checks if it is a active serial port via mvUartPortGet function.
 *
 * INPUT:
 *	fdt.
@@ -1381,13 +1760,13 @@
 		sprintf(node, "serial@%x", MV_UART_REGS_OFFSET(i));
 		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 -1;
+			return 0;
 		}
 	}
 
 	return 0;
 }
-
+#ifdef CONFIG_PIC_GPIO
 /*******************************************************************************
 * mv_fdt_update_pic_gpio
 *
@@ -1397,7 +1776,7 @@
 * 1. pinctrl/pic-pins-0/marvell,pins = "mpp33", "mpp34";
 * 2. pm_pic/ctrl-gpios = <0x0000000c 0x00000001 0x00000001 0x0000000c 0x00000002 0x00000001>;
 *    Each GPIO is represented in 'ctrl-gpios' property with 3 values of 32 bits:
-*    '<pinctrl-0_base + gpio_group_num   gpio_pin_num_in_group   ACTIVE_LOW>'
+*    '<gpios_phandle[gpio_group_num]   gpio_pin_num_in_group   ACTIVE_LOW>'
 *    i.e : for mpp 33, and given pinctrl-0 = <0x0000000b> :
 *    gpio_group_num	= 33/32 = 1
 *    gpio_pin_num_in_group= 33%32 = 1
@@ -1421,11 +1800,13 @@
 	const char *marvell_pins_prop 	= "marvell,pins";
 	const char *pm_picNode  	= "pm_pic";
 	const char *ctrl_gpios_prop 	= "ctrl-gpios";
-	const void *pinctrl_0_base;
-	MV_U32 pinctrl_0_base_val, picGpioInfo[MAX_GPIO_NUM];
+	MV_U32 picGpioInfo[MAX_GPIO_NUM];
 	MV_U32 ctrl_gpios_prop_value[3*MAX_GPIO_NUM]; /* 3*32bit is required per GPIO */
 	char propval[256] = "";
 	int err, len = 0, nodeoffset, i, gpioMaxNum = mvBoardPICGpioGet(picGpioInfo);
+	MV_U32 gpios_phandle[2];	/* phandle values of gpio nodes */
+	MV_U32 gpio_offset;
+	char gpio_node[30] = "";
 
 	/* if board has no dedicated PIC MPP Pins: remove 'pm_pic' & 'pinctrl/pic-pins-0' */
 	if (gpioMaxNum <= 0) {
@@ -1437,6 +1818,21 @@
 		return 0;
 	}
 
+	/* fetch gpio nodes' phandle.
+	 * every GPIO group have GPIO node id DT
+	 * and for each GPIO pin, an entry is added to the ctrl-gpios,
+	 * in order to link between the entry and the relevant gpio node for the relevant
+	 * group, the phandle of the gpio node is added to the entry */
+	for (i = 0; i < 2; ++i) {
+		sprintf(gpio_node, "gpio@%X", MV_GPP_REGS_OFFSET(i));
+		gpio_offset = mv_fdt_find_node(fdt, gpio_node);
+		gpios_phandle[i] = fdt_get_phandle(fdt, gpio_offset);
+		if (!gpios_phandle[i]) {
+			mvOsPrintf("Failed updating suspend-resume GPIO pin settings in DT\n");
+			return 0;
+		}
+	}
+
 	/* set pinctrl/pic-pins-0/marvell,pins property as concatenated strings.
 	 * (i.e : marvell,pins = "mpp33", "mpp34", "mpp35")
 	 * append next string after the NULL character that the previous
@@ -1448,29 +1844,28 @@
 	mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, marvell_pins_prop, propval, len));
 	if (err < 0) {
 		mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", marvell_pins_prop, picPinsNode);
-		return -1;
+		return 0;
 	}
 	mv_fdt_dprintf("Set '%s' property in '%s' node\n", marvell_pins_prop, picPinsNode);
 
 
 	/* set pm_pic/ctrl-gpios property: */
 	nodeoffset = mv_fdt_find_node(fdt, pm_picNode); 	/* find 'pm_pic' node */
-	pinctrl_0_base = fdt_getprop(fdt, nodeoffset, "pinctrl-0", &len);
+
 	if (len == 0) {
 		printf("Empty property value\n");
-		return -1;
+		return 0;
 	}
 	/* Each GPIO is represented in 'ctrl-gpios' property with 3 values of 32 bits:
-	 * '<pinctrl-0_base + gpio_group_num   gpio_pin_num_in_group   ACTIVE_LOW>'
+	 * '<gpios_phandle[gpio_group_num]   gpio_pin_num_in_group   ACTIVE_LOW>'
 	 * i.e : for mpp 33, and given pinctrl-0 = <0x0000000b> :
 	 * gpio_group_num	= 33/32 = 1
 	 * gpio_pin_num_in_group= 33%32 = 1
 	 * ACTIVE_LOW = 1
 	 * DT entry is : '<0x0000000c 0x00000001 0x00000001>'; */
-	pinctrl_0_base_val = ntohl(*((unsigned int*)pinctrl_0_base));	/* DT integer values are in BE format */
 	for (i = 0 ; i < gpioMaxNum ; i++) {
 		/* pinctrl_0_base +gpio Group num */
-		ctrl_gpios_prop_value[3*i] = htonl(pinctrl_0_base_val + picGpioInfo[i] / 32);
+		ctrl_gpios_prop_value[3*i] = htonl(gpios_phandle[picGpioInfo[i] / 32]);
 
 		/* 32 pins in each group */
 		ctrl_gpios_prop_value[3*i + 1] = htonl(picGpioInfo[i] % 32);
@@ -1482,11 +1877,135 @@
 	mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, ctrl_gpios_prop, ctrl_gpios_prop_value, 4*gpioMaxNum*3));
 	if (err < 0) {
 		mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", ctrl_gpios_prop, pm_picNode);
-		return -1;
+		return 0;
 	}
 	mv_fdt_dprintf("Set '%s' property in '%s' node\n", ctrl_gpios_prop, pm_picNode);
 
 	return 0;
-}
 
+}
+#endif /* CONFIG_PIC_GPIO */
+#ifdef MV_INCLUDE_SWITCH
+/*******************************************************************************
+* mv_fdt_update_switch
+*
+* DESCRIPTION:
+*  This routines updates switch node and ethernet-phy node on status and rgmii_(t)rx_timing_delay properties
+*  according to Switch existence and Device ID detection, this route also set ethernet-phy@i node on reg property
+*  if ethi is connected to switch
+*
+* INPUT:
+*	fdt.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	-1 on error os 0 otherwise.
+*
+*******************************************************************************/
+static int mv_fdt_update_switch(void *fdt)
+{
+	char propval[10];				/* property value */
+	u32 propval_u32 = 0;
+	char prop[50];					/* property name */
+	char node[64];					/* node name */
+	MV_U16 switch_device_id;
+	int nodeoffset;					/* node offset from libfdt */
+	int err;
+
+	switch_device_id = mvEthSwitchGetDeviceID();
+
+	/*if switch module is connected and detect correct switch device ID, enable switch in fdt*/
+	if (switch_device_id > 0)
+		sprintf(propval, "okay");
+	else
+		sprintf(propval, "disabled");
+
+	sprintf(node, "switch");
+	sprintf(prop, "status");
+
+	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;
+	}
+
+	if (mvBoardIsSwitchConnected()) {
+		int i = 0;
+		switch_device_id >>= QD_REG_SWITCH_ID_PRODUCT_NUM_OFFSET;
+
+		for (i = 0; i < mvCtrlEthMaxPortGet(); i++) {
+			/*change the switch connected eth ports' phy to 999*/
+			/*999 mean that ethernet is not connected to phy*/
+			if (mvBoardSwitchConnectedPortGet(i) != -1) {
+				sprintf(node, "ethernet-phy@%d", i);
+				sprintf(prop, "reg");
+				propval_u32 = 999;
+
+				nodeoffset = mv_fdt_find_node(fdt, node);
+				if (nodeoffset < 0) {
+					mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+					return -1;
+				}
+
+				/* Setup PHY address in DT in "reg" property of an appropriate PHY node.
+				This value is HEX number, not a string, and uses network byte order */
+				propval_u32 = htonl(propval_u32);
+				mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop,
+					&propval_u32, sizeof(propval_u32)));
+				if (err < 0) {
+					mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+					return -1;
+				}
+			}
+		}
+
+		/*for E6172 switch, rgmii_rx_timing_delay and rgmii_tx_timing_delay should be enabled*/
+		if (switch_device_id == MV_E6172_PRODUCT_NUM) {
+			/*set rgmii_rx_timing_delay and rgmii_tx_timing_delay to be enabled*/
+			sprintf(node, "switch");
+			sprintf(prop, "rgmii_rx_timing_delay");
+			/*enable delay to RXCLK for IND inputs when port is in RGMII mode*/
+			propval_u32 = 1;
+
+			nodeoffset = mv_fdt_find_node(fdt, node);
+			if (nodeoffset < 0) {
+				mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+				return -1;
+			}
+
+			/* Setup rgmii_rx_timing_delay in DT.
+			This value is HEX number, not a string, and uses network byte order */
+			propval_u32 = htonl(propval_u32);
+			mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop, &propval_u32, sizeof(propval_u32)));
+			if (err < 0) {
+				mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+				return -1;
+			}
+
+			sprintf(node, "switch");
+			sprintf(prop, "rgmii_tx_timing_delay");
+			/*enable delay to GTXCLK for OUTD outputs when port is in RGMII mode*/
+			propval_u32 = 1;
+			nodeoffset = mv_fdt_find_node(fdt, node);
+			if (nodeoffset < 0) {
+				mv_fdt_dprintf("Lack of '%s' node in device tree\n", node);
+				return -1;
+			}
+
+			/* Setup rgmii_tx_timing_delay in DT.
+			This value is HEX number, not a string, and uses network byte order */
+			propval_u32 = htonl(propval_u32);
+			mv_fdt_modify(fdt, err, fdt_setprop(fdt, nodeoffset, prop, &propval_u32, sizeof(propval_u32)));
+			if (err < 0) {
+				mv_fdt_dprintf("Modifying '%s' in '%s' node failed\n", prop, node);
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
 #endif
+#endif
+
diff --git a/board/mv_ebu/common/USP/mv_main.c b/board/mv_ebu/common/USP/mv_main.c
index dbf2159..2aaa439 100755
--- a/board/mv_ebu/common/USP/mv_main.c
+++ b/board/mv_ebu/common/USP/mv_main.c
@@ -98,7 +98,7 @@
 #else
 #define DB(x)
 #endif
-
+extern void fdt_env_setup(char *fdtfile, MV_BOOL runUpdate);
 extern int display_dram_config(int print);
 int late_print_cpuinfo(void);
 /* CPU address decode table. */
@@ -291,7 +291,6 @@
 		*(unsigned int *)(0x0 + i) = *(unsigned int*)(CONFIG_SYS_TEXT_BASE + i);
 	}
 	mvBoardDebugLed(4);
-	mv_print_map();
 	return 0;
 }
 
@@ -303,8 +302,8 @@
 
 	envSetDefault("console", "console=ttyS0,115200");
 #if defined(MV_NAND) && defined(MV_INCLUDE_SPI)
-	envSetDefault("mtdparts", "'mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);mtdparts=spi_flash:4m(boot),-(spi-rootfs)'");
-	envSetDefault("mtdids", "nand0=armada-nand;spi0=spi_flash");
+	envSetDefault("mtdparts", "'mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs);spi_flash:4m(boot),-(spi-rootfs)'");
+	envSetDefault("mtdids", "nand0=armada-nand,spi0=spi_flash");
 #elif defined(MV_NAND)
 	envSetDefault("mtdparts", "mtdparts=armada-nand:8m(boot)ro,8m@8m(kernel),-(rootfs)");
 	envSetDefault("mtdids", "nand0=armada-nand");
@@ -393,6 +392,9 @@
 	envSetDefault("bootcmd_lgcy", "tftpboot 0x2000000 $image_name; setenv bootargs $bootargs_dflt; bootm 0x2000000; ");
 #endif /* #if defined (CONFIG_CMD_STAGE_BOOT) */
 
+#ifdef CONFIG_CMD_SOURCE
+	envSetDefault("run_script", "no");
+#endif
 	/* netbsd boot arguments */
 	env = getenv("netbsd_en");
 	if( !env || ( ((strcmp(env,"no") == 0) || (strcmp(env,"No") == 0) ))) {
@@ -463,6 +465,13 @@
 	envSetDefault("enaLPAE", "no");;
 #endif
 
+	/* Flatten Device Tree environment setup */
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+	fdt_env_setup("msys.dtb", MV_FALSE); /* static setup: Skip DT update for customer */
+#else
+	fdt_env_setup("msys.dtb", MV_FALSE); /* dynamic setup: run DT update (false since not supported yet) */
+#endif
+
 #if (CONFIG_BOOTDELAY >= 0)
 	env = getenv("bootcmd");
 	if(!env)
@@ -681,7 +690,7 @@
 
 	/* init the units decode windows */
 	misc_init_r_dec_win();
-
+	mv_print_map();
 	/* Clear old kernel images which remained stored in memory */
 	memset ((void *)CONFIG_SYS_LOAD_ADDR, 0, CONFIG_SYS_MIN_HDR_DEL_SIZE);
 	mvBoardDebugLed(6);
@@ -698,7 +707,12 @@
 	/* Init the PHY or Switch of the board */
 	mvBoardEgigaPhyInit();
 #endif /* #if defined(MV_INCLUDE_UNM_ETH) || defined(MV_INCLUDE_GIG_ETH) */
-
+#ifdef CONFIG_CMD_SOURCE
+	/* run saved script */
+	env = getenv("run_script");
+	if (env && strcmp(env, "yes") == 0)
+		run_command("mvsource run", 0);
+#endif
 	return 0;
 }
 
diff --git a/board/mv_ebu/common/USP/mv_phy.c b/board/mv_ebu/common/USP/mv_phy.c
index 411e739..d289e2e 100644
--- a/board/mv_ebu/common/USP/mv_phy.c
+++ b/board/mv_ebu/common/USP/mv_phy.c
@@ -80,6 +80,7 @@
 #include "eth/gbe/mvEthRegs.h"
 #endif
 #include "mvSysEthPhyApi.h"
+#include "ethSwitch/mvSwitchRegs.h"
 #include "ethSwitch/mvSwitch.h"
 
 #if defined (MV88F66XX)
@@ -191,7 +192,9 @@
 *******************************************************************************/
 void mvBoardLedMatrixInit(void)
 {
+#ifdef MV_INCLUDE_SWITCH
 	MV_U8 i;
+#endif
 
 	if (mvCtrlDevFamilyIdGet(0) == MV_88F67X0)
 		/* Led matrix mode in 7Bit */
@@ -205,6 +208,7 @@
 		/* Use an internal device signal to drive the LED Matrix Control */
 		MV_REG_WRITE(LED_MATRIX_CONTROL_REG(2), BIT0 | BIT2 | BIT3 | BIT5);
 
+#ifdef MV_INCLUDE_SWITCH
 		/* initialize internal PHYs controlled by switch */
 		if (mvBoardIsInternalSwitchConnected() == MV_TRUE) {
 			for (i = 0; i < 4; i++) {
@@ -218,6 +222,7 @@
 				mvEthSwitchPhyRegWrite(0x0, i, 0x16, 0x0);
 			}
 		}
+#endif
 	}
 
 	/* initialize External RGMII-0 PHY (SMI controlled by MAC0 @address 0x1) */
@@ -286,6 +291,9 @@
 	int i;
 	MV_STATUS   status;
 	MV_U32 phyAddr;
+#ifdef MV_INCLUDE_SWITCH
+	MV_U16 switchDeviceID;
+#endif
 
 	for (i = 0; i < mvCtrlEthMaxPortGet(); i++) {
 		if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, i))
@@ -321,6 +329,27 @@
 		}
 	}
 
+#ifdef MV_INCLUDE_SWITCH
+	switchDeviceID = mvEthSwitchGetDeviceID();
+	if (mvBoardIsSwitchConnected()) {
+		switchDeviceID >>= QD_REG_SWITCH_ID_PRODUCT_NUM_OFFSET;
+		for (i = 0; i < mvCtrlEthMaxPortGet(); i++) {
+			/*force the switch connected eth port link up and disable auto-neg, bit 15 must set to 1*/
+			if (mvBoardSwitchConnectedPortGet(i) != -1)
+				MV_REG_WRITE((NETA_GMAC_AN_CTRL_REG(i) + INTER_REGS_BASE),
+					(NETA_FORCE_LINK_PASS_MASK | NETA_SET_GMII_SPEED_1000_MASK |
+					NETA_SET_FLOW_CONTROL_MASK | NETA_FLOW_CONTROL_ADVERTISE_MASK |
+					NETA_SET_FULL_DUPLEX_MASK | BIT15)/*0x9342*/);
+		}
+
+		/*now only E6172 switch works for NETA, so here no other switch initialization is called*/
+		if (switchDeviceID == MV_E6172_PRODUCT_NUM)
+			mvEthE6172SwitchBasicInit(0);
+		if (switchDeviceID == MV_E6176_PRODUCT_NUM)
+			mvEthE6171SwitchBasicInit(0);
+	}
+#endif
+
 #elif defined (MV88F66XX) /* Avanta-LP: dynamic PPv2 configuration */
         MV_U32 ethComplex = mvBoardEthComplexConfigGet();
 	char *eeeEnable = NULL;
diff --git a/board/mv_ebu/common/USP/mv_rtc2.c b/board/mv_ebu/common/USP/mv_rtc2.c
index 03b8120..c61b405 100644
--- a/board/mv_ebu/common/USP/mv_rtc2.c
+++ b/board/mv_ebu/common/USP/mv_rtc2.c
@@ -70,38 +70,100 @@
 #include "mv_rtc2.h"
 
 #if defined(CONFIG_CMD_DATE)
-
+/* This define for WA in rtc read */
+#define SAMPLE_NR 100
 static int rtc_ready = -1;
 
+
 /*******************************************************/
 void rtc_init(void)
 {
 	/* Update RTC-MBUS bridge timing parameters */
+	#ifdef ERRATA_FE_3124064
+	/* Functional Errata Ref #: FE-3124064 -  WA for failing time read attempts.
+	 * Description:
+	 * 	The device supports CPU write and read access to the RTC Time register.
+	 * 	However, due to this erratum, Write to RTC TIME register may fail.
+	 * 	Read from RTC TIME register may fail.
+	 * Workaround:
+	 * 	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to RTC Status register.
+	 * 	RTC TIME register should be read twice, the second read will return a proper value.
+	 * 	Configure maximum value (0x3FF) in write clock period in RTC Mbus Bridge Timing Control register.
+	 * Functional Impact After Workaround is applied:
+	 * 	No functional impact after WA is applied
+	 */
+	MV_REG_WRITE(MV_RTC2_SOC_OFFSET, 0xFD4D4FFF);
+#else
 	MV_REG_WRITE(MV_RTC2_SOC_OFFSET, 0xFD4D4CFA);
+#endif
 	rtc_ready = 1;
 }
 
+#ifdef ERRATA_FE_3124064
+struct _strTime2Freq {
+	unsigned long nTime;
+	unsigned int  nFreq;
+
+};
+#endif
+
 /*******************************************************/
 int rtc_get(struct rtc_time *tm)
 {
-	unsigned long time, time_check;
+#ifdef ERRATA_FE_3124064
+	/* Functional Errata Ref #: FE-3124064 - WA for failing time read attempts.
+	 * Description:
+	 *      The device supports CPU write and read access to the RTC Time register.
+	 *	However, due to this erratum, Write to RTC TIME register may fail.
+	 *	Read from RTC TIME register may fail.
+	 * Workaround:
+	 *	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to
+	 *	RTC Status register.
+	 *	Configure maximum value (0x3FF) in write clock period in RTC Mbus Bridge
+	 *	Timing Control register.
+	 *	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to
+	 *	RTC Status register.
+	 *      RTC TIME register should be read 100 times, then find the result
+	 *	that appear most frequently, use this result as the correct value.
+	 */
+	unsigned long nTimeArray[SAMPLE_NR], i, j, nTime, nMax = 0, indexMax = SAMPLE_NR - 1;
+	struct _strTime2Freq sTimeToFreq[SAMPLE_NR];
+#endif
 
 	if (rtc_ready != 1)
 		rtc_init();
+#ifdef ERRATA_FE_3124064
+	/* read RTC TIME register 100 times and save the values in array,
+	   initialize the counters to zero */
+	for (i = 0; i < SAMPLE_NR; i++) {
+		sTimeToFreq[i].nFreq = 0;
+		nTimeArray[i] = RTC_READ_REG(RTC_TIME_REG_OFFS);
+	}
+	for (i = 0; i < SAMPLE_NR; i++) {
+		nTime = nTimeArray[i];
+		/* if nTime appears in sTimeToFreq array so add the counter of nTime value,
+		   if didn't appear yet in counters array then allocate new member of
+		   sTimeToFreq array with counter = 1 */
+		for (j = 0; j < SAMPLE_NR; j++) {
+			if (sTimeToFreq[j].nFreq == 0 || sTimeToFreq[j].nTime == nTime)
+				break;
+		}
+		if (sTimeToFreq[j].nFreq == 0)
+			sTimeToFreq[j].nTime = nTime;
+		sTimeToFreq[j].nFreq++;
+		/*find the most common result*/
+		if (nMax < sTimeToFreq[j].nFreq) {
+			indexMax = j;
+			nMax = sTimeToFreq[j].nFreq;
+		}
+	}
 
-	time = RTC_READ_REG(RTC_TIME_REG_OFFS);
-	/* WA for failing time read attempts. The HW ERRATA information should be added here */
-	/* if detected more than one second between two time reads, read once again */
-	time_check = RTC_READ_REG(RTC_TIME_REG_OFFS);
-	if ((time_check - time) > 1)
-		time_check = RTC_READ_REG(RTC_TIME_REG_OFFS);
-	/* End of WA */
-
-	to_tm(time_check, tm);
-
+	to_tm(sTimeToFreq[indexMax].nTime, tm);
+#else
+	to_tm(RTC_READ_REG(RTC_TIME_REG_OFFS), tm);
+#endif
 	return 0;
 }
-
 /*******************************************************/
 int rtc_set(struct rtc_time *tm)
 {
@@ -113,10 +175,22 @@
 	time = mktime(tm->tm_year, tm->tm_mon,
 				  tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
-	/* WA for failing time set attempts. The HW ERRATA information should be added here */
+#ifdef ERRATA_FE_3124064
+	/* Functional Errata Ref #: FE-3124064 -  WA for failing time read attempts.
+	 * Description:
+	 * 	The device supports CPU write and read access to the RTC Time register.
+	 * 	However, due to this erratum, Write to RTC TIME register may fail.
+	 * 	Read from RTC TIME register may fail.
+	 * Workaround:
+	 * 	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to RTC Status register.
+	 * 	RTC TIME register should be read twice, the second read will return a proper value.
+	 * 	Configure maximum value (0x3FF) in write clock period in RTC Mbus Bridge Timing Control register.
+	 * Functional Impact After Workaround is applied:
+	 * 	No functional impact after WA is applied
+	 */
 	RTC_WRITE_REG(0, RTC_STATUS_REG_OFFS);
-	mdelay(100);
-	/* End of SW WA */
+	RTC_WRITE_REG(0, RTC_STATUS_REG_OFFS);
+#endif
 	RTC_WRITE_REG(time, RTC_TIME_REG_OFFS);
 
 	return 0;
diff --git a/board/mv_ebu/common/USP/mv_serial.c b/board/mv_ebu/common/USP/mv_serial.c
index 89ea29b..1e49ef9 100755
--- a/board/mv_ebu/common/USP/mv_serial.c
+++ b/board/mv_ebu/common/USP/mv_serial.c
@@ -40,7 +40,11 @@
  */
 __weak MV_U32 mvUartPortGet(void)
 {
+#ifdef CONFIG_AMP_SUPPORT
+	return whoAmI();
+#else
 	return CONFIG_SYS_DUART_CHAN;
+#endif
 }
 
 int mv_serial_init (void)
@@ -66,18 +70,18 @@
 {
 	if (c == '\n')
 
-	mvUartPutc(whoAmI(), '\r');
-	mvUartPutc(whoAmI(), c);
+	mvUartPutc(mvUartPortGet(), '\r');
+	mvUartPutc(mvUartPortGet(), c);
 }
 
 int mv_serial_getc(void)
 {
-	return mvUartGetc(whoAmI());
+	return mvUartGetc(mvUartPortGet());
 }
 
 int mv_serial_tstc(void)
 {
-	return mvUartTstc(whoAmI());
+	return mvUartTstc(mvUartPortGet());
 }
 
 void mv_serial_setbrg (void)
diff --git a/board/mv_ebu/common/USP/mv_usb.c b/board/mv_ebu/common/USP/mv_usb.c
index 3794dd0..bd24b65 100644
--- a/board/mv_ebu/common/USP/mv_usb.c
+++ b/board/mv_ebu/common/USP/mv_usb.c
@@ -35,42 +35,6 @@
 #endif
 #include "mvSysUsbConfig.h"
 
-/*******************************************************************************
-* getUsbActive - read 'usbActive' env variable and set active port
-*
-* INPUT:
-* 	MV_U32 usbUnitId - USB interface indication (USB2.0 / USB3.0)
-*
-* OUTPUT:
-* 	prints selected active port number, and selected interface
-*
-* RETURN:
-*       Num of requested interface USB2/3
-*
-*******************************************************************************/
-MV_STATUS getUsbActive(MV_U32 usbUnitId, MV_U32 maxUsbHostPorts, MV_U32 maxSerDesLanes, MV_BOOL printEn)
-{
-	char *env = getenv("usbActive");
-	int usbActive = simple_strtoul(env, NULL, 10);
-
-	/*  if requested USB3.0 is not connected via SerDes, but there are enough USB3.0 ports */
-	if (printEn) {
-		if (usbUnitId == USB3_UNIT_ID && (usbActive >= maxSerDesLanes && maxUsbHostPorts > maxSerDesLanes)) {
-			mvOsPrintf("\n'usbActive' warning (%d): Invalid USB3.0 port (no valid SerDes)..", usbActive);
-			mvOsPrintf("Trying USB2.0 Host via USB3.0\n");
-		} else if (usbActive >= maxUsbHostPorts && usbUnitId == USB_UNIT_ID) {
-			mvOsPrintf("\n'usbActive' warning (%d): Invalid USB2.0 port\n", usbActive);
-		}
-
-		mvOsPrintf("Port (usbActive) : %d\tInterface (usbType = %d) : ", usbActive,
-				((usbUnitId == USB3_UNIT_ID) ? 3 : 2));
-	}
-	/* Fetch SoC USB mapping:
-	   For Some SoCs, when using single USB port, unit 1 is active and not 0 */
-	usbActive = mvCtrlUsbMapGet(usbUnitId, usbActive);
-
-	return usbActive;
-}
 
 #if defined (CONFIG_USB_XHCI)
 /*********************************************************************************/
@@ -197,6 +161,44 @@
 	.interface_supported = MV_FALSE
 #endif
 };
+/*******************************************************************************
+* printUsbError  - This function used to print error message when USB error dedected.
+*			 called from "usb_lowlevel_init" and "usb_lowlevel_stop" functions.
+*
+* INPUT:
+*	MV_BOOL value - MV_TRUE if usb connected on current board ,MV_FALSE otherwise.
+*
+* OUTPUT:
+*	prints USB error messages.
+*
+* RETURN:
+*	-1
+*
+*******************************************************************************/
+static int printUsbError(MV_BOOL mvBoardIsUsbPortConnected ,int port)
+{
+        int usbType = simple_strtoul(getenv("usbType"), NULL, 10);
+        int usb3HostNum = mvCtrlUsb3HostMaxGet();
+        int usb2HostNum = mvCtrlUsbMaxGet();
+
+	if(mvBoardIsUsbPortConnected == MV_FALSE)
+		mvOsPrintf("\nError: requested 'usbActive' (%d) is not connected on current board\n",port);
+	else {
+		mvOsPrintf("Error: requested 'usbType' (Type %d) is not supported.", usbType);
+		if ((usbType == 2 && usb2HostNum < 1) || (usbType ==3 && usb3HostNum < 1))
+		mvOsPrintf(" (no available USB%d ports on current Soc).\n",usbType);
+	}
+	if ((hc_ehci.interface_supported == MV_TRUE && usb2HostNum > 0) ||
+			(hc_xhci.interface_supported == MV_TRUE && usb3HostNum > 0))
+		mvOsPrintf("\n\n\t Supported Units:\n");
+	if (hc_ehci.interface_supported == MV_TRUE && usb2HostNum > 0)
+		mvOsPrintf("\n\tUSB2.0: %d ports: set usbType = 2 --> EHCI Stack will be used\n", usb2HostNum);
+	if (hc_xhci.interface_supported == MV_TRUE && usb3HostNum > 0)
+		mvOsPrintf("\tUSB3.0: %d ports: set usbType = 3 --> xHCI Stack will be used\n", usb3HostNum);
+	return -1;
+
+}
+
 
 /* usb_lowlevel_init:
 *	this routine navigate between currently selected stack (eHCI/xHCI)
@@ -205,10 +207,14 @@
 *	  usbType = 3 -- > xHCI
 *	- Call usb_lowlevel_init from selected stack
 */
+
+/* mark detected usb port, to ensure proper 'stop'
+ * process before next detection request */
+int currentUsbActive = -1;
 int usb_lowlevel_init(int index, void **controller)
 {
 	int usb2HostNum, usb3HostNum, usbType, usbActive = 0;
-
+	usbActive = simple_strtoul(getenv("usbActive"), NULL, 10);
 	usbType = simple_strtoul(getenv("usbType"), NULL, 10);
 	usb3HostNum = mvCtrlUsb3HostMaxGet();
 	usb2HostNum = mvCtrlUsbMaxGet();
@@ -216,95 +222,70 @@
 	switch (usbType) {
 	case 2:
 		if (hc_ehci.interface_supported == MV_TRUE && usb2HostNum > 0) {
-			usbActive = getUsbActive(USB_UNIT_ID, usb2HostNum, 0, MV_TRUE); /* read requested active port */
+			usbActive = mvCtrlUsbMapGet(USB_UNIT_ID, usbActive);
+			if (mvBoardIsUsbPortConnected(USB_UNIT_ID, usbActive) == MV_FALSE)
+				return printUsbError(MV_FALSE, usbActive);
 			hc = &hc_ehci; /* set Host Controller struct for function pointers  */
 		} else
-			goto input_error;
+			 return printUsbError(MV_TRUE, usbActive);
 		break;
 	case 3:
 		if (hc_xhci.interface_supported == MV_TRUE && usb3HostNum > 0) {
-			usbActive = getUsbActive(USB3_UNIT_ID, usb3HostNum , mvCtrlUsb3MaxGet(),
-					MV_TRUE); /* read requested active port */
+			/* mvCtrlUsbMapGet used only for legacy devices ALP/A375 */
+			usbActive = mvCtrlUsbMapGet(USB3_UNIT_ID, usbActive);
+			if (mvBoardIsUsbPortConnected(USB3_UNIT_ID, usbActive) == MV_FALSE)
+				return printUsbError(MV_FALSE, usbActive);
+			if (mvCtrlIsUsbSerDesConnected(usbActive) == MV_FALSE) {
+				mvOsPrintf("\n'usbActive' warning (%d): Invalid USB3.0 port (no valid SerDes)..", usbActive);
+				mvOsPrintf("Trying USB2.0 Host via USB3.0\n");
+			}
+#ifdef MV_USB_VBUS_CYCLE
+			/* VBUS signal is lowered prior to SerDes initialization sequence,
+			 * before initializing and detecting device, set VBUS enabled */
+			mvBoardUsbVbusSet(usbActive);
+#endif
 			hc = &hc_xhci; /* set Host Controller struct for function pointers  */
 		} else
-			goto input_error;
+			return printUsbError(MV_TRUE, usbActive);
 		break;
 	default:
-		goto input_error;
+		return printUsbError(MV_TRUE, usbActive);
+	}
+	mvOsPrintf("Port (usbActive) : %d\tInterface (usbType = %d) : ", usbActive,
+                ((usbType == 3) ? 3 : 2));
+
+	/* Make sure that usbActive never exeeds the configured max controllers count
+	   The CONFIG_USB_MAX_CONTROLLER_COUNT can be changed for different boards */
+	if (usbActive >= CONFIG_USB_MAX_CONTROLLER_HOST_COUNT) {
+		mvOsPrintf("usbActive=%d is out of supported range\n",usbActive);
+		return -1;
 	}
 
+	/* Marvell USB code supports only one active controller (USB0), while the actual host
+	   device is selected by usbActive environment variable */
+	if (index > 0) {
+		mvOsPrintf("\nOnly one active controller supported! Skipping USB%d initialization.\n", index);
+		return -1;
+	}
+
+	currentUsbActive = usbActive;
 	return hc->hc_usb_lowlevel_init(usbActive, controller);
-
-input_error:
-	mvOsPrintf("Error: requested 'usbType' (Type %d) is not supported", usbType);
-	if ((usbType == 2 && usb2HostNum < 1) || (usbType ==3 && usb3HostNum < 1))
-		mvOsPrintf(" (no available USB ports).\n");
-
-	if ((hc_ehci.interface_supported == MV_TRUE && usb2HostNum > 0) ||
-		(hc_xhci.interface_supported == MV_TRUE && usb3HostNum > 0))
-		mvOsPrintf("\n\n\t Supported Units:\n");
-	if (hc_ehci.interface_supported == MV_TRUE && usb2HostNum > 0)
-		mvOsPrintf("\n\tUSB2.0: %d ports: set usbType = 2 --> EHCI Stack will be used\n", usb2HostNum);
-	if (hc_xhci.interface_supported == MV_TRUE && usb3HostNum > 0)
-		mvOsPrintf("\tUSB3.0: %d ports: set usbType = 3 --> xHCI Stack will be used\n", usb3HostNum);
-	return -1;
 }
 
 int usb_lowlevel_stop(int index)
 {
-	int usb2UnitNum, usb3UnitNum, usbType, usbActive = 0;
+	int usbActive = currentUsbActive, ret;
 
 	if (!hc) {
 		mvOsPrintf("%s: Error: run 'usb reset' to set host controller interface.\n", __func__);
 		return -1;
 	}
 
-	usbType = simple_strtoul(getenv("usbType"), NULL, 10);
-	usb3UnitNum = mvCtrlUsb3MaxGet();
-	usb2UnitNum = mvCtrlUsbMaxGet();
-
-	switch (usbType) {
-	case 2:
-		if (hc != &hc_ehci) {
-			mvOsPrintf("Error - Please run \"usb stop\" before changing \"usbType\".\n");
-			return 0;
-		}
-		if (hc_ehci.interface_supported == MV_TRUE && usb2UnitNum > 0)
-			usbActive = getUsbActive(USB_UNIT_ID, usb2UnitNum, 0,
-					MV_FALSE); /* read requested active port */
-		else
-			goto input_error;
-		break;
-	case 3:
-		if (hc != &hc_xhci) {
-			mvOsPrintf("Error - Please run \"usb stop\" before changing \"usbType\".\n");
-			return 0;
-		}
-		if (hc_xhci.interface_supported == MV_TRUE && usb3UnitNum > 0)
-			usbActive = getUsbActive(USB3_UNIT_ID, usb3UnitNum, mvCtrlUsb3MaxGet(),
-					MV_FALSE); /* read requested active port */
-		else
-			goto input_error;
-		break;
-	default:
-		goto input_error;
-	}
-
-	return hc->hc_usb_lowlevel_stop(usbActive);
-input_error:
-	mvOsPrintf("Error: requested 'usbType' (Type %d) is not supported", usbType);
-	if ((usbType == 2 && usb2UnitNum < 1) || (usbType == 3 && usb3UnitNum < 1))
-		mvOsPrintf(" (no available USB ports).\n");
-
-	if ((hc_ehci.interface_supported == MV_TRUE && usb2UnitNum > 0) ||
-		(hc_xhci.interface_supported == MV_TRUE && usb3UnitNum > 0))
-		mvOsPrintf("\n\n\t Supported Units:\n");
-	if (hc_ehci.interface_supported == MV_TRUE && usb2UnitNum > 0)
-		mvOsPrintf("\n\tUSB2.0: %d ports: set usbType = 2 --> EHCI Stack will be used\n", usb2UnitNum);
-	if (hc_xhci.interface_supported == MV_TRUE && usb3UnitNum > 0)
-		mvOsPrintf("\tUSB3.0: %d ports: set usbType = 3 --> xHCI Stack will be used\n", usb3UnitNum);
-	return -1;
-
+	/* Mark that there is no current usbActive to stop */
+	currentUsbActive = -1;
+	ret = hc->hc_usb_lowlevel_stop(usbActive);
+	hc = NULL;
+	return ret;
 }
 
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
diff --git a/board/mv_ebu/common/USP/switchingServices/sar_bc2.c b/board/mv_ebu/common/USP/switchingServices/sar_bc2.c
new file mode 100755
index 0000000..714865d
--- /dev/null
+++ b/board/mv_ebu/common/USP/switchingServices/sar_bc2.c
@@ -0,0 +1,478 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+
+*******************************************************************************/
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <pci.h>
+#include <net.h>
+#include <spi_flash.h>
+#include <bzlib.h>
+
+#include "mvCommon.h"
+#include "ctrlEnv/mvCtrlEnvLib.h"
+#include "boardEnv/mvBoardEnvLib.h"
+#include "cpu/mvCpu.h"
+
+#if defined(MV_INC_BOARD_NOR_FLASH)
+#include "norflash/mvFlash.h"
+#endif
+
+#if defined(MV_INCLUDE_GIG_ETH)
+#include "eth-phy/mvEthPhy.h"
+#endif
+
+#if defined(MV_INCLUDE_PEX)
+#include "pex/mvPex.h"
+#endif
+
+#if defined(MV_INCLUDE_PDMA)
+#include "pdma/mvPdma.h"
+#include "mvSysPdmaApi.h"
+#endif
+
+#if defined(MV_INCLUDE_XOR)
+#include "xor/mvXorRegs.h"
+#include "xor/mvXor.h"
+#endif
+
+#if defined(MV_INCLUDE_PMU)
+#include "pmu/mvPmuRegs.h"
+#endif
+
+#include "cntmr/mvCntmrRegs.h"
+#include "switchingServices.h"
+
+/* defines  */
+#undef MV_DEBUG
+#ifdef MV_DEBUG
+#define DB(x) x
+#define DB1(x)  x
+#else
+#define DB(x)
+#define DB1(x)
+#endif
+
+/* SAR defines when Connected to Bc2*/
+#define MV_BOARD_CTRL_I2C_ADDR_BC2	0x0
+#define TWSI_CHANNEL_BC2			0
+#define TWSI_SPEED_BC2				20000 // wa for bits 1,2 in 0x4c. Mmust lower 100000 -> 20000 . adiy, erez
+typedef volatile unsigned long VUL;
+
+static MV_U8 tread_bc2(MV_U8 addr, int reg)
+{
+		MV_TWSI_SLAVE twsiSlave;
+		MV_TWSI_ADDR slave;
+		MV_U8 data;
+
+		DB(printf("tread_bc2, DevAddr = 0x%x\n", addr));
+
+		/* TWSI init */
+		slave.address = MV_BOARD_CTRL_I2C_ADDR_BC2;
+		slave.type = ADDR7_BIT;
+
+		mvTwsiInit (TWSI_CHANNEL_BC2, TWSI_SPEED_BC2, mvBoardTclkGet(), &slave, 0);
+
+		/* read SatR */
+		twsiSlave.slaveAddr.type = ADDR7_BIT;
+		twsiSlave.slaveAddr.address = addr ;
+		twsiSlave.validOffset = MV_TRUE;
+		twsiSlave.offset = reg;
+		twsiSlave.moreThen256 = MV_FALSE;
+
+		if (MV_OK != mvTwsiRead(TWSI_CHANNEL_BC2, &twsiSlave, &data, 1)) {
+				DB(printf("tread_bc2 : twsi read fail\n"));
+				return MV_ERROR;
+		}
+		DB(printf("tread_bc2: twsi read succeeded, data = 0x%x\n", data));
+
+		return data;
+}
+
+static MV_STATUS twrite_bc2(MV_U8 addr, int reg, MV_U8 regVal)
+{
+		MV_TWSI_SLAVE twsiSlave;
+		MV_TWSI_ADDR slave;
+		MV_U8 data;
+
+		//  printf(">>> in twrite_bc2, addr=0x%x, reg = 0x%x, val=0x%x\n", addr, reg, regVal);
+		/* TWSI init */
+		slave.address = MV_BOARD_CTRL_I2C_ADDR_BC2;
+		slave.type = ADDR7_BIT;
+
+		mvTwsiInit (TWSI_CHANNEL_BC2, TWSI_SPEED_BC2, mvBoardTclkGet(), &slave, 0);
+
+		/* write SatR */
+		twsiSlave.slaveAddr.address = addr;
+		twsiSlave.slaveAddr.type = ADDR7_BIT;
+		twsiSlave.validOffset = MV_TRUE;
+		twsiSlave.offset = reg;
+		twsiSlave.moreThen256 = MV_FALSE;
+
+		data = regVal;
+		if (MV_OK != mvTwsiWrite(TWSI_CHANNEL_BC2, &twsiSlave, &data, 1)) {
+				DB(mvOsPrintf("twrite_bc2: twsi write fail\n"));
+				return MV_ERROR;
+		}
+		DB(mvOsPrintf("twrite_bc2: twsi write succeeded\n"));
+
+		return MV_OK;
+}
+
+static int do_sar_list_bc2(int argc, char *const argv[])
+{
+		const char *cmd;
+		int all = 0;
+
+		if (argc < 1)
+				goto usage;
+		cmd = argv[0];
+
+		if (strcmp(cmd, "all") == 0)
+				all = 1;
+
+		if ((strcmp(cmd, "corefreq") == 0) || all) {
+				printf("corefreq (0x4d 0:3): Determines the CORE frequency:\n");
+				printf("\t0x0 = 360MHz\n");
+				printf("\t0x1 = 220MHz\n");
+				printf("\t0x2 = 250MHz\n");
+				printf("\t0x3 = 400MHz\n");
+				printf("\t0x4 = 500MHz\n");
+				printf("\t0x5 = 520MHz\n");
+				printf("\t0x6 = 450MHz\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "cpufreq") == 0)  || all) {
+				printf("cpufreq (0x4d 3:4 + 0x4e 0:0): Determines the CPU and DDR frequencies:\n");
+				printf("\t0x0 = CPU 400MHz, DDR 400MHz\n");
+				printf("\t0x2 = CPU 667MHz, DDR 667MHz\n");
+				printf("\t0x3 = CPU 800MHz, DDR 800MHz\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "tmfreq") == 0)  || all) {
+				printf("tmfreq (0x4e 1:3): Determines the boot selection:\n");
+				printf("\t0x0 = TM clock is disabled\n");
+				printf("\t0x1 = TM runs 400MHZ, DDR3 runs 800MHz\n");
+				printf("\t0x2 = TM runs 466MHZ, DDR3 runs 933MHz\n");
+				printf("\t0x3 = TM runs 333MHZ, DDR3 runs 667MHz\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "bootsel") == 0) || all) {
+				printf("bootsel (0x4f 0:2): Determines the TM frequency:\n");
+				printf("\t0x0 = BootROM enabled, Boot from Device(NOR) flash\n");
+				printf("\t0x1 = BootROM enabled, Boot from NAND flash (new NF controller on DEV_CSn[0])\n");
+				printf("\t0x2 = BootROM enabled, boot from UART\n");
+				printf("\t0x3 = BootROM enabled, boot from SPI0(CS0)\n");
+				printf("\t0x5 = BootROM enabled, Standby slave. Must set PCIs as endpoint (i.e. CPU IDLE)\n");
+				printf("\t0x6 = BootROM enabled, UART debug prompt mode\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "jtagcpu") == 0) || all) {
+				printf("jtagcpu (0x4f 3:3): Determines the JTAG to CPU connection:\n");
+				printf("\t0x0 = JTAG is connected to C3M CPU\n");
+				printf("\t0x1 = JTAG is connected to MSYS CPU\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "ptppll") == 0) || all) {
+				printf("ptppll (0x4f 4:4): Determines the ptppll:\n");
+				printf("\t0x1 = Must write 0x1. PTP PLL runs @ 1093.75MHz, PTP Clock = 546.875MHz\n");
+				printf("\n");
+		}
+
+		if ((strcmp(cmd, "pciegen1") == 0) || all) {
+				printf("pciegen1 (0x4c.1 4:4): Determines the pciegen1:\n");
+				printf("\t0x0 = Do not force BC2 PCIe connection to GEN1\n");
+				printf("\t0x1 = Force BC2 PCIe connection to GEN1\n");
+				printf("\n");
+		}
+
+		return 0;
+
+		usage:
+		printf("Usage: Satr - see options\n");
+		return 1;
+}
+
+static int do_sar_read_bc2(int argc, char *const argv[])
+{
+
+/*
+   bc2 sample and reset register
+
+#     4f       #     4e       #     4d       #      4c      #
+#              #              #              #              #
+#--|--|--|--|--#--|--|--|--|--#--|--|--|--|--#--|--|--|--|--#
+#  |  |  |  |  #  |  |  |  |  #  |  |  |  |  #  |  |  |  |  #
+#--|--|--|--|--#--|--|--|--|--#--|--|--|--|--#--|--|--|--|--#
+#  |           #  |        |  #     |        #              #
+#-P|-R|bootsel-#-R|-TM-f---|-CPU-f--|-CORE-f-#-----devid----#
+
+
+*/
+
+		const char *cmd;
+		volatile uint satr_reg;
+
+		cmd = argv[0];
+
+		if (strcmp(cmd, "dump") == 0) {
+				satr_reg =
+				((tread_bc2(0x4c, 0)&0x1f) << 0) |	// 5 bits
+				((tread_bc2(0x4d, 0)&0x1f) << 5) |
+				((tread_bc2(0x4e, 0)&0x1f) << 10) |
+				((tread_bc2(0x4f, 0)&0x1f) << 15);
+				printf("BC2 S@R raw register = 0x%08x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "devid") == 0) {
+				satr_reg = tread_bc2(0x4c, 0) & 0x1f;
+				printf("BC2 S@R devid = 0x%02x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "corefreq") == 0) {
+				satr_reg = tread_bc2(0x4d, 0) & 0x07;
+				printf("BC2 S@R corefreq = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "cpufreq") == 0) {
+				satr_reg = ((tread_bc2(0x4d, 0) & 0x18) >> 3) | ((tread_bc2(0x4e, 0) & 0x01) << 2);
+				printf("BC2 S@R cpufreq = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "tmfreq") == 0) {
+				satr_reg = (tread_bc2(0x4e, 0) & 0x0e) >> 1;
+				printf("BC2 S@R tmfreq = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "bootsel") == 0) {
+				satr_reg = tread_bc2(0x4f, 0) & 0x07;
+				printf("BC2 S@R bootsel = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "jtagcpu") == 0) {
+				satr_reg = (tread_bc2(0x4f, 0) & 0x08) >> 3;
+				printf("BC2 S@R jtagcpu = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "ptppll") == 0) {
+				satr_reg = (tread_bc2(0x4f, 0) & 0x10) >> 4;
+				printf("BC2 S@R ptppll = 0x%x\n", satr_reg);
+		}
+
+		else if (strcmp(cmd, "pciegen1") == 0) {
+				satr_reg = (tread_bc2(0x4c, 1) & 0x10) >> 4;
+				printf("BC2 S@R pciegen1 = 0x%x\n", satr_reg);
+		}
+
+		return 0;
+}
+
+static int do_sar_write_bc2(int argc, char *const argv[])
+{
+		const char *cmd;
+		volatile uint satr_reg;
+		volatile int bit_mask;
+
+		cmd = argv[0];
+
+		if (strcmp(cmd, "devid") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x1f);
+				twrite_bc2(0x4c, 0, (MV_U8)bit_mask);
+		}
+
+		else if (strcmp(cmd, "corefreq") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x07);
+				satr_reg = tread_bc2(0x4d, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x18) | bit_mask;
+				twrite_bc2(0x4d, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "cpufreq") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x07);
+				satr_reg = tread_bc2(0x4d, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x07) | ((bit_mask & 0x03) << 3);
+				twrite_bc2(0x4d, 0, (MV_U8)satr_reg);
+
+				satr_reg = tread_bc2(0x4e, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x1e) | ((bit_mask & 0x04) >> 2);
+				twrite_bc2(0x4e, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "tmfreq") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x07);
+				satr_reg = tread_bc2(0x4e, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x11) | (bit_mask  << 1);
+				twrite_bc2(0x4e, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "bootsel") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x07);
+				satr_reg = tread_bc2(0x4f, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x18) | bit_mask;
+				twrite_bc2(0x4f, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "jtagcpu") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x01);
+				satr_reg = tread_bc2(0x4f, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x17) | (bit_mask << 3);
+				twrite_bc2(0x4f, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "ptppll") == 0) {
+				bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x01);
+				satr_reg = tread_bc2(0x4f, 0) & 0x1f;
+				satr_reg = (satr_reg & 0x0f) | (bit_mask << 4);
+				twrite_bc2(0x4f, 0, (MV_U8)satr_reg);
+		}
+
+		else if (strcmp(cmd, "pciegen1") == 0) {
+			bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x01);
+			satr_reg = tread_bc2(0x4c, 1) & 0x1f;
+			satr_reg = (satr_reg & 0x0f) | (bit_mask << 4);
+			twrite_bc2(0x4c, 1, (MV_U8)satr_reg);
+		}
+
+		return 0;
+}
+
+
+
+MV_STATUS check_twsi_bc2(void)
+{
+		MV_U8 reg = tread_bc2(0x4c, 0);
+		DB(printf("\ncheck_twsi_bc2: read_BC2= 0x%x\n", reg));
+		if (reg == 0xff)
+				return MV_ERROR;
+		else
+				return MV_OK;
+}
+
+int do_sar_bc2(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+
+		const char *cmd;
+
+		/* need at least two arguments */
+		if (argc < 2)
+				goto usage;
+
+		cmd = argv[1];
+
+		if (check_twsi_bc2() == MV_ERROR) {
+				printf("BC2 twsi channel not connected\n");
+				return 1;
+		}
+
+
+		if (strcmp(cmd, "list") == 0)
+				return do_sar_list_bc2(argc - 2, argv + 2);
+
+		else if (strcmp(cmd, "read") == 0)
+				return do_sar_read_bc2(argc - 2, argv + 2);
+
+
+		else if (strcmp(cmd, "write") == 0) {
+				if (do_sar_write_bc2(argc - 2, argv + 2) == 0) {
+						do_sar_read_bc2(argc - 2, argv + 2);
+				}
+				return 0;
+
+		}
+
+		usage:
+		printf("\n");
+		printf("BC2 Sample At Reset sub-system\n");
+		printf("SatR list corefreq  - print corefreq list\n");
+		printf("SatR list cpufreq   - print cpufreq list\n");
+		printf("SatR list tmfreq    - print tmfreq list\n");
+		printf("SatR list bootsel   - print boolsel list\n");
+		printf("SatR list jtagcpu   - print jtagcpu list\n");
+		printf("SatR list ptppll    - print ptppll list\n");
+		printf("SatR list pciegen1  - print pciegen1 list\n");
+
+		printf("\n");
+
+		printf("SatR read devid     - read device id\n");
+		printf("SatR read corefreq  - read CORE frequency\n");
+		printf("SatR read cpufreq   - read CPU frequency\n");
+		printf("SatR read tmfreq    - read TM frequency\n");
+		printf("SatR read bootsel   - read Boot select\n");
+		printf("SatR read jtagcpu   - read JTAG CPU selection\n");
+		printf("SatR read ptppll    - read PTP PLL setting\n");
+		printf("SatR read pciegen1  - read Force PCIe GEN1 setting\n");
+		printf("SatR read dump      - read all values\n");
+		printf("\n");
+
+		printf("SatR write devid    <val> - write device id\n");
+		printf("SatR write corefreq <val> - write CORE frequency\n");
+		printf("SatR write cpufreq  <val> - write CPU  frequency\n");
+		printf("SatR write tmfreq   <val> - write TM frequency\n");
+		printf("SatR write bootsel  <val> - write Boot select\n");
+		printf("SatR write jtagcpu  <val> - write JTAG CPU selection\n");
+		printf("SatR write ptppll   <val> - write PTP PLL setting\n");
+		printf("SatR write pciegen1 <val> - write Force PCIe GEN1 setting\n");
+
+		return 1;
+}
+
+#ifndef MV_MSYS
+/* This function used for AMC + remote MSYS case. The MSYS standalone implementation differs */
+static int do_qsgmii_sel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+		int bit_mask;
+
+		if (argc < 2)
+				goto usage;
+
+		if (check_twsi_bc2() == MV_ERROR) {
+				printf("BC2 twsi channel not connected\n");
+				return 1;
+		}
+
+		bit_mask = (simple_strtoul(argv[1], NULL, 16) & 0x0000ffff);
+
+		twrite_bc2(0x20, 2, (MV_U8)((bit_mask >> 0) & 0xff));
+		twrite_bc2(0x20, 3, (MV_U8)((bit_mask >> 8) & 0xff));
+		twrite_bc2(0x20, 6, 0x0);
+		twrite_bc2(0x20, 7, 0x0);
+		return 1;
+
+		usage:
+		cmd_usage(cmdtp);
+		return 1;
+}
+
+
+U_BOOT_CMD(
+		  qsgmii_sel,      2,     1,      do_qsgmii_sel,
+		  " Select SFP or QSGMII modes on bc2.\n",
+		  " apply 16 bit array to select SFP or QSGMII modes"
+		  );
+
+#endif
+
+
diff --git a/board/mv_ebu/common/USP/switchingServices/switchingServices.c b/board/mv_ebu/common/USP/switchingServices/switchingServices.c
index 5885aaf..8a5b5cc 100755
--- a/board/mv_ebu/common/USP/switchingServices/switchingServices.c
+++ b/board/mv_ebu/common/USP/switchingServices/switchingServices.c
@@ -246,6 +246,19 @@
 	"\n    - print information for all SPI FLASH memory banks\n"
 );
 
+static int isSwitchingServicesSupported(void)
+{
+	MV_U32 family = mvCtrlDevFamilyIdGet(0);
+
+	/* enable command only for AC3 & BC2 & AMC boards  */
+	if (!((family >= MV_ALLEYCAT3_DEV_ID && family <= MV_ALLEYCAT3_MAX_DEV_ID)
+		|| family == MV_BOBCAT2_DEV_ID || mvBoardisAmc())) {
+		printf("Command not supported for this SoC/Board\n");
+		return 0;
+	}
+	return 1;
+}
+
 /*******************************************************************************
 * do_cpss_env - Save CPSS enviroment on flash
 *
@@ -263,6 +276,9 @@
 {
 	char buf[1024];
 
+	if (!isSwitchingServicesSupported())
+		return 0;
+
 	printf("Saving cpss environment variable\n");
 	setenv("standalone", "");
 	setenv("bootcmd", "run standalone_mtd");
@@ -277,7 +293,7 @@
 					 "console=${consoledev},${baudrate} ${othbootargs} ${linux_parts}; tftp ${linux_loadaddr} "
 					 "${image_name};bootm ${linux_loadaddr}");
 
-	sprintf(buf,"'spi_flash:%dm(spi_uboot)ro,%dm(spi_kernel),%dm(spi_rootfs),-(remainder)"
+	sprintf(buf,"'mtdparts=spi_flash:%dm(spi_uboot)ro,%dm(spi_kernel),%dm(spi_rootfs),-(remainder)"
 		";armada-nand:%dm(nand_kernel),-(nand_rootfs)'", CFG_APPL_FLASH_PART_UBOOT_SIZE / _1M,
 		CFG_APPL_SPI_FLASH_PART_KERNEL_SIZE / _1M, CFG_APPL_SPI_FLASH_PART_ROOTFS_SIZE / _1M,
 		CFG_APPL_NAND_FLASH_PART_KERNEL_SIZE / _1M);
@@ -290,7 +306,7 @@
 	sprintf(buf,
 		"sf probe; sf read ${loadaddr} 0x%x 0x%x; setenv bootargs ${console} "
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off "
-		"root=/dev/mtdblock2 rw init=/linuxrc rootfstype=jffs2 rootwait mtdparts=${mtdparts} "
+		"root=/dev/mtdblock2 rw init=/linuxrc rootfstype=jffs2 rootwait ${mtdparts} "
 		"${mvNetConfig}; bootm ${loadaddr} ",
 		CFG_APPL_SPI_FLASH_PART_KERNEL_START, CFG_APPL_SPI_FLASH_PART_KERNEL_SIZE);
 #ifndef MV_NAND
@@ -304,7 +320,7 @@
 
 #ifdef MV_NAND
 	sprintf(buf,
-		"nand read ${loadaddr} 0x%x 0x%x; setenv bootargs ${console} mtdparts=${mtdparts} "
+		"nand read ${loadaddr} 0x%x 0x%x; setenv bootargs ${console} ${mtdparts} "
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off "
 		"ubi.mtd=5 root=ubi0:rootfs_nand ro rootfstype=ubifs ${mvNetConfig}; bootm 0x2000000;" ,
 		CFG_APPL_NAND_FLASH_PART_KERNEL_START,
@@ -324,7 +340,9 @@
 	""
 );
 
+#if defined(MV_INCLUDE_SPI)
 extern struct spi_flash *flash;
+#endif
 
 struct partitionInformation nandInfo = {
 	.defaultImage = "ubifs_arm_nand.image",
@@ -355,8 +373,11 @@
 		sprintf(cmdBuf, "nand write.trimffs %x %x %x\n", source, destination, len);
 		printf(cmdBuf);
 		run_command(cmdBuf, 0);
-	} else
+	}
+#if defined(MV_INCLUDE_SPI)
+	else
 		spi_flash_write(flash, destination, len, (const void *)source);
+#endif
 }
 
 void flashErase (MV_U32 destination, MV_U32 len, MV_BOOL isNand)
@@ -366,14 +387,16 @@
 		sprintf(cmdBuf, "nand erase %x %x\n", destination, len);
 		printf(cmdBuf);
 		run_command(cmdBuf, 0);
-	} else
+	}
+#if defined(MV_INCLUDE_SPI)
+	else
 		spi_flash_erase(flash, destination, len);
-
+#endif
 }
 
 static int do_mtdburn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	MV_U32 i, filesize, addr, src_addr, dest_addr;
+	MV_U32 i, addr, src_addr, dest_addr;
 	MV_U32 kernel_unc_len, rootfs_unc_len = 0, unc_len, src_len;
 	MV_U32 kernel_addr = CFG_DEF_KERNEL_DEST_ADDR;
 	MV_U32 rootfs_addr = CFG_DEF_ROOTFS_DEST_ADDR;
@@ -385,7 +408,10 @@
 	MV_U32 fsys = FS_TYPE_FAT;				/* default FS = FAT */
 	MV_BOOL isNand = MV_TRUE;				/* default destination = NAND */
 	addr = load_addr = CFG_DEF_SOURCE_LOAD_ADDR;
-	int fileSizeFromRam = -1;
+	int filesize, fileSizeFromRam = -1;
+
+	if (!isSwitchingServicesSupported())
+		return 0;
 
 	/* scan for flash destination in arguments (allowing usage of only 'mtdburn spi') */
 	for (i = 1 ; i < argc ; i++) {
@@ -403,30 +429,29 @@
 		fileSizeFromRam = simple_strtoul(argv[6], NULL, 16);
 	case 6:/* arg#6 is flash destination, scanned previously --> fall to 5*/
 	case 5:
-		copy_filename (BootFile, argv[4], sizeof(BootFile));
+		if(strcmp(argv[4], "EXT2") == 0)
+			fsys = FS_TYPE_EXT;
 		/* fall to 4*/
 	case 4:
-		if(strcmp(argv[3], "EXT2") == 0)
-			fsys = FS_TYPE_EXT;
+		devPart = argv[3];
 		/* fall to 3*/
 	case 3:
-		devPart = argv[2];
-		/* fall to 2*/
-	case 2:
-		if(strcmp(argv[1], "usb") == 0)
+		if(strcmp(argv[2], "usb") == 0)
 			loadfrom = 1;
-		else if(strcmp(argv[1], "mmc") == 0)
+		else if(strcmp(argv[2], "mmc") == 0)
 			loadfrom = 2;
-		else if(strcmp(argv[1], "ram") == 0) {
+		else if(strcmp(argv[2], "ram") == 0) {
 			loadfrom = 3;
 			if (devPart != NULL)
 				addr = load_addr = (unsigned int)simple_strtoul(devPart, NULL, 16);
 		}
 		if ((loadfrom == 1 || loadfrom == 2) && devPart == NULL) /* if using USB/MMC, and not selected interface num */
 			devPart = "0";					 /* default interface number is 0 */
-		/* fall to 1*/
+		/* fall to 2*/
+	case 2:
+		copy_filename (BootFile, argv[1], sizeof(BootFile));
 	case 1:    /* no parameter all default */
-		if(argc < 4)
+		if (argc < 2)
 			copy_filename (BootFile, partitionInfo->defaultImage, sizeof(BootFile));
 		break;
 	default:
@@ -451,12 +476,19 @@
 	if (mvVerifyRequest() == MV_FALSE)
 		return 0;
 
-	if (isNand == MV_FALSE && !flash) {
-		flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+	if (isNand == MV_FALSE) {
+#if defined(MV_INCLUDE_SPI)
 		if (!flash) {
-			printf("Failed to probe SPI Flash\n");
-			return 0;
+			flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+			if (!flash) {
+				printf("Failed to probe SPI Flash\n");
+				return 0;
+			}
 		}
+#else
+		printf("SPI Flash is not supported\n");
+		return 0;
+#endif
 	}
 
 	/* Fetch requested file, filesize is needed for single image only */
@@ -551,10 +583,11 @@
 	}
 
 	/* Erase entire NAND flash - avoid invalid file system preparations */
-	printf("\nGoing to erase the entire NAND flash. ");
-	if (mvVerifyRequest() == MV_TRUE)
-		run_command("nand erase.chip", 0);
-
+	if (isNand == MV_TRUE) {
+		printf("\nGoing to erase the entire NAND flash. ");
+		if (mvVerifyRequest() == MV_TRUE)
+			run_command("nand erase.chip", 0);
+	}
 	printf("\nBurning %s on flash at 0x%08x, length=%dK\n",
 		(single_file) ? "single image" : "kernel",
 		partitionInfo->KERNEL_START, kernel_unc_len/_1K);
@@ -593,14 +626,15 @@
 U_BOOT_CMD(
 	mtdburn,      6,     1,      do_mtdburn,
 	"Burn a Linux image and Filesystem` on the NAND/SPI flash.\n",
-	"[interface [<dev[:part]>  [File system [filename]]]] [flash destination] [single file size on RAM]\n"
+	"[filename [interface [<dev[:part]> [File system]]]] [flash destination] [single file size on RAM]\n"
 	"\tinterface  : ram <load address>, tftp, or mmc/usb <interface_num> (default is tftp)\n"
 	"\tFile system: FAT or EXT2 (default is FAT).\n"
 	"\tNAND default file-name is ubifs_arm_nand.image.\n"
 	"\tSPI default file-name is jffs2_arm.image.\n"
 	"\tFlash Destination: nand or spi (default is nand). \n"
-	"\te.g. MMC: 'mtdburn mmc 0 FAT ubifs_arm_nand.image nand'\n"
-	"\te.g. RAM: 'mtdburn ram 5000000 nand'\n"
+	"\te.g. TFTP: 'mtdburn ubifs_arm_nand.image'\n"
+	"\te.g. MMC: 'mtdburn ubifs_arm_nand.image mmc 0 FAT nand'\n"
+	"\te.g. RAM: 'mtdburn ubifs_arm_nand.image ram 5000000 nand'\n"
 
 );
 
@@ -791,6 +825,7 @@
 		return silt;
 }
 
+#ifdef MV_MSYS
 static int do_qsgmii_sel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 
@@ -821,6 +856,7 @@
 		  " Select SFP or QSGMII modes on bc2.\n",
 		  " apply 16 bit array to select SFP or QSGMII modes"
 		  );
+#endif
 
 void hwServicesLateInit(void)
 {
diff --git a/board/mv_ebu/common/USP/switchingServices/switchingServices.h b/board/mv_ebu/common/USP/switchingServices/switchingServices.h
index ab40daa..38e21d4 100755
--- a/board/mv_ebu/common/USP/switchingServices/switchingServices.h
+++ b/board/mv_ebu/common/USP/switchingServices/switchingServices.h
@@ -143,10 +143,10 @@
 		SILT_NP5,
 		SILT_BC2,
 		SILT_OTHER,
-		SLIC_NOT_DETECT = 0x5a5a
+		SILT_NOT_DETECT = 0x5a5a
 } SILICON_TYPE;
 
 SILICON_TYPE get_attached_silicon_type(void);
 int do_sar_bc2(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
-
+void hwServicesLateInit(void);
 #endif
diff --git a/board/mv_ebu/common/common/mvCommon.h b/board/mv_ebu/common/common/mvCommon.h
index 405fd3c..bc5ef84 100644
--- a/board/mv_ebu/common/common/mvCommon.h
+++ b/board/mv_ebu/common/common/mvCommon.h
@@ -231,6 +231,7 @@
 #define _2G         0x80000000
 
 /* Tclock and Sys clock define */
+#define _50MHz      50000000
 #define _100MHz     100000000
 #define _125MHz     125000000
 #define _133MHz     133333334
diff --git a/board/mv_ebu/common/common/mvDeviceId.h b/board/mv_ebu/common/common/mvDeviceId.h
index 4c84e15..ddcb503 100644
--- a/board/mv_ebu/common/common/mvDeviceId.h
+++ b/board/mv_ebu/common/common/mvDeviceId.h
@@ -400,6 +400,10 @@
 #define MV_6811_DEV_ID		0x6811
 #define MV_6820_DEV_ID		0x6820
 #define MV_6828_DEV_ID		0x6828
+#define MV_6W22_DEV_ID		0x6823 /* 6W22=A383 */
+#define MV_6W23_DEV_ID		0x6824 /* 6W23=A384 */
+#define MV_6W22_DEV_NAME	"6W22"
+#define MV_6W23_DEV_NAME	"6W23"
 
 /* A38x revisions */
 #define MV_88F68XX_Z1_ID		0x0
@@ -438,11 +442,46 @@
 	MV_BOBCAT2_B0_NAME,\
 }
 
+/* BobK  Family */
+#define MV_BOBK_DEV_ID		0xBC00
+
+/* BobK deivces matrix */
+#define MV_BOBK_CETUS_98DX4235_DEV_ID		0xBE00
+#define MV_BOBK_CAELUM_98DX4203_DEV_ID		0xBC00
+#define MV_BOBK_LEWIS_98DX8212_DEV_ID		0xBE10
+
+/* BobK  Revisions */
+#define MV_BOBK_A0_ID		0x0
+#define MV_BOBK_A0_NAME		"A0"
+
+#define MV_BOBK_ID_ARRAY { \
+	 MV_BOBK_A0_NAME,\
+}
+
  /* Lion2  Family */
 #define MV_LION2_DEV_ID		0x8000
 
 /* AlleyCat3  Family */
 #define MV_ALLEYCAT3_DEV_ID		0xF400
+#define MV_ALLEYCAT3_MAX_DEV_ID		0xF4FF
+
+/* AlleyCat3/Pomcat3 deivces matrix */
+#define MV_ALLEYCAT3_98DX3336_DEV_ID	0xF400
+#define MV_ALLEYCAT3_98DX3335_DEV_ID	0xF401
+#define MV_ALLEYCAT3_98DX3334_DEV_ID	0xF402
+#define MV_ALLEYCAT3_98DX3333_DEV_ID	0xF403
+#define MV_ALLEYCAT3_98DX1233_DEV_ID	0xF408
+#define MV_ALLEYCAT3_98DX1235_DEV_ID	0xF409
+#define MV_ALLEYCAT3_98DX3236_DEV_ID	0xF410
+#define MV_ALLEYCAT3_98DX3235_DEV_ID	0xF411
+#define MV_ALLEYCAT3_98DX3234_DEV_ID	0xF412
+#define MV_ALLEYCAT3_98DX3233_DEV_ID	0xF413
+#define MV_ALLEYCAT3_98DXH333_DEV_ID	0xF414
+#define MV_ALLEYCAT3_98DX1333_DEV_ID	0xF418
+#define MV_ALLEYCAT3_98DX1335_DEV_ID	0xF419
+#define MV_ALLEYCAT3_98DX1336_DEV_ID	0xF41A
+
+#define MV_MAX_DEV_ID			0xFFFF
 
 /* AlleyCat3  Revisions */
 #define MV_ALLEYCAT3_A0_ID		0x3
diff --git a/board/mv_ebu/common/mv_hal/cesa/mvCesa.c b/board/mv_ebu/common/mv_hal/cesa/mvCesa.c
index b39a8c5..9973e0c 100644
--- a/board/mv_ebu/common/mv_hal/cesa/mvCesa.c
+++ b/board/mv_ebu/common/mv_hal/cesa/mvCesa.c
@@ -1026,26 +1026,14 @@
 				return MV_OUT_OF_CPU_MEM;
 			}
 			status = mvCesaFragReqProcess(chan, pReq, frag);
-			if (status == MV_OK) {
-#if defined(MV_CESA_CHAIN_MODE) || defined(MV_CESA_INT_COALESCING_SUPPORT) || \
-							     defined(CONFIG_OF)
-#ifdef CONFIG_OF
-				if ((mv_cesa_feature == INT_COALESCING) ||
-						(mv_cesa_feature == CHAIN)) {
-#endif /* CONFIG_OF */
-					if (frag) {
-						pReq->dma[frag - 1].pDmaLast->phyNextDescPtr =
-						    MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf,
-							pReq->dma[frag].pDmaFirst));
-						mvOsCacheFlush(cesaOsHandle, pReq->dma[frag - 1].pDmaLast,
-						    sizeof(MV_DMA_DESC));
-					}
-#ifdef CONFIG_OF
-				}
-#endif /* CONFIG_OF */
-#endif /* MV_CESA_CHAIN_MODE || MV_CESA_INT_COALESCING_SUPPORT || CONFIG_OF*/
-				frag++;
+			if (status == MV_OK && frag) {
+				pReq->dma[frag - 1].pDmaLast->phyNextDescPtr =
+					MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf,
+						    pReq->dma[frag].pDmaFirst));
+				mvOsCacheFlush(cesaOsHandle, pReq->dma[frag - 1].pDmaLast,
+					       sizeof(MV_DMA_DESC));
 			}
+			frag++;
 		}
 		pReq->frags.numFrag = frag;
 
@@ -1282,12 +1270,8 @@
 		MV_U8 *pNewDigest;
 		int frag;
 
-#if defined(MV_CESA_CHAIN_MODE) || defined(MV_CESA_INT_COALESCING_SUPPORT) || \
-							     defined(CONFIG_OF)
 		pReq->frags.nextFrag = 1;
 		while (pReq->frags.nextFrag <= pReq->frags.numFrag) {
-#endif
-
 			frag = (pReq->frags.nextFrag - 1);
 
 			/* Restore DMA descriptor list */
@@ -1329,19 +1313,8 @@
 				}
 				readyStatus = MV_OK;
 			}
-#if defined(MV_CESA_CHAIN_MODE) || defined(MV_CESA_INT_COALESCING_SUPPORT) || \
-							     defined(CONFIG_OF)
-#ifdef CONFIG_OF
-		if ((mv_cesa_feature == INT_COALESCING) ||
-					(mv_cesa_feature == CHAIN))
 			pReq->frags.nextFrag++;
-		else
-			break;
-#else /* CONFIG_OF */
-			pReq->frags.nextFrag++;
-#endif /* CONFIG_OF */
 		}
-#endif /* MV_CESA_CHAIN_MODE || MV_CESA_INT_COALESCING_SUPPORT || CONFIG_OF */
 	} else {
 		mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
 
diff --git a/board/mv_ebu/common/mv_hal/neta/gbe/mvNeta.h b/board/mv_ebu/common/mv_hal/neta/gbe/mvNeta.h
index 12519e5..4492814 100644
--- a/board/mv_ebu/common/mv_hal/neta/gbe/mvNeta.h
+++ b/board/mv_ebu/common/mv_hal/neta/gbe/mvNeta.h
@@ -346,6 +346,9 @@
 #define MV_NETA_QUEUE_PREV_DESC(pQueueCtrl, descIdx)  \
     (((descIdx) > 0) ? ((descIdx) - 1) : (pQueueCtrl)->lastDesc)
 
+#define MV_NETA_RX_LAST_DESC_PTR(pQueueCtrl)  \
+	(((NETA_RX_DESC *)pQueueCtrl.pFirst) + pQueueCtrl.lastDesc)
+
 typedef struct {
 	MV_NETA_QUEUE_CTRL queueCtrl;
 
@@ -622,6 +625,19 @@
 	return pRxDesc;
 }
 
+/* Get the next desc pointer following current desc */
+static INLINE NETA_RX_DESC *mvNetaRxqNextDescPtr(MV_NETA_RXQ_CTRL *pRxq, NETA_RX_DESC *pRxDesc)
+{
+	NETA_RX_DESC *pNextDesc;
+
+	if (pRxDesc == MV_NETA_RX_LAST_DESC_PTR(pRxq->queueCtrl))
+		pNextDesc = (NETA_RX_DESC *)pRxq->queueCtrl.pFirst;
+	else
+		pNextDesc = ++pRxDesc;
+
+	return pNextDesc;
+}
+
 static INLINE NETA_RX_DESC *mvNetaRxqDescGet(MV_NETA_RXQ_CTRL *pRxq)
 {
 	NETA_RX_DESC	*pRxDesc;
diff --git a/board/mv_ebu/common/mv_hal/neta/gbe/mvNetaDebug.c b/board/mv_ebu/common/mv_hal/neta/gbe/mvNetaDebug.c
index 368e9a5..37f5e69 100644
--- a/board/mv_ebu/common/mv_hal/neta/gbe/mvNetaDebug.c
+++ b/board/mv_ebu/common/mv_hal/neta/gbe/mvNetaDebug.c
@@ -490,7 +490,7 @@
 				   i, pRxDesc, pRxDesc->status,
 				   pRxDesc->dataSize, (MV_U32) pRxDesc->bufPhysAddr, (MV_U32) pRxDesc->bufCookie);
 
-			mvOsCacheLineInv(NULL, pRxDesc);
+			mvOsCacheLineInv(pPortCtrl->osHandle, pRxDesc);
 		}
 	}
 }
@@ -541,7 +541,7 @@
 				   i, pTxDesc, pTxDesc->command, pTxDesc->dataSize,
 				   (MV_U32) pTxDesc->bufPhysAddr, pTxDesc->hw_cmd);
 
-			mvOsCacheLineInv(NULL, pTxDesc);
+			mvOsCacheLineInv(pPortCtrl->osHandle, pTxDesc);
 		}
 	}
 }
diff --git a/board/mv_ebu/common/mv_hal/neta/pnc/mvPnc.c b/board/mv_ebu/common/mv_hal/neta/pnc/mvPnc.c
index 648d6e3..493ec50 100644
--- a/board/mv_ebu/common/mv_hal/neta/pnc/mvPnc.c
+++ b/board/mv_ebu/common/mv_hal/neta/pnc/mvPnc.c
@@ -138,10 +138,7 @@
 		|| ctrl_model == MV88F6560_DEV_ID) {
 		/* Armada KW2 ID */
 		memcpy(&gbe_pnc_map, &gbe_pnc_map_kw2, sizeof(gbe_pnc_map_kw2));
-	} else if (ctrl_model == MV88F6810_DEV_ID
-		|| ctrl_model == MV88F6811_DEV_ID
-		|| ctrl_model == MV88F6820_DEV_ID
-		|| ctrl_model == MV88F6828_DEV_ID) {
+	} else if ((ctrl_model & ~0xFF) == MV_88F68XX) {
 		/* Armada A38x ID */
 		memcpy(&gbe_pnc_map, &gbe_pnc_map_38x, sizeof(gbe_pnc_map_38x));
 	} else {
diff --git a/board/mv_ebu/common/mv_hal/qd-dsdt-3.3/src/msapi/gtSysConfig.c b/board/mv_ebu/common/mv_hal/qd-dsdt-3.3/src/msapi/gtSysConfig.c
index bff020f..10d3c7b 100644
--- a/board/mv_ebu/common/mv_hal/qd-dsdt-3.3/src/msapi/gtSysConfig.c
+++ b/board/mv_ebu/common/mv_hal/qd-dsdt-3.3/src/msapi/gtSysConfig.c
@@ -762,6 +762,8 @@
                 break;
         case GT_88E6172:
                 dev->numOfPorts = 7;
+		dev->maxPorts = 7;
+		dev->maxPhyNum = 5;
                 dev->validPortVec = (1 << dev->numOfPorts) - 1;
                 dev->validPhyVec = 0x1F;
                 dev->validSerdesVec = 0x8000;
diff --git a/board/mv_ebu/common/mv_hal/sata/sata3/mvSata3AddrDec.c b/board/mv_ebu/common/mv_hal/sata/sata3/mvSata3AddrDec.c
index b30d2be0..7b76744 100644
--- a/board/mv_ebu/common/mv_hal/sata/sata3/mvSata3AddrDec.c
+++ b/board/mv_ebu/common/mv_hal/sata/sata3/mvSata3AddrDec.c
@@ -92,7 +92,7 @@
 #define MV_SATA3_WIN_BASE_OFFSET              4
 #define MV_SATA3_WIN_BASE_MASK                (0xFFFFFFF<<MV_SATA3_WIN_BASE_OFFSET)
 
-#define MV_SATA3_WIN_SIZE_ALIGN		    _64K
+#define MV_SATA3_WIN_SIZE_ALIGN		    _1M
 
 MV_TARGET sata3AddrDecPrioTab[] = {
 #if defined(MV_INCLUDE_SDRAM_CS0)
@@ -213,19 +213,14 @@
 		return MV_ERROR;
 	}
 
-	baseReg = pAddrDecWin->addrWin.baseLow & MV_SATA3_WIN_BASE_MASK;
+	baseReg = (pAddrDecWin->addrWin.baseLow / MV_SATA3_WIN_SIZE_ALIGN);
+	baseReg = (baseReg << MV_SATA3_WIN_BASE_OFFSET) & MV_SATA3_WIN_BASE_MASK;
 	sizeReg = (pAddrDecWin->addrWin.size / MV_SATA3_WIN_SIZE_ALIGN) - 1;
 	sizeReg = sizeReg << MV_SATA3_WIN_SIZE_OFFSET;
 
 	/* set attributes */
 	ctrlReg = (pAddrDecWin->attrib << MV_SATA3_WIN_ATTR_OFFSET);
 
-#ifdef MV88F68XX
-	/* Temp WA for A38x: set attribute with IOCC bit enabled:
-	 * When using Dual CS, disk detection fails without using IOCC bit enabled */
-	ctrlReg |= BIT12;
-#endif
-
 	/* set target ID */
 	ctrlReg &= ~MV_SATA3_WIN_TARGET_MASK;
 	ctrlReg |= (pAddrDecWin->targetId << MV_SATA3_WIN_TARGET_OFFSET);
@@ -276,7 +271,8 @@
 	/* Extract base address and size    */
 	sizeRegVal = (sizeReg & MV_SATA3_WIN_SIZE_MASK) >> MV_SATA3_WIN_SIZE_OFFSET;
 	pAddrDecWin->addrWin.size = (sizeRegVal + 1) * MV_SATA3_WIN_SIZE_ALIGN;
-	pAddrDecWin->addrWin.baseLow = baseReg & MV_SATA3_WIN_BASE_MASK;
+	pAddrDecWin->addrWin.baseLow = (baseReg & MV_SATA3_WIN_BASE_MASK) >> MV_SATA3_WIN_SIZE_OFFSET;
+	pAddrDecWin->addrWin.baseLow *= MV_SATA3_WIN_SIZE_ALIGN;
 	pAddrDecWin->addrWin.baseHigh = 0;
 
 	/* attrib and targetId              */
diff --git a/board/mv_ebu/common/mv_hal/spi/mvSpi.c b/board/mv_ebu/common/mv_hal/spi/mvSpi.c
index 62e2364..8a0fbf3 100644
--- a/board/mv_ebu/common/mv_hal/spi/mvSpi.c
+++ b/board/mv_ebu/common/mv_hal/spi/mvSpi.c
@@ -475,6 +475,25 @@
 		(spiHalData.ctrlModel == MV_6321_DEV_ID))
 			MV_SPI_REG_BIT_SET(MV_SPI_IF_CONFIG_REG(spiId), BIT14);
 
+	/* set relaxed SPI_TMISO_SAMPLE settings, in 1 of the following:
+	 * 1. Armada 38x/39x: ERRATA FE-9144572: Tclock @ 250MHz & SPI clock @ 50MHz & clkPhase=clockPolLow=1
+	 * 2. Alley-Cat3: always, to avoid timing violation with SCLK = 40/50Mhz*/
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) || defined(CONFIG_ALLEYCAT3)
+		MV_U32 timingReg;
+#ifndef CONFIG_ALLEYCAT3
+		if (spiHalData.tclk == MV_BOARD_TCLK_250MHZ && serialBaudRate == _50MHz
+			&& spiTypes[SPI_TYPE_FLASH].clockPolLow == 1
+			&& spiTypes[SPI_TYPE_FLASH].clkPhase == 1)
+#endif /* ifndef CONFIG_ALLEYCAT3 */
+			{
+		/* set TMISO_SAMPLE to 0x2: MISO sample occurs 2 core_clk after SPI_CLK edge */
+			timingReg = MV_REG_READ(MV_SPI_TMNG_PARAMS_REG(spiId));
+			timingReg &= ~MV_SPI_TMISO_SAMPLE_MASK;
+			timingReg |= (0x2) << MV_SPI_TMISO_SAMPLE_OFFSET;
+			MV_REG_WRITE(MV_SPI_TMNG_PARAMS_REG(spiId), timingReg);
+			}
+#endif /* CONFIG_ARMADA_38X || CONFIG_ARMADA_39X || CONFIG_ALLEYCAT3 */
+
     /* Verify that the CS is deasserted */
     mvSpiCsDeassert(spiId);
 
diff --git a/board/mv_ebu/common/mv_hal/twsi/mvTwsi.c b/board/mv_ebu/common/mv_hal/twsi/mvTwsi.c
index 6be6906..62920d5 100755
--- a/board/mv_ebu/common/mv_hal/twsi/mvTwsi.c
+++ b/board/mv_ebu/common/mv_hal/twsi/mvTwsi.c
@@ -354,7 +354,7 @@
 	MV_U32 actualFreq = 0, actualN = 0, actualM = 0, val;
 
 	if (frequancy > 100000)
-		mvOsPrintf("Warning TWSI frequancy is too high, please use up to 100Khz.\n");
+		mvOsPrintf("Warning TWSI frequency is too high, please use up to 100Khz.\n");
 
 	DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n", Tclk, frequancy));
 	/* Calucalte N and M for the TWSI clock baud rate */
diff --git a/board/mv_ebu/common/mv_hal_if/mvSysUsb.c b/board/mv_ebu/common/mv_hal_if/mvSysUsb.c
index 1352b0c..5dd9253 100755
--- a/board/mv_ebu/common/mv_hal_if/mvSysUsb.c
+++ b/board/mv_ebu/common/mv_hal_if/mvSysUsb.c
@@ -68,7 +68,8 @@
 #include "usb/mvUsb.h"
 #include "ctrlEnv/mvCtrlEnvAddrDec.h"
 #include "usb/mvUsbRegs.h"
-
+#include "boardEnv/mvBoardEnvLib.h"
+#include "ctrlEnv/mvCtrlEnvSpec.h"
 /*******************************************************************************
 * mvSysUsbHalInit - Initialize the USB subsystem
 *
@@ -88,7 +89,6 @@
 	MV_STATUS status = MV_OK;
 	MV_U32 dev;
 	MV_UNIT_WIN_INFO addrWinMap[MAX_TARGETS + 1];
-
 	halData.ctrlModel = mvCtrlModelGet();
 	halData.ctrlRev = mvCtrlRevGet();
 	halData.ctrlFamily = mvCtrlDevFamilyIdGet(halData.ctrlModel);
@@ -104,7 +104,9 @@
 		 MAC ID0 (usbActive =0) is connected to Physical MAC ID1 */
 		int id, mac_id[2] = {1, 0};
 
-		for (id = 0; id < mvCtrlUsbMaxGet(); id++) {
+		 for (id = 0; id < maxUsbPorts ; id++) {
+			if (mvBoardIsUsbPortConnected(USB_UNIT_ID,id) == MV_FALSE)
+				continue;
 			if (maxUsbPorts == 1 && (halData.ctrlFamily == MV_88F67X0 ||
 					(halData.ctrlRev == MV_88F66XX_A0_ID && halData.ctrlFamily == MV_88F66X0)))
 				dev = mac_id[id];
@@ -136,7 +138,9 @@
 #endif
 #ifdef CONFIG_USB_XHCI
 		MV_U32 reg;
-		for (dev = 0; dev < mvCtrlUsb3HostMaxGet() ; dev++) {
+		for (dev = 0; dev < mvCtrlUsb3HostMaxGet(); dev++) {
+			if (mvBoardIsUsbPortConnected(USB3_UNIT_ID,dev) == MV_FALSE)
+				continue;
 			status = mvUsbUtmiPhyInit(dev, &halData);
 			if (halData.ctrlFamily == MV_88F66X0 || halData.ctrlFamily == MV_88F67X0) {
 				/* ALP/A375: Set UTMI PHY Selector:
diff --git a/board/mv_ebu/msys/cmd_sar.c b/board/mv_ebu/msys/cmd_sar.c
index df62592..30d6572 100644
--- a/board/mv_ebu/msys/cmd_sar.c
+++ b/board/mv_ebu/msys/cmd_sar.c
@@ -24,8 +24,13 @@
 #include "ctrlEnv/mvCtrlEnvLib.h"
 #include "boardEnv/mvBoardEnvLib.h"
 
-extern MV_BOARD_INFO *marvellAC3BoardInfoTbl[];
-
+#if defined CONFIG_ALLEYCAT3
+	extern MV_BOARD_INFO *marvellAC3BoardInfoTbl[];
+	MV_BOARD_INFO **mvMsysBoardInfoTbl = marvellAC3BoardInfoTbl;
+#else
+	extern MV_BOARD_INFO *marvellBC2BoardInfoTbl[];
+	MV_BOARD_INFO **mvMsysBoardInfoTbl = marvellBC2BoardInfoTbl;
+#endif
 /*
    bc2 sample and reset register
 #     4f       #     4e       #     4d       #      4c      #
@@ -53,9 +58,9 @@
 	CMD_AVS_MODE,
 	CMD_SLAVE_ADDR,
 	CMD_DEVICE_NUM,
-	CMD_BOARD_ID,
 	CMD_DDR_ECC_EN,
 #endif
+	CMD_BOARD_ID,
 	CMD_PCIE_MODE,
 	CMD_BOOTSRC,
 	CMD_DEVICE_ID,
@@ -74,7 +79,8 @@
 						   0,	/* OOB0 connection */
 						   0,	/* OOB1 connection */
 						   0,	/* Force AMC RC GEN1 PCIe */
-						   1,	/* PCIe mode */
+						   0,	/* Board ID */
+						   0,	/* PCIe mode */
 						   3,	/* Boot source */
 						   0 };	/* Device ID */
 	MV_U32 coreClockTbl[] = MV_CORE_CLK_TBL_BC2;
@@ -87,8 +93,8 @@
 						   1,	/* AVS Mode */
 						   1,	/* I2C/SMI Slave address */
 						   0,	/* Device number */
-						   0,	/* Board ID */
 						   0,	/* DDR ECC enable */
+						   0,	/* Board ID */
 						   0,	/* PCIe mode */
 						   3,	/* Boot source */
 						   0 };	/* Device ID */
@@ -156,11 +162,11 @@
 		return CMD_SLAVE_ADDR;
 	if (strcmp(cmd, "devicenum") == 0)
 		return CMD_DEVICE_NUM;
-	if (strcmp(cmd, "boardid") == 0)
-		return CMD_BOARD_ID;
 	if (strcmp(cmd, "ddreccenable") == 0)
 		return CMD_DDR_ECC_EN;
 #endif
+	if (strcmp(cmd, "boardid") == 0)
+		return CMD_BOARD_ID;
 	if (strcmp(cmd, "pcimode") == 0)
 		return CMD_PCIE_MODE;
 	if (strcmp(cmd, "bootsrc") == 0)
@@ -301,18 +307,18 @@
 		printf("\t|  1  |          1          |\n");
 		printf("\t-----------------------------\n");
 		break;
-	case CMD_BOARD_ID:
-		printf("Determines the board ID (0-7)\n");
-		printf("\t| ID  |      Board               |\n");
-		printf("\t----------------------------------\n");
-		for (i = 0; i < AC3_MARVELL_BOARD_NUM ; i++)
-			printf("\t|  %d  |  %-22s  |\n", i, marvellAC3BoardInfoTbl[i]->boardName );
-		printf("\t----------------------------------\n");
-		break;
 	case CMD_DEVICE_NUM:
 		printf("Determines the device number (0-3)\n");
 		break;
 #endif
+	case CMD_BOARD_ID:
+		printf("Determines the board ID (0-7)\n");
+		printf("\t| ID  |      Board               |\n");
+		printf("\t----------------------------------\n");
+		for (i = 0; i < MV_MARVELL_BOARD_NUM ; i++)
+			printf("\t|  %d  |  %-22s  |\n", i, mvMsysBoardInfoTbl[i]->boardName );
+		printf("\t----------------------------------\n");
+		break;
 	case CMD_PCIE_MODE:
 		printf("Determines the PCI-E mode:\n");
 		printf("\t| ID  |       Mode     |\n");
@@ -459,14 +465,14 @@
 			printf("devicenum Error: failed reading devicenum\n");
 		break;
 
+#endif
 	case CMD_BOARD_ID:
 		if (mvBoardSarBoardIdGet(&tmp) == MV_OK)
-			printf("boardid\t\t\t= %d ==>  %s\n", tmp, marvellAC3BoardInfoTbl[tmp]->boardName);
+			printf("boardid\t\t\t= %d ==>  %s\n", tmp, mvMsysBoardInfoTbl[tmp]->boardName);
 		else
 			printf("boardid Error: failed reading boardid\n");
 		break;
 
-#endif
 	case CMD_PCIE_MODE:
 		if (mvBoardPcieModeGet(&tmp) == MV_OK)
 			printf("pcimode \t\t= %d ==>  %s\n", tmp, ((tmp == 0) ? "Endpoint" : "Root Complex"));
@@ -565,13 +571,13 @@
 	case CMD_SLAVE_ADDR:
 		rc = mvBoardSmiI2c2AddrSet(tmp);
 		break;
-	case CMD_BOARD_ID:
-		rc = mvBoardSarBoardIdSet(tmp);
-		break;
 	case CMD_DEVICE_NUM:
 		rc = mvBoardDeviceNumSet(tmp);
 		break;
 #endif
+	case CMD_BOARD_ID:
+		rc = mvBoardSarBoardIdSet(tmp);
+		break;
 	case CMD_PCIE_MODE:
 		rc = mvBoardPcieModeSet(tmp);
 		break;
@@ -583,15 +589,13 @@
 		break;
 	case CMD_DEFAULT:
 		for (i = 0 ; i < CMD_DUMP; i++) {
-#if defined CONFIG_ALLEYCAT3
 			if (i == CMD_BOARD_ID) {
 				MV_U32 brdId = mvBoardIdGet();
-				if ((brdId < AC3_MARVELL_BOARD_ID_BASE) || (brdId >= AC3_MARVELL_MAX_BOARD_ID))
+				if ((brdId < MARVELL_BOARD_ID_BASE) || (brdId >= MV_MAX_MARVELL_BOARD_ID))
 					mvOsPrintf("Bad Board ID returned - %d! Assigning default value!\n", brdId);
 				else
-					defaultValue[i] = brdId - AC3_MARVELL_BOARD_ID_BASE; /* Update default value with real board ID*/
+					defaultValue[i] = brdId - MARVELL_BOARD_ID_BASE; /* Update default value with real board ID*/
 			}
-#endif /* CONFIG_ALLEYCAT3 */
 			if (1 == do_sar_write(i, defaultValue[i]))
 				rc = MV_FALSE;
 			do_sar_read(i);
@@ -623,12 +627,10 @@
 	cmd = argv[1];
 	mode = sar_cmd_get(argv[2]);
 
-#if defined CONFIG_ALLEYCAT3
-	if(mvBoardIdGet() != DB_AC3_ID && mode != CMD_BOARD_ID) {
+	if(mvBoardIdGet() != MV_DEFAULT_BOARD_ID && mode != CMD_BOARD_ID) {
 		mvOsPrintf("Error: Sample at reset supports modifying only 'boardid' field for current board\n\n");
 		goto usage;
 	}
-#endif
 
 	if (strcmp(cmd, "list") == 0)
 		return do_sar_list(mode);
@@ -674,13 +676,13 @@
 #endif
 "bootsrc                    - Boot source\n"
 "deviceid                   - Device ID\n"
-#ifdef CONFIG_ALLEYCAT3
-"\t----Legacy fileds----\n"
-"pllclock                   - PLL2 VCO clock frequency. Valid for rev.A0 only\n"
 "\n\tSW SatR fields\n"
 "\t--------------\n"
-"ddreccenable               - DDR ECC modes\n"
 "boardid                    - Board ID\n"
+#ifdef CONFIG_ALLEYCAT3
+"ddreccenable               - DDR ECC modes\n"
+"\t----Legacy fileds----\n"
+"pllclock                   - PLL2 VCO clock frequency. Valid for rev.A0 only\n"
 #endif
 );
 #endif /*defined(CONFIG_CMD_SAR)*/
diff --git a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.c b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.c
index 332749c..5301aff 100755
--- a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.c
+++ b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.c
@@ -94,12 +94,39 @@
 extern MV_BOARD_INFO *customerBC2BoardInfoTbl[];
 extern MV_BOARD_INFO *marvellAC3BoardInfoTbl[];
 extern MV_BOARD_INFO *customerAC3BoardInfoTbl[];
+extern MV_BOARD_INFO *marvellBOBKBoardInfoTbl[];
+extern MV_BOARD_INFO *customerBOBKBoardInfoTbl[];
 /* Global variables should be removed from BSS (set to a non-zero value)
    for avoiding memory corruption during early access upon code relocation */
 static MV_BOARD_INFO *board = (MV_BOARD_INFO *)-1;
 
 /* Locals */
 static MV_DEV_CS_INFO *mvBoardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
+/*******************************************************************************
+* mvBoardisUsbPortConnected
+*
+* DESCRIPTION:
+*	return True if requested USB type and port num exists on current board
+*
+* INPUT:
+*	usbTypeID       - requested USB type : USB3_UNIT_ID / USB_UNIT_ID
+*	usbPortNumbder  - requested USB port number (according to xHCI MAC port num)
+*
+* OUTPUT: None
+*
+* RETURN: MV_TRUE if requested port/type exist on board
+
+*******************************************************************************/
+MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber)
+{
+	/*BobCat2 SoC have no usb port
+	AlleyCat3 & BobK SoC board has only one usb2 port */
+#ifdef MV_USB
+	if (usbTypeID == USB_UNIT_ID && usbPortNumber == 0)
+		return MV_TRUE;
+#endif
+	return MV_FALSE;
+}
 
 /*******************************************************************************
 * mvBoardIdIndexGet
@@ -176,6 +203,12 @@
 	mvGppTypeSet(0, 0xFFFFFFFF, board->gppOutEnValLow);
 	mvGppTypeSet(1, 0xFFFFFFFF, board->gppOutEnValMid);
 
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID) {
+		MV_REG_WRITE(GPP_DATA_OUT_REG(2), board->gppOutValHigh);
+		mvGppPolaritySet(2, 0xFFFFFFFF, board->gppPolarityValHigh);
+		mvGppTypeSet(2, 0xFFFFFFFF, board->gppOutEnValHigh);
+	}
+
 #ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
 	mvBoardOobPortCfgSet();
 #endif
@@ -275,10 +308,7 @@
 *******************************************************************************/
 MV_BOOL mvBoardIsEthConnected(MV_U32 ethNum)
 {
-	if (ethNum <= mvCtrlEthMaxPortGet())
-		return MV_TRUE;
-
-	return MV_FALSE;
+	return mvBoardIsGbEPortConnected(ethNum);
 }
 
 /*******************************************************************************
@@ -324,6 +354,10 @@
 *******************************************************************************/
 MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
 {
+	MV_U32 boardId = mvBoardIdGet();
+
+	if (boardId == DB_78X60_AMC_ID && ethPortNum == 0)
+		return MV_FALSE;
 	return MV_TRUE;
 }
 /*******************************************************************************
@@ -350,6 +384,30 @@
 }
 
 /*******************************************************************************
+* mvBoardPortTypeGet
+*
+* DESCRIPTION:
+*       This routine returns port type
+*
+* INPUT:
+*       ethPortNum - Ethernet port number.
+*
+* OUTPUT:
+*       None
+*
+* RETURN:
+*       Mode of the port
+*
+*******************************************************************************/
+MV_U32 mvBoardPortTypeGet(MV_U32 ethPortNum)
+{
+	if (mvBoardIsPortInSgmii(ethPortNum))
+		return MV_PORT_TYPE_SGMII;
+	else
+		return MV_PORT_TYPE_RGMII;
+}
+
+/*******************************************************************************
 * mvBoardIsPortInMii
 *
 * DESCRIPTION:
@@ -418,6 +476,8 @@
 
 MV_BOOL mvBoardIsPortInRgmii(MV_U32 ethPortNum)
 {
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return !mvBoardIsPortInGmii(ethPortNum);
 	return !mvBoardIsPortInGmii(ethPortNum) && !mvBoardIsPortInSgmii(ethPortNum);
 }
 /*******************************************************************************
@@ -489,7 +549,63 @@
 *******************************************************************************/
 MV_U32 mvBoardTclkGet(MV_VOID)
 {
-	return 200000000; /* constant Tclock @ 200MHz (not Sampled@Reset)  */
+	/* U-Boot flow for MSYS can not read FamilyIdGet to derrive Tclk,
+	since FamilyIdGet needs Board ID, via TWSI trasaction, which depends on Tclk reading.
+	MSYS platforms use static Tclk=200MHz (not Sampled@Reset)*/
+#ifdef MV_MSYS /* MV_MSYS is defined only in U-boot for MSYS platforms: AC3/BC2/BobK */
+	return MV_BOARD_TCLK_200MHZ;
+#else
+
+	/* for Linux flow, FamilyIdGet can use BoardIDGet, since Board id is not readen from TWSI,
+	but passed from U-Boot tags instead */
+
+	if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID)
+		/* constant Tclock @ 200MHz (not Sampled@Reset) */
+		return MV_BOARD_TCLK_200MHZ;
+
+	if ((MV_REG_READ(MPP_SAMPLE_AT_RESET(0)) & MSAR_TCLK_MASK) != 0)
+		return MV_BOARD_TCLK_200MHZ;
+	else
+		return MV_BOARD_TCLK_250MHZ;
+#endif
+}
+
+/*******************************************************************************
+* mvBoardSysClkGetAxp - Get the board SysClk of AXP (CPU bus clock , i.e. DDR clock)
+*
+* DESCRIPTION:
+*       This routine extract the CPU bus clock.
+*
+* INPUT:
+*       countNum - Counter number.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       32bit clock cycles in Hertz.
+*
+*******************************************************************************/
+MV_U32 mvBoardSysClkGetAxp(MV_VOID)
+{
+	MV_U32 idx;
+	MV_U32 cpuFreqMhz, ddrFreqMhz;
+	MV_CPU_ARM_CLK_RATIO clockRatioTbl[] = MV_DDR_L2_CLK_RATIO_TBL_AXP;
+
+	idx = MSAR_DDR_L2_CLK_RATIO_IDX(MV_REG_READ(MPP_SAMPLE_AT_RESET(0)),
+					MV_REG_READ(MPP_SAMPLE_AT_RESET(1)));
+
+	if (clockRatioTbl[idx].vco2cpu != 0) {			/* valid ratio ? */
+		cpuFreqMhz = mvCpuPclkGet() / 1000000;		/* obtain CPU freq */
+		cpuFreqMhz *= clockRatioTbl[idx].vco2cpu;	/* compute VCO freq */
+		ddrFreqMhz = cpuFreqMhz / clockRatioTbl[idx].vco2ddr;
+		/* round up to integer MHz */
+		if (((cpuFreqMhz % clockRatioTbl[idx].vco2ddr) * 10 / clockRatioTbl[idx].vco2ddr) >= 5)
+			ddrFreqMhz++;
+
+		return ddrFreqMhz * 1000000;
+	} else
+		return 0xFFFFFFFF;
 }
 
 /*******************************************************************************
@@ -513,8 +629,12 @@
 	MV_U32		idx;
 	MV_U32		freq_tbl_bc2[] = MV_CORE_CLK_TBL_BC2;
 	MV_U32		freq_tbl_ac3[] = MV_CORE_CLK_TBL_AC3;
+	MV_U32		freq_tbl_bobk_cetus[] = MV_CORE_CLK_TBL_BOBK_CETUS;
+	MV_U32		freq_tbl_bobk_caelum[] = MV_CORE_CLK_TBL_BOBK_CAELUM;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
+	if (family == MV_78460_DEV_ID)
+		return mvBoardSysClkGetAxp();
 	idx = MSAR_CORE_CLK(MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(0)), MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1)));
 
 	if (idx >= 7)
@@ -524,7 +644,20 @@
 		return freq_tbl_bc2[idx] * 1000000;
 	else if (family == MV_ALLEYCAT3_DEV_ID)
 		return freq_tbl_ac3[idx] * 1000000;
-	else
+	else if (family == MV_BOBK_DEV_ID) {
+		/* BobK family has two different flavors(Cetus/Caelum) with different settings */
+		switch (mvCtrlModelGet() & ~BOBK_FLAVOR_MASK) {
+		case MV_BOBK_CETUS_98DX4235_DEV_ID:
+			return freq_tbl_bobk_cetus[idx] * 1000000;
+			break;
+		case MV_BOBK_CAELUM_98DX4203_DEV_ID:
+			return freq_tbl_bobk_caelum[idx] * 1000000;
+			break;
+		default:
+			mvOsPrintf("ERROR: Unknown Device ID %d, CORE freq get failed\n", mvCtrlModelGet());
+			return 0xFFFFFFFF;
+		}
+	} else
 		return 0xFFFFFFFF;
 }
 
@@ -747,7 +880,8 @@
 *******************************************************************************/
 MV_BOOL mvBoardIsGbEPortConnected(MV_U32 ethPortNum)
 {
-	if ((ethPortNum + 1) <= board->numBoardMacInfo)
+	if ((ethPortNum < board->numBoardMacInfo) &&
+		(board->pBoardMacInfo[ethPortNum].boardMacEnabled == MV_TRUE))
 		return MV_TRUE;
 	else
 		return MV_FALSE;
@@ -772,30 +906,37 @@
 MV_VOID mvBoardCpldConfigurationGet(char *str)
 {
 	MV_U8 cpldTwsiDev, cpldConfig;
+	MV_U8 cpldBoardRevReg = CPLD_BOARD_REV_REG;
+	MV_U16 boardModel;
 
-	/* CPLD board configuration print for AC3 */
-	if (mvCtrlDevFamilyIdGet(0) != MV_ALLEYCAT3_DEV_ID)
-		return;
+	/* Prevent the caller function from printing the same string twice if this function fails */
+	*str = 0;
+
 	cpldTwsiDev = mvBoardTwsiAddrGet(BOARD_DEV_TWSI_PLD, 0);
 
 	/* verify that CPLD device is available on current board, else return*/
 	if (cpldTwsiDev == 0xff || mvTwsiProbe(cpldTwsiDev, mvBoardTclkGet()) != MV_TRUE)
 		return;
 
+	boardModel = mvBoardModelGet();
+	if (boardModel == RD_MTL_BC2_PCB_ID)
+		cpldBoardRevReg = CPLD_RD_MTL_BC2_BOARD_REV_REG;
+
 	/* Read Board Revision */
-	if (MV_ERROR == mvBoardTwsiRead(BOARD_DEV_TWSI_PLD, 0, CPLD_BOARD_REV_REG, &cpldConfig)) {
+	if (MV_ERROR == mvBoardTwsiRead(BOARD_DEV_TWSI_PLD, 0, cpldBoardRevReg, &cpldConfig)) {
 		mvOsPrintf("\n%s: Error: failed reading board Revision from CPLD.\n", __func__);
 		return;
 	}
 	sprintf(str, ", Rev %d" , cpldConfig & CPLD_BOARD_REV_MASK);
 
 	/* Read CPLD Revision */
-	if (MV_ERROR == mvBoardTwsiRead(BOARD_DEV_TWSI_PLD, 0, CPLD_REV_REG, &cpldConfig)) {
-		mvOsPrintf("\n%s: Error: failed reading CPLD Revision from CPLD.\n", __func__);
-		return;
+	if (boardModel != RD_MTL_BC2_PCB_ID) {
+		if (MV_ERROR == mvBoardTwsiRead(BOARD_DEV_TWSI_PLD, 0, CPLD_REV_REG, &cpldConfig)) {
+			mvOsPrintf("\n%s: Error: failed reading CPLD Revision from CPLD.\n", __func__);
+			return;
+		}
+		sprintf(str, "%s, CPLD Rev %d", str, cpldConfig & CPLD_BOARD_REV_MASK);
 	}
-
-	sprintf(str, "%s, CPLD Rev %d", str, cpldConfig & CPLD_BOARD_REV_MASK);
 }
 
 /* Board devices API managments */
@@ -1008,6 +1149,92 @@
 }
 
 /*******************************************************************************
+* mvBoardGetDevBusNum
+*
+* DESCRIPTION:
+*	Return the device's bus number.
+*
+* INPUT:
+*	devIndex - The device sequential number on the board
+*	devType - The device type ( Flash,RTC , etc .. )
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	If the device is found on the board the then the functions returns the
+*	dev bus number else the function returns 0xFFFFFFFF
+*
+*******************************************************************************/
+MV_U32 mvBoardGetDevBusNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
+{
+	MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass);
+
+	if (devEntry)
+		return devEntry->busNum;
+
+	return 0xFFFFFFFF;
+}
+
+/*******************************************************************************
+* mvBoardGetDevState
+*
+* DESCRIPTION:
+*	Return the device's activity state.
+*
+* INPUT:
+*	devIndex - The device sequential number on the board
+*	devType - The device type ( Flash,RTC , etc .. )
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	If the device is found on the board the then the functions returns the
+*	dev activity state else the function returns 0xFFFFFFFF
+*
+*******************************************************************************/
+MV_BOOL mvBoardGetDevState(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
+{
+	MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass);
+
+	if (devEntry)
+		return devEntry->active;
+
+	return 0xFFFFFFFF;
+}
+
+/*******************************************************************************
+* mvBoardSetDevState
+*
+* DESCRIPTION:
+*	Sets the device's activity state.
+*
+* INPUT:
+*	devIndex - The device sequential number on the board
+*   devType - The device type ( Flash,RTC , etc .. )
+*   newState - requested deevice state
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	If the device is found on the board the then the functions returns
+*	MV_OK else MV_ERROR
+*
+*******************************************************************************/
+MV_STATUS mvBoardSetDevState(MV_32 devNum, MV_BOARD_DEV_CLASS devClass, MV_BOOL newState)
+{
+	MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass);
+
+	if (devEntry) {
+		devEntry->active = newState;
+		return MV_OK;
+	} else
+		return MV_ERROR;
+}
+
+/*******************************************************************************
 * mvBoardTwsiAddrTypeGet -
 *
 * DESCRIPTION:
@@ -1127,14 +1354,22 @@
 static MV_U32 gBoardId = -1;
 MV_VOID mvBoardSet(MV_U32 boardId)
 {
+	/* Marvell BobK Boards */
+	if (boardId >= BOBK_MARVELL_BOARD_ID_BASE && boardId < BOBK_MARVELL_MAX_BOARD_ID) { /* Marvell Board */
+		board = marvellBOBKBoardInfoTbl[mvBoardIdIndexGet(boardId)];
+		gBoardId = boardId;
 	/* Marvell Bobcat2 Boards */
-	if (boardId >= BC2_MARVELL_BOARD_ID_BASE && boardId < BC2_MARVELL_MAX_BOARD_ID) { /* Marvell Board */
+	} else if (boardId >= BC2_MARVELL_BOARD_ID_BASE && boardId < BC2_MARVELL_MAX_BOARD_ID) { /* Marvell Board */
 		board = marvellBC2BoardInfoTbl[mvBoardIdIndexGet(boardId)];
 		gBoardId = boardId;
 	/* Marvell AlleyCat3 Boards */
 	} else if (boardId >= AC3_MARVELL_BOARD_ID_BASE && boardId < AC3_MARVELL_MAX_BOARD_ID) { /* Marvell Board */
 		board = marvellAC3BoardInfoTbl[mvBoardIdIndexGet(boardId)];
 		gBoardId = boardId;
+	/* Customer BobK Boards */
+	} else if (boardId >= BOBK_CUSTOMER_BOARD_ID_BASE && boardId < BOBK_CUSTOMER_MAX_BOARD_ID) {/*Customer Board*/
+		board = customerBOBKBoardInfoTbl[mvBoardIdIndexGet(boardId)];
+		gBoardId = boardId;
 	/* Customer Bobcat2 Boards */
 	} else if (boardId >= BC2_CUSTOMER_BOARD_ID_BASE && boardId < BC2_CUSTOMER_MAX_BOARD_ID) { /* Customer Board */
 		board = customerBC2BoardInfoTbl[mvBoardIdIndexGet(boardId)];
@@ -1143,14 +1378,24 @@
 	} else if (boardId >= AC3_CUSTOMER_BOARD_ID_BASE && boardId < AC3_CUSTOMER_MAX_BOARD_ID) { /* Customer Board */
 		board = customerAC3BoardInfoTbl[mvBoardIdIndexGet(boardId)];
 		gBoardId = boardId;
+	/* Marvell AXP-AMC Board */
+	} else if (boardId == DB_78X60_AMC_ID) {
+		/* This case should enter only for LSP 3.2/3.4 flow:
+		 * This board ID is passed from AXP-AMC U-Boot 2011.12, and shared here only
+		 * for Linux usage (AXP family is shared with MSYS family in LSP) */
+		board = marvellAXPboardInfoTbl[0];
+		gBoardId = boardId;
 	} else {
 		mvOsPrintf("%s: Error: wrong board Id (%d)\n", __func__, boardId);
 #ifdef CONFIG_ALLEYCAT3
 		gBoardId = AC3_CUSTOMER_BOARD_ID0;
 		board = customerAC3BoardInfoTbl[gBoardId];
-#else
+#elif defined CONFIG_BOBCAT2
 		gBoardId = BC2_CUSTOMER_BOARD_ID0;
 		board = customerBC2BoardInfoTbl[gBoardId];
+#else
+		gBoardId = BOBK_CETUS_CUSTOMER_BOARD_ID0;
+		board = customerBOBKBoardInfoTbl[gBoardId];
 #endif
 		mvOsPrintf("Applying default Customer board ID (%d: %s)\n", gBoardId, board->boardName);
 	}
@@ -1179,55 +1424,59 @@
 	if (gBoardId != -1)
 		return gBoardId;
 
-#if defined CONFIG_ALLEYCAT3
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 
-	#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+	#if defined CONFIG_ALLEYCAT3
 		#ifdef CONFIG_CUSTOMER_BOARD_0
 			gBoardId = AC3_CUSTOMER_BOARD_ID0;
 		#elif CONFIG_CUSTOMER_BOARD_1
 			gBoardId = AC3_CUSTOMER_BOARD_ID1;
 		#endif
-	#else	/* !CONFIG_CUSTOMER_BOARD_SUPPORT */
-
-	/* For Marvell Boards: Temporarily set generic board struct pointer to
-	   use S@R TWSI address, and read board ID */
-	board = marvellAC3BoardInfoTbl[mvBoardIdIndexGet(DB_AC3_ID)];
-	gBoardId = DB_AC3_ID; /* Terporary for usage by mvCtrlDevFamilyIdGet */
-	MV_U8 readValue;
-
-	if (mvBoardSarBoardIdGet(&readValue) != MV_OK || readValue >= AC3_MARVELL_BOARD_NUM) {
-		mvOsPrintf("%s: Error obtaining Board ID from EEPROM (%d)\n", __func__, readValue);
-		mvOsPrintf("%s: Setting default board: DB-DXAC3-MM\n", __func__);
-		readValue = DB_AC3_ID - AC3_MARVELL_BOARD_ID_BASE;
-	}
-
-	gBoardId = AC3_MARVELL_BOARD_ID_BASE + readValue;
-	#endif	/* CONFIG_CUSTOMER_BOARD_SUPPORT */
-
-#else /* CONFIG_BOBCAT2 */
-
-	#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+	#elif defined CONFIG_BOBCAT2
 		#ifdef CONFIG_CUSTOMER_BOARD_0
 			gBoardId = BC2_CUSTOMER_BOARD_ID0;
 		#elif CONFIG_CUSTOMER_BOARD_1
 			gBoardId = BC2_CUSTOMER_BOARD_ID1;
 		#endif
-	#else	/* !CONFIG_CUSTOMER_BOARD_SUPPORT */
-
-		#if defined(DB_BOBCAT2)
-			gBoardId = DB_DX_BC2_ID;
-		#elif defined(RD_BOBCAT2)
-			gBoardId = RD_DX_BC2_ID;
-		#elif defined(RD_MTL_BOBCAT2)
-			gBoardId = RD_MTL_BC2;
-		#else
-			mvOsPrintf("%s: Board ID must be defined!\n", __func__);
-			while (1)
-				continue;
+	#else /* BOBK */
+		#ifdef CONFIG_CUSTOMER_BOARD_0
+			gBoardId = BOBK_CETUS_CUSTOMER_BOARD_ID0;
+		#elif CONFIG_CUSTOMER_BOARD_1
+			gBoardId = BOBK_CAELUM_CUSTOMER_BOARD_ID1;
 		#endif
-	#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
+	#endif
 
-#endif
+#else	/* !CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+	MV_U8 readValue;
+	MV_BOARD_INFO **mvBoardInfoTbl =
+	#if defined CONFIG_ALLEYCAT3
+		marvellAC3BoardInfoTbl;
+	#elif defined CONFIG_BOBCAT2
+		marvellBC2BoardInfoTbl;
+	#else /* BOBK */
+		marvellBOBKBoardInfoTbl;
+	#endif
+
+	/* Temporarily set generic board struct pointer, to set/get EEPROM i2c address, and read board ID */
+	board = mvBoardInfoTbl[mvBoardIdIndexGet(MV_DEFAULT_BOARD_ID)];
+	gBoardId = MV_DEFAULT_BOARD_ID; /* Terporary for usage by mvCtrlDevFamilyIdGet */
+
+	if (mvBoardSarBoardIdGet(&readValue) != MV_OK) {
+		mvOsPrintf("%s: Error obtaining Board ID from EEPROM (%d)\n", __func__, readValue);
+		mvOsPrintf("%s: Setting default board to: %s\n", __func__, board->boardName);
+		return MV_DEFAULT_BOARD_ID;
+	}
+	readValue = readValue & (BOARD_ID_INDEX_MASK - 1);
+
+	if (readValue >= MV_MARVELL_BOARD_NUM) {
+		mvOsPrintf("%s: Error: read wrong board ID (%d)\n", __func__, readValue);
+		mvOsPrintf("%s: Setting default board to: %s\n", __func__, board->boardName);
+		return MV_DEFAULT_BOARD_ID;
+	}
+	gBoardId = MARVELL_BOARD_ID_BASE + readValue;
+
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
 
 	return gBoardId;
 }
@@ -1430,9 +1679,9 @@
 	MV_U8		sar0;
 	MV_STATUS	rc1;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U32		fieldOffs = (family == MV_BOBCAT2_DEV_ID) ? 0 : 2;
+	MV_U32		fieldOffs = (family == MV_ALLEYCAT3_DEV_ID) ? 2 : 0;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
@@ -1452,9 +1701,10 @@
 	MV_U8		sar0;
 	MV_STATUS	rc1;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U32		fieldOffs = (family == MV_BOBCAT2_DEV_ID) ? 0 : 2;
+	MV_U32		fieldOffs = (family == MV_ALLEYCAT3_DEV_ID) ? 2 : 0;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)
+		&& (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
@@ -1475,6 +1725,75 @@
 	DB(mvOsPrintf("Board: Write core FreqOpt S@R succeeded\n"));
 	return MV_OK;
 }
+
+/*******************************************************************************
+* Read the new SW SatR field "bypass_coreclock" from EEPROM(0x50), reg#6 bits[2:0]
+*******************************************************************************/
+MV_STATUS mvBoardBypassCoreFreqGet(MV_U8 *value)
+{
+	MV_U8		sar0;
+	MV_STATUS	rc1;
+	MV_U16		family = mvCtrlDevFamilyIdGet(0);
+
+	if (family != MV_BOBK_DEV_ID) {
+		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
+		return MV_ERROR;
+	}
+
+	/* The Core Frequency in Bypass mode is taken from the first address-value pair of the EEPROM
+	   initialization sequence, In order to support normal TWSI init sequence flow, the first pair
+	   of DWORDS on EEPROM should contain an address (bytes 0-3) of some scratch pad register
+	   (for instance an UART SCR) and a value (bytes 4-7), which will be partially interpreted
+	   as Core Freq in bypass mode (bits[2:0] of byte 6)
+	*/
+
+	rc1 = mvBoardTwsiRead(BOARD_DEV_TWSI_INIT_EPROM, 0, 6, &sar0);
+	if (MV_ERROR == rc1)
+		return MV_ERROR;
+
+	*value = (sar0 & 0x7);
+
+	return MV_OK;
+}
+
+/*******************************************************************************
+* Write the new SW SatR field "bypass_coreclock" to EEPROM(0x50), reg#6 bits[2:0]
+*******************************************************************************/
+MV_STATUS mvBoardBypassCoreFreqSet(MV_U8 freqVal)
+{
+	MV_U8		sar0;
+	MV_STATUS	rc1;
+	MV_U16		family = mvCtrlDevFamilyIdGet(0);
+
+	if (family != MV_BOBK_DEV_ID) {
+		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
+		return MV_ERROR;
+	}
+
+	/* The Core Frequency in Bypass mode is taken from the first address-value pair of the EEPROM
+	   initialization sequence, In order to support normal TWSI init sequence flow, the first pair
+	   of DWORDS on EEPROM should contain an address (bytes 0-3) of some scratch pad register
+	   (for instance an UART SCR) and a value (bytes 4-7), which will be partially interpreted
+	   as Core Freq in bypass mode (bits[2:0] of byte 6)
+	*/
+
+	rc1 = mvBoardTwsiRead(BOARD_DEV_TWSI_INIT_EPROM, 0, 6, &sar0);
+	if (MV_ERROR == rc1)
+		return MV_ERROR;
+
+	sar0 &= ~0x7;
+	sar0 |= (freqVal & 0x7);
+
+	if (MV_OK != mvBoardTwsiWrite(BOARD_DEV_TWSI_INIT_EPROM, 0, 6, sar0)) {
+		DB(mvOsPrintf("Board: Write Bypass core Freq S@R fail\n"));
+		return MV_ERROR;
+	}
+
+
+	DB(mvOsPrintf("Board: Write Bypss core FreqOpt S@R succeeded\n"));
+	return MV_OK;
+}
+
 /*******************************************************************************/
 MV_STATUS mvBoardCpuFreqGet(MV_U8 *value)
 {
@@ -1489,7 +1808,17 @@
 			(MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar2)))
 			return MV_ERROR;
 
-		*value = ((((sar2 & 0x1)) << 3) | ((sar & 0x18) >> 3));
+		*value = ((((sar2 & 0x1)) << 2) | ((sar & 0x18) >> 3));
+
+	} else if (family == MV_BOBK_DEV_ID) {
+		MV_U8		sar2;
+
+		/* BOBK */
+		if ((MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar)) ||
+			(MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar2)))
+			return MV_ERROR;
+
+		*value = ((((sar2 & 0x1)) << 2) | ((sar & 0x18) >> 3));
 
 	} else if (family == MV_ALLEYCAT3_DEV_ID) {
 
@@ -1534,6 +1863,27 @@
 			return MV_ERROR;
 		}
 
+	} else if (family == MV_BOBK_DEV_ID) {
+		MV_U8		sar2;
+		/* BOBK */
+		if ((MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar)) ||
+			(MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar2)))
+			return MV_ERROR;
+
+		sar  &= ~0x18;
+		sar2 &= ~0x1;
+		sar  |= ((freqVal & 0x03) << 3);
+		sar2 |= ((freqVal & 0x04) >> 2);
+
+		if (MV_OK != mvBoardTwsiSatRSet(0, 0, sar)) {
+			DB(mvOsPrintf("Board: Write CpuFreq(1) S@R fail\n"));
+			return MV_ERROR;
+		}
+		if (MV_OK != mvBoardTwsiSatRSet(3, 0, sar2)) {
+			DB(mvOsPrintf("Board: Write CpuFreq(2) S@R fail\n"));
+			return MV_ERROR;
+		}
+
 	} else if (family == MV_ALLEYCAT3_DEV_ID) {
 
 		/* AC3 */
@@ -1563,16 +1913,27 @@
 	MV_U8		sar2;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
-	if (family != MV_BOBCAT2_DEV_ID) {
+	if (family != MV_BOBCAT2_DEV_ID && family != MV_BOBK_DEV_ID) {
 		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
 		return MV_ERROR; /* AC3 */
 	}
 
-	/* BC2 */
-	if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar2))
-		return MV_ERROR;
+	if (family == MV_BOBCAT2_DEV_ID) {
 
-	*value = ((sar2 & 0x0E) >> 1);
+		/* BC2 */
+		if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar2))
+			return MV_ERROR;
+
+		*value = ((sar2 & 0x0E) >> 1);
+
+	} else if (family == MV_BOBK_DEV_ID) {
+
+		/* BOBK */
+		if (MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar2))
+			return MV_ERROR;
+
+		*value = (sar2 & 0x07);
+	}
 
 	return MV_OK;
 }
@@ -1583,22 +1944,41 @@
 	MV_U8		sar2;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
-	if (family != MV_BOBCAT2_DEV_ID) {
+	if (family != MV_BOBCAT2_DEV_ID && family != MV_BOBK_DEV_ID) {
 		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
 		return MV_ERROR; /* AC3 */
 	}
 
-	/* BC2 */
-	if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar2))
-		return MV_ERROR;
+	if (family == MV_BOBCAT2_DEV_ID) {
 
-	sar2 &= ~0xE;
-	sar2 |= ((freqVal & 0x07) << 1);
+		/* BC2 */
+		if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar2))
+			return MV_ERROR;
 
-	if (MV_OK != mvBoardTwsiSatRSet(2, 0, sar2)) {
-		DB(mvOsPrintf("Board: Write TM-Freq S@R fail\n"));
-		return MV_ERROR;
+		sar2 &= ~0xE;
+		sar2 |= ((freqVal & 0x07) << 1);
+
+		if (MV_OK != mvBoardTwsiSatRSet(2, 0, sar2)) {
+			DB(mvOsPrintf("Board: Write TM-Freq S@R fail\n"));
+			return MV_ERROR;
+		}
+	} else if (family == MV_BOBK_DEV_ID) {
+
+		/* BOBK */
+		if (MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar2))
+			return MV_ERROR;
+
+		sar2 &= ~0x7;
+		sar2 |= (freqVal & 0x07);
+
+		if (MV_OK != mvBoardTwsiSatRSet(0, 0, sar2)) {
+			DB(mvOsPrintf("Board: Write TM-Freq S@R fail\n"));
+			return MV_ERROR;
+		}
 	}
+
+	/* BC2 or BOBK*/
+
 	DB(mvOsPrintf("Board: Write TM-Freq S@R succeeded\n"));
 
 	return MV_OK;
@@ -1610,16 +1990,27 @@
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
-	if (family != MV_BOBCAT2_DEV_ID) {
+	if (family != MV_BOBCAT2_DEV_ID && family != MV_BOBK_DEV_ID) {
 		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
 		return MV_ERROR; /* AC3 */
 	}
 
-	/* BC2 */
-	if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
-		return MV_ERROR;
+	if (family == MV_BOBCAT2_DEV_ID) {
 
-	*value = (sar & 0x8) >> 3;
+		/* BC2 */
+		if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
+			return MV_ERROR;
+
+		*value = (sar & 0x8) >> 3;
+
+	} else if (family == MV_BOBK_DEV_ID) {
+
+		/* BOBK */
+		if (MV_ERROR == mvBoardTwsiSatRGet(1, 0, &sar))
+			return MV_ERROR;
+
+		*value = (sar & 0x8) >> 3;
+	}
 
 	return MV_OK;
 }
@@ -1630,21 +2021,38 @@
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
-	if (family != MV_BOBCAT2_DEV_ID) {
+	if (family != MV_BOBCAT2_DEV_ID && family != MV_BOBK_DEV_ID) {
 		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
 		return MV_ERROR; /* AC3 */
 	}
 
-	/* BC2 */
-	if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
-		return MV_ERROR;
+	if (family == MV_BOBCAT2_DEV_ID) {
 
-	sar &= ~(0x8);
-	sar |= ((cpu & 0x1) << 3);
+		/* BC2 */
+		if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
+			return MV_ERROR;
 
-	if (MV_OK != mvBoardTwsiSatRSet(3, 0, sar)) {
-		DB(mvOsPrintf("Board: Write JTAG CPU S@R fail\n"));
-		return MV_ERROR;
+		sar &= ~(0x8);
+		sar |= ((cpu & 0x1) << 3);
+
+		if (MV_OK != mvBoardTwsiSatRSet(3, 0, sar)) {
+			DB(mvOsPrintf("Board: Write JTAG CPU S@R fail\n"));
+			return MV_ERROR;
+		}
+
+	} else if (family == MV_BOBK_DEV_ID) {
+
+		/* BOBK */
+		if (MV_ERROR == mvBoardTwsiSatRGet(1, 0, &sar))
+			return MV_ERROR;
+
+		sar &= ~(0x8);
+		sar |= ((cpu & 0x1) << 3);
+
+		if (MV_OK != mvBoardTwsiSatRSet(1, 0, sar)) {
+			DB(mvOsPrintf("Board: Write JTAG CPU S@R fail\n"));
+			return MV_ERROR;
+		}
 	}
 
 	DB(mvOsPrintf("Board: Write JTAG CPU  S@R succeeded\n"));
@@ -1658,8 +2066,8 @@
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
 	if (family != MV_BOBCAT2_DEV_ID) {
-		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
-		return MV_ERROR; /* AC3 */
+		DB(mvOsPrintf("%s: Only Support BC2 controller family\n", __func__));
+		return MV_ERROR; /* AC3/BOBK */
 	}
 
 	/* BC2 */
@@ -1678,8 +2086,8 @@
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
 	if (family != MV_BOBCAT2_DEV_ID) {
-		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
-		return MV_ERROR; /* AC3 */
+		DB(mvOsPrintf("%s: Only Support BC2 controller family\n", __func__));
+		return MV_ERROR; /* AC3/BOBK */
 	}
 
 	/* BC2 */
@@ -1705,8 +2113,8 @@
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
 	if (family != MV_BOBCAT2_DEV_ID) {
-		DB(mvOsPrintf("%s: AC3 controller family is not supported\n", __func__));
-		return MV_ERROR; /* AC3 */
+		DB(mvOsPrintf("%s: Only Support BC2 controller family\n", __func__));
+		return MV_ERROR; /* AC3/BOBK */
 	}
 
 	if (port > 1) {
@@ -1809,9 +2217,9 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U8		twsiDevice = (family == MV_BOBCAT2_DEV_ID) ? 3 : 2;
+	MV_U8		twsiDevice = (family == MV_ALLEYCAT3_DEV_ID) ? 2 : 3;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
@@ -1819,7 +2227,10 @@
 	if (MV_ERROR == mvBoardTwsiSatRGet(twsiDevice, 0, &sar))
 		return MV_ERROR;
 
-	*value = (sar & 0x7);
+	if (family == MV_BOBK_DEV_ID)
+		*value = ((sar & 0x0E) >> 1);
+	else
+		*value = (sar & 0x7);
 
 	return MV_OK;
 }
@@ -1829,9 +2240,9 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U8		twsiDevice = (family == MV_BOBCAT2_DEV_ID) ? 3 : 2;
+	MV_U8		twsiDevice = (family == MV_ALLEYCAT3_DEV_ID) ? 2 : 3;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
@@ -1839,8 +2250,13 @@
 	if (MV_ERROR == mvBoardTwsiSatRGet(twsiDevice, 0, &sar))
 		return MV_ERROR;
 
-	sar &= ~(0x7);
-	sar |= (val & 0x7);
+	if (family == MV_BOBK_DEV_ID) {
+		sar &= ~(0xE);
+		sar |= ((val & 0x7) << 1);
+	} else {
+		sar &= ~(0x7);
+		sar |= (val & 0x7);
+	}
 
 	if (MV_OK != mvBoardTwsiSatRSet(twsiDevice, 0, sar)) {
 		DB(mvOsPrintf("Board: Write BootDev S@R fail\n"));
@@ -1855,16 +2271,17 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
+	MV_U8		twsiDevice = (family == MV_BOBK_DEV_ID) ? 2 : 0;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
 
-	if (MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar))
-		return MV_ERROR;
+	if (MV_ERROR == mvBoardTwsiSatRGet(twsiDevice, 0, &sar))
+			return MV_ERROR;
 
-	*value = (sar & 0x1F);
+		*value = (sar & 0x1F);
 
 	return MV_OK;
 }
@@ -1874,19 +2291,20 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
+	MV_U8		twsiDevice = (family == MV_BOBK_DEV_ID) ? 2 : 0;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
 
-	if (MV_ERROR == mvBoardTwsiSatRGet(0, 0, &sar))
+	if (MV_ERROR == mvBoardTwsiSatRGet(twsiDevice, 0, &sar))
 		return MV_ERROR;
 
 	sar &= ~(0x1F);
 	sar |= (val & 0x1F);
 
-	if (MV_OK != mvBoardTwsiSatRSet(0, 0, sar)) {
+	if (MV_OK != mvBoardTwsiSatRSet(twsiDevice, 0, sar)) {
 		DB(mvOsPrintf("Board: Write device-id S@R fail\n"));
 		return MV_ERROR;
 	}
@@ -1945,17 +2363,24 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U8		bitOffset = (family == MV_BOBCAT2_DEV_ID) ? 4 : 3;
+	MV_U8		bitOffset = (family == MV_ALLEYCAT3_DEV_ID) ? 3 : 4;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
 
-	if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar))
-		return MV_ERROR;
+	if ((family == MV_ALLEYCAT3_DEV_ID) || (family == MV_BOBCAT2_DEV_ID)) {
+		if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar))
+			return MV_ERROR;
 
-	*val = (sar & (0x1 << bitOffset)) >> bitOffset;
+		*val = (sar & (0x1 << bitOffset)) >> bitOffset;
+	} else if (family == MV_BOBK_DEV_ID) {
+		if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
+			return MV_ERROR;
+
+		*val = (sar & (0x1 << bitOffset)) >> bitOffset;
+	}
 
 	return MV_OK;
 }
@@ -1965,22 +2390,35 @@
 {
 	MV_U8		sar;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U8		bitOffset = (family == MV_BOBCAT2_DEV_ID) ? 4 : 3;
+	MV_U8		bitOffset = (family == MV_ALLEYCAT3_DEV_ID) ? 3 : 4;
 
-	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID)) {
+	if ((family != MV_ALLEYCAT3_DEV_ID) && (family != MV_BOBCAT2_DEV_ID) && (family != MV_BOBK_DEV_ID)) {
 		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
 		return MV_ERROR;
 	}
 
-	if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar))
-		return MV_ERROR;
+	if ((family == MV_ALLEYCAT3_DEV_ID) || (family == MV_BOBCAT2_DEV_ID)) {
+		if (MV_ERROR == mvBoardTwsiSatRGet(2, 0, &sar))
+			return MV_ERROR;
 
-	sar &= ~(0x1 << bitOffset);
-	sar |= (val & 0x1) << bitOffset;
+		sar &= ~(0x1 << bitOffset);
+		sar |= (val & 0x1) << bitOffset;
 
-	if (MV_OK != mvBoardTwsiSatRSet(2, 0, sar)) {
-		DB(mvOsPrintf("Board: Write pcimode S@R fail\n"));
-		return MV_ERROR;
+		if (MV_OK != mvBoardTwsiSatRSet(2, 0, sar)) {
+			DB(mvOsPrintf("Board: Write pcimode S@R fail\n"));
+			return MV_ERROR;
+		}
+	} else if (family == MV_BOBK_DEV_ID) {
+		if (MV_ERROR == mvBoardTwsiSatRGet(3, 0, &sar))
+			return MV_ERROR;
+
+		sar &= ~(0x1 << bitOffset);
+		sar |= (val & 0x1) << bitOffset;
+
+		if (MV_OK != mvBoardTwsiSatRSet(3, 0, sar)) {
+			DB(mvOsPrintf("Board: Write pcimode S@R fail\n"));
+			return MV_ERROR;
+		}
 	}
 
 	DB(mvOsPrintf("Board: Write pcimode S@R succeeded\n"));
@@ -2182,12 +2620,6 @@
 MV_STATUS mvBoardSarBoardIdGet(MV_U8 *value)
 {
 	MV_U8		boardId;
-	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-
-	if (family != MV_ALLEYCAT3_DEV_ID) {
-		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
-		return MV_ERROR;
-	}
 
 	/* The Board Id is taken from the first address-value pair of the EEPROM initialization sequence
 	   In order to support normal TWSI init sequence flow, the first pair of DWORDS on EEPROM
@@ -2208,14 +2640,21 @@
 	MV_U8		boardId;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
 
-	if (family != MV_ALLEYCAT3_DEV_ID) {
-		DB(mvOsPrintf("%s: Controller family (0x%04x) is not supported\n", __func__, family));
-		return MV_ERROR;
-	}
-
-	if (val >= AC3_MARVELL_BOARD_NUM) {
-		mvOsPrintf("%s: Error: Unsupported board ID (%d)\n", __func__, val);
-		return MV_ERROR;
+	if (family == MV_ALLEYCAT3_DEV_ID) {
+		if (val >= AC3_MARVELL_BOARD_NUM) {
+			mvOsPrintf("%s: Error: Unsupported board ID (%d)\n", __func__, val);
+			return MV_ERROR;
+		}
+	} else if (family == MV_BOBK_DEV_ID) {
+		if (val >= BOBK_MARVELL_BOARD_NUM) {
+			mvOsPrintf("%s: Error: Unsupported board ID (%d)\n", __func__, val);
+			return MV_ERROR;
+		}
+	} else if (family == MV_BOBCAT2_DEV_ID) {
+		if (val >= BC2_MARVELL_BOARD_NUM) {
+			mvOsPrintf("%s: Error: Unsupported board ID (%d)\n", __func__, val);
+			return MV_ERROR;
+		}
 	}
 
 	/* The Board Id is taken from the first address-value pair of the EEPROM initalization sequnce
@@ -2367,6 +2806,29 @@
 }
 
 /*******************************************************************************
+* mvBoardConfigAutoDetectEnabled
+*
+* DESCRIPTION:
+*	Indicate if the board supports auto configuration and detection of
+*	modules. This is usually enabled for DB boards only.
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*       MV_TRUE if auto-config/detection is enabled.
+*	MV_FALSE otherwise.
+*
+*******************************************************************************/
+MV_BOOL mvBoardConfigAutoDetectEnabled()
+{
+	return board->configAutoDetect;
+}
+
+/*******************************************************************************
 * mvBoardDebugLeg - Set the board debug Leds
 *
 * DESCRIPTION: turn on/off status leds.
@@ -2460,6 +2922,53 @@
 	return MV_NFC_ECC_DISABLE;
 #endif
 }
+/*******************************************************************************
+* mvBoardCompatibleNameGet
+*
+* DESCRIPTION: return string containing 'compatible' property value
+*		needed for Device Tree auto-update parsing sequence
+*
+* INPUT:  None
+* OUTPUT: None.
+*
+* RETURN: length of returned string (including special delimiters)
+*
+*******************************************************************************/
+MV_U8 mvBoardCompatibleNameGet(char *pNameBuff)
+{
+	MV_U8 len = 0;
+	MV_U32 boardId;
+	/* i.e: compatible = "marvell,msys", "marvell,msys-bc2", "marvell,msys-bc2-db", "marvell,armada-370-xp"; */
+	len = sprintf(pNameBuff, "marvell,msys") + 1;
+	/*
+	 * append next strings after the NULL character that the previous
+	 * sprintf wrote.  This is how a device tree stores multiple
+	 * strings in a property.
+	 */
+	boardId = mvBoardIdGet();
+	if (boardId >= BC2_MARVELL_BOARD_ID_BASE && boardId < BC2_MARVELL_MAX_BOARD_ID) {
+		len += sprintf(pNameBuff + len, "marvell,msys-bc2") + 1;
+		len += sprintf(pNameBuff + len, "marvell,msys-bc2-db") + 1;
+	} else if (boardId >= AC3_MARVELL_BOARD_ID_BASE && boardId < AC3_MARVELL_MAX_BOARD_ID) {
+		len += sprintf(pNameBuff + len, "marvell,msys-ac3") + 1;
+		len += sprintf(pNameBuff + len, "marvell,msys-ac3-db") + 1;
+	} else if (boardId >= BOBK_MARVELL_BOARD_ID_BASE && boardId < BOBK_MARVELL_MAX_BOARD_ID) {
+		len += sprintf(pNameBuff + len, "marvell,msys-bobk") + 1;
+		if (boardId == BOBK_CETUS_DB_ID) {
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-cetus") + 1;
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-cetus-db") + 1;
+		} else if (boardId == BOBK_CAELUM_DB_ID) {
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-caelum") + 1;
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-caelum-db") + 1;
+		} else if (boardId == BOBK_LEWIS_RD_ID) {
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-lewis") + 1;
+			len += sprintf(pNameBuff + len, "marvell,msys-bobk-lewis-rd") + 1;
+		}
+	}
+	len += sprintf(pNameBuff + len, "marvell,armada-370-xp") + 1;
+
+	return len;
+}
 
 MV_NAND_IF_MODE mvBoardNandIfGet()
 {
@@ -2530,3 +3039,141 @@
 
 	return MV_OK;
 }
+/*******************************************************************************
+* mvBoardisAmc
+* DESCRIPTION: MSYS platform are not AMC compliant - return always false
+*
+* INPUT:  None
+* OUTPUT: None.
+* RETURN: MV_FALSE
+*******************************************************************************/
+MV_BOOL mvBoardisAmc(void)
+{
+	return MV_FALSE;
+}
+
+/*******************************************************************************
+* mvBoardPPSmiIndexGet
+* DESCRIPTION: Get the PP SMI index for the board
+*
+* INPUT:  None
+* OUTPUT: PP SMI index.
+* RETURN: MV_TRUE
+*******************************************************************************/
+MV_STATUS mvBoardPPSmiIndexGet(MV_U32 *index)
+{
+	*index = board->smiExternalPpIndex;
+	return MV_OK;
+}
+
+/*******************************************************************************
+* mvBoardUpdateConfigforDT
+* DESCRIPTION: Update board configuration structure for DT update
+*
+* INPUT:  None.
+* OUTPUT: None.
+* RETURN: None.
+*******************************************************************************/
+MV_VOID mvBoardUpdateConfigforDT(MV_VOID)
+{
+
+}
+
+#ifdef CONFIG_MMC
+/*******************************************************************************
+* mvBoardisSdioConnected
+* DESCRIPTION: return true if SDIO connected on board
+*
+* INPUT:  None
+* OUTPUT: None.
+* RETURN: MV_TRUE:SDIO connected on board
+*         MV_FALSE: else
+*******************************************************************************/
+MV_BOOL mvBoardisSdioConnected(void)
+{
+	return board->isSdMmcConnected;
+}
+#endif
+
+/*******************************************************************************
+* mvBoardGetModelName
+*
+* DESCRIPTION:
+*       This function returns a string describing the board model.
+*
+* OUTPUT:
+*       pNameBuff - Buffer to contain board model name string. Minimum size 128 chars.
+*
+*******************************************************************************/
+void mvBoardGetModelName(char *pNameBuff)
+{
+	mvOsSPrintf(pNameBuff, "Marvell MSYS %s %s", board->modelName, board->boardName);
+}
+
+/*******************************************************************************
+* mvBoardIsPpSmi
+* DESCRIPTION:
+*	checks whether PP_SMI is used or not
+*
+* INPUT:  None
+* OUTPUT: None.
+* RETURN: MV_TRUE PP_SMI is used
+*	  MV_FALSE otherwise
+*******************************************************************************/
+MV_BOOL mvBoardIsPpSmi(void)
+{
+	return board->isSmiExternalPp;
+}
+
+/*******************************************************************************
+* mvBoardPinCtrlNameGet
+*
+* DESCRIPTION:
+*       This function returns the compatible string of pinctrl
+*
+* OUTPUT:
+*       compatibleBuf - Buffer to contain pinctrl compatible string
+*
+*******************************************************************************/
+void mvBoardPinCtrlNameGet(char *compatibleBuf)
+{
+	mvOsSPrintf(compatibleBuf, "marvell,bc2-ac3-pinctrl");
+}
+
+#ifdef MV_CM3
+/*******************************************************************************
+* mvBoardIsCm3
+* DESCRIPTION:
+*	checks whether CM3 is used or not
+*
+* INPUT:  None
+* OUTPUT: None.
+* RETURN: MV_TRUE CM3 is used
+*	  MV_FALSE otherwise
+*******************************************************************************/
+MV_BOOL mvBoardIsCm3(void)
+{
+	return board->isCm3;
+}
+
+/*******************************************************************************
+* mvBoardCm3CompatibleNameGet
+*
+* DESCRIPTION:
+*       This function returns the compatible string of cm3
+*
+* OUTPUT:
+*       compatibleBuf - Buffer to contain cm3 compatible string
+*
+*******************************************************************************/
+void mvBoardCm3CompatibleNameGet(char *compatibleBuf)
+{
+	if (gBoardId >=  BOBK_MARVELL_BOARD_ID_BASE &&
+			gBoardId < BOBK_MARVELL_MAX_BOARD_ID)
+		mvOsSPrintf(compatibleBuf, "marvell,msys-bobk-cm3");
+	else if (gBoardId >=  BC2_MARVELL_BOARD_ID_BASE &&
+			gBoardId < BC2_MARVELL_MAX_BOARD_ID)
+		mvOsSPrintf(compatibleBuf, "marvell,msys-bc2-cm3");
+
+}
+#endif
diff --git a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.h b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.h
index 6c79636..904fea8 100755
--- a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.h
+++ b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvLib.h
@@ -83,6 +83,14 @@
 
 #define MV_BOARD_MAX_MPP		9	/* number of MPP conf registers */
 #define MV_BOARD_NAME_LEN  		0x20
+#define MV_BOARD_MODEL_NAME_LEN		0x50
+
+enum {
+	MV_PORT_TYPE_SGMII,
+	MV_PORT_TYPE_QSGMII,
+	MV_PORT_TYPE_RGMII,
+	MV_PORT_TYPE_UNKNOWN = -1,
+};
 
 typedef enum _devBoardMppTypeClass {
 	MV_BOARD_AUTO = 0,
@@ -153,6 +161,8 @@
 	MV_U32 devClass;	/* MV_BOARD_DEV_CLASS */
 	MV_U8 devWidth;
 	MV_U8 busWidth;
+	MV_U8 busNum;
+	MV_BOOL active;
 } MV_DEV_CS_INFO;
 
 typedef struct _boardSwitchInfo {
@@ -187,6 +197,7 @@
 	MV_BOARD_MAC_SPEED boardMacSpeed;
 	MV_32	boardEthSmiAddr;
 	MV_32 boardEthSmiAddr0;
+	MV_BOOL boardMacEnabled;
 } MV_BOARD_MAC_INFO;
 
 typedef struct _boardMppInfo {
@@ -255,7 +266,16 @@
 	MV_BOARD_PEX_INFO	boardPexInfo;	/* filled in runtime */
 	MV_U32 norFlashReadParams;
 	MV_U32 norFlashWriteParams;
+	MV_BOOL isSmiExternalPp;
+	MV_U32 smiExternalPpIndex;
+	MV_BOOL isSdMmcConnected;
 
+	/* Indicates if auto-detection of modules is enabled on this board. */
+	/* Set to MV_FALSE for any board that is not a DB. */
+	MV_BOOL configAutoDetect;
+
+	char modelName[MV_BOARD_MODEL_NAME_LEN];
+	MV_BOOL isCm3;
 } MV_BOARD_INFO;
 
 MV_VOID mvBoardEnvInit(MV_VOID);
@@ -266,11 +286,13 @@
 MV_BOOL mvBoardIsEthActive(MV_U32 ethNum);
 MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
 MV_BOOL mvBoardIsPortInGmii(MV_U32 ethPortNum);
+MV_U32 mvBoardPortTypeGet(MV_U32 ethPortNum);
 MV_BOOL mvBoardIsPortInMii(MV_U32 ethPortNum);
 MV_BOOL mvBoardIsPortInRgmii(MV_U32 ethPortNum);
 MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
 MV_32 mvBoardQuadPhyAddr0Get(MV_U32 ethPortNum);
 MV_32 mvBoardSwitchCpuPortGet(MV_U32 switchIdx);
+MV_BOOL mvBoardConfigAutoDetectEnabled(void);
 MV_32 mvBoardSmiScanModeGet(MV_U32 switchIdx);
 MV_U32 mvBoardTclkGet(MV_VOID);
 MV_U32 mvBoardSysClkGet(MV_VOID);
@@ -289,6 +311,9 @@
 MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
 MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
 MV_U32 mvBoardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
+MV_U32 mvBoardGetDevBusNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
+MV_BOOL mvBoardGetDevState(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
+MV_STATUS mvBoardSetDevState(MV_32 devNum, MV_BOARD_DEV_CLASS devClass, MV_BOOL newState);
 MV_U8 mvBoardTwsiAddrTypeGet(MV_BOARD_TWSI_CLASS twsiClass, MV_U32 index);
 MV_U8 mvBoardTwsiAddrGet(MV_BOARD_TWSI_CLASS twsiClass, MV_U32 index);
 MV_32 mvBoardNandWidthGet(void);
@@ -330,6 +355,8 @@
 MV_STATUS mvBoardDramBusWidthSet(MV_U16 conf);
 MV_U16 mvBoardDramBusWidthGet(MV_VOID);
 MV_STATUS mvBoardCoreFreqGet(MV_U8 *value);
+MV_STATUS mvBoardBypassCoreFreqGet(MV_U8 *value);
+MV_STATUS mvBoardBypassCoreFreqSet(MV_U8 freqVal);
 MV_STATUS mvBoardTmFreqGet(MV_U8 *value);
 MV_STATUS mvBoardTmFreqSet(MV_U8 freqVal);
 MV_STATUS mvBoardJtagCpuGet(MV_U8 *value);
@@ -362,12 +389,28 @@
 MV_VOID mvBoardDebugLed(MV_U32 hexNum);
 MV_NFC_ECC_MODE mvBoardNandECCModeGet(void);
 MV_U32 mvBoardCpssBoardIdSet(MV_U8);
+MV_U8 mvBoardCompatibleNameGet(char *pNameBuff);
 MV_NAND_IF_MODE mvBoardNandIfGet(void);
 MV_STATUS mvBoardOobPortCfgSet(MV_VOID);
+MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber);
+MV_BOOL mvBoardisAmc(void);
+MV_STATUS mvBoardPPSmiIndexGet(MV_U32 *index);
+MV_VOID mvBoardUpdateConfigforDT(MV_VOID);
+#ifdef CONFIG_MMC
+MV_BOOL mvBoardisSdioConnected(void);
+#endif
+void mvBoardGetModelName(char *pNameBuff);
+MV_BOOL mvBoardIsPpSmi(void);
+void mvBoardPinCtrlNameGet(char *compatibleBuf);
+#ifdef MV_CM3
+MV_BOOL mvBoardIsCm3(void);
+void mvBoardCm3CompatibleNameGet(char *compatibleBuf);
+#endif
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
+extern MV_BOARD_INFO *marvellAXPboardInfoTbl[];
 
 #endif /* __INCmvBoardEnvLibh */
diff --git a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.c b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.c
index 7450bf8..55721f5 100644
--- a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.c
+++ b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.c
@@ -98,8 +98,8 @@
 
 MV_BOARD_MAC_INFO bobcat2_customer_board_0_InfoBoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0 },
-	{BOARD_MAC_SPEED_AUTO, 0x1, 0x1 },
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
 };
 
 MV_BOARD_MODULE_TYPE_INFO bobcat2_customer_board_0_InfoBoardModTypeInfo[] = {
@@ -109,12 +109,17 @@
 };
 
 MV_DEV_CS_INFO bobcat2_customer_board_0_InfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth, busWidth }*/
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8}, /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
 #endif
-#if defined(MV_INCLUDE_NOR)
-	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16} /* NOR DEV */
+#if defined(MV_INCLUDE_NOR) && defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE}, /* NAND DEV */
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#elif defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#elif defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
 #endif
 };
 
@@ -170,7 +175,8 @@
 	.nandFlashControl		= BOBCAT2_CUSTOMER_0_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= BOBCAT2_CUSTOMER_0_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= BOBCAT2_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= BOBCAT2_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_FALSE	/* Enable modules auto-detection. */
 };
 
 MV_BOARD_INFO *customerBC2BoardInfoTbl[] = {
@@ -178,6 +184,230 @@
 	&bobcat2_customer_board_0_Info,
 };
 
+/*******************************************************************************
+	BobK Cetus customer board - Based on BOBK-CETUS-DB-98DX4235-12XG
+*******************************************************************************/
+#define BOBK_CETUS_CUSTOMER_0_BOARD_NAND_READ_PARAMS	0x000C0282
+#define BOBK_CETUS_CUSTOMER_0_BOARD_NAND_WRITE_PARAMS	0x00010305
+/*NAND care support for small page chips*/
+#define BOBK_CETUS_CUSTOMER_0_BOARD_NAND_CONTROL		0x01c00543
+
+#define BOBK_CETUS_CUSTOMER_0_BOARD_NOR_READ_PARAMS	0x403E07CF
+#define BOBK_CETUS_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS	0x000F0F0F
+
+MV_BOARD_TWSI_INFO	bobk_cetus_customer_board_0_InfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_PLD, 0x18, ADDR7_BIT},		/* Access to control PLD reg file */
+	{BOARD_DEV_TWSI_ZARLINK, 0x1B, ADDR7_BIT},		/* Access to Zarlink	*/
+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},         /* SatR bios 0		*/
+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},         /* SatR bios 1		*/
+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},          /* SatR bios 2		*/
+	{BOARD_DEV_TWSI_SATR, 0x4F, ADDR7_BIT},          /* SatR bios 3		*/
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},          /* Serial Init EPROM	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x70, ADDR7_BIT},          /* PCA9548 I2C mux 0	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x71, ADDR7_BIT},          /* PCA9548 I2C mux 1	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x75, ADDR7_BIT}          /* PCA9548 I2C mux 2	*/
+};
+
+MV_BOARD_MAC_INFO bobk_cetus_customer_board_0_InfoBoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_FALSE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+};
+
+MV_BOARD_MODULE_TYPE_INFO bobk_cetus_customer_board_0_InfoBoardModTypeInfo[] = {
+	{
+		.boardMppMod		= MV_BOARD_AUTO,
+	}
+};
+
+MV_DEV_CS_INFO bobk_cetus_customer_board_0_InfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
+#if defined(MV_INCLUDE_SPI)
+		{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NOR)
+		{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+		{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO bobk_cetus_customer_board_0_InfoBoardMppConfigValue[] = {
+	{ {
+	BOBK_CETUS_CUSTOMER_0_MPP0_7,
+	BOBK_CETUS_CUSTOMER_0_MPP8_15,
+	BOBK_CETUS_CUSTOMER_0_MPP16_23,
+	BOBK_CETUS_CUSTOMER_0_MPP24_31,
+	BOBK_CETUS_CUSTOMER_0_MPP32_39,
+	} },
+};
+
+MV_BOARD_INFO bobk_cetus_customer_board_0_Info = {
+	.boardName			= "BOBK-Cetus-Customer-Board-0",
+	.numBoardMppTypeValue		= ARRSZ(bobk_cetus_customer_board_0_InfoBoardModTypeInfo),
+	.pBoardModTypeValue		= bobk_cetus_customer_board_0_InfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(bobk_cetus_customer_board_0_InfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= bobk_cetus_customer_board_0_InfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(bobk_cetus_customer_board_0_InfoBoardDeCsInfo),
+	.pDevCsInfo			= bobk_cetus_customer_board_0_InfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(bobk_cetus_customer_board_0_InfoBoardTwsiDev),
+	.pBoardTwsiDev			= bobk_cetus_customer_board_0_InfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(bobk_cetus_customer_board_0_InfoBoardMacInfo),
+	.pBoardMacInfo			= bobk_cetus_customer_board_0_InfoBoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= NULL,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= BOBK_CETUS_CUSTOMER_0_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= BOBK_CETUS_CUSTOMER_0_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= 0,
+	.gppOutValLow			= BOBK_CETUS_CUSTOMER_0_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= BOBK_CETUS_CUSTOMER_0_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= 0,
+	.gppPolarityValLow		= BOBK_CETUS_CUSTOMER_0_GPP_POL_LOW,
+	.gppPolarityValMid		= BOBK_CETUS_CUSTOMER_0_GPP_POL_MID,
+	.gppPolarityValHigh		= 0,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= BOBK_CETUS_CUSTOMER_0_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= BOBK_CETUS_CUSTOMER_0_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= BOBK_CETUS_CUSTOMER_0_BOARD_NAND_CONTROL,
+	/* NOR init params */
+	.norFlashReadParams		= BOBK_CETUS_CUSTOMER_0_BOARD_NOR_READ_PARAMS,
+	.norFlashWriteParams		= BOBK_CETUS_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS,
+	.isSmiExternalPp		= MV_TRUE,
+	.smiExternalPpIndex		= 0,
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_FALSE	/* Enable modules auto-detection. */
+};
+
+/*******************************************************************************
+	BobK Caelum customer board - Based on BOBK-CAELUM-DB-98DX4203-48G12XG
+*******************************************************************************/
+#define BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_READ_PARAMS	0x000C0282
+#define BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_WRITE_PARAMS	0x00010305
+/*NAND care support for small page chips*/
+#define BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_CONTROL		0x01c00543
+
+#define BOBK_CAELUM_CUSTOMER_1_BOARD_NOR_READ_PARAMS	0x403E07CF
+#define BOBK_CAELUM_CUSTOMER_1_BOARD_NOR_WRITE_PARAMS	0x000F0F0F
+
+MV_BOARD_TWSI_INFO	bobk_caelum_customer_board_1_InfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_PLD, 0x18, ADDR7_BIT},		/* Access to control PLD reg file */
+	{BOARD_DEV_TWSI_ZARLINK, 0x1B, ADDR7_BIT},		/* Access to Zarlink	*/
+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},         /* SatR bios 0		*/
+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},         /* SatR bios 1		*/
+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},          /* SatR bios 2		*/
+	{BOARD_DEV_TWSI_SATR, 0x4F, ADDR7_BIT},          /* SatR bios 3		*/
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},          /* Serial Init EPROM	*/
+	{BOARD_DEV_TWSI_PCA9555_IO_EXPANDER, 0x20, ADDR7_BIT},          /* Qsgmii/sfp mux control PCA9555 IO expander */
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x70, ADDR7_BIT},          /* PCA9548 I2C mux 0	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x71, ADDR7_BIT},          /* PCA9548 I2C mux 1	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x75, ADDR7_BIT}          /* PCA9548 I2C mux 2	*/
+};
+
+MV_BOARD_MAC_INFO bobk_caelum_customer_board_1_InfoBoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_FALSE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+};
+
+MV_BOARD_MODULE_TYPE_INFO bobk_caelum_customer_board_1_InfoBoardModTypeInfo[] = {
+	{
+		.boardMppMod		= MV_BOARD_AUTO,
+	}
+};
+
+MV_DEV_CS_INFO bobk_caelum_customer_board_1_InfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
+#if defined(MV_INCLUDE_SPI)
+		{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NOR)
+		{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+		{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO bobk_caelum_customer_board_1_InfoBoardMppConfigValue[] = {
+	{ {
+	BOBK_CAELUM_CUSTOMER_1_MPP0_7,
+	BOBK_CAELUM_CUSTOMER_1_MPP8_15,
+	BOBK_CAELUM_CUSTOMER_1_MPP16_23,
+	BOBK_CAELUM_CUSTOMER_1_MPP24_31,
+	BOBK_CAELUM_CUSTOMER_1_MPP32_39,
+	} },
+};
+
+MV_BOARD_INFO bobk_caelum_customer_board_1_Info = {
+	.boardName			= "BOBK-Caelum-Customer-Board-1",
+	.numBoardMppTypeValue		= ARRSZ(bobk_caelum_customer_board_1_InfoBoardModTypeInfo),
+	.pBoardModTypeValue		= bobk_caelum_customer_board_1_InfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(bobk_caelum_customer_board_1_InfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= bobk_caelum_customer_board_1_InfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(bobk_caelum_customer_board_1_InfoBoardDeCsInfo),
+	.pDevCsInfo			= bobk_caelum_customer_board_1_InfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(bobk_caelum_customer_board_1_InfoBoardTwsiDev),
+	.pBoardTwsiDev			= bobk_caelum_customer_board_1_InfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(bobk_caelum_customer_board_1_InfoBoardMacInfo),
+	.pBoardMacInfo			= bobk_caelum_customer_board_1_InfoBoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= NULL,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= BOBK_CAELUM_CUSTOMER_1_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= BOBK_CAELUM_CUSTOMER_1_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= 0,
+	.gppOutValLow			= BOBK_CAELUM_CUSTOMER_1_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= BOBK_CAELUM_CUSTOMER_1_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= 0,
+	.gppPolarityValLow		= BOBK_CAELUM_CUSTOMER_1_GPP_POL_LOW,
+	.gppPolarityValMid		= BOBK_CAELUM_CUSTOMER_1_GPP_POL_MID,
+	.gppPolarityValHigh		= 0,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= BOBK_CAELUM_CUSTOMER_1_BOARD_NAND_CONTROL,
+	/* NOR init params */
+	.norFlashReadParams		= BOBK_CAELUM_CUSTOMER_1_BOARD_NOR_READ_PARAMS,
+	.norFlashWriteParams		= BOBK_CAELUM_CUSTOMER_1_BOARD_NOR_WRITE_PARAMS,
+	.isSmiExternalPp		= MV_TRUE,
+	.smiExternalPpIndex		= 1,
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_FALSE	/* Enable modules auto-detection. */
+};
+
+
+MV_BOARD_INFO *customerBOBKBoardInfoTbl[] = {
+	&bobk_cetus_customer_board_0_Info,
+	&bobk_caelum_customer_board_1_Info,
+};
 
 /*******************************************************************************
 	Alleycat3 board - Based on BOBCAT2-DB-DX
@@ -207,8 +437,8 @@
 
 MV_BOARD_MAC_INFO alleycat3_customer_board_0_InfoBoardMacInfo[] = {
 /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_AUTO, -1, -1 },
-	{BOARD_MAC_SPEED_AUTO, -1, -1 }
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE}
 };
 
 MV_BOARD_MODULE_TYPE_INFO alleycat3_customer_board_0_InfoBoardModTypeInfo[] = {
@@ -218,12 +448,17 @@
 };
 
 MV_DEV_CS_INFO alleycat3_customer_board_0_InfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth, busWidth }*/
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8}, /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
 #endif
-#if defined(MV_INCLUDE_NOR)
-	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16} /* NOR DEV */
+#if defined(MV_INCLUDE_NOR) && defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE}, /* NAND DEV */
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#elif defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#elif defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
 #endif
 };
 
@@ -279,7 +514,8 @@
 	.nandFlashControl		= ALLEYCAT3_CUSTOMER_0_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= ALLEYCAT3_CUSTOMER_0_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= ALLEYCAT3_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= ALLEYCAT3_CUSTOMER_0_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_FALSE	/* Enable modules auto-detection. */
 };
 
 MV_BOARD_INFO *customerAC3BoardInfoTbl[] = {
@@ -316,8 +552,8 @@
 
 MV_BOARD_MAC_INFO db_dx_bc2InfoBoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_AUTO, -1, -1 },
-	{BOARD_MAC_SPEED_AUTO, -1, -1 },
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE},
 };
 
 MV_BOARD_MODULE_TYPE_INFO db_dx_bc2InfoBoardModTypeInfo[] = {
@@ -327,12 +563,17 @@
 };
 
 MV_DEV_CS_INFO db_dx_bc2InfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth, busWidth }*/
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8}, /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
 #endif
-#if defined(MV_INCLUDE_NOR)
-	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 8, 8} /* NOR DEV */
+#if defined(MV_INCLUDE_NOR) && defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE}, /* NAND DEV */
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#elif defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#elif defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
 #endif
 };
 
@@ -393,7 +634,12 @@
 	.nandFlashControl		= DB_DX_BC2_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= DB_DX_BC2_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= DB_DX_BC2_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_BC2_BOARD_NOR_WRITE_PARAMS,
+	.modelName			= "BobCat2 Development Board",
+	.isSmiExternalPp		= MV_FALSE,
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.isCm3				= MV_TRUE
 };
 
 /**********************************************************************************/
@@ -407,8 +653,7 @@
 
 MV_BOARD_MAC_INFO rd_dx_bc2InfoBoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_1000M, 0x0, 0x0 },
-	{BOARD_MAC_SPEED_1000M, 0x1, 0x1 },
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
 };
 
 MV_BOARD_MODULE_TYPE_INFO rd_dx_bc2InfoBoardModTypeInfo[] = {
@@ -418,9 +663,12 @@
 };
 
 MV_DEV_CS_INFO rd_dx_bc2InfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth}*/
+	/*{deviceCS, params, devType, devWidth, busNum, active}*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8} /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
 #endif
 };
 
@@ -473,7 +721,12 @@
 	 /* NAND init params */
 	.nandFlashReadParams		= RD_DX_BC2_BOARD_NAND_READ_PARAMS,
 	.nandFlashWriteParams		= RD_DX_BC2_BOARD_NAND_WRITE_PARAMS,
-	.nandFlashControl		= RD_DX_BC2_BOARD_NAND_CONTROL
+	.nandFlashControl		= RD_DX_BC2_BOARD_NAND_CONTROL,
+	.modelName			= "BobCat2 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE,
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.isCm3				= MV_TRUE
 };
 
 /**********************************************************************************/
@@ -485,10 +738,15 @@
 /*NAND care support for small page chips*/
 #define RD_MTL_BC2_BOARD_NAND_CONTROL			0x01c00543
 
+MV_BOARD_TWSI_INFO	bc2_rd_mtlInfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_PLD, 0x77, ADDR7_BIT},				/* Access to control PLD reg file */
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},		/* Serial Ini EPROM	*/
+};
+
 MV_BOARD_MAC_INFO bc2_rd_mtlInfoBoardMacInfo[] = {
 	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_1000M, 0x0, 0x0 },
-	{BOARD_MAC_SPEED_1000M, 0x1, 0x1 },
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
 };
 
 MV_BOARD_MODULE_TYPE_INFO bc2_rd_mtlInfoBoardModTypeInfo[] = {
@@ -498,9 +756,12 @@
 };
 
 MV_DEV_CS_INFO bc2_rd_mtlInfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth}*/
+	/*{deviceCS, params, devType, devWidth, busNum, active}*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8} /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
 #endif
 };
 
@@ -515,24 +776,24 @@
 };
 
 MV_BOARD_INFO bc2_rd_mtlInfo = {
-	.boardName			= "RD-BC2-MTL-PoE-2QSFP-6SFP",
+	.boardName					= "RD-MTL-BC2-48G-12XG2XLG",
 	.numBoardMppTypeValue		= ARRSZ(bc2_rd_mtlInfoBoardModTypeInfo),
-	.pBoardModTypeValue		= bc2_rd_mtlInfoBoardModTypeInfo,
+	.pBoardModTypeValue			= bc2_rd_mtlInfoBoardModTypeInfo,
 	.numBoardMppConfigValue		= ARRSZ(bc2_rd_mtlInfoBoardMppConfigValue),
 	.pBoardMppConfigValue		= bc2_rd_mtlInfoBoardMppConfigValue,
 	.intsGppMaskLow			= 0,
 	.intsGppMaskMid			= 0,
 	.intsGppMaskHigh		= 0,
 	.numBoardDeviceIf		= ARRSZ(bc2_rd_mtlInfoBoardDeCsInfo),
-	.pDevCsInfo			= bc2_rd_mtlInfoBoardDeCsInfo,
-	.numBoardTwsiDev		= 0,
-	.pBoardTwsiDev			= NULL,
+	.pDevCsInfo				= bc2_rd_mtlInfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(bc2_rd_mtlInfoBoardTwsiDev),
+	.pBoardTwsiDev			= bc2_rd_mtlInfoBoardTwsiDev,
 	.numBoardMacInfo		= ARRSZ(bc2_rd_mtlInfoBoardMacInfo),
 	.pBoardMacInfo			= bc2_rd_mtlInfoBoardMacInfo,
 	.numBoardGppInfo		= 0,
 	.pBoardGppInfo			= NULL,
 	.activeLedsNumber		= 0,
-	.pLedGppPin			= NULL,
+	.pLedGppPin				= NULL,
 	.ledsPolarity			= 0,
 
 	/* GPP values */
@@ -551,9 +812,339 @@
 	.switchInfoNum = 0,
 
 	/* NAND init params */
-	.nandFlashReadParams		= RD_MTL_BC2_BOARD_NAND_READ_PARAMS,
-	.nandFlashWriteParams		= RD_MTL_BC2_BOARD_NAND_WRITE_PARAMS,
-	.nandFlashControl		= RD_MTL_BC2_BOARD_NAND_CONTROL
+	.nandFlashReadParams	= RD_MTL_BC2_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams	= RD_MTL_BC2_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= RD_MTL_BC2_BOARD_NAND_CONTROL,
+	.modelName			= "BobCat2 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE,
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.isCm3				= MV_TRUE
+};
+
+/*********************************************************************************/
+/*************************************/
+/* BOBK-CETUS-DB-98DX4235-12XG BOARD */
+/*************************************/
+#define DB_DX_BOBK_BOARD_NAND_READ_PARAMS	0x000C0282
+#define DB_DX_BOBK_BOARD_NAND_WRITE_PARAMS	0x00010305
+/*NAND care support for small page chips*/
+#define DB_DX_BOBK_BOARD_NAND_CONTROL		0x01c00543
+
+#define DB_DX_BOBK_BOARD_NOR_READ_PARAMS	0x403E07CF
+#define DB_DX_BOBK_BOARD_NOR_WRITE_PARAMS	0x000F0F0F
+
+/* TODO */
+MV_BOARD_TWSI_INFO	db_dx_bobkCetusInfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_PLD, 0x18, ADDR7_BIT},		/* Access to control PLD reg file */
+	{BOARD_DEV_TWSI_ZARLINK, 0x1B, ADDR7_BIT},		/* Access to Zarlink	*/
+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},         /* SatR bios 0		*/
+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},         /* SatR bios 1		*/
+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},          /* SatR bios 2		*/
+	{BOARD_DEV_TWSI_SATR, 0x4F, ADDR7_BIT},          /* SatR bios 3		*/
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},          /* Serial Init EPROM	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x70, ADDR7_BIT},          /* PCA9548 I2C mux 0	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x71, ADDR7_BIT},          /* PCA9548 I2C mux 1	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x75, ADDR7_BIT}          /* PCA9548 I2C mux 2	*/
+};
+
+MV_BOARD_MAC_INFO db_dx_bobkCetusInfoBoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_FALSE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+};
+
+MV_BOARD_MODULE_TYPE_INFO db_dx_bobkCetusInfoBoardModTypeInfo[] = {
+	{
+		.boardMppMod		= MV_BOARD_AUTO,
+	}
+};
+
+/* TO DE */
+MV_DEV_CS_INFO db_dx_bobkCetusInfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth }*/
+#if defined(MV_INCLUDE_SPI)
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO db_dx_bobkCetusInfoBoardMppConfigValue[] = {
+	{ {
+#if defined(MV_INCLUDE_NOR)
+	DB_DX_BOBK_CETUS_NOR_MPP0_7,
+	DB_DX_BOBK_CETUS_NOR_MPP8_15,
+#else
+	DB_DX_BOBK_CETUS_MPP0_7,
+	DB_DX_BOBK_CETUS_MPP8_15,
+#endif
+	DB_DX_BOBK_CETUS_MPP16_23,
+	DB_DX_BOBK_CETUS_MPP24_31,
+	DB_DX_BOBK_CETUS_MPP32_39,
+	} },
+};
+
+MV_BOARD_INFO db_dx_bobkCetusInfo = {
+	.boardName			= "DB-98DX4235-12XG",
+	.numBoardMppTypeValue		= ARRSZ(db_dx_bobkCetusInfoBoardModTypeInfo),
+	.pBoardModTypeValue		= db_dx_bobkCetusInfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(db_dx_bobkCetusInfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= db_dx_bobkCetusInfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(db_dx_bobkCetusInfoBoardDeCsInfo),
+	.pDevCsInfo			= db_dx_bobkCetusInfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(db_dx_bobkCetusInfoBoardTwsiDev),
+	.pBoardTwsiDev			= db_dx_bobkCetusInfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(db_dx_bobkCetusInfoBoardMacInfo),
+	.pBoardMacInfo			= db_dx_bobkCetusInfoBoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= NULL,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= DB_DX_BOBK_CETUS_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= DB_DX_BOBK_CETUS_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= 0,
+	.gppOutValLow			= DB_DX_BOBK_CETUS_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= DB_DX_BOBK_CETUS_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= 0,
+	.gppPolarityValLow		= DB_DX_BOBK_CETUS_GPP_POL_LOW,
+	.gppPolarityValMid		= DB_DX_BOBK_CETUS_GPP_POL_MID,
+	.gppPolarityValHigh		= 0,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= DB_DX_BOBK_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= DB_DX_BOBK_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= DB_DX_BOBK_BOARD_NAND_CONTROL,
+	/* NOR init params */
+	.norFlashReadParams		= DB_DX_BOBK_BOARD_NOR_READ_PARAMS,
+	.norFlashWriteParams		= DB_DX_BOBK_BOARD_NOR_WRITE_PARAMS,
+	.isSmiExternalPp		= MV_TRUE,
+	.smiExternalPpIndex		= 0,
+	.modelName			= "BobK Cetus Development Board",
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.isCm3				= MV_TRUE
+};
+
+/*********************************************************************************/
+/**************************************/
+/* BOBK-CAELUM-DB-98DX4203-48G12XG BOARD */
+/**************************************/
+
+MV_BOARD_TWSI_INFO	db_dx_bobkCaelumInfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_PLD, 0x18, ADDR7_BIT},		/* Access to control PLD reg file */
+	{BOARD_DEV_TWSI_ZARLINK, 0x1B, ADDR7_BIT},		/* Access to Zarlink	*/
+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},         /* SatR bios 0		*/
+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},         /* SatR bios 1		*/
+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},          /* SatR bios 2		*/
+	{BOARD_DEV_TWSI_SATR, 0x4F, ADDR7_BIT},          /* SatR bios 3		*/
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},          /* Serial Init EPROM	*/
+	{BOARD_DEV_TWSI_PCA9555_IO_EXPANDER, 0x20, ADDR7_BIT},          /* Qsgmii/sfp mux control PCA9555 IO expander */
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x70, ADDR7_BIT},          /* PCA9548 I2C mux 0	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x71, ADDR7_BIT},          /* PCA9548 I2C mux 1	*/
+	{BOARD_DEV_TWSI_PCA9548_IO_MUX, 0x75, ADDR7_BIT}          /* PCA9548 I2C mux 2	*/
+};
+
+MV_BOARD_MAC_INFO db_dx_bobkCaelumInfoBoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_FALSE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+};
+
+MV_BOARD_MODULE_TYPE_INFO db_dx_bobkCaelumInfoBoardModTypeInfo[] = {
+	{
+		.boardMppMod		= MV_BOARD_AUTO,
+	}
+};
+
+/* TO DE */
+MV_DEV_CS_INFO db_dx_bobkCaelumInfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth }*/
+#if defined(MV_INCLUDE_SPI)
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO db_dx_bobkCaelumInfoBoardMppConfigValue[] = {
+	{ {
+#if defined(MV_INCLUDE_NOR)
+	DB_DX_BOBK_CAELUM_NOR_MPP0_7,
+	DB_DX_BOBK_CAELUM_NOR_MPP8_15,
+#else
+	DB_DX_BOBK_CAELUM_MPP0_7,
+	DB_DX_BOBK_CAELUM_MPP8_15,
+#endif
+	DB_DX_BOBK_CAELUM_MPP16_23,
+	DB_DX_BOBK_CAELUM_MPP24_31,
+	DB_DX_BOBK_CAELUM_MPP32_39,
+	} },
+};
+
+MV_BOARD_INFO db_dx_bobkCaelumInfo = {
+	.boardName			= "DB-98DX4203-48G12XG",
+	.numBoardMppTypeValue		= ARRSZ(db_dx_bobkCaelumInfoBoardModTypeInfo),
+	.pBoardModTypeValue		= db_dx_bobkCaelumInfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(db_dx_bobkCaelumInfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= db_dx_bobkCaelumInfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(db_dx_bobkCaelumInfoBoardDeCsInfo),
+	.pDevCsInfo			= db_dx_bobkCaelumInfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(db_dx_bobkCaelumInfoBoardTwsiDev),
+	.pBoardTwsiDev			= db_dx_bobkCaelumInfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(db_dx_bobkCaelumInfoBoardMacInfo),
+	.pBoardMacInfo			= db_dx_bobkCaelumInfoBoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= NULL,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= DB_DX_BOBK_CAELUM_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= DB_DX_BOBK_CAELUM_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= 0,
+	.gppOutValLow			= DB_DX_BOBK_CAELUM_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= DB_DX_BOBK_CAELUM_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= 0,
+	.gppPolarityValLow		= DB_DX_BOBK_CAELUM_GPP_POL_LOW,
+	.gppPolarityValMid		= DB_DX_BOBK_CAELUM_GPP_POL_MID,
+	.gppPolarityValHigh		= 0,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= DB_DX_BOBK_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= DB_DX_BOBK_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= DB_DX_BOBK_BOARD_NAND_CONTROL,
+	/* NOR init params */
+	.norFlashReadParams		= DB_DX_BOBK_BOARD_NOR_READ_PARAMS,
+	.norFlashWriteParams		= DB_DX_BOBK_BOARD_NOR_WRITE_PARAMS,
+	.isSmiExternalPp		= MV_TRUE,
+	.smiExternalPpIndex		= 1,
+	.modelName			= "BobK Caelum Development Board",
+	.isSdMmcConnected		= MV_TRUE,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.isCm3				= MV_TRUE
+};
+
+/*********************************************************************************/
+/**************************************/
+/* BOBK-LEWIS-RD-LWS-12XG-A BOARD */
+/**************************************/
+
+
+MV_BOARD_TWSI_INFO	rd_dx_bobkLewisInfoBoardTwsiDev[] = {
+/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */
+	{BOARD_DEV_TWSI_INIT_EPROM, 0x50, ADDR7_BIT},	/* Serial Init EPROM	*/
+};
+
+
+MV_BOARD_MAC_INFO rd_dx_bobkLewisInfoBoardMacInfo[] = {
+/* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_FALSE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE},
+};
+
+MV_BOARD_MODULE_TYPE_INFO rd_dx_bobkLewisInfoBoardModTypeInfo[] = {
+	{
+		.boardMppMod		= MV_BOARD_AUTO,
+	}
+};
+
+/* TO DE */
+MV_DEV_CS_INFO rd_dx_bobkLewisInfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth, busWidth }*/
+#if defined(MV_INCLUDE_SPI)
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO rd_dx_bobkLewisInfoBoardMppConfigValue[] = {
+	{ {
+	RD_DX_BOBK_LEWIS_MPP0_7,
+	RD_DX_BOBK_LEWIS_MPP8_15,
+	RD_DX_BOBK_LEWIS_MPP16_23,
+	RD_DX_BOBK_LEWIS_MPP24_31,
+	RD_DX_BOBK_LEWIS_MPP32_39,
+	} },
+};
+
+MV_BOARD_INFO rd_dx_bobkLewisInfo = {
+	.boardName			= "RD-LWS-12XG-A",
+	.numBoardMppTypeValue		= ARRSZ(rd_dx_bobkLewisInfoBoardModTypeInfo),
+	.pBoardModTypeValue		= rd_dx_bobkLewisInfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(rd_dx_bobkLewisInfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= rd_dx_bobkLewisInfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(rd_dx_bobkLewisInfoBoardDeCsInfo),
+	.pDevCsInfo			= rd_dx_bobkLewisInfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(rd_dx_bobkLewisInfoBoardTwsiDev),
+	.pBoardTwsiDev			= rd_dx_bobkLewisInfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(rd_dx_bobkLewisInfoBoardMacInfo),
+	.pBoardMacInfo			= rd_dx_bobkLewisInfoBoardMacInfo,
+	.numBoardGppInfo		= 0,
+	.pBoardGppInfo			= NULL,
+	.activeLedsNumber		= 0,
+	.pLedGppPin			= NULL,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= RD_DX_BOBK_LEWIS_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= RD_DX_BOBK_LEWIS_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= 0,
+	.gppOutValLow			= RD_DX_BOBK_LEWIS_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= RD_DX_BOBK_LEWIS_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= 0,
+	.gppPolarityValLow		= RD_DX_BOBK_LEWIS_GPP_POL_LOW,
+	.gppPolarityValMid		= RD_DX_BOBK_LEWIS_GPP_POL_MID,
+	.gppPolarityValHigh		= 0,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= DB_DX_BOBK_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= DB_DX_BOBK_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= DB_DX_BOBK_BOARD_NAND_CONTROL,
+	/* NOR init params */
+	.norFlashReadParams		= DB_DX_BOBK_BOARD_NOR_READ_PARAMS,
+	.norFlashWriteParams		= DB_DX_BOBK_BOARD_NOR_WRITE_PARAMS,
+	.isSmiExternalPp		= MV_TRUE,
+	.smiExternalPpIndex		= 0,
+	.modelName			= "BobK Lewis Reference Design Board",
+	.isSdMmcConnected		= MV_TRUE
 };
 
 /*********************************************************************************/
@@ -584,8 +1175,8 @@
 
 MV_BOARD_MAC_INFO db_dx_ac3InfoBoardMacInfo[] = {
 /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_32 boardEthSmiAddr , MV_32 boardEthSmiAddr0;}} */
-	{BOARD_MAC_SPEED_AUTO, -1, -1 },
-	{BOARD_MAC_SPEED_AUTO, -1, -1 }
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, -1, -1, MV_TRUE}
 };
 
 MV_BOARD_MODULE_TYPE_INFO db_dx_ac3InfoBoardModTypeInfo[] = {
@@ -595,12 +1186,17 @@
 };
 
 MV_DEV_CS_INFO db_dx_ac3InfoBoardDeCsInfo[] = {
-	/*{deviceCS, params, devType, devWidth, busWidth }*/
+	/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
 #if defined(MV_INCLUDE_SPI)
-	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8}, /* SPI DEV */
+	{SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
 #endif
-#if defined(MV_INCLUDE_NOR)
-	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16} /* NOR DEV */
+#if defined(MV_INCLUDE_NOR) && defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE}, /* NAND DEV */
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
+#elif defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#elif defined(MV_INCLUDE_NOR)
+	{DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_TRUE} /* NOR DEV */
 #endif
 };
 
@@ -656,7 +1252,10 @@
 	.nandFlashControl		= DB_DX_AC3_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= DB_DX_AC3_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AlleyCat3 Development Board",
+	.isSmiExternalPp		= MV_FALSE
 };
 
 /*********************************************************************************/
@@ -715,7 +1314,10 @@
 	.nandFlashControl		= DB_DX_AC3_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= DB_DX_AC3_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AlleyCat3 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE
 };
 /*********************************************************************************/
 /***********************************/
@@ -773,12 +1375,15 @@
 	.nandFlashControl		= DB_DX_AC3_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= DB_DX_AC3_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AlleyCat3 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE
 };
 
 /*********************************************************************************/
 /***********************************/
-/* ALLEYCAT3-DB-MISL-24G BOARD     */
+/* ALLEYCAT3-RD-MTL-2XXG-2XG BOARD */
 /***********************************/
 MV_BOARD_MPP_INFO db_misl_24G_46_ac3InfoBoardMppConfigValue[] = {
 	{ {
@@ -791,11 +1396,11 @@
 };
 
 MV_BOARD_INFO db_misl_24G_4xg_ac3Info = {
-	.boardName				= "DB-XC3-24G-4G",
-	.numBoardMppTypeValue	= ARRSZ(db_dx_ac3InfoBoardModTypeInfo),
+	.boardName			= "DB-XC3-24G-4G",
+	.numBoardMppTypeValue		= ARRSZ(db_dx_ac3InfoBoardModTypeInfo),
 	.pBoardModTypeValue		= db_dx_ac3InfoBoardModTypeInfo,
-	.numBoardMppConfigValue	= ARRSZ(db_misl_24G_46_ac3InfoBoardMppConfigValue),
-	.pBoardMppConfigValue	= db_misl_24G_46_ac3InfoBoardMppConfigValue,
+	.numBoardMppConfigValue		= ARRSZ(db_misl_24G_46_ac3InfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= db_misl_24G_46_ac3InfoBoardMppConfigValue,
 	.intsGppMaskLow			= 0,
 	.intsGppMaskMid			= 0,
 	.intsGppMaskHigh		= 0,
@@ -832,7 +1437,10 @@
 	.nandFlashControl			= DB_DX_AC3_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams			= DB_DX_AC3_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AlleyCat3 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE
 };
 
 /*********************************************************************************/
@@ -862,8 +1470,8 @@
 	.pDevCsInfo				= db_dx_ac3InfoBoardDeCsInfo,
 	.numBoardTwsiDev		= ARRSZ(db_dx_ac3InfoBoardTwsiDev),
 	.pBoardTwsiDev			= db_dx_ac3InfoBoardTwsiDev,
-	.numBoardMacInfo		= 0,
-	.pBoardMacInfo			= NULL,
+	.numBoardMacInfo		= ARRSZ(db_dx_ac3InfoBoardMacInfo),
+	.pBoardMacInfo			= db_dx_ac3InfoBoardMacInfo,
 	.numBoardGppInfo		= 0,
 	.pBoardGppInfo			= NULL,
 	.activeLedsNumber		= 0,
@@ -882,18 +1490,122 @@
 	.gppPolarityValHigh		= 0,
 
 	/* External Switch Configuration */
-	.pSwitchInfo			= NULL,
-	.switchInfoNum			= 0,
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
 
 	/* NAND init params */
-	.nandFlashReadParams	= DB_DX_AC3_BOARD_NAND_READ_PARAMS,
-	.nandFlashWriteParams	= DB_DX_AC3_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashReadParams		= DB_DX_AC3_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= DB_DX_AC3_BOARD_NAND_WRITE_PARAMS,
 	.nandFlashControl		= DB_DX_AC3_BOARD_NAND_CONTROL,
 	/* NOR init params */
 	.norFlashReadParams		= DB_DX_AC3_BOARD_NOR_READ_PARAMS,
-	.norFlashWriteParams	= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS
+	.norFlashWriteParams		= DB_DX_AC3_BOARD_NOR_WRITE_PARAMS,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AlleyCat3 Reference Design Board",
+	.isSmiExternalPp		= MV_FALSE
 };
 
+/***************************************************************************************/
+/* ARMADA-XP AMC BOARD -  only for Linux usage (AXP family is shared with MSYS in LSP) */
+/***************************************************************************************/
+#define DB_78X60_AMC_BOARD_NAND_READ_PARAMS		0x000C0282
+#define DB_78X60_AMC_BOARD_NAND_WRITE_PARAMS		0x00010305
+/*NAND care support for small page chips*/
+#define DB_78X60_AMC_BOARD_NAND_CONTROL			0x01c00543
+
+MV_U8	db78X60amcInfoBoardDebugLedIf[] = {53, 54, 55, 56}; /* 7 segment MPPs*/
+
+MV_BOARD_TWSI_INFO	db78X60amcInfoBoardTwsiDev[] = {
+	/* No TWSI devices on board*/
+};
+
+MV_BOARD_MAC_INFO db78X60amcInfoBoardMacInfo[] = {
+	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */
+	{BOARD_MAC_SPEED_AUTO, 0x1, 0x0, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, 0xD, 0x0, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, 0xC, 0x0, MV_TRUE},
+	{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE}
+};
+
+
+MV_BOARD_MODULE_TYPE_INFO db78X60amcInfoBoardModTypeInfo[] = {
+	/* No Modules */
+};
+
+MV_BOARD_GPP_INFO db78X60amcInfoBoardGppInfo[] = {
+	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */
+	{BOARD_GPP_USB_VBUS,    46} /* from MPP map */
+};
+
+MV_DEV_CS_INFO db78X60amcInfoBoardDeCsInfo[] = {
+	/*{deviceCS, params, devType, devWidth}*/
+#if defined(MV_INCLUDE_SPI)
+	{SPI_CS0_AXP, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE}, /* SPI DEV */
+#endif
+#if defined(MV_INCLUDE_NAND)
+	{DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 8, 8, 0, MV_TRUE} /* NAND DEV */
+#endif
+};
+
+MV_BOARD_MPP_INFO db78X60amcInfoBoardMppConfigValue[] = {
+	{ {
+		DB_78X60_AMC_MPP0_7,
+		DB_78X60_AMC_MPP8_15,
+		DB_78X60_AMC_MPP16_23,
+		DB_78X60_AMC_MPP24_31,
+		DB_78X60_AMC_MPP32_39,
+		DB_78X60_AMC_MPP40_47,
+		DB_78X60_AMC_MPP48_55,
+		DB_78X60_AMC_MPP56_63,
+		DB_78X60_AMC_MPP64_67,
+	} }
+};
+
+MV_BOARD_INFO db78X60amcInfo = {
+	.boardName			= "DB-78460-AMC",
+	.numBoardMppTypeValue		= ARRSZ(db78X60amcInfoBoardModTypeInfo),
+	.pBoardModTypeValue		= db78X60amcInfoBoardModTypeInfo,
+	.numBoardMppConfigValue		= ARRSZ(db78X60amcInfoBoardMppConfigValue),
+	.pBoardMppConfigValue		= db78X60amcInfoBoardMppConfigValue,
+	.intsGppMaskLow			= 0,
+	.intsGppMaskMid			= 0,
+	.intsGppMaskHigh		= 0,
+	.numBoardDeviceIf		= ARRSZ(db78X60amcInfoBoardDeCsInfo),
+	.pDevCsInfo			= db78X60amcInfoBoardDeCsInfo,
+	.numBoardTwsiDev		= ARRSZ(db78X60amcInfoBoardTwsiDev),
+	.pBoardTwsiDev			= db78X60amcInfoBoardTwsiDev,
+	.numBoardMacInfo		= ARRSZ(db78X60amcInfoBoardMacInfo),
+	.pBoardMacInfo			= db78X60amcInfoBoardMacInfo,
+	.numBoardGppInfo		= ARRSZ(db78X60amcInfoBoardGppInfo),
+	.pBoardGppInfo			= db78X60amcInfoBoardGppInfo,
+	.activeLedsNumber		= ARRSZ(db78X60amcInfoBoardDebugLedIf),
+	.pLedGppPin			= db78X60amcInfoBoardDebugLedIf,
+	.ledsPolarity			= 0,
+
+	/* GPP values */
+	.gppOutEnValLow			= DB_78X60_AMC_GPP_OUT_ENA_LOW,
+	.gppOutEnValMid			= DB_78X60_AMC_GPP_OUT_ENA_MID,
+	.gppOutEnValHigh		= DB_78X60_AMC_GPP_OUT_ENA_HIGH,
+	.gppOutValLow			= DB_78X60_AMC_GPP_OUT_VAL_LOW,
+	.gppOutValMid			= DB_78X60_AMC_GPP_OUT_VAL_MID,
+	.gppOutValHigh			= DB_78X60_AMC_GPP_OUT_VAL_HIGH,
+	.gppPolarityValLow		= DB_78X60_AMC_GPP_POL_LOW,
+	.gppPolarityValMid		= DB_78X60_AMC_GPP_POL_MID,
+	.gppPolarityValHigh		= DB_78X60_AMC_GPP_POL_HIGH,
+
+	/* External Switch Configuration */
+	.pSwitchInfo = NULL,
+	.switchInfoNum = 0,
+
+	/* NAND init params */
+	.nandFlashReadParams		= DB_78X60_AMC_BOARD_NAND_READ_PARAMS,
+	.nandFlashWriteParams		= DB_78X60_AMC_BOARD_NAND_WRITE_PARAMS,
+	.nandFlashControl		= DB_78X60_AMC_BOARD_NAND_CONTROL,
+	.configAutoDetect		= MV_TRUE,	/* Enable modules auto-detection. */
+	.modelName			= "AMC Development Board"
+};
+
+
 /*********************************************************************************/
 
 MV_BOARD_INFO *marvellBC2BoardInfoTbl[] = {
@@ -902,6 +1614,12 @@
 	&bc2_rd_mtlInfo
 };
 
+MV_BOARD_INFO *marvellBOBKBoardInfoTbl[] = {
+	&db_dx_bobkCetusInfo,
+	&db_dx_bobkCaelumInfo,
+	&rd_dx_bobkLewisInfo
+};
+
 MV_BOARD_INFO *marvellAC3BoardInfoTbl[] = {
 	&db_dx_ac3Info,
 	&rd_mtl_4xg_ac3Info,
@@ -909,3 +1627,8 @@
 	&db_misl_24G_4xg_ac3Info,
 	&rd_mtl_24G_ac3Info
 };
+
+/* only for Linux usage (AXP family is shared with MSYS in LSP) */
+MV_BOARD_INFO *marvellAXPboardInfoTbl[] = {
+	&db78X60amcInfo
+};
diff --git a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.h b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.h
index 3434624..fba63de 100644
--- a/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.h
+++ b/board/mv_ebu/msys/msys_family/boardEnv/mvBoardEnvSpec.h
@@ -80,9 +80,9 @@
 
 /* Bobcat2 Marvell boards */
 #define BC2_MARVELL_BOARD_ID_BASE	0x10
-#define DB_DX_BC2_ID				(BC2_MARVELL_BOARD_ID_BASE + 0)
-#define RD_DX_BC2_ID				(BC2_MARVELL_BOARD_ID_BASE + 1)
-#define RD_MTL_BC2					(BC2_MARVELL_BOARD_ID_BASE + 2)
+#define DB_DX_BC2_ID			(BC2_MARVELL_BOARD_ID_BASE + 0)
+#define RD_DX_BC2_ID			(BC2_MARVELL_BOARD_ID_BASE + 1)
+#define RD_MTL_BC2			(BC2_MARVELL_BOARD_ID_BASE + 2)
 #define BC2_MARVELL_MAX_BOARD_ID	(BC2_MARVELL_BOARD_ID_BASE + 3)
 #define BC2_MARVELL_BOARD_NUM		(BC2_MARVELL_MAX_BOARD_ID - BC2_MARVELL_BOARD_ID_BASE)
 
@@ -96,17 +96,52 @@
 
 /* AlleyCat3 Marvell boards */
 #define AC3_MARVELL_BOARD_ID_BASE	0x30
-#define DB_AC3_ID					(AC3_MARVELL_BOARD_ID_BASE + 0)
-#define RD_MTL_4XG_AC3_ID			(AC3_MARVELL_BOARD_ID_BASE + 1)
+#define DB_AC3_ID			(AC3_MARVELL_BOARD_ID_BASE + 0)
+#define RD_MTL_4XG_AC3_ID		(AC3_MARVELL_BOARD_ID_BASE + 1)
 #define RD_MTL_2XXG_2XG_AC3_ID		(AC3_MARVELL_BOARD_ID_BASE + 2)
 #define DB_MISL_24G4G_AC3_ID		(AC3_MARVELL_BOARD_ID_BASE + 3)
-#define RD_MTL_24G_AC3_ID			(AC3_MARVELL_BOARD_ID_BASE + 4)
+#define RD_MTL_24G_AC3_ID		(AC3_MARVELL_BOARD_ID_BASE + 4)
 #define AC3_MARVELL_MAX_BOARD_ID	(AC3_MARVELL_BOARD_ID_BASE + 5)
 #define AC3_MARVELL_BOARD_NUM		(AC3_MARVELL_MAX_BOARD_ID - AC3_MARVELL_BOARD_ID_BASE)
 
-#define INVALID_BOARD_ID			0xFFFF
+/* BobK Customer Boards */
+#define BOBK_CUSTOMER_BOARD_ID_BASE	0x40
+#define BOBK_CETUS_CUSTOMER_BOARD_ID0		(BOBK_CUSTOMER_BOARD_ID_BASE + 0)
+#define BOBK_CAELUM_CUSTOMER_BOARD_ID1		(BOBK_CUSTOMER_BOARD_ID_BASE + 1)
+#define BOBK_CUSTOMER_MAX_BOARD_ID			(BOBK_CUSTOMER_BOARD_ID_BASE + 2)
+#define BOBK_CUSTOMER_BOARD_NUM			(BOBK_CUSTOMER_MAX_BOARD_ID - BOBK_CUSTOMER_BOARD_ID_BASE)
 
+/* BobK Marvell Boards */
+#define BOBK_MARVELL_BOARD_ID_BASE	0x50
+#define BOBK_CETUS_DB_ID			(BOBK_MARVELL_BOARD_ID_BASE + 0)
+#define BOBK_CAELUM_DB_ID			(BOBK_MARVELL_BOARD_ID_BASE + 1)
+#define BOBK_LEWIS_RD_ID			(BOBK_MARVELL_BOARD_ID_BASE + 2)
+#define BOBK_MARVELL_MAX_BOARD_ID		(BOBK_MARVELL_BOARD_ID_BASE + 3)
+#define BOBK_MARVELL_BOARD_NUM		(BOBK_MARVELL_MAX_BOARD_ID - BOBK_MARVELL_BOARD_ID_BASE)
+
+/* AXP-AMC board: for Linux 2.6/3.4 usage only (AXP family is shared with MSYS in LSP) */
+#define DB_78X60_AMC_ID			0x6
+
+#define INVALID_BOARD_ID		0xFFFF
 #define BOARD_ID_INDEX_MASK		0x10	/* Mask used to return board index via board Id */
+#define RD_MTL_BC2_PCB_ID		0x70
+
+#if defined CONFIG_ALLEYCAT3
+	#define MARVELL_BOARD_ID_BASE		AC3_MARVELL_BOARD_ID_BASE
+	#define MV_MAX_MARVELL_BOARD_ID		AC3_MARVELL_MAX_BOARD_ID
+	#define MV_MARVELL_BOARD_NUM		AC3_MARVELL_BOARD_NUM
+	#define MV_DEFAULT_BOARD_ID		DB_AC3_ID
+#elif defined CONFIG_BOBCAT2
+	#define MARVELL_BOARD_ID_BASE		BC2_MARVELL_BOARD_ID_BASE
+	#define MV_MAX_MARVELL_BOARD_ID		BC2_MARVELL_MAX_BOARD_ID
+	#define MV_MARVELL_BOARD_NUM		BC2_MARVELL_BOARD_NUM
+	#define MV_DEFAULT_BOARD_ID		DB_DX_BC2_ID
+#else
+	#define MARVELL_BOARD_ID_BASE		BOBK_MARVELL_BOARD_ID_BASE
+	#define MV_MAX_MARVELL_BOARD_ID		BOBK_MARVELL_MAX_BOARD_ID
+	#define MV_MARVELL_BOARD_NUM		BOBK_MARVELL_BOARD_NUM
+	#define MV_DEFAULT_BOARD_ID		BOBK_CETUS_DB_ID
+#endif
 
 /********************************************
 *		Bobcat2 Boards
@@ -274,6 +309,238 @@
 #define RD_MTL_BC2_GPP_POL_MID		0x0
 
 /********************************************
+*		Bobk Boards
+*********************************************/
+/*******************************************************************************
+* BobK Cetus Customer board - Based on BOBK-CETUS-DB-98DX4235-12XG
+*******************************************************************************/
+
+#define BOBK_CETUS_CUSTOMER_0_MPP0_7		0x22242222
+#define BOBK_CETUS_CUSTOMER_0_MPP8_15		0x11122222
+#define BOBK_CETUS_CUSTOMER_0_MPP16_23		0x44444044
+#define BOBK_CETUS_CUSTOMER_0_MPP24_31		0x14444444
+#define BOBK_CETUS_CUSTOMER_0_MPP32_39		0x00000001
+
+#define BOBK_CETUS_CUSTOMER_0_GPP_OUT_ENA_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+							 | BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30))
+#define BOBK_CETUS_CUSTOMER_0_GPP_OUT_ENA_MID	(~(0))
+
+#define BOBK_CETUS_CUSTOMER_0_GPP_OUT_VAL_LOW	(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+							| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30)
+#define BOBK_CETUS_CUSTOMER_0_GPP_OUT_VAL_MID	0x0
+
+#define BOBK_CETUS_CUSTOMER_0_GPP_POL_LOW		0x0
+#define BOBK_CETUS_CUSTOMER_0_GPP_POL_MID		0x0
+
+/*******************************************************************************
+* BobK Caelum Customer board - Based on BOBK-CAELUM-DB-98DX4203-48G12XG
+*******************************************************************************/
+
+#define BOBK_CAELUM_CUSTOMER_1_MPP0_7		0x22242222
+#define BOBK_CAELUM_CUSTOMER_1_MPP8_15		0x11122222
+#define BOBK_CAELUM_CUSTOMER_1_MPP16_23		0x44444044
+#define BOBK_CAELUM_CUSTOMER_1_MPP24_31		0x14444444
+#define BOBK_CAELUM_CUSTOMER_1_MPP32_39		0x00000001
+
+#define BOBK_CAELUM_CUSTOMER_1_GPP_OUT_ENA_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+							 | BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30))
+#define BOBK_CAELUM_CUSTOMER_1_GPP_OUT_ENA_MID	(~(0))
+
+#define BOBK_CAELUM_CUSTOMER_1_GPP_OUT_VAL_LOW	(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+							| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30)
+#define BOBK_CAELUM_CUSTOMER_1_GPP_OUT_VAL_MID	0x0
+
+#define BOBK_CAELUM_CUSTOMER_1_GPP_POL_LOW		0x0
+#define BOBK_CAELUM_CUSTOMER_1_GPP_POL_MID		0x0
+
+
+/************************************/
+/*   BOBK-CETUS-DB-98DX4235-12XG    */
+/************************************/
+#define DB_DX_BOBK_CETUS_MPP0_7	0x22242222
+#define DB_DX_BOBK_CETUS_MPP8_15	0x11122222
+#define DB_DX_BOBK_CETUS_MPP16_23	0x44444044
+#define DB_DX_BOBK_CETUS_MPP24_31	0x14444444
+#define DB_DX_BOBK_CETUS_MPP32_39	0x00000001
+
+#define DB_DX_BOBK_CETUS_NOR_MPP0_7	0x44444444
+#define DB_DX_BOBK_CETUS_NOR_MPP8_15	0x11122244
+
+/* GPPs
+MPP#	NAME			IN/OUT
+----------------------------------------------
+0	SPI_MOSI		(out)
+1	SPI_MISO		(in)
+2	SPI_SCK			(out)
+3	SPI_CS0n		(out)
+4	DEV_CSn[0]		(out) NF CS (Boot)
+5	SD_CMD			(in/out)
+6	SD_CLK			(out)
+7	SD_D[0]			(in/out)
+8	SD_D[1]			(in/out)
+9	SD_D[2]			(in/out)
+10	SD_D[3]			(in/out)
+11	UART1_RXD		(in)
+12	UART1_TXD		(out)
+13	INTERRUPT_OUTn		(out)
+14	I2C_SCL			(in/out)
+15	I2C_SDA			(in/out)
+
+16	DEV_Oen_NF_Ren		(out)
+17	DEV_CLK_OUT		(out) Test point
+18	GPIO[18]		(in/out) INT_in / SD_WP / VC2_GPP
+19	NF_RBn			(in)
+20	DEV_WEn[0]		(out)
+21	DEV_AD[0]		(in/out)
+22	DEV_AD[1]		(in/out)
+23	DEV_AD[2]		(in/out)
+24	DEV_AD[3]		(in/out)
+25	DEV_AD[4]		(in/out)
+26	DEV_AD[5]		(in/out)
+27	DEV_AD[6]		(in/out)
+28	DEV_AD[7]		(in/out)
+29	NF_CLE_DEV_A[0]		(out)
+30	NF_ALE_DEV_A[1]		(out)
+31	SLV_SMI_MDC		(in)
+32	SLV_SMI_MDIO		(in/out)
+
+*/
+#define DB_DX_BOBK_CETUS_GPP_OUT_ENA_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+					| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30))
+#define DB_DX_BOBK_CETUS_GPP_OUT_ENA_MID	(~(0))
+
+#define DB_DX_BOBK_CETUS_GPP_OUT_VAL_LOW	(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+					| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30)
+#define DB_DX_BOBK_CETUS_GPP_OUT_VAL_MID	0x0
+
+#define DB_DX_BOBK_CETUS_GPP_POL_LOW		0x0
+#define DB_DX_BOBK_CETUS_GPP_POL_MID		0x0
+
+/*************************************/
+/*   BOBK-CAELUM-DB-98DX4203-48G12XG    */
+/*************************************/
+#define DB_DX_BOBK_CAELUM_MPP0_7	0x22242222
+#define DB_DX_BOBK_CAELUM_MPP8_15	0x11122222
+#define DB_DX_BOBK_CAELUM_MPP16_23	0x44444044
+#define DB_DX_BOBK_CAELUM_MPP24_31	0x14444444
+#define DB_DX_BOBK_CAELUM_MPP32_39	0x00000001
+
+#define DB_DX_BOBK_CAELUM_NOR_MPP0_7	0x44444444
+#define DB_DX_BOBK_CAELUM_NOR_MPP8_15	0x11122244
+
+/* GPPs
+MPP#	NAME			IN/OUT
+----------------------------------------------
+0	SPI_MOSI		(out)
+1	SPI_MISO		(in)
+2	SPI_SCK			(out)
+3	SPI_CS0n		(out)
+4	DEV_CSn[0]		(out) NF CS (Boot)
+5	SD_CMD			(in/out)
+6	SD_CLK			(out)
+7	SD_D[0]			(in/out)
+8	SD_D[1]			(in/out)
+9	SD_D[2]			(in/out)
+10	SD_D[3]			(in/out)
+11	UART1_RXD		(in)
+12	UART1_TXD		(out)
+13	INTERRUPT_OUTn		(out)
+14	I2C_SCL			(in/out)
+15	I2C_SDA			(in/out)
+
+16	DEV_Oen_NF_Ren		(out)
+17	DEV_CLK_OUT		(out) Test point
+18	GPIO[18]		(in/out) INT_in / SD_WP / VC2_GPP
+19	NF_RBn			(in)
+20	DEV_WEn[0]		(out)
+21	DEV_AD[0]		(in/out)
+22	DEV_AD[1]		(in/out)
+23	DEV_AD[2]		(in/out)
+24	DEV_AD[3]		(in/out)
+25	DEV_AD[4]		(in/out)
+26	DEV_AD[5]		(in/out)
+27	DEV_AD[6]		(in/out)
+28	DEV_AD[7]		(in/out)
+29	NF_CLE_DEV_A[0]		(out)
+30	NF_ALE_DEV_A[1]		(out)
+31	SLV_SMI_MDC		(in)
+32	SLV_SMI_MDIO		(in/out)
+
+*/
+#define DB_DX_BOBK_CAELUM_GPP_OUT_ENA_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+					| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30))
+#define DB_DX_BOBK_CAELUM_GPP_OUT_ENA_MID	(~(0))
+
+#define DB_DX_BOBK_CAELUM_GPP_OUT_VAL_LOW	(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT12\
+					| BIT13 | BIT16 | BIT17 | BIT20 | BIT29  | BIT30)
+#define DB_DX_BOBK_CAELUM_GPP_OUT_VAL_MID	0x0
+
+#define DB_DX_BOBK_CAELUM_GPP_POL_LOW		0x0
+#define DB_DX_BOBK_CAELUM_GPP_POL_MID		0x0
+
+
+/************************************/
+/*   BOBK-LEWIS-RD-LWS-12XG-A    */
+/************************************/
+#define RD_DX_BOBK_LEWIS_MPP0_7	0x00042222 /* 0-3:SPI, 4:NF_CEn, 5:SFP_Data, 6:DIAG LED, 7:TWSI_SEL1 */
+#define RD_DX_BOBK_LEWIS_MPP8_15	0x11000000 /* 8:TWSI_SEL2,9:SFP_TX,10,TMP_INT,11:INIT_Done,12:MPP12,
+							13:USB_OC,14-15:I2C_[SCLK,SDA] */
+#define RD_DX_BOBK_LEWIS_MPP16_23	0x44444004 /* 16:NF_REn, 17:TWSI_SEL0, 18:NA, 19-23:NF_[Busy,WEn,IO[0,1,2]] */
+#define RD_DX_BOBK_LEWIS_MPP24_31	0x14444444 /* 24-30: NF_IO[3,4,5,6,7],NF_CLE,NF_ALE, 31: SMI_MST_MDC(SMI) */
+#define RD_DX_BOBK_LEWIS_MPP32_39	0x00000001 /* 32: SMI_MST_MDIO(SMI) */
+
+
+/* GPPs
+MPP#	NAME			IN/OUT
+----------------------------------------------
+0	SPI_SI			(in/out)
+1	SPI_SO			(in/out)
+2	SPI_SCK			(in/out)
+3	SPI_CS0n			(in/out)
+4	NF_CEn			(in/out) NAND Flash
+5	SFP_Data			(in)
+6	DIAG LED			(out)
+7	TWSI_SEL1		(out)
+8	TWSI_SEL2		(out)
+9	SFP_TX_DIS		(out)
+10	TMP_INT			(in)
+11	INIT_Done		(in)
+12	MPP12			(N/A)
+13	USB_OC			(in)
+14	I2C_SCLK			(out)
+15	I2C_SDA			(in/out)
+
+16	NF_REn			(in/out)NAND Flash
+17	TWSI_SEL0		(out)
+18	NA			(NA)
+19	NF_Busy			(in/out)NAND Flash
+20	NF_WEn			(in/out)NAND Flash
+21	NF_IO[0]			(in/out)NAND Flash
+22	NF_IO[1]			(in/out)NAND Flash
+23	NF_IO[2]			(in/out)NAND Flash
+24	NF_IO[3]			(in/out)NAND Flash
+25	NF_IO[4]			(in/out)NAND Flash
+26	NF_IO[5]			(in/out)NAND Flash
+27	NF_IO[6]			(in/out)NAND Flash
+28	NF_IO[7]			(in/out)NAND Flash
+29	NF_CLE			(in/out)NAND Flash
+30	NF_ALE			(in/out)NAND Flash
+31	SMI_MST_MDC		(out)
+32	SMI_MST_MDIO		(in/out)
+
+*/
+#define RD_DX_BOBK_LEWIS_GPP_OUT_ENA_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT7 | BIT8\
+					| BIT9 | BIT14 | BIT17 | BIT31))
+#define RD_DX_BOBK_LEWIS_GPP_OUT_ENA_MID	(~(0))
+
+#define RD_DX_BOBK_LEWIS_GPP_OUT_VAL_LOW	(~(BIT0 | BIT2 | BIT3 | BIT4 | BIT6 | BIT9\
+					| BIT14 | BIT17 | BIT31))
+#define RD_DX_BOBK_LEWIS_GPP_OUT_VAL_MID	0x0
+
+#define RD_DX_BOBK_LEWIS_GPP_POL_LOW		0x0
+#define RD_DX_BOBK_LEWIS_GPP_POL_MID		0x0
+
+/********************************************
 *		AlleyCat3 Boards
 *********************************************/
 /*******************************************************************************
@@ -424,8 +691,8 @@
 /*********************************/
 /*   RD_DX_2XXG_2XG_AC3 (MTL2)   */
 /*********************************/
-#define RD_MTL_2XXG_2XG_AC3_MPP0_7				RD_MTL_4XG_AC3_MPP0_7
-#define RD_MTL_2XXG_2XG_AC3_MPP8_15				RD_MTL_4XG_AC3_MPP8_15
+#define RD_MTL_2XXG_2XG_AC3_MPP0_7			RD_MTL_4XG_AC3_MPP0_7
+#define RD_MTL_2XXG_2XG_AC3_MPP8_15			RD_MTL_4XG_AC3_MPP8_15
 #define RD_MTL_2XXG_2XG_AC3_MPP16_23			RD_MTL_4XG_AC3_MPP16_23
 #define RD_MTL_2XXG_2XG_AC3_MPP24_31			RD_MTL_4XG_AC3_MPP24_31
 #define RD_MTL_2XXG_2XG_AC3_MPP32_39			RD_MTL_4XG_AC3_MPP32_39
@@ -434,8 +701,8 @@
 #define RD_MTL_2XXG_2XG_AC3_GPP_OUT_ENA_MID		RD_MTL_4XG_AC3_GPP_OUT_ENA_MID
 #define RD_MTL_2XXG_2XG_AC3_GPP_OUT_VAL_LOW		RD_MTL_4XG_AC3_GPP_OUT_VAL_LOW
 #define RD_MTL_2XXG_2XG_AC3_GPP_OUT_VAL_MID		RD_MTL_4XG_AC3_GPP_OUT_VAL_MID
-#define RD_MTL_2XXG_2XG_AC3_GPP_POL_LOW			RD_MTL_4XG_AC3_GPP_POL_LOW
-#define RD_MTL_2XXG_2XG_AC3_GPP_POL_MID			RD_MTL_4XG_AC3_GPP_POL_MID
+#define RD_MTL_2XXG_2XG_AC3_GPP_POL_LOW		RD_MTL_4XG_AC3_GPP_POL_LOW
+#define RD_MTL_2XXG_2XG_AC3_GPP_POL_MID		RD_MTL_4XG_AC3_GPP_POL_MID
 
 /**************************************/
 /*   DB-XC3-24G4G_2XG_AC3  (RD_MISL)  */
@@ -469,5 +736,56 @@
 #define RD_MTL_24G_AC3_GPP_POL_LOW			RD_MTL_4XG_AC3_GPP_POL_LOW
 #define RD_MTL_24G_AC3_GPP_POL_MID			RD_MTL_4XG_AC3_GPP_POL_MID
 
+/**********************************************************************************/
+/* ArmadaXP Boards : only for Linux usage (AXP family is shared with MSYS in LSP) */
+/**********************************************************************************/
+/********************/
+/* DB-78460-AMC     */
+/********************/
+
+#define DB_78X60_AMC_MPP0_7			0x11111111
+#define DB_78X60_AMC_MPP8_15			0x00001111
+#define DB_78X60_AMC_MPP16_23			0x00000000
+#define DB_78X60_AMC_MPP24_31			0x00000000
+#define DB_78X60_AMC_MPP32_39			0x11110000
+#define DB_78X60_AMC_MPP40_47			0x00004000
+#define DB_78X60_AMC_MPP48_55			0x00001113
+#define DB_78X60_AMC_MPP56_63			0x11111110
+#define DB_78X60_AMC_MPP64_67			0x00000111
+
+/* GPPs
+MPP#	NAME		IN/OUT
+----------------------------------------------
+16	MB_INT#		IN
+17	Phy1_INT#	IN
+18	Phy2_INT#	IN
+19	Brd_Led_0	IN (for next board)
+21	Brd_Led_1	OUT
+23	Brd_Led_2	OUT
+29	Brd_Led_3	OUT
+30	Brd_Led_4	OUT
+34	Dbg_JP0		IN
+35	Dbg_JP1		IN
+40	Dbg_JP2		IN
+41	Dbg_JP3		IN
+42	Dbg_JP4		IN
+53	7 Segment 0	OUT
+54	7 Segment 1	OUT
+55	7 Segment 2	OUT
+56	7 Segment 3	OUT
+*/
+
+#define DB_78X60_AMC_GPP_OUT_ENA_LOW		(~(BIT19 | BIT21 | BIT22 | BIT23 | BIT29 | BIT30))
+#define DB_78X60_AMC_GPP_OUT_ENA_MID		(~(BIT21 | BIT22 | BIT23 | BIT24))
+#define DB_78X60_AMC_GPP_OUT_ENA_HIGH		(~(0x0))
+
+#define DB_78X60_AMC_GPP_OUT_VAL_LOW		0x0
+#define DB_78X60_AMC_GPP_OUT_VAL_MID		0x0
+#define DB_78X60_AMC_GPP_OUT_VAL_HIGH		0x0
+
+#define DB_78X60_AMC_GPP_POL_LOW		0x0
+#define DB_78X60_AMC_GPP_POL_MID		0x0
+#define DB_78X60_AMC_GPP_POL_HIGH		0x0
+
 #endif /* __INCmvBoardEnvSpech */
 
diff --git a/board/mv_ebu/msys/msys_family/cpu/mvCpu.c b/board/mv_ebu/msys/msys_family/cpu/mvCpu.c
index 63cf76a..a7a143f 100644
--- a/board/mv_ebu/msys/msys_family/cpu/mvCpu.c
+++ b/board/mv_ebu/msys/msys_family/cpu/mvCpu.c
@@ -96,17 +96,42 @@
 {
 	MV_U32			idx;
 	MV_U32			freqMhz;
+	MV_U32			cpuClk[] = MV_CPU_CLK_TBL_AXP;
 	MV_CPUDDR_MODE	bc2ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BC2;
 	MV_CPUDDR_MODE	ac3ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_AC3;
+	MV_CPUDDR_MODE	bobkCetusClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CETUS;
+	MV_CPUDDR_MODE	bobkCaelumClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CAELUM;
 	MV_U16			family = mvCtrlDevFamilyIdGet(0);
-	MV_U32			sar2 = MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1));
+	MV_U32			sar2;
+
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID) {
+		idx = MSAR_CPU_CLK_IDX(MV_REG_READ(MPP_SAMPLE_AT_RESET(0)),
+				       MV_REG_READ(MPP_SAMPLE_AT_RESET(1)));
+		return cpuClk[idx] * 1000000;
+	}
+
+	sar2 = MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1));
 
 	idx = MSAR_CPU_DDR_CLK(0, sar2);
 	if (family == MV_BOBCAT2_DEV_ID)
 		freqMhz = bc2ClockRatioTbl[idx].cpuFreq * 1000000;
 	else if (family == MV_ALLEYCAT3_DEV_ID)
 		freqMhz = ac3ClockRatioTbl[idx].cpuFreq * 1000000;
-	else
+	else if (family == MV_BOBK_DEV_ID) {
+		switch (mvCtrlModelGet()) {
+		case MV_BOBK_CETUS_98DX4235_DEV_ID:
+		case MV_BOBK_LEWIS_98DX8212_DEV_ID:
+			/* LEWIS RD board's CPU freq setting is the same as CETUS board */
+			freqMhz = bobkCetusClockRatioTbl[idx].cpuFreq * 1000000;
+			break;
+		case MV_BOBK_CAELUM_98DX4203_DEV_ID:
+			freqMhz = bobkCaelumClockRatioTbl[idx].cpuFreq * 1000000;
+			break;
+		default:
+			mvOsPrintf("ERROR: Unknown DeviceID %d, CPU freq get failed\n", mvCtrlModelGet());
+			return 0xFFFFFFFF;
+		}
+	} else
 		return 0xFFFFFFFF;
 
 	return freqMhz;
@@ -134,6 +159,8 @@
 	MV_U32			freqMhz;
 	MV_CPUDDR_MODE	bc2ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BC2;
 	MV_CPUDDR_MODE	ac3ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_AC3;
+	MV_CPUDDR_MODE	bobkCetusClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CETUS;
+	MV_CPUDDR_MODE	bobkCaelumClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CAELUM;
 	MV_U16			family = mvCtrlDevFamilyIdGet(0);
 	MV_U32			sar2 = MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1));
 
@@ -142,7 +169,21 @@
 		freqMhz = bc2ClockRatioTbl[idx].ddrFreq * 1000000;
 	else if (family == MV_ALLEYCAT3_DEV_ID)
 		freqMhz = ac3ClockRatioTbl[idx].ddrFreq * 1000000;
-	else
+	else if (family == MV_BOBK_DEV_ID) {
+		switch (mvCtrlModelGet()) {
+		case MV_BOBK_CETUS_98DX4235_DEV_ID:
+		case MV_BOBK_LEWIS_98DX8212_DEV_ID:
+			/* LEWIS RD board's CPU freq setting is the same as CETUS board */
+			freqMhz = bobkCetusClockRatioTbl[idx].ddrFreq * 1000000;
+			break;
+		case MV_BOBK_CAELUM_98DX4203_DEV_ID:
+			freqMhz = bobkCaelumClockRatioTbl[idx].ddrFreq * 1000000;
+			break;
+		default:
+			mvOsPrintf("ERROR: Unknown DeviceID %d, DDR freq get failed\n", mvCtrlModelGet());
+			return 0xFFFFFFFF;
+		}
+	} else
 		return 0xFFFFFFFF;
 
 	return freqMhz;
@@ -170,20 +211,37 @@
 	MV_U32		freqMhz;
 	MV_CPUDDR_MODE	bc2ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BC2;
 	MV_CPUDDR_MODE	ac3ClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_AC3;
+	MV_CPUDDR_MODE	bobkCetusClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CETUS;
+	MV_CPUDDR_MODE	bobkCaelumClockRatioTbl[8] = MV_CPU_DDR_CLK_TBL_BOBK_CAELUM;
 	MV_U16		family = mvCtrlDevFamilyIdGet(0);
-	MV_U32		sar2 = MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1));
+	MV_U32		sar2;
+
+	if (family == MV_78460_DEV_ID)
+		return AXP_PLL_IN_CLK;
+
+	sar2 = MV_DFX_REG_READ(DFX_DEVICE_SAR_REG(1));
 
 	idx = MSAR_CPU_DDR_CLK(0, sar2);
-	switch (family) {
-	case MV_BOBCAT2_DEV_ID:
+	if (family == MV_BOBCAT2_DEV_ID)
 		freqMhz = bc2ClockRatioTbl[idx].pllClk * 1000000;
-		break;
-	case MV_ALLEYCAT3_DEV_ID:
+	else if (family == MV_ALLEYCAT3_DEV_ID)
 		freqMhz = ac3ClockRatioTbl[idx].pllClk * 1000000;
-		break;
-	default:
+	else if (family == MV_BOBK_DEV_ID) {
+		switch (mvCtrlModelGet()) {
+		case MV_BOBK_CETUS_98DX4235_DEV_ID:
+		case MV_BOBK_LEWIS_98DX8212_DEV_ID:
+			/* LEWIS RD board's CPU freq setting is the same as CETUS board */
+			freqMhz = bobkCetusClockRatioTbl[idx].pllClk * 1000000;
+			break;
+		case MV_BOBK_CAELUM_98DX4203_DEV_ID:
+			freqMhz = bobkCaelumClockRatioTbl[idx].pllClk * 1000000;
+			break;
+		default:
+			mvOsPrintf("ERROR: Unknown DeviceID %d, PLL freq get failed\n", mvCtrlModelGet());
+			return 0xFFFFFFFF;
+		}
+	} else
 		return 0xFFFFFFFF;
-	}
 
 	return freqMhz;
 }
@@ -200,6 +258,10 @@
 *******************************************************************************/
 MV_U32 mvCpuL2ClkGet(MV_VOID)
 {
+	MV_U32 idx;
+	MV_U32 freqMhz, l2FreqMhz;
+	MV_CPU_ARM_CLK_RATIO clockRatioTbl[] = MV_DDR_L2_CLK_RATIO_TBL_AXP;
+
 /*	MV_U32 idx;
 	MV_U32 freqMhz;
 	MV_CPUDDR_MODE clockRatioTbl[8] = MV_CPU_DDR_CLK_TBL;
@@ -207,7 +269,24 @@
 
 	idx = MSAR_CPU_DDR_CLK(0, sar2);
 	freqMhz = clockRatioTbl[idx].cpuFreq * 1000000; */
-	return 200000000;
+	if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID)
+		return 200000000;
+
+	idx = MSAR_DDR_L2_CLK_RATIO_IDX(MV_REG_READ(MPP_SAMPLE_AT_RESET(0)),
+					MV_REG_READ(MPP_SAMPLE_AT_RESET(1)));
+
+	if (clockRatioTbl[idx].vco2cpu != 0) {
+		freqMhz = mvCpuPclkGet() / 1000000;	/* CPU freq */
+		freqMhz *= clockRatioTbl[idx].vco2cpu;	/* VCO freq */
+		l2FreqMhz = freqMhz / clockRatioTbl[idx].vco2l2c;
+		/* round up to integer MHz */
+		if (((freqMhz % clockRatioTbl[idx].vco2l2c) * 10 / clockRatioTbl[idx].vco2l2c) >= 5)
+			l2FreqMhz++;
+
+		return l2FreqMhz * 1000000;
+	} else {
+		return (MV_U32)-1;
+	}
 }
 
 /*******************************************************************************
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvAddrDec.c b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvAddrDec.c
index a34dba4..711531f 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvAddrDec.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvAddrDec.c
@@ -91,7 +91,8 @@
 #endif
 
 /* Default Attributes array */
-MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
+MV_TARGET_ATTRIB mvTargetDefaultsArrayMsys[] = TARGETS_DEF_ARRAY;
+MV_TARGET_ATTRIB mvTargetDefaultsArrayAxp[] = TARGETS_DEF_ARRAY_AXP;
 
 /*******************************************************************************
 * mvCtrlAttribGet -
@@ -107,6 +108,13 @@
 *******************************************************************************/
 MV_STATUS mvCtrlAttribGet(MV_TARGET target, MV_TARGET_ATTRIB *targetAttrib)
 {
+	MV_TARGET_ATTRIB *mvTargetDefaultsArray;
+
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		mvTargetDefaultsArray = mvTargetDefaultsArrayAxp;
+	else
+		mvTargetDefaultsArray = mvTargetDefaultsArrayMsys;
+
 	targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
 	targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
 
@@ -115,6 +123,13 @@
 /*******************************************************************************/
 MV_STATUS mvCtrlAttribSet(MV_TARGET target, MV_TARGET_ATTRIB *targetAttrib)
 {
+	MV_TARGET_ATTRIB *mvTargetDefaultsArray;
+
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		mvTargetDefaultsArray = mvTargetDefaultsArrayAxp;
+	else
+		mvTargetDefaultsArray = mvTargetDefaultsArrayMsys;
+
 	mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib  = targetAttrib->attrib;
 	mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId= targetAttrib->targetId;
 
@@ -137,6 +152,13 @@
 {
 	MV_TARGET target;
 	MV_TARGET x;
+	MV_TARGET_ATTRIB *mvTargetDefaultsArray;
+
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		mvTargetDefaultsArray = mvTargetDefaultsArrayAxp;
+	else
+		mvTargetDefaultsArray = mvTargetDefaultsArrayMsys;
+
 	for (target = SDRAM_CS0; target < MAX_TARGETS; target++) {
 		x = MV_CHANGE_BOOT_CS(target);
 		if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
@@ -165,6 +187,13 @@
 {
 	MV_TARGET target;
 	MV_TARGET x;
+	MV_TARGET_ATTRIB *mvTargetDefaultsArray;
+
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		mvTargetDefaultsArray = mvTargetDefaultsArrayAxp;
+	else
+		mvTargetDefaultsArray = mvTargetDefaultsArrayMsys;
+
 	for (target = SDRAM_CS0; target < MAX_TARGETS; target++) {
 		x = MV_CHANGE_BOOT_CS(target);
 		if ((mvTargetDefaultsArray[x].attrib == unitWinInfo->attrib) &&
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
index be1616d..17cec27 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
@@ -89,6 +89,8 @@
 #include "ddr2_3/mvDramIfRegs.h"
 
 #include "twsi/mvTwsiSpec.h"
+#include "device/mvDevice.h"
+#include "mvDeviceId.h"
 
 /* defines  */
 #undef MV_DEBUG
@@ -101,22 +103,62 @@
 /* MSYS family linear id */
 #define MV_MSYS_BC2_INDEX		0
 #define MV_MSYS_AC3_INDEX		1
-#define MV_MSYS_INDEX_MAX		2
+#define MV_78460_INDEX			2
+#define MV_MSYS_BOBK_INDEX			3
+#define MV_MSYS_AXP_INDEX_MAX		4
 
-MV_UNIT_ID mvCtrlSocUnitNums[MAX_UNITS_ID][MV_MSYS_INDEX_MAX] = {
-/*			    BC2		AC3 */
-/* DRAM_UNIT_ID         */ { 1,		1, },
-/* PEX_UNIT_ID          */ { 1,		1, },
-/* ETH_GIG_UNIT_ID      */ { 2,		2, },
-/* XOR_UNIT_ID          */ { 1,		1, },
-/* UART_UNIT_ID         */ { 2,		2, },
-/* SPI_UNIT_ID          */ { 2,		1, },
-/* SDIO_UNIT_ID         */ { 1,		1, },
-/* I2C_UNIT_ID          */ { 2,		2, },
-/* USB_UNIT_ID          */ { 0,		1, },
-/* USB3_UNIT_ID         */ { 0,		0, },
+MV_UNIT_ID mvCtrlSocUnitNums[MAX_UNITS_ID][MV_MSYS_AXP_INDEX_MAX] = {
+/*			     BC2	AC3		78460		BOBK*/
+/* DRAM_UNIT_ID		*/ { 1,		1,		1,		1,},
+/* PEX_UNIT_ID		*/ { 1,		1,		4,		1,},
+/* ETH_GIG_UNIT_ID	*/ { 2,		2,		4,		2,},
+/* XOR_UNIT_ID		*/ { 1,		1,		4,		1,},
+/* UART_UNIT_ID		*/ { 2,		2,		4,		2,},
+/* SPI_UNIT_ID		*/ { 1,		1,		2,		1,},
+/* SDIO_UNIT_ID		*/ { 1,		1,		1,		1,},
+/* I2C_UNIT_ID		*/ { 2,		2,		2,		2,},
+/* USB_UNIT_ID		*/ { 0,		1,		3,		1,},
+/* USB3_UNIT_ID		*/ { 0,		0,		0,		0,},
+/* NAND_UNIT_ID		*/ { 1,		1,		1,		1,},
+/* DEVBUS_UNIT_ID	*/ { 0,		0,		0,		0,},
+/* IDMA_UNIT_ID		*/ { 0,		0,		4,		0,},
+/* SATA_UNIT_ID		*/ { 0,		0,		2,		0,},
+/* TDM_UNIT_ID		*/ { 0,		0,		1,		0,},
+/* CESA_UNIT_ID		*/ { 0,		0,		2,		0,},
+/* AUDIO_UNIT_ID	*/ { 0,		0,		0,		0,},
+/* TS_UNIT_ID		*/ { 0,		0,		0,		0,},
+/* XPON_UNIT_ID		*/ { 0,		0,		0,		0,},
+/* BM_UNIT_ID		*/ { 0,		0,		1,		0,},
+/* PNC_UNIT_ID		*/ { 0,		0,		1,		0,},
 };
 
+MV_U32  mvDev2CpuMapTable[20][2] = {
+/*	Dev ID			cores#   */
+	{MV_BOBCAT2_DEV_ID,		2},
+	{MV_BOBK_CETUS_98DX4235_DEV_ID,		2},
+	{MV_BOBK_CAELUM_98DX4203_DEV_ID,	2},
+	{MV_BOBK_LEWIS_98DX8212_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX3336_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX3335_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX3334_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX3333_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX1233_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DX1235_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DX3236_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DX3235_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DX3234_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DX3233_DEV_ID,	1},
+	{MV_ALLEYCAT3_98DXH333_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX1333_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX1335_DEV_ID,	2},
+	{MV_ALLEYCAT3_98DX1336_DEV_ID,	2},
+	{MV_78460_DEV_ID,		4},
+	{MV_MAX_DEV_ID,			0},
+};
+
+
+
+
 static MV_U32 mvCtrlDevIdIndexGet(MV_U32 devId)
 {
 	MV_U32 index;
@@ -128,12 +170,36 @@
 	case MV_ALLEYCAT3_DEV_ID:
 		index = MV_MSYS_AC3_INDEX;
 		break;
+	case MV_78460_DEV_ID:
+		index = MV_78460_INDEX;
+		break;
+	case MV_BOBK_DEV_ID:
+		index = MV_MSYS_BOBK_INDEX;
+		break;
 	default:
 		index = MV_MSYS_AC3_INDEX;
 	}
 
 	return index;
 }
+/******************************************************************************
+* mvCtrlIsUsbSerDesConnected
+*
+* DESCRIPTION: check if SerDes lane is connected to USB3 host.
+*
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:return true if SerDes lane is connected to USB3 host, false otherwise.
+*
+*
+*******************************************************************************/
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort)
+{
+	return MV_FALSE;/*return false because in msys there is no usb3*/
+}
 
 MV_U32 mvCtrlSocUnitInfoNumGet(MV_UNIT_ID unit)
 {
@@ -147,11 +213,34 @@
 	devIdIndex = mvCtrlDevIdIndexGet(mvCtrlModelGet());
 	return mvCtrlSocUnitNums[unit][devIdIndex];
 }
-
-MV_U32 mvCtrlGetCpuNum(MV_VOID)
+/******************************************************************************
+* mvCtrlGetCpuNum
+*
+* DESCRIPTION: Get the number of CPU cores
+*
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:cpu cores number or 0 if the deviceID not found in device IDs table
+*
+*
+*******************************************************************************/
+MV_U32  mvCtrlGetCpuNum(MV_VOID)
 {
+	MV_U32	table_index = 0;
+	MV_U32	deviceId = mvCtrlModelGet();
+
+	while (mvDev2CpuMapTable[table_index][0] != MV_MAX_DEV_ID) {
+		if (deviceId == mvDev2CpuMapTable[table_index][0])
+			return mvDev2CpuMapTable[table_index][1];
+		table_index++;
+	}
+	mvOsPrintf("%s: Error: DevID (%#X) is not found in CPU cores count per device table!\n", __func__, deviceId);
 	return 0;
 }
+
 MV_BOOL mvCtrlIsValidSatR(MV_VOID)
 {
 	return MV_TRUE;
@@ -248,7 +337,9 @@
 	MV_U32 mppGroup;
 	MV_U32 mppVal;
 	MV_U32 i, gppMask;
-
+	MV_U32 maxGroup = mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID ?
+		MV_MPP_MAX_GROUP_AXP : MV_MPP_MAX_GROUP;
+	MV_STATUS status;
 
 	/* Disable MBus Error Propagation */
 	MV_REG_BIT_RESET(SOC_COHERENCY_FABRIC_CTRL_REG, BIT8);
@@ -260,23 +351,23 @@
 	mvBoardMppModulesScan();
 
 	/* Read MPP config values from board level and write MPP options to HW */
-	for (mppGroup = 0; mppGroup < MV_MPP_MAX_GROUP; mppGroup++) {
+	for (mppGroup = 0; mppGroup < maxGroup; mppGroup++) {
 		mppVal = mvBoardMppGet(mppGroup);	/* get pre-defined values */
 		MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
 	}
 
 	/* disable all GPIO interrupts */
-	for (i = 0; i < MV_GPP_MAX_GROUP; i++) {
+	for (i = 0; i < maxGroup; i++) {
 		MV_REG_WRITE(GPP_INT_MASK_REG(i), 0x0);
 		MV_REG_WRITE(GPP_INT_LVL_REG(i), 0x0);
 	}
 
 	/* clear all int */
-	for (i = 0; i < MV_GPP_MAX_GROUP; i++)
+	for (i = 0; i < maxGroup; i++)
 		MV_REG_WRITE(GPP_INT_CAUSE_REG(i), 0x0);
 
 	/* Set gpp interrupts as needed */
-	for (i = 0; i < MV_GPP_MAX_GROUP; i++) {
+	for (i = 0; i < maxGroup; i++) {
 		gppMask = mvBoardGpioIntMaskGet(i);
 		mvGppTypeSet(i, gppMask , (MV_GPP_IN & gppMask));
 		mvGppPolaritySet(i, gppMask , (MV_GPP_IN_INVERT & gppMask));
@@ -286,15 +377,22 @@
 	mvBoardOtherModulesScan();
 
 	/* Update interfaces configuration based on above scan */
-	if (MV_OK != mvCtrlSerdesPhyConfig())
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		status = mvCtrlSerdesPhyConfigAxp();
+	else
+		status = mvCtrlSerdesPhyConfig();
+
+	if (status != MV_OK)
 		mvOsPrintf("mvCtrlEnvInit: Can't init some or all SERDES lanes\n");
 
-	mvCtrlDevBusInit();
+	if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID) {
+		mvCtrlDevBusInit();
 
 #ifdef ERRATA_GL_5956802
 		/* SW WA for ERRATA 5956802 - disable the external i2c debugger access */
 		MV_REG_BIT_RESET(TWSI_CONFIG_DEBUG_REG, TWSI_DEBUG_SLAVE_PORT0_EN);
 #endif
+	}
 
 	mvOsDelay(100);
 
@@ -318,9 +416,14 @@
 *******************************************************************************/
 MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
 {
-	MV_U32 ret;
+	MV_U32 ret, maxGroup;
 
-	if (mppGroup >= MV_MPP_MAX_GROUP)
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		maxGroup = MV_MPP_MAX_GROUP_AXP;
+	else
+		maxGroup = MV_MPP_MAX_GROUP;
+
+	if (mppGroup >= maxGroup)
 		mppGroup = 0;
 
 	ret = MPP_CONTROL_REG(mppGroup);
@@ -348,6 +451,8 @@
 *******************************************************************************/
 MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
 {
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return MV_PEX_MAX_IF;
 	return mvCtrlSocUnitInfoNumGet(PEX_UNIT_ID);
 }
 
@@ -437,6 +542,8 @@
 *******************************************************************************/
 MV_U8 mvCtrlEthMaxCPUsGet(MV_VOID)
 {
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return mvCtrlEthMaxPortGet();
 	return 2;
 }
 
@@ -558,6 +665,64 @@
 #endif
 
 /*******************************************************************************
+* mvCtrlModelGetAxp - Get Marvell controller device model (Id) for AXP devices
+*
+* DESCRIPTION:
+*       This function returns 16bit describing the device model (ID) as defined
+*       in PCI Device and Vendor ID configuration register offset 0x0.
+*
+* INPUT:
+*       None.
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       16bit desscribing Marvell controller ID
+*
+*******************************************************************************/
+MV_U16 mvCtrlModelGetAxp(MV_VOID)
+{
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	MV_U32 pexPower;
+#endif
+	MV_U32 devId;
+	MV_U16 model = 0;
+	MV_U32 reg, reg2;
+	static MV_U16 modelId = 0xffff;
+
+	if (modelId != 0xffff)
+		return modelId;
+
+	/* if PEX0 clocks are disabled - enabled it to read */
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	/* Check pex power state */
+	pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID, 0);
+	if (pexPower == MV_FALSE)
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
+#endif
+	reg = MV_REG_READ(POWER_MNG_CTRL_REG);
+	if ((reg & AXP_PMC_PEXSTOPCLOCK_MASK(0)) == AXP_PMC_PEXSTOPCLOCK_STOP(0)) {
+		reg2 = ((reg & ~AXP_PMC_PEXSTOPCLOCK_MASK(0)) | AXP_PMC_PEXSTOPCLOCK_EN(0));
+		MV_REG_WRITE(POWER_MNG_CTRL_REG, reg2);
+	}
+
+	devId = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0, PEX_DEVICE_AND_VENDOR_ID));
+
+	/* Reset the original value of the PEX0 clock */
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	/* Return to power off state */
+	if (pexPower == MV_FALSE)
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
+#endif
+
+	model = (MV_U16) ((devId >> 16) & 0xFFFF);
+
+	modelId = model;
+	return model;
+}
+
+/*******************************************************************************
 * mvCtrlModelGet - Get Marvell controller device model (Id)
 *
 * DESCRIPTION:
@@ -578,11 +743,15 @@
 {
 	MV_U32	ctrlId = MV_REG_READ(DEV_ID_REG);
 
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return mvCtrlModelGetAxp();
+
 	ctrlId = (ctrlId & (DEVICE_ID_MASK)) >> DEVICE_ID_OFFS;
 
 	switch (ctrlId & ~DEVICE_FLAVOR_MASK) {
 	case MV_BOBCAT2_DEV_ID:
 	case MV_ALLEYCAT3_DEV_ID:
+	case MV_BOBK_DEV_ID:
 		return ctrlId;
 	default:
 		mvOsPrintf("%s: Error: Failed to obtain Controller Device ID\n", __func__);
@@ -609,8 +778,30 @@
 *******************************************************************************/
 MV_U8 mvCtrlRevGet(MV_VOID)
 {
-	MV_U32 value = MV_DFX_REG_READ(DEV_REV_ID_REG);
-	return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	MV_U32 pexPower;
+#endif
+	MV_U32 value;
+	MV_U8 revNum;
+
+	if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID) {
+		value = MV_DFX_REG_READ(DEV_REV_ID_REG);
+		return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
+	}
+
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	/* Check pex power state */
+	pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID, 0);
+	if (pexPower == MV_FALSE)
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
+#endif
+	revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0, PCI_CLASS_CODE_AND_REVISION_ID));
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	/* Return to power off state */
+	if (pexPower == MV_FALSE)
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
+#endif
+	return (revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
 }
 
 /*******************************************************************************
@@ -631,7 +822,11 @@
 *******************************************************************************/
 MV_STATUS mvCtrlNameGet(char *pNameBuff)
 {
-	mvOsSPrintf(pNameBuff, "%s", SOC_NAME_PREFIX);
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		mvOsSPrintf(pNameBuff, "%s", "");
+	else
+		mvOsSPrintf(pNameBuff, "%s", SOC_NAME_PREFIX);
+
 	return MV_OK;
 }
 
@@ -701,7 +896,26 @@
 			mvOsSPrintf(pNameBuff, " Rev %s", revArrayAC3[revId]);
 			return;
 		}
+	} else if (ctrlFamily == MV_78460_DEV_ID) {
+		switch (mvCtrlModelRevGet()) {
+		case MV_78460_A0_ID:
+			mvOsSPrintf(pNameBuff, "%s", MV_78460_A0_NAME);
+			return;
+		case MV_78460_B0_ID:
+			mvOsSPrintf(pNameBuff, "%s", MV_78460_B0_NAME);
+			return;
+		default:
+			break;
+		}
+	} else if (ctrlFamily == MV_BOBK_DEV_ID) {
 
+		char *revArrayBOBK[] = MV_BOBK_ID_ARRAY;
+
+		switch (revId) {
+		case MV_BOBK_A0_ID:
+			mvOsSPrintf(pNameBuff, " Rev %s", revArrayBOBK[revId]);
+			return;
+		}
 	} else
 		mvOsPrintf("%s: Error: Wrong controller model %#x\n", __func__, ctrlFamily);
 
@@ -751,17 +965,22 @@
 {
 	MV_U32	boardId = mvBoardIdGet();
 
-	if ((boardId >= BC2_CUSTOMER_BOARD_ID_BASE) && (boardId < BC2_MARVELL_MAX_BOARD_ID))
+	if (boardId == DB_78X60_AMC_ID)
+		return MV_78460_DEV_ID;
+	else if ((boardId >= BC2_CUSTOMER_BOARD_ID_BASE) && (boardId < BC2_MARVELL_MAX_BOARD_ID))
 		return MV_BOBCAT2_DEV_ID;
 	else if ((boardId >= AC3_CUSTOMER_BOARD_ID_BASE) && (boardId < AC3_MARVELL_MAX_BOARD_ID))
 		return MV_ALLEYCAT3_DEV_ID;
+	else if ((boardId >= BOBK_CUSTOMER_BOARD_ID_BASE) && (boardId < BOBK_MARVELL_MAX_BOARD_ID))
+		return MV_BOBK_DEV_ID;
 	else {
 		mvOsPrintf("%s: ERR. Invalid Board ID (%d) ,Using BC2 as default family\n", __func__, boardId);
 		return MV_BOBCAT2_DEV_ID;
 	}
 }
 
-static const char *cntrlName[] = TARGETS_NAME_ARRAY;
+static const char * const cntrlNameMsys[] = TARGETS_NAME_ARRAY;
+static const char * const cntrlNameAxp[] = TARGETS_NAME_ARRAY_AXP;
 
 /*******************************************************************************
 * mvCtrlTargetNameGet - Get Marvell controller target name
@@ -783,7 +1002,10 @@
 	if (target >= MAX_TARGETS)
 		return "target unknown";
 
-	return cntrlName[target];
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return cntrlNameAxp[target];
+	else
+		return cntrlNameMsys[target];
 }
 
 #if defined(MV_INCLUDE_PEX)
@@ -1161,8 +1383,10 @@
 
 	if (mvCtrlDevFamilyIdGet(0) == MV_BOBCAT2_DEV_ID)
 		satr = MSAR_BC2_BOOT_MODE(satr, 0);
-	else
+	else if (mvCtrlDevFamilyIdGet(0) == MV_ALLEYCAT3_DEV_ID)
 		satr = MSAR_AC3_BOOT_MODE(satr, 0);
+	else
+		satr = MSAR_BOBK_BOOT_MODE(satr, 0);
 
 	if (satr == SAR1_BOOT_FROM_NOR)
 		return MV_TRUE;
@@ -1192,8 +1416,10 @@
 
 	if (mvCtrlDevFamilyIdGet(0) == MV_BOBCAT2_DEV_ID)
 		satr = MSAR_BC2_BOOT_MODE(satr, 0);
-	else
+	else if (mvCtrlDevFamilyIdGet(0) == MV_ALLEYCAT3_DEV_ID)
 		satr = MSAR_AC3_BOOT_MODE(satr, 0);
+	else
+		satr = MSAR_BOBK_BOOT_MODE(satr, 0);
 
 	if (satr == SAR1_BOOT_FROM_SPI)
 		return MV_TRUE;
@@ -1223,8 +1449,10 @@
 
 	if (mvCtrlDevFamilyIdGet(0) == MV_BOBCAT2_DEV_ID)
 		satr = MSAR_BC2_BOOT_MODE(satr, 0);
-	else
+	else if (mvCtrlDevFamilyIdGet(0) == MV_ALLEYCAT3_DEV_ID)
 		satr = MSAR_AC3_BOOT_MODE(satr, 0);
+	else
+		satr = MSAR_BOBK_BOOT_MODE(satr, 0);
 
 	if (satr == SAR1_BOOT_FROM_NAND)
 		return MV_TRUE;
@@ -1266,33 +1494,84 @@
 *******************************************************************************/
 MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
 {
+	MV_U32 mask;
 
 	switch (unitId) {
 #if defined(MV_INCLUDE_PEX)
 	case PEX_UNIT_ID:
-		if (enable == MV_FALSE)
-			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+			mask = AXP_PMC_PEXSTOPCLOCK_MASK(index);
 		else
-			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
+			mask = PMC_PEXSTOPCLOCK_MASK;
+
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, mask);
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, mask);
 
 		break;
 #endif
 #if defined(MV_INCLUDE_GIG_ETH)
 	case ETH_GIG_UNIT_ID:
-		if (enable == MV_FALSE)
-			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+			mask = AXP_PMC_GESTOPCLOCK_MASK(index);
 		else
-			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
+			mask = PMC_GESTOPCLOCK_MASK(index);
+
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, mask);
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, mask);
 
 		break;
 #endif
 #if defined(MV_INCLUDE_SDIO)
 	case SDIO_UNIT_ID:
-		if (enable == MV_FALSE)
-			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+			mask = AXP_PMC_SDIOSTOPCLOCK_MASK;
 		else
-			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
+			mask = PMC_SDIOSTOPCLOCK_MASK;
 
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, mask);
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, mask);
+
+		break;
+#endif
+#if defined(MV_INCLUDE_CESA)
+	case CESA_UNIT_ID:
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_CESASTOPCLOCK_MASK);
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_CESASTOPCLOCK_MASK);
+
+		break;
+#endif
+#if defined(MV_INCLUDE_USB)
+	case USB_UNIT_ID:
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_USBSTOPCLOCK_MASK(index));
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_USBSTOPCLOCK_MASK(index));
+
+		break;
+#endif
+#if defined(MV_INCLUDE_INTEG_SATA)
+	case SATA_UNIT_ID:
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_SATASTOPCLOCK_MASK(index));
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_SATASTOPCLOCK_MASK(index));
+
+		break;
+#endif
+#if defined(MV_INCLUDE_TDM)
+	case TDM_UNIT_ID:
+		if (enable == MV_FALSE)
+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_TDMSTOPCLOCK_MASK);
+		else
+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_TDMSTOPCLOCK_MASK);
 		break;
 #endif
 	default:
@@ -1315,13 +1594,22 @@
 {
 #if defined(MV_INCLUDE_PEX) || defined(MV_INCLUDE_PEX) || defined(MV_INCLUDE_GIG_ETH) || defined(MV_INCLUDE_SDIO)
 	MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
+	MV_U32 mask, stop;
 #endif
 	MV_BOOL state = MV_TRUE;
 
 	switch (unitId) {
 #if defined(MV_INCLUDE_PEX)
 	case PEX_UNIT_ID:
-		if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID) {
+			mask = AXP_PMC_PEXSTOPCLOCK_MASK(index);
+			stop = AXP_PMC_PEXSTOPCLOCK_STOP(index);
+		} else {
+			mask = PMC_PEXSTOPCLOCK_MASK;
+			stop = PMC_PEXSTOPCLOCK_STOP;
+		}
+
+		if ((reg & mask) == stop)
 			state = MV_FALSE;
 		else
 			state = MV_TRUE;
@@ -1329,7 +1617,15 @@
 #endif
 #if defined(MV_INCLUDE_GIG_ETH)
 	case ETH_GIG_UNIT_ID:
-		if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID) {
+			mask = AXP_PMC_GESTOPCLOCK_MASK(index);
+			stop = AXP_PMC_GESTOPCLOCK_STOP(index);
+		} else {
+			mask = PMC_GESTOPCLOCK_MASK(index);
+			stop = PMC_GESTOPCLOCK_STOP(index);
+		}
+
+		if ((reg & mask) == stop)
 			state = MV_FALSE;
 		else
 			state = MV_TRUE;
@@ -1337,7 +1633,49 @@
 #endif
 #if defined(MV_INCLUDE_SDIO)
 	case SDIO_UNIT_ID:
-		if ((reg & PMC_SDIOSTOPCLOCK_MASK) == PMC_SDIOSTOPCLOCK_STOP)
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID) {
+			mask = AXP_PMC_SDIOSTOPCLOCK_MASK;
+			stop = AXP_PMC_SDIOSTOPCLOCK_STOP;
+		} else {
+			mask = PMC_SDIOSTOPCLOCK_MASK;
+			stop = PMC_SDIOSTOPCLOCK_STOP;
+		}
+
+		if ((reg & mask) == stop)
+			state = MV_FALSE;
+		else
+			state = MV_TRUE;
+		break;
+#endif
+#if defined(MV_INCLUDE_CESA)
+	case CESA_UNIT_ID:
+		if ((reg & AXP_PMC_CESASTOPCLOCK_MASK) == AXP_PMC_CESASTOPCLOCK_STOP)
+			state = MV_FALSE;
+		else
+			state = MV_TRUE;
+		break;
+#endif
+#if defined(MV_INCLUDE_USB)
+	case USB_UNIT_ID:
+		if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID)
+			state = MV_TRUE;
+		else if ((reg & AXP_PMC_USBSTOPCLOCK_MASK(index)) == AXP_PMC_USBSTOPCLOCK_STOP(index))
+			state = MV_FALSE;
+		else
+			state = MV_TRUE;
+		break;
+#endif
+#if defined(MV_INCLUDE_SATA)
+	case SATA_UNIT_ID:
+		if ((reg & AXP_PMC_SATASTOPCLOCK_MASK(index)) == AXP_PMC_SATASTOPCLOCK_STOP(index))
+			state = MV_FALSE;
+		else
+			state = MV_TRUE;
+		break;
+#endif
+#if defined(MV_INCLUDE_TDM)
+	case TDM_UNIT_ID:
+		if ((reg & AXP_PMC_TDMSTOPCLOCK_MASK) == AXP_PMC_TDMSTOPCLOCK_STOP)
 			state = MV_FALSE;
 		else
 			state = MV_TRUE;
@@ -1366,9 +1704,16 @@
 MV_U32 mvCtrlDDRBudWidth(MV_VOID)
 {
 	MV_U32 reg;
-	reg = MV_REG_READ(REG_SDRAM_CONFIG_ADDR);
 
-	return (reg & (1 << REG_SDRAM_CONFIG_DDR_BUS_OFFS)) ? 32 : 16;
+	reg = MV_REG_READ(REG_SDRAM_CONFIG_ADDR);
+	reg = reg & (1 << REG_SDRAM_CONFIG_DDR_BUS_OFFS);
+
+	/* Bobcat2 and BobK have 64/16 DDR Bus width */
+	if (mvCtrlDevFamilyIdGet(0) == MV_BOBCAT2_DEV_ID || mvCtrlDevFamilyIdGet(0) == MV_BOBK_DEV_ID)
+		return reg ? 64 : 32;
+	else	/* Alley-Cat3 have 32/16 DDR Bus width */
+		return reg ? 32 : 16;
+
 }
 MV_BOOL mvCtrlDDRThruXbar(MV_VOID)
 {
@@ -1386,6 +1731,166 @@
 	return (reg & (0x1 << REG_SDRAM_CONFIG_ECC_OFFS)) ? MV_TRUE : MV_FALSE;
 }
 
+static const MV_U8 serdesCfg[][8] = SERDES_CFG_AXP;
+
+/*******************************************************************************
+* mvCtrlSerdesPhyConfigAxp
+*
+* DESCRIPTION:
+*	Configure Serdes MUX and init PHYs connected to SERDES lines for AXP.
+*
+* INPUT:
+*	None.
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*	Status
+*
+*******************************************************************************/
+MV_STATUS mvCtrlSerdesPhyConfigAxp(MV_VOID)
+{
+	MV_U32		socCtrlReg, RegX4, serdesLine0_7;
+	MV_U32		serdesLineCfg;
+	MV_U8		serdesLineNum;
+	MV_U8		pexIf;
+	MV_U8		pexUnit;
+	MV_STATUS	status = MV_OK;
+	MV_U32		pexIfNum = mvCtrlPexMaxIfGet();
+	MV_U8		maxSerdesLines = 16;	/* Valid for MV_78460_DEV_ID */
+	MV_BOARD_PEX_INFO	*boardPexInfo = mvBoardPexInfoGet();
+
+	/* This is a mapping of the final power management clock
+	 * gating control register value @ 0x18220
+	 */
+	MV_U32	powermngmntctrlregmap = 0x0;
+	MV_U32	tmpcounter = 0;
+
+	/* Check if no SERDESs available - FPGA */
+	if (maxSerdesLines == 0)
+		return MV_OK;
+
+	memset(boardPexInfo, 0, sizeof(MV_BOARD_PEX_INFO));
+	socCtrlReg = MV_REG_READ(SOC_CTRL_REG);
+	RegX4 = MV_REG_READ(GEN_PURP_RES_2_REG);
+	boardPexInfo->pexUnitCfg[0].pexCfg = ((RegX4 & 0x0F) == 0x0F) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+	boardPexInfo->pexUnitCfg[1].pexCfg = ((RegX4 & 0x0F0) == 0x0F0) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+	boardPexInfo->pexUnitCfg[2].pexCfg = ((RegX4 & 0x0F00) == 0x0F00) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+	boardPexInfo->pexUnitCfg[3].pexCfg = ((RegX4 & 0x0F000) == 0x0F000) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+
+	serdesLine0_7 = MV_REG_READ(SERDES_LINE_MUX_REG_0_7);
+	/* Prepare PHY parameters for each step according to  MUX selection */
+	for (pexIf = 0; pexIf < pexIfNum; pexIf++) {
+		/* For each serdes lane */
+		pexUnit = (pexIf < 9) ? (pexIf >> 2) : 3;
+		if ((socCtrlReg & (1 << pexUnit)) == 0) {
+			boardPexInfo->pexUnitCfg[pexUnit].pexCfg = PEX_BUS_DISABLED;
+			continue;
+		}
+		if (pexIf < 8) {
+			serdesLineCfg = (serdesLine0_7 >> (pexIf << 2)) & 0xF;
+			if (serdesLineCfg != serdesCfg[pexIf][SERDES_UNIT_PEX])
+				continue;
+		}
+		boardPexInfo->pexMapping[boardPexInfo->boardPexIfNum] = pexIf;
+		boardPexInfo->boardPexIfNum++;
+		boardPexInfo->pexUnitCfg[pexUnit].pexLaneStat[pexIf] = 0x1;
+		powermngmntctrlregmap = powermngmntctrlregmap | (0x1 << (pexIf + 5));
+		if (pexIf < 8) {
+			if (boardPexInfo->pexUnitCfg[pexUnit].pexCfg == PEX_BUS_MODE_X4) {
+				powermngmntctrlregmap |= (0xf << (pexIf + 5));
+				pexIf += 3;
+			} else
+				powermngmntctrlregmap |= (0x1 << (pexIf + 5));
+		} else
+			powermngmntctrlregmap |= (0x1 << (18 + pexIf));
+	}
+
+	for (serdesLineNum = 0; serdesLineNum < 8; serdesLineNum++) {
+		serdesLineCfg = (serdesLine0_7 >> (serdesLineNum << 2)) & 0xF;
+		if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SATA]) {
+			if ((serdesLineNum == 4) || (serdesLineNum == 6))
+				powermngmntctrlregmap |= AXP_PMC_SATASTOPCLOCK_MASK(0);
+			else if (serdesLineNum == 5)
+				powermngmntctrlregmap |= AXP_PMC_SATASTOPCLOCK_MASK(1);
+			else
+				goto err_cfg;
+
+		} else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII0])
+				powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(0);
+			else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII1])
+				powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(1);
+			else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII2])
+				powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(2);
+			else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII3])
+				powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(3);
+			else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_QSGMII])
+				powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(0) |
+							 AXP_PMC_GESTOPCLOCK_MASK(1) |
+							 AXP_PMC_GESTOPCLOCK_MASK(2) |
+							 AXP_PMC_GESTOPCLOCK_MASK(3);
+	}
+
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+	/* Enabling port GE0 always since we need SMI 0 to access other PHYs*/
+	powermngmntctrlregmap = powermngmntctrlregmap | BIT4;
+	/* Check if GE1 is not enabled via MPPs and not Serdes - if yes you have to enable the clock*/
+		if (MV_TRUE == mvBoardIsGbEPortConnected(1))
+			powermngmntctrlregmap = powermngmntctrlregmap | AXP_PMC_GESTOPCLOCK_MASK(1);
+
+	/* Hard core enable DDR, USB, SDIO, LCD, XOR, IDMA, CESA cause we don't support this at this momemt*/
+	powermngmntctrlregmap = powermngmntctrlregmap | (BIT0  | BIT13 | (0x1FF<<16) |
+				BIT24 | BIT25 | BIT28 | BIT31);
+	DB(mvOsPrintf("%s:Shutting down unused interfaces:\n", __func__));
+	/* Now report everything to the screen*/
+	if (!(powermngmntctrlregmap & AXP_PMC_SATASTOPCLOCK_MASK(0))) {
+		DB(mvOsPrintf("%s:       SATA0\n", __func__));
+		mvCtrlPwrClckSet(SATA_UNIT_ID, 0, MV_FALSE);
+	}
+	if (!(powermngmntctrlregmap & AXP_PMC_SATASTOPCLOCK_MASK(1))) {
+		DB(mvOsPrintf("%s:       SATA1\n", __func__));
+		mvCtrlPwrClckSet(SATA_UNIT_ID, 1, MV_FALSE);
+	}
+	for (tmpcounter = 0; tmpcounter < 4; tmpcounter++) {
+		if (!(powermngmntctrlregmap & (1 << (4 - tmpcounter)))) {
+			DB(mvOsPrintf("%s:       GBE%d\n", __func__, tmpcounter));
+			mvCtrlPwrClckSet(ETH_GIG_UNIT_ID, tmpcounter, MV_FALSE);
+		}
+	}
+	for (tmpcounter = 0; tmpcounter < 8; tmpcounter++) {
+		if (!(powermngmntctrlregmap & (1 << (5 + tmpcounter)))) {
+			DB(mvOsPrintf("%s:       PEX%d.%d\n", __func__, tmpcounter>>2, tmpcounter % 4));
+			mvCtrlPwrClckSet(PEX_UNIT_ID, tmpcounter, MV_FALSE);
+		}
+	}
+	if (!(powermngmntctrlregmap & BIT26)) {
+		DB(mvOsPrintf("%s:       PEX2\n", __func__));
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 8, MV_FALSE);
+	}
+	if (!(powermngmntctrlregmap & BIT27)) {
+		DB(mvOsPrintf("%s:       PEX3\n", __func__));
+		mvCtrlPwrClckSet(PEX_UNIT_ID, 9, MV_FALSE);
+	}
+
+	if (!(powermngmntctrlregmap & BIT25)) {
+		DB(mvOsPrintf("%s:       TDM\n", __func__));
+		mvCtrlPwrClckSet(TDM_UNIT_ID, 0, MV_FALSE);
+	}
+
+	/* Apply clock gating */
+	MV_REG_WRITE(POWER_MNG_CTRL_REG, MV_REG_READ(POWER_MNG_CTRL_REG) & powermngmntctrlregmap);
+	/* The Sata driver doesn't support clock gating at this point so we enable the logic to the block*/
+	MV_REG_WRITE(POWER_MNG_CTRL_REG, MV_REG_READ(POWER_MNG_CTRL_REG) | (BIT15 | BIT30));
+#endif /* defined(MV_INCLUDE_CLK_PWR_CNTRL) */
+
+	return status;
+err_cfg:
+	DB(mvOsPrintf("%s: Wrong CFG (%#x) for SERDES line %d.\n",
+		__func__, serdesLineCfg, serdesLineNum));
+	return MV_ERROR;
+}
+
 /*******************************************************************************
 * mvCtrlSerdesPhyConfig
 *
@@ -1548,6 +2053,53 @@
 }
 
 /*******************************************************************************
+* mvCtrlNandClkSetAxp
+*
+* DESCRIPTION:
+*	Set the division ratio of ECC Clock for AXP
+*
+*******************************************************************************/
+static int mvCtrlNandClkSetAxp(int nfc_clk_freq, MV_U32 pll_clk)
+{
+	int divider;
+
+	/* Set the division ratio of ECC Clock 0x00018748[13:8] (by default it's
+	 * double of core clock)
+	 */
+	MV_U32 nVal = MV_REG_READ(AXP_CORE_DIV_CLK_CTRL(1));
+
+	/* Calculate nand divider for requested nfc_clk_freq. If integer divider
+	 * cannot be achieved, it will be rounded-up, which will result in
+	 * setting the closest lower frequency.
+	 * ECC engine clock = (PLL frequency / divider)
+	 * NFC clock = ECC clock / 2
+	 */
+	divider = DIV_ROUND_UP(pll_clk, (2 * nfc_clk_freq));
+	DB(mvOsPrintf("%s: divider %d\n", __func__, divider));
+
+	nVal &= ~(AXP_NAND_ECC_DIVCLK_RATIO_MASK);
+	nVal |= (divider << AXP_NAND_ECC_DIVCLK_RATIO_OFFS);
+	MV_REG_WRITE(AXP_CORE_DIV_CLK_CTRL(1), nVal);
+
+	/* Set reload force of ECC clock 0x00018740[7:0] to 0x2 (meaning you
+	 * will force only the ECC clock)
+	 */
+	nVal = MV_REG_READ(AXP_CORE_DIV_CLK_CTRL(0));
+	nVal &= ~(AXP_CORE_DIVCLK_RELOAD_FORCE_MASK);
+	nVal |= AXP_CORE_DIVCLK_RELOAD_FORCE_VAL;
+	MV_REG_WRITE(AXP_CORE_DIV_CLK_CTRL(0), nVal);
+
+	/* Set reload ratio bit 0x00018740[8] to 1'b1 */
+	MV_REG_BIT_SET(AXP_CORE_DIV_CLK_CTRL(0), AXP_CORE_DIVCLK_RELOAD_RATIO_MASK);
+	mvOsDelay(1); /*  msec */
+	/* Set reload ratio bit 0x00018740[8] to 0'b1 */
+	MV_REG_BIT_RESET(AXP_CORE_DIV_CLK_CTRL(0), AXP_CORE_DIVCLK_RELOAD_RATIO_MASK);
+
+	/* Return calculated nand clock frequency */
+	return (pll_clk)/(2 * divider);
+}
+
+/*******************************************************************************
 * mvCtrlNandClkSet
 *
 * DESCRIPTION:
@@ -1565,9 +2117,14 @@
 int mvCtrlNandClkSet(int nfc_clk_freq)
 {
 	int divider;
-	MV_U32 nVal = MV_DFX_REG_READ(CORE_DIV_CLK_CTRL(2));
+	MV_U32 nVal;
 	MV_U32 pll_clk = mvCpuPllClkGet();
 
+	if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+		return mvCtrlNandClkSetAxp(nfc_clk_freq, pll_clk);
+
+	nVal = MV_DFX_REG_READ(CORE_DIV_CLK_CTRL(2));
+
 	/*
 	 * Calculate nand divider for requested nfc_clk_freq. If integer divider
 	 * cannot be achieved, it will be rounded-up, which will result in
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
index 624d149..1e11379 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
@@ -82,6 +82,18 @@
 /* typedefs */
 typedef MV_STATUS(*MV_WIN_GET_FUNC_PTR)(MV_U32, MV_U32, MV_UNIT_WIN_INFO*);
 
+/* SERDES description - AXP only */
+typedef enum {
+	SERDES_UNIT_UNCONNECTED	= 0x0,
+	SERDES_UNIT_PEX		= 0x1,
+	SERDES_UNIT_SATA	= 0x2,
+	SERDES_UNIT_SGMII0	= 0x3,
+	SERDES_UNIT_SGMII1	= 0x4,
+	SERDES_UNIT_SGMII2	= 0x5,
+	SERDES_UNIT_SGMII3	= 0x6,
+	SERDES_UNIT_QSGMII	= 0x7,
+	SERDES_UNIT_LAST
+} MV_SERDES_UNIT_INDX;
 
 typedef enum {
 	PEX_BUS_DISABLED	= 0,
@@ -162,11 +174,12 @@
 
 MV_U32	  mvCtrlEthMaxPortGet(MV_VOID);
 MV_U8	  mvCtrlEthMaxCPUsGet(MV_VOID);
-#if defined(MV_INCLUDE_USB)
 MV_U32 mvCtrlUsbMaxGet(MV_VOID);
+#if defined(MV_INCLUDE_USB)
 MV_U32 mvCtrlUsb3MaxGet(MV_VOID);
 MV_U32 mvCtrlUsb3HostMaxGet(MV_VOID);
 MV_VOID mvCtrlUtmiPhySelectorSet(MV_U32 usbUnitId);
+MV_BOOL mvCtrlIsUsbSerDesConnected(MV_U32 usbPort);
 #endif
 #if defined(MV_INCLUDE_XOR)
 MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
@@ -197,6 +210,7 @@
 MV_BOOL	  mvCtrlIsBootFromNAND(MV_VOID);
 MV_BOOL	  mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
 MV_STATUS mvCtrlSerdesPhyConfig(MV_VOID);
+MV_STATUS mvCtrlSerdesPhyConfigAxp(MV_VOID);
 MV_BOOL mvCtrlIsDLBEnabled(MV_VOID);
 MV_U32 mvCtrlDDRBudWidth(MV_VOID);
 MV_BOOL mvCtrlDDRThruXbar(MV_VOID);
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
index f1d2632..bc7c468 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
@@ -151,6 +151,73 @@
 #define PMC_GESTOPCLOCK_EN(port)		(1 << PMC_GESTOPCLOCK_OFFS(port))
 #define PMC_GESTOPCLOCK_STOP(port)		(0 << PMC_GESTOPCLOCK_OFFS(port))
 
+/*  Power Management Clock Gating Control Register - AXP only */
+
+#define AXP_PMC_TDMSTOPCLOCK_OFFS		25
+#define AXP_PMC_TDMSTOPCLOCK_MASK		(1 << AXP_PMC_TDMSTOPCLOCK_OFFS)
+#define AXP_PMC_TDMSTOPCLOCK_EN			(1 << AXP_PMC_TDMSTOPCLOCK_OFFS)
+#define AXP_PMC_TDMSTOPCLOCK_STOP		(0 << AXP_PMC_TDMSTOPCLOCK_OFFS)
+
+#define AXP_PMC_PEXSTOPCLOCK_OFFS(port)		((port) < 8 ? (5 + (port)) : (18 + (port)))
+#define AXP_PMC_PEXSTOPCLOCK_MASK(port)		(1 << AXP_PMC_PEXSTOPCLOCK_OFFS(port))
+#define AXP_PMC_PEXSTOPCLOCK_EN(port)		(1 << AXP_PMC_PEXSTOPCLOCK_OFFS(port))
+#define AXP_PMC_PEXSTOPCLOCK_STOP(port)		(0 << AXP_PMC_PEXSTOPCLOCK_OFFS(port))
+
+#define AXP_PMC_USBSTOPCLOCK_OFFS(port)		((port) < 3 ? (18 + (port)) : 0)
+#define AXP_PMC_USBSTOPCLOCK_MASK(port)		(1 << AXP_PMC_USBSTOPCLOCK_OFFS(port))
+#define AXP_PMC_USBSTOPCLOCK_EN(port)		(1 << AXP_PMC_USBSTOPCLOCK_OFFS(port))
+#define AXP_PMC_USBSTOPCLOCK_STOP(port)		(0 << AXP_PMC_USBSTOPCLOCK_OFFS(port))
+
+#define AXP_PMC_SDIOSTOPCLOCK_OFFS		17
+#define AXP_PMC_SDIOSTOPCLOCK_MASK		(1 << AXP_PMC_SDIOSTOPCLOCK_OFFS)
+#define AXP_PMC_SDIOSTOPCLOCK_EN		(1 << AXP_PMC_SDIOSTOPCLOCK_OFFS)
+#define AXP_PMC_SDIOSTOPCLOCK_STOP		(0 << AXP_PMC_SDIOSTOPCLOCK_OFFS)
+
+#define AXP_PMC_RUNITSTOPCLOCK_OFFS		24
+#define AXP_PMC_RUNITSTOPCLOCK_MASK		(1 << AXP_PMC_RUNITSTOPCLOCK_OFFS)
+#define AXP_PMC_RUNITSTOPCLOCK_EN		(1 << AXP_PMC_RUNITSTOPCLOCK_OFFS)
+#define AXP_PMC_RUNITSTOPCLOCK_STOP		(0 << AXP_PMC_RUNITSTOPCLOCK_OFFS)
+
+#define AXP_PMC_XORSTOPCLOCK_OFFS		22
+#define AXP_PMC_XORSTOPCLOCK_MASK		(1 << AXP_PMC_XORSTOPCLOCK_OFFS)
+#define AXP_PMC_XORSTOPCLOCK_EN			(1 << AXP_PMC_XORSTOPCLOCK_OFFS)
+#define AXP_PMC_XORSTOPCLOCK_STOP		(0 << AXP_PMC_XORSTOPCLOCK_OFFS)
+
+#define AXP_PMC_SATASTOPCLOCK_OFFS(ch)		(ch == 0 ? 14 : 29)
+#define AXP_PMC_SATASTOPCLOCK_MASK(ch)		(3 << AXP_PMC_SATASTOPCLOCK_OFFS(ch))
+#define AXP_PMC_SATASTOPCLOCK_EN(ch)		(3 << AXP_PMC_SATASTOPCLOCK_OFFS(ch))
+#define AXP_PMC_SATASTOPCLOCK_STOP(ch)		(0 << AXP_PMC_SATASTOPCLOCK_OFFS(ch))
+
+#define AXP_PMC_CESASTOPCLOCK_OFFS		23
+#define AXP_PMC_CESASTOPCLOCK_MASK		(1 << AXP_PMC_CESASTOPCLOCK_OFFS)
+#define AXP_PMC_CESASTOPCLOCK_EN		(1 << AXP_PMC_CESASTOPCLOCK_OFFS)
+#define AXP_PMC_CESASTOPCLOCK_STOP		(0 << AXP_PMC_CESASTOPCLOCK_OFFS)
+
+#define AXP_PMC_GESTOPCLOCK_OFFS(port)		((port) < 4 ? (4 - (port)) : 0)
+#define AXP_PMC_GESTOPCLOCK_MASK(port)		(1 << AXP_PMC_GESTOPCLOCK_OFFS(port))
+#define AXP_PMC_GESTOPCLOCK_EN(port)		(1 << AXP_PMC_GESTOPCLOCK_OFFS(port))
+#define AXP_PMC_GESTOPCLOCK_STOP(port)		(0 << AXP_PMC_GESTOPCLOCK_OFFS(port))
+
+#define AXP_PMC_NETASTOPCLOCK_OFFS		13
+#define AXP_PMC_NETASTOPCLOCK_MASK		(1 << AXP_PMC_NETASTOPCLOCK_OFFS)
+#define AXP_PMC_NETASTOPCLOCK_EN		(1 << AXP_PMC_NETASTOPCLOCK_OFFS)
+#define AXP_PMC_NETASTOPCLOCK_STOP		(0 << AXP_PMC_NETASTOPCLOCK_OFFS)
+
+#define AXP_PMC_LCDSTOPCLOCK_OFFS		16
+#define AXP_PMC_LCDSTOPCLOCK_MASK		(1 << AXP_PMC_LCDSTOPCLOCK_OFFS)
+#define AXP_PMC_LCDSTOPCLOCK_EN			(1 << AXP_PMC_LCDSTOPCLOCK_OFFS)
+#define AXP_PMC_LCDSTOPCLOCK_STOP		(0 << AXP_PMC_LCDSTOPCLOCK_OFFS)
+
+#define AXP_PMC_IDMASTOPCLOCK_OFFS		21
+#define AXP_PMC_IDMASTOPCLOCK_MASK		(1 << AXP_PMC_IDMASTOPCLOCK_OFFS)
+#define AXP_PMC_IDMASTOPCLOCK_EN		(1 << AXP_PMC_IDMASTOPCLOCK_OFFS)
+#define AXP_PMC_IDMASTOPCLOCK_STOP		(0 << AXP_PMC_IDMASTOPCLOCK_OFFS)
+
+#define AXP_PMC_DDRSTOPCLOCK_OFFS		28
+#define AXP_PMC_DDRSTOPCLOCK_MASK		(1 << AXP_PMC_DDRSTOPCLOCK_OFFS)
+#define AXP_PMC_DDRSTOPCLOCK_EN			(1 << AXP_PMC_DDRSTOPCLOCK_OFFS)
+#define AXP_PMC_DDRSTOPCLOCK_STOP		(0 << AXP_PMC_DDRSTOPCLOCK_OFFS)
+
 /* dummy defenition, used for SGMII capable interfaces */
 #define SGMII_SERDES_CFG_REG(port)		(0)
 
@@ -158,6 +225,27 @@
 
 #define MPP_CONTROL_REG(id)			(0x18000 + (id * 4))
 
+/* Switch core registers */
+#define MV_PP_ADDCOMP_CNCTRL 0x00000140
+#define MV_PP_ADDCOMP_REG(n) (0x00000120 + 4*n)
+#define MV_PP_ADDCOMP_MODE_BIT			16
+#define MV_PP_ADDCOMP_MODE_MASK			(1 << MV_PP_ADDCOMP_MODE_BIT)
+
+#define MV_PP_SMI_MISC_CONFIG_OFFSET 0x4
+#define MV_PP_SMI_INVERT_MDC_BIT          11
+#define MV_PP_SMI_INVERT_MDC_MASK         (1 << MV_PP_SMI_INVERT_MDC_BIT)
+
+#define MV_PP_ETH_ADDCOMP_INDEX 1
+#define MV_PP_ETH_REG_BASE_NORNAL (SWITCH_REGS_VIRT_BASE | MV_PP_ETH_ADDCOMP_INDEX<<19)
+#define MV_PP_ETH_REG_BASE_LEGACY (SWITCH_REGS_VIRT_BASE | MV_PP_ETH_ADDCOMP_INDEX<<24)
+
+/* Sample at Reset - AXP only */
+#define MPP_SAMPLE_AT_RESET(id)			(0x18230 + (id * 4))
+
+/* Controller environment and SERDERS registers - AXP only */
+#define SERDES_LINE_MUX_REG_0_7			0x18270
+#define GEN_PURP_RES_2_REG			0x182F8
+
 /* Dragonite Register */
 #define DRAGONITE_CTRL_REG			0x1c
 #define DRAGONITE_POE_CAUSE_IRQ_REG		0x64
@@ -178,6 +266,9 @@
 #define MSAR_AC3_BOOT_MODE(sar1, sar2)	(((sar1) >> 11) & 0x7)		/* boot from */
 #define MSAR_AC3_TM_CLK(sar1, sar2)	(((sar2) >> 17) & 0x1)		/* PLL 2 config */
 
+#define MSAR_BOBK_BOOT_MODE(sar1, sar2)	(((sar1) >> 13) & 0x7)		/* boot from */
+#define MSAR_BOBK_TM_CLK(sar1, sar2)	(((sar2) >> 15) & 0x7)		/* PLL 2 config */
+
 #define SAR1_BOOT_FROM_NOR			0
 #define SAR1_BOOT_FROM_NAND			1
 #define SAR1_BOOT_FROM_UART			2
@@ -209,10 +300,23 @@
 
 #define CORE_DIV_CLK_CTRL(num)			(DFX_CORE_DIVCLK_CONTROL0_REG + ((num) * 0x4))
 
-
 #define DFX_TEMPERATURE_SENSOR_LSB_CTRL_REG		0xF8070
 #define DFX_TEMPERATURE_SENSOR_MSB_CTRL_REG		0xF8074
 #define DFX_TEMPERATURE_SENSOR_STATUS_REG		0xF8078
+
+/* Core Divider Clock Control - AXP only */
+#define AXP_CORE_DIV_CLK_CTRL(num)		(0x18740 + ((num) * 0x8))
+
+#define AXP_CORE_DIVCLK_RELOAD_FORCE_OFFS	0
+#define AXP_CORE_DIVCLK_RELOAD_FORCE_MASK	(0xFF << AXP_CORE_DIVCLK_RELOAD_FORCE_OFFS)
+#define AXP_CORE_DIVCLK_RELOAD_FORCE_VAL	(0x2 << AXP_CORE_DIVCLK_RELOAD_FORCE_OFFS)
+
+#define AXP_NAND_ECC_DIVCLK_RATIO_OFFS		8
+#define AXP_NAND_ECC_DIVCLK_RATIO_MASK		(0x3F << AXP_NAND_ECC_DIVCLK_RATIO_OFFS)
+
+#define AXP_CORE_DIVCLK_RELOAD_RATIO_OFFS	8
+#define AXP_CORE_DIVCLK_RELOAD_RATIO_MASK	(1 << AXP_CORE_DIVCLK_RELOAD_RATIO_OFFS)
+
 /* definition for caculate Temperature */
 #define TEMPERATURE_OFFSET        (596)
 #define TEMPERATURE_FACTOR        (2154)
@@ -255,6 +359,7 @@
 #define	ICDR_UINIT_ID_MASK	0x0F
 #define ICDR_UNIT_ID_4_DFX	0x0f
 
+#define CPLD_RD_MTL_BC2_BOARD_REV_REG	2
 #define CPLD_BOARD_REV_REG	1
 #define CPLD_BOARD_REV_MASK	0x7
 #define CPLD_REV_REG		2
@@ -263,27 +368,114 @@
 #define DEV_ID_REG				0x1823C
 #define DEVICE_ID_OFFS			0
 #define DEVICE_ID_MASK			0xFFFF
-#define DEVICE_FLAVOR_MASK		0xFF
+
+/* for BobK devID, Cetus: 0xBE00 Caelum:0xBC00, the higher 6bits are the same.
+so update mask to 0x3FF, for BC2 flavor(0xF4XX), and AC3 flavor(0xFC00),
+the higher 6bits are also the same, so can work normally */
+#define DEVICE_FLAVOR_MASK		0x3FF
+
+#define BOBK_FLAVOR_MASK		0xFF	/* only for Cetus & Caelum flavor */
 #define DEV_REV_ID_REG			0xF8244
 #define REVISON_ID_OFFS			28
 #define REVISON_ID_MASK			0xF0000000
 
 /* Extract CPU, L2, DDR clocks SAR value from
-** SAR bits 24-27
-*/
+ * SAR bits 24-27 - AXP only
+ */
+#define MSAR_CPU_CLK_IDX(sar0, sar1)		((((sar0) >> 21) & 0x7) + ((((sar1) >> 20) & 1) << 3))
+#define MSAR_CPU_CLK_TWSI(sar0, sar1)		((((sar0) >> 2)  & 0x7) + (((sar1) & 1) << 3))
+#define MSAR_DDR_L2_CLK_RATIO_IDX(sar0, sar1)	((((sar0) >> 24) & 0xF) + ((((sar1) >> 19) & 1) << 4))
+#define MSAR_DDR_L2_CLK_RATIO_TWSI(sar0)	(((sar0) >> 1)  & 0xF)
 
+/* SAR TCLK bit - AXP only */
+#define MSAR_TCLK_OFFS				28
+#define MSAR_TCLK_MASK				(0x1 << MSAR_TCLK_OFFS)
+
+/* PLL(CPU) input clock - AXP only */
+#define AXP_PLL_IN_CLK			_2GHz
 
 #ifndef MV_ASMLANGUAGE
 
+#define MV_CPU_CLK_TBL_AXP { 1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000,\
+			      600,  667,  800, 1600, 2133, 2200, 2400, 0 }
 
+/*		cpu	l2c	hclk	ddr	*/
+#define MV_DDR_L2_CLK_RATIO_TBL_AXP { \
+/*00*/	{	1,	1,	4,	2	},\
+/*01*/	{	1,	2,	2,	2	},\
+/*02*/	{	2,	2,	6,	3	},\
+/*03*/	{	2,	2,	3,	3	},\
+/*04*/	{	1,	2,	3,	3	},\
+/*05*/	{	1,	2,	4,	2	},\
+/*06*/	{	1,	1,	2,	2	},\
+/*07*/	{	2,	3,	6,	6	},\
+/*08*/	{	2,	3,	5,	5	},\
+/*09*/	{	1,	2,	6,	3	},\
+/*10*/	{	2,	4,	10,	5	},\
+/*11*/	{	1,	3,	6,	6	},\
+/*12*/	{	1,	2,	4,	4	},\
+/*13*/	{	1,	3,	6,	3	},\
+/*14*/	{	1,	2,	5,	5	},\
+/*15*/	{	2,	2,	5,	5	},\
+/*16*/	{	1,	1,	3,	3	},\
+/*17*/	{	2,	5,	10,	10	},\
+/*18*/	{	1,	3,	8,	4	},\
+/*19*/	{	1,	1,	2,	1	},\
+/*20*/	{	2,	3,	6,	3	},\
+/*21*/	{	1,	2,	8,	4	},\
+/*22*/	{	2,	5,	10,	5	} \
+}
+
+/* This structure refrect registers:
+ * Serdes 0-7 selectors		0x18270
+ * and Serdes 8-15 selectors	0x18274
+ * AXP only
+ */
+
+#define SERDES_CFG_AXP { \
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 0 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 1 */	\
+	{0, 1, -1 ,  2, -1, -1, -1, -1}, /* Lane 2 */	\
+	{0, 1, -1 , -1,  2, -1, -1,  3}, /* Lane 3 */	\
+	{0, 1,  2 , -1, -1,  3, -1, -1}, /* Lane 4 */	\
+	{0, 1,  2 , -1,  3, -1, -1,  4}, /* Lane 5 */	\
+	{0, 1,  2 ,  4, -1,  3, -1, -1}, /* Lane 6 */	\
+	{0, 1, -1 ,  2, -1, -1,  3, -1}, /* Lane 7 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 8 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 9 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 10 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 11 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 12 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 13 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 14 */	\
+	{0, 1, -1 , -1, -1, -1, -1, -1}	 /* Lane 15 */	\
+}
 /* These macros help units to identify a target Mport Arbiter group */
 #define MV_TARGET_IS_DRAM(target)   \
 		((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
 
 #define MV_TARGET_IS_PEX0(target)   \
 		((target >= PEX0_MEM) && (target <= PEX0_IO))
+#define MV_TARGET_IS_PEX1(target)   \
+		((target >= (MV_8)PEX1_MEM) && (target <= (MV_8)PEX1_IO))
+#define MV_TARGET_IS_PEX2(target)   \
+		((target >= (MV_8)PEX2_MEM) && (target <= (MV_8)PEX2_IO))
+#define MV_TARGET_IS_PEX3(target)   \
+		((target >= (MV_8)PEX3_MEM) && (target <= (MV_8)PEX3_IO))
+#define MV_TARGET_IS_PEX4(target)   \
+		((target >= (MV_8)PEX4_MEM) && (target <= (MV_8)PEX4_IO))
+#define MV_TARGET_IS_PEX5(target)   \
+		((target >= (MV_8)PEX5_MEM) && (target <= (MV_8)PEX5_IO))
+#define MV_TARGET_IS_PEX6(target)   \
+		((target >= (MV_8)PEX6_MEM) && (target <= (MV_8)PEX6_IO))
+#define MV_TARGET_IS_PEX7(target)   \
+		((target >= (MV_8)PEX7_MEM) && (target <= (MV_8)PEX7_IO))
+#define MV_TARGET_IS_PEX8(target)   \
+		((target >= (MV_8)PEX8_MEM) && (target <= (MV_8)PEX8_IO))
+#define MV_TARGET_IS_PEX9(target)   \
+		((target >= (MV_8)PEX9_MEM) && (target <= (MV_8)PEX9_IO))
 
-#define MV_TARGET_IS_PEX(target)	MV_TARGET_IS_PEX0(target)
+#define MV_TARGET_IS_PEX(target)	((target >= PEX0_MEM) && (target <= (MV_8)PEX9_IO))
 
 #define MV_TARGET_IS_DEVICE(target)	((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
 
@@ -321,7 +513,16 @@
 
 typedef enum {
 	PEX0_0x4	= 0,
-	PEXIF_MAX	= 1
+	PEX0_1x4	= 1,
+	PEX0_2x4	= 2,
+	PEX0_3x4	= 3,
+	PEX1_0x4	= 4,
+	PEX1_1x4	= 5,
+	PEX1_2x4	= 6,
+	PEX1_3x4	= 7,
+	PEX2_0x4	= 8,
+	PEX3_0x4	= 9,
+	PEXIF_MAX	= 10
 } MV_PEXIF_INDX;
 
 typedef struct {
@@ -344,6 +545,24 @@
 		450					\
 	}
 
+#define MV_CORE_CLK_TBL_BOBK_CETUS	{	\
+		365, 220,			\
+		250, 200,			\
+		167					\
+	}
+
+#define MV_CORE_CLK_TBL_BOBK_CAELUM	{	\
+		365, 220,			\
+		250, 200,			\
+		167, 133			\
+	}
+
+#define MV_BYPASS_CORE_CLK_TBL_BOBK	{	\
+		365, 220,			\
+		250, 200,			\
+		167					\
+	}
+
 #define MV_CORE_CLK_TBL_AC3	{	\
 		290, 250,			\
 		222, 167,			\
@@ -362,6 +581,26 @@
 	{1333, 666, 1600, MV_TRUE}	\
 }
 
+#define MV_CPU_DDR_CLK_TBL_BOBK_CETUS {	\
+	{ 400, 400,  400, MV_FALSE},	\
+	{1000, 667, 2000, MV_FALSE},	\
+	{ 667, 667, 2000, MV_FALSE},	\
+	{ 800, 800,  800, MV_FALSE},	\
+	{1200, 800, 2400, MV_FALSE},	\
+	{ 800, 400,  800, MV_FALSE},	\
+	{ 800, 800,  800, MV_TRUE}	\
+}
+
+#define MV_CPU_DDR_CLK_TBL_BOBK_CAELUM {	\
+	{ 400, 400,  400, MV_FALSE},	\
+	{1000, 667, 2000, MV_TRUE},	\
+	{ 667, 667, 2000, MV_FALSE},	\
+	{ 800, 800,  800, MV_FALSE},	\
+	{1200, 800, 2400, MV_TRUE},	\
+	{ 800, 400,  800, MV_FALSE},	\
+	{ 800, 800,  800, MV_TRUE}	\
+}
+
 #define MV_CPU_DDR_CLK_TBL_AC3 {	\
 	{ 533, 533,  533, MV_TRUE},	\
 	{ 667, 667, 2000, MV_FALSE},	\
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
index 21026e9..6854b95 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
@@ -70,19 +70,23 @@
 
 #include "ctrlEnv/sys/mvCpuIfRegs.h"
 
+#define MAX_TARGETS	(mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID ? \
+			 MAX_TARGETS_AXP : MAX_TARGETS_MSYS)
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 #define MV_ARM_SOC
-#ifdef CONFIG_ALLEYCAT3
+#if defined CONFIG_ALLEYCAT3
 #define SOC_NAME_PREFIX				"Alleycat3"
-#else
+#elif defined CONFIG_BOBCAT2
 #define SOC_NAME_PREFIX				"Bobcat2"
+#else
+#define SOC_NAME_PREFIX				"BobK"
 #endif
 /*
- * Bobcat2 Units Address decoding
+ * Bobcat2/AXP Units Address decoding
  */
 #define MV_DRAM_REGS_OFFSET			(0x0)
 #define MV_AURORA_L2_REGS_OFFSET		(0x8000)
@@ -92,9 +96,11 @@
 #define MV_TWSI_SLAVE_REGS_OFFSET(chanNum)	(0x11000 + (chanNum * 0x100))
 
 #define MV_UART_REGS_OFFSET(chanNum)		(0x12000 + (chanNum * 0x100))
+#define MV_RUNIT_PMU_REGS_OFFSET		(0x1C000)
 
 #define MV_MPP_REGS_OFFSET			(0x18000)
 #define MV_GPP_REGS_OFFSET(unit)		(0x18100 + ((unit) * 0x80))
+#define MV_GPP_REGS_OFFSET_AXP(unit)		(0x18100 + ((unit) * 0x40))
 
 #define MV_MISC_REGS_OFFSET			(0x18200)
 #define MV_CLK_CMPLX_REGS_OFFSET		(0x18700)
@@ -108,16 +114,21 @@
 #define MV_CPUIF_REGS_OFFSET(cpu)		(0x21800 + (cpu) * 0x100)
 #define MV_PMU_NFABRIC_UNIT_SERV_OFFSET		(0x22000)
 #define MV_CPU_PMU_UNIT_SERV_OFFSET(cpu)	(0x22100 + (cpu) * 0x100)
+#define MV_CPU_HW_SEM_OFFSET			(0x20500)
 #define MV_ETH_BASE_ADDR			(0x70000)
-#define MV_ETH_REGS_OFFSET(port)		(MV_ETH_BASE_ADDR + (port) * 0x4000)
+#define MV_ETH_REGS_OFFSET(port)		(MV_ETH_BASE_ADDR - ((port) / 2) * 0x40000 + ((port) % 2) * 0x4000)
 #define MV_PEX_IF_REGS_OFFSET(pexIf)\
 			(pexIf < 8 ? (0x40000 + ((pexIf) / 4) * 0x40000 + ((pexIf) % 4) * 0x4000)\
 	: (0X42000 + ((pexIf) % 8) * 0x40000))
 #define MV_USB_REGS_OFFSET(dev)			(0x50000 + (dev * 0x1000))
+#define MV_USB2_USB3_REGS_OFFSET(unitType, dev) (MV_USB_REGS_OFFSET(dev))
 #define MV_XOR_REGS_OFFSET(unit)		(0xF0800)
+#define MV_XOR_REGS_OFFSET_AXP(unit)		(unit ? 0xF0900 : 0x60900)
 #if defined(MV_INCLUDE_IDMA)
 #define MV_IDMA_REGS_OFFSET			(0x60800)
 #endif
+#define MV_CESA_TDMA_REGS_OFFSET(chanNum)	(0x90000 + (chanNum * 0x2000))
+#define MV_CESA_REGS_OFFSET(chanNum)		(0x9D000 + (chanNum * 0x2000))
 #define MV_SATA_REGS_OFFSET			(0xA0000)
 #define MV_COMM_UNIT_REGS_OFFSET		(0xB0000)
 #define MV_NFC_REGS_OFFSET			(0xD0000)
@@ -126,8 +137,11 @@
 #define MV_SDMMC_REGS_OFFSET			(0xD4000)
 
 #define MV_USB2_CAPLENGTH_OFFSET(index)		(INTER_REGS_BASE + MV_USB_REGS_OFFSET(index) + 0x100)
-
 #define MV_ETH_SMI_PORT   0
+
+#define MV_PP_SMI_BASE(n) (0x54000000 + 0x01000000*n)
+#define MV_PP_ETH_SMI_PORT 0
+
 /*
  * Miscellanuous Controller Configurations
  */
@@ -142,17 +156,19 @@
 #define TWSI0_CPU_MAIN_INT_BIT(ch)		((ch) + 3)
 #define TWSI_SPEED				100000
 
-#define MV_GPP_MAX_PINS				33
+#define MV_GPP_MAX_PINS				68
 #define MV_GPP_MAX_GROUP    			2 	/* group == configuration register? */
+#define MV_GPP_MAX_GROUP_AXP			3
 #define MV_CNTMR_MAX_COUNTER 			8 	/* 4 global + 1 global WD + 2 current private CPU + 1 private CPU WD*/
 
 #define MV_UART_MAX_CHAN			2
 
-#define MV_XOR_MAX_UNIT				1 /* XOR unit == XOR engine */
-#define MV_XOR_MAX_CHAN         		2 /* total channels for all units together*/
+#define MV_XOR_MAX_UNIT				2 /* XOR unit == XOR engine */
+#define MV_XOR_MAX_CHAN				4 /* total channels for all units together*/
 #define MV_XOR_MAX_CHAN_PER_UNIT		2 /* channels for units */
 
 #define MV_MPP_MAX_GROUP			5
+#define MV_MPP_MAX_GROUP_AXP			9
 
 #define MV_DRAM_MAX_CS				4
 #define MV_SPI_MAX_CS				8
@@ -168,8 +184,8 @@
 #endif
 
 /* This define describes the maximum number of supported PEX Interfaces */
-#define MV_PEX_MAX_IF				1
-#define MV_PEX_MAX_UNIT				1
+#define MV_PEX_MAX_IF				10	/* 1 for MSYS */
+#define MV_PEX_MAX_UNIT				4	/* 1 for MSYS */
 #ifdef MV_INCLUDE_PEX
 #define MV_INCLUDE_PEX0
 #define MV_DISABLE_PEX_DEVICE_BAR
@@ -186,15 +202,27 @@
 /* This define describes the maximum number of supported PCI Interfaces 	*/
 #define MV_DEVICE_MAX_CS      			4
 
+/* CESA version #3: One channel, 2KB SRAM, TDMA, CHAIN Mode support */
+#define MV_CESA_VERSION				3
+#define MV_CESA_SRAM_SIZE			(2 * 1024)
+
+#ifdef MV_USB
+#define MV_USB_MAX_PORTS 1
+#else
+#define MV_USB_MAX_PORTS 0
+#endif
+#define MV_USB3_MAX_HOST_PORTS 0
 
 /* This define describes the maximum number of supported Ethernet ports */
 /* TODO - verify all these numbers */
 #define MV_ETH_VERSION 				4 /* for Legacy mode */
 #define MV_NETA_VERSION				1 /* for NETA mode */
-#define MV_ETH_MAX_PORTS			2
+#define MV_ETH_MAX_PORTS			4
 #define MV_ETH_MAX_RXQ              		8
 #define MV_ETH_MAX_TXQ              		8
 #define MV_ETH_TX_CSUM_MAX_SIZE 		9800
+#define MV_ETH_TX_CSUM_MIN_SIZE			2048
+#define MV_PNC_TCAM_LINES			1024	/* TCAM num of entries */
 #define BOARD_ETH_SWITCH_PORT_NUM		2
 
 /* New GMAC module is used */
@@ -235,6 +263,17 @@
 	I2C_UNIT_ID,
 	USB_UNIT_ID,
 	USB3_UNIT_ID,
+	NAND_UNIT_ID,
+	DEVBUS_UNIT_ID,
+	IDMA_UNIT_ID,
+	SATA_UNIT_ID,
+	TDM_UNIT_ID,
+	CESA_UNIT_ID,
+	AUDIO_UNIT_ID,
+	TS_UNIT_ID,
+	XPON_UNIT_ID,
+	BM_UNIT_ID,
+	PNC_UNIT_ID,
 	MAX_UNITS_ID
 } MV_UNIT_ID;
 
@@ -288,9 +327,57 @@
 	DEV_BOOCS,	/* 23 DEV_BOOCS			*/
 	USB_REGS,	/* 24 USB Internal registers	*/
 	DRAGONITE,	/* 25 Dragonite co-processor	*/
-	MAX_TARGETS
+	MAX_TARGETS_MSYS
 } MV_TARGET;
 
+enum _mvTarget_axp {
+	SDRAM_CS0_AXP,	/*0 SDRAM chip select 0		*/
+	SDRAM_CS1_AXP,	/*1 SDRAM chip select 1		*/
+	SDRAM_CS2_AXP,	/*2 SDRAM chip select 2		*/
+	SDRAM_CS3_AXP,	/*3 SDRAM chip select 3		*/
+	DEVICE_CS0_AXP,	/*4 Device chip select 0	*/
+	DEVICE_CS1_AXP,	/*5 Device chip select 1	*/
+	DEVICE_CS2_AXP,	/*6 Device chip select 2	*/
+	DEVICE_CS3_AXP,	/*7 Device chip select 3	*/
+	PEX0_MEM_AXP,	/*8 PCI Express 0 Memory	*/
+	PEX0_IO_AXP,	/*9 PCI Express 0 IO		*/
+	PEX1_MEM,	/*10 PCI Express 1 Memory	*/
+	PEX1_IO,	/*11 PCI Express 1 IO		*/
+	PEX2_MEM,	/*12 PCI Express 2 Memory	*/
+	PEX2_IO,	/*13 PCI Express 2 IO		*/
+	PEX3_MEM,	/*14 PCI Express 3 Memory	*/
+	PEX3_IO,	/*15 PCI Express 3 IO		*/
+	PEX4_MEM,	/*16 PCI Express 4 Memory	*/
+	PEX4_IO,	/*17 PCI Express 4 IO		*/
+	PEX5_MEM,	/*18 PCI Express 5 Memory	*/
+	PEX5_IO,	/*19 PCI Express 5 IO		*/
+	PEX6_MEM,	/*20 PCI Express 6 Memory	*/
+	PEX6_IO,	/*21 PCI Express 6 IO		*/
+	PEX7_MEM,	/*22 PCI Express 7 Memory	*/
+	PEX7_IO,	/*23 PCI Express 7 IO		*/
+	PEX8_MEM,	/*24 PCI Express 8 Memory	*/
+	PEX8_IO,	/*25 PCI Express 8 IO		*/
+	PEX9_MEM,	/*26 PCI Express 9 Memory	*/
+	PEX9_IO,	/*27 PCI Express 9 IO		*/
+	INTER_REGS_AXP,	/*28 Internal registers		*/
+	DMA_UART_AXP,	/*29 DMA based UART request	*/
+	SPI_CS0_AXP,	/*30 SPI_CS0			*/
+	SPI_CS1_AXP,	/*31 SPI_CS1			*/
+	SPI_CS2_AXP,	/*32 SPI_CS2			*/
+	SPI_CS3_AXP,	/*33 SPI_CS3			*/
+	SPI_CS4_AXP,	/*34 SPI_CS4			*/
+	SPI_CS5_AXP,	/*35 SPI_CS5			*/
+	SPI_CS6_AXP,	/*36 SPI_CS6			*/
+	SPI_CS7_AXP,	/*37 SPI_CS7			*/
+	BOOT_ROM_CS_AXP, /*38 BOOT_ROM_CS		*/
+	DEV_BOOCS_AXP,	/*39 DEV_BOOCS			*/
+	PMU_SCRATCHPAD,	/*40 PMU Scratchpad		*/
+	CRYPT0_ENG,	/* 41 Crypto0 Engine		*/
+	CRYPT1_ENG,	/* 42 Crypto1 Engine		*/
+	PNC_BM,		/* 43 PNC + BM			*/
+	MAX_TARGETS_AXP
+};
+
 #ifdef AURORA_IO_CACHE_COHERENCY
 #define DRAM_CS0_ATTR		0x1E
 #define DRAM_CS1_ATTR		0x1D
@@ -364,6 +451,100 @@
 
 
 
+#define TARGETS_DEF_ARRAY_AXP	{			\
+	{DRAM_CS0_ATTR, DRAM_TARGET_ID	}, /* SDRAM_CS0 */	\
+	{DRAM_CS1_ATTR, DRAM_TARGET_ID	}, /* SDRAM_CS1 */	\
+	{DRAM_CS2_ATTR, DRAM_TARGET_ID	}, /* SDRAM_CS0 */	\
+	{DRAM_CS3_ATTR, DRAM_TARGET_ID	}, /* SDRAM_CS1 */	\
+	{0x3E, DEV_TARGET_ID	}, /* DEVICE_CS0 */	\
+	{0x3D, DEV_TARGET_ID	}, /* DEVICE_CS1 */	\
+	{0x3B, DEV_TARGET_ID	}, /* DEVICE_CS2 */	\
+	{0x37, DEV_TARGET_ID	}, /* DEVICE_CS3 */	\
+	{0xE8, PEX0_TARGET_ID	}, /* PEX0_LANE0_MEM */	\
+	{0xE0, PEX0_TARGET_ID	}, /* PEX0_LANE0_IO */	\
+	{0xD8, PEX0_TARGET_ID	}, /* PEX0_LANE1_MEM */	\
+	{0xD0, PEX0_TARGET_ID	}, /* PEX0_LANE1_IO */	\
+	{0xB8, PEX0_TARGET_ID	}, /* PEX0_LANE2_MEM */	\
+	{0xB0, PEX0_TARGET_ID	}, /* PEX0_LANE2_IO */	\
+	{0x78, PEX0_TARGET_ID	}, /* PEX0_LANE3_MEM */	\
+	{0x70, PEX0_TARGET_ID	}, /* PEX0_LANE3_IO */	\
+	{0xE8, DFX_TARGET_ID	}, /* PEX1_LANE0_MEM */	\
+	{0xE0, DFX_TARGET_ID	}, /* PEX1_LANE0_IO */	\
+	{0xD8, DFX_TARGET_ID	}, /* PEX1_LANE1_MEM */	\
+	{0xD0, DFX_TARGET_ID	}, /* PEX1_LANE1_IO */	\
+	{0xB8, DFX_TARGET_ID	}, /* PEX1_LANE2_MEM */	\
+	{0xB0, DFX_TARGET_ID	}, /* PEX1_LANE2_IO */	\
+	{0x78, DFX_TARGET_ID	}, /* PEX1_LANE3_MEM */	\
+	{0x70, DFX_TARGET_ID	}, /* PEX1_LANE3_IO */	\
+	{0xF8, PEX0_TARGET_ID	}, /* PEX2_LANE0_MEM */	\
+	{0xF0, PEX0_TARGET_ID	}, /* PEX2_LANE0_IO */	\
+	{0xF8, DFX_TARGET_ID	}, /* PEX3_LANE0_MEM */	\
+	{0xF0, DFX_TARGET_ID	}, /* PEX3_LANE0_IO */	\
+	{0xFF, 0xFF		}, /* INTER_REGS */	\
+	{0x01, DEV_TARGET_ID	}, /* DMA_UART */	\
+	{0x1E, DEV_TARGET_ID	}, /* SPI_CS0 */	\
+	{0x5E, DEV_TARGET_ID	}, /* SPI_CS1 */	\
+	{0x9E, DEV_TARGET_ID	}, /* SPI_CS2 */	\
+	{0xDE, DEV_TARGET_ID	}, /* SPI_CS3 */	\
+	{0x1F, DEV_TARGET_ID	}, /* SPI_CS4 */	\
+	{0x5F, DEV_TARGET_ID	}, /* SPI_CS5 */	\
+	{0x9F, DEV_TARGET_ID	}, /* SPI_CS6 */	\
+	{0xDF, DEV_TARGET_ID	}, /* SPI_CS7 */	\
+	{0x1D, DEV_TARGET_ID	}, /* Main Boot device */	\
+	{0x2F, DEV_TARGET_ID	}, /* Secondary Boot device, */	\
+	{0x2D, DEV_TARGET_ID	}, /* PMU_SCRATCHPAD */	\
+	{0x09, CRYPT_TARGET_ID	}, /* CRYPT_ENG0 */	\
+	{0x05, CRYPT_TARGET_ID	}, /* CRYPT_ENG1 */     \
+	{0x00, PNC_BM_TARGET_ID	}, /* PNC_BM */		\
+}
+
+#define TARGETS_NAME_ARRAY_AXP	{		\
+	"SDRAM_CS0",	/* SDRAM_CS0 */		\
+	"SDRAM_CS1",	/* SDRAM_CS1 */		\
+	"SDRAM_CS2",	/* SDRAM_CS1 */		\
+	"SDRAM_CS3",	/* SDRAM_CS1 */		\
+	"DEVICE_CS0",	/* DEVICE_CS0 */	\
+	"DEVICE_CS1",	/* DEVICE_CS1 */	\
+	"DEVICE_CS2",	/* DEVICE_CS2 */	\
+	"DEVICE_CS3",	/* DEVICE_CS3 */	\
+	"PEX0_MEM",	/* PEX0_MEM */		\
+	"PEX0_IO",	/* PEX0_IO */		\
+	"PEX1_MEM",	/* PEX1_MEM */		\
+	"PEX1_IO",	/* PEX1_IO */		\
+	"PEX2_MEM",	/* PEX2_MEM */		\
+	"PEX2_IO",	/* PEX2_IO */		\
+	"PEX3_MEM",	/* PEX3_MEM */		\
+	"PEX3_IO",	/* PEX3_IO */		\
+	"PEX4_MEM",	/* PEX4_MEM */		\
+	"PEX4_IO",	/* PEX4_IO */		\
+	"PEX5_MEM",	/* PEX5_MEM */		\
+	"PEX5_IO",	/* PEX5_IO */		\
+	"PEX6_MEM",	/* PEX6_MEM */		\
+	"PEX6_IO",	/* PEX6_IO */		\
+	"PEX7_MEM",	/* PEX7_MEM */		\
+	"PEX7_IO",	/* PEX7_IO */		\
+	"PEX8_MEM",	/* PEX8_MEM */		\
+	"PEX8_IO",	/* PEX8_IO */		\
+	"PEX9_MEM",	/* PEX9_MEM */		\
+	"PEX9_IO",	/* PEX9_IO */		\
+	"INTER_REGS",	/* INTER_REGS */	\
+	"DMA_UART",	/* DMA_UART */		\
+	"SPI_CS0",	/* SPI_CS0 */		\
+	"SPI_CS1",	/* SPI_CS1 */		\
+	"SPI_CS2",	/* SPI_CS2 */		\
+	"SPI_CS3",	/* SPI_CS3 */		\
+	"SPI_CS4",	/* SPI_CS4 */		\
+	"SPI_CS5",	/* SPI_CS5 */		\
+	"SPI_CS6",	/* SPI_CS6 */		\
+	"SPI_CS7",	/* SPI_CS7 */		\
+	"BOOT_ROM_CS",	/* BOOT_ROM_CS */	\
+	"DEV_BOOTCS",	/* DEV_BOOCS */		\
+	"PMU_SCRATCHPAD",/* PMU_SCRATCHPAD */	\
+	"CRYPT1_ENG",	/* CRYPT1_ENG */	\
+	"CRYPT2_ENG",	/* CRYPT2_ENG */	\
+	"PNC_BM"	/* PNC_BM */		\
+}
+
 #endif /* MV_ASMLANGUAGE */
 
 #ifdef __cplusplus
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.c b/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.c
index d71df4e..de6c496 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.c
@@ -42,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-        notice, this list of conditions and the following disclaimer in the
-        documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-        used to endorse or promote products derived from this software without
-        specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.h
index 8b8994c..9ac8134 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvSemaphore.h
@@ -42,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-        notice, this list of conditions and the following disclaimer in the
-        documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-        used to endorse or promote products derived from this software without
-        specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvAhbToMbus.c b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvAhbToMbus.c
index e4608ab..0229d22 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvAhbToMbus.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvAhbToMbus.c
@@ -255,7 +255,10 @@
 
 	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) {
 		pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
-		pAddrDecWin->target = INTER_REGS;
+		if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+			pAddrDecWin->target = (MV_U8)INTER_REGS_AXP;
+		else
+			pAddrDecWin->target = INTER_REGS;
 		pAddrDecWin->enable = MV_TRUE;
 
 		return MV_OK;
@@ -301,7 +304,7 @@
 		return 0xffffffff;
 	}
 
-	if (INTER_REGS == target)
+	if (INTER_REGS == target || (MV_U8)INTER_REGS_AXP == target)
 		return MV_AHB_TO_MBUS_INTREG_WIN;
 
 	for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++) {
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIf.c b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIf.c
index 58db349..b5d2632 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIf.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIf.c
@@ -156,7 +156,7 @@
 	/* Set IO Bypass base address and size according to the cpuAddrWinMap */
 	for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) {
 		if ((MV_TARGET_IS_DRAM(target)) || (DIS == cpuAddrWinMap[target].enable) ||
-		    (target == INTER_REGS))
+		    (target == INTER_REGS) || (target == (MV_U8)INTER_REGS_AXP))
 			continue;
 		if (cpuAddrWinMap[target].addrWin.baseLow == 0)
 			continue;
@@ -190,7 +190,8 @@
 
 	/* First disable all CPU target windows  */
 	for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) {
-		if ((MV_TARGET_IS_DRAM(target)) || (target == INTER_REGS))
+		if ((MV_TARGET_IS_DRAM(target)) || (target == INTER_REGS) ||
+		    (target == (MV_U8)INTER_REGS_AXP))
 			continue;
 
 #if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
@@ -720,9 +721,23 @@
 	MV_U32 winNum;
 
 	/* Check parameters */
-	if (!MV_TARGET_IS_PEX0(pexTarget)) {
-		mvOsPrintf("mvCpuIfPexRemap: target %d is illegal\n", pexTarget);
-		return 0xffffffff;
+	if (mvCtrlPexMaxIfGet() > 1) {
+		if ((!MV_TARGET_IS_PEX0(pexTarget)) &&
+			(!MV_TARGET_IS_PEX1(pexTarget)) &&
+			(!MV_TARGET_IS_PEX2(pexTarget)) &&
+			(!MV_TARGET_IS_PEX3(pexTarget)) &&
+			(!MV_TARGET_IS_PEX4(pexTarget)) &&
+			(!MV_TARGET_IS_PEX5(pexTarget)) &&
+			(!MV_TARGET_IS_PEX6(pexTarget)) &&
+			(!MV_TARGET_IS_PEX7(pexTarget)) &&
+			(!MV_TARGET_IS_PEX8(pexTarget)) &&
+			(!MV_TARGET_IS_PEX9(pexTarget))) {
+			mvOsPrintf("mvCpuIfPexRemap: target %d is illegal\n", pexTarget);
+			return 0xffffffff;
+		}
+	} else if (!MV_TARGET_IS_PEX0(pexTarget)) {
+			mvOsPrintf("mvCpuIfPexRemap: target %d is illegal\n", pexTarget);
+			return 0xffffffff;
 	}
 
 	/* get the Window number associated with this target */
@@ -940,3 +955,32 @@
 
 	return MV_OK;
 }
+
+/*******************************************************************************
+* mvCpuIfMbusWindowSet
+*
+* DESCRIPTION:
+*	Set Mbus Bridge Window register
+*
+* INPUT:
+*	Windows Base Address
+*
+* OUTPUT:
+*       None.
+*
+* RETURN:
+*       None.
+*
+*******************************************************************************/
+MV_VOID mvCpuIfMbusWindowSet(MV_U32 base, MV_U32 size)
+{
+	MV_U32 reg;
+
+	MV_REG_WRITE(MBUS_BRIDGE_WIN_BASE_REG, base);
+	/* Align window size to 64KB */
+	size = ((size / _64K) - 1) << BRIDGWCR_SIZE_OFFS;
+	reg = MV_REG_READ(MBUS_BRIDGE_WIN_CTRL_REG);
+	reg &= ~BRIDGWCR_SIZE_MASK;
+	reg |= (size & BRIDGWCR_SIZE_MASK);
+	MV_REG_WRITE(MBUS_BRIDGE_WIN_CTRL_REG, reg);
+}
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIfRegs.h b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIfRegs.h
index 0c6c14f..f795ecf 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIfRegs.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/sys/mvCpuIfRegs.h
@@ -348,6 +348,17 @@
 #define CPU_ARM_TO_HOST_DRBL_REG(cpu)		(MV_CPUIF_REGS_BASE(cpu) + 0x70)
 #define CPU_ARM_TO_HOST_MASK_REG(cpu)		(MV_CPUIF_REGS_BASE(cpu) + 0x74)
 
+/*******************************************/
+/* CLOCK Complex Registers Map - AXP only  */
+/*******************************************/
+
+#define CPU_DIV_CLK_CTRL0_REG			(MV_CLK_CMPLX_REGS_OFFSET)
+#define CPU_DIV_CLK_CTRL0_RESET_MASK_OFFS	8
+#define CPU_DIV_CLK_CTRL2_RATIO_FULL0_REG	(MV_CLK_CMPLX_REGS_OFFSET + 0x8)
+#define CPU_DIV_CLK_CTRL2_NB_RATIO_OFFS		16
+#define CPU_DIV_CLK_CTRL3_RATIO_FULL1_REG	(MV_CLK_CMPLX_REGS_OFFSET + 0xC)
+#define CPU_DIV_CLK_CTRL3_CPU_RATIO_OFFS	8
+
 /* CPU control register map */
 /* Set bits means value is about to change according to new value */
 #define CPU_CONFIG_DEFAULT_MASK         	(CCR_VEC_INIT_LOC_MASK)
diff --git a/board/mv_ebu/msys/msys_family/device/mvDeviceRegs.h b/board/mv_ebu/msys/msys_family/device/mvDeviceRegs.h
index 413abd8..69bd8aa 100644
--- a/board/mv_ebu/msys/msys_family/device/mvDeviceRegs.h
+++ b/board/mv_ebu/msys/msys_family/device/mvDeviceRegs.h
@@ -76,6 +76,8 @@
 	switch (num) {
 	case (DEV_BOOCS):
 		return MV_DEV_BUS_REGS_OFFSET + 0x00;
+	case (DEV_BOOCS_AXP):
+		return MV_DEV_BUS_REGS_OFFSET + 0x00;
 	case (DEVICE_CS0):
 		return MV_DEV_BUS_REGS_OFFSET + 0x08;
 	case (DEVICE_CS1):
diff --git a/board/mv_ebu/msys/mvSysHwConfig.h b/board/mv_ebu/msys/mvSysHwConfig.h
index e7d490e..aaf184e 100644
--- a/board/mv_ebu/msys/mvSysHwConfig.h
+++ b/board/mv_ebu/msys/mvSysHwConfig.h
@@ -135,6 +135,7 @@
 #define SWITCH_REGS_BASE		0xA8000000
 #define SWITCH_REGS_SIZE		_64M
 #define SWITCH_REGS_VIRT_BASE	SWITCH_REGS_BASE
+#define SWITCH_WIN_ID			5
 /************************************************************/
 /* Device: CS0 - NOR or NAND, CS1 - SPI, CS2 - Boot ROM, CS3 - Boot device */
 /* NOR and NAND are configure to CS0 but it is posible to load
@@ -252,7 +253,7 @@
 		{ { PEX0_IO_BASE,         0,      PEX0_IO_SIZE    },      TBL_UNUSED,     DIS },        /*  9 PEX0_IO */	\
 		{ { INTER_REGS_BASE,      0, INTER_REGS_SIZE }, MV_AHB_TO_MBUS_INTREG_WIN, EN },        /* 10 INTER_REGS */ \
 		{ { DFX_REGS_BASE,        0,      DFX_REGS_SIZE   },      1,               EN },        /* 11 DFX_REGS */ \
-		{ { SWITCH_REGS_BASE,     0,     SWITCH_REGS_SIZE },      5,               EN },        /* 12 SWITCH   */ \
+		{ { SWITCH_REGS_BASE,     0,     SWITCH_REGS_SIZE },      SWITCH_WIN_ID,   EN },        /* 12 SWITCH   */ \
 		{ { TBL_UNUSED,           0,      TBL_UNUSED      },      TBL_UNUSED,     DIS },        /* 13 DMA_UART   */ \
 		{ { SPI_CS_BASE,          0,      SPI_CS_SIZE     },      8,               EN },        /* 14 SPI_CS0 */	\
 		{ { TBL_UNUSED,           0,      TBL_UNUSED      },      TBL_UNUSED,     DIS },        /* 15 SPI_CS1 */	\
diff --git a/boards.cfg b/boards.cfg
index f497b89..4a01430 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -54,6 +54,7 @@
 armada_38x                   arm         armv7       a38x                mv_ebu         mvca9        armada_38x:ARMADA_38X
 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
diff --git a/build.pl b/build.pl
index 17b9968..d786ee1 100755
--- a/build.pl
+++ b/build.pl
@@ -13,14 +13,14 @@
 	print "Options:\n";
 	print "\t-f\tBoot device. Accepts spi, nor, nand, mmc\n";
 	print "\t-b\tBoard type. Accepts:\tavanta_lp , avanta_lp_customer0 , avanta_lp_customer1\n";
-	print "\t\t\t\t\tarmada_38x, armada_38x_customer0, armada_38x_customer1\n";
+	print "\t\t\t\t\tarmada_38x, armada_38x_clearfog, armada_38x_customer0, armada_38x_customer1\n";
 	print "\t\t\t\t\tarmada_39x, armada_39x_customer0, armada_39x_customer1\n";
 	print "\t\t\t\t\tarmada_375, armada_375_customer0, armada_375_customer1\n";
 	print "\t\t\t\t\tbobcat2_db, bobcat2_rd, bobcat2_customer0, bobcat2_customer1\n";
 	print "\t\t\t\t\tac3_db, ac3_rd, ac3_customer0, ac3_customer1\n";
 	print "\t-o\tOutput dir/file. The image will be copied into this dir/file\n";
 	print "\t-e\tBig Endian. If not specified Little endian is used\n";
-	print "\t-m\tDDR type(default: DDR3). Accepts: 3 for DDR3, 4 for DDR4\n";
+ 	print "\t-m\tDDR type(default: DDR4 for A39x, DDR3 for the rest). Accepts: 3 for DDR3, 4 for DDR4\n";
 	print "\t-i\tSupported interfaces, seperated by \":\" -  Accepts [spi:nor:nand]\n";
 	print "\t-v\tSW version (in file name: u-boot-alp-X.X.X-spi.bin, else using date by default)\n";
 	print "\t\tinterfaces. Supports spi, nor, nand. the boot \n";
@@ -94,6 +94,7 @@
 	($opt_b eq "armada_375_customer0") or
 	($opt_b eq "armada_375_customer1") or
 	($opt_b eq "armada_38x") or
+	($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
@@ -111,19 +112,24 @@
 	($opt_b eq "ac3_customer1") )
 {
 	$board = $opt_b;
+	$ddr3LibBuild="yes";
 	if( (substr $board,7 , 3) eq "370" ) {
 		$boardID="a370";
 		$targetBoard = substr $board, 11;
+		$ddr3LibBuild="no";
 	}
 	elsif ( (substr $board,7 , 2) eq "xp" ) {
 		$boardID="axp";
 		$targetBoard = substr $board, 10;
+		$ddr3LibBuild="no";
 	}
 	elsif ( (substr $board,7 , 2) eq "lp" ) {
 		$boardID="alp";
+		$ddr3LibBuild="no";
 	}
 	elsif ( (substr $board,7 , 3) eq "375" ) {
 		$boardID="a375";
+		$ddr3LibBuild="no";
 	}
 	elsif ( (substr $board,7 , 3) eq "38x" ) {
 		$boardID="a38x";
@@ -139,10 +145,12 @@
 		$boardID="msys-ac3";
 		$targetBoard = substr $board, 8;
 	}
-	# if board string contains "customer", use customer define for binary_header
-	if (index($board, "customer") != -1 || index($board, "gfch100") != -1){
-		system("echo \"#define CONFIG_CUSTOMER_BOARD_SUPPORT 1\" >> include/config.h");
+	# 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)
+		or (index($board, "gfch100") != -1)) {
+			system("echo \"#define CONFIG_CUSTOMER_BOARD_SUPPORT 1\" >> include/config.h");
 	}
+
 }
 else
 {
@@ -344,6 +352,19 @@
 	print "\n";
 }
 
+if($opt_d eq 4)
+{
+	system("echo \"DDR4SUBLIB = yes\" >> include/config.mk");
+	print "** Rebuild DDR4 sublib **\n";
+	$opt_d = 2;
+}
+
+#by default -d 2 will be enabled for new TIP SoCs
+if(($ddr3LibBuild eq "yes") && !((substr $board,7 , 3) eq "39x"))
+{
+	$opt_d = 2;
+}
+
 if(defined $opt_d)
 {
 	system("echo \"DDR3LIB = $opt_d\" >> include/config.mk");
@@ -439,6 +460,7 @@
 print "\n**** [Creating Image]\t*****\n\n";
 
 $failUart = system("./tools/marvell/doimage -T uart -D 0 -E 0 -G ./tools/marvell/bin_hdr/bin_hdr.uart.bin u-boot.bin u-boot-$boardID-$opt_v-$flash_name$targetBoard-uart.bin");
+$failDebug = system("./tools/marvell/doimage -T uart -D 0 -E 0 -H 3 -G ./tools/marvell/bin_hdr/bin_hdr.debug.bin u-boot.bin u-boot-$boardID-$opt_v-$flash_name$targetBoard-debug.bin");
 $fail = system("./tools/marvell/doimage -T $img_type -D 0x0 -E 0x0 $img_opts $rsa_opts $id_opts $extra_opt -G ./tools/marvell/bin_hdr/$bin_hdr_n u-boot.bin u-boot-$boardID-$opt_v-$flash_name$targetBoard.bin");
 
 if($fail){
@@ -449,6 +471,10 @@
 	print "\n *** Error: Doimage for uart image failed\n\n";
 	exit 1;
 }
+if($failDebug){
+	print "\n *** Error: Doimage for debug image failed\n\n";
+	exit 1;
+}
 
 if(defined $opt_o)
 {
diff --git a/common/cmd_disk.c b/common/cmd_disk.c
index ee4e215..8c4d0bd 100644
--- a/common/cmd_disk.c
+++ b/common/cmd_disk.c
@@ -67,7 +67,8 @@
 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
 	       info.type);
 
-	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+	debug("First Block: " LBAFU ",  # of blocks: " LBAFU
+	      ", Block Size: %ld\n",
 	      info.start, info.size, info.blksz);
 
 	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 4380794..6b55ca8 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1576,6 +1576,8 @@
 /***************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char i2c_help_text[] =
+	"address.[.0, .2] = Address length [byte, 2byte]"
+	"xx.[.b, .w, .l]  = Returned Data length [byte, 2byte, 4byte]"
 #if defined(CONFIG_I2C_MUX)
 	"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
 #endif  /* CONFIG_I2C_MUX */
@@ -1588,9 +1590,9 @@
 #endif  /* CONFIG_I2C_EDID */
 	"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
 	"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
-	"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
-	"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
-	"i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n"
+	"i2c mm[.b, .w, .l] chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
+	"i2c nm[.b, .w, .l] chip address[.0, .1, .2] - write to I2C device (constant address)\n"
+	"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill constant value)\n"
 	"i2c probe [address] - test for and show device(s) on the I2C bus\n"
 	"i2c read chip address[.0, .1, .2] length memaddress - read to memory \n"
 	"i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n"
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 642ed4b..1826e1e 100755
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -866,6 +866,19 @@
 	/* verify if we have a valid device specified */
 	if ((id = id_find_by_mtd_id(mtd_id, mtd_id_len - 1)) == NULL) {
 		printf("invalid mtd device '%.*s'\n", mtd_id_len - 1, mtd_id);
+		/* let 'p' point to the start of the next device in order
+		 * to try to parse it in the next iteration
+		 * example: mtdparts=spi_flash:4m(boot),-(spi-rootfs);armada-nand:8m...
+		 * when failing to recognize 'spi_flash', let 'p' point to the start
+		 * of 'armada-nand'
+		 * */
+		p = strchr(p, ';');
+		if (ret) {
+			if (p)
+				*ret = ++p;
+			else
+				*ret = NULL;
+		}
 		return 1;
 	}
 
@@ -928,7 +941,12 @@
 		if (*p == ';') {
 			if (ret)
 				*ret = ++p;
-		} else if (*p == '\0') {
+		} else if (*p == '\0' || (*p == '\'' && *(p+1) == '\0')) {
+			/* ignore ' if it is the last character, in case 'mtdparts' is wrapped
+			 * with quotation marks.
+			 * example: mtdparts='mtdparts=spi_flash:4m(boot),-(spi-rootfs);armada-nand:8m...'
+			 * ignore the last character (quotation mark '), and don't print error message on it
+			 * */
 			if (ret)
 				*ret = p;
 		} else {
@@ -1551,6 +1569,14 @@
 	/* re-read 'mtdparts' variable, mtd_devices_init may be updating env */
 	p = getenv("mtdparts");
 
+	/* ignore ' if it is the first character, in case 'mtdparts' is wrapped
+	 * with quotation marks.
+	 * example: mtdparts='mtdparts=spi_flash:4m(boot),-(spi-rootfs);armada-nand:8m...'
+	 * ignore the first character (quotation mark '), and don't print error
+	 * */
+	if (*p == '\'')
+		p++;
+
 	if (strncmp(p, "mtdparts=", 9) != 0) {
 		printf("mtdparts variable doesn't start with 'mtdparts='\n");
 		return err;
@@ -1559,8 +1585,12 @@
 
 	while (p && (*p != '\0')) {
 		err = 1;
-		if ((device_parse(p, &p, &dev) != 0) || (!dev))
-			break;
+		if ((device_parse(p, &p, &dev) != 0) || (!dev)) {
+			/* try to parse next device if the current device fails
+			 * 'p' will point to the next device */
+			err = 0;
+			continue;
+		}
 
 		debug("+ device: %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type),
 				dev->id->num, dev->id->mtd_id);
@@ -1619,8 +1649,17 @@
 
 		ret = 1;
 		/* parse 'nor'|'nand'|'onenand'<dev-num> */
-		if (mtd_id_parse(p, &p, &type, &num) != 0)
-			break;
+		if (mtd_id_parse(p, &p, &type, &num) != 0) {
+			/* let 'p' point to the next <idmap>, when the current <idmap> parsing fails.
+			 * example: mtdids=spi0=spi_flash,nand0=armada-nand
+			 * when failing to parse spi0, let 'p' point to the start of nand0=armada-nand
+			 */
+			p = strchr(p, ',');
+			if (p)
+				p++;
+			ret = 0;
+			continue;
+		}
 
 		if (*p != '=') {
 			printf("mtdids: incorrect <dev-num>\n");
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index 62f2042..977bde9 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -112,6 +112,14 @@
 	lbaint_t capacity;
 	unsigned long blksz;
 	ccb* pccb=(ccb *)&tempccb;
+	static int scsi_detected = 0;
+
+	if (scsi_detected) {
+		printf("** scsi detection can run only once - please");
+		printf(" reset board before running detection again **\n");
+		return;
+	}
+	scsi_detected = 1;
 
 	if(mode==1) {
 		printf("scanning bus for devices...\n");
@@ -517,7 +525,7 @@
 		      __func__, start, smallblks, buf_addr);
 		if (scsi_exec(pccb) != TRUE) {
 			scsi_print_error(pccb);
-			blkcnt -= blks;
+			blkcnt -= (blks + smallblks);
 			break;
 		}
 		buf_addr += pccb->datalen;
diff --git a/disk/part_efi.c b/disk/part_efi.c
old mode 100755
new mode 100644
index 112b438..6fb5d46
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -206,8 +206,8 @@
 	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
 #endif
 
-	debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
-		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 */
 	free(gpt_pte);
@@ -442,7 +442,7 @@
 			gpt_e[i].partition_name[k] =
 				(efi_char16_t)(partitions[i].name[k]);
 
-		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
 		      __func__, partitions[i].name, i,
 		      offset, i, partitions[i].size);
 	}
diff --git a/disk/part_iso.c b/disk/part_iso.c
index baeced7..49bff15 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -261,8 +261,8 @@
 	printf("Part   Start     Sect x Size Type\n");
 	i=0;
 	do {
-		printf (" %2d %8ld %8ld %6ld %.32s\n",
-			i, info.start, info.size, info.blksz, info.type);
+		printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n",
+		       i, info.start, info.size, info.blksz, info.type);
 		i++;
 	} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
 }
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index d9767b3..04c1729 100755
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -503,6 +503,20 @@
 	pp->cmd_slot->tbl_addr_hi = 0;
 }
 
+static int wait_spinup(volatile u8 *port_mmio)
+{
+	ulong start;
+	u32 tf_data;
+
+	start = get_timer(0);
+	do {
+		tf_data = readl(port_mmio + PORT_TFDATA);
+		if (!(tf_data & ATA_BUSY))
+			return 0;
+	} while (get_timer(start) < WAIT_MS_SPINUP);
+
+	return -ETIMEDOUT;
+}
 
 #ifdef CONFIG_AHCI_SETFEATURES_XFER
 static void ahci_set_feature(struct ahci_probe_ent *probe_ent, u8 port)
@@ -595,7 +609,11 @@
 
 	debug("Exit start port %d\n", port);
 
-	return 0;
+	/*
+	 * Make sure interface is not busy based on error and status
+	 * information from task file data register before proceeding
+	 */
+	return wait_spinup(port_mmio);
 }
 
 
@@ -1065,6 +1083,14 @@
 	fis[1] = 1 << 7;	 /* Command FIS. */
 	fis[2] = ATA_CMD_FLUSH_EXT;
 
+	/* Clear IRQ status register
+	 * before issuing the flush command to the controller, make
+	 * sure IRQ status register is flushed (in case a previous
+	 * transaction ended, without clearing it). ** Flush command
+	 * will not start/complete unless clearing IRQ **
+	 * */
+	writel_with_flush(0xffffffff, port_mmio + PORT_IRQ_STAT);
+
 	memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
 	ahci_fill_cmd_slot(pp, cmd_fis_len);
 	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 3bab739..7227bfd 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -149,8 +149,8 @@
 	int trans_bytes = 0, is_aligned = 1;
 	u32 mask, flags, mode;
 	unsigned int time = 0, start_addr = 0;
-	unsigned int retry = 10000;
 	int mmc_dev = mmc->block_dev.dev;
+	unsigned start = get_timer(0);
 
 	/* Timeout unit - ms */
 	static unsigned int cmd_timeout = CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT;
@@ -236,6 +236,7 @@
 	flush_cache(start_addr, trans_bytes);
 #endif
 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
+	start = get_timer(0);
 	do {
 		stat = sdhci_readl(host, SDHCI_INT_STATUS);
 		if (stat & SDHCI_INT_ERROR)
@@ -247,11 +248,10 @@
 			cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 			udelay(5);
 #endif
-		if (--retry == 0)
-			break;
-	} while ((stat & mask) != mask);
+	} while (((stat & mask) != mask) &&
+		 (get_timer(start) < CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT));
 
-	if (retry == 0) {
+	if (get_timer(start) >= CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT) {
 		if (host->quirks & SDHCI_QUIRK_BROKEN_R1B)
 			return 0;
 		else {
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index d79bc1c..ed40ab6 100755
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -121,7 +121,7 @@
 	board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
 #endif
 }
-#if defined(CONFIG_ENV_IS_IN_NAND)
+
 int nand_get_env_offs(void)
 {
 	size_t offset = 0;
@@ -145,7 +145,7 @@
                         offset = (i + 1) * blocksize;
                 }
                 i++;
-                if (sum >= CONFIG_ENV_RANGE)
+                if (sum >= CONFIG_ENV_RANGE_NAND)
                         break;
 
         }
@@ -166,11 +166,10 @@
 	size_t env_size = 0;
 	size_t blocksize = nand_info[0].erasesize;
 
-	if (blocksize < CONFIG_ENV_SIZE) {
-		env_size = ((CONFIG_ENV_SIZE + (blocksize - 1)) & (~(blocksize-1)));
+	if (blocksize < CONFIG_ENV_SIZE_NAND) {
+		env_size = ((CONFIG_ENV_SIZE_NAND + (blocksize - 1)) & (~(blocksize-1)));
 		return env_size;
 	} else
 		return blocksize;
 }
-#endif
 
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
index bc4fcdb..e2163dd 100644
--- a/drivers/net/sk98lin/h/skaddr.h
+++ b/drivers/net/sk98lin/h/skaddr.h
@@ -156,6 +156,7 @@
 
 typedef struct s_MacAddr {
 	SK_U8	a[SK_MAC_ADDR_LEN];
+	SK_U16	DummyAlignWord; /* Dummy entry for 32bit alignment only. */
 } SK_MAC_ADDR;
 
 
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 5981200..c55300d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -119,7 +119,7 @@
 	},
 };
 
-static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_HOST_COUNT];
 
 /**
  * Waits for as per specified amount of time
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 464a67d..dcbb17f 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -41,7 +41,7 @@
 #include <ext4fs.h>
 #include <ext_common.h>
 
-unsigned long part_offset;
+lbaint_t part_offset;
 
 static block_dev_desc_t *ext4fs_block_dev_desc;
 static disk_partition_t *part_info;
@@ -55,7 +55,7 @@
 	get_fs()->dev_desc = rbdd;
 }
 
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE);
 	unsigned block_len;
@@ -64,7 +64,7 @@
 	if ((sector < 0)
 	    || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
 		part_info->size)) {
-		printf("%s read outside partition %d\n", __func__, sector);
+		printf("%s read outside partition " LBAFU "\n", __func__, sector);
 		return 0;
 	}
 
@@ -72,7 +72,7 @@
 	sector += byte_offset >> SECTOR_BITS;
 	byte_offset &= SECTOR_SIZE - 1;
 
-	debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
+	debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
 
 	if (ext4fs_block_dev_desc == NULL) {
 		printf("** Invalid Block Device Descriptor (NULL)\n");
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index bcc9dc8..c6185ca 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -84,7 +84,7 @@
 
 	if ((startblock + (size / SECTOR_SIZE)) >
 	    (part_offset + fs->total_sect)) {
-		printf("part_offset is %lu\n", part_offset);
+		printf("part_offset is " LBAFU "\n", part_offset);
 		printf("total_sector is %llu\n", fs->total_sect);
 		printf("error: overflow occurs\n");
 		return;
@@ -405,7 +405,7 @@
 		previous_blknr = root_blknr;
 	}
 
-	status = ext4fs_devread(first_block_no_of_root
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root
 				* fs->sect_perblk,
 				0, fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -457,9 +457,9 @@
 					goto fail;
 				}
 				put_ext4(((uint64_t)
-					  (g_parent_inode->b.
+					  ((uint64_t)g_parent_inode->b.
 					   blocks.dir_blocks[direct_blk_idx] *
-					   fs->blksz)), zero_buffer, fs->blksz);
+					   (uint64_t)fs->blksz)), zero_buffer, fs->blksz);
 				g_parent_inode->size =
 				    g_parent_inode->size + fs->blksz;
 				g_parent_inode->blockcnt =
@@ -545,7 +545,7 @@
 		if (!block_buffer)
 			goto fail;
 
-		status = ext4fs_devread(blknr * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 					0, fs->blksz, (char *)block_buffer);
 		if (status == 0)
 			goto fail;
@@ -783,7 +783,7 @@
 	if (!root_first_block_buffer)
 		return -ENOMEM;
 	root_first_block_addr = root_first_block_buffer;
-	status = ext4fs_devread(first_block_no_of_root *
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root *
 				fs->sect_perblk, 0,
 				fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -876,8 +876,8 @@
 		for (i = 0; i < fs->no_blkgrp; i++) {
 			if (bgd[i].free_blocks) {
 				if (bgd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) {
-					put_ext4(((uint64_t) (bgd[i].block_id *
-							      fs->blksz)),
+					put_ext4(((uint64_t) ((uint64_t)bgd[i].block_id *
+							      (uint64_t)fs->blksz)),
 						 zero_buffer, fs->blksz);
 					bgd[i].bg_flags =
 					    bgd[i].
@@ -895,7 +895,8 @@
 				fs->first_pass_bbmap++;
 				bgd[i].free_blocks--;
 				fs->sb->free_blocks--;
-				status = ext4fs_devread(bgd[i].block_id *
+				status = ext4fs_devread((lbaint_t)
+							bgd[i].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -940,8 +941,8 @@
 
 		if (bgd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) {
 			memset(zero_buffer, '\0', fs->blksz);
-			put_ext4(((uint64_t) (bgd[bg_idx].block_id *
-					fs->blksz)), zero_buffer, fs->blksz);
+			put_ext4(((uint64_t) ((uint64_t)bgd[bg_idx].block_id *
+					(uint64_t)fs->blksz)), zero_buffer, fs->blksz);
 			memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
 			bgd[bg_idx].bg_flags = bgd[bg_idx].bg_flags &
 						~EXT4_BG_BLOCK_UNINIT;
@@ -957,7 +958,7 @@
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1007,8 +1008,8 @@
 						bgd[i].free_inodes;
 				if (bgd[i].bg_flags & EXT4_BG_INODE_UNINIT) {
 					put_ext4(((uint64_t)
-						  (bgd[i].inode_id *
-							fs->blksz)),
+						  ((uint64_t)bgd[i].inode_id *
+							(uint64_t)fs->blksz)),
 						 zero_buffer, fs->blksz);
 					bgd[i].bg_flags = bgd[i].bg_flags &
 							~EXT4_BG_INODE_UNINIT;
@@ -1026,7 +1027,8 @@
 				bgd[i].free_inodes--;
 				bgd[i].bg_itable_unused--;
 				fs->sb->free_inodes--;
-				status = ext4fs_devread(bgd[i].inode_id *
+				status = ext4fs_devread((lbaint_t)
+							bgd[i].inode_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -1047,8 +1049,8 @@
 		ibmap_idx = fs->curr_inode_no / inodes_per_grp;
 		if (bgd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) {
 			memset(zero_buffer, '\0', fs->blksz);
-			put_ext4(((uint64_t) (bgd[ibmap_idx].inode_id *
-					      fs->blksz)), zero_buffer,
+			put_ext4(((uint64_t) ((uint64_t)bgd[ibmap_idx].inode_id *
+					      (uint64_t)fs->blksz)), zero_buffer,
 				 fs->blksz);
 			bgd[ibmap_idx].bg_flags =
 			    bgd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT;
@@ -1067,7 +1069,8 @@
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[ibmap_idx].inode_id
+			status = ext4fs_devread((lbaint_t)
+						bgd[ibmap_idx].inode_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1129,7 +1132,7 @@
 		(*no_blks_reqd)++;
 		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);
 
-		status = ext4fs_devread(si_blockno * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
 					0, fs->blksz, (char *)si_buffer);
 		memset(si_buffer, '\0', fs->blksz);
 		if (status == 0)
@@ -1152,7 +1155,7 @@
 		}
 
 		/* write the block to disk */
-		put_ext4(((uint64_t) (si_blockno * fs->blksz)),
+		put_ext4(((uint64_t) ((uint64_t)si_blockno * (uint64_t)fs->blksz)),
 			 si_start_addr, fs->blksz);
 		file_inode->b.blocks.indir_block = si_blockno;
 	}
@@ -1193,7 +1196,7 @@
 		debug("DIPB %ld: %u\n", di_blockno_parent,
 		      *total_remaining_blocks);
 
-		status = ext4fs_devread(di_blockno_parent *
+		status = ext4fs_devread((lbaint_t)di_blockno_parent *
 					fs->sect_perblk, 0,
 					fs->blksz, (char *)di_parent_buffer);
 
@@ -1224,7 +1227,7 @@
 			debug("DICB %ld: %u\n", di_blockno_child,
 			      *total_remaining_blocks);
 
-			status = ext4fs_devread(di_blockno_child *
+			status = ext4fs_devread((lbaint_t)di_blockno_child *
 						fs->sect_perblk, 0,
 						fs->blksz,
 						(char *)di_child_buff);
@@ -1251,7 +1254,7 @@
 					break;
 			}
 			/* write the block  table */
-			put_ext4(((uint64_t) (di_blockno_child * fs->blksz)),
+			put_ext4(((uint64_t) ((uint64_t)di_blockno_child * (uint64_t)fs->blksz)),
 				 di_child_buff_start, fs->blksz);
 			free(di_child_buff_start);
 			di_child_buff_start = NULL;
@@ -1259,7 +1262,7 @@
 			if (*total_remaining_blocks == 0)
 				break;
 		}
-		put_ext4(((uint64_t) (di_blockno_parent * fs->blksz)),
+		put_ext4(((uint64_t) ((uint64_t)di_blockno_parent * (uint64_t)fs->blksz)),
 			 di_block_start_addr, fs->blksz);
 		file_inode->b.blocks.double_indir_block = di_blockno_parent;
 	}
@@ -1357,8 +1360,8 @@
 						break;
 				}
 				/* write the child block */
-				put_ext4(((uint64_t) (ti_child_blockno *
-						      fs->blksz)),
+				put_ext4(((uint64_t) ((uint64_t)ti_child_blockno *
+						      (uint64_t)fs->blksz)),
 					 ti_cbuff_start_addr, fs->blksz);
 				free(ti_cbuff_start_addr);
 
@@ -1366,7 +1369,7 @@
 					break;
 			}
 			/* write the parent block */
-			put_ext4(((uint64_t) (ti_parent_blockno * fs->blksz)),
+			put_ext4(((uint64_t) ((uint64_t)ti_parent_blockno * (uint64_t)fs->blksz)),
 				 ti_pbuff_start_addr, fs->blksz);
 			free(ti_pbuff_start_addr);
 
@@ -1374,7 +1377,7 @@
 				break;
 		}
 		/* write the grand parent block */
-		put_ext4(((uint64_t) (ti_gp_blockno * fs->blksz)),
+		put_ext4(((uint64_t) ((uint64_t)ti_gp_blockno * (uint64_t)fs->blksz)),
 			 ti_gp_buff_start_addr, fs->blksz);
 		file_inode->b.blocks.triple_indir_block = ti_gp_blockno;
 	}
@@ -1447,7 +1450,8 @@
 		block = le32_to_cpu(index[i].ei_leaf_hi);
 		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
 
-		if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
+		if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz,
+				   buf))
 			ext_block = (struct ext4_extent_header *)buf;
 		else
 			return 0;
@@ -1469,7 +1473,7 @@
 	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
 	      group, blkno, blkoff);
 
-	return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data),
+	return ext4fs_devread((lbaint_t)blkno << LOG2_EXT2_BLOCK_SIZE(data),
 			      blkoff, sizeof(struct ext2_block_group),
 			      (char *)blkgrp);
 }
@@ -1495,7 +1499,7 @@
 	    (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
-	status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff,
+	status = ext4fs_devread((lbaint_t)blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff,
 				sizeof(struct ext2_inode), (char *)inode);
 	if (status == 0)
 		return 0;
@@ -1592,7 +1596,7 @@
 		if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    indir_block) << log2_blksz, 0,
 					   blksz, (char *)ext4fs_indir1_block);
@@ -1641,7 +1645,7 @@
 		if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    double_indir_block) << log2_blksz,
 					   0, blksz,
@@ -1681,7 +1685,7 @@
 		}
 		if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
 		     log2_blksz) != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock]) << log2_blksz, 0,
@@ -1733,7 +1737,8 @@
 		if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status = ext4fs_devread
-			    (__le32_to_cpu(inode->b.blocks.triple_indir_block)
+			    ((lbaint_t)
+			     __le32_to_cpu(inode->b.blocks.triple_indir_block)
 			     << log2_blksz, 0, blksz,
 			     (char *)ext4fs_indir1_block);
 			if (status == 0) {
@@ -1773,7 +1778,7 @@
 						       perblock_parent]) <<
 		     log2_blksz)
 		    != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock_parent]) <<
@@ -1818,7 +1823,7 @@
 						       perblock_child]) <<
 		     log2_blksz) != ext4fs_indir3_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (ext4fs_indir2_block
 					    [(rblock / perblock_child)
 					     % (blksz / 4)]) << log2_blksz, 0,
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 9f01708..bafd793 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -360,7 +360,8 @@
 			  (struct ext2_inode *)&inode_journal);
 	blknr = read_allocated_block((struct ext2_inode *)
 				     &inode_journal, i);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	p_jdb = (char *)temp_buff;
 	jdb = (struct journal_header_t *) temp_buff;
 	ofs = sizeof(struct journal_header_t);
@@ -384,9 +385,9 @@
 				continue;
 		}
 		blknr = read_allocated_block(&inode_journal, i);
-		ext4fs_devread(blknr * fs->sect_perblk, 0,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
 			       fs->blksz, metadata_buff);
-		put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
+		put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz),
 			 metadata_buff, (uint32_t) fs->blksz);
 	} while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
 fail:
@@ -431,7 +432,8 @@
 
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
@@ -455,7 +457,7 @@
 	while (1) {
 		blknr = read_allocated_block(&inode_journal, i);
 		memset(temp_buff1, '\0', fs->blksz);
-		ext4fs_devread(blknr * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 			       0, fs->blksz, temp_buff1);
 		jdb = (struct journal_header_t *) temp_buff1;
 
@@ -547,7 +549,7 @@
 
 		blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-		put_ext4((uint64_t) (blknr * fs->blksz),
+		put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
 			 (struct journal_superblock_t *)temp_buff,
 			 (uint32_t) fs->blksz);
 		ext4fs_free_revoke_blks();
@@ -576,7 +578,8 @@
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
@@ -605,7 +608,7 @@
 	tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
 	memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
 	       sizeof(struct ext3_journal_block_tag));
-	put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
+	put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
 
 	free(temp_buff);
 	free(buf);
@@ -623,10 +626,12 @@
 	if (!temp_buff)
 		return;
 
-	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
+	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
+			  &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
@@ -638,7 +643,7 @@
 		return;
 	}
 	memcpy(buf, &jdb, sizeof(struct journal_header_t));
-	put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
+	put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
 
 	free(temp_buff);
 	free(buf);
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index b2f84b1..2d79f76 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -66,15 +66,15 @@
 		unsigned int len, char *buf)
 {
 	int i;
-	int blockcnt;
+	lbaint_t blockcnt;
 	int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data);
 	int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
 	unsigned int filesize = __le32_to_cpu(node->inode.size);
-	int previous_block_number = -1;
-	int delayed_start = 0;
-	int delayed_extent = 0;
-	int delayed_skipfirst = 0;
-	int delayed_next = 0;
+	lbaint_t previous_block_number = -1;
+	lbaint_t delayed_start = 0;
+	lbaint_t delayed_extent = 0;
+	lbaint_t delayed_skipfirst = 0;
+	lbaint_t delayed_next = 0;
 	char *delayed_buf = NULL;
 	short status;
 
@@ -85,7 +85,7 @@
 	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
 
 	for (i = pos / blocksize; i < blockcnt; i++) {
-		int blknr;
+		lbaint_t blknr;
 		int blockoff = pos % blocksize;
 		int blockend = blocksize;
 		int skipfirst = 0;
@@ -211,18 +211,18 @@
 	/* update block groups */
 	for (i = 0; i < fs->no_blkgrp; i++) {
 		fs->bgd[i].bg_checksum = ext4fs_checksum_update(i);
-		put_ext4((uint64_t)(fs->bgd[i].block_id * fs->blksz),
+		put_ext4((uint64_t)((uint64_t)fs->bgd[i].block_id * (uint64_t)fs->blksz),
 			 fs->blk_bmaps[i], fs->blksz);
 	}
 
 	/* update inode table groups */
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		put_ext4((uint64_t) (fs->bgd[i].inode_id * fs->blksz),
+		put_ext4((uint64_t) ((uint64_t)fs->bgd[i].inode_id * (uint64_t)fs->blksz),
 			 fs->inode_bmaps[i], fs->blksz);
 	}
 
 	/* update the block group descriptor table */
-	put_ext4((uint64_t)(fs->gdtable_blkno * fs->blksz),
+	put_ext4((uint64_t)((uint64_t)fs->gdtable_blkno * (uint64_t)fs->blksz),
 		 (struct ext2_block_group *)fs->gdtable,
 		 (fs->blksz * fs->no_blk_pergdt));
 
@@ -247,7 +247,7 @@
 	if (!fs->gdtable)
 		return -ENOMEM;
 	/* read the group descriptor table */
-	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0,
+	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, 0,
 				fs->blksz * fs->no_blk_pergdt, fs->gdtable);
 	if (status == 0)
 		goto fail;
@@ -301,7 +301,7 @@
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			status =
-			    ext4fs_devread(bgd[bg_idx].block_id *
+			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 					   fs->sect_perblk, 0, fs->blksz,
 					   journal_buffer);
 			if (status == 0)
@@ -345,7 +345,7 @@
 		}
 		DIB_start_addr = (unsigned int *)di_buffer;
 		blknr = inode->b.blocks.double_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)di_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*di_buffer == 0)
@@ -367,7 +367,7 @@
 			fs->sb->free_blocks++;
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -397,7 +397,7 @@
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -446,7 +446,7 @@
 		}
 		tib_start_addr = (unsigned int *)tigp_buffer;
 		blknr = inode->b.blocks.triple_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)tigp_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*tigp_buffer == 0)
@@ -457,7 +457,7 @@
 			if (!tip_buffer)
 				goto fail;
 			tipb_start_addr = (unsigned int *)tip_buffer;
-			status = ext4fs_devread((*tigp_buffer) *
+			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *
 						fs->sect_perblk, 0, fs->blksz,
 						(char *)tip_buffer);
 			for (j = 0; j < fs->blksz / sizeof(int); j++) {
@@ -484,6 +484,7 @@
 				if (prev_bg_bmap_idx != bg_idx) {
 					status =
 					    ext4fs_devread(
+							(lbaint_t)
 							bgd[bg_idx].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
@@ -524,7 +525,7 @@
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -553,7 +554,7 @@
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -639,7 +640,7 @@
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -683,7 +684,7 @@
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk,
 							0, fs->blksz,
 							journal_buffer);
@@ -714,7 +715,7 @@
 	if (!read_buffer)
 		goto fail;
 	start_block_address = read_buffer;
-	status = ext4fs_devread(blkno * fs->sect_perblk,
+	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,
 				0, fs->blksz, read_buffer);
 	if (status == 0)
 		goto fail;
@@ -737,7 +738,7 @@
 	fs->sb->free_inodes++;
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread(bgd[ibmap_idx].inode_id *
+	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 		goto fail;
@@ -813,7 +814,7 @@
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 		status =
-		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0,
+		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id * fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
 			goto fail;
@@ -830,7 +831,7 @@
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id * fs->sect_perblk,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
 		if (status == 0)
@@ -870,11 +871,11 @@
 				  &inode_journal);
 		blknr = read_allocated_block(&inode_journal,
 					EXT2_JOURNAL_SUPERBLOCK);
-		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 			       temp_buff);
 		jsb = (struct journal_superblock_t *)temp_buff;
 		jsb->s_start = cpu_to_be32(0);
-		put_ext4((uint64_t) (blknr * fs->blksz),
+		put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
 			 (struct journal_superblock_t *)temp_buff, fs->blksz);
 		free(temp_buff);
 	}
@@ -956,8 +957,8 @@
 					delayed_extent += blockend;
 					delayed_next += blockend >> SECTOR_BITS;
 				} else {	/* spill */
-					put_ext4((uint64_t) (delayed_start *
-							     SECTOR_SIZE),
+					put_ext4((uint64_t) delayed_start *
+							     SECTOR_SIZE,
 						 delayed_buf,
 						 (uint32_t) delayed_extent);
 					previous_block_number = blknr;
@@ -978,8 +979,8 @@
 		} else {
 			if (previous_block_number != -1) {
 				/* spill */
-				put_ext4((uint64_t) (delayed_start *
-						     SECTOR_SIZE), delayed_buf,
+				put_ext4((uint64_t) delayed_start *
+						     SECTOR_SIZE, delayed_buf,
 					 (uint32_t) delayed_extent);
 				previous_block_number = -1;
 			}
@@ -989,7 +990,7 @@
 	}
 	if (previous_block_number != -1) {
 		/* spill */
-		put_ext4((uint64_t) (delayed_start * SECTOR_SIZE),
+		put_ext4((uint64_t) delayed_start * SECTOR_SIZE,
 			 delayed_buf, (uint32_t) delayed_extent);
 		previous_block_number = -1;
 	}
@@ -1091,7 +1092,7 @@
 			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
-	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
+	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
 	if (ext4fs_log_journal(temp_ptr, itable_blkno))
 		goto fail;
 
@@ -1111,7 +1112,7 @@
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
 	if (parent_itable_blkno != itable_blkno) {
 		memset(temp_ptr, '\0', fs->blksz);
-		ext4fs_devread(parent_itable_blkno * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,
 			       0, fs->blksz, temp_ptr);
 		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))
 			goto fail;
diff --git a/include/configs/armada_375.h b/include/configs/armada_375.h
index 0c45e3c..446cbec 100755
--- a/include/configs/armada_375.h
+++ b/include/configs/armada_375.h
@@ -265,20 +265,26 @@
 #define CONFIG_SF_DEFAULT_BUS		CONFIG_ENV_SPI_BUS
 #endif
 
+#if defined(MV_SEC_64K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x10000
+#elif defined(MV_SEC_128K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x20000
+#elif defined(MV_SEC_256K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x40000
+#endif
+
+#define	CONFIG_ENV_OFFSET_SPI		0x100000
+#define	CONFIG_ENV_SIZE_SPI		CONFIG_ENV_SECT_SIZE_SPI
+
+
 /* Boot from SPI settings */
 	#if defined(MV_SPI_BOOT)
 		#define CONFIG_ENV_IS_IN_SPI_FLASH
 
-		#if defined(MV_SEC_64K)
-			#define CONFIG_ENV_SECT_SIZE            0x10000
-		#elif defined(MV_SEC_128K)
-			#define CONFIG_ENV_SECT_SIZE            0x20000
-		#elif defined(MV_SEC_256K)
-			#define CONFIG_ENV_SECT_SIZE            0x40000
-		#endif
+		#define CONFIG_ENV_SECT_SIZE			CONFIG_ENV_SECT_SIZE_SPI
 
-		#define CONFIG_ENV_SIZE                         CONFIG_ENV_SECT_SIZE    /* environment takes one sector */
-		#define CONFIG_ENV_OFFSET                       0x100000                /* (1MB For Image) environment starts here  */
+		#define CONFIG_ENV_SIZE                         CONFIG_ENV_SECT_SIZE_SPI    /* environment takes one sector */
+		#define CONFIG_ENV_OFFSET                       CONFIG_ENV_OFFSET_SPI   /* (1MB For Image) environment starts here  */
 		#define CONFIG_ENV_ADDR                         CONFIG_ENV_OFFSET
 		#define MONITOR_HEADER_LEN                      0x200
 		#define CONFIG_SYS_MONITOR_BASE                 0
@@ -301,6 +307,9 @@
 /* NAND-FLASH stuff     */
 /************************/
 #ifdef MV_NAND
+	#ifndef __ASSEMBLY__
+extern int nand_get_env_offs(void);
+	#endif /* __ASSEMBLY__ */
 	#define MV_NAND_PIO_MODE
 	#define MV_NAND_1CS_MODE
 	/*
@@ -324,17 +333,21 @@
 	#undef MV_NFC_DBG
 	#define CONFIG_JFFS2_NAND
 
+	#define	CONFIG_ENV_SIZE_NAND			0x80000
+	#define CONFIG_ENV_OFFSET_NAND			nand_get_env_offs()
+	#define	CONFIG_ENV_RANGE_NAND			CONFIG_ENV_SIZE_NAND * 8
+
 /* Boot from NAND settings */
 	#if defined(MV_NAND_BOOT)
 		#define CONFIG_ENV_IS_IN_NAND
 
-		#define CONFIG_ENV_SIZE                 0x80000                 /* environment takes one erase block */
-		#define CONFIG_ENV_OFFSET               nand_get_env_offs()     /* environment starts here  */
+		#define CONFIG_ENV_SIZE                 CONFIG_ENV_SIZE_NAND                 /* environment takes one erase block */
+		#define CONFIG_ENV_OFFSET               CONFIG_ENV_OFFSET_NAND     /* environment starts here  */
 		#define CONFIG_ENV_ADDR                 CONFIG_ENV_OFFSET
 		#define MONITOR_HEADER_LEN              0x200
 		#define CONFIG_SYS_MONITOR_BASE         0
 		#define CONFIG_SYS_MONITOR_LEN          0x80000           /* Reserve 512 kB for Monitor */
-		#define CONFIG_ENV_RANGE                CONFIG_ENV_SIZE * 8
+		#define CONFIG_ENV_RANGE                CONFIG_ENV_RANGE_NAND
 
 		#define MV_NBOOT_BASE                   0
 		#define MV_NBOOT_LEN                    (4 << 10)       /* Reserved 4KB for boot strap */
@@ -443,6 +456,13 @@
 	#define ENV_USB0_MODE   "host"
 	#define ENV_USB_ACTIVE        "0"
 	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
+	/* Marvell encapsulate it's USB usage with usbActive internal index,
+	 * the usb stack uses 1 controller simultaneously */
+	#define CONFIG_USB_MAX_CONTROLLER_COUNT		1
+	/* xHCI code relies on index receiving from that usbActive,
+	 * which could go up to 2 for several SoCs. this requires xHCI arrays to be as big as
+	 * the actual USB host count */
+	#define CONFIG_USB_MAX_CONTROLLER_HOST_COUNT	1
 #if defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_EHCI)
 	#define CONFIG_USB_XHCI_HCD /* set kernel define - for mv_hal/usb usage */
 #endif /* CONFIG_USB_XHCI */
diff --git a/include/configs/armada_38x.h b/include/configs/armada_38x.h
index 75efaa2..16238bd 100644
--- a/include/configs/armada_38x.h
+++ b/include/configs/armada_38x.h
@@ -57,6 +57,7 @@
  */
 #ifdef CONFIG_ARMADA_38X
 	#define MV88F68XX
+	#define CONFIG_SWITCHING_SERVICES
 #endif
 #ifdef CONFIG_ARMADA_39X
 	#define MV88F69XX
@@ -67,14 +68,21 @@
 #define MV_DDR_64BIT
 #define MV_BOOTROM
 
-#if defined (CONFIG_CUSTOMER_BOARD_0) || defined (CONFIG_CUSTOMER_BOARD_1) || defined (CONFIG_GFCH100)
+#if defined (CONFIG_CUSTOMER_BOARD_0) || defined (CONFIG_CUSTOMER_BOARD_1) || defined (CONFIG_CLEARFOG_BOARD) || defined (CONFIG_GFCH100)
 #define CONFIG_CUSTOMER_BOARD_SUPPORT
 #endif
 
+#ifdef MV_INCLUDE_SWITCH
+/*ARMADA38x switch resgiters are accessed by SMI*/
+/*we provide name unified switch register access APIs with different implementations according to the access way*/
+#define MV_SWITCH_SMI_ACCESS
+#endif
+
 #define MV_USB
 #define MV_FS
 #define CONFIG_CMD_DATE
 #define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_PIC_GPIO 		/*  support GPIO signals for PIC (programmable interface circuit) */
 
 #define MV_DDR_TRAINING_CMD_NEW_TIP
 
@@ -156,11 +164,13 @@
 #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
 */
 #ifdef CONFIG_ARMADA_39X
 	#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+		#define MV_CROSS_FLASH_BOOT
 		#define CONFIG_CMD_BOARDCFG
 	#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
 #endif /* CONFIG_ARMADA_39X */
@@ -286,6 +296,17 @@
 	#define CONFIG_ENV_SPI_CS               0
 	#define CONFIG_ENV_SPI_BUS              mvBoardSpiBusGet()
 
+#if defined(MV_SEC_64K)
+	#define CONFIG_ENV_SECT_SIZE_SPI		0x10000
+#elif defined(MV_SEC_128K)
+	#define CONFIG_ENV_SECT_SIZE_SPI		0x20000
+#elif defined(MV_SEC_256K)
+	#define CONFIG_ENV_SECT_SIZE_SPI		0x40000
+#endif
+
+#define CONFIG_ENV_SIZE_SPI		CONFIG_ENV_SECT_SIZE_SPI	/* environment takes one sector */
+#define CONFIG_ENV_OFFSET_SPI		0x100000			/* (1MB For Image) environment starts here  */
+
 #ifndef CONFIG_SF_DEFAULT_SPEED
 # define CONFIG_SF_DEFAULT_SPEED        CONFIG_ENV_SPI_MAX_HZ
 #endif
@@ -303,16 +324,10 @@
 	#if defined(MV_SPI_BOOT)
 		#define CONFIG_ENV_IS_IN_SPI_FLASH
 
-		#if defined(MV_SEC_64K)
-			#define CONFIG_ENV_SECT_SIZE            0x10000
-		#elif defined(MV_SEC_128K)
-			#define CONFIG_ENV_SECT_SIZE            0x20000
-		#elif defined(MV_SEC_256K)
-			#define CONFIG_ENV_SECT_SIZE            0x40000
-		#endif
+		#define CONFIG_ENV_SECT_SIZE           		CONFIG_ENV_SECT_SIZE_SPI
 
 		#define CONFIG_ENV_SIZE                         CONFIG_ENV_SECT_SIZE    /* environment takes one sector */
-		#define CONFIG_ENV_OFFSET                       0x100000                /* (1MB For Image) environment starts here  */
+		#define CONFIG_ENV_OFFSET                       CONFIG_ENV_OFFSET_SPI
 		#define CONFIG_ENV_ADDR                         CONFIG_ENV_OFFSET
 		#define MONITOR_HEADER_LEN                      0x200
 		#define CONFIG_SYS_MONITOR_BASE                 0
@@ -335,6 +350,10 @@
 /* NAND-FLASH stuff     */
 /************************/
 #ifdef MV_NAND
+	#ifndef __ASSEMBLY__
+extern int nand_get_env_offs(void);
+	#endif /* __ASSEMBLY__ */
+
 	#define MV_NAND_PIO_MODE
 	#define MV_NAND_1CS_MODE
 	/* The following defines are masked for a38x:
@@ -364,17 +383,22 @@
 	#undef MV_NFC_DBG
 	#define CONFIG_JFFS2_NAND
 
+
+	#define CONFIG_ENV_SIZE_NAND			0x80000
+	#define CONFIG_ENV_OFFSET_NAND			nand_get_env_offs()
+	#define CONFIG_ENV_RANGE_NAND			CONFIG_ENV_SIZE_NAND * 8
+
 /* Boot from NAND settings */
 	#if defined(MV_NAND_BOOT)
 		#define CONFIG_ENV_IS_IN_NAND
 
-		#define CONFIG_ENV_SIZE                 0x80000                 /* environment takes one erase block */
+		#define CONFIG_ENV_SIZE                 CONFIG_ENV_SIZE_NAND                 /* environment takes one erase block */
 		#define CONFIG_ENV_OFFSET               nand_get_env_offs()     /* environment starts here  */
 		#define CONFIG_ENV_ADDR                 CONFIG_ENV_OFFSET
 		#define MONITOR_HEADER_LEN              0x200
 		#define CONFIG_SYS_MONITOR_BASE         0
 		#define CONFIG_SYS_MONITOR_LEN          0x80000           /* Reserve 512 kB for Monitor */
-		#define CONFIG_ENV_RANGE                CONFIG_ENV_SIZE * 8
+		#define CONFIG_ENV_RANGE                CONFIG_ENV_RANGE_NAND
 
 		#define MV_NBOOT_BASE                   0
 		#define MV_NBOOT_LEN                    (4 << 10)       /* Reserved 4KB for boot strap */
@@ -493,17 +517,32 @@
 	#define CONFIG_USB_XHCI
 	#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS  1
 	#define MV_INCLUDE_USB
+	#define MV_INCLUDE_USB_DEVICE
 	#define CONFIG_CMD_USB
 	#define CONFIG_USB_STORAGE
 	#define CONFIG_EHCI_IS_TDI
 	#define CONFIG_DOS_PARTITION
 	#define CONFIG_ISO_PARTITION
 	#define ENV_USB0_MODE   "host"
+#ifdef CONFIG_CLEARFOG_BOARD
+	#define ENV_USB_ACTIVE        "1"
+	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
+#else
 	#define ENV_USB_ACTIVE        "0"
 	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
+#endif
 
 	#define CONFIG_USB_HOST_ETHER
 	#define CONFIG_USB_ETHER_ASIX
+	/* Marvell encapsulate it's USB usage with usbActive internal index,
+	 * the usb stack uses 1 controller simultaneously */
+	#define CONFIG_USB_MAX_CONTROLLER_COUNT		1
+	/* xHCI code relies on index receiving from that usbActive,
+	 * which could go up to 2. this requires xHCI arrays to be as big as
+	 * the actual USB host count */
+	#define CONFIG_USB_MAX_CONTROLLER_HOST_COUNT	2
+
+	#define MV_USB_VBUS_CYCLE
 
 #if defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_EHCI)
 	#define CONFIG_USB_XHCI_HCD /* set kernel define - for mv_hal/usb usage */
@@ -539,6 +578,14 @@
 //#define CONFIG_MMC_TRACE
 /* Boot from MMC settings */
 #if defined(MV_MMC_BOOT)
+/* the following commands are supported only with SPI/NAND interfaces */
+#if (!defined(MV_INCLUDE_SPI) && !defined(MV_NAND))
+	#undef CONFIG_CMD_SOURCE	/* cmd_mvsource.c supports script burning to SPI/NAND only */
+	#undef CONFIG_CMD_STAGE_BOOT
+	#undef CONFIG_CMD_RCVR
+	#undef CONFIG_CMD_BOOT_MENU
+	#undef CONFIG_CMD_SYS_RESTORE
+#endif
 	#define CONFIG_ENV_IS_IN_MMC	/* Environment is at absolute location (RAW) */
 //	#define CONFIG_ENV_IS_IN_FAT	/* Environment is in file on FAT partition */
 //	#define CONFIG_FAT_WRITE
@@ -567,11 +614,9 @@
  */
 #ifdef CONFIG_ARMADA_38X
 #define MV_BOOTARGS_END         ":10.4.50.254:255.255.255.0:Armada38x:eth0:none"
-#define MV_BOOTARGS_END_SWITCH  ":::Armada38x:eth0:none"
 #define MV_DDR_L2_ALIGNMENT
 #elif defined CONFIG_ARMADA_39X
 #define MV_BOOTARGS_END         ":10.4.50.254:255.255.255.0:Armada39x:eth0:none"
-#define MV_BOOTARGS_END_SWITCH  ":::Armada39x:eth0:none"
 #endif
 #define RCVR_IP_ADDR            "169.254.100.100"
 	#define RCVR_LOAD_ADDR          "0x02000000"
@@ -627,7 +672,6 @@
 /* PnP PCI Network cards */
 	#define CONFIG_EEPRO100 /* Support for Intel 82557/82559/82559ER chips */
 	#define CONFIG_E1000
-	#define CONFIG_SK98
 	#define YUK_ETHADDR                     "00:00:00:EE:51:81"
 #endif
 
@@ -695,7 +739,13 @@
 #define BOARD_LATE_INIT
 #define CONFIG_BOARD_LATE_INIT
 #undef  CONFIG_USE_IRQ
+#define CONFIG_BZIP2
 
 #define CONFIG_STACKSIZE        (1 << 20)       /* regular stack - up to 4M (in case of exception)*/
 
+/*
+ * ERRATA
+ */
+#define ERRATA_FE_3124064
+
 #endif /* __CONFIG_H */
diff --git a/include/configs/avanta_lp.h b/include/configs/avanta_lp.h
old mode 100755
new mode 100644
index bc83f03..43f59b3
--- a/include/configs/avanta_lp.h
+++ b/include/configs/avanta_lp.h
@@ -53,6 +53,12 @@
 
 #include "../../board/mv_ebu/alp/mvSysHwConfig.h"
 
+#ifdef MV_INCLUDE_SWITCH
+/*Avanta LP switch resgiters are accessed by CPU directly*/
+/*we provide name unified switch register access APIs with different implementations according to the access way*/
+#define MV_SWITCH_DIRECT_ACCESS
+#endif
+
 /* Version number passed to kernel */
 #define VER_NUM 0x11120000              /* 2011.12 */
 
@@ -265,21 +271,27 @@
 #define CONFIG_SF_DEFAULT_BUS		CONFIG_ENV_SPI_BUS
 #endif
 
+#if defined(MV_SEC_64K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x10000
+#elif defined(MV_SEC_128K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x20000
+#elif defined(MV_SEC_256K)
+#define CONFIG_ENV_SECT_SIZE_SPI	0x40000
+#endif
+
+#define	CONFIG_ENV_OFFSET_SPI		0x100000
+#define	CONFIG_ENV_SIZE_SPI		CONFIG_ENV_SECT_SIZE_SPI
+
+
 /* Boot from SPI settings */
 	#if defined(MV_SPI_BOOT)
 		#define CONFIG_ENV_IS_IN_SPI_FLASH
 
-		#if defined(MV_SEC_64K)
-			#define CONFIG_ENV_SECT_SIZE            0x10000
-		#elif defined(MV_SEC_128K)
-			#define CONFIG_ENV_SECT_SIZE            0x20000
-		#elif defined(MV_SEC_256K)
-			#define CONFIG_ENV_SECT_SIZE            0x40000
-		#endif
+		#define CONFIG_ENV_SECT_SIZE            	CONFIG_ENV_SECT_SIZE_SPI
 
-		#define CONFIG_ENV_SIZE                         CONFIG_ENV_SECT_SIZE    /* environment takes one sector */
-		#define CONFIG_ENV_OFFSET                       0x100000                /* (1MB For Image) environment starts here  */
-		#define CONFIG_ENV_ADDR                         CONFIG_ENV_OFFSET
+		#define CONFIG_ENV_SIZE                         CONFIG_ENV_SECT_SIZE_SPI    /* environment takes one sector */
+		#define CONFIG_ENV_OFFSET                       CONFIG_ENV_OFFSET_SPI       /* (1MB For Image) environment starts here  */
+		#define CONFIG_ENV_ADDR                         CONFIG_ENV_OFFSET_SPI
 		#define MONITOR_HEADER_LEN                      0x200
 		#define CONFIG_SYS_MONITOR_BASE                 0
 		#define CONFIG_SYS_MONITOR_LEN                  0x80000                 /*(512 << 10) Reserve 512 kB for Monitor */
@@ -301,6 +313,10 @@
 /* NAND-FLASH stuff     */
 /************************/
 #ifdef MV_NAND
+	#ifndef __ASSEMBLY__
+extern int nand_get_env_offs(void);
+extern int nand_get_env_range(void);
+	#endif /* __ASSEMBLY__ */
 	#define MV_NAND_PIO_MODE
 	#define MV_NAND_1CS_MODE
 	#define MV_NAND_4BIT_MODE
@@ -319,17 +335,21 @@
 	#undef CONFIG_CMD_NAND_YAFFS2
 	#undef CONFIG_MTD_NAND_YAFFS2
 
+	#define	CONFIG_ENV_SIZE_NAND			0x10000
+	#define CONFIG_ENV_OFFSET_NAND			nand_get_env_offs()
+	#define	CONFIG_ENV_RANGE_NAND			nand_get_env_range()
+
 /* Boot from NAND settings */
 	#if defined(MV_NAND_BOOT)
 		#define CONFIG_ENV_IS_IN_NAND
 
-		#define CONFIG_ENV_SIZE                 0x10000			/* environment takes one erase block */
-		#define CONFIG_ENV_OFFSET               nand_get_env_offs()     /* environment starts here  */
-		#define CONFIG_ENV_ADDR                 CONFIG_ENV_OFFSET
+		#define CONFIG_ENV_SIZE                 CONFIG_ENV_SIZE_NAND	/* environment takes one erase block */
+		#define CONFIG_ENV_OFFSET               CONFIG_ENV_OFFSET_NAND  /* environment starts here  */
+		#define CONFIG_ENV_ADDR                 CONFIG_ENV_OFFSET_NAND
 		#define MONITOR_HEADER_LEN              0x200
 		#define CONFIG_SYS_MONITOR_BASE         0
 		#define CONFIG_SYS_MONITOR_LEN          0x80000           /* Reserve 512 kB for Monitor */
-		#define CONFIG_ENV_RANGE                nand_get_env_range()
+		#define CONFIG_ENV_RANGE                CONFIG_ENV_RANGE_NAND
 
 		#define MV_NBOOT_BASE                   0
 		#define MV_NBOOT_LEN                    (4 << 10)       /* Reserved 4KB for boot strap */
@@ -443,6 +463,13 @@
 	#define ENV_USB1_MODE   "host"
 	#define ENV_USB_ACTIVE        "0"
 	#define ENV_USB_MODE          "3"	/* 3 = USB3.0 | 2 = USB2.0 */
+	/* Marvell encapsulate it's USB usage with usbActive internal index,
+	 * the usb stack uses 1 controller simultaneously */
+	#define CONFIG_USB_MAX_CONTROLLER_COUNT		1
+	/* xHCI code relies on index receiving from that usbActive,
+	 * which could go up to 2 for several SoCs. this requires xHCI arrays to be as big as
+	 * the actual USB host count */
+	#define CONFIG_USB_MAX_CONTROLLER_HOST_COUNT	1
 #if defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_EHCI)
 	#define CONFIG_USB_XHCI_HCD /* set kernel define - for mv_hal/usb usage */
 #endif /* CONFIG_USB_XHCI */
diff --git a/include/configs/msys.h b/include/configs/msys.h
index 37b7804..8cd137f 100644
--- a/include/configs/msys.h
+++ b/include/configs/msys.h
@@ -114,6 +114,7 @@
 #ifndef __ASSEMBLY__
 	extern unsigned int mvCpuDdrClkGet(void);
 	extern unsigned int mvTclkGet(void);
+	extern unsigned int mvUartPortGet(void);
 	#define UBOOT_CNTR		0		/* counter to use for uboot timer */
 	#define MV_TCLK_CNTR		1		/* counter to use for uboot timer */
 	#define MV_REF_CLK_DEV_BIT	1000		/* Number of cycle to eanble timer */
@@ -204,6 +205,11 @@
 #define CONFIG_BOOTP_PXE_CLIENTARCH	0x100
 #define CONFIG_BOOTP_VCI_STRING		"U-boot.armv7.armada_xp"
 
+/* Flattened Device Tree (FDT) support */
+#define CONFIG_OF_LIBFDT               1
+#define CONFIG_OF_BOARD_SETUP
+#undef CONFIG_OF_LIBFDT_IS_DEFAULT   /* dft is the default for bootcmd */
+
 /* FS supported */
 #define CONFIG_CMD_EXT2
 #define CONFIG_CMD_EXT4
@@ -330,7 +336,7 @@
  */
 #define CONFIG_BAUDRATE         	115200   /* console baudrate = 115200    */
 #define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 }
-#define CONFIG_SYS_DUART_CHAN		1		/* channel to use for console */
+#define CONFIG_SYS_DUART_CHAN		0		/* channel to use for console */
 
 
 #define CONFIG_SYS_INIT_CHAN1
@@ -398,6 +404,13 @@
 	#define ENV_USB1_MODE   "host"
 	#define ENV_USB_ACTIVE        "0"
 	#define ENV_USB_MODE          "2" /* 3 = USB3.0 | 2 = USB2.0 */
+	/* Marvell encapsulate it's USB usage with usbActive internal index,
+	 * the usb stack uses 1 controller simultaneously */
+	#define CONFIG_USB_MAX_CONTROLLER_COUNT		1
+	/* xHCI code relies on index receiving from that usbActive,
+	 * which could go up to 2 for several SoCs. this requires xHCI arrays to be as big as
+	 * the actual USB host count */
+	#define CONFIG_USB_MAX_CONTROLLER_HOST_COUNT	1
 
 	#define CONFIG_USB_HOST_ETHER
 	#define CONFIG_USB_ETHER_ASIX
@@ -579,6 +592,11 @@
 	#define CONFIG_SYS_NAND_MAX_CHIPS 1
 
 #if defined(MV_NAND)
+
+	#ifndef __ASSEMBLY__
+extern int nand_get_env_offs(void);
+	#endif /* __ASSEMBLY__ */
+
 	#define MV_NAND_PIO_MODE
 	#define MV_NAND_1CS_MODE
 	#define MV_NAND_4BIT_MODE
@@ -666,6 +684,7 @@
 #define CONFIG_BOARD_LATE_INIT
 #undef CONFIG_USE_IRQ
 #define CONFIG_BZIP2
+#define MV_SWITCH_ADDRESS_COMPLETION
 
 /* for running from L2 SRAM
 #define CONFIG_STACKSIZE	(128 << 10)
diff --git a/include/configs/mv_version.h b/include/configs/mv_version.h
index e3590a5..458936e 100644
--- a/include/configs/mv_version.h
+++ b/include/configs/mv_version.h
@@ -39,6 +39,6 @@
 /*
  * Version
  */
-#define CONFIG_IDENT_STRING	" Marvell version: 2015_T1.0"
+#define CONFIG_IDENT_STRING	" Marvell version: 2015_T1.0p16"
 
 #endif /* __MV_VERSION_H */
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 09ba37e..526bdbd 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -135,7 +135,7 @@
 void ext4fs_close(void);
 int ext4fs_ls(const char *dirname, char *outbuff, int outsize);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
 long int read_allocated_block(struct ext2_inode *inode, int fileblock);
 #endif
diff --git a/include/ext_common.h b/include/ext_common.h
index 86373a6..87b33ac 100644
--- a/include/ext_common.h
+++ b/include/ext_common.h
@@ -186,7 +186,7 @@
 	struct ext2fs_node diropen;
 };
 
-extern unsigned long part_offset;
+extern lbaint_t part_offset;
 
 int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/ide.h b/include/ide.h
index 7541cb8..f6f9654 100755
--- a/include/ide.h
+++ b/include/ide.h
@@ -44,6 +44,7 @@
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
 #define LBAF "%llx"
+#define LBAFU "%llu"
 #define IDE_BLOCK_NUMBER_MASK 0x0000fffff0000000
 #define LBA_LOW_REG_SHIFT	24
 #define LBA_MID_REG_SHIFT	32
@@ -51,6 +52,7 @@
 #else
 typedef ulong lbaint_t;
 #define LBAF "%lx"
+#define LBAFU "%lu"
 #define IDE_BLOCK_NUMBER_MASK 0xf0000000
 #define LBA_LOW_REG_SHIFT	24
 #define LBA_MID_REG_SHIFT	0
diff --git a/include/part.h b/include/part.h
index 35c1c5b..8e31e75 100644
--- a/include/part.h
+++ b/include/part.h
@@ -97,8 +97,8 @@
 #define DEV_TYPE_OPDISK		0x07	/* optical disk */
 
 typedef struct disk_partition {
-	ulong	start;		/* # of first block in partition	*/
-	ulong	size;		/* number of blocks in partition	*/
+	lbaint_t	start;	/* # of first block in partition	*/
+	lbaint_t	size;	/* number of blocks in partition	*/
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
diff --git a/net/eth.c b/net/eth.c
index 4e4a847..e9d9b06 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -231,7 +231,6 @@
 int eth_register(struct eth_device *dev)
 {
 	struct eth_device *d;
-	static int index;
 
 	assert(strlen(dev->name) < sizeof(dev->name));
 
@@ -246,7 +245,6 @@
 
 	dev->state = ETH_STATE_INIT;
 	dev->next  = eth_devices;
-	dev->index = index++;
 
 	return 0;
 }
diff --git a/tools/marvell/.gitignore b/tools/marvell/.gitignore
index 6736688..84cd9cd 100755
--- a/tools/marvell/.gitignore
+++ b/tools/marvell/.gitignore
@@ -29,6 +29,7 @@
 /gdb/gdbcont
 /gdb/gdbsend
 /bin_hdr/src_ddr/ddr3lib/
+/bin_hdr/src_ddr/ddr3libv2/
 doimage*
 linker.scr
 linker_sec.scr
diff --git a/tools/marvell/bin_hdr/Makefile b/tools/marvell/bin_hdr/Makefile
index f2e0434..7c3cfac 100755
--- a/tools/marvell/bin_hdr/Makefile
+++ b/tools/marvell/bin_hdr/Makefile
@@ -85,6 +85,8 @@
 AOBJ = $(subst .s,.o,$(ASRC))
 COBJ = $(subst .c,.o,$(CSRC))
 CUART_OBJ = $(subst .c,.uart.o,$(CSRC))
+CDEBUG_OBJ = $(subst .c,.debug.o,$(CSRC)) # debug object for mvdispatcher
+
 
 LIB_PHY = phy_$(BOARD).a
 LIB_DDR = ddr_$(BOARD).a
@@ -98,17 +100,27 @@
 LIB_SWUP_UART = suspendWUP.uart.a
 LIB_GENERAL_INIT_UART = generalInit.uart.a
 
+LIB_PLAT_DEBUG = plat.debug.a # specific platform library with bin header debug tool
+
 LIBGCC = $(MAIN)/libgcc.lib
 
 ifeq ($(DDRTYPE),)
 DDRTYPE = ddr3
 endif
 
+ifeq ($(DDRTYPE),ddr4)
+	TLIBS = $(TLIB) $(TDDR4SUBLIB)
+else
+	TLIBS = $(TLIB)
+endif
+
 TLIB = ./src_ddr/lib/$(DDRTYPE)_training_$(LIBNAME).lib
+TDDR4SUBLIB = ./src_ddr/lib/$(DDRTYPE)_training_$(LIBNAME)sub.lib
 
 COMPONENT_SUBDIRS = platform src_phy src_ddr src_pm src_init
-HDR_COMPONENTS = $(LIB_PLAT) $(LIB_GENERAL_INIT) $(LIB_PHY) $(LIB_DDR) $(TLIB) $(LIB_SWUP)
-HDR_COMPONENTS_UART = $(LIB_PLAT_UART) $(LIB_GENERAL_INIT_UART) $(LIB_PHY_UART) $(LIB_DDR_UART) $(TLIB) $(LIB_SWUP_UART)
+HDR_COMPONENTS = $(LIB_PLAT) $(LIB_GENERAL_INIT) $(LIB_PHY) $(LIB_DDR) $(TLIBS) $(LIB_SWUP)
+HDR_COMPONENTS_UART = $(LIB_PLAT_UART) $(LIB_GENERAL_INIT_UART) $(LIB_PHY_UART) $(LIB_DDR_UART) $(TLIBS) $(LIB_SWUP_UART)
+HDR_COMPONENTS_DEBUG = $(LIB_PLAT_DEBUG) $(LIB_GENERAL_INIT) $(LIB_PHY) $(LIB_DDR) $(TLIBS) $(LIB_SWUP)
 
 #how to add new component to binary header:
 #EXAMPLE_COMPONENT=no
@@ -125,7 +137,7 @@
 $(info )
 endif
 
-all:   subdirs $(TGT).bin $(TGT)_sec.bin $(TGT).uart.bin  $(TGT).dis $(TGT)_sec.dis $(TGT).uart.dis $(TGT).srec $(TGT)_sec.srec $(TGT).uart.srec
+all:   subdirs $(TGT).bin $(TGT)_sec.bin $(TGT).uart.bin  $(TGT).dis $(TGT)_sec.dis $(TGT).uart.dis $(TGT).srec $(TGT)_sec.srec $(TGT).uart.srec $(TGT).debug.bin
 
 %.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
@@ -133,6 +145,9 @@
 %.uart.o: %.c
 	$(CC) $(CFLAGS) -DNOT_USE_UART -DMV_NO_INPUT -DMV_NO_PRINT  $(CPPFLAGS) -c -o  $@ $<
 
+%.debug.o: %.c
+	$(CC) $(CFLAGS) -DMV_DEBUG_MODE $(CPPFLAGS) -c -o  $@ $<
+
 $(TGT).bin: $(TGT).elf
 	$(OBJCOPY) -S -O binary $< $(addsuffix .tmp, $@)
 	$(CAT) $(PARAMSFILE).raw $(addsuffix .tmp, $@) > $@
@@ -148,6 +163,11 @@
 	$(CAT) $(PARAMSFILE).raw $(addsuffix .tmp, $@) > $@
 	$(RM) $(addsuffix .tmp, $@)
 
+$(TGT).debug.bin: $(TGT).debug.elf
+	$(OBJCOPY) -S -O binary $< $(addsuffix .tmp, $@)
+	$(CAT) $(PARAMSFILE).raw $(addsuffix .tmp, $@) > $@
+	$(RM) $(addsuffix .tmp, $@)
+
 $(TGT).srec: $(TGT).elf
 	$(OBJCOPY) -O srec $< $@
 
@@ -175,6 +195,9 @@
 $(TGT).uart.elf: $(AOBJ) $(CUART_OBJ) subdirs
 	$(CC) $(LDFLAGSBIN) $(AOBJ) $(CUART_OBJ) $(HDR_COMPONENTS_UART) $(LIB_PLAT_UART) $(LIBGCC) -o $@
 
+$(TGT).debug.elf: $(AOBJ) $(CDEBUG_OBJ) subdirs
+	$(CC) $(LDFLAGSBIN) $(AOBJ) $(CDEBUG_OBJ) $(HDR_COMPONENTS_DEBUG) $(LIB_PLAT_DEBUG) $(LIBGCC) -o $@
+
 $(LDSCRIPT): $(SETPARAMS)
 	./$(SETPARAMS) -B $(BOARD) -P $(PARAMSFILE).txt -R $(DRAMREGS) -d $(DEBUG_MODE_FLAG) $(PARAMSFILE).raw $@
 
@@ -196,7 +219,7 @@
 	done
 
 clean:
-	$(RM) *.raw *.elf *.srec *.dis *.bin *.a *.uart.bin *.uart.elf ./src/*.o  $(LDSCRIPT) $(LDSECSCRIPT) $(SETPARAMS)
+	$(RM) *.raw *.elf *.srec *.dis *.bin *.a *.uart.bin *.uart.elf *.debug.bin ./src/*.o  $(LDSCRIPT) $(LDSECSCRIPT) $(SETPARAMS)
 	@for dir in $(COMPONENT_SUBDIRS) ; do \
 	    $(MAKE) clean -s -C $$dir || exit 1 ; \
 	done
diff --git a/tools/marvell/bin_hdr/base.mk b/tools/marvell/bin_hdr/base.mk
index 1e5da62..607b236 100755
--- a/tools/marvell/bin_hdr/base.mk
+++ b/tools/marvell/bin_hdr/base.mk
@@ -83,6 +83,9 @@
 ifeq "$(CONFIG_CUSTOMER_BOARD_1)"  "y"
   CFLAGS += -DCONFIG_CUSTOMER_BOARD_1
 endif
+ifeq "$(CONFIG_CLEARFOG_BOARD)"  "y"
+  CFLAGS += -DCONFIG_CLEARFOG_BOARD
+endif
 ifeq "$(CONFIG_GFCH100)"  "y"
   CFLAGS += -DCONFIG_GFCH100
 endif
@@ -206,7 +209,7 @@
 
 BH_ROOT_DIR  = $(TOPDIR)/tools/marvell/bin_hdr
 INCLUDE      = -I$(BH_ROOT_DIR)/src_ddr -I$(BH_ROOT_DIR)/src_phy/$(BOARD) -I$(BH_ROOT_DIR)/inc/common \
-	       -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(INCNAME)  -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(BOARD) -I$(BH_ROOT_DIR)/platform/sysEnv/$(BOARD) -I$(TOPDIR)/include
+	       -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(INCNAME)  -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(BOARD) -I$(BH_ROOT_DIR)/platform/sysEnv/$(BOARD) -I$(TOPDIR)/include -I$(BH_ROOT_DIR)/src_init/$(BOARD)
 HOSTCFLAGS   = -Wall $(INCLUDE)
 
 ifeq ($(BIN_HDR_DEBUG),1)
@@ -223,13 +226,15 @@
 endif
 
 CFLAGS   += -Wall $(INCLUDE) $(DEBUG_FLAGS) $(CPUOPTS) -msoft-float -mabi=aapcs
-ifeq ($(BOARD),a38x)
-CFLAGS   += -fdata-sections -ffunction-sections
-EXTRA_LD_FLAGS = -Wl,--gc-sections --entry=_start
-else
+
+ifeq ($(BOARD),msys_bc2)
 CFLAGS   += -fPIE -fno-zero-initialized-in-bss -fno-unwind-tables
+else
+CFLAGS   += -fdata-sections -ffunction-sections
 endif
 
+EXTRA_LD_FLAGS = -Wl,--gc-sections --entry=_start
+
 ifeq ($(DDRTYPE),ddr4)
 CFLAGS += -DCONFIG_DDR4
 else
diff --git a/tools/marvell/bin_hdr/inc/common/bin_hdr_twsi.h b/tools/marvell/bin_hdr/inc/common/bin_hdr_twsi.h
index e04d993..e83e93d 100644
--- a/tools/marvell/bin_hdr/inc/common/bin_hdr_twsi.h
+++ b/tools/marvell/bin_hdr/inc/common/bin_hdr_twsi.h
@@ -110,7 +110,10 @@
 /*
 ** Base address for TWSI registers.
 */
-#define MV_TWSI_SLAVE_REGS_BASE(unit)       (MV_TWSI_SLAVE_REGS_OFFSET(unit))
+#define MV_TWSI_SLAVE_REGS_BASE(unit)		(MV_TWSI_SLAVE_REGS_OFFSET(unit))
+#define TWSI_CONFIG_DEBUG_REG			(MV_TWSI_SLAVE_REGS_BASE(0) + 0x8c)
+#define TWSI_DEBUG_SLAVE_PORT0_EN		BIT18
+#define TWSI_DEBUG_SLAVE_PORT1_EN		BIT19
 
 /*
 ** Specific definition for Main CPU interrupt cause register.
diff --git a/tools/marvell/bin_hdr/inc/common/ddr3_hws_hw_training_def.h b/tools/marvell/bin_hdr/inc/common/ddr3_hws_hw_training_def.h
index 98455d7..0531296 100644
--- a/tools/marvell/bin_hdr/inc/common/ddr3_hws_hw_training_def.h
+++ b/tools/marvell/bin_hdr/inc/common/ddr3_hws_hw_training_def.h
@@ -49,16 +49,6 @@
 #define MV_MAX_DDR3_STATIC_SIZE					50
 #define MV_DDR3_MODES_NUMBER					30
 
-#define RESUME_RL_PATTERNS_ADDR                	(0xFE0000)
-#define RESUME_RL_PATTERNS_SIZE                 (0x100)
-#define RESUME_TRAINING_VALUES_ADDR            	(RESUME_RL_PATTERNS_ADDR + RESUME_RL_PATTERNS_SIZE)
-#define RESUME_TRAINING_VALUES_MAX             	(0xCD0)
-#define BOOT_INFO_ADDR 							(RESUME_RL_PATTERNS_ADDR + 0x1000)
-#define CHECKSUM_RESULT_ADDR                    (BOOT_INFO_ADDR + 0x1000)
-#define NUM_OF_REGISTER_ADDR 					(CHECKSUM_RESULT_ADDR + 4)
-#define SUSPEND_MAGIC_WORD 						(0xDEADB002)
-#define REGISTER_LIST_END 						(0xFFFFFFFF)
-
 /* MISC */
 #define INTER_REGS_BASE							0xD0000000
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/inc/common/debug.h
similarity index 63%
copy from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
copy to tools/marvell/bin_hdr/inc/common/debug.h
index da82e24..6069222 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/inc/common/debug.h
@@ -1,4 +1,3 @@
-
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -43,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-		notice, this list of conditions and the following disclaimer in the
-		documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-		used to endorse or promote products derived from this software without
-		specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -62,79 +61,7 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-#ifndef _MV_DDR3_TOPOLOGY_DEF_H
-#define _MV_DDR3_TOPOLOGY_DEF_H
 
+#define MV_UART_XMODEM_ACK_CHAR 0x6
 
-/*************************TOPOLOGY*******************************************/
-#ifdef CONFIG_DDR3
-typedef enum
-{
-   SPEED_BIN_DDR_800D,
-   SPEED_BIN_DDR_800E,
-   SPEED_BIN_DDR_1066E,
-   SPEED_BIN_DDR_1066F,
-   SPEED_BIN_DDR_1066G,
-   SPEED_BIN_DDR_1333F,
-   SPEED_BIN_DDR_1333G,
-   SPEED_BIN_DDR_1333H,
-   SPEED_BIN_DDR_1333J,
-   SPEED_BIN_DDR_1600G,
-   SPEED_BIN_DDR_1600H,
-   SPEED_BIN_DDR_1600J,
-   SPEED_BIN_DDR_1600K,
-   SPEED_BIN_DDR_1866J,
-   SPEED_BIN_DDR_1866K,
-   SPEED_BIN_DDR_1866L,
-   SPEED_BIN_DDR_1866M,
-   SPEED_BIN_DDR_2133K,
-   SPEED_BIN_DDR_2133L,
-   SPEED_BIN_DDR_2133M,
-   SPEED_BIN_DDR_2133N,
-
-   SPEED_BIN_DDR_1333H_EXT,
-   SPEED_BIN_DDR_1600K_EXT,
-   SPEED_BIN_DDR_1866M_EXT
-}MV_HWS_SPEED_BIN;
-
-typedef enum 
-{
-  DDR_FREQ_LOW_FREQ,
-  DDR_FREQ_400,
-  DDR_FREQ_533,
-  DDR_FREQ_667,
-  DDR_FREQ_800,
-  DDR_FREQ_933,
-  DDR_FREQ_1066,
-  DDR_FREQ_311,
-  DDR_FREQ_333,
-  DDR_FREQ_467,
-  DDR_FREQ_850,
-  DDR_FREQ_600,
-  DDR_FREQ_300,
-  DDR_FREQ_900,
-  DDR_FREQ_360,
-  DDR_FREQ_1000,
-   DDR_FREQ_LIMIT
-}MV_HWS_DDR_FREQ;
-
-typedef enum
-{
-    speedBinTableElements_tRCD,
-    speedBinTableElements_tRP,
-    speedBinTableElements_tRAS,
-    speedBinTableElements_tRC,
-    speedBinTableElements_tRRD1K,
-    speedBinTableElements_tRRD2K,
-    speedBinTableElements_tPD,
-    speedBinTableElements_tFAW1K,
-    speedBinTableElements_tFAW2K,
-    speedBinTableElements_tWTR,
-    speedBinTableElements_tRTP,
-    speedBinTableElements_tWR,
-    speedBinTableElements_tMOD
-}speedBinTableElements;
-#endif /*CONFIG_DDR3 */
-#endif /* _MV_DDR3_TOPOLOGY_DEF_H */
-
-
+MV_STATUS mvBinHeaderDebugPrompt(void);
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/gtEnvDep.h b/tools/marvell/bin_hdr/inc/common/gtOs/gtEnvDep.h
old mode 100644
new mode 100755
similarity index 100%
rename from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/gtEnvDep.h
rename to tools/marvell/bin_hdr/inc/common/gtOs/gtEnvDep.h
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/gtGenTypes.h b/tools/marvell/bin_hdr/inc/common/gtOs/gtGenTypes.h
old mode 100644
new mode 100755
similarity index 100%
rename from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/gtGenTypes.h
rename to tools/marvell/bin_hdr/inc/common/gtOs/gtGenTypes.h
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/mvXor.h b/tools/marvell/bin_hdr/inc/common/gtOs/mvXor.h
similarity index 100%
rename from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/mvXor.h
rename to tools/marvell/bin_hdr/inc/common/gtOs/mvXor.h
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/mvXorRegs.h b/tools/marvell/bin_hdr/inc/common/gtOs/mvXorRegs.h
similarity index 100%
rename from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/gtOs/mvXorRegs.h
rename to tools/marvell/bin_hdr/inc/common/gtOs/mvXorRegs.h
diff --git a/tools/marvell/bin_hdr/inc/common/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/inc/common/mvDdr3TopologyDef.h
index 958492f..dbe604a 100644
--- a/tools/marvell/bin_hdr/inc/common/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/inc/common/mvDdr3TopologyDef.h
@@ -151,6 +151,7 @@
     DDR_FREQ_933,
     DDR_FREQ_1066,
 	DDR_FREQ_900,
+	DDR_FREQ_1000,
     DDR_FREQ_LIMIT
 }MV_HWS_DDR_FREQ;
 
@@ -218,7 +219,7 @@
    /* Speed Bin Table*/
    MV_HWS_SPEED_BIN      speedBinIndex;
 
-   /* bus width of memory */
+   /* bus width of memory device*/
    MV_HWS_BUS_WIDTH   busWidth;
 
    /* Bus memory size (MBit) */
@@ -248,21 +249,28 @@
    /* Controller configuration per interface */
    InterfaceParams      interfaceParams[MAX_INTERFACE_NUM];
 
-   /* BUS per interface (default is 4)*/
-   MV_U8               numOfBusPerInterface;
-
-   /* Bit mask for active buses*/
+   /* Bit mask for active buses defined interface width and ECC configuration*/
    MV_U8               activeBusMask;
 
 } MV_HWS_TOPOLOGY_MAP;
 
 typedef struct
 {
-   MV_U32              ckDelay;
-   MV_U32              ckDelay_16;
-   MV_U32              Pfinger;
-   MV_U32              Nfinger;
-   MV_U32              PhyReg3Val;
+	MV_U32	ckDelay;	/*the delay between clock to C/A for by8 devices*/
+	MV_U32	PhyReg3Val;	/*Initial value of RX centralization phy reg*/
+
+	MV_U32 gZpriData; 	/*Controller Data P drive strength*/
+	MV_U32 gZnriData; 	/*Controller Data N drive strength*/
+	MV_U32 gZpriCtrl; 	/*Controller C/A P drive strength*/
+	MV_U32 gZnriCtrl; 	/*Controller C/A N drive strength*/
+	MV_U32 gZpodtData; 	/*Controller Data P ODT at the receive*/
+	MV_U32 gZnodtData; 	/*Controller Data N ODT at the receive*/
+	MV_U32 gZpodtCtrl; 	/*Controller C/A P ODT at the receive*/
+	MV_U32 gZnodtCtrl; 	/*Controller C/A N ODT at the receive*/
+	MV_U32 gDic; 		/*Memory drive strength*/
+	MV_U32 uiODTConfig; /*ODT Pin Configuration*/
+	MV_U32 gRttNom; 	/*Memory ODT at the receive*/
+	MV_U32 gRttWR; 		/*Memory ODT at the receive during write*/
 } MV_TUNE_TRAINING_PARAMS;
 
 #endif /* _DDR3_TOPOLOGY_CONFIG_H */
diff --git a/tools/marvell/bin_hdr/inc/common/mvDdrTopologyDef.h b/tools/marvell/bin_hdr/inc/common/mvDdrTopologyDef.h
new file mode 100644
index 0000000..65e44b3
--- /dev/null
+++ b/tools/marvell/bin_hdr/inc/common/mvDdrTopologyDef.h
@@ -0,0 +1,276 @@
+
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+		notice, this list of conditions and the following disclaimer in the
+		documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+		used to endorse or promote products derived from this software without
+		specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+*******************************************************************************/
+#ifndef _DDR3_TOPOLOGY_CONFIG_H
+#define _DDR3_TOPOLOGY_CONFIG_H
+
+#define      ADDR_SIZE_512Mb    0x04000000 
+#define      ADDR_SIZE_1Gb      0x08000000
+#define      ADDR_SIZE_2Gb      0x10000000
+#define      ADDR_SIZE_4Gb      0x20000000
+#define      ADDR_SIZE_8Gb      0x40000000
+
+
+/*************************TOPOLOGY*******************************************/
+#ifdef CONFIG_DDR3
+
+typedef enum
+{
+   SPEED_BIN_DDR_800D,
+   SPEED_BIN_DDR_800E,
+   SPEED_BIN_DDR_1066E,
+   SPEED_BIN_DDR_1066F,
+   SPEED_BIN_DDR_1066G,
+   SPEED_BIN_DDR_1333F,
+   SPEED_BIN_DDR_1333G,
+   SPEED_BIN_DDR_1333H,
+   SPEED_BIN_DDR_1333J,
+   SPEED_BIN_DDR_1600G,
+   SPEED_BIN_DDR_1600H,
+   SPEED_BIN_DDR_1600J,
+   SPEED_BIN_DDR_1600K,
+   SPEED_BIN_DDR_1866J,
+   SPEED_BIN_DDR_1866K,
+   SPEED_BIN_DDR_1866L,
+   SPEED_BIN_DDR_1866M,
+   SPEED_BIN_DDR_2133K,
+   SPEED_BIN_DDR_2133L,
+   SPEED_BIN_DDR_2133M,
+   SPEED_BIN_DDR_2133N,
+
+   SPEED_BIN_DDR_1333H_EXT,
+   SPEED_BIN_DDR_1600K_EXT,
+   SPEED_BIN_DDR_1866M_EXT
+}MV_HWS_SPEED_BIN;
+
+typedef enum 
+{
+  DDR_FREQ_LOW_FREQ,
+  DDR_FREQ_400,
+  DDR_FREQ_533,
+  DDR_FREQ_667,
+  DDR_FREQ_800,
+  DDR_FREQ_933,
+  DDR_FREQ_1066,
+  DDR_FREQ_311,
+  DDR_FREQ_333,
+  DDR_FREQ_467,
+  DDR_FREQ_850,
+  DDR_FREQ_600,
+  DDR_FREQ_300,
+  DDR_FREQ_900,
+  DDR_FREQ_360,
+  DDR_FREQ_1000,
+   DDR_FREQ_LIMIT
+}MV_HWS_DDR_FREQ;
+
+#else
+typedef enum
+{
+    SPEED_BIN_DDR_1600J,
+    SPEED_BIN_DDR_1600K,
+    SPEED_BIN_DDR_1600L,
+    SPEED_BIN_DDR_1866L,
+    SPEED_BIN_DDR_1866M,
+    SPEED_BIN_DDR_1866N,
+    SPEED_BIN_DDR_2133N,
+    SPEED_BIN_DDR_2133P,
+    SPEED_BIN_DDR_2133R,
+    SPEED_BIN_DDR_2400P,
+    SPEED_BIN_DDR_2400R,
+    SPEED_BIN_DDR_2400U,
+}MV_HWS_SPEED_BIN;
+
+typedef enum
+{
+    DDR_FREQ_LOW_FREQ,
+    DDR_FREQ_667,
+    DDR_FREQ_800,
+    DDR_FREQ_933,
+    DDR_FREQ_1066,
+	DDR_FREQ_900,
+    DDR_FREQ_LIMIT
+}MV_HWS_DDR_FREQ;
+
+#endif
+
+typedef enum
+{
+   DDR_BOARD_ETP,
+   DDR_BOARD_FUNCTIONAL,
+   DDR_BOARD_CUSTOMER,
+   DDR_BOARD_MAX
+
+} MV_HWS_DDR_BOARD;
+
+/* bus width in bits */
+typedef enum 
+{
+   BUS_WIDTH_4,
+   BUS_WIDTH_8,
+   BUS_WIDTH_16,
+   BUS_WIDTH_32
+
+} MV_HWS_BUS_WIDTH;
+
+typedef enum 
+{
+   MEM_512M,
+   MEM_1G,
+   MEM_2G,
+   MEM_4G,
+   MEM_8G,
+
+   MEM_SIZE_LAST
+}MV_HWS_MEM_SIZE;
+
+typedef enum
+{
+   MV_HWS_TEMP_LOW,
+   MV_HWS_TEMP_NORMAL,
+   MV_HWS_TEMP_HIGH
+
+}MV_HWS_TEMPERTURE;
+
+typedef struct 
+{
+   /* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */
+   MV_U8      csBitmask;
+
+   /* mirror enable/disable (bits 0-CS0 mirroring, bit 1- CS1 mirroring ...)*/
+   MV_BOOL      mirrorEnableBitmask;
+
+   /* DQS Swap (polarity) - true if enable*/
+   MV_BOOL      isDqsSwap;
+
+   /* CK swap (polarity) - true if enable*/
+   MV_BOOL      isCkSwap;
+
+} BusParams;
+
+typedef struct
+{
+   /* bus configuration */
+   BusParams   asBusParams[MAX_BUS_NUM];
+
+   /* Speed Bin Table*/
+   MV_HWS_SPEED_BIN      speedBinIndex;
+
+   /* bus width of memory device*/
+   MV_HWS_BUS_WIDTH   busWidth;
+
+   /* Bus memory size (MBit) */
+   MV_HWS_MEM_SIZE      memorySize;
+
+   /* The DDR frequency for each interfaces */
+   MV_HWS_DDR_FREQ      memoryFreq;
+
+   /* delay CAS Write Latency - 0 for using default value (jedec suggested) */
+   MV_U8      casWL;
+
+   /* delay CAS Latency - 0 for using default value (jedec suggested) */
+   MV_U8      casL;
+
+   /* operation temperature */
+   MV_HWS_TEMPERTURE   interfaceTemp;
+
+} InterfaceParams;
+
+/***********************************/
+
+typedef struct
+{
+    /* Number of interfaces (default is 12)*/
+    MV_U8              interfaceActiveMask;
+
+   /* Controller configuration per interface */
+   InterfaceParams      interfaceParams[MAX_INTERFACE_NUM];
+
+   /* Bit mask for active buses defined interface width and ECC configuration*/
+   MV_U8               activeBusMask;
+
+} MV_HWS_TOPOLOGY_MAP;
+
+typedef struct
+{
+	MV_U32	ckDelay;	/*the delay between clock to C/A for by8 devices*/
+	MV_U32	PhyReg3Val;	/*Initial value of RX centralization phy reg*/
+
+	MV_U32 gZpriData; 	/*Controller Data P drive strength*/
+	MV_U32 gZnriData; 	/*Controller Data N drive strength*/
+	MV_U32 gZpriCtrl; 	/*Controller C/A P drive strength*/
+	MV_U32 gZnriCtrl; 	/*Controller C/A N drive strength*/
+	MV_U32 gZpodtData; 	/*Controller Data P ODT at the receive*/
+	MV_U32 gZnodtData; 	/*Controller Data N ODT at the receive*/
+	MV_U32 gZpodtCtrl; 	/*Controller C/A P ODT at the receive*/
+	MV_U32 gZnodtCtrl; 	/*Controller C/A N ODT at the receive*/
+	MV_U32 gDic; 		/*Memory drive strength*/
+	MV_U32 uiODTConfig; /*ODT Pin Configuration*/
+	MV_U32 gRttNom; 	/*Memory ODT at the receive*/
+	MV_U32 gRttWR; 		/*Memory ODT at the receive during write*/
+} MV_TUNE_TRAINING_PARAMS;
+
+#endif /* _DDR3_TOPOLOGY_CONFIG_H */
+
+
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x.h
old mode 100644
new mode 100755
index 26630cb..904a2de
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr3_a38x.h
@@ -71,25 +71,56 @@
 #include "ddr3_hws_hw_training_def.h"
 
 /*Allow topolgy update from board TWSI device*/
-#if !defined(CONFIG_CUSTOMER_BOARD_SUPPORT)
+#if ( (!defined(CONFIG_CUSTOMER_BOARD_SUPPORT)) && defined(CONFIG_DDR3) )
+/*TBD - Currentry 16Bit mode not supported in DDR4, open this define after 16Bit mode validation*/
 #define MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
 #endif
 
+#define CONFIG_AVS_FROM_EFUSE /* Read pre-burnt EFUSE values, to derive requested AVS value for current chip */
 #define ECC_SUPPORT
 
 /*Controler bus divider 1 for 32 bit, 2 for 64 bit*/
 #define MV_DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER		1
 
 /*Tune internal training params values*/
-#define MV_TUNE_TRAINING_PARAMS_CK_DELAY 		160
-#define MV_TUNE_TRAINING_PARAMS_CK_DELAY_16		160
-#define MV_TUNE_TRAINING_PARAMS_PFINGER			41
-#define MV_TUNE_TRAINING_PARAMS_NFINGER			43
-#define MV_TUNE_TRAINING_PARAMS_PHYREG3VAL		0xA
+#ifdef CONFIG_CLEARFOG_BOARD
+	/* SolidRun Armada 38x MicroSOM has short traces on it's DDR clock.
+	   using increased internal delay inside the SoC to compensate for that */
+	#define MV_TUNE_TRAINING_PARAMS_CK_DELAY 	260
+#else
+	#define MV_TUNE_TRAINING_PARAMS_CK_DELAY 	160
+#endif
+#define MV_TUNE_TRAINING_PARAMS_PHYREG3VAL	0xA
+
+#define MV_TUNE_TRAINING_PARAMS_PRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_NRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_PRI_CTRL	74
+#define MV_TUNE_TRAINING_PARAMS_NRI_CTRL	74
+
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_CTRL	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_CTRL	45
+
+#define MV_TUNE_TRAINING_PARAMS_DIC				0x2
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS	0x120012
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS	0x10000
+#define MV_TUNE_TRAINING_PARAMS_RTT_NOM			0x44
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_1CS		0x0
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_2CS		0x0
+
+#ifdef CONFIG_DDR4
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_DATA_DDR4	0xD
+#define MV_TUNE_TRAINING_PARAMS_DIC_DDR4		0x0
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_DDR4	0x330012
+#define MV_TUNE_TRAINING_PARAMS_RTT_NOM_DDR4	0x600 /*RZQ/3 = 0x600*/
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR			0x400 /*RZQ/1 = 0x400*/
+#else
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR		0x0 /*off*/
+#endif
 
 #define MARVELL_BOARD MARVELL_BOARD_ID_BASE
 
-
 #define REG_DEVICE_SAR1_ADDR                        0xE4204
 #define RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET         17
 #define RST2_CPU_DDR_CLOCK_SELECT_IN_MASK           0x1F
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
old mode 100644
new mode 100755
index 46ed119..3ac5580
--- 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
@@ -68,15 +68,41 @@
 #include "mvDdr3LoggingDef.h"
 
 /*Bus mask variants*/
-#define BUS_MASK_32BIT				0xF
-#define BUS_MASK_32BIT_ECC			0x1F
-#define BUS_MASK_16BIT				0x3
-#define BUS_MASK_16BIT_ECC			0x13
-#define BUS_MASK_16BIT_ECC_PUP3		0xB
+#define INTERFACE_BUS_MASK_32BIT				0xF
+#define INTERFACE_BUS_MASK_32BIT_ECC			0x1F
+#define INTERFACE_BUS_MASK_16BIT				0x3
+#define INTERFACE_BUS_MASK_16BIT_ECC			0x13
+#define INTERFACE_BUS_MASK_16BIT_ECC_PUP3		0xB
 
 #define  DYNAMIC_CS_SIZE_CONFIG
 #define  DISABLE_L2_FILTERING_DURING_DDR_TRAINING
 
+#ifdef CONFIG_DDR3
+	#define SPEED_BIN_DDR_CUST_BOARD_1	SPEED_BIN_DDR_1866L
+	#define BUS_WIDTH_CUST_BOARD_1		BUS_WIDTH_8
+	#define SPEED_BIN_DDR_CUST_BOARD_2	SPEED_BIN_DDR_1866L
+	#define BUS_WIDTH_CUST_BOARD_2		BUS_WIDTH_8
+	#define SPEED_BIN_DDR_CLEARFOG_BOARD	SPEED_BIN_DDR_1600K
+	#define BUS_WIDTH_CLEARFOG_BOARD	BUS_WIDTH_16
+
+	#define SPEED_BIN_DDR_DB_68XX		SPEED_BIN_DDR_1866L
+	#define BUS_WIDTH_DB_68XX			BUS_WIDTH_8
+	#define SPEED_BIN_DDR_DB_BP_6821	SPEED_BIN_DDR_1866L
+	#define BUS_WIDTH_DB_BP_6821		BUS_WIDTH_8
+#else
+/*Elpida by 16 is 2400R Micron by 8 is 2133P Samsung by 16 is 2133P Hynux by16 is 2133P*/
+	#define SPEED_BIN_DDR_CUST_BOARD_1	SPEED_BIN_DDR_2400R
+	#define BUS_WIDTH_CUST_BOARD_1		BUS_WIDTH_16
+	#define SPEED_BIN_DDR_CUST_BOARD_2	SPEED_BIN_DDR_2400R
+	#define BUS_WIDTH_CUST_BOARD_2		BUS_WIDTH_16
+
+	#define SPEED_BIN_DDR_DB_68XX		SPEED_BIN_DDR_2400R
+	#define BUS_WIDTH_DB_68XX			BUS_WIDTH_16
+	#define SPEED_BIN_DDR_DB_BP_6821	SPEED_BIN_DDR_2400R
+	#define BUS_WIDTH_DB_BP_6821		BUS_WIDTH_16
+#endif
+
+
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 /************************************* Customer Boards Topology *************************************/
 MV_HWS_TOPOLOGY_MAP TopologyMap[] =
@@ -84,26 +110,30 @@
     /* 1st Customer board - reference from DB */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    /*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_CUST_BOARD_1, BUS_WIDTH_CUST_BOARD_1 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-    /* 2nd Customer board */
+    /* 2nd Customer board  - GP Board*/
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    /*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_CUST_BOARD_2, BUS_WIDTH_CUST_BOARD_2 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
+    },
+    /* 3rd Customer board  -  SolidRun ClearFog-A1 REV2.0 */
+    {
+    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_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_width  mem_size     frequency  casL casWL      temperature */
+    /*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}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT_ECC  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT_ECC  /* Buses mask */
     }
 };
 
@@ -112,72 +142,54 @@
 /************************************* Marvell Boards Topology *************************************/
 MV_HWS_TOPOLOGY_MAP TopologyMap[] =
 {
-    /* 1st Marvell board - RD_NAS */
+    /* Marvell board - Board_ID = RD_NAS_68XX_ID = 0*/
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-#ifdef CONFIG_DDR3
-    /* 2nd Marvell board - DB (DDR3) */
+    /* Marvell board - Board_ID = DB_68XX_ID = 1 (DDR3/4)*/
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
-	{{{{0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_device_width  mem_size     frequency  casL casWL      temperature */
+	{{{{0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}}, SPEED_BIN_DDR_DB_68XX, BUS_WIDTH_DB_68XX , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-#else
-    /* 2nd Marvell board - DB (DDR4) */
+    /* Marvell board - Board_ID = RD_AP_68XX_ID = 2 */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
-    {{{{0x1,0,0,0},{ 0x1,0,0,0},{ 0x1,0,0,0},{ 0x1,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133P, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
-    },
-#endif
-    /* 3rd Marvell board - RD_AP */
-    {
-    0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-    /* 4rd Marvell board - DB_AP */
+    /* Marvell board - Board_ID = DB_AP_68XX_ID = 3 */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-    /* 5th Marvell board - DB_GP */
+    /* Marvell board - Board_ID = DB_GP_68XX_ID = 4 */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
-    /* 6th Marvell board - A381/2 DB-BP */
+    /* Marvell board - Board_ID = DB_BP_6821_ID = 5 (DDR3/4) */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
-	{{{{0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_device_width  mem_size     frequency  casL casWL      temperature */
+	{{{{0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}, {0x1,0x1,0,0}}, SPEED_BIN_DDR_DB_BP_6821, BUS_WIDTH_DB_BP_6821, MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
-	/* 6th Marvell board - DB_AMC */
+	/* Marvell board - Board_ID = DB_AMC_6820_ID = 6 */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT_ECC  /* Buses mask */
+	INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
 };
 #endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
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
old mode 100644
new mode 100755
index 21f0f26..7b51135
--- 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
@@ -66,7 +66,10 @@
 #define _INC_A38X_VARS_H
 
 #include "ddr3_a38x_mc_static.h"
-#include "mvDdr3TopologyDef.h"
+#include "mvDdrTopologyDef.h"
+
+/* to run DDR viewer tool (including BIST) uncomment the define
+#define MV_RUN_WIN_VALIDATION_TEST */
 
 typedef struct __mvDramModes {
     char *mode_name;
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr_a38x_dlb_config.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr_a38x_dlb_config.h
index 44a3c6d..b03180f 100755
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr_a38x_dlb_config.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a38x/ddr_a38x_dlb_config.h
@@ -65,62 +65,43 @@
 #define _INC_A38X_DLB_CONFIG_H
 
 #include "ddr3_hws_hw_training_def.h"
+
 #ifdef CONFIG_DDR4
-/* for a39x Z and A38x A0 */
-MV_DRAM_DLB_CONFIG ddr3DlbConfigTable_A0[] =
+MV_DRAM_DLB_CONFIG ddr3DlbConfigTable[] =
 {
-      {REG_STATIC_DRAM_DLB_CONTROL, 	 	0x2000005F},
-      {DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 	0x00880000},
-	  {DLB_AGING_REGISTER, 					0x3F7F007F},
-	  {DLB_EVICTION_CONTROL_REG, 			0x0000129F},
-      {DLB_EVICTION_TIMERS_REGISTER_REG, 	0x00FF0000},
-      {DLB_BUS_WEIGHTS_DIFF_CS, 			0x04030803},
-      {DLB_BUS_WEIGHTS_DIFF_BG,				0x00000A02},
-      {DLB_BUS_WEIGHTS_SAME_BG, 			0x08000901},
-      {DLB_BUS_WEIGHTS_RD_WR,  				0x00020005},
-      {DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 		0x00060F10},
-      {DLB_MAIN_QUEUE_MAP,					0x00000543},
-      {DLB_LINE_SPLIT, 						0x0000000F},
-      {DLB_USER_COMMAND_REG,  				0x00000000},
-      {0x0, 0x0}
+	{REG_STATIC_DRAM_DLB_CONTROL, 	 	0x2000005F},
+	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 	0x00880000},
+	{DLB_AGING_REGISTER, 				0x3F7F007F},
+	{DLB_EVICTION_CONTROL_REG, 			0x0000129F},
+	{DLB_EVICTION_TIMERS_REGISTER_REG, 	0x00FF0000},
+	{DLB_BUS_WEIGHTS_DIFF_CS, 			0x04030803},
+	{DLB_BUS_WEIGHTS_DIFF_BG,			0x00000A02},
+	{DLB_BUS_WEIGHTS_SAME_BG, 			0x08000901},
+	{DLB_BUS_WEIGHTS_RD_WR,  			0x00020005},
+	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 	0x00060F10},
+	{DLB_MAIN_QUEUE_MAP,				0x00000543},
+	{DLB_LINE_SPLIT, 					0x0000000F},
+	{DLB_USER_COMMAND_REG,  			0x00000000},
+    {0x0, 0x0}
 };
 #else
 MV_DRAM_DLB_CONFIG ddr3DlbConfigTable[] =
 {
-	{REG_STATIC_DRAM_DLB_CONTROL, 0x2000005C},
-	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG,  0x00880000},
-	{DLB_AGING_REGISTER,  0x0F7F007F},
-	{DLB_EVICTION_CONTROL_REG,   0x0000129F},
-	{DLB_EVICTION_TIMERS_REGISTER_REG,  0x00FF0000},
-	{DLB_BUS_WEIGHTS_DIFF_CS, 0x04030802},
-	{DLB_BUS_WEIGHTS_DIFF_BG, 0x00000A02},
-	{DLB_BUS_WEIGHTS_SAME_BG, 0x09000A01},
-	{DLB_BUS_WEIGHTS_RD_WR, 0x00020005},
-	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO,0x00060F10},
-	{DLB_MAIN_QUEUE_MAP, 0x00000543},
-	{DLB_LINE_SPLIT,0x00000000},
-	{DLB_USER_COMMAND_REG, 0x00000000},
-	{0x0, 0x0}
-};
-
-MV_DRAM_DLB_CONFIG ddr3DlbConfigTable_A0[] =
-{
-	{REG_STATIC_DRAM_DLB_CONTROL, 0x2000005C},
-	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x00880000},
-	{DLB_AGING_REGISTER,0x0F7F007F},
-	{DLB_EVICTION_CONTROL_REG,0x0000129F},
-	{DLB_EVICTION_TIMERS_REGISTER_REG,0x00FF0000},
-	{DLB_BUS_WEIGHTS_DIFF_CS,0x04030802},
-	{DLB_BUS_WEIGHTS_DIFF_BG,0x00000A02},
-	{DLB_BUS_WEIGHTS_SAME_BG,0x09000A01},
-	{DLB_BUS_WEIGHTS_RD_WR,0x00020005},
-	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO,0x00060F10},
-	{DLB_MAIN_QUEUE_MAP,0x00000543},
-	{DLB_LINE_SPLIT,0x00000000},
-	{DLB_USER_COMMAND_REG,0x00000000},
+	{REG_STATIC_DRAM_DLB_CONTROL, 		0x2000005C},
+	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 	0x00880000},
+	{DLB_AGING_REGISTER,				0x0F7F007F},
+	{DLB_EVICTION_CONTROL_REG,			0x0000129F},
+	{DLB_EVICTION_TIMERS_REGISTER_REG,	0x00FF0000},
+	{DLB_BUS_WEIGHTS_DIFF_CS,			0x04030802},
+	{DLB_BUS_WEIGHTS_DIFF_BG,			0x00000A02},
+	{DLB_BUS_WEIGHTS_SAME_BG,			0x09000A01},
+	{DLB_BUS_WEIGHTS_RD_WR,				0x00020005},
+	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO,		0x00060F10},
+	{DLB_MAIN_QUEUE_MAP,				0x00000543},
+	{DLB_LINE_SPLIT,					0x00000000},
+	{DLB_USER_COMMAND_REG,				0x00000000},
 	{0x0, 0x0}
 };
 #endif
 
-
 #endif /* _INC_A38X_DLB_CONFIG_H */
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_topology.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_topology.h
index 45f266a..e457fec 100644
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_topology.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_topology.h
@@ -68,11 +68,11 @@
 #include "mvDdr3LoggingDef.h"
 
 /*Bus mask variants*/
-#define BUS_MASK_32BIT				0xF
-#define BUS_MASK_32BIT_ECC			0x1F
-#define BUS_MASK_16BIT				0x3
-#define BUS_MASK_16BIT_ECC			0x13
-#define BUS_MASK_16BIT_ECC_PUP3		0xB
+#define INTERFACE_BUS_MASK_32BIT				0xF
+#define INTERFACE_BUS_MASK_32BIT_ECC			0x1F
+#define INTERFACE_BUS_MASK_16BIT				0x3
+#define INTERFACE_BUS_MASK_16BIT_ECC			0x13
+#define INTERFACE_BUS_MASK_16BIT_ECC_PUP3		0xB
 
 #define  DYNAMIC_CS_SIZE_CONFIG
 #define  DISABLE_L2_FILTERING_DURING_DDR_TRAINING
@@ -84,18 +84,16 @@
     /* 1st Customer board - reference from DB */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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},{ 0x2,1,0,0},{ 0x2,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
     /* 2nd Customer board */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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},{ 0x2,1,0,0},{ 0x2,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     }
 };
 
@@ -107,23 +105,21 @@
     /* 1st Marvell board - RD_NAS */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
 #else
     /* 2nd Marvell board - DB (DDR4) */
     {
     0x1, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
-/*Elpida by 16 is 2400R
-	Micron by 8 is 2133P
-	samsung by 16 is XXX
-	Hynux by16 is 2133P*/
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_device_width  mem_size     frequency  casL casWL      temperature */
+/*	Elpida 	by16 	is 2400R
+	Micron 	by8 	is 2133P
+	samsung by16 	is 2133P
+	Hynux 	by16 	is 2133P*/
     {{{{0x3,2,0,0},{ 0x3,2,0,0},{ 0x3,2,0,0},{ 0x3,2,0,0}, {0x3,2 ,0,0}}, SPEED_BIN_DDR_2400R, BUS_WIDTH_16, MEM_4G, DDR_FREQ_800, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_32BIT_ECC  /* Buses mask */
+    INTERFACE_BUS_MASK_32BIT_ECC  /* Buses mask */
     },
 #endif
 
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_vars.h b/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_vars.h
index bd575ee..d04d1f7 100644
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_vars.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/a39x/ddr3_a39x_vars.h
@@ -66,7 +66,7 @@
 #define _INC_A39X_VARS_H
 
 #include "ddr3_a39x_mc_static.h"
-#include "mvDdr3TopologyDef.h"
+#include "mvDdrTopologyDef.h"
 
 typedef struct __mvDramModes {
     char *mode_name;
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3.h
old mode 100644
new mode 100755
index 29fafd7..c5753fd
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3.h
@@ -64,13 +64,13 @@
 #ifndef _DDR3_MSYS_AC3_H
 #define _DDR3_MSYS_AC3_H
 
-#define MAX_INTERFACE_NUM  		(12)
-#define MAX_BUS_NUM        		(8)
+#define MAX_INTERFACE_NUM  		(1)
+#define MAX_BUS_NUM        		(5)
 
 #include "ddr3_hws_hw_training_def.h"
 
-/*Controler bus divider 1 for 32 bit, 2 for 64 bit*/
-#define MV_DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER		1
+/*Controler bus divider 1 for 32 bit, 2 for 64 bit */
+#define MV_DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER         1
 
 /* MISC */
 #define INTER_REGS_BASE								0xD0000000
@@ -102,7 +102,7 @@
 #define	REG_SAMPLE_RESET_CPU_ARCH_OFFS			31
 #define	REG_SAMPLE_RESET_HIGH_CPU_FREQ_OFFS		20
 
-#define MV_BOARD_REFCLK			250000000
+#define MV_BOARD_REFCLK			mvBoardTclkGet()
 
 /* DDR3 Frequencies: */
 #define DDR_100									0
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_config.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_config.h
index 5a93789..3314b09 100644
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_config.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_config.h
@@ -62,13 +62,9 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-
-
 #ifndef _DDR3_MSYS_AC3_CONFIG_H
 #define _DDR3_MSYS_AC3_CONFIG_H
 
-#define DDR3_FAST_PATH_EN			1
-#define SUPPORT_STATIC_DUNIT_CONFIG
-
 #endif /* _DDR3_MSYS_AC3_CONFIG_H */
 
+
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_topology.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_topology.h
index 8721fef..43e0b79 100755
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_topology.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_topology.h
@@ -68,15 +68,16 @@
 #include "mvDdr3LoggingDef.h"
 
 /*Bus mask variants*/
-#define BUS_MASK_32BIT				0xF
-#define BUS_MASK_32BIT_ECC			0x1F
-#define BUS_MASK_16BIT				0x3
-#define BUS_MASK_16BIT_ECC			0x13
-#define BUS_MASK_16BIT_ECC_PUP3		0xB
+#define INTERFACE_BUS_MASK_32BIT				0xF
+#define INTERFACE_BUS_MASK_32BIT_ECC			0x1F
+#define INTERFACE_BUS_MASK_16BIT				0x3
+#define INTERFACE_BUS_MASK_16BIT_ECC			0x13
+#define INTERFACE_BUS_MASK_16BIT_ECC_PUP3		0xB
 
 #define  DYNAMIC_CS_SIZE_CONFIG
 #define  MV_DEVICE_MAX_DRAM_ADDRESS_SIZE          ADDR_SIZE_2Gb
 
+
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 /************************************* Customer Boards Topology *************************************/
 MV_HWS_TOPOLOGY_MAP TopologyMap[] =
@@ -85,19 +86,17 @@
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                                     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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}, {0x3,0,0,0}, {0x3,0,0,0}, {0x0,0,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
     /* 2nd Customer board */
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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},{ 0x2,1,0,0},{ 0x2,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     }
 };
 
@@ -109,46 +108,41 @@
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin        memory_device_width  mem_size     frequency  casL casWL      temperature */
 	{{{{0x3,2,0,0}, {0x3,2,0,0},{0x3,2,0,0}, {0x3,2,0,0}, {0x3,2,0,0}}, SPEED_BIN_DDR_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
 	/* 2rd Marvell board - RD_MTL_4XG  (BoardId = 0x1) */
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
 	/* 3rd Marvell board - RD_MTL_2XXG_2XG: No ECC (BoardId = 0x2) */
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
     /* 4th Marvell board - DB_MISL_24G4G - No ECC (BoardId = 0x3) */
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
     /* 5th Marvell board - RD_MTL_24G - No ECC (BoardId = 0x4) */
     {
     0x1, /* active interfaces */
 	/* ATTENTION - cs_mask and mirror  HAVE to be the same for all PUPs*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs     speed_bin        memory_width  mem_size     frequency  casL casWL      temperature */
+    /*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_1866L, BUS_WIDTH_8 , MEM_4G, DDR_FREQ_400, 0 ,   0 , MV_HWS_TEMP_LOW}},
-    5, /* Num Of Bus Per Interface*/
-    BUS_MASK_16BIT  /* Buses mask */
+    INTERFACE_BUS_MASK_16BIT  /* Buses mask */
     },
 };
 #endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_vars.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_vars.h
old mode 100644
new mode 100755
index afd1bd3..f8dd185
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_vars.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_ac3_vars.h
@@ -67,7 +67,7 @@
 
 #include "ddr3_msys_ac3_config.h"
 #include "ddr3_msys_ac3_mc_static.h"
-#include "mvDdr3TopologyDef.h"
+#include "mvDdrTopologyDef.h"
 
 #if !defined(CONFIG_CUSTOMER_BOARD_SUPPORT)
 #define MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
@@ -77,11 +77,25 @@
 
 /*Tune internal training params values*/
 #define MV_TUNE_TRAINING_PARAMS_CK_DELAY 		200
-#define MV_TUNE_TRAINING_PARAMS_CK_DELAY_16		200
-#define MV_TUNE_TRAINING_PARAMS_PFINGER			41
-#define MV_TUNE_TRAINING_PARAMS_NFINGER			43
 #define MV_TUNE_TRAINING_PARAMS_PHYREG3VAL		0xA
 
+#define MV_TUNE_TRAINING_PARAMS_PRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_NRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_PRI_CTRL	74
+#define MV_TUNE_TRAINING_PARAMS_NRI_CTRL	74
+
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_CTRL	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_CTRL	45
+
+#define MV_TUNE_TRAINING_PARAMS_DIC				0x2
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS	0x120012
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS	0x10000
+#define MV_TUNE_TRAINING_PARAMS_RTT_NOM			0x44
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_1CS		0x0 /* off */
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_2CS		0x0 /* off */
+
 typedef struct __mvDramModes {
     char *mode_name;
     MV_U8 cpuFreq;
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2.h
index bfc3cc6..4327611 100644
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2.h
@@ -65,13 +65,13 @@
 #ifndef _DDR3_MSYS_BC2_H
 #define _DDR3_MSYS_BC2_H
 
-#define MAX_INTERFACE_NUM  		(12)
-#define MAX_BUS_NUM        		(8)
+#define MAX_INTERFACE_NUM  		(5)
+#define MAX_BUS_NUM        		(5)
 
 #include "ddr3_hws_hw_training_def.h"
 
-/*Controler bus divider 1 for 32 bit, 2 for 64 bit*/
-#define MV_DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER		2
+/*Controler bus divider 1 for 32 bit, 2 for 64  bit */
+#define MV_DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER         2
 
 /* MISC */
 #define INTER_REGS_BASE								0xD0000000
@@ -104,7 +104,7 @@
 #define	REG_SAMPLE_RESET_CPU_ARCH_OFFS			31
 #define	REG_SAMPLE_RESET_HIGH_CPU_FREQ_OFFS		20
 
-#define MV_BOARD_REFCLK			250000000
+#define MV_BOARD_REFCLK			mvBoardTclkGet()
 
 /* DDR3 Frequencies: */
 #define DDR_100									0
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_topology.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_topology.h
index 8c9f44c..049fe80 100644
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_topology.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_topology.h
@@ -68,47 +68,34 @@
 #include "ddr3_msys_bc2_config.h"
 #include "mvDdr3LoggingDef.h"
 
-#define ACTUAL_BUS_WIDTH	BUS_WIDTH_32
+#define INTERFACE_BUS_MASK_32BIT       0xF
+#define DYNAMIC_CS_SIZE_CONFIG
 
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
 /************************************* Customer Boards Topology *************************************/
 MV_HWS_TOPOLOGY_MAP TopologyMap[] =  {{
     /* 1st Customer board  referenced from MArvell DB board*/
     0x10, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
- {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0,    0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH}} ,
-    4, /* Num Of Bus Per Interface*/
-    0xF  /* Buses mask */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                          speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+ } ,
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
     /* 2nd Customer board  reference from MArvell RD board*/
 {
     0x10, /* active interfaces #1*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
- {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0,    0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH}} ,
-    4, /* Num Of Bus Per Interface*/
-    0xF  /* Buses mask */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                          speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+} ,
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
 };
 
@@ -117,41 +104,38 @@
 MV_HWS_TOPOLOGY_MAP TopologyMap[] =  {{
     /* 1st Marvell board */
     0x10, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
- {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0,    0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_1866M, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH}} ,
-    4, /* Num Of Bus Per Interface*/
-    0xF  /* Buses mask */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                          speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_1866M, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+} ,
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
     },
     /* 2nd Marvell board */
 {
     0x10, /* active interfaces #1*/
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
- {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0,    0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{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}}, SPEED_BIN_DDR_2133N, ACTUAL_BUS_WIDTH, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH}} ,
-    4, /* Num Of Bus Per Interface*/
-    0xF  /* Buses mask */
-    }
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                         speed_bin            memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, }, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+ } ,
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
+    },
+    /* 3rd Marvell board */
+{
+    0x10, /* active interfaces #1*/
+    /*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}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16, MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH}} ,
+    INTERFACE_BUS_MASK_32BIT  /* Buses mask */
+    },
 };
 
 #endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
diff --git a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_vars.h b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_vars.h
old mode 100644
new mode 100755
index d1417da..634a671
--- a/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_vars.h
+++ b/tools/marvell/bin_hdr/inc/ddr3_soc/msys/ddr3_msys_bc2_vars.h
@@ -66,15 +66,29 @@
 #define _INC_MSYS_BC2_VARS_H
 
 #include "ddr3_msys_bc2_config.h"
-#include "mvDdr3TopologyDef.h"
+#include "mvDdrTopologyDef.h"
 
 /*Tune internal training params values*/
 #define MV_TUNE_TRAINING_PARAMS_CK_DELAY 		150
-#define MV_TUNE_TRAINING_PARAMS_CK_DELAY_16		150
-#define MV_TUNE_TRAINING_PARAMS_PFINGER			41
-#define MV_TUNE_TRAINING_PARAMS_NFINGER			43
 #define MV_TUNE_TRAINING_PARAMS_PHYREG3VAL		0xA
 
+#define MV_TUNE_TRAINING_PARAMS_PRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_NRI_DATA	123
+#define MV_TUNE_TRAINING_PARAMS_PRI_CTRL	74
+#define MV_TUNE_TRAINING_PARAMS_NRI_CTRL	74
+
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_DATA	45
+#define MV_TUNE_TRAINING_PARAMS_P_ODT_CTRL	45
+#define MV_TUNE_TRAINING_PARAMS_N_ODT_CTRL	45
+
+#define MV_TUNE_TRAINING_PARAMS_DIC				0x2
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS	0x120012
+#define MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS	0x10000
+#define MV_TUNE_TRAINING_PARAMS_RTT_NOM			0x44
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_1CS		0x200 /*RZQ/4*/
+#define MV_TUNE_TRAINING_PARAMS_RTT_WR_2CS		0x200 /*RZQ/4*/
+
 typedef struct __mvDramMcInit {
 	MV_U32 reg_addr;
 	MV_U32 reg_value;
diff --git a/tools/marvell/bin_hdr/main/mvdispacher.c b/tools/marvell/bin_hdr/main/mvdispacher.c
index 46c1f8b..d22013d 100755
--- a/tools/marvell/bin_hdr/main/mvdispacher.c
+++ b/tools/marvell/bin_hdr/main/mvdispacher.c
@@ -65,14 +65,35 @@
 #include "mv_os.h"
 #include "mvUart.h"
 #include "mvBinHdrComponents.h"
+#include "printf.h"
+
+#ifdef MV_DEBUG_MODE
+#include "debug.h"
+#endif
 
 MV_BINARY_HEADER_COMPONENTS componentTable[]={ BIN_HEADER_COMPONENT_TABLE};
 
+#ifdef MV_DEBUG_MODE
+static void print_menu() {
+	mvPrintf("\nPlease choose one of the following commands:\n");
+	mvPrintf("\t1.SERDES initialization\n");
+	mvPrintf("\t2.DRAM initialization\n");
+	mvPrintf("\t3.Suspend wake up\n");
+	mvPrintf("\t4.Prompt mode\n");
+	mvPrintf("\t\tSelected command number:");
+}
+#endif
+
 int mvBinHdrDispatcher(void)
 {
-	MV_STATUS rc;
 	MV_BINARY_HEADER_COMPONENTS *pComponent= componentTable;
+	MV_STATUS rc;
+#ifdef MV_DEBUG_MODE
+	int i;
+	char c;
+#endif
 
+#ifndef MV_DEBUG_MODE
     while (pComponent->ComponentFunc){
 		rc = pComponent->ComponentFunc();
 		if (rc != MV_OK)
@@ -85,5 +106,37 @@
 		}
 		pComponent++;
 	}
+#else
+	/* Run GeneralInit component
+	 * needed for genereal MPP's (i.e UART, I2C, etc.) */
+	if (pComponent->ComponentFunc)
+		pComponent->ComponentFunc();
+	/* send ACKs to the sender to finish sx-at91 protocol running
+	 * and start using UART for prints
+	 * 3 ACKS are required to finish transaction */
+	for (i = 0; i < 3; ++i)
+		mvUartPutc(MV_UART_XMODEM_ACK_CHAR);
+	/* get the last char sent by the protocol (EOT) */
+	mvUartGetc();
+
+	while (1) {
+		print_menu();
+		c = mvUartGetc();
+
+		if (c >= '1' && c <= '3') {
+			pComponent = componentTable + (c - '0');
+			if (pComponent->ComponentFunc) {
+				rc = pComponent->ComponentFunc();
+				if (rc != MV_OK)
+					mvPrintf("\n\n ********** %s failed! **********", pComponent->ComponentName);
+			}
+		} else if (c == '4') {
+			rc = mvBinHeaderDebugPrompt();
+			if (rc != MV_OK)
+				mvPrintf("\n\n ********** Binary Header Debug Prompt failed! **********");
+		} else
+			mvPrintf("\n\nInvalid command number\n");
+	}
+#endif
 	return 0;
 }
diff --git a/tools/marvell/bin_hdr/platform/Makefile b/tools/marvell/bin_hdr/platform/Makefile
index 9ba1eb0..c196bef 100755
--- a/tools/marvell/bin_hdr/platform/Makefile
+++ b/tools/marvell/bin_hdr/platform/Makefile
@@ -70,14 +70,17 @@
 
 TGT = plat.a
 TGT_UART = plat.uart.a
+TGT_DEBUG = plat.debug.a
 
 DRV = drivers
 UTILS = utils
 SYS_ENV = sysEnv/$(BOARD)
+BIN_HDR_DEBUG = $(UTILS)/debug
 
 CSRC_DRV = $(DRV)/mv_uart.c $(DRV)/mv_twsi.c $(DRV)/mv_time.c
 CSRC_UTILS = $(UTILS)/utils.c $(UTILS)/printf.c $(UTILS)/mvHwsSiliconIf.c
 CSRC_SYS_ENV = $(SYS_ENV)/mvSysEnvLib.c
+CSRC_BIN_HDR_DEBUG = $(BIN_HDR_DEBUG)/debug.c $(BIN_HDR_DEBUG)/lib_utils.c $(BIN_HDR_DEBUG)/command.c $(BIN_HDR_DEBUG)/mem.c $(BIN_HDR_DEBUG)/xor_memtest.c
 
 ifeq "$(CONFIG_ALLEYCAT3)"  "y"
   CSRC_UTILS += $(UTILS)/mv_seq_exec_ext.c
@@ -98,11 +101,14 @@
 endif
 
 CSRC = $(CSRC_DRV) $(CSRC_UTILS) $(CSRC_SYS_ENV)
+CSRC_DEBUG = $(CSRC) $(CSRC_BIN_HDR_DEBUG)
 
 COBJ = $(subst .c,.o,$(CSRC))
 CUART_OBJ = $(subst .c,.uart.o,$(CSRC))
+CDEBUG_OBJ = $(subst .c,.debug.o,$(CSRC_DEBUG))
 
-all:   $(TGT) $(TGT_UART)
+
+all:   $(TGT) $(TGT_UART) $(TGT_DEBUG)
 
 %.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
@@ -110,6 +116,9 @@
 %.uart.o: %.c
 	$(CC) $(CFLAGS) -DNOT_USE_UART -DMV_NO_INPUT -DMV_NO_PRINT  $(CPPFLAGS) -c -o  $@ $<
 
+%.debug.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o  $@ $<
+
 $(TGT): $(COBJ)
 	ar rcs $(TGT)  $(COBJ)
 	$(CP) ./$@ ../
@@ -118,6 +127,10 @@
 	ar rcs $(TGT_UART)  $(CUART_OBJ)
 	$(CP) ./$@ ../
 
+$(TGT_DEBUG): $(CDEBUG_OBJ)
+	ar rcs $(TGT_DEBUG)  $(CDEBUG_OBJ)
+	$(CP) ./$@ ../
+
 setparams:
 	$(HOSTCC) $(BOARDFLAG) -Wall $(INCLUDE) $(CPPFLAGS) -o $@  $(addsuffix .c, $(UTILS)/$@)
 	$(CP) $@ ../
diff --git a/tools/marvell/bin_hdr/platform/drivers/mv_time.c b/tools/marvell/bin_hdr/platform/drivers/mv_time.c
index 72fca45..765647b 100755
--- a/tools/marvell/bin_hdr/platform/drivers/mv_time.c
+++ b/tools/marvell/bin_hdr/platform/drivers/mv_time.c
@@ -63,6 +63,7 @@
 *******************************************************************************/
 #include "config_marvell.h"     /* Required to identify SOC and Board */
 #include "mv_os.h"
+#include "mvSysEnvLib.h"
 #if defined(MV88F78X60)
 #include "ddr3_axp.h"
 #elif defined(MV88F6710)
@@ -87,7 +88,6 @@
 #endif
 #define UBOOT_CNTR              0       /* counter to use for uboot timer  0,1 */
 
-
 void __udelay(unsigned long usec)
 {
     unsigned long delayticks;
@@ -104,7 +104,11 @@
     cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG(UBOOT_CNTR));
     cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
     cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
-    cntmrCtrl |= CTCR_ARM_TIMER_25MhzFRQ_EN(UBOOT_CNTR);
+
+	/* check if 25Mhz as ref clock is supported by SoC */
+	if (mvSysEnvTimerIsRefClk25Mhz())
+		cntmrCtrl |= CTCR_ARM_TIMER_25MhzFRQ_EN(UBOOT_CNTR);
+
     MV_REG_WRITE(CNTMR_CTRL_REG(UBOOT_CNTR),cntmrCtrl);
 
     while(MV_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)));
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a370/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/a370/mvSysEnvLib.c
index 7437467..206a85e 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/a370/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a370/mvSysEnvLib.c
Binary files differ
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.c
index 1a0daf0..9a213a6 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.c
@@ -307,3 +307,11 @@
 	value = MV_REG_READ(DEV_VERSION_ID_REG);
 	return  ((value & (REVISON_ID_MASK) ) >> REVISON_ID_OFFS);
 }
+
+/* mvSysEnvTimerIsRefClk25Mhz:
+ * A375 support 25Mhz as ref.clock for timer
+ */
+MV_BOOL mvSysEnvTimerIsRefClk25Mhz(void)
+{
+	return MV_TRUE;
+}
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.h b/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.h
index 1ec3b9d..2984529 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.h
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a375/mvSysEnvLib.h
@@ -277,5 +277,15 @@
 MV_STATUS mvBoardTwsiGet(MV_U32 address, MV_U8 devNum, MV_U8 regNum, MV_U8 *pData);
 MV_U32 mvBoardIdIndexGet(MV_U32 boardId);
 MV_U32 mvBoardIdGet(MV_VOID);
+/**************************************************************************
+ * mvSysEnvTimerIsRefClk25Mhz -
+ *
+ * DESCRIPTION:          Routine to indicate if 25Mhz ref clock for timer is supported
+ * INPUT:                None.
+ * OUTPUT:               None.
+ * RETURNS:              None.
+ ***************************************************************************/
+MV_STATUS mvSysEnvTimerIsRefClk25Mhz(MV_VOID);
 
 #endif /* __INCmvBHboardEnvSpech */
+
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
index c32eb08..0b6a6d3 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.c
@@ -68,6 +68,8 @@
 #include "util.h"
 #include "mv_seq_exec.h"
 #include "printf.h"
+#include "generalInit.h"
+
 #ifdef MV88F69XX
        #include "ddr3_a39x.h"
 #else
@@ -80,31 +82,241 @@
 
 #ifdef CONFIG_ARMADA_38X
 MV_UNIT_ID mvSysEnvSocUnitNums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
-/*                     6820    6810     6811     6828     */
-/* PEX_UNIT_ID      */ { 4,     3,       3,       4},
-/* ETH_GIG_UNIT_ID  */ { 3,		2,       3,       3},
-/* USB3H_UNIT_ID    */ { 2,     2,       2,       2},
-/* USB3D_UNIT_ID    */ { 1,     1,       1,       1},
-/* SATA_UNIT_ID     */ { 2,     2,       2,       4},
-/* QSGMII_UNIT_ID   */ { 1,     0,       0,       1},
-/* XAUI_UNIT_ID     */ { 0,     0,       0,       0},
-/* RXAUI_UNIT_ID    */ { 0,     0,       0,       0}
+/*                     6820    6810     6811     6828   6W22    6W23 */
+/*                     A385    A380     A381/2   A388   A383    A384 */
+/*                     ========= HW Flavors =========   == Virtual ==*/
+/* PEX_UNIT_ID      */ { 4,     3,       3,       4,	2,	2},
+/* SGMII_UNIT_ID*/     { 3,	2,       3,       3,	2,	2},
+/* USB3H_UNIT_ID    */ { 2,     2,       2,       2,	1,	1},
+/* USB3D_UNIT_ID    */ { 1,     1,       1,       1,	0,	0},
+/* SATA_UNIT_ID     */ { 2,     2,       2,       4,	1,	1},
+/* QSGMII_UNIT_ID   */ { 1,     0,       0,       1,	0,	0},
+/* XAUI_UNIT_ID     */ { 0,     0,       0,       0,	0,	0},
+/* RXAUI_UNIT_ID    */ { 0,     0,       0,       0,	0,	0}
 };
 #else  /* if (CONFIG_ARMADA_39X) */
 MV_UNIT_ID mvSysEnvSocUnitNums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
-/*                      6920     6928     */
-/* PEX_UNIT_ID      */ { 4,       4},
-/* ETH_GIG_UNIT_ID  */ { 3,       4},
-/* USB3H_UNIT_ID    */ { 1,       2},
-/* USB3D_UNIT_ID    */ { 0,       1},
-/* SATA_UNIT_ID     */ { 0,       4},
-/* QSGMII_UNIT_ID   */ { 0,       1},
-/* XAUI_UNIT_ID     */ { 1,       1},
-/* RXAUI_UNIT_ID    */ { 1,		  1}
+/*				6920     6928     */
+/* PEX_UNIT_ID      */		{ 4,       4},
+/* SGMII_UNIT_ID    */		{ 3,       4},
+/* USB3H_UNIT_ID    */		{ 1,       2},
+/* USB3D_UNIT_ID    */		{ 0,       1},
+/* SATA_UNIT_ID     */		{ 0,       4},
+/* QSGMII_UNIT_ID   */		{ 0,       1},
+/* XAUI_UNIT_ID     */		{ 1,       1},
+/* RXAUI_UNIT_ID    */		{ 1,	   1}
 };
 #endif
 
+static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs, MV_U32 mask, MV_U32 value)
+{
+	MV_U32 gppData;
 
+	gppData = MV_REG_READ(regOffs);
+
+	gppData &= ~mask;
+
+	gppData |= (value & mask);
+
+	MV_REG_WRITE(regOffs, gppData);
+}
+/*******************************************************************************
+* mvSysEnvIoExpValSet - Set USB VBUS signal via GPIO
+*
+** INPUT:	gppNo - GPIO pin number.
+** OUTPUT:	None.
+** RETURN:	None.
+*******************************************************************************/
+MV_VOID mvSysEnvUsbVbusGppReset(int gppNo)
+{
+	MV_U32 regVal;
+
+	/* MPP Control Register - set mpp as GPP (value = 0)*/
+	regVal = MV_REG_READ(MPP_CONTROL_REG((unsigned int)(gppNo / 8)));
+	regVal &= ~(0xf << ((gppNo % 8) * 4));
+	MV_REG_WRITE(MPP_CONTROL_REG((unsigned int)(gppNo / 8)), regVal);
+
+	if (gppNo < 32) {
+		/* GPIO Data Out Enable Control Register - set to output */
+		MV_REG_WRITE(GPP_DATA_OUT_EN_REG(0), 0);
+		/* GPIO output Data Value Register - set as low */
+		MV_REG_WRITE(GPP_DATA_OUT_REG(0), 0);
+	} else {
+		/* GPIO Data Out Enable Control Register - set to output */
+		MV_REG_WRITE(GPP_DATA_OUT_EN_REG(1), 0);
+		/* GPIO output Data Value Register - set as low */
+		MV_REG_WRITE(GPP_DATA_OUT_REG(1), 0);
+	}
+}
+/*******************************************************************************
+* mvSysEnvIoExpValSet - Set USB VBUS signal for DB-GP board via IO expander
+*
+** INPUT:	None.
+** OUTPUT:	None.
+** RETURN:	None.
+*******************************************************************************/
+MV_STATUS mvSysEnvIoExpUsbVbusSet(MV_U8 value)
+{
+	MV_U8 readVal, configVal, offset = 7; /* Io Expander#1 (0x21), register#1, bit 7 */
+	MV_TWSI_SLAVE twsiSlave;
+
+	/* Read bit[4] in BC2 bios0 SW SatR (register 1) */
+	twsiSlave.slaveAddr.type = ADDR7_BIT;
+	twsiSlave.slaveAddr.address = MV_BOARD_IO_EXPANDER1_ADDR;
+	twsiSlave.validOffset = MV_TRUE;
+	twsiSlave.moreThen256 = MV_FALSE;
+
+	twsiSlave.offset = 7;	/* direction reg #1 (register 7) for output/input setting */
+	if (MV_OK != mvTwsiRead(TWSI_CHANNEL_A3XX, &twsiSlave, &configVal, 1)) {
+		mvPrintf("%s: Error: Read Configuration from IO Expander failed\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* Modify direction (output/input) value of requested pin */
+	configVal &= ~(1 << offset);	/* output marked as 0: clean bit of old value  */
+
+	if (mvTwsiWrite(TWSI_CHANNEL_A3XX, &twsiSlave, &configVal, 1) != MV_OK) {
+		/* Write again in case the controller is busy */
+		if (mvTwsiWrite(TWSI_CHANNEL_A3XX, &twsiSlave, &configVal, 1) != MV_OK) {
+			mvPrintf("%s: Error: direction Write to IO Expander at 0x%x failed\n", __func__
+			   , MV_BOARD_IO_EXPANDER1_ADDR);
+			return MV_ERROR;
+		}
+	}
+
+	twsiSlave.offset = 3; 	/* Read Output Value */
+	if (MV_OK != mvTwsiRead(TWSI_CHANNEL_A3XX, &twsiSlave, &readVal, 1)) {
+		mvPrintf("%s: Error: Read Configuration from IO Expander failed\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* Modify */
+	readVal &= ~(1 << offset);	/* clean bit of old value  */
+	readVal |= (value << offset);
+
+	if (mvTwsiWrite(TWSI_CHANNEL_A3XX, &twsiSlave, &readVal, 1) != MV_OK) {
+		/* Write again in case the controller is busy */
+		if (mvTwsiWrite(TWSI_CHANNEL_A3XX, &twsiSlave, &readVal, 1) != MV_OK) {
+		mvPrintf("%s: Error: direction Write to IO Expander at 0x%x failed\n", __func__
+			   , MV_BOARD_IO_EXPANDER1_ADDR);
+			return MV_ERROR;
+		}
+	}
+
+	return MV_OK;
+}
+
+/*******************************************************************************
+* mvSysEnvUsbVbusReset - Set USB VBUS signal before detection
+*
+* DESCRIPTION:
+* this routine sets VBUS signal via GPIO or via I2C IO expander
+*
+** INPUT:	int  dev - USB Host number
+** OUTPUT:	None.
+** RETURN:	None.
+*******************************************************************************/
+MV_VOID mvSysEnvUsbVbusReset(MV_VOID)
+{
+	MV_32 i, gppNo;
+	MV_BOARD_USB_VBUS_GPIO boardUsbVbusGpio[] = MV_BOARD_USB_VBUS_GPIO_INFO;
+	MV_U32 boardIdIndex;
+
+	/* Some of Marvell boards control VBUS signal via I2C IO expander unit */
+#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+	/* if VBUS signal is Controlled via I2C IO Expander on board*/
+	if (mvBoardIdGet() == DB_GP_68XX_ID) {
+		mvSysEnvIoExpUsbVbusSet(0);
+		return;
+	}
+#endif
+
+	boardIdIndex = mvBoardIdIndexGet(mvBoardIdGet());
+	if (!(sizeof(boardUsbVbusGpio)/sizeof(MV_BOARD_USB_VBUS_GPIO) > boardIdIndex)) {
+		mvPrintf("\nFailed loading USB VBUS GPIO information (invalid board ID)\n");
+		return;
+	}
+
+	for (i = 0; i < mvSysEnvUnitMaxNumGet(USB3H_UNIT_ID); i++) {
+		gppNo = boardUsbVbusGpio[boardIdIndex].usbVbusGpio[i];
+		/* if VBUS signal is Controlled via GPIO on board */
+		if (gppNo != MV_ERROR) {
+			mvSysEnvUsbVbusGppReset(gppNo);
+			continue;
+		}
+	}
+}
+
+/* mvBoardDb6820AmcTwsiConfig:
+ * for AMC board, to allow detection of remote PCIe GEN1/GEN2 enforcement settings:
+ * 1. Enable external i2c channel for via GPIO
+ * 2. Disable I2C Slave Port0 of local AMC device, to avoid bus address contention
+ */
+static MV_VOID mvBoardDb6820AmcTwsiConfig(MV_VOID)
+{
+	/* Disable I2C Slave Ports of local AMC device, to avoid bus address contention*/
+	MV_REG_BIT_RESET(TWSI_CONFIG_DEBUG_REG, TWSI_DEBUG_SLAVE_PORT0_EN);
+	MV_REG_BIT_RESET(TWSI_CONFIG_DEBUG_REG, TWSI_DEBUG_SLAVE_PORT1_EN);
+
+	/* GPP configuration is required for disabling access to i2c channel 1
+	   Output from GPP-44 should set to be HIGH for disabling external
+	   i2c channel 1 buffer circuit
+	   The entire GPPs configuration is the same as in u-boot */
+	/* Set GPP Out value */
+	MV_REG_WRITE(GPP_DATA_OUT_REG(0), BIT29); /* GPIO29: QS_SMI_ENA = OUT VAL High */
+	MV_REG_WRITE(GPP_DATA_OUT_REG(1), BIT12); /* GPIO44 (BIT12) : I2C_EXT_EN = FALSE (False = OUT VAL High) */
+	MV_REG_WRITE(GPP_DATA_OUT_REG(2), 0);
+
+	/* set GPP polarity */
+	gppRegSet(0, GPP_DATA_IN_POL_REG(0), 0xFFFFFFFF, 0x0);
+	gppRegSet(1, GPP_DATA_IN_POL_REG(1), 0xFFFFFFFF, 0x0);
+	gppRegSet(2, GPP_DATA_IN_POL_REG(2), 0xFFFFFFFF, 0x0);
+
+	/* Set GPP Out Enable */
+	/* GPIO29: QS_SMI_ENA */
+	gppRegSet(0, GPP_DATA_OUT_EN_REG(0), 0xFFFFFFFF, ~(BIT29));
+	/* 44:I2C_EXT_EN, 49,50,52,53:Leds*/
+	gppRegSet(1, GPP_DATA_OUT_EN_REG(1), 0xFFFFFFFF, ~(BIT12 | BIT17 | BIT18 | BIT20 | BIT21));
+	gppRegSet(2, GPP_DATA_OUT_EN_REG(2), 0xFFFFFFFF, ~(0x0));
+}
+
+/*******************************************************************************
+* mvBoardForcePcieGen1Get - read MSYS BC2/AC3 SatR bios0 bit[4] for PCIe GEN1/GEN2 mode
+*
+* DESCRIPTION:
+*
+* INPUT:
+*
+* OUTPUT:
+*       None.
+*
+* RETURN: TRUE if GEN1 connection is enforced
+*******************************************************************************/
+MV_BOOL mvBoardForcePcieGen1Get(MV_VOID)
+{
+	MV_TWSI_SLAVE twsiSlave;
+	MV_TWSI_ADDR slave;
+	MV_U8 data;
+
+	/* TWSI init */
+	slave.address = MV_BOARD_CTRL_I2C_ADDR_BC2;
+	slave.type    = ADDR7_BIT;
+	mvTwsiInit(TWSI_CHANNEL_A3XX, TWSI_SPEED_BC2, mvBoardTclkGet(), &slave, 0);
+
+	/* Read bit[4] in BC2 bios0 SW SatR (register 1) */
+	twsiSlave.slaveAddr.type = ADDR7_BIT;
+	twsiSlave.slaveAddr.address = MV_BOARD_BIOS0_ADDR;
+	twsiSlave.offset = 1; /* register 1, SW SatR fields */
+	twsiSlave.validOffset = MV_TRUE;
+	twsiSlave.moreThen256 = MV_FALSE;
+
+	if (MV_OK == mvTwsiRead(TWSI_CHANNEL_A3XX, &twsiSlave, &data, 1)) {
+		if ((data >> 4) & 0x1)
+			return MV_TRUE;
+	}
+
+	return MV_FALSE;
+}
 
 MV_U32 gBoardId = -1;
 MV_U32 mvBoardIdGet(MV_VOID)
@@ -117,6 +329,8 @@
 		gBoardId = CUSTOMER_BOARD_ID0;
 	#elif CONFIG_CUSTOMER_BOARD_1
 		gBoardId = CUSTOMER_BOARD_ID1;
+	#elif CONFIG_CLEARFOG_BOARD
+		gBoardId = A38X_CLEARFOG_BOARD_ID;
 	#elif CONFIG_GFCH100
 		gBoardId = GFCH100_ID;
 	#endif
@@ -162,13 +376,21 @@
 
 MV_U32 mvBoardTclkGet(MV_VOID)
 {
-	MV_U32 value;
+	MV_U32 value, devId;
 
 	value = (MV_MEMIO_LE32_READ(INTER_REGS_BASE | DEVICE_SAMPLE_AT_RESET1_REG) >> 15) & 0x1;
 
 	switch (value) {
 	case (0x0):
-		return MV_BOARD_TCLK_250MHZ;
+		/* Read HW device ID from S@R:
+		 * note: avoiding reading device ID here with mvSysEnvDeviceIdGet(), since it include
+		 * prints, and TWSI reads, which require Tclk value--> reading Tclk value straight from register */
+		devId = MV_REG_READ(DEVICE_SAMPLE_AT_RESET1_REG);
+		devId = devId >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
+		if (devId == MV_6811)
+			return MV_BOARD_TCLK_166MHZ;	/* device 381/2 (6811/21) use 166MHz instead of 250MHz */
+		else
+			return MV_BOARD_TCLK_250MHZ;
 	case (0x1):
 		return MV_BOARD_TCLK_200MHZ;
 	default:
@@ -188,6 +410,7 @@
 {
 	MV_TWSI_ADDR slave;
 	MV_U32 tClock;
+
 	if (flagTwsiInit == -1) {
 		DEBUG_INIT_FULL_S("\n### mvHwsTwsiInitWrapper ###\n");
 		slave.type = ADDR7_BIT;
@@ -200,6 +423,12 @@
 
 		mvTwsiInit(0, TWSI_SPEED, tClock, &slave, 0);
 		flagTwsiInit = 1;
+
+		/* for AMC board, to allow detection of remote PCIe GEN1/GEN2 enforcement settings:
+		   1. Enable external i2c channel for via GPIO
+		   2. Disable I2C Slave Port0 of local AMC device, to avoid bus address contention */
+		if (mvBoardIdGet() == DB_AMC_6820_ID)
+			mvBoardDb6820AmcTwsiConfig();
 	}
 	return MV_OK;
 }
@@ -250,6 +479,34 @@
 }
 
 /*******************************************************************************
+* mvSysEnvCheckWakeupDramEnable
+*
+* DESCRIPTION: Check the magic wakeup enabled
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:
+*       MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED or MV_SUSPEND_WAKEUP_DISABLED
+*
+*******************************************************************************/
+MV_SUSPEND_WAKEUP_STATUS mvSysEnvCheckWakeupDramEnable(void)
+{
+	int *boot_info = (int*)(BOOT_INFO_ADDR);
+	int  magic_word;
+
+	magic_word =  *(boot_info);
+
+	if(magic_word == SUSPEND_MAGIC_WORD) {
+		return MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED;
+	}
+	else{
+		return MV_SUSPEND_WAKEUP_DISABLED;
+	}
+}
+
+/*******************************************************************************
 * mvCtrlDevIdIndexGet
 *
 * DESCRIPTION: return SOC device index
@@ -265,6 +522,7 @@
 MV_U32 mvSysEnvIdIndexGet(MV_U32 ctrlModel)
 {
 	switch (ctrlModel) {
+	/* HW flavors - represented by devid bits in S@R @ 0x18600 */
 	case MV_6820_DEV_ID:
 		return MV_6820_INDEX;
 	case MV_6810_DEV_ID:
@@ -277,6 +535,11 @@
 		return MV_6920_INDEX;
 	case MV_6928_DEV_ID:
 		return MV_6928_INDEX;
+	/* Virtual flavors - not represented by dev ID bits in S@R @ 0x18600 */
+	case MV_6W22_DEV_ID: /* 6W22=A383 */
+		return MV_6W22_INDEX;
+	case MV_6W23_DEV_ID: /* 6W23=A384 */
+		return MV_6W23_INDEX;
 	default:
 		return MV_6820_INDEX;
 	}
@@ -306,12 +569,16 @@
 	ctrlId = (ctrlId & (DEV_ID_REG_DEVICE_ID_MASK)) >> DEV_ID_REG_DEVICE_ID_OFFS;
 
 	switch (ctrlId) {
+	/* HW flavors - represented by devid bits in S@R @ 0x18600 */
 	case MV_6820_DEV_ID:
 	case MV_6810_DEV_ID:
 	case MV_6811_DEV_ID:
 	case MV_6828_DEV_ID:
 	case MV_6920_DEV_ID:
 	case MV_6928_DEV_ID:
+	/* Virtual flavors - not represented by dev ID bits in S@R @ 0x18600 */
+	case MV_6W22_DEV_ID: /* 6W22=A383 */
+	case MV_6W23_DEV_ID: /* 6W23=A384 */
 		return ctrlId;
 	default: /*Device ID Default for A38x: 6820 , for A39x: 6920 */
 	#ifdef MV88F68XX
@@ -323,26 +590,94 @@
 		return defaultCtrlId;
 	}
 }
+#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+/************************************************************************************
+* mvSysEnvIsFlavourReduced
+* DESCRIPTION:		Reduced Flavor A383/A384 is simulated on
+*			DB-GP/DB-381/2. configured by SatR field 'flavor'
+ ***************************************************************************/
+MV_16 isFlavorReduced = -1;
+static MV_16 mvSysEnvIsFlavourReduced(MV_VOID)
+{
+	MV_TWSI_SLAVE twsiSlave;
+	MV_U8 reducedVal;
 
+	if (isFlavorReduced != -1)
+		return isFlavorReduced; /* read last value if already read from EEPROM */
+
+	twsiSlave.slaveAddr.address = EEPROM_I2C_ADDR;
+	twsiSlave.slaveAddr.type = ADDR7_BIT;
+	twsiSlave.validOffset = MV_TRUE;
+	twsiSlave.moreThen256 = MV_TRUE;
+	twsiSlave.offset = 2;		/* SW EEPROM, register 2, bit 4 */
+
+	if (mvTwsiRead(0, &twsiSlave, &reducedVal, 1) != MV_OK) {
+		mvPrintf("%s: TWSI Read of 'flavor' failed\n", __func__);
+		return 0;
+	}
+	isFlavorReduced = !((reducedVal & SATR_DEVICE_FLAVOR_MASK) >> SATR_DEVICE_FLAVOR_OFFSET);
+
+
+	return isFlavorReduced;
+}
+#endif
 /************************************************************************************
 * mvSysEnvDeviceIdGet
-* DESCRIPTION:	 	Returns enum (0..7) index of the device model (ID)
+* DESCRIPTION:	Returns enum:
+*			(0..7) index of the device model (ID)
+*			(8..) index of the virtual device model (ID)
  ***************************************************************************/
 MV_U32 gDevId = -1;
 MV_U32 mvSysEnvDeviceIdGet(MV_VOID)
 {
-	char *deviceIdStr[7] = { "6810", "6820", "6811", "6828",
-				"NONE", "6920", "6928" };
+	char *deviceIdStr[10] = { "6810", "6820", "6811", "6828",
+				"NONE", "6920", "6928", "MAX_HW_DEV_ID",
+				"6W22", "6W23"}; /* 6W22=A383, 6W23=A384 */
+#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+	MV_U32 boardId = mvBoardIdGet();
+#endif
 
 	if (gDevId != -1)
 		return gDevId;
 
+	/* read HW device ID value */
 	gDevId = MV_REG_READ(DEVICE_SAMPLE_AT_RESET1_REG);
 	gDevId = gDevId >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
+	/* Virtual Reduced flavor Device IDs :
+		- Hardware Device ID's represented by index 0..7
+		- Virtual Device ID's represented by index 8..
+		- Customer boards: reduced flavor ID defined by REDUCED_FLAVOR value.
+		- Marvell boards: Reduced Flavor A383/A384 is simulated on DB-GP/DB-381/2
+		  only (configured by SatR field 'flavor').
+	 */
+#if defined(CONFIG_CUSTOMER_BOARD_SUPPORT)
+#ifdef REDUCED_FLAVOR
+	if (REDUCED_FLAVOR == 0x383)
+		gDevId = MV_6W22;
+	else if (REDUCED_FLAVOR == 0x384)
+		gDevId = MV_6W23;
+#endif
+#else
+	if (mvSysEnvIsFlavourReduced() == 1) {
+		if (boardId == DB_GP_68XX_ID || boardId == DB_68XX_ID
+				|| boardId == DB_AP_68XX_ID) {
+			if (gDevId != MV_6810) /* simulate 6W23(A384) only on 6820(A385) or 6828(A388) */
+				gDevId = MV_6W23;
+			else {
+				mvPrintf("%s: Error: A384 (6W23) can not run with device ", __func__);
+				mvPrintf("id A380 (6810)\nto set A384,run 'SatR ");
+				mvPrintf("write devid 3' OR 'SatR write devid 1'\n");
+			}
+		}
+		else if (boardId == DB_BP_6821_ID)
+			gDevId = MV_6W22;
+	}
+#endif
 	mvPrintf("Detected Device ID %s\n" ,deviceIdStr[gDevId]);
 	return gDevId;
 }
 
+
 /*******************************************************************************
 * mvSysEnvDeviceRevGet - Get Marvell controller device revision number
 *
@@ -382,17 +717,9 @@
 *******************************************************************************/
 MV_DRAM_DLB_CONFIG  *mvSysEnvDlbConfigPtrGet(MV_VOID)
 {
-#ifdef MV88F69XX
-	return (&ddr3DlbConfigTable_A0[0]);
-#else
-	if (mvSysEnvDeviceRevGet() == MV_88F68XX_A0_ID)
-		return (&ddr3DlbConfigTable_A0[0]);
-	else
-		return (&ddr3DlbConfigTable[0]);
-#endif
+	return (&ddr3DlbConfigTable[0]);
 }
 
-
 #ifdef CONFIG_CMD_BOARDCFG
 MV_BOARD_CONFIG_TYPE_INFO boardConfigTypesInfo[] = MV_EEPROM_CONFIG_INFO;
 MV_U8 boardOptionsConfig[MV_CONFIG_TYPE_MAX_OPTION];
@@ -831,7 +1158,7 @@
 {
 	MV_BOARD_CONFIG_TYPE_INFO configInfo;
 
-	if (configField < MV_CONFIG_TYPE_MAX_OPTION &&
+	if (configField >=MV_CONFIG_TYPE_MAX_OPTION ||
 		mvSysEnvConfigTypeGet(configField, &configInfo) != MV_TRUE) {
 		DEBUG_INIT_S("mvSysEnvConfigGet: Error: Requested board config is invalid for this board\n");
 		return MV_ERROR;
@@ -1012,3 +1339,11 @@
 {
 	return MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & REG_DDR3_RANK_CTRL_CS_ENA_MASK;
 }
+
+/* mvSysEnvTimerIsRefClk25Mhz:
+ * A38x/A39x support 25Mhz as ref.clock for timer
+ */
+MV_BOOL mvSysEnvTimerIsRefClk25Mhz(void)
+{
+	return MV_TRUE;
+}
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
index 77982d5..5829e32 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
+++ b/tools/marvell/bin_hdr/platform/sysEnv/a38x/mvSysEnvLib.h
@@ -86,15 +86,25 @@
 #define DEVICE_SAMPLE_AT_RESET2_REG             0x18604
 #define DEV_ID_REG                              0x18238
 
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET	0
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ	0
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_40MHZ	1
+
 #define CORE_PLL_PARAMETERS_REG                 0xE42E0
 #define CORE_PLL_CONFIG_REG                     0xE42E4
 
 #define QSGMII_CONTROL_REG1                     0x18494
 
+#define USB3_CONFIG_REG				0x18420
+
+#define DBG_PORT_CONFIG_REG			0x186c0
+#define DBG_PORT_CONFIG2_REG			0x186c4
+
 #define DEV_ID_REG_DEVICE_ID_OFFS               16
 #define DEV_ID_REG_DEVICE_ID_MASK               0xFFFF0000
 
-
+#define SAR_FREQ_OFFSET 						10
+#define SAR_FREQ_MASK  							0x1F
 #define SAR_DEV_ID_OFFS                         27
 #define SAR_DEV_ID_MASK                         0x7
 
@@ -110,6 +120,7 @@
 #define MISC_REG                                0xa013C
 #define GLUE_REG                                0xa0140
 #define GENERATION_DIVIDER_FORCE_REG            0xa0144
+#define PLLINTP_REG1                            0xa0150
 #define PCIE_REG0                               0xa0120
 #define LANE_ALIGN_REG0                         0xa0124
 #define SQUELCH_FFE_SETTING_REG                 0xa0018
@@ -133,10 +144,12 @@
 #define RX_REG3                                 0xa0188
 #define PCIE_REG1                               0xa0288
 #define PCIE_REG3                               0xa0290
+#define LANE_CFG0_REG                           0xa0600
 #define LANE_CFG1_REG                           0xa0604
 #define LANE_CFG4_REG                           0xa0620
 #define LANE_CFG5_REG                           0xa0624
 #define GLOBAL_CLK_CTRL                         0xa0704
+#define GLOBAL_TEST_CTRL                        0xa0708
 #define GLOBAL_MISC_CTRL                        0xa0718
 #define GLOBAL_CLK_SRC_HI                       0xa0710
 
@@ -174,7 +187,6 @@
 #define REF_CLK_SELECTOR_VAL(regVal)            (regVal & 0x1)
 
 #define MAX_SELECTOR_VAL                        10
-
 /* TWSI addresses */
 /* starting from A38x A0, i2c address of EEPROM is 0x57 */
 #ifdef MV88F69XX
@@ -187,6 +199,9 @@
 #define DB_GET_MODE_SLM1364_ADDR                0x24
 #define DB381_GET_MODE_SLM1426_1427_ADDR	0x56
 
+#define SATR_DEVICE_FLAVOR_MASK			0x10 /* DB-GP & DB-381/2 boards : SatR field 'flavor'*/
+#define SATR_DEVICE_FLAVOR_OFFSET		4
+
 /* DB-BP Board 'SatR' mapping */
 #define SATR_DB_LANE1_MAX_OPTIONS		7
 #define SATR_DB_LANE1_CFG_MASK			0x7
@@ -213,14 +228,68 @@
 #define AVS_DEBUG_CNTR_REG              0xE4124
 #define AVS_DEBUG_CNTR_DEFAULT_VALUE    0x08008073
 
+#ifdef CONFIG_ARMADA_38X
+	#define AVS_LIMIT_VAL_SLOW		0x23	/*1.15V*/
+	#define EFUSE_WIN_CTRL_VAL		((0xF << 16) | (0x0A << 8) | (0xE << 4) | 0x1)
+	#define EFUSE_WIN_BASE_VAL		0xB0000000
+	#define MV_EFUSE_REG_READ(offset)	\
+		MV_MEMIO_LE32_READ(EFUSE_WIN_BASE_VAL | (offset))
+	#define EFUSE_WIN_ID				5
+
+	#define EFUSE_REG_BASE			0xF8F00
+	#define EFUSE_AVS_AND_BIN_REG		(EFUSE_REG_BASE + 0xC)
+	#define EFUSE_AVS_VAL_BASE		6
+	#define EFUSE_AVS_VAL_OFFSET		8
+	#define EFUSE_AVS_VAL_MASK		0xFF
+	#define EFUSE_AVS_VERSION_REG		(EFUSE_REG_BASE + 0x8)
+	#define EFUSE_AVS_VERSION_OFFSET	24
+	#define EFUSE_AVS_VERSION_MASK		0xF
+	#define EFUSE_AVS_BIN_OFFSET		4
+	#define EFUSE_AVS_BIN_MASK		0x3
+	#define MV_AVS_DEFAULT_VALUE		0x27	/* 1.25V */
+	typedef struct boardAvsFromEfuseMap {
+		MV_32 cpu_freq_mode;
+		MV_32 cpu_freq;
+		MV_32 avs_bin_value;
+	} MV_BOARD_AVS_EFUSE_MAP;
+	/* predefined values for FUNCTION_ENABLE_CONTROL per flavour */
+	#define EFUSE_FREQ_VAL_SIZE		3
+	#define EFUSE_AVS_VAL_OFFSET_AT_IND(index) (EFUSE_AVS_VAL_BASE + \
+						   (EFUSE_FREQ_VAL_SIZE - (index+1))*EFUSE_AVS_VAL_OFFSET)
+	#define EFUSE_FREQ_VAL_INFO {\
+	/*		CPU frequency mode,	CPU Frequecny,	AVS_BIN_VALUE */\
+	/* 1600MHz */	{0xC,			1600,		0x3},\
+	/* 1866MHZ */	{0x10,			1866,		0x2},\
+	/* 2000MHZ */	{0x13,			2000,		0x1},\
+	};
+#else
+	#define AVS_LIMIT_VAL			0x27
+#endif
+/* DFX Server general registers mapping (on top of internal registers) */
+#define DFX_REG_BASE				0xE4000
+#define DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS	0
+/* DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS:
+ * Since address completion in 14bit address mode, and given that [14:8] => [19:13],
+ * the 2 lower bits [9:8] => [14:13] are dismissed. hence field offset is also shifted to 10 */
+#define DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS	10
+#define DFX_PIPE_SELECT_VAL	        	(0x1 << DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS \
+							| 0x1 << DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS)
+
+#define RTC_MEMORY_CTRL_REG_BASE		0xE6000
+#define RTC_MEMORY_WRAPPER_COUNT		8
+#define RTC_MEMORY_WRAPPER_REG(i)		(RTC_MEMORY_CTRL_REG_BASE + (i * 0x40))
+#define RTC_MEMORY_CTRL_RTC_FIELD_OFFS		3
+#define RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS	6
+#define RTC_MEMORY_WRAPPER_CTRL_VAL	        (0x1 << RTC_MEMORY_CTRL_RTC_FIELD_OFFS \
+							| 0x1 << RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS)
+
 #define AVS_ENABLED_CONTROL             0xE4130
 #define AVS_LOW_VDD_LIMIT_OFFS          4
 #define AVS_LOW_VDD_LIMIT_MASK          (0xff << AVS_LOW_VDD_LIMIT_OFFS)
-#define AVS_LOW_VDD_LIMIT_VAL           (0x27 << AVS_LOW_VDD_LIMIT_OFFS)
 
 #define AVS_HIGH_VDD_LIMIT_OFFS         12
 #define AVS_HIGH_VDD_LIMIT_MASK         (0xff << AVS_HIGH_VDD_LIMIT_OFFS)
-#define AVS_HIGH_VDD_LIMIT_VAL          (0x27 << AVS_HIGH_VDD_LIMIT_OFFS)
+
 
 /* Board ID numbers */
 #define MARVELL_BOARD_ID_MASK			0x10
@@ -228,8 +297,9 @@
 #define A38X_CUSTOMER_BOARD_ID_BASE		0x0
 #define A38X_CUSTOMER_BOARD_ID0			(A38X_CUSTOMER_BOARD_ID_BASE + 0)
 #define A38X_CUSTOMER_BOARD_ID1			(A38X_CUSTOMER_BOARD_ID_BASE + 1)
-#define A38X_GFCH100_ID				(A38X_CUSTOMER_BOARD_ID_BASE + 2)
-#define A38X_MV_MAX_CUSTOMER_BOARD_ID		(A38X_CUSTOMER_BOARD_ID_BASE + 3)
+#define A38X_CLEARFOG_BOARD_ID			(A38X_CUSTOMER_BOARD_ID_BASE + 2)
+#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*/
@@ -299,6 +369,7 @@
 #define MPP_CONTROL_REG(id)                     (0x18000 + (id * 4))
 #define GPP_DATA_OUT_REG(grp)			(MV_GPP_REGS_BASE(grp) + 0x00)
 #define GPP_DATA_OUT_EN_REG(grp)		(MV_GPP_REGS_BASE(grp) + 0x04)
+#define GPP_DATA_IN_POL_REG(grp)		(MV_GPP_REGS_BASE(grp) + 0x0C)
 #define GPP_DATA_IN_REG(grp)			(MV_GPP_REGS_BASE(grp) + 0x10)
 #define MV_GPP_REGS_BASE(unit) 			(0x18100 + ((unit) * 0x40))
 
@@ -313,31 +384,38 @@
 #define MV_6811_DEV_ID		0x6811
 #define MV_6820_DEV_ID		0x6820
 #define MV_6828_DEV_ID		0x6828
+#define MV_6W22_DEV_ID		0x6823 /* 6W22 - A383: using device ID value 0f 0x6823 */
+#define MV_6W23_DEV_ID		0x6824 /* 6W23 - A384: using device ID value 0f 0x6824 */
 /* Armada 39x Family */
 #define MV_6920_DEV_ID		0x6920
 #define MV_6928_DEV_ID		0x6928
 
 typedef enum _mvDeviceId {
-	MV_6810,
-	MV_6820,
-	MV_6811,
-	MV_6828,
-	MV_NONE,
-	MV_6920,
-	MV_6928,
-	MV_MAX_DEV_ID,
+/* 0 */	MV_6810,
+/* 1 */	MV_6820,
+/* 2 */	MV_6811,
+/* 3 */	MV_6828,
+/* 4 */	MV_NONE,
+/* 5 */	MV_6920,
+/* 6 */	MV_6928,
+/* 7 */	MV_MAX_HW_DEV_ID,	/* Dummy entry to indicate end of HW device ID's */
+/* 8 */	MV_6W22,		/* A383: Virtual Device ID - not represented by dev id in S@R @ 0x18600 */
+/* 9 */	MV_6W23,		/* A384: Virtual Device ID - not represented by dev id in S@R @ 0x18600 */
+/* 10*/	MV_MAX_DEV_ID,
 } MV_DEVICE_ID;
 
 #define MV_6820_INDEX                         0
 #define MV_6810_INDEX                         1
 #define MV_6811_INDEX                         2
 #define MV_6828_INDEX                         3
+#define MV_6W22_INDEX			      4 /* 6W22=A383 */
+#define MV_6W23_INDEX			      5 /* 6W23=A384 */
 
 #define MV_6920_INDEX                         0
 #define MV_6928_INDEX                         1
 
 #ifdef CONFIG_ARMADA_38X
-#define MAX_DEV_ID_NUM                        4
+#define MAX_DEV_ID_NUM                        6
 #else
 #define MAX_DEV_ID_NUM                        2
 #endif
@@ -350,12 +428,12 @@
 #define MV_6928_INDEX                         1
 
 typedef enum _mvUnitId {
-            PEX_UNIT_ID ,
-            ETH_GIG_UNIT_ID,
+			PEX_UNIT_ID ,
+			SGMII_UNIT_ID,
 			USB3H_UNIT_ID,
 			USB3D_UNIT_ID,
 			SATA_UNIT_ID,
-            QSGMII_UNIT_ID,
+			QSGMII_UNIT_ID,
 			XAUI_UNIT_ID,
 			RXAUI_UNIT_ID,
 			MAX_UNITS_ID
@@ -374,11 +452,14 @@
 /* 		dev,	ctrlModel,		WO_VAL0,	WO_VAL1 */\
 /* A380 */ {MV_6810,	MV_6810_DEV_ID,		0x71fd7f3,	0x00 },\
 /* A381 */ {MV_6820,	MV_6820_DEV_ID,		0x77fdfff,	0x00 },\
-/* A385 */ {MV_6811,	MV_6811_DEV_ID,		0x77fffff,	0x00 },\
+/* A385 */ {MV_6811,	MV_6811_DEV_ID,		0x77fdfff,	0x00 },\
 /* A388 */ {MV_6828,	MV_6828_DEV_ID,		0x77fffff,	0x00 },\
 /* NONE */ {MV_NONE,	0x0,			0x0,		0x0  },\
-/* A395 */ {MV_6920,	MV_6920_DEV_ID,		0x17fcff7,	0x00 },\
-/* A398 */ {MV_6928,	MV_6928_DEV_ID,		0x77ffff3,	0x00 },\
+/* A395 */ {MV_6920,	MV_6920_DEV_ID,		0x17fcfff,	0x00 },\
+/* A398 */ {MV_6928,	MV_6928_DEV_ID,		0x77fffff,	0x00 },\
+/*MAX_HW_DEV_ID*/ {MV_MAX_HW_DEV_ID,	0x0,			0x0,		0x0  },\
+/* A383 */ {MV_6W22,	MV_6W22_DEV_ID,		0x77fffff,	0x00 },\
+/* A384 */ {MV_6W23,	MV_6W23_DEV_ID,		0x77fffff,	0x00 },\
 };
 
 typedef struct boardWakeupGPIO {
@@ -386,12 +467,23 @@
 	MV_32 gpioNum;
 } MV_BOARD_WAKEUP_GPIO;
 
+
+typedef struct boardUsbVbusGPIO {
+	MV_U32 boardId;
+	MV_32 usbVbusGpio[2];
+} MV_BOARD_USB_VBUS_GPIO;
+
 typedef enum _mvSuspendWakeupStatus {
 	MV_SUSPEND_WAKEUP_DISABLED,
 	MV_SUSPEND_WAKEUP_ENABLED,
 	MV_SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED,
+	MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED,
 } MV_SUSPEND_WAKEUP_STATUS;
 
+#define BOOT_INFO_ADDR				(0x3000)
+#define SUSPEND_MAGIC_WORD			(0xDEADB002)
+#define REGISTER_LIST_END			(0xFFFFFFFF)
+
 
 /* GPIO status indication for Suspend Wakeup:
  * if suspend to RAM is supported and GPIO inidcation is implemented, set the gpio number
@@ -403,13 +495,26 @@
 #define MV_BOARD_WAKEUP_GPIO_INFO {\
 {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 {\
 {A39X_CUSTOMER_BOARD_ID0,	-1 },\
 {A39X_CUSTOMER_BOARD_ID0,	-1 },\
 };
+
+#define MV_BOARD_USB_VBUS_GPIO_INFO {\
+{A39X_CUSTOMER_BOARD_ID0, {-1, -1} },\
+{A39X_CUSTOMER_BOARD_ID0, {-1, -1} },\
+};
 #endif /* MV88F68XX */
 
 #else
@@ -424,11 +529,26 @@
 {DB_BP_6821_ID,	 -2 },\
 {DB_AMC_6820_ID, -2 },\
 };
+
+#define MV_BOARD_USB_VBUS_GPIO_INFO {\
+{RD_NAS_68XX_ID, {-1, -1} },\
+{DB_68XX_ID,	 {-1, -1} },\
+{RD_AP_68XX_ID,	 {-1, -1} },\
+{DB_AP_68XX_ID,	 {44, -1} },\
+{DB_GP_68XX_ID,	 {-1, -1} },\
+{DB_BP_6821_ID,	 {-1, -1} },\
+{DB_AMC_6820_ID, {-1, -1} },\
+};
 #else
 #define MV_BOARD_WAKEUP_GPIO_INFO {\
 {A39X_RD_69XX_ID, -1 },\
 {A39X_DB_69XX_ID, -1 },\
 };
+
+#define MV_BOARD_USB_VBUS_GPIO_INFO {\
+{A39X_RD_69XX_ID, {-1, -1} },\
+{A39X_DB_69XX_ID, {-1, -1} },\
+};
 #endif /* MV88F68XX */
 #endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
 extern MV_DRAM_DLB_CONFIG ddr3DlbConfigTable[];
@@ -550,12 +670,19 @@
 * mvSysEnvDlbConfigPtrGet
 * DESCRIPTION: defines pointer to to DLB COnfiguration table
 * INPUT: none
-* OUTPUT: 
+* OUTPUT:
 * RETURN:
 *       returns pointer to DLB COnfiguration table
 *******************************************************************************/
 MV_DRAM_DLB_CONFIG  *mvSysEnvDlbConfigPtrGet(MV_VOID);
 
+#define MV_BOARD_BIOS0_ADDR				0x4C
+#define MV_BOARD_IO_EXPANDER1_ADDR			0x21
+#define TWSI_CHANNEL_A3XX				0
+#define MV_BOARD_CTRL_I2C_ADDR_BC2		0x0
+/* WA for bits 1,2 in 0x4c. Must be lower than 100000 -> 20000 */
+#define TWSI_SPEED_BC2					20000
+
 #ifdef CONFIG_CMD_BOARDCFG
 
 #define MV_BOARD_CONFIG_MAX_BYTE_COUNT		8
@@ -648,6 +775,20 @@
 #endif /* CONFIG_CMD_BOARDCFG */
 
 /*******************************************************************************
+* mvBoardForcePcieGen1Get - read BC2 SatR bios0 bit[4] for PCIe GEN1/GEN2 mode
+*
+* DESCRIPTION:
+*
+* INPUT:
+*
+* OUTPUT:
+*       None.
+*
+* RETURN: TRUE if connected to BC2
+*******************************************************************************/
+MV_BOOL mvBoardForcePcieGen1Get(MV_VOID);
+
+/*******************************************************************************
 * mvSysEnvGetTopologyUpdateInfo
 *
 * DESCRIPTION: Read TWSI fields to update DDR topology structure
@@ -676,5 +817,38 @@
 *
 *******************************************************************************/
 MV_U32 mvSysEnvGetCSEnaFromReg(void);
+
+/*******************************************************************************
+* mvSysEnvCheckWakeupDramEnable
+*
+* DESCRIPTION: Check the magic wakeup enabled
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:
+*       MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED or MV_SUSPEND_WAKEUP_DISABLED
+*
+*******************************************************************************/
+MV_SUSPEND_WAKEUP_STATUS mvSysEnvCheckWakeupDramEnable(void);
+/**************************************************************************
+ * mvSysEnvTimerIsRefClk25Mhz -
+ *
+ * DESCRIPTION:          Routine to indicate if 25Mhz ref clock for timer is supported
+ * INPUT:                None.
+ * OUTPUT:               None.
+ * RETURNS:              None.
+ ***************************************************************************/
+MV_STATUS mvSysEnvTimerIsRefClk25Mhz(MV_VOID);
+/**************************************************************************
+ * mvBoardUsbVbusReset -
+ *
+ * DESCRIPTION:          Routine to reset USB VBUS (via GPIO or I2C IO expander)
+ * INPUT:                None.
+ * OUTPUT:               None.
+ * RETURNS:              None.
+ ***************************************************************************/
+MV_VOID mvSysEnvUsbVbusReset(MV_VOID);
 #endif /* __INCmvSysEnvLibh */
 
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.c
index 5ab1c90..4b698eb 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.c
@@ -370,3 +370,11 @@
 /* Marvell Boards use 0x10 as base for Board ID: mask MSB to receive index for board ID*/
 	return boardId & (MARVELL_BOARD_ID_BASE - 1);
 }
+
+/* mvSysEnvTimerIsRefClk25Mhz:
+ * ALP support 25Mhz as ref.clock for timer
+ */
+MV_BOOL mvSysEnvTimerIsRefClk25Mhz(void)
+{
+	return MV_TRUE;
+}
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.h b/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.h
index 0bd00d7..ea1e702 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.h
+++ b/tools/marvell/bin_hdr/platform/sysEnv/alp/mvSysEnvLib.h
@@ -298,5 +298,7 @@
 MV_U32 mvCpuL2ClkGet(MV_VOID);
 MV_U32 mvBoardFreqModesNumGet(MV_VOID);
 MV_U32 mvBoardIdIndexGet(MV_U32 boardId);
+MV_STATUS mvSysEnvTimerIsRefClk25Mhz(MV_VOID);
 
 #endif /* __INCmvBHboardEnvSpech */
+
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/axp/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/axp/mvSysEnvLib.c
index 89d4cdc..28e7246 100644
--- a/tools/marvell/bin_hdr/platform/sysEnv/axp/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/axp/mvSysEnvLib.c
Binary files differ
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.c b/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.c
index 00b2862..0534261 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.c
+++ b/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.c
@@ -87,41 +87,40 @@
 	if (gBoardId != -1)
 		return gBoardId;
 
-/* Customer board ID's */
 #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
-	#ifdef CONFIG_BOBCAT2
-	#ifdef CONFIG_CUSTOMER_BOARD_0
-			gBoardId = BC2_CUSTOMER_BOARD_ID0;
-		#elif CONFIG_CUSTOMER_BOARD_1
-			gBoardId = BC2_CUSTOMER_BOARD_ID1;
-		#endif
-	#elif defined CONFIG_ALLEYCAT3
+
+	#if defined CONFIG_ALLEYCAT3
 		#ifdef CONFIG_CUSTOMER_BOARD_0
 			gBoardId = AC3_CUSTOMER_BOARD_ID0;
 		#elif CONFIG_CUSTOMER_BOARD_1
 			gBoardId = AC3_CUSTOMER_BOARD_ID1;
 		#endif
+	#else /* BC2 */
+		#ifdef CONFIG_CUSTOMER_BOARD_0
+			gBoardId = BC2_CUSTOMER_BOARD_ID0;
+		#elif CONFIG_CUSTOMER_BOARD_1
+			gBoardId = BC2_CUSTOMER_BOARD_ID1;
+		#endif
 	#endif
-#else
-/* BobCat2 Board ID's */
-	#if defined(DB_BOBCAT2)
-		gBoardId = DB_DX_BC2_ID;
-	#elif defined(RD_BOBCAT2)
-		gBoardId = RD_DX_BC2_ID;
-	#elif defined(RD_MTL_BOBCAT2)
-		gBoardId = RD_MTL_BC2;
-	#else
-		MV_U8 readValue = 0;
-		/* AlleyCat3 Board ID's */
-		if (mvBoardSarBoardIdGet(&readValue) != MV_OK || readValue >= AC3_MARVELL_BOARD_NUM) {
-			mvPrintf("%s: Error obtaining Board ID from EEPROM (%d)\n", __func__, readValue);
-			mvPrintf("%s: Setting default board: DB-DXAC3-MM\n", __func__);
-			readValue = DB_AC3_ID - AC3_MARVELL_BOARD_ID_BASE;
-		}
 
-		gBoardId = AC3_MARVELL_BOARD_ID_BASE + readValue;
-	#endif
-#endif
+#else	/* !CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+	MV_U8 readValue;
+
+	if (mvBoardSarBoardIdGet(&readValue) != MV_OK) {
+		mvPrintf("%s: Error obtaining Board ID from EEPROM (%d)\n", __func__, readValue);
+		mvPrintf("%s: Setting default board to: %d\n", __func__, MV_DEFAULT_BOARD_ID);
+		readValue = MV_DEFAULT_BOARD_ID;
+	}
+	readValue = readValue & (BOARD_ID_INDEX_MASK - 1);
+
+	if (readValue >= MV_MARVELL_BOARD_NUM) {
+		mvPrintf("%s: Error: read wrong board ID (%d)\n", __func__, readValue);
+		return INVALID_BOARD_ID;
+	}
+	gBoardId = MARVELL_BOARD_ID_BASE + readValue;
+
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
 
 	return gBoardId;
 }
@@ -155,6 +154,22 @@
 	return MV_BOARD_TCLK_200MHZ;
 }
 
+/* Use flagTwsiInit global flag to init the Twsi once */
+static int flagTwsiInit = -1;
+MV_STATUS mvHwsTwsiInitWrapper(MV_VOID)
+{
+	MV_TWSI_ADDR slave;
+
+	if (flagTwsiInit == -1) {
+		slave.type = ADDR7_BIT;
+		slave.address = 0;
+		mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
+		flagTwsiInit = 1;
+
+	}
+	return MV_OK;
+}
+
 /*******************************************************************************/
 /* The Board Id is taken from the first address-value pair of the EEPROM initialization sequence
  * In order to support normal TWSI init sequence flow, the first pair of DWORDS on EEPROM
@@ -231,6 +246,25 @@
 	/* TBD */
 	return MV_SUSPEND_WAKEUP_DISABLED;
 }
+
+/*******************************************************************************
+* mvSysEnvCheckWakeupDramEnable
+*
+* DESCRIPTION: Check the magic wakeup enabled
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:
+*       MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED or MV_SUSPEND_WAKEUP_DISABLED
+*
+*******************************************************************************/
+MV_SUSPEND_WAKEUP_STATUS mvSysEnvCheckWakeupDramEnable(void)
+{
+	return MV_SUSPEND_WAKEUP_DISABLED;
+}
+
 /*******************************************************************************
 * mvSysEnvDlbConfigPtrGet
 * DESCRIPTION: defines pointer to to DLB COnfiguration table
@@ -263,16 +297,24 @@
 	MV_U8	configVal;
 	MV_TWSI_SLAVE twsiSlave;
 
-	/*Fix the topology for A380 by SatR values*/
+	/* on AC3, DDR configuration (i.e ECC) supported only for DB board */
+#if defined CONFIG_ALLEYCAT3
+	if (mvBoardIdGet() != DB_AC3_ID)
+		return 0;
+#endif
+
+	/*Fix the topology for msys by SatR values*/
 	twsiSlave.slaveAddr.address = 0x4D;
 	twsiSlave.slaveAddr.type = ADDR7_BIT;
 	twsiSlave.validOffset = MV_TRUE;
 	twsiSlave.offset = 0;
 	twsiSlave.moreThen256 = MV_TRUE;
 
-	/* Reading board id */
+	/* Reading update DDR ECC Enable from device
+	 * address: 0x4D, register: 0 bits[0:1]
+	 */
 	if (mvTwsiRead(0, &twsiSlave, &configVal, 1) != MV_OK) {
-		DEBUG_INIT_S("mvHwsBoardIdGet: TWSI Read failed\n");
+		mvPrintf("%s: Twsi failed to read enable DDR ECC update\n", __func__);
 		return 0;
 	}
 
@@ -313,4 +355,10 @@
 	return 1;
 #endif
 }
-
+/* mvSysEnvTimerIsRefClk25Mhz:
+ * MSYS Bobcat2 and AlleyCat3 doesn't support 25Mhz as ref.clock for timer
+ */
+MV_BOOL mvSysEnvTimerIsRefClk25Mhz(void)
+{
+	return MV_FALSE;
+}
diff --git a/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.h b/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.h
index 7df8c08..a7a1867 100755
--- a/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.h
+++ b/tools/marvell/bin_hdr/platform/sysEnv/msys/mvSysEnvLib.h
@@ -104,6 +104,18 @@
 #define INVALID_BOARD_ID			0xFFFF
 #define BOARD_ID_INDEX_MASK			0x10	/* Mask used to return board index via board Id */
 
+#if defined CONFIG_ALLEYCAT3
+	#define MARVELL_BOARD_ID_BASE		AC3_MARVELL_BOARD_ID_BASE
+	#define MV_MAX_MARVELL_BOARD_ID		AC3_MARVELL_MAX_BOARD_ID
+	#define MV_MARVELL_BOARD_NUM		AC3_MARVELL_BOARD_NUM
+	#define MV_DEFAULT_BOARD_ID			DB_AC3_ID
+#else
+	#define MARVELL_BOARD_ID_BASE		BC2_MARVELL_BOARD_ID_BASE
+	#define MV_MAX_MARVELL_BOARD_ID		BC2_MARVELL_MAX_BOARD_ID
+	#define MV_MARVELL_BOARD_NUM		BC2_MARVELL_BOARD_NUM
+	#define MV_DEFAULT_BOARD_ID			DB_DX_BC2_ID
+#endif
+
 
 /* Bobcat2 device revision */
 #define BC2_DEV_VERSION_ID_REG		           0xF8240	/* under server space */
@@ -121,6 +133,7 @@
 	MV_SUSPEND_WAKEUP_DISABLED,
 	MV_SUSPEND_WAKEUP_ENABLED,
 	MV_SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED,
+	MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED,
 } MV_SUSPEND_WAKEUP_STATUS;
 
 /*************************** Globals ***************************/
@@ -270,5 +283,38 @@
 *
 *******************************************************************************/
 MV_U32 mvSysEnvGetCSEnaFromReg(void);
+
+/*******************************************************************************
+* mvSysEnvCheckWakeupDramEnable
+*
+* DESCRIPTION: Check the magic wakeup enabled
+*
+* INPUT: None
+*
+* OUTPUT: None
+*
+* RETURN:
+*       MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED or MV_SUSPEND_WAKEUP_DISABLED
+*
+*******************************************************************************/
+MV_SUSPEND_WAKEUP_STATUS mvSysEnvCheckWakeupDramEnable(void);
+/**************************************************************************
+ * mvSysEnvTimerIsRefClk25Mhz -
+ *
+ * DESCRIPTION:          Routine to indicate if 25Mhz ref clock for timer is supported
+ * INPUT:                None.
+ * OUTPUT:               None.
+ * RETURNS:              None.
+ ***************************************************************************/
+MV_STATUS mvSysEnvTimerIsRefClk25Mhz(MV_VOID);
+/**************************************************************************
+ * mvHwsTwsiInitWrapper -
+ *
+ * DESCRIPTION:          Wrapper for initializing the TWSI unit
+ * INPUT:                None.
+ * OUTPUT:               None.
+ * RETURNS:              None.
+ ***************************************************************************/
+MV_STATUS mvHwsTwsiInitWrapper(MV_VOID);
 #endif /* __INCmvBHboardEnvSpech */
 
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/command.c b/tools/marvell/bin_hdr/platform/utils/debug/command.c
new file mode 100644
index 0000000..bf13f4a
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/command.c
@@ -0,0 +1,431 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+*******************************************************************************/
+/* includes */
+
+#include "command.h"
+#include "mvUart.h"
+#include "lib_utils.h"
+#include "printf.h"
+
+int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int ir_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int training_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_xorMemTest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/* Commands Table
+ * Every new command is added here, Thus it must be declared in
+ * this file, or include the file declaring it
+ * For example, To add new command that is implemented in 'hello_world' function
+ * this line is added to the declaration:
+ *	{ "hello", 2, hello_world, "prints hello world", ""}
+ */
+cmd_tbl_t commands[] = {
+	{ "?", 2, do_help, "prints help message of command", "command-name"},
+	{ "md", 3, do_mem_md, "memory display", "[.b, .w, .l] address [# of objects]"},
+	{ "mw",	4, do_mem_mw, "memory write (fill)", "[.b, .w, .l] address value [count]"},
+	{ "mm",	2, do_mem_mm, "memory modify (auto-incrementing address)", "[.b, .w, .l] address"},
+	{ "cmp", 4, do_mem_cmp, "memory compare", "[.b, .w, .l] addr1 addr2 count"},
+	{ "cp", 4, do_mem_cp, "memory copy", "[.b, .w, .l] source target count"},
+	{ "ir", 2, ir_cmd, "ir	- reading and changing MV internal register values.\n", "address"},
+	{ "training", 1, training_cmd, "training	- prints the results of the DDR3 Training.\n"},
+	{ "mtest", 5, do_mem_mtest, "simple RAM read/write test", "[start [end [pattern [iterations]]]]"},
+	{ "xormtest", 4, do_xorMemTest, "run memory test based on XOR engine",
+		"[source [destination [size(bytes) [iterations]]]]"}
+};
+
+/* local functions definitions */
+cmd_tbl_t *find_cmd(const char *cmd);
+void cmd_usage(const cmd_tbl_t *cmdtp);
+
+/*******************************************************************************
+* do_help
+*
+* DESCRIPTION:
+* Command that prints the help message of commands
+*
+*******************************************************************************/
+int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *cmd;
+
+	if (argc <= 1)
+		return 0;
+
+	cmd = find_cmd(argv[1]);
+	if (cmd == NULL) {
+		mvPrintf("Command not found");
+		return 0;
+	}
+
+	cmd_usage(cmd);
+	return 0;
+}
+
+int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int ir_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int training_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/*******************************************************************************
+* cmd_get_data_size
+*
+* DESCRIPTION:
+* Check for a size specification .b, .w or .l.
+*
+* INPUT:
+*	arg		- command (e.g. "mw.l")
+*	default_size	- default size to return if no size was specified
+*
+* RETURN:
+*	if size was specified, return corresponding size
+*		(.b = 1, .w = 2, .l = 4)
+*	otherwise, return default_size
+*
+*******************************************************************************/
+int cmd_get_data_size(char *arg, int default_size)
+{
+	int len = strlen(arg);
+	if (len > 2 && arg[len-2] == '.') {
+		switch (arg[len-1]) {
+		case 'b':
+			return 1;
+		case 'w':
+			return 2;
+		case 'l':
+			return 4;
+		case 's':
+			return -2;
+		default:
+			return -1;
+		}
+	}
+	return default_size;
+}
+
+/*******************************************************************************
+* find_cmd_tbl
+*
+* DESCRIPTION:
+* search for command in command table
+*
+* INPUT:
+*	cmd		- command (e.g. "ir")
+*	table		- commands table
+*	table_len	- commands table length
+*
+* RETURN:
+*	if command was found, cmd_tbl_t entry corresponding the command
+*	otherwise, NULL
+*
+*******************************************************************************/
+cmd_tbl_t *find_cmd_tbl(const char *cmd, cmd_tbl_t *table, int table_len)
+{
+	cmd_tbl_t *cmdtp;
+	cmd_tbl_t *cmdtp_temp = table;	/*Init value */
+	const char *p;
+	int len;
+	int n_found = 0;
+
+	if (!cmd)
+		return NULL;
+	/*
+	 * Some commands allow length modifiers (like "cp.b");
+	 * compare command name only until first dot.
+	 */
+	len = ((p = strchr(cmd, '.')) == NULL) ? strlen(cmd) : (p - cmd);
+
+	for (cmdtp = table;
+	     cmdtp != table + table_len;
+	     cmdtp++) {
+		if (strncmp(cmd, cmdtp->name, len) == 0) {
+			if (len == strlen(cmdtp->name))
+				return cmdtp;	/* full match */
+
+			cmdtp_temp = cmdtp;	/* abbreviated command ? */
+			n_found++;
+		}
+	}
+	if (n_found == 1) {			/* exactly one match */
+		return cmdtp_temp;
+	}
+
+	return NULL;	/* not found or ambiguous command */
+}
+
+/*******************************************************************************
+* find_cmd
+*
+* DESCRIPTION:
+* wrapper function for 'find_cmd_tbl'
+*
+*******************************************************************************/
+cmd_tbl_t *find_cmd(const char *cmd)
+{
+	return find_cmd_tbl(cmd, commands, sizeof(commands)/sizeof(struct cmd_tbl_s));
+}
+
+static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int result;
+
+	result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
+	return result;
+}
+
+/*******************************************************************************
+* cmd_usage
+*
+* DESCRIPTION:
+* prints the help message of the command
+*
+* INPUT:
+*	cmdtp	- command entry pointer
+*
+*
+*******************************************************************************/
+void cmd_usage(const cmd_tbl_t *cmdtp)
+{
+	mvPrintf("%s - %s\n\n", cmdtp->name, cmdtp->usage);
+	mvPrintf("Usage:\n%s ", cmdtp->name);
+
+	if (!cmdtp->help)
+		return;
+
+	mvPrintf("%s\n", cmdtp->help);
+}
+
+/*******************************************************************************
+* cmd_process
+*
+* DESCRIPTION:
+* search for command in command table and run it
+*
+* INPUT:
+*	flag	- command flag
+*	argc	- number of arguments
+*	argv	- arguments array
+*
+* RETURN:
+*	CMD_RET_SUCCESS(0), if command was ran successfully
+*	CMD_RET_FAILURE(1), on failure
+*	CMD_RET_USAGE(-1), on failure and need to print help message (future use)
+*
+*
+*******************************************************************************/
+enum command_ret_t cmd_process(int flag, int argc, char * const argv[])
+{
+	enum command_ret_t rc = CMD_RET_SUCCESS;
+	cmd_tbl_t *cmdtp;
+
+	/* Look up command in command table */
+	cmdtp = find_cmd(argv[0]);
+	if (cmdtp == NULL) {
+		putstring("Unknown command\n");
+		return 1;
+	}
+
+	/* found - check max args */
+	if (argc > cmdtp->maxargs)
+		rc = CMD_RET_USAGE;
+
+
+	/* If OK so far, then do the command */
+	if (!rc)
+		rc = cmd_call(cmdtp, flag, argc, argv);
+
+	if (rc == CMD_RET_USAGE)
+		cmd_usage(cmdtp);
+
+	return rc;
+}
+
+/*******************************************************************************
+* parse_line
+*
+* DESCRIPTION:
+* parse command and store arguments in argv
+*
+* INPUT:
+*	line	- pointer to the beginning of the command string
+*
+* OUTPUT:
+*	argv	- output array of the parsed arguments
+*
+* RETURN:
+*	number of arguments
+*
+*******************************************************************************/
+int parse_line(char *line, char *argv[])
+{
+	int nargs = 0;
+
+	while (nargs < CONFIG_SYS_MAXARGS) {
+
+		/* skip any white space */
+		while (isblank1(*line))
+			++line;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		argv[nargs++] = line;	/* begin of argument string	*/
+
+		/* find end of string */
+		while (*line && !isblank1(*line))
+			++line;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		*line++ = '\0';		/* terminate current arg	 */
+	}
+
+	putstring("** Too many args **\n");
+
+	return nargs;
+}
+
+/*******************************************************************************
+* run_command
+*
+* DESCRIPTION:
+* runs input command
+*
+* INPUT:
+*	cmd	- input command string to run (including parameters).
+*	flag	- command flag
+*
+*******************************************************************************/
+void run_command(const char *cmd, int flag)
+{
+	char cmdbuf[CONFIG_SYS_CBSIZE];	/* working copy of cmd		*/
+	char *token;			/* start of token in cmdbuf	*/
+	char *sep;			/* end of token (separator) in cmdbuf */
+	char *str = cmdbuf;
+	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated	*/
+	int argc, inquotes;
+
+	if (!cmd || !*cmd)
+		return;	/* empty command */
+
+	if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
+		putstring("## Command too long!\n");
+		return;
+	}
+
+	strcpy(cmdbuf, cmd);
+
+	/* Process separators */
+
+	while (*str) {
+
+		/*
+		 * Find separator, or string end
+		 * Allow simple escape of ';' by writing "\;"
+		 */
+		for (inquotes = 0, sep = str; *sep; sep++) {
+			if ((*sep == '\'') &&
+			    (*(sep - 1) != '\\'))
+				inquotes = !inquotes;
+
+			if (!inquotes &&
+			    (*sep == ';') &&	/* separator		*/
+			    (sep != str) &&	/* past string start	*/
+			    (*(sep-1) != '\\'))	/* and NOT escaped	*/
+				break;
+		}
+
+		/*
+		 * Limit the token to data between separators
+		 */
+		token = str;
+		if (*sep) {
+			str = sep + 1;	/* start of command for next pass */
+			*sep = '\0';
+		} else
+			str = sep;	/* no more commands for next pass */
+
+		/* Extract arguments */
+		argc = parse_line(token, argv);
+		if (argc == 0)
+			continue;
+
+		cmd_process(flag, argc, argv);
+	}
+}
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/platform/utils/debug/command.h
similarity index 63%
copy from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
copy to tools/marvell/bin_hdr/platform/utils/debug/command.h
index da82e24..18f7b9b 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/platform/utils/debug/command.h
@@ -1,4 +1,3 @@
-
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -43,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-		notice, this list of conditions and the following disclaimer in the
-		documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-		used to endorse or promote products derived from this software without
-		specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -62,79 +61,32 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-#ifndef _MV_DDR3_TOPOLOGY_DEF_H
-#define _MV_DDR3_TOPOLOGY_DEF_H
 
+#include "mv_os.h"
+#include "mvUart.h"
 
-/*************************TOPOLOGY*******************************************/
-#ifdef CONFIG_DDR3
-typedef enum
-{
-   SPEED_BIN_DDR_800D,
-   SPEED_BIN_DDR_800E,
-   SPEED_BIN_DDR_1066E,
-   SPEED_BIN_DDR_1066F,
-   SPEED_BIN_DDR_1066G,
-   SPEED_BIN_DDR_1333F,
-   SPEED_BIN_DDR_1333G,
-   SPEED_BIN_DDR_1333H,
-   SPEED_BIN_DDR_1333J,
-   SPEED_BIN_DDR_1600G,
-   SPEED_BIN_DDR_1600H,
-   SPEED_BIN_DDR_1600J,
-   SPEED_BIN_DDR_1600K,
-   SPEED_BIN_DDR_1866J,
-   SPEED_BIN_DDR_1866K,
-   SPEED_BIN_DDR_1866L,
-   SPEED_BIN_DDR_1866M,
-   SPEED_BIN_DDR_2133K,
-   SPEED_BIN_DDR_2133L,
-   SPEED_BIN_DDR_2133M,
-   SPEED_BIN_DDR_2133N,
+#define CONFIG_SYS_MAXARGS 8
+#define CMD_FLAG_REPEAT 0x0001
 
-   SPEED_BIN_DDR_1333H_EXT,
-   SPEED_BIN_DDR_1600K_EXT,
-   SPEED_BIN_DDR_1866M_EXT
-}MV_HWS_SPEED_BIN;
+struct cmd_tbl_s {
+	char		*name;		/* Command Name			*/
+	int		maxargs;	/* maximum number of arguments	*/
+					/* Implementation function	*/
+	int		(*cmd)(struct cmd_tbl_s *, int, int, char * const []);
+	char		*usage;		/* Usage message	(short)	*/
+	char		*help;		/* Usage message	(long)	*/
+};
 
-typedef enum 
-{
-  DDR_FREQ_LOW_FREQ,
-  DDR_FREQ_400,
-  DDR_FREQ_533,
-  DDR_FREQ_667,
-  DDR_FREQ_800,
-  DDR_FREQ_933,
-  DDR_FREQ_1066,
-  DDR_FREQ_311,
-  DDR_FREQ_333,
-  DDR_FREQ_467,
-  DDR_FREQ_850,
-  DDR_FREQ_600,
-  DDR_FREQ_300,
-  DDR_FREQ_900,
-  DDR_FREQ_360,
-  DDR_FREQ_1000,
-   DDR_FREQ_LIMIT
-}MV_HWS_DDR_FREQ;
+enum command_ret_t {
+	CMD_RET_SUCCESS,	/* 0 = Success */
+	CMD_RET_FAILURE,	/* 1 = Failure */
+	CMD_RET_USAGE = -1,	/* Failure, please report 'usage' error */
+};
 
-typedef enum
-{
-    speedBinTableElements_tRCD,
-    speedBinTableElements_tRP,
-    speedBinTableElements_tRAS,
-    speedBinTableElements_tRC,
-    speedBinTableElements_tRRD1K,
-    speedBinTableElements_tRRD2K,
-    speedBinTableElements_tPD,
-    speedBinTableElements_tFAW1K,
-    speedBinTableElements_tFAW2K,
-    speedBinTableElements_tWTR,
-    speedBinTableElements_tRTP,
-    speedBinTableElements_tWR,
-    speedBinTableElements_tMOD
-}speedBinTableElements;
-#endif /*CONFIG_DDR3 */
-#endif /* _MV_DDR3_TOPOLOGY_DEF_H */
+typedef struct cmd_tbl_s cmd_tbl_t;
+
+int cmd_get_data_size(char *arg, int default_size);
+
+void run_command(const char *cmd, int flag);
 
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/platform/utils/debug/debug.c
similarity index 63%
copy from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
copy to tools/marvell/bin_hdr/platform/utils/debug/debug.c
index da82e24..47830cf 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/platform/utils/debug/debug.c
@@ -1,4 +1,3 @@
-
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -43,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-		notice, this list of conditions and the following disclaimer in the
-		documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-		used to endorse or promote products derived from this software without
-		specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -62,79 +61,26 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-#ifndef _MV_DDR3_TOPOLOGY_DEF_H
-#define _MV_DDR3_TOPOLOGY_DEF_H
 
+/* includes */
+#include "mv_os.h"
+#include "config_marvell.h"  	/* Required to identify SOC and Board */
+#include "mvUart.h"
+#include "printf.h"
+#include "mvSysEnvLib.h"
+#include "command.h"
+#include "lib_utils.h"
 
-/*************************TOPOLOGY*******************************************/
-#ifdef CONFIG_DDR3
-typedef enum
+MV_STATUS mvBinHeaderDebugPrompt(void)
 {
-   SPEED_BIN_DDR_800D,
-   SPEED_BIN_DDR_800E,
-   SPEED_BIN_DDR_1066E,
-   SPEED_BIN_DDR_1066F,
-   SPEED_BIN_DDR_1066G,
-   SPEED_BIN_DDR_1333F,
-   SPEED_BIN_DDR_1333G,
-   SPEED_BIN_DDR_1333H,
-   SPEED_BIN_DDR_1333J,
-   SPEED_BIN_DDR_1600G,
-   SPEED_BIN_DDR_1600H,
-   SPEED_BIN_DDR_1600J,
-   SPEED_BIN_DDR_1600K,
-   SPEED_BIN_DDR_1866J,
-   SPEED_BIN_DDR_1866K,
-   SPEED_BIN_DDR_1866L,
-   SPEED_BIN_DDR_1866M,
-   SPEED_BIN_DDR_2133K,
-   SPEED_BIN_DDR_2133L,
-   SPEED_BIN_DDR_2133M,
-   SPEED_BIN_DDR_2133N,
+	putstring("\nPrompt mode\n");
+	while (1) {
+		readline("Marvell_Debug>> ");
+		if (strcmp(console_buffer, "q") == 0)
+			break;
 
-   SPEED_BIN_DDR_1333H_EXT,
-   SPEED_BIN_DDR_1600K_EXT,
-   SPEED_BIN_DDR_1866M_EXT
-}MV_HWS_SPEED_BIN;
-
-typedef enum 
-{
-  DDR_FREQ_LOW_FREQ,
-  DDR_FREQ_400,
-  DDR_FREQ_533,
-  DDR_FREQ_667,
-  DDR_FREQ_800,
-  DDR_FREQ_933,
-  DDR_FREQ_1066,
-  DDR_FREQ_311,
-  DDR_FREQ_333,
-  DDR_FREQ_467,
-  DDR_FREQ_850,
-  DDR_FREQ_600,
-  DDR_FREQ_300,
-  DDR_FREQ_900,
-  DDR_FREQ_360,
-  DDR_FREQ_1000,
-   DDR_FREQ_LIMIT
-}MV_HWS_DDR_FREQ;
-
-typedef enum
-{
-    speedBinTableElements_tRCD,
-    speedBinTableElements_tRP,
-    speedBinTableElements_tRAS,
-    speedBinTableElements_tRC,
-    speedBinTableElements_tRRD1K,
-    speedBinTableElements_tRRD2K,
-    speedBinTableElements_tPD,
-    speedBinTableElements_tFAW1K,
-    speedBinTableElements_tFAW2K,
-    speedBinTableElements_tWTR,
-    speedBinTableElements_tRTP,
-    speedBinTableElements_tWR,
-    speedBinTableElements_tMOD
-}speedBinTableElements;
-#endif /*CONFIG_DDR3 */
-#endif /* _MV_DDR3_TOPOLOGY_DEF_H */
-
+		run_command(console_buffer, 0);
+	}
+	return MV_OK;
+}
 
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/lib_utils.c b/tools/marvell/bin_hdr/platform/utils/debug/lib_utils.c
new file mode 100644
index 0000000..b50fceb
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/lib_utils.c
@@ -0,0 +1,304 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+*******************************************************************************/
+
+#include "lib_utils.h"
+#include <stdlib.h>
+#include "mv_os.h"
+#include "mvUart.h"
+#include "printf.h"
+
+/*******************************************************************************
+ * implementation of used ctype functions
+ *******************************************************************************/
+
+/*******************************************************************************
+* isprint
+*
+* DESCRIPTION:
+* Checks whether c is a printable character
+* A printable character is a character that occupies a printing position on a display
+*
+*******************************************************************************/
+int isprint(int c)
+{
+	return c >= ' ' && c <= '~';
+}
+
+/*******************************************************************************
+* isblank1
+*
+* DESCRIPTION:
+* Checks whether c is a blank character
+* the blank characters are space and horizontal tab
+*
+*******************************************************************************/
+int isblank1(char c)
+{
+	return (c >= 9 && c <= 13) || c == 32;
+}
+
+/*******************************************************************************
+* isxdigit
+*
+* DESCRIPTION:
+* Checks whether c is a hexdecimal digit character
+* Hexadecimal digits are any of: 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
+*
+*******************************************************************************/
+int isxdigit(int c)
+{
+	if (c >= '0' && c <= '9')
+		return 1;
+
+	if (c >= 'A' && c <= 'F')
+		return 1;
+
+	if (c >= 'a' && c <= 'f')
+		return 1;
+
+	return 0;
+}
+
+/*******************************************************************************
+* isdigit
+*
+* DESCRIPTION:
+* Checks whether c is a decimal digit character
+* Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9
+*
+*******************************************************************************/
+int isdigit(int c)
+{
+	if (c >= '0' && c <= '9')
+		return 1;
+
+	return 0;
+}
+
+/*******************************************************************************
+* islower
+*
+* DESCRIPTION:
+* Checks whether c is a lowercase letter
+*
+*******************************************************************************/
+int islower(int c)
+{
+	if (c >= 'a' && c <= 'z')
+		return 1;
+
+	return 0;
+}
+
+/*******************************************************************************
+* toupper
+*
+* DESCRIPTION:
+* Returns the uppercase equivalent of c
+*
+*******************************************************************************/
+int toupper(int c)
+{
+	if (islower(c))
+		return 'A' + (c - 'a');
+	else
+		return c;
+}
+
+/*******************************************************************************
+ * implementation of used string functions
+ *******************************************************************************/
+
+/* strchr */
+char *strchr(const char *s, int c)
+{
+/* Scan s for the character.  When this loop is finished,
+ s will either point to the end of the string or the
+ character we were looking for.  */
+	while (*s != '\0' && *s != (char)c)
+		s++;
+	return (*s == (char)c) ? (char *) s : NULL;
+}
+
+/* strlen */
+int strlen(const char *s)
+{
+	const char *p = s;
+	/* Loop over the data in s.  */
+	while (*p != '\0')
+		p++;
+	return (int)(p - s);
+}
+
+/* strcmp */
+int strcmp(const char *s1, const char *s2)
+{
+	int __res;
+	while (1) {
+		__res = *s1 - *s2++;
+		if (__res != 0 || !*s1++)
+			break;
+	}
+
+	return __res;
+}
+
+/* strncmp */
+int strncmp(const char *s1, const char *s2, int n)
+{
+	unsigned char uc1, uc2;
+	/* Nothing to compare?  Return zero.  */
+	if (n == 0)
+		return 0;
+
+	/* Loop, comparing bytes.  */
+	while (n-- > 0 && *s1 == *s2) {
+		/* If we've run out of bytes or hit a null, return zero
+		since we already know *s1 == *s2.  */
+		if (n == 0 || *s1 == '\0')
+			return 0;
+
+		s1++;
+		s2++;
+	}
+	uc1 = (*(unsigned char *) s1);
+	uc2 = (*(unsigned char *) s2);
+	return ((uc1 < uc2) ? -1 : (uc1 > uc2));
+}
+/* strcpy */
+char *strcpy(char *s1, const char *s2)
+{
+	char *dst = s1;
+	const char *src = s2;
+	/* Do the copying in a loop.  */
+	while ((*dst++ = *src++) != '\0')
+		;               /* The body of this loop is left empty. */
+	/* Return the destination string.  */
+	return s1;
+}
+
+/*******************************************************************************
+ * implementation of other utils
+ *******************************************************************************/
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+char console_buffer[CONFIG_SYS_CBSIZE + 1];
+/*******************************************************************************
+* readline
+*
+* DESCRIPTION:
+* prints 'disp' and reads characters from UART until newline character(ACSII 13)
+* received and writes the characters to 'console_buffer'
+*
+* INPUT:
+*	disp	- string to display.
+*
+* RETURN:
+*	Number of read characters, not including newline character
+*
+*******************************************************************************/
+int readline(const char *disp)
+{
+	char c;
+	int curr = 0;
+	mvPrintf(disp);
+
+	while (curr <= CONFIG_SYS_CBSIZE) {
+		c = mvUartGetc();
+		if (c == 13) {
+			console_buffer[curr] = 0;
+			putstring("\n");
+			return curr;
+		}
+		mvUartPutc(c);
+		console_buffer[curr++] = c;
+	}
+	console_buffer[CONFIG_SYS_CBSIZE] = 0;
+	return curr;
+}
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/platform/utils/debug/lib_utils.h
similarity index 63%
copy from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
copy to tools/marvell/bin_hdr/platform/utils/debug/lib_utils.h
index da82e24..f445ee0 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/platform/utils/debug/lib_utils.h
@@ -1,4 +1,3 @@
-
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -43,12 +42,12 @@
 	    this list of conditions and the following disclaimer.
 
     *   Redistributions in binary form must reproduce the above copyright
-		notice, this list of conditions and the following disclaimer in the
-		documentation and/or other materials provided with the distribution.
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
 
     *   Neither the name of Marvell nor the names of its contributors may be
-		used to endorse or promote products derived from this software without
-		specific prior written permission.
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -62,79 +61,21 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-#ifndef _MV_DDR3_TOPOLOGY_DEF_H
-#define _MV_DDR3_TOPOLOGY_DEF_H
 
+#define CONFIG_SYS_CBSIZE 1024
+extern char console_buffer[CONFIG_SYS_CBSIZE + 1];
 
-/*************************TOPOLOGY*******************************************/
-#ifdef CONFIG_DDR3
-typedef enum
-{
-   SPEED_BIN_DDR_800D,
-   SPEED_BIN_DDR_800E,
-   SPEED_BIN_DDR_1066E,
-   SPEED_BIN_DDR_1066F,
-   SPEED_BIN_DDR_1066G,
-   SPEED_BIN_DDR_1333F,
-   SPEED_BIN_DDR_1333G,
-   SPEED_BIN_DDR_1333H,
-   SPEED_BIN_DDR_1333J,
-   SPEED_BIN_DDR_1600G,
-   SPEED_BIN_DDR_1600H,
-   SPEED_BIN_DDR_1600J,
-   SPEED_BIN_DDR_1600K,
-   SPEED_BIN_DDR_1866J,
-   SPEED_BIN_DDR_1866K,
-   SPEED_BIN_DDR_1866L,
-   SPEED_BIN_DDR_1866M,
-   SPEED_BIN_DDR_2133K,
-   SPEED_BIN_DDR_2133L,
-   SPEED_BIN_DDR_2133M,
-   SPEED_BIN_DDR_2133N,
+/* ctype */
+int isblank1(char c);
+int isprint(int c);
 
-   SPEED_BIN_DDR_1333H_EXT,
-   SPEED_BIN_DDR_1600K_EXT,
-   SPEED_BIN_DDR_1866M_EXT
-}MV_HWS_SPEED_BIN;
+/* string */
+char *strchr(const char *s, int c);
+int strlen(const char *s);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, int n);
+char *strcpy(char *s1, const char *s2);
 
-typedef enum 
-{
-  DDR_FREQ_LOW_FREQ,
-  DDR_FREQ_400,
-  DDR_FREQ_533,
-  DDR_FREQ_667,
-  DDR_FREQ_800,
-  DDR_FREQ_933,
-  DDR_FREQ_1066,
-  DDR_FREQ_311,
-  DDR_FREQ_333,
-  DDR_FREQ_467,
-  DDR_FREQ_850,
-  DDR_FREQ_600,
-  DDR_FREQ_300,
-  DDR_FREQ_900,
-  DDR_FREQ_360,
-  DDR_FREQ_1000,
-   DDR_FREQ_LIMIT
-}MV_HWS_DDR_FREQ;
-
-typedef enum
-{
-    speedBinTableElements_tRCD,
-    speedBinTableElements_tRP,
-    speedBinTableElements_tRAS,
-    speedBinTableElements_tRC,
-    speedBinTableElements_tRRD1K,
-    speedBinTableElements_tRRD2K,
-    speedBinTableElements_tPD,
-    speedBinTableElements_tFAW1K,
-    speedBinTableElements_tFAW2K,
-    speedBinTableElements_tWTR,
-    speedBinTableElements_tRTP,
-    speedBinTableElements_tWR,
-    speedBinTableElements_tMOD
-}speedBinTableElements;
-#endif /*CONFIG_DDR3 */
-#endif /* _MV_DDR3_TOPOLOGY_DEF_H */
-
-
+/* other utils */
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
+int readline(const char *disp);
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/mem.c b/tools/marvell/bin_hdr/platform/utils/debug/mem.c
new file mode 100644
index 0000000..1a6651d
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/mem.c
@@ -0,0 +1,703 @@
+#include "command.h"
+#include "printf.h"
+#include "mvUart.h"
+#include "lib_utils.h"
+#include "mv_os.h"
+#include "soc_spec.h"
+#include "ddr3_hws_hw_training_def.h"
+#include "stdint.h"
+
+
+#define DISP_LINE_LEN 16
+#define MAX_LINE_LENGTH_BYTES (64)
+#define DEFAULT_LINE_LENGTH_BYTES (16)
+#define REG_PHY_DATA		0
+#define CONFIG_SYS_MEMTEST_START        0x00400000
+#define CONFIG_SYS_MEMTEST_END          0x007fffff
+
+static unsigned int dp_last_addr, dp_last_size;
+static unsigned int dp_last_length = 0x40;
+static unsigned int mm_last_addr, mm_last_size;
+
+/*******************************************************************************
+* printHex
+*
+* DESCRIPTION:
+* Prints unsigned value in hex with specified width
+*
+* INPUT:
+*	x		- value to print
+*	width		- data value width.  May be 2, 4, or 8.
+*
+*******************************************************************************/
+static void printHex(MV_U32 x, unsigned int width)
+{
+	switch (width) {
+	case 8:
+		mvPrintf(" %08x", x);
+		break;
+	case 4:
+		mvPrintf(" %04x", x);
+		break;
+	default:
+		mvPrintf(" %02x", x);
+		break;
+	}
+}
+
+/*******************************************************************************
+* print_buffer
+*
+* DESCRIPTION:
+* Print data buffer in hex and ascii form to the terminal.
+* data reads are buffered so that each memory address is only read once.
+* Useful when displaying the contents of volatile registers.
+*
+* INPUT:
+*	addr		- Starting address to display at start of line
+*	data		- pointer to data buffer
+*	width		- data value width.  May be 1, 2, or 4.
+*	count		- number of values to display
+*	linelen		- Number of values to print per line
+*				specify 0 for default length
+*
+*******************************************************************************/
+void print_buffer(unsigned long addr, void *data, unsigned int width, unsigned int count, unsigned int linelen)
+{
+	/* linebuf as a union causes proper alignment */
+	union linebuf {
+		MV_U32 ui[MAX_LINE_LENGTH_BYTES/sizeof(MV_U32) + 1];
+		MV_U16 us[MAX_LINE_LENGTH_BYTES/sizeof(MV_U16) + 1];
+		MV_U8  uc[MAX_LINE_LENGTH_BYTES/sizeof(MV_U8) + 1];
+	} lb;
+	int i;
+
+	if (linelen*width > MAX_LINE_LENGTH_BYTES)
+		linelen = MAX_LINE_LENGTH_BYTES / width;
+	if (linelen < 1)
+		linelen = DEFAULT_LINE_LENGTH_BYTES / width;
+
+	while (count) {
+		mvPrintf("%08lx:", addr);
+
+		/* check for overflow condition */
+		if (count < linelen)
+			linelen = count;
+
+		/* Copy from memory into linebuf and print hex values */
+		for (i = 0; i < linelen; i++) {
+			MV_U32 x;
+			if (width == 4)
+				x = lb.ui[i] = *(volatile MV_U32*)data;
+			else if (width == 2)
+				x = lb.us[i] = *(volatile MV_U16*)data;
+			else
+				x = lb.uc[i] = *(volatile MV_U8*)data;
+			printHex(x, width*2);
+			data += width;
+		}
+
+		/* Print data in ASCII characters */
+		for (i = 0; i < linelen * width; i++) {
+			if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
+				lb.uc[i] = '.';
+		}
+		lb.uc[i] = '\0';
+		mvPrintf("    %s\n", lb.uc);
+
+		/* update references */
+		addr += linelen * width;
+		count -= linelen;
+	}
+}
+
+/*******************************************************************************
+* align_address
+*
+* DESCRIPTION:
+* Unaligned memory access Workaround:
+* if size = long/word, & address not aligned to long/word (respectively)
+* align address to meet requested size
+*
+* INPUT:
+*	addr		- address in memory to align (1/2/4)
+*	size		- size in bytes
+*
+* RETURN:
+*	the aligned address
+*
+*******************************************************************************/
+static unsigned long align_address(unsigned long addr, int size)
+{
+
+	if ((size > 1) && (addr % size > 0)) {
+		mvPrintf("Error: Requested unaligned memory address (0x%x)\n", (unsigned int)addr);
+		addr &= ~(size - 1);
+		mvPrintf("Using aligned address (0x%x)\n", (unsigned int)addr);
+	}
+	return addr;
+}
+
+/*******************************************************************************
+* do_mem_md
+*
+* DESCRIPTION:
+* The command allows the user to display memory values
+*
+*******************************************************************************/
+int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned long addr, length;
+	int size;
+	int rc = 0;
+	/* We use the last specified parameters, unless new ones are
+	 * entered.
+	 */
+	addr = dp_last_addr;
+	size = dp_last_size;
+	length = dp_last_length;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if ((flag & CMD_FLAG_REPEAT) == 0) {
+		/* New command specified.  Check for a size specification.
+		 * Defaults to long if no or incorrect specification.
+		 */
+		size = cmd_get_data_size(argv[0], 4);
+		if (size < 0)
+			return 1;
+
+		/* Address is specified since argc > 1
+		*/
+		addr = simple_strtoul(argv[1], NULL, 16);
+
+		/* If another parameter, it is the length to display.
+		 * Length is the number of objects, not number of bytes.
+		 */
+		if (argc > 2)
+			length = simple_strtoul(argv[2], NULL, 16);
+	}
+
+	addr = align_address(addr, size);
+	/* Print the lines. */
+	print_buffer(addr, (void *)addr, size, length, DISP_LINE_LEN/size);
+	addr += size*length;
+
+
+	dp_last_addr = addr;
+	dp_last_length = length;
+	dp_last_size = size;
+	return rc;
+}
+
+/*******************************************************************************
+* do_mem_mw
+*
+* DESCRIPTION:
+* The command allows the user to write to memory
+*
+*******************************************************************************/
+int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned long addr, writeval, count;
+	int size;
+
+	if ((argc < 3) || (argc > 4))
+		return CMD_RET_USAGE;
+
+	/* Check for size specification.
+	*/
+	size = cmd_get_data_size(argv[0], 4);
+	if (size < 1)
+		return 1;
+
+	/* Address is specified since argc > 1
+	*/
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	addr = align_address(addr, size);
+
+	/* Get the value to write.
+	*/
+	writeval = simple_strtoul(argv[2], NULL, 16);
+
+	/* Count ? */
+	if (argc == 4)
+		count = simple_strtoul(argv[3], NULL, 16);
+	else
+		count = 1;
+
+	while (count-- > 0) {
+		if (size == 4)
+			*((unsigned long *)addr) = (unsigned long)writeval;
+		else if (size == 2)
+			*((unsigned short *)addr) = (unsigned short)writeval;
+		else
+			*((unsigned char *)addr) = (unsigned char)writeval;
+		addr += size;
+	}
+	return 0;
+}
+
+static int mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
+{
+	unsigned long addr, i;
+	int nbytes, size;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	/* We use the last specified parameters, unless new ones are
+	 * entered.
+	 */
+	addr = mm_last_addr;
+	size = mm_last_size;
+
+	if ((flag & CMD_FLAG_REPEAT) == 0) {
+		/* New command specified.  Check for a size specification.
+		 * Defaults to long if no or incorrect specification.
+		 */
+		size = cmd_get_data_size(argv[0], 4);
+		if (size < 0)
+			return 1;
+
+		/* Address is specified since argc > 1
+		*/
+		addr = simple_strtoul(argv[1], NULL, 16);
+	}
+
+
+	addr = align_address(addr, size);
+
+	/* Print the address, followed by value.  Then accept input for
+	 * the next value.  A non-converted value exits.
+	 */
+	do {
+		mvPrintf("%08lx:", addr);
+		if (size == 4)
+			mvPrintf(" %08x", *((unsigned int *)addr));
+		else if (size == 2)
+			mvPrintf(" %04x", *((unsigned short *)addr));
+		else
+			mvPrintf(" %02x", *((unsigned char *)addr));
+
+		nbytes = readline(" ? ");
+		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
+			/* <CR> pressed as only input, don't modify current
+			 * location and move to next. "-" pressed will go back.
+			 */
+			if (incrflag)
+				addr += nbytes ? -size : size;
+			nbytes = 1;
+		} else {
+			char *endp;
+			i = simple_strtoul(console_buffer, &endp, 16);
+			nbytes = endp - console_buffer;
+			if (nbytes) {
+				if (size == 4)
+					*((unsigned int *)addr) = i;
+				else if (size == 2)
+					*((unsigned short *)addr) = i;
+				else
+					*((unsigned char *)addr) = i;
+				if (incrflag)
+					addr += size;
+			}
+		}
+	} while (nbytes);
+
+	mm_last_addr = addr;
+	mm_last_size = size;
+	return 0;
+}
+
+/*******************************************************************************
+* do_mem_mm
+*
+* DESCRIPTION:
+* The command allows the user to modify bytes in memory
+*
+*******************************************************************************/
+int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return mod_mem(cmdtp, 1, flag, argc, argv);
+}
+
+/*******************************************************************************
+* do_mem_cmp
+*
+* DESCRIPTION:
+* The command allows the user to compare bytes in memory
+*
+*******************************************************************************/
+int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned long addr1, addr2, count, ngood;
+	int size;
+	int rcode = 0;
+	const char *type;
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	/* Check for size specification.
+	*/
+	size = cmd_get_data_size(argv[0], 4);
+	if (size < 0)
+		return 1;
+
+	type = size == 4 ? "word" : size == 2 ? "halfword" : "byte";
+
+	addr1 = simple_strtoul(argv[1], NULL, 16);
+
+	addr2 = simple_strtoul(argv[2], NULL, 16);
+
+	addr1 = align_address(addr1, size);
+	addr2 = align_address(addr2, size);
+
+	count = simple_strtoul(argv[3], NULL, 16);
+
+	for (ngood = 0; ngood < count; ++ngood) {
+		unsigned long word1, word2;
+		if (size == 4) {
+			word1 = *(unsigned long *)addr1;
+			word2 = *(unsigned long *)addr2;
+		} else if (size == 2) {
+			word1 = *(unsigned short *)addr1;
+			word2 = *(unsigned short *)addr2;
+		} else {
+			word1 = *(unsigned char *)addr1;
+			word2 = *(unsigned char *)addr2;
+		}
+		if (word1 != word2) {
+			mvPrintf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
+				type, addr1, size, word1,
+				type, addr2, size, word2);
+			rcode = 1;
+			break;
+		}
+
+		addr1 += size;
+		addr2 += size;
+	}
+
+	mvPrintf("Total of %ld %s(s) were the same\n", ngood, type);
+	return rcode;
+}
+
+/*******************************************************************************
+* do_mem_cp
+*
+* DESCRIPTION:
+* The command allows the user to copy bytes from/to memory
+*
+*******************************************************************************/
+int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned long addr, dest, count;
+	int size;
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	/* Check for size specification.
+	*/
+	size = cmd_get_data_size(argv[0], 4);
+	if (size < 0)
+		return 1;
+
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	dest = simple_strtoul(argv[2], NULL, 16);
+
+	addr = align_address(addr, size);
+	dest = align_address(dest, size);
+
+	count = simple_strtoul(argv[3], NULL, 16);
+
+	if (count == 0) {
+		mvPrintf("Zero length ???\n");
+		return 1;
+	}
+	while (count-- > 0) {
+		if (size == 4)
+			*((unsigned long *)dest) = *((unsigned long *)addr);
+		else if (size == 2)
+			*((unsigned short *)dest) = *((unsigned short *)addr);
+		else
+			*((unsigned char *)dest) = *((unsigned char *)addr);
+		addr += size;
+		dest += size;
+	}
+	return 0;
+}
+
+/*******************************************************************************
+* ir_cmd
+*
+* DESCRIPTION:
+* The command allows the user to view the contents of the MV
+*                internal registers and modify them.
+*
+*******************************************************************************/
+int ir_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	MV_U32 regNum = 0x0, regVal, regValTmp, res;
+	MV_8 regValBin[40];
+	MV_8 cmd[40];
+	int i;
+	int j = 0, flagm = 0;
+
+	if (argc == 2)
+		regNum = simple_strtoul(argv[1], NULL, 16);
+	else {
+		mvPrintf("Usage:\n%s\n", cmdtp->usage);
+		return 0;
+	}
+
+	regVal = MV_REG_READ(regNum + INTER_REGS_BASE);
+	regValTmp = regVal;
+	mvPrintf("Internal register 0x%x value : 0x%x\n ", regNum, regVal);
+	mvPrintf("\n    31      24        16         8         0");
+	mvPrintf("\n     |       |         |         |         |\nOLD: ");
+
+	for (i = 31; i >= 0; i--) {
+		if (regValTmp > 0) {
+			res = regValTmp % 2;
+			regValTmp = (regValTmp - res) / 2;
+			if (res == 0)
+				regValBin[i] = '0';
+			else
+				regValBin[i] = '1';
+		} else
+			regValBin[i] = '0';
+	}
+
+	for (i = 0; i < 32; i++) {
+		mvPrintf("%c", regValBin[i]);
+		if ((((i+1) % 4) == 0) && (i > 1) && (i < 31))
+			mvPrintf("-");
+	}
+
+	readline("\nNEW: ");
+	strcpy(cmd, console_buffer);
+	if ((cmd[0] == '0') && (cmd[1] == 'x')) {
+		regVal = simple_strtoul(cmd, NULL, 16);
+		flagm = 1;
+	} else {
+		for (i = 0; i < 40; i++) {
+			if (cmd[i] == '\0')
+				break;
+			if (i == 4 || i == 9 || i == 14 || i == 19 || i == 24 || i == 29 || i == 34)
+				continue;
+			if (cmd[i] == '1') {
+				regVal = regVal | (0x80000000 >> j);
+				flagm = 1;
+			} else if (cmd[i] == '0') {
+				regVal = regVal & (~(0x80000000 >> j));
+				flagm = 1;
+			}
+			j++;
+		}
+	}
+
+	if (flagm == 1) {
+		MV_REG_WRITE(regNum + INTER_REGS_BASE, regVal);
+		mvPrintf("\nNew value = 0x%x\n\n", MV_REG_READ(regNum +
+					INTER_REGS_BASE));
+	}
+	return 1;
+}
+
+unsigned int trainingReadPhyReg(int uiRegAddr, int uiPup, int type)
+{
+	unsigned int uiReg;
+	unsigned int addrLow = 0x3F & uiRegAddr;
+	unsigned int addrHi = ((0xC0 & uiRegAddr) >> 6);
+
+	uiReg = (1 << 31) + (uiPup << 22) + (type << 26) + (addrHi << 28) + (addrLow << 16);
+	MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, uiReg & 0x7FFFFFFF);
+	MV_REG_WRITE(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, uiReg);
+
+	do {
+		uiReg = ((MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & (1 << 31));
+	} while (uiReg);	/* Wait for '0' to mark the end of the transaction */
+
+	uiReg = MV_REG_READ(REG_PHY_REGISTRY_FILE_ACCESS_ADDR);
+	uiReg = uiReg & 0xFFFF;
+
+	return uiReg;
+}
+
+/*******************************************************************************
+* training_cmd
+*
+* DESCRIPTION:
+* The command prints the results of the DDR3 Training
+*
+*******************************************************************************/
+int training_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	MV_U32 uiCsEna, uiCs, uiReg, uiPup, uiPhase, uiDelay;
+	MV_U32 uiRdRdyDly, uiRdSmplDly, uiDq, uiCentralTxRes, uiCentralRxRes;
+	MV_U32 uiPupNum;
+
+	uiCsEna = MV_REG_READ(REG_DDR3_RANK_CTRL_ADDR) & 0xF;
+	mvPrintf("DDR3 Training results:\n");
+
+	uiPupNum = 5;
+
+	for (uiCs = 0; uiCs < 4; uiCs++) {
+		if (uiCsEna & (1 << uiCs)) {
+			mvPrintf("CS: %d\n", uiCs);
+			for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
+				uiReg = trainingReadPhyReg(0 + uiCs*4, uiPup, REG_PHY_DATA);
+				uiPhase = (uiReg >> 6) & 0x7;
+				uiDelay = uiReg & 0x1F;
+				mvPrintf("Write Leveling: PUP: %d, Phase: %d, Delay: %d\n", uiPup, uiPhase, uiDelay);
+			}
+
+			for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
+				uiReg = trainingReadPhyReg(2 + uiCs*4, uiPup, REG_PHY_DATA);
+				uiPhase = (uiReg >> 6) & 0x7;
+				uiDelay = uiReg & 0x1F;
+				mvPrintf("Read Leveling: PUP: %d, Phase: %d, Delay: %d\n", uiPup, uiPhase, uiDelay);
+			}
+
+			uiRdRdyDly = ((MV_REG_READ(REG_READ_DATA_READY_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
+			uiRdSmplDly = ((MV_REG_READ(REG_READ_DATA_SAMPLE_DELAYS_ADDR) >> (8*uiCs)) & 0x1F);
+			mvPrintf("Read Sample Delay:\t%d\n", uiRdSmplDly);
+			mvPrintf("Read Ready Delay:\t%d\n", uiRdRdyDly);
+
+			/* PBS */
+			if (uiCs == 0) {
+				for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
+					for (uiDq = 0; uiDq < 10; uiDq++) {
+						if (uiDq == 9)
+							uiDq++;
+
+						uiReg = trainingReadPhyReg(0x10+uiDq+uiCs*0x12, uiPup, REG_PHY_DATA);
+						uiDelay = uiReg & 0x1F;
+
+						if (uiDq == 0)
+							mvPrintf("PBS TX: PUP: %d: ", uiPup);
+						mvPrintf("%d ", uiDelay);
+					}
+					mvPrintf("\n");
+				}
+				for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
+					for (uiDq = 0; uiDq < 9; uiDq++) {
+						uiReg = trainingReadPhyReg(0x50 + uiDq + uiCs*0x12,
+									   uiPup, REG_PHY_DATA);
+						uiDelay = uiReg & 0x1F;
+
+						if (uiDq == 0)
+							mvPrintf("PBS RX: PUP: %d: ", uiPup);
+						mvPrintf("%d ", uiDelay);
+					}
+					mvPrintf("\n");
+				}
+			}
+
+			/*Read Centralization windows sizes for Scratch PHY registers*/
+			for (uiPup = 0; uiPup < uiPupNum; uiPup++) {
+				uiReg = trainingReadPhyReg(0xC0 + uiCs, uiPup, REG_PHY_DATA);
+				uiCentralRxRes = uiReg >> 5;
+				uiCentralTxRes = uiReg & 0x1F;
+				mvPrintf("Central window size for PUP %d is %d(RX) and %d(TX)\n",
+						uiPup, uiCentralRxRes, uiCentralTxRes);
+			}
+		}
+	}
+	return 1;
+}
+
+/*******************************************************************************
+* do_mem_mtest
+*
+* DESCRIPTION:
+* Perform a memory test. A more complete alternative test can be
+* configured using CONFIG_SYS_ALT_MEMTEST.
+*
+*******************************************************************************/
+int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	volatile unsigned long	*addr, *start, *end;
+	unsigned long	val;
+	unsigned long	readback;
+	unsigned long	errs = 0;
+	int iterations = 1;
+	int iteration_limit;
+	unsigned long	incr;
+	unsigned long	pattern;
+
+	if (argc > 1)
+		start = (unsigned long *)simple_strtoul(argv[1], NULL, 16);
+	else
+		start = (unsigned long *)CONFIG_SYS_MEMTEST_START;
+
+	if (argc > 2)
+		end = (unsigned long *)simple_strtoul(argv[2], NULL, 16);
+	else
+		end = (unsigned long *)(CONFIG_SYS_MEMTEST_END);
+
+	start = (unsigned long *)align_address((unsigned long)start, 4);
+	end = (unsigned long *)align_address((unsigned long)end, 4);
+
+	if (argc > 3)
+		pattern = (unsigned long)simple_strtoul(argv[3], NULL, 16);
+	else
+		pattern = 0;
+
+	if (argc > 4)
+		iteration_limit = (unsigned long)simple_strtoul(argv[4], NULL, 16);
+	else
+		iteration_limit = 0;
+
+	incr = 1;
+	for (;;) {
+		if (iteration_limit && iterations > iteration_limit) {
+			mvPrintf("Tested %d iteration(s) with %lu errors.\n",
+				iterations-1, errs);
+			return errs != 0;
+		}
+		++iterations;
+
+		mvPrintf("\rPattern %08lX  Writing...", pattern);
+		mvPrintf("%12s", "");
+		mvPrintf("\b\b\b\b\b\b\b\b\b\b");
+
+		for (addr = start, val = pattern; addr < end; addr++) {
+			*addr = val;
+			val += incr;
+		}
+
+		mvPrintf("Reading...");
+
+		for (addr = start, val = pattern; addr < end; addr++) {
+			readback = *addr;
+			if (readback != val) {
+				mvPrintf("\nMem error @");
+				mvPrintf(" 0x%08X: found %08lX, expected %08lX\n",
+					(unsigned int)(uintptr_t)addr, readback, val);
+				errs++;
+			}
+			val += incr;
+		}
+
+		/*
+		 * 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
+			pattern = ~pattern;
+
+		incr = -incr;
+	}
+	return 0;	/* not reached */
+}
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.c b/tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.c
new file mode 100644
index 0000000..43289c6
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.c
@@ -0,0 +1,314 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+		notice, this list of conditions and the following disclaimer in the
+		documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+		used to endorse or promote products derived from this software without
+		specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+*******************************************************************************/
+
+#include "command.h"
+#include "printf.h"
+#include "mvUart.h"
+#include "lib_utils.h"
+#include "mv_os.h"
+#include "soc_spec.h"
+#include "ddr3_hws_hw_training_def.h"
+#include "stdint.h"
+#include "gtOs/mvXor.h"
+#include "gtOs/mvXorRegs.h"
+#include "stdlib.h"
+#include "util.h"
+#include "xor_memtest.h"
+
+extern GT_U32 mvHwsDdr3TipMaxCSGet(GT_U32 devNum);
+
+/*******************************************************************************
+* fillKillerPattern
+*
+* DESCRIPTION:
+* Writes the killer pattern in the specified source address in DRAM
+*
+* INPUT:
+*	nBase		- base address to start writing to
+*	nSize		- size of the block in bytes
+*	nbusWidth	- bus width, must be multiply of 32
+*
+*******************************************************************************/
+void fillKillerPattern(MV_U32 nBase, MV_U32 nSize, MV_U32 nbusWidth)
+{
+	MV_U8 killerPatternBusState[ST_KP_LEN] = KILLER_PATTERN_BUS_STATE;
+	MV_U8 killerPatternBitState[ST_KP_LEN] = KILLER_PATTERN_BIT_STATE;
+	MV_U32 nOffset = 0;
+	MV_U32 nNumOfWord = nbusWidth / 32;
+	MV_U32 nPattern;
+	MV_U32 nIndex   = 0;
+	MV_U32 nVicBit  = BIT0;
+	MV_U32 nVicWord = 0;
+	MV_U32 nWord;
+
+	while (nOffset < nSize) {
+		if (nIndex == ST_KP_LEN) {
+			nIndex = 0;
+			nVicBit <<= 1;
+			if (nVicBit == 0) {
+				nVicBit = BIT0;
+				nVicWord++;
+				if (nVicWord == nNumOfWord)
+					nVicWord = 0;
+			}
+		}
+		for (nWord = 0; ((nWord < nNumOfWord) && (nOffset < nSize)); nWord++, nOffset += 0x4) {
+			nPattern = BUS_STATUS(killerPatternBusState[nIndex]);
+			if (nWord == nVicWord)
+				nPattern = ((killerPatternBitState[nIndex]) ?
+						(nPattern | nVicBit) : (nPattern & ~nVicBit));
+
+			MV_MEMIO_LE32_WRITE(nBase + nOffset, nPattern);
+		}
+		nIndex++;
+	}
+}
+
+/*******************************************************************************
+* configureMemoryMapping
+*
+* DESCRIPTION:
+* Opens memory windows in the XOR Engine to the DRAM and SRAM
+*
+*******************************************************************************/
+void configureMemoryMapping()
+{
+	MV_U32 max_cs;
+	MV_U32 uiCsEna = 0, cs_c;
+#ifndef MV88F672X
+	max_cs = mvHwsDdr3TipMaxCSGet(0);
+#else
+	max_cs = 2;
+#endif
+	for (cs_c = 0; cs_c < max_cs; cs_c++)
+		uiCsEna |= 1 << cs_c;
+
+	/* enable SRAM window */
+	uiCsEna |= 1 << SRAM_WIN_ID;
+	max_cs++;
+	/* configure XOR engine windows */
+	mvSysXorInit(max_cs, uiCsEna, 0x80000000, 0);
+
+	/* shrink first DRAM(CS0) window to 0x40000000 (bytes)
+	 * to avoid memory mapping conflict:
+	 * First DRAM(CS0) window starts in 0x0 and ends in 0x80000000
+	 * SRAM window starts in 0x40000000
+	 * Hence, there is a conflict */
+	MV_REG_WRITE(XOR_SIZE_MASK_REG(0, 0), 0x3FFF0000);
+}
+
+/*******************************************************************************
+* XORCalculateCRC
+*
+* DESCRIPTION:
+* Calculates crc32c using the XOR engine
+*
+* INPUT:
+*	nChannel	- channel number (0..3)
+*	nSrcAddr	- source address
+*	nByteCnt	- size of the block in bytes
+*
+* OUTPUT:
+*	res		- crc32c result
+*
+* RETURN:
+*	MV_ERROR, in case of any error in calculation
+*	MV_OK, otherwise
+*
+*******************************************************************************/
+MV_STATUS XORCalculateCRC(MV_U32 nChannel, MV_U32 nSrcAddr, MV_U32 nByteCnt, MV_U32 *res)
+{
+
+	MV_U32 nTimeout = XOR_ENGINE_TIMEOUT;
+	MV_XOR_DESC XorDesc;
+	MV_XOR_DESC *pXorDesc = &XorDesc;
+	MV_U32 nXorChannel = XOR_CHAN(nChannel);
+
+	/* align pointer address to be multiple of 32 */
+	pXorDesc = (MV_XOR_DESC *)(((MV_U32)((void *)pXorDesc + 32)) & ~(32 - 1));
+
+	memset((void *)pXorDesc, 0, sizeof(MV_CRC_DMA_DESC));
+
+	/* clean previous indication from engine */
+	MV_REG_WRITE(XOR_CAUSE_REG(XOR_UNIT(nChannel)), 0);
+
+	memset((void *)pXorDesc, 0, sizeof(MV_CRC_DMA_DESC));
+	pXorDesc->srcAdd0		= nSrcAddr;
+	pXorDesc->byteCnt		= nByteCnt;
+	pXorDesc->descCommand		= BIT30;
+	pXorDesc->phyNextDescPtr	= 0;
+	pXorDesc->status		= BIT31;
+	pXorDesc->crc32Result		= 0;
+
+	/* wait for previous transfer to finnish */
+	while (mvXorStateGet(nChannel) != MV_IDLE)
+		;
+
+	/* disable address override */
+	MV_REG_WRITE(XOR_OVERRIDE_CTRL_REG(nChannel), 0x0);
+
+	if (mvXorTransfer(nChannel, MV_CRC32, (MV_U32)pXorDesc) != MV_OK) {
+		mvPrintf("%s: Error during XOR CRC...!\n", __func__);
+		return MV_ERROR;
+	}
+
+	/* wait for the engine to finish */
+	while ((MV_REG_READ(XOR_CAUSE_REG(XOR_UNIT(nChannel))) & ((BIT1|BIT0) << (16*nXorChannel))) == 0) {
+		if (nTimeout-- == 0) {
+			mvPrintf("%s: XOR CRC timeout!!\n", __func__);
+			return MV_ERROR;
+		}
+	}
+
+	nTimeout = XOR_ENGINE_TIMEOUT;
+	while (mvXorStateGet(nChannel) != MV_IDLE) {
+		if (nTimeout-- == 0) {
+			mvPrintf("%s: XOR CRC timeout 0!!\n", __func__);
+			return MV_ERROR;
+		}
+	}
+
+	*res = pXorDesc->crc32Result;
+	return MV_OK;
+}
+
+/*******************************************************************************
+* do_xorMemTest
+*
+* DESCRIPTION:
+* The command run memory test that is based on the XOR engine
+*
+*******************************************************************************/
+int do_xorMemTest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	MV_STATUS status;
+	MV_U32 nBlockCRC, nOffsetInDest, nOffset, nCRC, i, nSourceAddr, nDestAddr;
+	MV_U32 sourceBase = SOURCE_ADDRESS_BASE;
+	MV_U32 destBase = DESTANTION_ADDRESS_BASE;
+	MV_U32 destSize = DESTANTION_SIZE;
+	MV_U32 iterations = 1;
+
+	if (argc > 1)
+		nSourceAddr = simple_strtoul(argv[1], NULL, 16);
+
+	if (argc > 2)
+		nDestAddr = simple_strtoul(argv[2], NULL, 16);
+
+	if (argc > 3)
+		destSize = simple_strtoul(argv[3], NULL, 16);
+
+	if (argc > 4)
+		iterations = simple_strtoul(argv[4], NULL, 16);
+
+	/* check destSize, must be multiply of 1MB */
+	if (destSize & (_1M - 1)) {
+		mvPrintf("Error: Destination size must be multiply of 0x%X(1MB)\n", _1M);
+		mvSysXorFinish();
+		return -1;
+	}
+
+	configureMemoryMapping();
+
+	/* write the killer pattern in the source block */
+	fillKillerPattern(sourceBase, BLOCK_SIZE, 64);
+	fillKillerPattern(sourceBase + BLOCK_SIZE, BLOCK_SIZE, 128);
+
+	status = XORCalculateCRC(2, sourceBase, TOTAL_BLOCK_SIZE, &nBlockCRC);
+	CHECK_CRC_STATUS(status);
+	mvPrintf("nBlockCRC %x\n", nBlockCRC);
+
+	/* Start copying blocks */
+	for (i = 0; i < iterations; i++) {
+		for (nOffsetInDest = 0; nOffsetInDest < destSize; nOffsetInDest += TOTAL_BLOCK_SIZE) {
+
+			/* Copy block to the current destination address*/
+			for (nOffset = 0; nOffset < TOTAL_BLOCK_SIZE; nOffset += CPU_BURST_SIZE) {
+				nSourceAddr = sourceBase + nOffset;
+				nDestAddr = destBase + nOffsetInDest + nOffset;
+				MV_PLD_RANGE(nDestAddr, nDestAddr + CPU_BURST_SIZE);
+				memcpy((void *)nDestAddr, (void *)nSourceAddr, CPU_BURST_SIZE);
+				MV_FLUSH_CACHE_L1(nDestAddr, nDestAddr + CPU_BURST_SIZE);
+			}
+		}
+
+		/* Check the copied blocks in destination */
+		for (nOffsetInDest = 0; nOffsetInDest < destSize; nOffsetInDest += TOTAL_BLOCK_SIZE) {
+			nDestAddr = destBase + nOffsetInDest;
+			status = XORCalculateCRC(2, nDestAddr, TOTAL_BLOCK_SIZE, &nCRC);
+			CHECK_CRC_STATUS(status);
+			if (nCRC != nBlockCRC) {
+				mvPrintf("Error at Block start address %X\n", nDestAddr);
+				mvPrintf("CRC was %X expected %X\n", nCRC, nBlockCRC);
+				mvSysXorFinish();
+				return -1;
+			}
+		}
+		mvPrintf("\b\b\b\b%4d", i);
+	}
+	mvPrintf("\b\b\b\b");
+	mvPrintf("MemTest end successfully\n");
+	mvSysXorFinish();
+
+	return 0;
+}
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h b/tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.h
similarity index 64%
rename from tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
rename to tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.h
index da82e24..91d7ab7 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TopologyDef.h
+++ b/tools/marvell/bin_hdr/platform/utils/debug/xor_memtest.h
@@ -1,4 +1,3 @@
-
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -62,79 +61,85 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-#ifndef _MV_DDR3_TOPOLOGY_DEF_H
-#define _MV_DDR3_TOPOLOGY_DEF_H
 
+#define SRAM_WIN_ID		0x4
+#define SRAM_WIN_BASE		0x40000000
 
-/*************************TOPOLOGY*******************************************/
-#ifdef CONFIG_DDR3
-typedef enum
-{
-   SPEED_BIN_DDR_800D,
-   SPEED_BIN_DDR_800E,
-   SPEED_BIN_DDR_1066E,
-   SPEED_BIN_DDR_1066F,
-   SPEED_BIN_DDR_1066G,
-   SPEED_BIN_DDR_1333F,
-   SPEED_BIN_DDR_1333G,
-   SPEED_BIN_DDR_1333H,
-   SPEED_BIN_DDR_1333J,
-   SPEED_BIN_DDR_1600G,
-   SPEED_BIN_DDR_1600H,
-   SPEED_BIN_DDR_1600J,
-   SPEED_BIN_DDR_1600K,
-   SPEED_BIN_DDR_1866J,
-   SPEED_BIN_DDR_1866K,
-   SPEED_BIN_DDR_1866L,
-   SPEED_BIN_DDR_1866M,
-   SPEED_BIN_DDR_2133K,
-   SPEED_BIN_DDR_2133L,
-   SPEED_BIN_DDR_2133M,
-   SPEED_BIN_DDR_2133N,
+#define XOR_ENGINE_TIMEOUT	0x5000000
 
-   SPEED_BIN_DDR_1333H_EXT,
-   SPEED_BIN_DDR_1600K_EXT,
-   SPEED_BIN_DDR_1866M_EXT
-}MV_HWS_SPEED_BIN;
+#define ST_KP_LEN		59
+#define ONE			0xffffffff
+#define ZERO			0
+#define BUS_STATUS(nValue)	((nValue) ? ONE : ZERO)
+#define BIT(X)			(0x1 << X)
 
-typedef enum 
-{
-  DDR_FREQ_LOW_FREQ,
-  DDR_FREQ_400,
-  DDR_FREQ_533,
-  DDR_FREQ_667,
-  DDR_FREQ_800,
-  DDR_FREQ_933,
-  DDR_FREQ_1066,
-  DDR_FREQ_311,
-  DDR_FREQ_333,
-  DDR_FREQ_467,
-  DDR_FREQ_850,
-  DDR_FREQ_600,
-  DDR_FREQ_300,
-  DDR_FREQ_900,
-  DDR_FREQ_360,
-  DDR_FREQ_1000,
-   DDR_FREQ_LIMIT
-}MV_HWS_DDR_FREQ;
+#define NUM_OF_DESC		8
+#define DESC_SIZE		_8M
 
-typedef enum
-{
-    speedBinTableElements_tRCD,
-    speedBinTableElements_tRP,
-    speedBinTableElements_tRAS,
-    speedBinTableElements_tRC,
-    speedBinTableElements_tRRD1K,
-    speedBinTableElements_tRRD2K,
-    speedBinTableElements_tPD,
-    speedBinTableElements_tFAW1K,
-    speedBinTableElements_tFAW2K,
-    speedBinTableElements_tWTR,
-    speedBinTableElements_tRTP,
-    speedBinTableElements_tWR,
-    speedBinTableElements_tMOD
-}speedBinTableElements;
-#endif /*CONFIG_DDR3 */
-#endif /* _MV_DDR3_TOPOLOGY_DEF_H */
+#define SOURCE_ADDRESS_BASE    0x83000000
+#define BLOCK_SIZE             _1M
+#define TOTAL_BLOCK_SIZE       (BLOCK_SIZE*2)
+#define KILLER_64BIT_BASE      SOURCE_ADDRESS_BASE
+#define KILLER_128BIT_BASE     (KILLER_64BIT_BASE + BLOCK_SIZE)
+#define CPU_BURST_SIZE         _1K
 
+#define DESTANTION_ADDRESS_BASE 0x84000000
+#define DESTANTION_SIZE         _128M
 
+#define NUM_OF_XOR_ENGINE              4
+#define XOR_BLOCK_SIZE                 (_16M - 1)
+#define XOR_SOURCE_ADDRESS(nXorNum)    (0x10000000 + _128M*nXorNum)
+#define XOR_DEST_ADDRESS(nXorNum)      (XOR_SOURCE_ADDRESS(nXorNum) + (DESC_SIZE*NUM_OF_DESC))
+
+#define MV_PLD(Address)\
+{\
+	__asm__ __volatile__("pld [%0]" : : "r" (Address));\
+}
+
+#define MV_PLD_RANGE(from, to)\
+{\
+	MV_U32 addr;\
+	for (addr = from; addr < to; addr += 32) {\
+		MV_PLD(addr);\
+	} \
+}
+
+#define CHECK_CRC_STATUS(status)\
+{\
+	if (status != MV_OK) {\
+		mvPrintf("Failed to calculate CRC32\n");\
+		return 1;\
+	} \
+}
+
+void cache_inv(MV_U32 dest);
+void flush_l1_v7(MV_U32 dest);
+
+#define MV_FLUSH_CACHE_L1(from, to)\
+{\
+	MV_U32 addr;\
+	for (addr = from; addr < to; addr += 32) {\
+		cache_inv(addr);\
+		flush_l1_v7(addr);\
+	} \
+}
+
+#define KILLER_PATTERN_BUS_STATE\
+	{\
+		0, 0, 0, 1, 1, 1, 0, 1, 0, 1,\
+		0, 0, 1, 0, 1, 0, 1, 0, 1, 0,\
+		1, 0, 1, 0, 0, 1, 0, 1, 0, 0,\
+		0, 1, 1, 1, 0, 0, 1, 1, 0, 1,\
+		0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\
+		1, 1, 0, 1, 1, 0, 0\
+	}
+
+#define KILLER_PATTERN_BIT_STATE\
+	{\
+		1, 0, 1, 1, 0, 0, 1, 0, 1, 0,\
+		1, 1, 0, 1, 0, 0, 1, 0, 1, 0,\
+		1, 0, 1, 1, 0, 1, 0, 1, 0, 0,\
+		0, 0, 0, 1, 0, 0, 1, 1, 0, 1,\
+		0, 1, 1, 0, 0, 1, 0, 1, 0, 0,\
+		0, 0, 0, 1, 1, 1, 1\
+	}
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3_init_tipv2.c b/tools/marvell/bin_hdr/src_ddr/ddr3_init_tipv2.c
index 66d1da6..0255f77 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3_init_tipv2.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3_init_tipv2.c
@@ -120,6 +120,20 @@
     MV_HWS_TOPOLOGY_MAP     *topology
 );
 
+extern MV_STATUS ddr3TipGetFirstActiveIf
+(
+    MV_U8   devNum,
+    MV_U32  interfaceMask,
+    MV_U32  *ifId
+);
+
+extern MV_STATUS    mvCalcCsNum
+(
+    MV_U32          devNum,
+	MV_U32          interfaceId,
+	MV_U32          *csNum
+);
+
 extern MV_U32 ddr3TipGetInitFreq();
 
 extern MV_VOID ddr3HwsSetLogLevel(
@@ -137,6 +151,9 @@
 static MV_U32 ddr3GetStaticDdrMode(void);
 #endif
 
+/* global parameter (defined in TIP lib which holds the DDR topology */
+extern MV_HWS_TOPOLOGY_MAP *topologyMap;
+
 /*Set 1 to use dynamic DUNIT configuration,
 	set 0(supported for A380 and AC3) to configure DUNIT in values set by ddr3TipInitSpecificRegConfig*/
 MV_U8 genericInitController = 1;
@@ -148,7 +165,9 @@
 MV_U32 	mvBoardIdIndexGet(MV_U32 boardId);
 MV_U32 mvBoardIdGet(MV_VOID);
 MV_U32 ddr3GetBusWidth(void);
-
+#ifdef MV_RUN_WIN_VALIDATION_TEST
+extern MV_VOID mvHwsDdr3TipSweepTest(MV_BOOL enable);
+#endif
 extern MV_VOID ddr3SetLogLevel(MV_U32 nLogLevel);
 static MV_U32 gLogLevel = 0;
 static MV_STATUS ddr3HwsTuneTrainingParams(MV_U8 devNum);
@@ -409,6 +428,11 @@
 
 	/*Set log level for training lib*/
 	ddr3HwsSetLogLevel(MV_DEBUG_BLOCK_ALL, DEBUG_LEVEL_ERROR);
+	/*ddr3HwsSetLogLevel(MV_DEBUG_TRAINING_MAIN, DEBUG_LEVEL_TRACE);*/
+
+#ifdef MV_RUN_WIN_VALIDATION_TEST /* to run DDR viewer tool (to display DDR training results) */
+	mvHwsDdr3TipSweepTest(MV_TRUE);
+#endif
 
 	/*Start New Training IP*/
 	status = ddr3HwsHwTraining();
@@ -431,7 +455,11 @@
 	ddr3NewTipDlbConfig();
 
 #if defined(ECC_SUPPORT)
-	if( MV_TRUE == ddr3IfEccEnabled()){
+	if( (MV_TRUE == ddr3IfEccEnabled())/* &&
+		(mvSysEnvSuspendWakeupCheck() != MV_SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED) &&
+		(mvSysEnvCheckWakeupDramEnable() != MV_SUSPEND_WAKEUP_ENABLED_MEM_DETECTED) */){
+		/*Scrub all DRAM area if ECC enabled (and Suspend wakeup state not detected - TBD)*/
+		/* Disabled SuspendWakeup support until debug*/
 		ddr3NewTipEccScrub();
 	}
 #endif
@@ -769,6 +797,11 @@
 {
 	MV_TOPOLOGY_UPDATE_INFO topologyUpdateInfo;
 
+/* when booting from UART , skip reading DDR configuration from SW EEPROM, since EEPROM is not configured at 1st boot */
+#if defined(MV_NO_PRINT)
+	return MV_OK;
+#endif
+
 	topologyUpdateInfo.mvUpdateWidth = MV_FALSE;
 	topologyUpdateInfo.mvUpdateECC = MV_FALSE;
 	topologyUpdateInfo.mvUpdateECCPup3Mode = MV_FALSE;
@@ -807,15 +840,52 @@
 static MV_STATUS ddr3HwsTuneTrainingParams(MV_U8 devNum)
 {
 	MV_TUNE_TRAINING_PARAMS params;
+	MV_U32 interfaceId;
+	MV_U32 csNum;
 	MV_STATUS status;
 
+	/* initilaize the global ddr topology */
+	CHECK_STATUS(ddr3GetTopologyMap(&topologyMap));
+
+	/* get first active interface */
+	CHECK_STATUS(ddr3TipGetFirstActiveIf(devNum, topologyMap->interfaceActiveMask, &interfaceId));
+
+	CHECK_STATUS(mvCalcCsNum(devNum, interfaceId, &csNum));
+
 	/*NOTE: do not remove any field initilization*/
 	params.ckDelay = MV_TUNE_TRAINING_PARAMS_CK_DELAY;
-	params.ckDelay_16 = MV_TUNE_TRAINING_PARAMS_CK_DELAY_16;
-	params.Pfinger = MV_TUNE_TRAINING_PARAMS_PFINGER;
-	params.Nfinger = MV_TUNE_TRAINING_PARAMS_NFINGER;
 	params.PhyReg3Val = MV_TUNE_TRAINING_PARAMS_PHYREG3VAL;
 
+	params.gZpriData = MV_TUNE_TRAINING_PARAMS_PRI_DATA;
+	params.gZnriData = MV_TUNE_TRAINING_PARAMS_NRI_DATA;
+	params.gZpriCtrl = MV_TUNE_TRAINING_PARAMS_PRI_CTRL;
+	params.gZnriCtrl = MV_TUNE_TRAINING_PARAMS_NRI_CTRL;
+
+	params.gZpodtData = MV_TUNE_TRAINING_PARAMS_P_ODT_DATA;
+	params.gZnodtData = MV_TUNE_TRAINING_PARAMS_N_ODT_DATA;
+	params.gZpodtCtrl = MV_TUNE_TRAINING_PARAMS_P_ODT_CTRL;
+	params.gZnodtCtrl = MV_TUNE_TRAINING_PARAMS_N_ODT_CTRL;
+
+	params.gDic = MV_TUNE_TRAINING_PARAMS_DIC;
+	params.gRttNom = MV_TUNE_TRAINING_PARAMS_RTT_NOM;
+
+#ifdef CONFIG_DDR3
+	if (csNum == 1) {
+		params.gRttWR = MV_TUNE_TRAINING_PARAMS_RTT_WR_1CS;
+		params.uiODTConfig = MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS;
+	} else {
+		params.gRttWR = MV_TUNE_TRAINING_PARAMS_RTT_WR_2CS;
+		params.uiODTConfig = MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS;
+	}
+#else /* CONFIG_DDR3 */
+	/* DDR4 */
+	params.gZpodtData = MV_TUNE_TRAINING_PARAMS_P_ODT_DATA_DDR4;
+	params.uiODTConfig = MV_TUNE_TRAINING_PARAMS_ODT_CONFIG_DDR4;
+	params.gRttNom = MV_TUNE_TRAINING_PARAMS_RTT_NOM_DDR4;
+	params.gRttWR =  MV_TUNE_TRAINING_PARAMS_RTT_WR;
+	params.gDic = MV_TUNE_TRAINING_PARAMS_DIC_DDR4;
+#endif
+
 	status = ddr3TipTuneTrainingParams(devNum, &params);
 	if (MV_OK != status) {
 		mvPrintf("%s Training Sequence - FAILED\n", ddrType);
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/.gitignore b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/.gitignore
index a43fafc..63dab12 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/.gitignore
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/.gitignore
@@ -1,2 +1,3 @@
 *.rej
-
+*.o
+src/Driver/ddr4/
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile
new file mode 100755
index 0000000..a43c981
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile
@@ -0,0 +1,155 @@
+#;/*******************************************************************************
+#;Copyright (C) Marvell International Ltd. and its affiliates
+#;
+#;This software file (the "File") is owned and distributed by Marvell
+#;International Ltd. and/or its affiliates ("Marvell") under the following
+#;alternative licensing terms.  Once you have made an election to distribute the
+#;File under one of the following license alternatives, please (i) delete this
+#;introductory statement regarding license alternatives, (ii) delete the two
+#;license alternatives that you have not elected to use and (iii) preserve the
+#;Marvell copyright notice above.
+#;
+#;********************************************************************************
+#;Marvell Commercial License Option
+#;
+#;If you received this File from Marvell and you have entered into a commercial
+#;license agreement (a "Commercial License") with Marvell, the File is licensed
+#;to you under the terms of the applicable Commercial License.
+#;
+#;********************************************************************************
+#;Marvell GPL License Option
+#;
+#;If you received this File from Marvell, you may opt to use, redistribute and/or
+#;modify this File in accordance with the terms and conditions of the General
+#;Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+#;available along with the File in the license.txt file or by writing to the Free
+#;Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+#;on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+#;
+#;THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+#;WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+#;DISCLAIMED.  The GPL License provides additional details about this warranty
+#;disclaimer.
+#;********************************************************************************
+#;Marvell BSD License Option
+#;
+#;If you received this File from Marvell, you may opt to use, redistribute and/or
+#;modify this File under the following licensing terms.
+#;Redistribution and use in source and binary forms, with or without modification,
+#;are permitted provided that the following conditions are met:
+#;
+#;   *   Redistributions of source code must retain the above copyright notice,
+#;	    this list of conditions and the following disclaimer.
+#;
+#;    *   Redistributions in binary form must reproduce the above copyright
+#;        notice, this list of conditions and the following disclaimer in the
+#;        documentation and/or other materials provided with the distribution.
+#;
+#;    ;*   Neither the name of Marvell nor the names of its contributors may be
+#;        used to endorse or promote products derived from this software without
+#;        specific prior written permission.
+#;
+#;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+#;
+#;*******************************************************************************/
+#.SECONDARY:
+
+include ../../base.mk
+
+TIP_INC = $(BH_ROOT_DIR)/src_ddr/ddr3libv2/h
+
+INCLUDE = -I$(TIP_INC)/Os -I$(TIP_INC)/Os/gtOs -I$(TIP_INC)/Os/common/siliconIf \
+	  -I$(TIP_INC)/SoC -I$(TIP_INC)/Silicon -I$(TIP_INC)/Os/common/configElementDb \
+	  -I$(TIP_INC)/Driver -I$(TIP_INC)/Driver/ddr3  -I$(BH_ROOT_DIR)/inc/common -I$(BH_ROOT_DIR)/inc/common/gtOs\
+	  -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(BOARD) -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(INCNAME) \
+	  -I$(BH_ROOT_DIR)/src_ddr  -I$(BH_ROOT_DIR)/platform/sysEnv/$(BOARD)
+
+ifeq ($(DDRTYPE),ddr4)
+	INCLUDE += -I$(BH_ROOT_DIR)/src_ddr/ddr3libv2/src/Driver/ddr4/h
+endif
+
+TGT = ddr_$(LIBNAME).a
+TGT_UART = ddr_$(LIBNAME).uart.a
+
+TLIB = ./$(DDRTYPE)_training_$(LIBNAME).lib
+
+TDDR4SUBLIB = ./$(DDRTYPE)_training_$(LIBNAME)sub.lib
+
+TSRC = $(wildcard ./src/Driver/ddr3/*.c)
+TSRC += ./src/Silicon/mvHwsDdr3$(SILNAME).c
+ifeq "$(BOARD)"  "msys"
+	TSRC += ./src/Silicon/mvHwsDdr3Msys.c
+endif
+TSRC += ./src/Soc/ddr3_$(BOARDNAME)_training.c
+TSRC += ./src/Soc/ddr3_hws_hw_training.c
+TSRC += ./src/Os/gtOs/mvXor.c
+
+
+TSRCDDR4 = $(wildcard ./src/Driver/ddr4/src/*.c)
+
+TOBJ = $(TSRC:.c=.o)
+TOBJDDR4 = $(TSRCDDR4:.c=.o)
+
+ifeq ($(DDR4SUBLIB),yes)
+	TARGETS = $(TLIB) $(TDDR4SUBLIB)
+else
+	TARGETS = $(TLIB)
+endif
+
+
+#############global flags enable/disable features to save footprint###########
+# exclude debug function not relevent for SoC( set by default)
+CFLAGS += -DEXCLUDE_SWITCH_DEBUG -DDDR_VIEWER_TOOL
+ifeq "$(CONFIG_BOBCAT2)"  "y"
+CFLAGS += -DMV_HWS_EXCLUDE_DEBUG_PRINTS
+endif
+#remove all debug prints from training( unset by default)
+#CFLAGS += -DSILENT_LIB
+CFLAGS += -DLIB_FUNCTIONAL_DEBUG_ONLY
+
+#Flag to support static training algo functions( unset by default)
+ifeq ($(BOARD),a38x)
+ #CFLAGS += -DSTATIC_ALGO_SUPPORT
+else
+CFLAGS += -DSTATIC_ALGO_SUPPORT
+endif
+#flag to support ODT test debug function( unset by default)
+#CFLAGS += -DODT_TEST_SUPPORT
+
+# Flag to enable RX IO BIST Test
+# CFLAGS += -DMV_HWS_RX_IO_BIST
+# Flag enable IO BIST of CMD/ADDR Test (in addition to MV_HWS_RX_IO_BIST)
+# CFLAGS += -DMV_HWS_RX_IO_BIST_ETP
+
+#############end of global flags #############################################
+
+
+all:   $(TARGETS)
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+
+%.uart.o: %.c
+	$(CC) $(CFLAGS) -DNOT_USE_UART -DMV_NO_INPUT -DMV_NO_PRINT  $(CPPFLAGS) -c -o  $@ $<
+
+$(TDDR4SUBLIB): $(TOBJDDR4)
+	$(RM) ./$@
+	ar rcs $(TDDR4SUBLIB) $(TOBJDDR4)
+	$(CP) ./$@ ../lib
+
+$(TLIB): $(TOBJ)
+	$(RM) ./$@
+	ar rcs $(TLIB) $(TOBJ)
+	$(CP) ./$@ ../lib
+
+clean:
+	$(RM) ./*.o  ./*.a
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/gtBuild b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/gtBuild
new file mode 100755
index 0000000..5656244
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/gtBuild
@@ -0,0 +1,31 @@
+
+## VIPS compilation environment #################
+ifeq (VIPS, $(HOME_ENV))
+
+#INCLUDE_PATH =
+#C_FILE_LIST  =
+#SUBDIRS      =
+#C_EXCLUDE_FILE_LIST =
+
+
+##################################################
+##################################################
+ROOT_DIR = $(subst \,/,$(SW_ROOT))
+include $(ROOT_DIR)/mainLabServices/gtBuild
+
+##################################################
+
+else
+
+## CPSS compilation environment #################
+#INCLUDE_PATH =
+#C_FILE_LIST  =
+#SUBDIRS      =
+#C_EXCLUDE_FILE_LIST =
+
+CFLAGS += -DCONFIG_DDR3
+
+##################################################
+##################################################
+include $(PROJ_BASE)/gtTopMake
+endif
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIp.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIp.h
index 4cdfcf2..eba88b7 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIp.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIp.h
@@ -52,9 +52,9 @@
 #endif
 
 #ifdef CONFIG_DDR4
-#define DDR3_TIP_VERSION_STRING "DDR4 Training Sequence - Ver TIP-0.7."
+#define DDR3_TIP_VERSION_STRING "DDR4 Training Sequence - Ver TIP-0.22."
 #else
-#define DDR3_TIP_VERSION_STRING "DDR3 Training Sequence - Ver TIP-1.29."
+#define DDR3_TIP_VERSION_STRING "DDR3 Training Sequence - Ver TIP-1.46."
 #endif
 
 #define MAX_CS_NUM         (4)
@@ -320,19 +320,32 @@
 */
 
 GT_STATUS    mvHwsDdr3TipRunAlg
-( 
+(
     GT_U32              devNum,
     MV_HWS_ALGO_TYPE    algoType
 );
 
+/*****************************************************************************
+Get DDR version
+******************************************************************************/
+/******************************************************************************
+* Name:     mvHwsDdr3TipVersionGet
+* Desc:     Return DDR version string
+* Args:
+*
+*
+* Notes:
+* Returns:  OK if success, other error code if fail.
+*/
+const GT_CHAR* mvHwsDdr3TipVersionGet(void);
 
 /******************************************************************************
 * Name:     mvHwsDdr3TipModeRead.
 * Desc:     read Mode registers
-* Args:     devNum - channel ID 
+* Args:     devNum - Device number
 *           modeInfo - pointer to mode info struct
 *
-* Notes:    
+* Notes:
 * Returns:  OK if success, other error code if fail.
 */
 GT_STATUS    mvHwsDdr3TipModeRead
@@ -347,7 +360,7 @@
 * Args:     devNum
 *           result
 *
-* Notes:    
+* Notes:
 * Returns:  OK if success, other error code if fail.
 */
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpBist.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpBist.h
index f3d5ffa..db5c8ac 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpBist.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpBist.h
@@ -158,6 +158,13 @@
     GT_U32 mode
 );
 
+GT_BOOL ddr3TipRunLevelingSweepTest
+(
+    GT_32 devNum,
+    GT_U32 RepeatNum,
+    GT_U32 direction,
+    GT_U32 mode
+);
 /******************************************************************************
 * Name:     ddr3TipPrintRegs.
 * Desc:     Print Specified Dunit/Pup Registers
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDb.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDb.h
index cba3d2a..139597f 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDb.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDb.h
@@ -1,81 +1,2 @@
-/******************************************************************************
-*              Copyright (c) Marvell International Ltd. and its affiliates
-*
-* This software file (the "File") is owned and distributed by Marvell
-* International Ltd. and/or its affiliates ("Marvell") under the following
-* alternative licensing terms.
-* If you received this File from Marvell, you may opt to use, redistribute
-* and/or modify this File under the following licensing terms.
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-*  -   Redistributions of source code must retain the above copyright notice,
-*       this list of conditions and the following disclaimer.
-*  -   Redistributions in binary form must reproduce the above copyright
-*       notice, this list of conditions and the following disclaimer in the
-*       documentation and/or other materials provided with the distribution.
-*  -    Neither the name of Marvell nor the names of its contributors may be
-*       used to endorse or promote products derived from this software without
-*       specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
-*******************************************************************************
-* mvDdr3TrainingIpDb.h
-*
-* DESCRIPTION:
-*
-*
-* FILE REVISION NUMBER:
-*       $Revision: 3 $
-*
-*******************************************************************************/
-
-#ifndef _MV_DDR3_TRAININGIP_DB_H_
-#define _MV_DDR3_TRAININGIP_DB_H_
-
-#ifdef __cplusplus
-   extern "C"
-   {
-#endif
-
-typedef enum
-{
-   PATTERN_PBS1,
-   PATTERN_PBS2,
-   PATTERN_RL,
-   PATTERN_STATIC_PBS,
-   PATTERN_KILLER_DQ0,
-   PATTERN_KILLER_DQ1,
-   PATTERN_KILLER_DQ2,
-   PATTERN_KILLER_DQ3,
-   PATTERN_KILLER_DQ4,
-   PATTERN_KILLER_DQ5,
-   PATTERN_KILLER_DQ6,
-   PATTERN_KILLER_DQ7,
-   PATTERN_PBS3,
-   PATTERN_RL2,
-   PATTERN_TEST,
-   PATTERN_FULL_SSO0,
-   PATTERN_FULL_SSO1,
-   PATTERN_FULL_SSO2,
-   PATTERN_FULL_SSO3,
-   PATTERN_VREF,
-   PATTERN_LIMIT
-}MV_HWS_PATTERN;
-
-#ifdef __cplusplus
-   }
-#endif
-
-#endif /* _MV_DDR3_TRAININGIP_DB_H_ */
 
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDef.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDef.h
index be53af8..2746fad 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDef.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpDef.h
@@ -46,6 +46,10 @@
 #include "common/siliconIf/mvSiliconIf.h"
 
 #if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
+#define CPSS_BUILD
+#endif
+
+#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
 #define osMemCpy	hwsOsMemCopyFuncPtr
 #else
 #include <gtOs/gtOsMem.h>
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpEngine.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpEngine.h
index 7663517..458323e 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpEngine.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpEngine.h
@@ -121,21 +121,6 @@
 );
 
 /******************************************************************************
-* Name:     ddr3TipLoadPatternToMemByCpu.
-* Desc:     Load expected Pattern to external memory
-* Args:
-* Notes:
-* Returns:  OK if success, other error code if fail.
-*/
-GT_STATUS    ddr3TipLoadPatternToMemByCpu
-(
-    GT_U32          devNum,
-    MV_HWS_PATTERN  pattern,
-    GT_U32          offset
-);
-
-
-/******************************************************************************
 * load pattern to memory using ODPG
 */
 GT_STATUS    ddr3TipLoadAllPatternToMem
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpFlow.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpFlow.h
index 3ddf76e..cec7712 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpFlow.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpFlow.h
@@ -47,9 +47,6 @@
 
 #include "mvDdr3TrainingIp.h"
 #include "mvDdr3TrainingIpPbs.h"
-#ifdef CONFIG_DDR4
-#include "mvDdr4TrainingIpFlow.h"
-#endif
 
 #ifdef __cplusplus
    extern "C"
@@ -86,10 +83,9 @@
 #define PATTERN_MAXIMUM_LENGTH (64)
 #define EXT_ACCESS_BURST_LENGTH (8)
 #define  CHIP_ID                0
-#define IS_INTERFACE_ACTIVE( _uiInterfaceMask_ , _uiInterfaceId_ )   ( _uiInterfaceMask_ & ( 1 << _uiInterfaceId_ ) ) 
-#define IS_BUS_ACTIVE( _uiInterfaceMask_ , _uiInterfaceId_ )   ( _uiInterfaceMask_ & ( 1 << _uiInterfaceId_ ) ) 
-#define GET_TOPOLOGY_NUM_OF_BUSES(devNum)   (ddr3TipGetTopologyMap(devNum)->numOfBusPerInterface)
-
+#define IS_INTERFACE_ACTIVE( _uiInterfaceMask_ , _uiInterfaceId_ )   ( _uiInterfaceMask_ & ( 1 << _uiInterfaceId_ ) )
+#define IS_BUS_ACTIVE( _uiInterfaceMask_ , _uiInterfaceId_ )   ( (_uiInterfaceMask_ >> _uiInterfaceId_) & 1 )
+       /*Haim ( _uiInterfaceMask_ & ( 1 << _uiInterfaceId_ ) )*/  
 #define DDR3_IS_ECC_PUP3_MODE(_uiInterfaceMask_)	((_uiInterfaceMask_ == 0xB)?(GT_TRUE):(GT_FALSE))
 #define DDR3_IS_ECC_PUP4_MODE(_uiInterfaceMask_)	((((_uiInterfaceMask_ & 0x10) == 0))?(GT_FALSE):(GT_TRUE))
 #define DDR3_IS_16BIT_DRAM_MODE(_activeBusMask_)	((((_activeBusMask_ & 0x4) == 0))?(GT_TRUE):(GT_FALSE))
@@ -135,17 +131,16 @@
 #define  DISABLE_DDR_TUNING_DATA          (0x02294285)
 #define  ENABLE_DDR_TUNING_DATA           (0x12294285)
 
-
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
+#if !defined(CPSS_BUILD) && !defined(CONFIG_BOBCAT2)
 #define ODPG_TRAINING_STATUS_REG          (0x18488)
-#define ODPG_TRAINING_TRIGGER_REG         (0x1030)
-#define ODPG_STATUS_DONE_REG         	  (0x16FC)
-#define ODPG_ENABLE_REG                   (0x186D4)//KW28
-#define ODPG_ENABLE_OFFS                  (0)
-#define ODPG_DISABLE_OFFS                 (8)
 #else
 #define ODPG_TRAINING_STATUS_REG          (0x1030)
 #endif
+#define ODPG_TRAINING_TRIGGER_REG         (0x1030)
+#define ODPG_STATUS_DONE_REG         	  (0x16FC)
+#define ODPG_ENABLE_REG                   (0x186D4)
+#define ODPG_ENABLE_OFFS                  (0)
+#define ODPG_DISABLE_OFFS                 (8)
 
 #define ODPG_TRAINING_CONTROL_REG         (0x1034)
 #define ODPG_OBJ1_OPCODE_REG              (0x103C)
@@ -210,21 +205,22 @@
 #define CS_ENABLE_REG                     (0x16D8)
 #define WR_LEVELING_DQS_PATTERN_REG       (0x16DC)
 
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
+#if !defined(CPSS_BUILD) && !defined(CONFIG_BOBCAT2)
 #define ODPG_BIST_DONE                    (0x186D4)
-#define ODPG_BIST_DONE_BIT_OFFS           (0)
-#define ODPG_BIST_DONE_BIT_VALUE          (0)
 #else
 #define ODPG_BIST_DONE                    (0x16FC)
 #endif
+#define ODPG_BIST_DONE_BIT_OFFS           (0)
+#define ODPG_BIST_DONE_BIT_VALUE_REV2          (1)
+#define ODPG_BIST_DONE_BIT_VALUE_REV3          (0)
 
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
+#if !defined(CPSS_BUILD) && !defined(CONFIG_BOBCAT2)
 #define RESULT_CONTROL_BYTE_PUP_0_REG     (0x1830)
 #define RESULT_CONTROL_BYTE_PUP_1_REG     (0x1834)
 #define RESULT_CONTROL_BYTE_PUP_2_REG     (0x1838)
 #define RESULT_CONTROL_BYTE_PUP_3_REG     (0x183C)
 #define RESULT_CONTROL_BYTE_PUP_4_REG     (0x18B0)
-										  
+
 #define RESULT_CONTROL_PUP_0_BIT_0_REG    (0x18B4)
 #define RESULT_CONTROL_PUP_0_BIT_1_REG    (0x18B8)
 #define RESULT_CONTROL_PUP_0_BIT_2_REG    (0x18BC)
@@ -377,12 +373,27 @@
 #define PHASE_REG_OFFSET   (32)
 #define NUM_BYTES_IN_BURST (31)
 #define NUM_OF_CS          (4)
-#define CS_REG_VALUE(csNum)   (csMaskReg[csNum])
+#define CS_BYTE_GAP(csNum)   (csNum*0x4)
+#define CS_PBS_GAP(csNum)   (csNum*0x10)
 #define ADLL_LENGTH (32)
 
+#ifdef CONFIG_DDR4
+/* DDR4 MRS */
+#define MRS4_CMD (0x10)
+#define MRS5_CMD (0X11)
+#define MRS6_CMD (0X12)
 
-/************************* Enums ***********************************************/
-
+/* DDR4 Registers */
+#define DDR4_MR0_REG                      (0x1900)
+#define DDR4_MR1_REG                      (0x1904)
+#define DDR4_MR2_REG                      (0x1908)
+#define DDR4_MR3_REG                      (0x190C)
+#define DDR4_MR4_REG                      (0x1910)
+#define DDR4_MR5_REG                      (0x1914)
+#define DDR4_MR6_REG                      (0x1918)
+#define DDR4_MPR_WR_REG                   (0x19D0)
+#define DRAM_PINS_MUX_REG                 (0x19D4)
+#endif
 
 
 /************************* Structures ***********************************************/
@@ -403,6 +414,56 @@
       /* Mask used in register */
 }PageElement;
 
+#ifdef CONFIG_DDR4
+/******************************************************************************
+* Name:     ddr4TipDynamicWriteLevelingSupp
+* Desc:     Write leveling phase correction
+* Args:     devNum - device number
+*
+* Notes:
+* Returns:  OK if success, other error code if fail.
+*/
+GT_STATUS ddr4TipDynamicWriteLevelingSupp
+(
+	GT_U32 devNum
+);
+
+GT_STATUS    ddr4TipConfigurePhy
+(
+    GT_U32    devNum
+);
+
+GT_STATUS ddr4TipSetTiming
+(
+    GT_U32				    devNum,
+    MV_HWS_ACCESS_TYPE      accessType,
+    GT_U32					interfaceId,
+    MV_HWS_DDR_FREQ			frequency
+);
+
+GT_STATUS ddr4ModeRegsInit
+(
+    GT_U8 devNum
+);
+
+GT_STATUS ddr4SdramConfig
+(
+    GT_U32 devNum
+);
+
+GT_STATUS    ddr4TipCalibrationAdjust
+(
+    GT_U32		devNum,
+	GT_U8		Vref_en,
+	GT_U8		POD_Only
+);
+
+GT_STATUS ddr3TipDDR4Ddr4TrainingMainFlow
+(
+    GT_U32 devNum
+);
+
+#endif
 
 /******************************************************************************
 * Name:     ddr3TipWriteLevelingStaticConfig.
@@ -879,11 +940,11 @@
 
 GT_STATUS    ddr3TipResetFifoPtr(GT_U32 devNum);
 
-GT_BOOL readPupValue(GT_32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask);
+GT_BOOL mvHwsDdr3TipReadPupValue(GT_U32 devNum, GT_32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask);
 
-GT_BOOL readAdllValue(GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask);
+GT_BOOL mvHwsDdr3TipReadAdllValue(GT_U32 devNum,GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask);
 
-GT_BOOL writeAdllValue(GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr);
+GT_BOOL mvHwsDdr3TipWriteAdllValue(GT_U32 devNum,GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr);
 
 
 /******************************************************************************
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpPrvIf.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpPrvIf.h
index 0f46c81..8607b47 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpPrvIf.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingIpPrvIf.h
@@ -295,6 +295,11 @@
 	GT_U8    devNum
 );
 
+typedef GT_U8 (*MV_HWS_TRAINING_IP_GET_RATIO)
+(
+	GT_U32    freq
+);
+
 
 /******************************** Functions Strut ***************************************/
 typedef struct
@@ -307,6 +312,10 @@
     MV_HWS_SET_FREQ_DIVIDER_FUNC_PTR        tipSetFreqDividerFunc;
     MV_HWS_GET_CS_CONFIG_FUNC_PTR           tipGetCsConfigInfo;
 	MV_HWS_TRAINING_IP_GET_TEMP				tipGetTemperature;
+	MV_HWS_TRAINING_IP_GET_RATIO			tipGetClockRatio;
+    MV_HWS_TRAINING_IP_EXTERNAL_READ_PTR	tipExternalRead;
+    MV_HWS_TRAINING_IP_EXTERNAL_WRITE_PTR	tipExternalWrite;
+
 } MV_HWS_TIP_CONFIG_FUNC_DB;
 
 
@@ -332,7 +341,6 @@
 
 }MV_HWS_TRAINING_IP_FUNC_PTRS;
 
-
 /******************************** declarations ***************************************/
 
 /*******************************************************************************
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingLeveling.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingLeveling.h
index c6682f2..8de6e9e 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingLeveling.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/ddr3/mvDdr3TrainingLeveling.h
@@ -65,7 +65,7 @@
 );
 
 
-GT_U32 mvHwsDdr3TipMaxCSGet(void);
+GT_U32 mvHwsDdr3TipMaxCSGet(GT_U32 devNum);
 
 #ifdef __cplusplus
    }
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTopologyDef.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTopologyDef.h
index 679dae3..7679aa3 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTopologyDef.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTopologyDef.h
@@ -1,4 +1,5 @@
 
+
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -68,26 +69,143 @@
 #include "mvDdr3TrainingIpDef.h"
 
 #ifdef CONFIG_DDR3
-#include "mvDdr3TopologyDef.h"
+typedef enum
+{
+   SPEED_BIN_DDR_800D,
+   SPEED_BIN_DDR_800E,
+   SPEED_BIN_DDR_1066E,
+   SPEED_BIN_DDR_1066F,
+   SPEED_BIN_DDR_1066G,
+   SPEED_BIN_DDR_1333F,
+   SPEED_BIN_DDR_1333G,
+   SPEED_BIN_DDR_1333H,
+   SPEED_BIN_DDR_1333J,
+   SPEED_BIN_DDR_1600G,
+   SPEED_BIN_DDR_1600H,
+   SPEED_BIN_DDR_1600J,
+   SPEED_BIN_DDR_1600K,
+   SPEED_BIN_DDR_1866J,
+   SPEED_BIN_DDR_1866K,
+   SPEED_BIN_DDR_1866L,
+   SPEED_BIN_DDR_1866M,
+   SPEED_BIN_DDR_2133K,
+   SPEED_BIN_DDR_2133L,
+   SPEED_BIN_DDR_2133M,
+   SPEED_BIN_DDR_2133N,
+
+   SPEED_BIN_DDR_1333H_EXT,
+   SPEED_BIN_DDR_1600K_EXT,
+   SPEED_BIN_DDR_1866M_EXT
+}MV_HWS_SPEED_BIN;
+
+typedef enum 
+{
+  DDR_FREQ_LOW_FREQ,
+  DDR_FREQ_400,
+  DDR_FREQ_533,
+  DDR_FREQ_667,
+  DDR_FREQ_800,
+  DDR_FREQ_933,
+  DDR_FREQ_1066,
+  DDR_FREQ_311,
+  DDR_FREQ_333,
+  DDR_FREQ_467,
+  DDR_FREQ_850,
+  DDR_FREQ_600,
+  DDR_FREQ_300,
+  DDR_FREQ_900,
+  DDR_FREQ_360,
+  DDR_FREQ_1000,
+   DDR_FREQ_LIMIT
+}MV_HWS_DDR_FREQ;
+
+typedef enum
+{
+    speedBinTableElements_tRCD,
+    speedBinTableElements_tRP,
+    speedBinTableElements_tRAS,
+    speedBinTableElements_tRC,
+    speedBinTableElements_tRRD1K,
+    speedBinTableElements_tRRD2K,
+    speedBinTableElements_tPD,
+    speedBinTableElements_tFAW1K,
+    speedBinTableElements_tFAW2K,
+    speedBinTableElements_tWTR,
+    speedBinTableElements_tRTP,
+    speedBinTableElements_tWR,
+    speedBinTableElements_tMOD
+}speedBinTableElements;
+
 #elif defined(CONFIG_DDR4)
-#include "mvDdr4TopologyDef.h"
+
+typedef enum
+{
+    SPEED_BIN_DDR_1600J,
+    SPEED_BIN_DDR_1600K,
+    SPEED_BIN_DDR_1600L,
+    SPEED_BIN_DDR_1866L,
+    SPEED_BIN_DDR_1866M,
+    SPEED_BIN_DDR_1866N,
+    SPEED_BIN_DDR_2133N,
+    SPEED_BIN_DDR_2133P,
+    SPEED_BIN_DDR_2133R,
+    SPEED_BIN_DDR_2400P,
+    SPEED_BIN_DDR_2400R,
+    SPEED_BIN_DDR_2400U,
+}MV_HWS_SPEED_BIN;
+
+typedef enum 
+{
+    DDR_FREQ_LOW_FREQ,
+    DDR_FREQ_667,
+    DDR_FREQ_800,
+    DDR_FREQ_933,
+    DDR_FREQ_1066,
+	DDR_FREQ_900,
+	DDR_FREQ_1000,
+    DDR_FREQ_LIMIT
+}MV_HWS_DDR_FREQ;
+
+typedef enum
+{
+    speedBinTableElements_tRCD,
+    speedBinTableElements_tRP,
+    speedBinTableElements_tRAS,
+    speedBinTableElements_tRC,
+    speedBinTableElements_tRRD0_5K,
+    speedBinTableElements_tRRD1K,
+    speedBinTableElements_tRRD2K,
+    speedBinTableElements_tRRDL0_5K,
+    speedBinTableElements_tRRDL1K,
+    speedBinTableElements_tRRDL2K,
+    speedBinTableElements_tPD,
+    speedBinTableElements_tFAW0_5K,
+    speedBinTableElements_tFAW1K,
+    speedBinTableElements_tFAW2K,
+    speedBinTableElements_tWTR,
+    speedBinTableElements_tWTRL,
+    speedBinTableElements_tRTP,
+    speedBinTableElements_tWR,
+    speedBinTableElements_tMOD
+}speedBinTableElements;
+
 #else
 # error "CONFIG_DDR3 or CONFIG_DDR4 must be defined !!!"
 #endif
 
 /************************* Definitions *******************************************/
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
-#define MAX_INTERFACE_NUM  		(1)
-#define MAX_BUS_NUM        		(5)
+#if defined(CONFIG_BOBK) || defined(CONFIG_BOBCAT2) || (defined(CHX_FAMILY) || defined(EXMXPM_FAMILY))
+#define MAX_INTERFACE_NUM  		(5)
 #else
-#define MAX_INTERFACE_NUM  		(12)
-#define MAX_BUS_NUM        		(8)
+#define MAX_INTERFACE_NUM  		(1)
 #endif
 
-#define SDRAM_CS_SIZE							0xFFFFFFF
+#define MAX_BUS_NUM        		(5)
+
+#define SDRAM_CS_SIZE				0xFFFFFFF
+#define MV_PARAMS_UNDEFINED 		0xFFFFFFFF
 /************************* Topology *******************************************/
-#define SDRAM_CS_SIZE							0xFFFFFFF
 
 /* bus width in bits */
 typedef enum
@@ -171,9 +289,6 @@
    /* Controller configuration per interface */
    InterfaceParams      interfaceParams[MAX_INTERFACE_NUM];
 
-   /* BUS per interface (default is 4)*/
-   GT_U8               numOfBusPerInterface;
-
    /* Bit mask for active buses*/
    GT_U8               activeBusMask;
 
@@ -184,10 +299,20 @@
 typedef struct
 {
 	GT_U32	ckDelay;
-	GT_U32	ckDelay_16;
-	GT_U32	Pfinger;
-	GT_U32	Nfinger;
 	GT_U32	PhyReg3Val;
+
+	GT_U32 gZpriData;
+	GT_U32 gZnriData;
+	GT_U32 gZpriCtrl;
+	GT_U32 gZnriCtrl;
+	GT_U32 gZpodtData;
+	GT_U32 gZnodtData;
+	GT_U32 gZpodtCtrl;
+	GT_U32 gZnodtCtrl;
+	GT_U32 gDic;
+	GT_U32 uiODTConfig;
+	GT_U32 gRttNom;
+	GT_U32 gRttWR;
 } GT_TUNE_TRAINING_PARAMS;
 
 #endif /* _DDR_TOPOLOGY_CONFIG_H */
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTrainingIpDb.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTrainingIpDb.h
index 4c947dd..dd7860a 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTrainingIpDb.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Driver/mvDdrTrainingIpDb.h
@@ -47,9 +47,107 @@
 
 #include "mvDdrTopologyDef.h"
 #ifdef CONFIG_DDR3
-#include "mvDdr3TrainingIpDb.h"
+typedef enum
+{
+   PATTERN_PBS1,
+   PATTERN_PBS2,
+   PATTERN_PBS3,
+   PATTERN_TEST,
+   PATTERN_RL,
+   PATTERN_RL2,
+   PATTERN_STATIC_PBS,
+   PATTERN_KILLER_DQ0,
+   PATTERN_KILLER_DQ1,
+   PATTERN_KILLER_DQ2,
+   PATTERN_KILLER_DQ3,
+   PATTERN_KILLER_DQ4,
+   PATTERN_KILLER_DQ5,
+   PATTERN_KILLER_DQ6,
+   PATTERN_KILLER_DQ7,
+   PATTERN_VREF,
+   PATTERN_FULL_SSO0,
+   PATTERN_FULL_SSO1,
+   PATTERN_FULL_SSO2,
+   PATTERN_FULL_SSO3,
+   PATTERN_SSO_FULL_XTALK_DQ0,
+   PATTERN_SSO_FULL_XTALK_DQ1,
+   PATTERN_SSO_FULL_XTALK_DQ2,
+   PATTERN_SSO_FULL_XTALK_DQ3,
+   PATTERN_SSO_FULL_XTALK_DQ4,
+   PATTERN_SSO_FULL_XTALK_DQ5,
+   PATTERN_SSO_FULL_XTALK_DQ6,
+   PATTERN_SSO_FULL_XTALK_DQ7,
+   PATTERN_SSO_XTALK_FREE_DQ0,
+   PATTERN_SSO_XTALK_FREE_DQ1,
+   PATTERN_SSO_XTALK_FREE_DQ2,
+   PATTERN_SSO_XTALK_FREE_DQ3,
+   PATTERN_SSO_XTALK_FREE_DQ4,
+   PATTERN_SSO_XTALK_FREE_DQ5,
+   PATTERN_SSO_XTALK_FREE_DQ6,
+   PATTERN_SSO_XTALK_FREE_DQ7,
+   PATTERN_ISI_XTALK_FREE,
+   PATTERN_LIMIT
+} MV_HWS_PATTERN;
 #elif defined(CONFIG_DDR4)
-#include "mvDdr4TrainingIpDb.h"
+typedef enum
+{
+   PATTERN_PBS1,/*0*/
+   PATTERN_PBS2,
+   PATTERN_PBS3,
+   PATTERN_TEST,
+   PATTERN_RL,
+   PATTERN_RL2,
+   PATTERN_STATIC_PBS,
+   PATTERN_KILLER_DQ0,
+   PATTERN_KILLER_DQ1,
+   PATTERN_KILLER_DQ2,
+   PATTERN_KILLER_DQ3,/*10*/
+   PATTERN_KILLER_DQ4,
+   PATTERN_KILLER_DQ5,
+   PATTERN_KILLER_DQ6,
+   PATTERN_KILLER_DQ7,
+   PATTERN_KILLER_DQ0_INV,
+   PATTERN_KILLER_DQ1_INV,
+   PATTERN_KILLER_DQ2_INV,
+   PATTERN_KILLER_DQ3_INV,
+   PATTERN_KILLER_DQ4_INV,
+   PATTERN_KILLER_DQ5_INV,/*20*/
+   PATTERN_KILLER_DQ6_INV,
+   PATTERN_KILLER_DQ7_INV,
+   PATTERN_VREF,
+   PATTERN_VREF_INV,
+   PATTERN_FULL_SSO0,
+   PATTERN_FULL_SSO1,
+   PATTERN_FULL_SSO2,
+   PATTERN_FULL_SSO3,
+   PATTERN_SSO_FULL_XTALK_DQ0,
+   PATTERN_SSO_FULL_XTALK_DQ1,/*30*/
+   PATTERN_SSO_FULL_XTALK_DQ2,
+   PATTERN_SSO_FULL_XTALK_DQ3,
+   PATTERN_SSO_FULL_XTALK_DQ4,
+   PATTERN_SSO_FULL_XTALK_DQ5,
+   PATTERN_SSO_FULL_XTALK_DQ6,
+   PATTERN_SSO_FULL_XTALK_DQ7,
+   PATTERN_SSO_XTALK_FREE_DQ0,
+   PATTERN_SSO_XTALK_FREE_DQ1,
+   PATTERN_SSO_XTALK_FREE_DQ2,
+   PATTERN_SSO_XTALK_FREE_DQ3,/*40*/
+   PATTERN_SSO_XTALK_FREE_DQ4,
+   PATTERN_SSO_XTALK_FREE_DQ5,
+   PATTERN_SSO_XTALK_FREE_DQ6,
+   PATTERN_SSO_XTALK_FREE_DQ7,
+   PATTERN_ISI_XTALK_FREE,
+   PATTERN_RESONANCE_1T,
+   PATTERN_RESONANCE_2T,
+   PATTERN_RESONANCE_3T,
+   PATTERN_RESONANCE_4T,
+   PATTERN_RESONANCE_5T,/*50*/
+   PATTERN_RESONANCE_6T,
+   PATTERN_RESONANCE_7T,
+   PATTERN_RESONANCE_8T,
+   PATTERN_RESONANCE_9T,
+   PATTERN_LIMIT
+}MV_HWS_PATTERN;
 #else
 #error "CONFIG_DDR3 or CONFIG_DDR4 must be defined !!!"
 #endif
@@ -68,9 +166,49 @@
     WriteLevelingSupp_ECCMode_ECCPup3
 }MV_HWS_WL_SUPP_MODE;
 
+typedef enum
+{
+    MV_ATTR_TIP_REV,
+    MV_ATTR_PHY_EDGE,
+    MV_ATTR_OCTET_PER_INTERFACE,
+    MV_ATTR_PLL_BEFORE_INIT,
+    MV_ATTR_TUNE_MASK,
+    MV_ATTR_INIT_FREQ,
+    MV_ATTR_MID_FREQ,
+    MV_ATTR_DFS_LOW_FREQ,
+    MV_ATTR_DFS_LOW_PHY,
+    MV_ATTR_DELAY_ENABLE,
+    MV_ATTR_CK_DELAY,
+    MV_ATTR_CA_DELAY,
+    MV_ATTR_INTERLEAVE_WA,
+    MV_ATTR_LAST
+} MV_DDR_DEV_ATTRIBUTE;
+
+typedef enum
+{
+    MV_TIP_REV_NA,
+    MV_TIP_REV_1, /* NP5 */
+    MV_TIP_REV_2, /* BC2 */
+    MV_TIP_REV_3, /* AC3 */
+    MV_TIP_REV_4, /* A-380/A-390 */
+    MV_TIP_REV_LAST
+} MV_DDR_TIP_REVISION;
+
+typedef enum
+{
+    MV_DDR_TRAINING_CONTROLLER_TIP,
+    MV_DDR_TRAINING_CONTROLLER_CPU
+} MV_DDR_TRAINING_CONTROLLER;
+
+typedef enum
+{
+    MV_DDR_PHY_EDGE_POSITIVE,
+    MV_DDR_PHY_EDGE_NEGATIVE
+} MV_DDR_PHY_EDGE;
 
 
 /************************* Declarations ***********************************************/
+
 GT_U32 speedBinTable
 (
     GT_U8 index,
@@ -84,6 +222,7 @@
     GT_U8 index
 );
 
+/* Device topology functionality */
 MV_HWS_TOPOLOGY_MAP* ddr3TipGetTopologyMap
 (
     GT_U32  devNum
@@ -95,6 +234,45 @@
     MV_HWS_TOPOLOGY_MAP* topology
 );
 
+/******************************************************************************
+* Name:     ddr3TipDevAttrInit.
+* Desc:     Init device attributes structures
+* Args:
+* Notes:
+* Returns:  none.
+*/
+void    ddr3TipDevAttrInit
+(
+    GT_U32  devNum
+);
+
+/******************************************************************************
+* Name:     ddr3TipDevAttrGet.
+* Desc:     get specified device attribute value
+* Args:
+* Notes:
+* Returns:  none.
+*/
+GT_U32    ddr3TipDevAttrGet
+(
+    GT_U32                  devNum,
+    MV_DDR_DEV_ATTRIBUTE    attrId
+);
+
+/******************************************************************************
+* Name:     ddr3TipDevAttrSet.
+* Desc:     set specified device attribute value
+* Args:
+* Notes:
+* Returns:  none.
+*/
+void    ddr3TipDevAttrSet
+(
+    GT_U32                  devNum,
+    MV_DDR_DEV_ATTRIBUTE    attrId,
+    GT_U32                  value
+);
+
 #endif /* _MV_DDR3_TRAININGIP_DB_H_ */
 
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/common/siliconIf/mvSiliconIf.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/common/siliconIf/mvSiliconIf.h
index b9d1875..f6e985c 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/common/siliconIf/mvSiliconIf.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Os/common/siliconIf/mvSiliconIf.h
@@ -84,10 +84,10 @@
 #define ABS(val) ((val) < 0) ? -(val) : (val)
 
 /* max number of devices supported by driver */
-#ifdef CO_CPU_RUN
-#define HWS_MAX_DEVICE_NUM (1)
-#else
+#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
 #define HWS_MAX_DEVICE_NUM (16)
+#else
+#define HWS_MAX_DEVICE_NUM (1)
 #endif
 /* max number of SERDESes in one device */
 #define HWS_MAX_DEV_SERDES_NUM (96)
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3A38x.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3A38x.h
index bdc105e..c60da34 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3A38x.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3A38x.h
@@ -38,17 +38,23 @@
 #define __mvHwsDdr3_A38x_H
 
 /* Termal Sensor Registers */
-#define TSEN_STATE_REG						0xE4070
-#define TSEN_STATE_OFFSET					31
-#define TSEN_STATE_MASK						(0x1 << TSEN_STATE_OFFSET)
-#define TSEN_CONF_REG						0xE4074
-#define TSEN_CONF_RST_OFFSET				8
-#define TSEN_CONF_RST_MASK					(0x1 << TSEN_CONF_RST_OFFSET)
+#define TSEN_CONTROL_LSB_REG					0xE4070
+#define TSEN_CONTROL_LSB_TC_TRIM_OFFSET				0
+#define TSEN_CONTROL_LSB_TC_TRIM_MASK				(0x7 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET)
+#define TSEN_CONTROL_MSB_REG					0xE4074
+#define TSEN_CONTROL_MSB_RST_OFFSET				8
+#define TSEN_CONTROL_MSB_RST_MASK				(0x1 << TSEN_CONTROL_MSB_RST_OFFSET)
 #define TSEN_STATUS_REG						0xE4078
 #define TSEN_STATUS_READOUT_VALID_OFFSET	10
 #define TSEN_STATUS_READOUT_VALID_MASK		(0x1 << TSEN_STATUS_READOUT_VALID_OFFSET)
 #define TSEN_STATUS_TEMP_OUT_OFFSET			0
 #define TSEN_STATUS_TEMP_OUT_MASK			(0x3FF << TSEN_STATUS_TEMP_OUT_OFFSET)
 
+/* device ID and revision */
+#define DEV_ID_REG					0x18238
+#define DEV_VERSION_ID_REG			0x1823C
+#define REVISON_ID_OFFS				8
+#define REVISON_ID_MASK				0xF00
+
 #endif /*__mvHwsDdr3_A38x_H*/
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3Bc2.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3Bc2.h
index e7d4476..4cf4cbf 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3Bc2.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3Bc2.h
@@ -51,21 +51,21 @@
 
 /************************* Definitions ***********************************************/
 
-#define BC2_NUMBER_OF_INTERFACES		5
-#define BC2_NUMBER_OF_PUP				4
-#define BC2_NUMBER_OF_BOARDS			2
+#define BC2_NUMBER_OF_INTERFACES               (5)
+#define BC2_NUMBER_OF_PUP                      (4)
+#define BC2_NUMBER_OF_BOARDS                   (2)
 
-#define BC2_DEVICE_SAR1_REG_ADDR                        0xF8200
-#define BC2_DEVICE_SAR2_REG_ADDR                        0xF8204
+#define BC2_DEVICE_SAR1_REG_ADDR               0xF8200
+#define BC2_DEVICE_SAR2_REG_ADDR               0xF8204
 
 #define BC2_JTAG_DEV_ID_STATUS_REG_ADDR        0x000F8244
 #define BC2_DEV_GENERAL_STATUS_REG1_ADDR_A0    0x000F82B4
 #define BC2_DEV_GENERAL_STATUS_REG1_ADDR_B0    0x000F8C84
 
-#define BC2_JTAG_DEV_ID_STATUS_VERSION_OFFSET     28
+#define BC2_JTAG_DEV_ID_STATUS_VERSION_OFFSET  28
 
-#define BC2_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_OFFSET    	11
-#define BC2_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_MASK      	0x1
+#define BC2_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_OFFSET   11
+#define BC2_DEVICE_SAR1_MSYS_TM_SDRAM_SEL_MASK     0x1
 
 /************************* Enums ***********************************************/
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3BobK.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3BobK.h
new file mode 100755
index 0000000..9508902
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/Silicon/mvHwsDdr3BobK.h
@@ -0,0 +1,153 @@
+/******************************************************************************
+*              Copyright (c) Marvell International Ltd. and its affiliates
+*
+* This software file (the "File") is owned and distributed by Marvell
+* International Ltd. and/or its affiliates ("Marvell") under the following
+* alternative licensing terms.
+* If you received this File from Marvell, you may opt to use, redistribute
+* and/or modify this File under the following licensing terms.
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*  -   Redistributions of source code must retain the above copyright notice,
+*       this list of conditions and the following disclaimer.
+*  -   Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*  -    Neither the name of Marvell nor the names of its contributors may be
+*       used to endorse or promote products derived from this software without
+*       specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+*******************************************************************************
+* mvHwsDdr3BobK.h
+*
+* DESCRIPTION:
+*
+*
+* FILE REVISION NUMBER:
+*       $Revision: 9 $
+*
+*******************************************************************************/
+
+#ifndef __mvHwsDdr3_BOBK_H
+#define __mvHwsDdr3_BOBK_H
+
+#include "mvDdr3TrainingIpDef.h"
+#if !defined(CPSS_BUILD)
+#include "config_marvell.h"     /* Required to identify SOC and Board */
+#include "mvSysEnvLib.h"
+#endif
+#include "mvDdr3TrainingIpStatic.h"
+#include "mvDdr3TrainingIp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************* Definitions ***********************************************/
+
+#define BOBK_NUMBER_OF_BOARDS           (2)
+#define NUMBER_OF_PUP					5
+/************************* Enums ***********************************************/
+
+typedef enum {
+	TM_EN,
+	MSYS_EN
+}DDR_IF_ASSIGNMENT;
+
+/************************* Globals ***********************************************/
+
+#ifndef DEFINE_GLOBALS
+extern TripDelayElement bobKBoardRoundTripDelayArray[MAX_INTERFACE_NUM*MAX_BUS_NUM*BOBK_NUMBER_OF_BOARDS];
+#else
+/* this array hold the board round trip delay (DQ and CK) per <interfcae,bus> */
+TripDelayElement bobKBoardRoundTripDelayArray[MAX_INTERFACE_NUM*MAX_BUS_NUM*BOBK_NUMBER_OF_BOARDS] =
+{
+   /* 1st board */
+   /*interface bus DQS-delay CK-delay */
+   { 3012,   6715 },
+   { 2625,   6715 },
+   { 3023,   6458 },
+   { 2663,   6458 },
+   { 2596,   6691 },
+
+   /* 2nd board */
+   /*interface bus DQS-delay CK-delay */
+   { 3012,   6715 },
+   { 2625,   6715 },
+   { 3023,   6458 },
+   { 2663,   6458 },
+   { 2596,   6691 },
+};
+#endif
+
+
+#ifndef DEFINE_GLOBALS
+extern TripDelayElement bobKPackageRoundTripDelayArray[MAX_INTERFACE_NUM*MAX_BUS_NUM];
+#else
+/* package trace */
+TripDelayElement bobKPackageRoundTripDelayArray[MAX_INTERFACE_NUM*MAX_BUS_NUM] =
+{
+     /*IF BUS DQ_DELYA CK_DELAY */
+    {  362,    813 },
+    {  458,    813 },
+    {  405,    750 },
+    {  446,    750 },
+    {  393,    718 }
+};
+#endif
+
+#ifndef DEFINE_GLOBALS
+extern GT_32 bobKSiliconDelayOffset[];
+#else
+GT_32 bobKSiliconDelayOffset[] =
+{
+    /* board 0 */
+    0,
+    /* board 1 */
+    0,
+    /* board 2 */
+    0
+};
+#endif
+
+/************************* Functions Declarations ***********************************************/
+
+/******************************************************************************
+* Name:     ddr3TipInitBobK.
+* Desc:     init Training SW DB and updates DDR topology.
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS ddr3TipInitBobK
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+) ;
+
+/******************************************************************************
+ * Name:     ddr3GetSdramAssignment
+ * Desc:     read S@R and return DDR3 assignment ( 0 = TM , 1 = MSYS )
+ * Args:
+ * Notes:
+ * Returns:  required value
+ */
+DDR_IF_ASSIGNMENT ddr3GetSdramAssignment(GT_U8 devNum);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __mvHwsDdr3_BOBK_H */
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/SoC/ddr3_hws_sil.h b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/SoC/ddr3_hws_sil.h
index 5ed42a7..57e11e8 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/SoC/ddr3_hws_sil.h
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/h/SoC/ddr3_hws_sil.h
@@ -27,6 +27,9 @@
 #if defined(MV_MSYS_BC2)
 #include "ddr3_msys_bc2.h"
 #include "ddr3_msys_bc2_config.h"
+#if defined(MV_MSYS_BOBK)
+#include "ddr3_msys_bobk.h"
+#include "ddr3_msys_bobk_config.h"
 #elif defined(MV_MSYS_AC3)
 #include "ddr3_msys_ac3.h"
 #include "ddr3_msys_ac3_config.h"
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/gtBuild b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/gtBuild
index 9e6c871..78a48ba 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/gtBuild
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/gtBuild
@@ -22,6 +22,12 @@
 #SUBDIRS      =
 C_EXCLUDE_FILE_LIST = mvHwsDdr3TrainingStub.c
 
+CFLAGS += -DDDR_VIEWER_TOOL -DMV_HWS_EXCLUDE_DEBUG_PRINTS
+
+# To enable RX IO BIST Test un-mark below line
+# CFLAGS += -DMV_HWS_RX_IO_BIST
+# To enable CMD/ADDR Test un-mark below line
+# CFLAGS += -DMV_HWS_RX_IO_BIST_ETP
 
 ##################################################
 ##################################################
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Debug.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Debug.c
index 6f69e0a..09a892f 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Debug.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Debug.c
@@ -32,11 +32,23 @@
 #include "mvDdrTrainingIpDb.h"
 
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 GT_STATUS printAdll(GT_U32 devNum, GT_U32 adll[MAX_INTERFACE_NUM*MAX_BUS_NUM]);
+GT_STATUS printPh(GT_U32 devNum, GT_U32 adll[MAX_INTERFACE_NUM*MAX_BUS_NUM]);
+
+GT_U8 sweepPatternIndexStart = PATTERN_KILLER_DQ0, sweepPatternIndexEnd = PATTERN_LIMIT;
 static char* ConvertFreq(MV_HWS_DDR_FREQ freq);
+#if defined(EXCLUDE_SWITCH_DEBUG)
+extern MV_HWS_PATTERN sweepPattern;
+GT_U32 ctrlSweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+GT_U32 ctrlADLL[MAX_CS_NUM*MAX_INTERFACE_NUM*MAX_BUS_NUM];
+GT_U32 ctrlADLL1[MAX_CS_NUM*MAX_INTERFACE_NUM*MAX_BUS_NUM];
+GT_U32 ctrlLevelPhase[MAX_CS_NUM*MAX_INTERFACE_NUM*MAX_BUS_NUM];
 #endif
-extern GT_U32 ckDelay, ckDelay_16;
+#endif
+
+extern GT_U32 ckDelay;
+extern GT_U32 dminPhyRegTable[MAX_BUS_NUM*MAX_CS_NUM][2];
 
 extern GT_STATUS ddr3TipRestoreDunitRegs
 (
@@ -146,7 +158,7 @@
 extern GT_U32 maskTuneFunc;
 extern GT_U32 freqVal[];
 MV_HWS_TIP_CONFIG_FUNC_DB configFuncInfo[HWS_MAX_DEVICE_NUM];
-GT_U8 isDefaultCentralization = 0 , isTuneResult = 0, isValidateWindowPerIf = 0, isValidateWindowPerPup = 0, sweepCnt = 1, isBistResetBit = 1;
+GT_U8 isDefaultCentralization = 0 , isTuneResult = 0, isValidateWindowPerIf = 0, isValidateWindowPerPup = 0, sweepCnt = 1, isBistResetBit = 1, isRunLevelingSweepTests = 0;
 static MV_HWS_XSB_INFO xsbInfo[HWS_MAX_DEVICE_NUM];
 
 
@@ -160,6 +172,7 @@
 {
     GT_U32 interfaceId, regAddr, dataValue, busId;
 	GT_U32 readData[MAX_INTERFACE_NUM];
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
     mvPrintf("-- dunit registers --\n");
     for(regAddr = 0x1400; regAddr < 0x19F0; regAddr+=4)
     {
@@ -180,15 +193,15 @@
         for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
         {
             VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-            for(busId = 0; busId < topologyMap->numOfBusPerInterface; busId++)
+            for(busId = 0; busId < octetsPerInterfaceNum; busId++)
             {
-		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
-		CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, busId,  DDR_PHY_DATA,  regAddr, &dataValue));
+				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
+				CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, busId,  DDR_PHY_DATA,  regAddr, &dataValue));
                 mvPrintf("0x%x ",  dataValue);
             }
-            for(busId = 0; busId < topologyMap->numOfBusPerInterface; busId++)
+            for(busId = 0; busId < octetsPerInterfaceNum; busId++)
             {
-		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
+				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
                 CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, busId,  DDR_PHY_CONTROL,  regAddr, &dataValue));
                 mvPrintf("0x%x ",  dataValue);
             }
@@ -265,7 +278,7 @@
 }
 
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 /*****************************************************************************
 Convert freq to character string
 ******************************************************************************/
@@ -413,9 +426,12 @@
 GT_STATUS ddr3TipPrintLog(GT_U32 devNum, GT_U32 memAddr)
 {
     GT_U32 interfaceId = 0;
-	memAddr = memAddr;
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+    memAddr = memAddr; /* avoid warnings */
+
+#ifndef DDR_VIEWER_TOOL
+    devNum = devNum; /* avoid warnings */
+#else
     if (( isValidateWindowPerIf != 0) || ( isValidateWindowPerPup != 0))
 
     {
@@ -425,17 +441,23 @@
 		freq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
 
         isPupLog = (isValidateWindowPerPup != 0) ? 1:0;
-	mvPrintf("===VALIDATE WINDOW LOG START===\n");
-	mvPrintf("DDR Frequency: %s   ======\n",ConvertFreq(freq));
+		mvPrintf("===VALIDATE WINDOW LOG START===\n");
+		mvPrintf("DDR Frequency: %s   ======\n",ConvertFreq(freq));
         /* print sweep windows */
         ddr3TipRunSweepTest(devNum, sweepCnt, 1 , isPupLog);
         ddr3TipRunSweepTest(devNum, sweepCnt, 0 , isPupLog);
-        ddr3TipPrintAllPbsResult(devNum);
-        ddr3TipPrintWLSuppResult(devNum);
-        mvPrintf("===VALIDATE WINDOW LOG END ===\n");
-	CHECK_STATUS(ddr3TipRestoreDunitRegs(devNum));
-        ddr3TipRegDump(devNum);
 
+#if defined(EXCLUDE_SWITCH_DEBUG)
+		if( isRunLevelingSweepTests == 1 ){
+			ddr3TipRunLevelingSweepTest(devNum, sweepCnt, 0 , isPupLog);
+			ddr3TipRunLevelingSweepTest(devNum, sweepCnt, 1 , isPupLog);
+		}
+#endif
+		ddr3TipPrintAllPbsResult(devNum);
+		ddr3TipPrintWLSuppResult(devNum);
+		mvPrintf("===VALIDATE WINDOW LOG END ===\n");
+		CHECK_STATUS(ddr3TipRestoreDunitRegs(devNum));
+		ddr3TipRegDump(devNum);
     }
 #endif
 
@@ -540,7 +562,7 @@
    }
     return GT_OK;
 }
-
+#ifndef MV_HWS_EXCLUDE_DEBUG_PRINTS
 /*****************************************************************************
 Print stability log info
 ******************************************************************************/
@@ -552,8 +574,11 @@
 	GT_U32 Ph = adllTap*32;
 	GT_U32 CC = Ph*2;*/
 	GT_U32 regData;
+#ifdef CONFIG_DDR4
+	GT_U32 regData1;
+#endif
 	GT_U32 readData[MAX_INTERFACE_NUM];
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 
 	/*Title print*/
 	for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
@@ -596,7 +621,7 @@
 	{
 		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 
-		mvPrintf("Data: %d,%d,",interfaceId, (configFuncInfo[devNum].tipGetTemperature != NULL)?(configFuncInfo[devNum].tipGetTemperature(devNum)):(0));
+		mvPrintf("Data: %d,%d,",interfaceId, (configFuncInfo[devNum].tipGetTemperature != NULL)?(configFuncInfo[devNum].tipGetTemperature((GT_U8)devNum)):(0));
 
 		CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x14C8, readData, MASK_ALL_BITS));
 		mvPrintf("%d,%d,",((readData[interfaceId]&0x3F0)>>4),((readData[interfaceId]&0xFC00)>>10));
@@ -616,17 +641,21 @@
 				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, RESULT_DB_PHY_REG_ADDR+csindex, &regData);
 				mvPrintf("%d,%d,",(regData&0x1F),((regData&0x3E0)>>5));
 				#else/*DDR4*/
+				/*DminTx, areaTX*/
 				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, RESULT_DB_PHY_REG_ADDR+csindex, &regData);
-				mvPrintf("%d,%d,",(regData&0x1F)*4,2*((regData&0xFFE0)>>5));
+				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, dminPhyRegTable[csindex*5+busId][0], DDR_PHY_CONTROL, dminPhyRegTable[csindex*5+busId][1], &regData1);
+				mvPrintf("%d,%d,",2*(regData1&0xFF),regData);
+				/*DminRx, areaRX*/
 				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, RESULT_DB_PHY_REG_ADDR+csindex + 4, &regData);
-				mvPrintf("%d,%d,",(regData&0x1F)*4,2*((regData&0xFFE0)>>5));
+				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, dminPhyRegTable[csindex*5+busId][0], DDR_PHY_CONTROL, dminPhyRegTable[csindex*5+busId][1], &regData1);
+				mvPrintf("%d,%d,",2*(regData1>>8),regData);
 				#endif
 				/*WL*/
 				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG+csindex*4, &regData);
 				mvPrintf("%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32,(regData&0x1F),(regData&0x1C0)>>6);
 				/*RL*/
 				CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, READ_DATA_SAMPLE_DELAY, readData, MASK_ALL_BITS));
-				readData[interfaceId] = (readData[interfaceId]&(0xF<<(4*csindex))) >> (4*csindex);
+				readData[interfaceId] = (readData[interfaceId]&(0x1F<<(8*csindex))) >> (8*csindex);
 				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, RL_PHY_REG+csindex*4, &regData);
 				mvPrintf("%d,%d,%d,%d,",(regData&0x1F)+((regData&0x1C0)>>6)*32 + readData[interfaceId]*64,(regData&0x1F),((regData&0x1C0)>>6),readData[interfaceId]);
 				/*Centralization*/
@@ -668,13 +697,13 @@
 	return GT_OK;
 }
 
-
+#endif
 /*****************************************************************************
 Register XSB information
 ******************************************************************************/
 GT_STATUS ddr3TipRegisterXsbInfo
 (
-    GT_U32					devNum, 
+    GT_U32					devNum,
     MV_HWS_XSB_INFO         *xsbInfoTable
 )
 {
@@ -685,20 +714,21 @@
 /*****************************************************************************
 Read ADLL Value
 ******************************************************************************/
-GT_BOOL readAdllValue(GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask)
+GT_BOOL mvHwsDdr3TipReadAdllValue(GT_U32 devNum, GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask)
 {
     GT_U32  dataValue;
     GT_U32 interfaceId = 0, busId = 0;
-    GT_U32 devNum = 0;
+    GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
     /* multi CS support - regAddr is calucalated in calling function with CS offset */
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-	    for(busId = 0 ; busId < topologyMap->numOfBusPerInterface ; busId++)
+	    for(busId = 0 ; busId < octetsPerInterfaceNum ; busId++)
 	    {
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
                 CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, busId,  DDR_PHY_DATA,  regAddr, &dataValue));
-                PupValues[interfaceId*topologyMap->numOfBusPerInterface + busId] = dataValue & mask;
+                PupValues[interfaceId*octetsPerInterfaceNum + busId] = dataValue & mask;
         }
 	}
 
@@ -708,20 +738,71 @@
 /*****************************************************************************
 Write ADLL Value
 ******************************************************************************/
-GT_BOOL writeAdllValue(GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr)
+GT_BOOL mvHwsDdr3TipWriteAdllValue(GT_U32 devNum, GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr)
 {
     GT_U32 interfaceId = 0, busId = 0;
-    GT_U32 devNum = 0, data;
+    GT_U32 data;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* multi CS support - regAddr is calucalated in calling function with CS offset */
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-	    for(busId = 0 ; busId < topologyMap->numOfBusPerInterface ; busId++)
+	    for(busId = 0 ; busId < octetsPerInterfaceNum ; busId++)
 	    {
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
-		data = PupValues[interfaceId*topologyMap->numOfBusPerInterface+busId];
+		data = PupValues[interfaceId*octetsPerInterfaceNum+busId];
+		CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, regAddr, data));
+	    }
+
+    }
+    return 0;
+}
+
+
+/*****************************************************************************
+Read Phase Value
+******************************************************************************/
+GT_BOOL readPhaseValue(GT_U32 devNum,GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], int regAddr, GT_U32 mask)
+{
+    GT_U32  dataValue;
+    GT_U32 interfaceId = 0, busId = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    /* multi CS support - regAddr is calucalated in calling function with CS offset */
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+	    for(busId = 0 ; busId < octetsPerInterfaceNum ; busId++)
+	    {
+		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
+                CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, busId,  DDR_PHY_DATA,  regAddr, &dataValue));
+                PupValues[interfaceId*octetsPerInterfaceNum + busId] = dataValue & mask;
+        }
+	}
+
+	return 0;
+}
+
+/*****************************************************************************
+Write Leveling Value
+******************************************************************************/
+GT_BOOL writeLevelingValue(GT_U32 devNum,GT_U32 PupValues[MAX_INTERFACE_NUM*MAX_BUS_NUM], GT_U32 PupPhValues[MAX_INTERFACE_NUM*MAX_BUS_NUM],int regAddr)
+{
+    GT_U32 interfaceId = 0, busId = 0;
+    GT_U32 data;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    /* multi CS support - regAddr is calucalated in calling function with CS offset */
+
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+	    for(busId = 0 ; busId < octetsPerInterfaceNum ; busId++)
+	    {
+		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
+		data = PupValues[interfaceId*octetsPerInterfaceNum+busId] + (PupPhValues[interfaceId*octetsPerInterfaceNum+busId]);
 		CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, regAddr, data));
 	    }
 
@@ -740,8 +821,13 @@
 extern GT_U8  isDfsInInit;
 extern GT_32 wlDebugDelay;
 extern GT_U32 siliconDelay[HWS_MAX_DEVICE_NUM];
-extern GT_U32 Pfinger;
-extern GT_U32 Nfinger;
+extern 	GT_U32 vrefInitialValue;
+extern 	GT_U32 gZpriData;
+extern 	GT_U32 gZnriData;
+extern 	GT_U32 gZpriCtrl;
+extern 	GT_U32 gZnriCtrl;
+extern 	GT_U32 gZpodtData;
+extern 	GT_U32 gZnodtData;
 extern GT_U32 freqVal[DDR_FREQ_LIMIT];
 extern GT_U32 startPattern, endPattern;
 extern GT_U32  PhyReg0Val;
@@ -750,11 +836,6 @@
 extern GT_U32  PhyReg3Val;
 extern MV_HWS_PATTERN sweepPattern;
 extern MV_HWS_PATTERN pbsPattern;
-extern GT_U8 isRzq6;
-extern GT_U32 znriDataPhyVal;
-extern GT_U32 zpriDataPhyVal;
-extern GT_U32 znriCtrlPhyVal;
-extern GT_U32 zpriCtrlPhyVal;
 extern GT_U8  debugTrainingAccess;
 extern GT_U32 fingerTest, pFingerStart,  pFingerEnd,  nFingerStart, nFingerEnd, pFingerStep, nFingerStep;
 extern GT_U32 mode2T;
@@ -770,22 +851,16 @@
 extern GT_U32 startPattern, endPattern;
 
 /*Declarations*/
-GT_U32 rlVersion = 1; /* 0 - old RL machine */
 MV_HWS_TIP_CONFIG_FUNC_DB configFuncInfo[HWS_MAX_DEVICE_NUM];
 GT_U32  startXsbOffset = 0;
 GT_U8 isRlOld = 0;
 GT_U8 isFreqOld = 0;
 GT_U8 isDfsDisabled = 0;
 GT_U32 defaultCentrlizationValue = 0x12;
-GT_U32 vref = 0x4;
 GT_U32 activateSelectBeforeRunAlg= 1, activateDeselectAfterRunAlg = 1, rlTest = 0, resetReadFifo = 0;
 GT_BOOL debugAcc = GT_FALSE;
 GT_U32 ctrlSweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
 GT_U32 ctrlADLL[MAX_CS_NUM*MAX_INTERFACE_NUM*MAX_BUS_NUM];
-GT_U8 csMaskReg[]=
-{
-    0, 4, 8, 12 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
 GT_U32 xsbTestTable[][8] =
 {
     {0x00000000,         0x11111111,         0x22222222,         0x33333333,         0x44444444,         0x55555555,         0x66666666,         0x77777777},
@@ -811,11 +886,12 @@
 GT_STATUS    ddr3TipPrintAdll()
 {
     GT_U32  busCnt = 0,  interfaceId,  dataP1, dataP2, uiData3, devNum = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+        for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
             CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId,  ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, 0x1, &dataP1));
@@ -904,27 +980,23 @@
     case 0:
         *ptr = (GT_U32*) &(topologyMap->interfaceActiveMask);
         break;
-			 
+
     case 0x1:
         *ptr = (GT_U32*) &maskTuneFunc;
         break;
 
     case 0x2:
-	    *ptr = (GT_U32*) &lowFreq;
+        lowFreq = (MV_HWS_DDR_FREQ)value;
 	    break;
 
     case 0x3:
-	    *ptr = (GT_U32*) &mediumFreq;
+        mediumFreq = (MV_HWS_DDR_FREQ)value;
 	    break;
-			 
+
     case 0x4:
         *ptr = (GT_U32*) &genericInitController;
         break;
 
-    case 0x5:
-        *ptr = (GT_U32*) &rlVersion;
-        break;
-
     case 0x8:
         *ptr = (GT_U32*) &startXsbOffset;
         break;
@@ -980,17 +1052,16 @@
    case 0x32:
        *ptr = (GT_U32*) &isDfsInInit;
        break;
-
    case 0x33:
-       *ptr = (GT_U32*) &Pfinger;
+       *ptr = (GT_U32*) &gZnodtData;
        break;
 
    case 0x34:
-       *ptr = (GT_U32*) &Nfinger;
+       *ptr = (GT_U32*) &gZpodtData;
        break;
 
    case 0x35:
-       *ptr = (GT_U32*) &initFreq;
+       initFreq = (MV_HWS_DDR_FREQ)value;
        break;
 
    case 0x36:
@@ -1021,25 +1092,20 @@
        *ptr = (GT_U32*) &PhyReg3Val;
        break;
 
-
    case 0x4e:
-       *ptr = (GT_U32*) &sweepPattern;
+       sweepPattern = (MV_HWS_PATTERN)value;
        break;
 /*
    case 0x4f:
        *ptr = (GT_U32*) &(phy1ValTable[DDR_FREQ_LOW_FREQ]);
        break;
 */
-   case 0x50:
-       *ptr = (GT_U32*) &isRzq6;
-       break;
-
    case 0x51:
-       *ptr = (GT_U32*) &znriDataPhyVal;
+       *ptr = (GT_U32*) &gZnriData;
        break;
 
    case 0x52:
-       *ptr = (GT_U32*) &zpriDataPhyVal;
+       *ptr = (GT_U32*) &gZpriData;
        break;
 
    case 0x53:
@@ -1071,19 +1137,18 @@
        break;
 
    case 0x5A:
-       *ptr = (GT_U32*) &znriCtrlPhyVal;
+       *ptr = (GT_U32*) &gZnriCtrl;
        break;
 
    case 0x5B:
-       *ptr = (GT_U32*) &zpriCtrlPhyVal;
+       *ptr = (GT_U32*) &gZpriCtrl;
        break;
-
    case 0x5C:
        *ptr = (GT_U32*) &isRegDump;
        break;
 
    case 0x5D:
-       *ptr = (GT_U32*) &vref;
+       *ptr = (GT_U32*) &vrefInitialValue;
        break;
 
    case 0x5E:
@@ -1115,21 +1180,17 @@
        break;
 
    case 0x71:
-       *ptr = (GT_U32*) &pbsPattern;
+       pbsPattern = (MV_HWS_PATTERN)value;
        break;
 
    case 0x72:
        *ptr = (GT_U32*) &delayEnable;
        break;
-	   
+
    case 0x73:
        *ptr = (GT_U32*) &ckDelay;
        break;
 
-   case 0x74:
-       *ptr = (GT_U32*) &ckDelay_16;
-       break;
-
    case 0x75:
        *ptr = (GT_U32*) &caDelay;
        break;
@@ -1269,29 +1330,50 @@
         }
         else
         {
-			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("flagId out of boundary %d \n",flagId)); 				
+			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("flagId out of boundary %d \n",flagId));
             return GT_BAD_PARAM;
         }
     }
-    return GT_OK; 
+    return GT_OK;
  }
-
-#ifndef EXCLUDE_SWITCH_DEBUG
+#endif /* #ifndef EXCLUDE_SWITCH_DEBUG */
+#ifdef DDR_VIEWER_TOOL
 /*****************************************************************************
 Print ADLL
 ******************************************************************************/
 GT_STATUS printAdll(GT_U32 devNum, GT_U32 adll[MAX_INTERFACE_NUM*MAX_BUS_NUM])
 {
     GT_U32 i,j;
+    GT_U32 octetsPerInterfaceNum;
 
-	devNum = devNum;
+    devNum = devNum;
+    octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-    for(j=0; j< topologyMap->numOfBusPerInterface; j++)
+    for(j=0; j< octetsPerInterfaceNum; j++)
     {
-       	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, j)
+        VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, j)
         for(i=0;i<MAX_INTERFACE_NUM; i++)
         {
-            mvPrintf("%d ,",adll[i*topologyMap->numOfBusPerInterface+j]);
+            mvPrintf("%d ,",adll[i*octetsPerInterfaceNum+j]);
+        }
+    }
+    mvPrintf("\n");
+    return GT_OK;
+}
+GT_STATUS printPh(GT_U32 devNum, GT_U32 adll[MAX_INTERFACE_NUM*MAX_BUS_NUM])
+{
+    GT_U32 i,j;
+    GT_U32 octetsPerInterfaceNum;
+
+    devNum = devNum;
+    octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    for(j=0; j< octetsPerInterfaceNum; j++)
+    {
+        VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, j)
+        for(i=0;i<MAX_INTERFACE_NUM; i++)
+        {
+            mvPrintf("%d ,",adll[i*octetsPerInterfaceNum+j]>>6);
         }
     }
     mvPrintf("\n");
@@ -1299,8 +1381,9 @@
 }
 #endif
 
+#ifndef EXCLUDE_SWITCH_DEBUG
 /* uiByteIndex - only byte 0,1,2, or 3, oxff - test all bytes */
-static 
+static
 GT_U32 ddr3TipCompare(GT_U32 interfaceId, GT_U32 *pSrc, GT_U32 *pDst, GT_U32 uiByteIndex)
 {
    GT_U32 burstCnt = 0, addrOffset,iId;
@@ -1309,7 +1392,7 @@
    addrOffset = (uiByteIndex == 0xff) ? (GT_U32) 0xffffffff: (GT_U32) (0xff << (uiByteIndex*8));
    for(burstCnt = 0; burstCnt < EXT_ACCESS_BURST_LENGTH; burstCnt++)
    {
-      if ((pSrc[burstCnt] & addrOffset) != (pDst[burstCnt] & addrOffset)) 
+      if ((pSrc[burstCnt] & addrOffset) != (pDst[interfaceId] & addrOffset))
       {
           bIsFail = GT_TRUE;
       }
@@ -1332,89 +1415,31 @@
 
 }
 
-/*******************************************************/
-/* uiTestType = 0-tx , 1 - rx */
-GT_STATUS    ddr3TipSweepTest(GT_U32   devNum, GT_U32 uiTestType, GT_U32 uiMemAddress, GT_U32 isModifyAdll, GT_U32 startIf, GT_U32 endIf, GT_U32 startpup, GT_U32 endpup)
-{
-    GT_U32    busCnt = 0, adllVal = 0, interfaceId, uiPrevAdll, uiMaskBit, end_adll, start_adll;
-    GT_U32 regAddr = 0, iter = 0;
-
-	uiMemAddress = uiMemAddress;
-
-    if (uiTestType == 0)
-    {
-        regAddr = 1;
-        uiMaskBit = 0x3f;
-        start_adll = 0;
-        end_adll = uiMaskBit;
-    }
-    else
-    {
-        regAddr = 3;
-        uiMaskBit = 0x1f;
-        start_adll = 0;
-        end_adll = uiMaskBit;
-    }
-    DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("==============================\n"));
-    DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("Test type %d (0-tx, 1-rx) \n",uiTestType));
-    
-    for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
-    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busCnt = startpup; busCnt < endpup; busCnt++)
-        {
-      
-            CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId,  ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, regAddr, &uiPrevAdll));
-
-            for(adllVal = start_adll; adllVal <= end_adll; adllVal++)
-            {
-                if (isModifyAdll == 1)
-                {
-                    CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  busCnt, DDR_PHY_DATA, regAddr, adllVal, uiMaskBit));
-                }
-                for(iter = 0; iter <= debugSweepVal; iter++)
-                {
-                    /*XsbRWTest(devNum, interfaceId, uiMemAddress, testPattern, busCnt, 0);
-					CHECK_STATUS(ddr3TipExtWrite(devNum, interfaceId, uiMemAddress, 1, xsbTestTable[seq]));
-					CHECK_STATUS(ddr3TipExtRead(  devNum, interfaceId, uiMemAddress, 1, dataRead));
-					retTmp = ddr3TipCompare(interfaceId, xsbTestTable[seq], dataRead, 0xff);*/
-				}
-			}
-            if (isModifyAdll == 1)
-            {
-                CHECK_STATUS(mvHwsDdr3TipBUSWrite(   devNum, ACCESS_TYPE_UNICAST, interfaceId,  ACCESS_TYPE_UNICAST,  busCnt, DDR_PHY_DATA, regAddr,  uiPrevAdll));
-            }
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
-        }
-        DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
-    }
-
-    return GT_OK;
-}
-
-#ifndef EXCLUDE_SWITCH_DEBUG
+#endif /* EXCLUDE_SWITCH_DEBUG*/
+#if defined(DDR_VIEWER_TOOL)
 /*****************************************************************************
 Sweep validation
 ******************************************************************************/
 GT_BOOL ddr3TipRunSweepTest(GT_32 devNum, GT_U32 RepeatNum, GT_U32 direction, GT_U32 mode)
 {
     GT_U32  pup = 0, startPup = 0, endPup = 0;
-    GT_U32 adll = 0;
+    GT_U32 adll = 0,rep = 0,sweepPatternIndex = 0;
     GT_U32 res[MAX_INTERFACE_NUM] = {0};
     GT_32  interfaceId = 0;
     GT_U32 adllValue = 0;
     GT_32 reg = (direction == 0) ? WRITE_CENTRALIZATION_PHY_REG : READ_CENTRALIZATION_PHY_REG;
     MV_HWS_ACCESS_TYPE  pupAccess;
     GT_U32 uiCs;
-    GT_U32 maxCs = mvHwsDdr3TipMaxCSGet();
+    GT_U32 maxCs = mvHwsDdr3TipMaxCSGet(devNum);
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     RepeatNum = RepeatNum;
-
+	RepeatNum = 2;
     if ( mode == 1)
     {
         /* per pup */
         startPup = 0;
-        endPup = topologyMap->numOfBusPerInterface-1;
+        endPup = octetsPerInterfaceNum-1;
         pupAccess = ACCESS_TYPE_UNICAST;
     }
     else
@@ -1429,7 +1454,7 @@
 		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-    			for( pup = startPup ;pup <= endPup ; pup++)
+			for( pup = startPup ;pup <= endPup ; pup++)
 			{
 				ctrlSweepres[adll][interfaceId][pup] = 0;
 			}
@@ -1441,24 +1466,30 @@
 		ctrlADLL[adll] = 0;
 	}
 	/*Save DQS value(after algorithm run)*/
-	readAdllValue(ctrlADLL, (reg + (uiCs * CS_REGISTER_ADDR_OFFSET)) , MASK_ALL_BITS );
+	mvHwsDdr3TipReadAdllValue(devNum,ctrlADLL, (reg + (uiCs * CS_REGISTER_ADDR_OFFSET)) , MASK_ALL_BITS );
 
 	/*Sweep ADLL  from 0:31 on all I/F on all Pup and perform BIST on each stage.*/
 	for(pup=startPup; pup <=endPup; pup++)
 	{
 		for(adll = 0 ; adll < ADLL_LENGTH ; adll++)
 		{
-			adllValue = (direction == 0) ? (adll*2):adll;
-			CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, 0, pupAccess, pup, DDR_PHY_DATA, reg + CS_REG_VALUE(uiCs), adllValue));
-			mvHwsDdr3RunBist(devNum, sweepPattern, res ,uiCs);
-			/*ddr3TipResetFifoPtr(devNum);*/
-			for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+			for(rep = 0; rep < RepeatNum ; rep++)
 			{
-				VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-				ctrlSweepres[adll][interfaceId][pup] = res[interfaceId];
-				if (mode == 1)
+				for(sweepPatternIndex = sweepPatternIndexStart ; sweepPatternIndex < sweepPatternIndexEnd ; sweepPatternIndex++)
 				{
-					CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, reg + CS_REG_VALUE(uiCs),  ctrlADLL[interfaceId*uiCs*topologyMap->numOfBusPerInterface+pup]));
+					adllValue = (direction == 0) ? (adll*2):adll;
+					CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, 0, pupAccess, pup, DDR_PHY_DATA, reg + CS_BYTE_GAP(uiCs), adllValue));
+					mvHwsDdr3RunBist(devNum, sweepPattern, res ,uiCs);
+					/*ddr3TipResetFifoPtr(devNum);*/
+					for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+					{
+						VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+						ctrlSweepres[adll][interfaceId][pup] += res[interfaceId];
+						if (mode == 1)
+						{
+							CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, reg + CS_BYTE_GAP(uiCs),  ctrlADLL[interfaceId*uiCs*octetsPerInterfaceNum+pup]));
+						}
+					}
 				}
 			}
 		}
@@ -1490,15 +1521,15 @@
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 			for( pup=startPup; pup <=endPup; pup++)
 			{
-				mvPrintf("%d , ",ctrlSweepres[adll][interfaceId][pup]);
+				mvPrintf("%8d , ",ctrlSweepres[adll][interfaceId][pup]);
 			}
 		}
 		mvPrintf("\n");
 	}
 	/*Write back to the phy the Rx DQS value, we store in the begging. */
-	writeAdllValue(ctrlADLL, (reg +  uiCs * CS_REGISTER_ADDR_OFFSET));
+	mvHwsDdr3TipWriteAdllValue(devNum,ctrlADLL, (reg +  uiCs * CS_REGISTER_ADDR_OFFSET));
 	/* print adll results */
-	readAdllValue(ctrlADLL, (reg + uiCs * CS_REGISTER_ADDR_OFFSET), MASK_ALL_BITS);
+	mvHwsDdr3TipReadAdllValue(devNum,ctrlADLL, (reg + uiCs * CS_REGISTER_ADDR_OFFSET), MASK_ALL_BITS);
 	mvPrintf("%s,DQS,ADLL,,,",(direction==0) ? "Tx":"Rx");
 	printAdll(devNum, ctrlADLL);
     }
@@ -1506,13 +1537,185 @@
     return 0;
 }
 
+#if defined(EXCLUDE_SWITCH_DEBUG)
+GT_BOOL ddr3TipRunLevelingSweepTest(GT_32 devNum, GT_U32 RepeatNum, GT_U32 direction, GT_U32 mode)
+{
+    GT_U32  pup = 0, startPup = 0, endPup = 0, startAdll = 0;
+    GT_U32 adll = 0,rep = 0,sweepPatternIndex = 0;
+	GT_U32  readData[MAX_INTERFACE_NUM];
+    GT_U32 res[MAX_INTERFACE_NUM] = {0};
+    GT_32  interfaceId = 0,gap = 0;
+    GT_32 adllValue = 0;
+    GT_32 reg = (direction == 0) ? WL_PHY_REG : RL_PHY_REG;
+    MV_HWS_ACCESS_TYPE  pupAccess;
+    GT_U32 uiCs;
+    GT_U32 maxCs = mvHwsDdr3TipMaxCSGet(devNum);
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+    RepeatNum = RepeatNum;
+	RepeatNum = 3;
+    if ( mode == 1)
+    {
+        /* per pup */
+        startPup = 0;
+        endPup = octetsPerInterfaceNum-1;
+        pupAccess = ACCESS_TYPE_UNICAST;
+    }
+    else
+    {
+        startPup = 0;
+        endPup = 0;
+        pupAccess = ACCESS_TYPE_MULTICAST;
+    }
+    for(uiCs=0; uiCs < maxCs; uiCs++){
+		for(adll = 0 ; adll < ADLL_LENGTH ; adll++)
+		{
+			for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+			{
+				VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+				for( pup = startPup ;pup <= endPup ; pup++)
+				{
+					ctrlSweepres[adll][interfaceId][pup] = 0;
+				}
+			}
+		}
+
+		for(adll = 0 ; adll < (MAX_INTERFACE_NUM * MAX_BUS_NUM) ; adll++)
+		{
+			ctrlADLL[adll] = 0;
+			ctrlLevelPhase[adll] = 0;
+			ctrlADLL1[adll] = 0;
+		}
+		/*Save Leveling value(after algorithm run)*/
+		mvHwsDdr3TipReadAdllValue(devNum,ctrlADLL, (reg + (uiCs * CS_REGISTER_ADDR_OFFSET)) , 0x1F );
+		readPhaseValue(devNum,ctrlLevelPhase, (reg + (uiCs * CS_REGISTER_ADDR_OFFSET)) , 0x7<<6 );
+		if(direction == 0)
+		{
+			mvHwsDdr3TipReadAdllValue(devNum,ctrlADLL1, (0x1 + (uiCs * CS_REGISTER_ADDR_OFFSET)) , MASK_ALL_BITS );
+		}
+		/*Sweep ADLL  from 0:31 on all I/F on all Pup and perform BIST on each stage.*/
+		for(pup=startPup; pup <=endPup; pup++)
+		{
+			for(adll = 0 ; adll < ADLL_LENGTH ; adll++)
+			{
+				for(rep = 0; rep < RepeatNum ; rep++)
+				{
+					adllValue = (direction == 0) ? (adll*2):(adll*3);
+					for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+					{
+						startAdll = ctrlADLL[interfaceId*uiCs*octetsPerInterfaceNum+pup] + (ctrlLevelPhase[interfaceId*uiCs*octetsPerInterfaceNum+pup]>>6)*32 ;
+						if(direction == 0)
+						{
+							startAdll = (startAdll>32)?(startAdll-32):0;
+						}else
+						{
+							startAdll = (startAdll>48)?(startAdll-48):0;
+						}
+						if(direction == 0)
+						{
+							adllValue = startAdll + adllValue;
+						}else
+						{
+							adllValue = startAdll + adllValue;
+						}
+						gap = ctrlADLL1[interfaceId*uiCs*octetsPerInterfaceNum+pup] - ctrlADLL[interfaceId*uiCs*octetsPerInterfaceNum+pup];
+						gap = (((adllValue%32) + gap)%64);
+						adllValue = ((adllValue%32) + (((adllValue- (adllValue%32))/32)<<6));
+
+						CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, pupAccess, pup, DDR_PHY_DATA, reg + CS_BYTE_GAP(uiCs), adllValue));
+						if(direction == 0)
+						{
+							CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, pupAccess, pup, DDR_PHY_DATA, 0x1 + CS_BYTE_GAP(uiCs), gap));
+						}
+					}
+					for(sweepPatternIndex = sweepPatternIndexStart ; sweepPatternIndex < sweepPatternIndexEnd ; sweepPatternIndex++)
+					{
+						mvHwsDdr3RunBist(devNum, sweepPattern, res ,uiCs);
+						ddr3TipResetFifoPtr(devNum);
+						for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+						{
+							VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+							if(pup != 4)
+							{
+								ctrlSweepres[adll][interfaceId][pup] += res[interfaceId];
+							}else
+							{
+								CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1458, readData, MASK_ALL_BITS));
+								ctrlSweepres[adll][interfaceId][pup] += readData[interfaceId];
+
+								CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1458, 0x0 , 0xFFFFFFFF));
+								CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x145C, 0x0 , 0xFFFFFFFF));
+							}
+						}
+					}
+				}
+			}
+			for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+			{
+				startAdll = ctrlADLL[interfaceId*uiCs*octetsPerInterfaceNum+pup] + ctrlLevelPhase[interfaceId*uiCs*octetsPerInterfaceNum+pup] ;
+				CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, pupAccess, pup, DDR_PHY_DATA, reg + CS_BYTE_GAP(uiCs), startAdll));
+				if(direction == 0)
+				{
+					CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, pupAccess, pup, DDR_PHY_DATA, 0x1 + CS_BYTE_GAP(uiCs), ctrlADLL1[interfaceId*uiCs*octetsPerInterfaceNum+pup]));
+				}
+			}
+		}
+		mvPrintf("Final,CS %d,%s,Leveling,Result,Adll,", uiCs,((direction==0) ? "TX":"RX"));
+		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+		{
+			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+			if (mode == 1)
+			{
+				for(pup=startPup; pup <=endPup; pup++)
+				{
+					VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
+					mvPrintf("I/F%d-PHY%d , ",interfaceId,pup);
+				}
+			}
+			else
+			{
+				mvPrintf("I/F%d , ",interfaceId);
+			}
+		}
+		mvPrintf("\n");
+		for(adll = 0 ; adll < ADLL_LENGTH ; adll++)
+		{
+			adllValue = (direction == 0) ? ((adll*2)-32):((adll*3)-48);
+			mvPrintf("Final,%s,LevelingSweep,Result, %d ,",((direction==0) ? "TX":"RX"),adllValue);
+
+			for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++){
+				VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+				for( pup=startPup; pup <=endPup; pup++)
+				{
+					mvPrintf("%8d , ",ctrlSweepres[adll][interfaceId][pup]);
+				}
+			}
+			mvPrintf("\n");
+		}
+		/*Write back to the phy the Rx DQS value, we store in the begging. */
+		writeLevelingValue(devNum,ctrlADLL,ctrlLevelPhase, (reg +  uiCs * CS_REGISTER_ADDR_OFFSET));
+		if(direction == 0)
+		{
+			mvHwsDdr3TipWriteAdllValue(devNum,ctrlADLL1, (0x1 + (uiCs * CS_REGISTER_ADDR_OFFSET)));
+		}
+		/* print adll results */
+		mvHwsDdr3TipReadAdllValue(devNum,ctrlADLL, (reg + uiCs * CS_REGISTER_ADDR_OFFSET), MASK_ALL_BITS);
+		mvPrintf("%s,DQS,Leveling,,,",(direction==0) ? "Tx":"Rx");
+		printAdll(devNum, ctrlADLL);
+		printPh(devNum, ctrlLevelPhase);
+	}/*End of CS*/
+
+    ddr3TipResetFifoPtr(devNum);
+    return 0;
+}
+#endif
+
 
 void printTopology(MV_HWS_TOPOLOGY_MAP *pTopologyDB)
 {
 	GT_U32 ui, uj;
 
 	mvPrintf("\tinterfaceMask: 0x%x\n",   pTopologyDB->interfaceActiveMask);
-	mvPrintf("\tNum Bus:  %d\n",   pTopologyDB->numOfBusPerInterface);
+	mvPrintf("\tNum Bus:  %d\n",   ddr3TipDevAttrGet(0, MV_ATTR_OCTET_PER_INTERFACE));
 	mvPrintf("\tactiveBusMask: 0x%x\n",   pTopologyDB->activeBusMask);
 
 	for( ui = 0; ui < MAX_INTERFACE_NUM; ui++ )
@@ -1538,7 +1741,7 @@
 	}
 }
 #endif
-
+#ifndef EXCLUDE_SWITCH_DEBUG
 /*****************************************************************************
 Execute XSB Test transaction (rd/wr/both)
 ******************************************************************************/
@@ -1578,14 +1781,7 @@
 }
 
 #else /*EXCLUDE_SWITCH_DEBUG*/
-GT_U32 rlVersion = 1; /* 0 - old RL machine */
-GT_U32 vref = 0x4;
 GT_U32  startXsbOffset = 0;
-GT_U8 csMaskReg[]=
-{
-    0, 4, 8, 12 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 GT_STATUS RunXsbTest(GT_U32 devNum, GT_U32 uiMemAddress, GT_U32 writeType, GT_U32 readType, GT_U32 burstLength)
 {
 	return GT_OK;
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3DebugRxIoBist.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3DebugRxIoBist.c
new file mode 100755
index 0000000..8fd4d13
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3DebugRxIoBist.c
@@ -0,0 +1,458 @@
+/*******************************************************************************
+*                Copyright 2001, Marvell International Ltd.
+* This code contains confidential information of Marvell semiconductor, inc.
+* no rights are granted herein under any patent, mask work right or copyright
+* of Marvell or any third party.
+* Marvell reserves the right at its sole discretion to request that this code
+* be immediately returned to Marvell. This code is provided "as is".
+* Marvell makes no warranties, express, implied or otherwise, regarding its
+* accuracy, completeness or performance.
+********************************************************************************
+* mvHwsDdr3DebugRxIoBist.c.c
+*
+* DESCRIPTION: RX IO BIST Test
+*
+*
+* DEPENDENCIES:
+*
+* FILE REVISION NUMBER:
+*       $Revision: 204 $
+******************************************************************************/
+
+#include "mvDdr3TrainingIpFlow.h"
+#include "mvDdr3LoggingDef.h"
+
+#if defined(MV_HWS_RX_IO_BIST) || defined(MV_HWS_RX_IO_BIST_ETP)
+
+/************************** definitions ******************************/
+
+#define MV_IO_BIST_PATTERN_SIZE     4
+
+/************************** enums ************************************/
+
+typedef enum
+{
+    TEST_STOP,
+    TEST_STAR,
+    TEST_STOP_AND_START,
+} MV_TEST_ENABLE;
+
+/************************** globals **********************************/
+
+GT_U32 ioBistCounter;
+extern MV_HWS_TOPOLOGY_MAP *topologyMap;
+
+/************************** Pre-Declaration **************************/
+
+void mvHwsInitDataAgrressor(GT_U8 devNum);
+void mvHwsInitCaAgressor(GT_U8 devNum);
+GT_BOOL mvHwsDataAndSyncSelect(GT_U8 devNum, GT_U32 interfaceId, GT_U32 pup);
+void mvHwsSetRxPbsDelay(GT_U8 devNum, GT_U32 DqValue, GT_U32 DqsValue);
+void mvHwsTestEnable(GT_U8 devNum, GT_U32 interfaceId, MV_HWS_ACCESS_TYPE phyAccess, GT_U32 pup, MV_TEST_ENABLE enMode);
+void mvHwsPhyAndTestReset(GT_U8 devNum, GT_U32 interfaceId, MV_HWS_ACCESS_TYPE phyAccess, GT_U32 pup);
+void nvHwsIoBistTest(GT_U8 devNum, GT_U32 interfaceId);
+void mvHwsSetVictimPattern(GT_U8 devNum, GT_U32 interfaceId);
+void mvHwsSetNoisePattern(GT_U8 devNum, GT_U32 interfaceId);
+void mvHwsIoBistTestRx(GT_U8 devNum, GT_U32 interfaceId, GT_U32 pup,GT_U32 victBit, GT_U32 agrBits, GT_U32 rxAdll);
+GT_U32 mvHwsConfigureTxAdllOpt(GT_U8 devNum,GT_U32 interfaceId, GT_U32 pup, GT_U32 VictBit, GT_U32 AgrBits, GT_U32 dirrection);
+void mvHwsFillPattern(GT_U8 devNum, GT_U32 interfaceId, GT_BOOL isNoise, GT_U32 pattern[MV_IO_BIST_PATTERN_SIZE]);
+
+/************************** functions ********************************/
+
+GT_STATUS mvHwsIoBistTest(GT_U8 devNum)
+{
+    GT_U32 interfaceId;
+
+    mvHwsSetRxPbsDelay(devNum, 0x1F, 0xF);
+
+#ifdef MV_HWS_RX_IO_BIST_ETP
+    mvHwsInitCaAgressor(devNum);
+#endif /* MV_HWS_RX_IO_BIST_ETP */
+
+    mvHwsInitDataAgrressor(devNum);
+
+    for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        nvHwsIoBistTest(devNum, interfaceId);
+    }
+
+    return GT_OK;
+}
+
+void mvHwsSetRxPbsDelay(GT_U8 devNum, GT_U32 DqValue, GT_U32 DqsValue)
+{
+    GT_U32 interfaceId;
+    GT_U32 busNum;
+    GT_U32 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
+        {
+            VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
+            mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, 0x5f, DqValue);
+            mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, 0x54, DqsValue);
+            mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, 0x55, DqsValue);
+            mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, 0x2, 0xDF);
+        }
+    }
+}
+
+void mvHwsInitCaAgressor(GT_U8 devNum)
+{
+    GT_U32 interfaceId;
+
+    /*aggressive pattern for all C/A signals*/
+                                  /* 0-15   16-31   32-47   48-63 */
+    GT_U32 addrKillerPattern[MV_IO_BIST_PATTERN_SIZE] = { 0xcfc0, 0x330c, 0x3333, 0xc0cc };
+
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+
+        /*Tx ETP mode*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, 0xB0, 0x2);
+
+        /*Continuous mode*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, 0xC8, 0x1);
+
+        /* PHY & Test reset/un-reset*/
+        mvHwsPhyAndTestReset(devNum, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE);
+
+        /*fill FIFO with aggressive pattern*/
+        mvHwsFillPattern(devNum, interfaceId, GT_FALSE, addrKillerPattern);
+
+        /*clock N invert*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, 0xB6, 0xC);
+
+        /*Select Noise FIFO*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, 0xB4, 0x0);
+
+        /*Stop & Start Test*/
+        mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TEST_STOP_AND_START);
+    }
+}
+
+void mvHwsInitDataAgrressor(GT_U8 devNum)
+{
+    GT_U32 interfaceId;
+
+    /*aggressive pattern for all Data signals*/
+                                  /* 0-15   16-31   32-47   48-63 */
+    GT_U32 dataKillerPattern[4] = { 0x52b8, 0x8a55, 0xa6b3, 0x066d };
+
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        /*Tx ETP mode*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xB0, 0x2);
+
+        /*Continuous mode*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xC8, 0x1);
+
+        /* PHY & Test reset/un-reset*/
+        mvHwsPhyAndTestReset(devNum, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE);
+
+        /*fill FIFO with aggressive pattern*/
+        mvHwsFillPattern(devNum, interfaceId, GT_FALSE, dataKillerPattern);
+
+        /*Select Noise FIFO*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xB4, 0x30);
+
+        /*Stop & Start Test*/
+        mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TEST_STOP_AND_START);
+    }
+}
+
+void nvHwsIoBistTest(GT_U8 devNum, GT_U32 interfaceId)
+{
+    GT_U32 dq;
+    GT_U32 AgrBits;
+    GT_U32 VictBit;
+    GT_U32 pup;
+    GT_U32 txAdll;
+    GT_U32 rxAdll;
+    GT_U32 mask = 0x7ff;
+    GT_U32 results[MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_DQ_NUM];
+
+    GT_U32 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    mvPrintf("octetsPerInterfaceNum: %d\n",octetsPerInterfaceNum);
+
+    mvHwsSetVictimPattern(devNum, interfaceId);
+
+    for(dq = 0; dq < octetsPerInterfaceNum * 8 ; dq++)
+    {
+        pup = dq/8;
+
+        VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
+        VictBit = dq%8;
+        AgrBits = (VictBit > 3) ? (~(1<<(VictBit + 2)) & mask) : (~(1<<VictBit) & mask); /* each pup=11 Bits  8 dq bits, Bits 4 & 5 are DQS, Bit 10=DM */
+
+        mvHwsSetNoisePattern(interfaceId, pup);
+        hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+
+        /* PHY & Test reset/un-reset*/
+        mvHwsPhyAndTestReset(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup);
+
+        /*Stop Test*/
+        mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, TEST_STOP);
+
+        txAdll = mvHwsConfigureTxAdllOpt(devNum, interfaceId, pup, VictBit, AgrBits, 1) + 1;
+        if ((txAdll > 0) && (txAdll < 5)) {
+            txAdll = mvHwsConfigureTxAdllOpt(devNum, interfaceId, pup, VictBit, AgrBits, 0) - 1;
+        }
+        mvPrintf("txAdll: %d\n",txAdll);
+
+        /*Set Optimal DQS_WR*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x1, txAdll);
+
+        /*Set Optimal Receiver Calibration*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xDB, 0x3F);
+
+        for(rxAdll = 0; rxAdll < 32; rxAdll++)   /* Search RX Window */
+        {
+            /* PHY & Test reset/un-reset*/
+            mvHwsPhyAndTestReset(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup);
+
+            /*Stop Test*/
+            mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, TEST_STOP);
+
+            /*Set Current Rx ADLL*/
+            mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x3, rxAdll);
+            mvHwsIoBistTestRx(devNum,interfaceId,pup,VictBit, AgrBits, rxAdll);
+        }
+        /*Reset DQS_WR*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x1, 0x0);
+        /*Reset DQS_RD*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x3, 0x0);
+        mvPrintf("\n ########## Rx - win size: %d #########\n",ioBistCounter);
+        results[interfaceId][pup][dq%8] = ioBistCounter;
+        ioBistCounter = 0;
+    }
+    /*print final results*/
+    mvPrintf("Interface     PUP     BIT     X_WIN_SIZE\n");
+    mvPrintf("-----------------------------------------\n");
+    for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        for (pup=0; pup<octetsPerInterfaceNum; pup++)
+        {
+            VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
+            for(dq = 0; dq < 8 ; dq++)
+            {
+                mvPrintf("%d        %d      %d      %d\n",interfaceId,pup,dq,results[interfaceId][pup][dq%8]);
+            }
+        }
+    }
+}
+
+void mvHwsTestEnable(GT_U8 devNum, GT_U32 interfaceId, MV_HWS_ACCESS_TYPE phyAccess, GT_U32 pup, MV_TEST_ENABLE enMode)
+{
+    if((enMode == TEST_STOP) || (enMode == TEST_STOP_AND_START))
+    {
+        /*Stop Test*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0xB1, 0x0);
+        hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+    }
+
+    if((enMode == TEST_STAR) || (enMode == TEST_STOP_AND_START))
+    {
+        /*Start Test*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0xB1, 0x1);
+        hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+    }
+}
+
+void mvHwsPhyAndTestReset(GT_U8 devNum, GT_U32 interfaceId, MV_HWS_ACCESS_TYPE phyAccess, GT_U32 pup)
+{
+    /*Phy Reset*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0x90, 0x2);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+
+    /*Phy Un-Reset*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0x90, 0x2002);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+
+    /*Test Reset*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0xBD, 0x1);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+
+    /*Test Un-Reset*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, phyAccess, pup, DDR_PHY_DATA, 0xBD, 0x0);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+}
+
+void mvHwsFillPattern(GT_U8 devNum, GT_U32 interfaceId, GT_BOOL isNoise, GT_U32 pattern[MV_IO_BIST_PATTERN_SIZE])
+{
+    GT_U32 offset = (isNoise) ? 0xC4 : 0xC0;
+    GT_U8 i;
+
+    for(i = 0; i < MV_IO_BIST_PATTERN_SIZE; i++)
+    {
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, offset + i, pattern[i]);
+    }
+}
+
+void mvHwsSetVictimPattern(GT_U8 devNum, GT_U32 interfaceId)
+{
+                                   /* 0-15   16-31   32-47   48-63 */
+    GT_U32 killerVictPattern[MV_IO_BIST_PATTERN_SIZE] = { 0xB9A6, 0x45A6, 0x5819, 0xDB9A };
+
+    /*fill FIFO with aggressive pattern*/
+    mvHwsFillPattern(devNum, interfaceId, GT_TRUE, killerVictPattern);
+
+    /*TBD - need to extend for BC2*/
+}
+
+void mvHwsSetNoisePattern(GT_U8 devNum, GT_U32 interfaceId)
+{
+                                /* 0-15   16-31   32-47   48-63 */
+    GT_U32 allZeroPattern[MV_IO_BIST_PATTERN_SIZE] = { 0x0000, 0x0000, 0x0000, 0x0000 };
+
+    /*fill FIFO with aggressive pattern*/
+    mvHwsFillPattern(devNum, interfaceId, GT_FALSE, allZeroPattern);
+
+    /*TBD - need to extend for BC2*/
+}
+
+void mvHwsIoBistTestRun(GT_U8 devNum, GT_U32 interfaceId, GT_U32 pup, GT_U32 victBit, GT_U32 agrBits)
+{
+    GT_U32 timeout = 0;
+    GT_U32 dataVal;
+
+    /*Configure I/O bist Mode*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB0, 0x3);
+
+    /*Set Repeat to 31*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xBE, 0xF);
+
+    /*Configure continuous mode to active*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xC8, 0x1);
+
+    /*Configure Sync Pattern to 0x7*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xBC, 0x7);
+
+    /* PHY & Test reset/un-reset*/
+    mvHwsPhyAndTestReset(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup);
+
+    /*Select Rx Bit*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB8, victBit);
+
+    /*Select Aggressor*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB4, agrBits);
+
+    /*Stop & Start Test*/
+    mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, TEST_STOP_AND_START);
+
+    do
+    {
+        mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB1, &dataVal);
+        hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+        if (timeout++>16)
+        {
+            /*Stop Test*/
+            mvHwsTestEnable(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, TEST_STOP);
+        }
+    } while (dataVal == 1);
+}
+
+GT_BOOL mvHwsDataAndSyncSelect(GT_U8 devNum, GT_U32 interfaceId, GT_U32 pup)
+{
+    GT_U32 dataResult;
+    GT_U32 syncResult;
+    GT_U32 dataVal;
+
+    /*Data Select*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB7, 0x1);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+    mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB2, &dataVal);
+    dataResult = dataVal;
+
+    /*Sync Select*/
+    mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB7, 0x0);
+    hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10);
+    mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0xB2, &dataVal);
+    syncResult = dataVal;
+
+    return ((dataResult == 0) && (syncResult == 0)) ? GT_TRUE : GT_FALSE;
+}
+
+GT_U32 mvHwsConfigureTxAdllOpt(GT_U8 devNum,GT_U32 interfaceId, GT_U32 pup, GT_U32 victBit, GT_U32 agrBits, GT_U32 dirrection)
+{
+	GT_U32 txAdll;
+	GT_U32 endLoop;
+    GT_BOOL isPass;
+
+	mvPrintf("direction = %d\n",dirrection);
+	if (dirrection) {
+		endLoop = 64;
+		txAdll = 5;
+	} else {
+		endLoop = 0;
+		txAdll = 64;
+	}
+
+	/*Set Rx Adll to min*/
+	mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x3, 0x0);
+
+	while(txAdll != endLoop)
+	{
+        if (dirrection) {
+            txAdll ++;
+        } else {
+            txAdll --;
+        }
+
+        /*Set Tx Adll*/
+        mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, 0x1, txAdll);
+
+        /* Run I/O BIST test */
+        mvHwsIoBistTestRun(devNum, interfaceId, pup, victBit, agrBits);
+
+        /* Check if Sync and/or Data pass */
+        isPass = mvHwsDataAndSyncSelect(devNum, interfaceId, pup);
+        if(isPass)
+        {
+            /* looking for failure so continue the search */
+            mvPrintf(".");
+        }
+        else
+        {
+            return txAdll;
+        }
+    }
+
+    /* we shouldn't reach this point. if so, it's en error */
+    mvPrintf("mvHwsConfigureTxAdllOpt: Error: couldn't find failure point\n");
+
+    return 0;
+}
+
+void mvHwsIoBistTestRx(GT_U8 devNum, GT_U32 interfaceId, GT_U32 pup,GT_U32 victBit, GT_U32 agrBits, GT_U32 rxAdll)
+{
+    GT_BOOL isPass;
+
+    /* Run I/O BIST test */
+    mvHwsIoBistTestRun(devNum, interfaceId, pup, victBit, agrBits);
+
+    mvPrintf("interfaceId: %d   PUP: %d   VictBit: %d  AgrBits: 0x%x  rxAdll: %d --> ",interfaceId, pup, victBit, agrBits, rxAdll);
+
+    /* Check if Sync and/or Data pass */
+    isPass = mvHwsDataAndSyncSelect(devNum, interfaceId, pup);
+    if(isPass)
+    {
+        mvPrintf("PASS\n");
+        ioBistCounter++;
+    }
+    else
+    {
+        mvPrintf("-----\n");
+    }
+}
+
+#endif /* defined(MV_HWS_RX_IO_BIST) || defined(MV_HWS_RX_IO_BIST_ETP) */
+
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Training.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Training.c
index 326939d..7a5f485 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Training.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3Training.c
@@ -31,10 +31,6 @@
 #include "mvDdr3TrainingIpPrvIf.h"
 #include "mvDdr3LoggingDef.h"
 
-#ifdef CONFIG_DDR4
-#include "mvHwsDdr4Training.h"
-#include "mvHwsDdr4MprPdaIf.h"
-#endif
 /************************** definitions ******************************/
 #ifdef FreeRTOS
 #define DFX_BAR1_BASE        (0x80000000)
@@ -50,7 +46,6 @@
 /*#define TIME_2_CLOCK_CYCLES(prm, clk)   ((prm-1)/clk)*/
 #define TIME_2_CLOCK_CYCLES             CEIL_DIVIDE
 
-
 #define GET_CS_FROM_MASK(mask) (csMask2Num[mask])
 #define CS_CBE_VALUE(csNum)   (csCbeReg[csNum])
 
@@ -62,7 +57,7 @@
 GT_U32  PhyReg0Val = 0;
 GT_U32  PhyReg1Val = 8;
 GT_U32  PhyReg2Val = 0;
-GT_U32  PhyReg3Val = 0xA;
+GT_U32  PhyReg3Val = MV_PARAMS_UNDEFINED;
 MV_HWS_DDR_FREQ initFreq = DDR_FREQ_667;
 MV_HWS_DDR_FREQ lowFreq = DDR_FREQ_LOW_FREQ;
 MV_HWS_DDR_FREQ mediumFreq;
@@ -71,13 +66,9 @@
 GT_U32* dqMapTable = NULL;
 GT_U32 odtConfig = 1;
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
-GT_U8  isPllBeforeInit = 0, isAdllCalibBeforeInit = 0, isDfsInInit = 0;
-GT_U32 dfsLowFreq = 130;
-#else
 GT_U8  isPllBeforeInit = 0, isAdllCalibBeforeInit = 1, isDfsInInit = 0;
-GT_U32 dfsLowFreq = 100;
-#endif
+GT_U32 dfsLowFreq;
+
 GT_U32 gRttNomCS0, gRttNomCS1;
 GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
 
@@ -109,12 +100,25 @@
 GT_U32 delayEnable = 0;
 static GT_U32 freqMask[HWS_MAX_DEVICE_NUM][DDR_FREQ_LIMIT];
 GT_BOOL rlMidFreqWA = GT_FALSE;
-extern GT_U32 ddr4TipConfigurePhyVrefTap;
 
-#if defined (CONFIG_ALLEYCAT3)
-GT_U32 mvHwsmemSize[] = { ADDR_SIZE_512Mb, ADDR_SIZE_1Gb, ADDR_SIZE_2Gb, ADDR_SIZE_4Gb ,ADDR_SIZE_8Gb };
-#define  MV_DEVICE_MAX_DRAM_ADDRESS_SIZE          ADDR_SIZE_2Gb
-#endif
+GT_U32 vrefInitialValue = 0x4;
+GT_U32 ckDelay = MV_PARAMS_UNDEFINED;
+
+/*Design Guidelines parameters*/
+GT_U32 gZpriData = MV_PARAMS_UNDEFINED; /* controller data - P drive strength */
+GT_U32 gZnriData = MV_PARAMS_UNDEFINED; /* controller data - N drive strength */
+GT_U32 gZpriCtrl = MV_PARAMS_UNDEFINED; /* controller C/A - P drive strength */
+GT_U32 gZnriCtrl = MV_PARAMS_UNDEFINED; /* controller C/A - N drive strength */
+
+GT_U32 gZpodtData = MV_PARAMS_UNDEFINED; /* controller data - P ODT */
+GT_U32 gZnodtData = MV_PARAMS_UNDEFINED; /* controller data - N ODT */
+GT_U32 gZpodtCtrl = MV_PARAMS_UNDEFINED; /* controller data - P ODT */
+GT_U32 gZnodtCtrl = MV_PARAMS_UNDEFINED; /* controller data - N ODT */
+
+GT_U32 uiODTConfig = MV_PARAMS_UNDEFINED;
+GT_U32 gRttNom = MV_PARAMS_UNDEFINED;
+GT_U32 gRttWR = MV_PARAMS_UNDEFINED;
+GT_U32 gDic = MV_PARAMS_UNDEFINED;
 
 /************************** globals ***************************************/
 
@@ -134,13 +138,6 @@
                        CENTRALIZATION_RX_MASK_BIT   |
                        CENTRALIZATION_TX_MASK_BIT   );
 
-void ddr3PrintVersion()
-{
-	mvPrintf(DDR3_TIP_VERSION_STRING);
-}
-
-
-
 extern GT_U32 isPllOld;
 extern ClValuePerFreq casLatencyTable[];
 extern PatternInfo patternTable[] ;
@@ -156,21 +153,7 @@
 extern GT_U16 rfcTable[];
 extern GT_U32 speedBinTableTRc[];
 extern GT_U32 speedBinTableTRcdTRp[];
-extern GT_U32 ckDelay, ckDelay_16;
-extern GT_U32 gZpriData;
-extern GT_U32 gZnriData;
-extern GT_U32 gZpriCtrl;
-extern GT_U32 gZnriCtrl;
-
-extern GT_U32 gZpodtData;
-extern GT_U32 gZnodtData;
-extern GT_U32 gZpodtCtrl;
-extern GT_U32 gZnodtCtrl;
-
-extern GT_U32 gDic;
-extern GT_U32 uiODTConfig;
-extern GT_U32 gRttNom;
-
+extern GT_U32 mvMemSize[];
 
 /************************** pre-declarations ******************************/
 static GT_STATUS    ddr3TipDDR3Ddr3TrainingMainFlow
@@ -225,6 +208,10 @@
     MV_HWS_DDR_FREQ			frequency
 );
 
+#if defined(MV_HWS_RX_IO_BIST) || defined(MV_HWS_RX_IO_BIST_ETP)
+GT_STATUS mvHwsIoBistTest(GT_U8 devNum);
+#endif
+
 /************************** global data ******************************/
 
 static PageElement pageParam[] =
@@ -331,6 +318,25 @@
 static GT_STATUS ddr3TipRankControl(GT_U32 devNum, GT_U32 interfaceId);
 
 /*****************************************************************************
+Version
+******************************************************************************/
+
+const GT_CHAR* mvHwsDdr3TipVersionGet(void)
+{
+    return DDR3_TIP_VERSION_STRING;
+}
+
+extern const GT_CHAR* mvHwsDdr4SubLibVersionGet(void);
+
+void ddr3PrintVersion()
+{
+    mvPrintf(mvHwsDdr3TipVersionGet());
+#ifdef CONFIG_DDR4
+    mvPrintf(mvHwsDdr4SubLibVersionGet());
+#endif
+}
+
+/*****************************************************************************
 Register freq mask
 ******************************************************************************/
 GT_STATUS mvHwsDdr3TipRegisterFreqMask(GT_U32 devNum, GT_U32* freqMaskUsr)
@@ -354,18 +360,78 @@
 {
 	devNum = devNum; /* avoid warnings */
 
-	if(params->ckDelay != -1)
-		ckDelay = params->ckDelay;
+	if(params->ckDelay != MV_PARAMS_UNDEFINED)     ckDelay = params->ckDelay;
 
-	if(params->ckDelay_16 != -1)
-		ckDelay_16 =  params->ckDelay_16;
-	if(params->PhyReg3Val != -1)
-		PhyReg3Val = params->PhyReg3Val;
+	if(params->PhyReg3Val != MV_PARAMS_UNDEFINED)  PhyReg3Val = params->PhyReg3Val;
+
+	if(params->gRttNom != MV_PARAMS_UNDEFINED)     gRttNom = params->gRttNom;
+	if(params->gRttWR != MV_PARAMS_UNDEFINED)     gRttWR = params->gRttWR;
+	if(params->gDic != MV_PARAMS_UNDEFINED)        gDic = params->gDic;
+	if(params->uiODTConfig != MV_PARAMS_UNDEFINED) uiODTConfig = params->uiODTConfig;
+
+	if(params->gZpriData != MV_PARAMS_UNDEFINED) gZpriData = params->gZpriData;
+	if(params->gZnriData != MV_PARAMS_UNDEFINED) gZnriData = params->gZnriData;
+	if(params->gZpriCtrl != MV_PARAMS_UNDEFINED) gZpriCtrl = params->gZpriCtrl;
+	if(params->gZnriCtrl != MV_PARAMS_UNDEFINED) gZnriCtrl = params->gZnriCtrl;
+
+	if(params->gZpodtData != MV_PARAMS_UNDEFINED) gZpodtData = params->gZpodtData;
+	if(params->gZnodtData != MV_PARAMS_UNDEFINED) gZnodtData = params->gZnodtData;
+	if(params->gZpodtCtrl != MV_PARAMS_UNDEFINED) gZpodtCtrl = params->gZpodtCtrl;
+	if(params->gZnodtCtrl != MV_PARAMS_UNDEFINED) gZnodtCtrl = params->gZnodtCtrl;
+
+	DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DGL params are 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
+				gZpriData, gZnriData, gZpriCtrl, gZnriCtrl,
+				gZpodtData, gZnodtData, gZpodtCtrl, gZnodtCtrl,
+				gRttNom, gDic, uiODTConfig, gRttWR));
 
 	return GT_OK;
 }
 
 /*****************************************************************************
+Configure phy ( called by static init controller)  for static flow
+******************************************************************************/
+GT_STATUS    ddr3TipConfigurePhy
+(
+    GT_U32    devNum
+)
+{
+    GT_U32 interfaceId, phyId;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_ZRI_CALIB_PHY_REG, ((0x7f & gZpriData) << 7 | (0x7f & gZnriData))));
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, PAD_ZRI_CALIB_PHY_REG, ((0x7f & gZpriCtrl) << 7 | (0x7f & gZnriCtrl))));
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_ODT_CALIB_PHY_REG, ((0x3f & gZpodtData) << 6 | (0x3f & gZnodtData))));
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, PAD_ODT_CALIB_PHY_REG, ((0x3f & gZpodtCtrl) << 6 | (0x3f & gZnodtCtrl))));
+
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_PRE_DISABLE_PHY_REG, 0));
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, CMOS_CONFIG_PHY_REG, 0));
+    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, CMOS_CONFIG_PHY_REG, 0));
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+	{
+		/* check if the interface is enabled */
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        for(phyId=0;phyId<octetsPerInterfaceNum; phyId++)
+        {
+   			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, phyId)
+            /* Vref & clamp */
+            CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  phyId, DDR_PHY_DATA, PAD_CONFIG_PHY_REG,   ((clampTbl[interfaceId] << 4) | vrefInitialValue ), ((0x7 << 4) | 0x7) ));
+            /* clamp not relevant for control */
+            CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  phyId, DDR_PHY_CONTROL, PAD_CONFIG_PHY_REG,    0x4 , 0x7 ));
+        }
+    }
+
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_PHY_EDGE ) == MV_DDR_PHY_EDGE_POSITIVE){
+		CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0x90, 0x6002));
+	}
+
+#ifdef CONFIG_DDR4
+    ddr4TipConfigurePhy(devNum);
+#endif
+
+   return GT_OK;
+}
+
+/*****************************************************************************
 Configure CS
 ******************************************************************************/
 GT_STATUS ddr3TipConfigureCs(GT_U32 devNum, GT_U32 interfaceId, GT_U32 csNum, GT_U32 enable)
@@ -418,7 +484,9 @@
 	GT_U32 csCount;
 	GT_U32 csBitmask;
 	GT_U32 currCsNum = 0;
-	for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+	for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
 		csCount = 0;
@@ -461,7 +529,8 @@
     GT_U32 clValue = 0, cwlVal = 0;
     GT_U32 refreshIntervalCnt = 0,  busCnt = 0, adllTap = 0;
     MV_HWS_ACCESS_TYPE	  accessType = ACCESS_TYPE_UNICAST;
-     GT_U32 dataRead[MAX_INTERFACE_NUM];
+    GT_U32 dataRead[MAX_INTERFACE_NUM];
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("InitController, doMrsPhy=%d, isCtrl64Bit=%d\n", initCntrPrm->doMrsPhy, initCntrPrm->isCtrl64Bit));
 
@@ -477,7 +546,7 @@
             VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
             DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("active IF %d\n", interfaceId));
             memMask = 0;
-            for(busIndex=0; busIndex < GET_TOPOLOGY_NUM_OF_BUSES(devNum) ; busIndex++)
+            for(busIndex=0; busIndex < octetsPerInterfaceNum ; busIndex++)
             {
         		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
                 memMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busIndex].mirrorEnableBitmask;
@@ -508,7 +577,7 @@
             /* SRMode */
             CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, SDRAM_CONFIGURATION_REG, dataValue, 0x100FFFF));
 
-			/* Intrleave first command pre-charge enable (TBD) */
+            /* Interleave first command pre-charge enable (TBD) */
             CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, SDRAM_OPEN_PAGE_CONTROL_REG, (1 << 10), (1 << 10)));
 
             /* PHY configuration*/
@@ -531,11 +600,13 @@
 
             /*Pad calibration control - enable*/
             CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, CALIB_MACHINE_CTRL_REG, 0x1, 0x1));
-#if !defined(CONFIG_ARMADA_38X) && !defined(CONFIG_ALLEYCAT3) && !defined (CONFIG_ARMADA_39X)
-            /* DDR3_Rank_Control \96 Part of the Generic code */
-            /*: CS1 Mirroring enable + w/a for JIRA DUNIT-14581 */ 
-            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, RANK_CTRL_REG, 0x27, MASK_ALL_BITS));
-#endif
+
+			if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3){
+		        /* DDR3_Rank_Control \96 Part of the Generic code */
+		        /*: CS1 Mirroring enable + w/a for JIRA DUNIT-14581 */
+		        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, RANK_CTRL_REG, 0x27, MASK_ALL_BITS));
+			}
+
             csMask = 0;
             dataValue = 0x7;
             /* Address ctrl \96 Part of the Generic code 
@@ -561,7 +632,7 @@
 
             dataValue = (topologyMap->interfaceParams[interfaceId].busWidth == BUS_WIDTH_8) ? 0 : 1;
             /* create merge cs mask for all cs available in dunit */
-            for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+            for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
             {
        			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
                 csMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask;
@@ -584,9 +655,11 @@
 	            cwlVal = topologyMap->interfaceParams[interfaceId].casWL;
 	            DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("clValue 0x%x cwlVal 0x%x \n", clValue, cwlVal));
 
+                tWR = TIME_2_CLOCK_CYCLES(speedBinTable(speedBinIndex,speedBinTableElements_tWR), tCKCLK);
+
 	            dataValue = ((clMaskTable[clValue] & 0x1) << 2) | ((clMaskTable[clValue] & 0xE)  <<  3);
-	            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, MR0_REG, dataValue,(0x7 << 4) | (1 << 2)));
-				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, MR0_REG, twrMaskTable[tWR + 1],0xE00));
+	            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, MR0_REG, dataValue, (0x7 << 4) | (1 << 2)));
+				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, MR0_REG, (twrMaskTable[tWR + 1] << 9), (0x7 << 9)));
 
 				/* MR1: Set RTT and DIC Design GL values configured by user */
 				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, MR1_REG, gDic | gRttNom, 0x266));
@@ -597,18 +670,21 @@
 	            2)CAS Write  Latency */
 	            dataValue = (cwlMaskTable[cwlVal] << 3);
 	            dataValue |= ((topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? (1 << 7) : 0);
+				dataValue |= gRttWR;
 	            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3) | (0x1<<7) | (0x3<<9)));
             }
 
 			ddr3TipWriteOdt(devNum,  accessType, interfaceId, clValue, cwlVal);
             ddr3TipSetTiming(devNum, accessType, interfaceId, freq);
 
-#if !defined(CONFIG_ARMADA_38X) && !defined(CONFIG_ALLEYCAT3) && !defined (CONFIG_ARMADA_39X)
-			/*WrBuff, RdBuff*/
-			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DUNIT_CONTROL_HIGH_REG, 0x1000119,0x100017F));
-#else
-			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DUNIT_CONTROL_HIGH_REG, 0x177,0x1000177));
-#endif
+			if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3){
+				/*WrBuff, RdBuff*/
+				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DUNIT_CONTROL_HIGH_REG, 0x1000119,0x100017F));
+			}
+			else{
+				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DUNIT_CONTROL_HIGH_REG, 0x177,0x1000177));
+			}
+
 		    if (initCntrPrm->isCtrl64Bit)
 	      	{
 	        /* disable 0.25 cc delay */
@@ -645,20 +721,20 @@
 
 			/*Set Active control for ODT write transactions*/
 			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1494, uiODTConfig, MASK_ALL_BITS));
-#if defined (CONFIG_ALLEYCAT3)
-			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, 0x14a8, 0x900,0x900));
-			/*WA: Controls whether to float The Control pups outputs during Self Refresh*/
-			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, 0x16d0, 0,0x8000));
-#endif
+
+            if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) == MV_TIP_REV_3) /* AC3/BobK only */
+            {
+			    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, 0x14a8, 0x900,0x900));
+			    /*WA: Controls whether to float The Control pups outputs during Self Refresh*/
+			    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, 0x16d0, 0,0x8000));
+            }
         }
     }
     else
     {
 #ifdef STATIC_ALGO_SUPPORT
         CHECK_STATUS(ddr3TipStaticInitController(devNum));
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ARMADA_39X)
 		CHECK_STATUS(ddr3TipStaticPhyInitController(devNum));
-#endif
 #endif/*STATIC_ALGO_SUPPORT*/
     }
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
@@ -670,16 +746,13 @@
 	    {
 	      CHECK_STATUS(ddr3TipPadInv(devNum, interfaceId));
 	    }
-    
 
-    /*Pad calibration control - disable*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, CALIB_MACHINE_CTRL_REG, 0x0, 0x1));
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, CALIB_MACHINE_CTRL_REG, calibrationUpdateControl<<3, 0x3<<3));
+        /*Pad calibration control - disable*/
+        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, CALIB_MACHINE_CTRL_REG, 0x0, 0x1));
+        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, CALIB_MACHINE_CTRL_REG, calibrationUpdateControl<<3, 0x3<<3));
     }
 #ifdef CONFIG_DDR4
-	CHECK_STATUS(ddr4TipCalibrationAdjust(devNum, ddr4TipConfigurePhyVrefTap,1,0));/*devNum,VrefTap,Vref_en,POD_Only*/
-    ddr4ModeRegsInit(devNum);
-    ddr4SdramConfig(devNum);
+	CHECK_STATUS(ddr4TipCalibrationAdjust(devNum, 1,0));/*devNum,VrefTap,Vref_en,POD_Only*/
 #endif
 
     CHECK_STATUS(ddr3TipEnableInitSequence(devNum));
@@ -705,15 +778,13 @@
     MV_HWS_SPEED_BIN speedBinIndex;
     MV_HWS_DDR_FREQ freq = DDR_FREQ_LIMIT;
     GT_U32 interfaceId = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-
-    freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq;
-    /*osMemCpy(&topologyMap[devNum], (void*) topology,sizeof(MV_HWS_TOPOLOGY_MAP));*/
     ddr3TipSetTopologyMap(devNum, topologyMapPtr);
     topologyMap = ddr3TipGetTopologyMap(devNum);
     CHECK_STATUS(ddr3TipGetFirstActiveIf((GT_U8)devNum, topologyMap->interfaceActiveMask, &firstActiveIf));
-    DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("board IF_Mask=0x%x numOfBusPerInterface=0x%x\n",
-					   topologyMap->interfaceActiveMask, topologyMap->numOfBusPerInterface));
+    DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("board IF_Mask=0x%x octetsPerInterfaceNum=0x%x\n",
+					   topologyMap->interfaceActiveMask, octetsPerInterfaceNum));
 
     /* if CL, CWL values are missing in topology map, then fill them according to speedbin tables */
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
@@ -742,50 +813,49 @@
 /*****************************************************************************
 RANK Control Flow
 ******************************************************************************/
-#if !defined(CONFIG_ARMADA_38X) &&  !defined (CONFIG_ARMADA_39X) && !defined(CONFIG_ALLEYCAT3)
-static GT_STATUS ddr3TipRankControl(GT_U32 devNum, GT_U32 interfaceId)
+static GT_STATUS ddr3TipRev2RankControl(GT_U32 devNum, GT_U32 interfaceId)
 {
     GT_U32 dataValue = 0,  busCnt= 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-    for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+    for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
         dataValue |= topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask;
-      
+
         if (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask == GT_TRUE)
-        { 
-        /* checking cs mask is same as cs_bitmask - if CS is enabled than  CS+4 bit in word shall be '1' */
+        {
+        /* checking mirrorEnableBitmask - if mirrorEnableBitmask is enabled - CS+4 bit in word shall be '1' */
             if ((topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask & 0x1) != 0)
             {
-                dataValue |= (1 << 4);
+                dataValue |= (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask << 4);
             }
             if ((topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask & 0x2) != 0)
             {
-                dataValue |= (1 << 5);
+                dataValue |= (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask << 5);
             }
             if ((topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask & 0x4) != 0)
             {
-                dataValue |= (1 << 6);
+                dataValue |= (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask << 6);
             }
             if ((topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask & 0x8) != 0)
             {
-                dataValue |= (1 << 7);
+                dataValue |= (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask << 7);
             }
         }
     }
-#if !defined(CONFIG_ALLEYCAT3)
-    /* jirra CS2 exist */
-    dataValue |= (1 << CS2_EXIST_BIT);
-#endif
+
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, RANK_CTRL_REG, dataValue, 0xFF));
-     
+
     return GT_OK;
 }
-#else
-static GT_STATUS ddr3TipRankControl(GT_U32 devNum, GT_U32 interfaceId)
+
+static GT_STATUS ddr3TipRev3RankControl(GT_U32 devNum, GT_U32 interfaceId)
 {
     GT_U32 dataValue = 0,  busCnt;
-	for (busCnt= 1; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++) {
+	GT_U32 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+	for (busCnt= 1; busCnt < octetsPerInterfaceNum; busCnt++) {
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
 		if ((topologyMap->interfaceParams[interfaceId].asBusParams[0].csBitmask !=topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].csBitmask) ||
 			(topologyMap->interfaceParams[interfaceId].asBusParams[0].mirrorEnableBitmask !=topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].mirrorEnableBitmask))
@@ -794,11 +864,24 @@
 	}
 	dataValue |= topologyMap->interfaceParams[interfaceId].asBusParams[0].csBitmask;
 	dataValue |= topologyMap->interfaceParams[interfaceId].asBusParams[0].mirrorEnableBitmask << 4;
-
 	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, RANK_CTRL_REG, dataValue, 0xFF));
-return GT_OK;
+
+    return GT_OK;
 }
-#endif
+
+static GT_STATUS ddr3TipRankControl(GT_U32 devNum, GT_U32 interfaceId)
+{
+    if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) == MV_TIP_REV_2)
+    {
+        /* BC2 */
+        return ddr3TipRev2RankControl(devNum, interfaceId);
+    }
+    else
+    {
+        /* Other devices */
+        return ddr3TipRev3RankControl(devNum, interfaceId);
+    }
+}
 
 /*****************************************************************************
 PAD Inverse Flow
@@ -810,8 +893,9 @@
 )
 {
     GT_U32 busCnt, dataValue, ckSwapPupCtrl;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-    for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+    for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
         if (topologyMap->interfaceParams[interfaceId].asBusParams[busCnt].isDqsSwap == GT_TRUE)
@@ -839,6 +923,68 @@
 }
 
 /*****************************************************************************
+Algorithm parameters validation
+******************************************************************************/
+GT_BOOL mvHwsValidateAlgoVar(GT_U32 value, GT_U32 failValue, char* varName)
+{
+    if(value == failValue)
+    {
+        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s is not initialized (Algo Components Validation)\n", varName));
+        return GT_FALSE;
+    }
+
+    return GT_TRUE;
+}
+
+GT_BOOL mvHwsValidateAlgoPtr(GT_VOID* ptr, GT_VOID* failValue, char* ptrName)
+{
+    if(ptr == failValue)
+    {
+        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s is not initialized (Algo Components Validation)\n", ptrName));
+        return GT_FALSE;
+    }
+
+    return GT_TRUE;
+}
+
+GT_STATUS mvHwsValidateAlgoComponents(GT_U8 devNum)
+{
+    GT_BOOL status = GT_TRUE;
+
+    /* check DGL parameters*/
+    status &= mvHwsValidateAlgoVar(ckDelay,     MV_PARAMS_UNDEFINED, "ckDelay");
+    status &= mvHwsValidateAlgoVar(PhyReg3Val,  MV_PARAMS_UNDEFINED, "PhyReg3Val");
+    status &= mvHwsValidateAlgoVar(gRttNom,     MV_PARAMS_UNDEFINED, "gRttNom");
+    status &= mvHwsValidateAlgoVar(gDic,        MV_PARAMS_UNDEFINED, "gDic");
+    status &= mvHwsValidateAlgoVar(uiODTConfig, MV_PARAMS_UNDEFINED, "uiODTConfig");
+    status &= mvHwsValidateAlgoVar(gZpriData,   MV_PARAMS_UNDEFINED, "gZpriData");
+    status &= mvHwsValidateAlgoVar(gZnriData,   MV_PARAMS_UNDEFINED, "gZnriData");
+    status &= mvHwsValidateAlgoVar(gZpriCtrl,   MV_PARAMS_UNDEFINED, "gZpriCtrl");
+    status &= mvHwsValidateAlgoVar(gZnriCtrl,   MV_PARAMS_UNDEFINED, "gZnriCtrl");
+    status &= mvHwsValidateAlgoVar(gZpodtData,  MV_PARAMS_UNDEFINED, "gZpodtData");
+    status &= mvHwsValidateAlgoVar(gZnodtData,  MV_PARAMS_UNDEFINED, "gZnodtData");
+    status &= mvHwsValidateAlgoVar(gZpodtCtrl,  MV_PARAMS_UNDEFINED, "gZpodtCtrl");
+    status &= mvHwsValidateAlgoVar(gZnodtCtrl,  MV_PARAMS_UNDEFINED, "gZnodtCtrl");
+
+    /* check functions pointers */
+#ifndef ASIC_SIMULATION
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipDunitMuxSelectFunc,    NULL, "tipDunitMuxSelectFunc");
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipDunitWriteFunc,        NULL, "tipDunitWriteFunc");
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipDunitReadFunc,         NULL, "tipDunitReadFunc");
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipGetFreqConfigInfoFunc, NULL, "tipGetFreqConfigInfoFunc");
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipSetFreqDividerFunc,    NULL, "tipSetFreqDividerFunc");
+    status &= mvHwsValidateAlgoPtr(configFuncInfo[devNum].tipGetClockRatio,         NULL, "tipGetClockRatio");
+#else
+	devNum = devNum; /* avoid warnings */
+#endif
+
+    status &= mvHwsValidateAlgoPtr(dqMapTable, NULL, "dqMapTable");
+    status &= mvHwsValidateAlgoVar(dfsLowFreq, 0, "dfsLowFreq");
+
+    return (status == GT_TRUE) ? GT_OK : GT_NOT_INITIALIZED;
+}
+
+/*****************************************************************************
 Run Training Flow
 ******************************************************************************/
 GT_STATUS    mvHwsDdr3TipRunAlg
@@ -847,7 +993,7 @@
     MV_HWS_ALGO_TYPE    algoType
 )
 {
-    GT_STATUS          retVal = GT_OK , retTune = GT_OK ;
+    GT_STATUS          retVal = GT_OK;
 
 #ifdef ODT_TEST_SUPPORT
    if (fingerTest == 1)
@@ -870,7 +1016,7 @@
         /* add to mask */
         if (isAdllCalibBeforeInit != 0)
         {
-            mvPrintf("with adll calib before init\n");
+            DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("with adll calib before init\n"));
             AdllCalibration(devNum, ACCESS_TYPE_MULTICAST, 0, freq );
         }
         /* frequency per interface is not relevant, only interface 0 */
@@ -880,7 +1026,7 @@
     }
     if (retVal != GT_OK)
     {
-        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("RunAlg: tuning failed %d\n", retTune));
+        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("********   DRAM initialization Failed (res 0x%x)   ********\n", retVal));
     }
 
    return retVal;
@@ -938,11 +1084,7 @@
     GT_BOOL  enable
 )
 {
-    if (configFuncInfo[devNum].tipDunitMuxSelectFunc != NULL)
-    {
-        return configFuncInfo[devNum].tipDunitMuxSelectFunc((GT_U8)devNum, enable);
-    }
-    return GT_FAIL;
+    return configFuncInfo[devNum].tipDunitMuxSelectFunc((GT_U8)devNum, enable);
 }
 
 
@@ -959,11 +1101,7 @@
     GT_U32                mask
 )
 {
-    if (configFuncInfo[devNum].tipDunitWriteFunc != NULL)
-    {
-        return configFuncInfo[devNum].tipDunitWriteFunc((GT_U8)devNum, interfaceAccess, interfaceId, regAddr, dataValue, mask);
-    }
-    return GT_FAIL;
+    return configFuncInfo[devNum].tipDunitWriteFunc((GT_U8)devNum, interfaceAccess, interfaceId, regAddr, dataValue, mask);
 }
 
 
@@ -981,11 +1119,7 @@
     GT_U32                mask
 )
 {
-    if (configFuncInfo[devNum].tipDunitReadFunc != NULL)
-    {
-        return configFuncInfo[devNum].tipDunitReadFunc((GT_U8)devNum, interfaceAccess, interfaceId, regAddr, data, mask);
-    }
-    return GT_FAIL;
+    return configFuncInfo[devNum].tipDunitReadFunc((GT_U8)devNum, interfaceAccess, interfaceId, regAddr, data, mask);
 }
 
 /*****************************************************************************
@@ -1071,10 +1205,11 @@
 {
     GT_U32 busIndex = 0;
     GT_U32 dataRead[MAX_INTERFACE_NUM];
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
 	if (phyAccess == ACCESS_TYPE_MULTICAST)
 	{
-		for(busIndex=0; busIndex < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busIndex++)
+		for(busIndex=0; busIndex < octetsPerInterfaceNum; busIndex++)
 		{
        		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
 			CHECK_STATUS(ddr3TipBusAccess(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busIndex, phyType , regAddr, 0, Operation_READ));
@@ -1242,34 +1377,27 @@
 {
     MV_HWS_TIP_FREQ_CONFIG_INFO		freqConfigInfo;
     GT_U32 busCnt = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* Reset Diver_b assert -> de-assert*/
     CHECK_STATUS (mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0, 0x10000000));
     CHECK_STATUS(hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10));
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0x10000000, 0x10000000));
 
-    if (configFuncInfo[devNum].tipGetFreqConfigInfoFunc != NULL)
-    {
-        CHECK_STATUS(configFuncInfo[devNum].tipGetFreqConfigInfoFunc((GT_U8)devNum, frequency, &freqConfigInfo));
-    }
-	else
-	{
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("tipGetFreqConfigInfoFunc is NULL"));
-		return GT_NOT_INITIALIZED;
-	}
-	for (busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+    CHECK_STATUS(configFuncInfo[devNum].tipGetFreqConfigInfoFunc((GT_U8)devNum, frequency, &freqConfigInfo));
+
+	for (busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
         CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, accessType, interfaceId,  busCnt, DDR_PHY_DATA, BW_PHY_REG,   freqConfigInfo.bwPerFreq << 8 /*freqMask[devNum][frequency] << 8*/, 0x700));
         CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, accessType, interfaceId,  busCnt, DDR_PHY_DATA,  RATE_PHY_REG,  freqConfigInfo.ratePerFreq , 0x7));
     }
-#if !defined(CONFIG_ARMADA_38X) && !defined(CONFIG_ARMADA_39X)
-    for (busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+
+    for (busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
     {
         CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  busCnt, DDR_PHY_CONTROL, BW_PHY_REG,   freqConfigInfo.bwPerFreq << 8 /*freqMask[devNum][frequency] << 8*/, 0x700));
         CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST,  interfaceId,  busCnt, DDR_PHY_CONTROL,  RATE_PHY_REG,  freqConfigInfo.ratePerFreq , 0x7));
     }
-#endif
 
     /* DUnit to Phy drive post edge, ADLL reset  assert  de-assert*/ 
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DRAM_PHY_CONFIGURATION, 0, (0x80000000  | 0x40000000)));
@@ -1302,12 +1430,14 @@
 )
 {
     GT_U32 clValue = 0, cwlValue = 0, memMask = 0, dataValue = 0, tHCLK = 0, tWR = 0, refreshIntervalCnt = 0, cntId, interfaceIdx = 0;
+    GT_U32 tCKCLK = 0;
 	GT_U32 startIf, endIf;
     GT_U32 tREFI = 0;
     GT_BOOL isDllOff = GT_FALSE;
     GT_U32 busIndex = 0, adllTap = 0;
     MV_HWS_SPEED_BIN      speedBinIndex = 0;
 	GT_U32   csMask[MAX_INTERFACE_NUM];
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("dev %d access %d IF %d freq %d\n",devNum , accessType , interfaceId , frequency));
 
@@ -1361,7 +1491,7 @@
     DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n"));
     memMask = 0;
 	/*moti TBD - need to insert loop on interface*/
-    for(busIndex=0; busIndex < GET_TOPOLOGY_NUM_OF_BUSES(devNum) ; busIndex++)
+    for(busIndex=0; busIndex < octetsPerInterfaceNum ; busIndex++)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
         memMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busIndex].mirrorEnableBitmask;
@@ -1375,8 +1505,9 @@
     /*DFS  - CL/CWL parameters after exiting SR*/
 
     /*DFS  - Enter Self-Refresh*/
-    tWR = speedBinTable(speedBinIndex,speedBinTableElements_tWR);
-    tWR = (tWR / 1000);
+    tCKCLK = (MEGA/freqVal[frequency]);
+    tWR = TIME_2_CLOCK_CYCLES(speedBinTable(speedBinIndex,speedBinTableElements_tWR), tCKCLK);
+
     /* dataValue = (clMaskTable[clValue] << 8) |  (cwlMaskTable[cwlValue] << 12) | (1 << 1) | (1 << 2) | (twrMaskTable[tWR+1] << 16);*/
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DFS_REG, (clMaskTable[clValue] << 8) , 0xF00));
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DFS_REG, (cwlMaskTable[cwlValue] << 12) , 0x7000));
@@ -1415,24 +1546,22 @@
 	/*moti TBD - need to insert loop on interface*/
     tREFI = (topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? TREFI_HIGH:TREFI_LOW;
     tREFI *= 1000; /*psec */
+
     /* HCLK in [ps] */
-    tHCLK = MEGA/(freqVal[frequency]/2);
+    tHCLK = MEGA/(freqVal[frequency]/configFuncInfo[devNum].tipGetClockRatio(frequency));
     refreshIntervalCnt = tREFI/tHCLK; /* no units */
 
     dataValue = 0x4000  | refreshIntervalCnt;
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, dataValue, 0x7FFF));
 
     /* PLL configuration */
-    if (configFuncInfo[devNum].tipSetFreqDividerFunc != NULL)
+    /* Ofer b 5/11- assert ADLL */
+    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0, 0x60000000));
+    /* configure pll devider*/
+    for(interfaceIdx = startIf; interfaceIdx <= endIf; interfaceIdx++)
     {
-		/* Ofer b 5/11- assert ADLL */
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0, 0x60000000));
-		/* configure pll devider*/
-		for(interfaceIdx = startIf; interfaceIdx <= endIf; interfaceIdx++)
-		{
-			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceIdx)
-			configFuncInfo[devNum].tipSetFreqDividerFunc((GT_U8)devNum, interfaceIdx, frequency);
-		}
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceIdx)
+        configFuncInfo[devNum].tipSetFreqDividerFunc((GT_U8)devNum, interfaceIdx, frequency);
     }
 
     /* PLL configuration End */
@@ -1456,7 +1585,7 @@
 
 	if (delayEnable != 0)
 	{
-		adllTap =  MEGA/(freqVal[frequency]*64);
+		adllTap =  (isDllOff == GT_TRUE)?(1000):(MEGA/(freqVal[frequency]*64));
 		ddr3TipCmdAddrInitDelay(devNum, adllTap);
 	}
 
@@ -1485,12 +1614,8 @@
     dataValue = ((clMaskTable[clValue] & 0x1) << 2) | ((clMaskTable[clValue] & 0xE)  <<  3);
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR0_REG, dataValue, (0x7 << 4) | (1 << 2)));
     /*MR2:  CWL = 10 , Auto Self-Refresh - disable */
-    dataValue = (cwlMaskTable[cwlValue] << 3);
-    /*dataValue |= (1 << 9); removed by Ofer 31/10
-    dataValue |= ((topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? (1 << 7) : 0);
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3) | (0x1<<7) | (0x3<<9)));*/
-
-	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3)));
+    dataValue = (cwlMaskTable[cwlValue] << 3) | gRttWR;
+	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3) | (0x3 << 9)));
 
     ddr3TipWriteOdt(devNum, accessType, interfaceId, clValue, cwlValue);
 
@@ -1500,9 +1625,9 @@
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR0_REG, dataValue, (0x7 << 4) | (1 << 2)));
 
     /* re-write CWL */
-    dataValue = (cwlMaskTable[cwlValue] << 3);
-    CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS2_CMD, dataValue, (0x7 << 3) ));
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR2_REG, dataValue, (0x7 << 3)));
+    dataValue = (cwlMaskTable[cwlValue] << 3)  | gRttWR;
+    CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS2_CMD, dataValue, (0x7 << 3)  | (0x3 << 9)));
+    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR2_REG, dataValue, (0x7 << 3) | (0x3 << 9)));
 
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_OPERATION_REG, 0xC00, 0xF00)); /* CS0 & CS1*/
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_OPERATION_REG, 0x3, 0x1F));     /* MR0 Update Command */
@@ -1520,6 +1645,7 @@
     return GT_OK;
 }
 #else
+/* for A-380/A-390 */
 GT_STATUS    ddr3TipFreqSet
 (
     GT_U32					devNum,
@@ -1529,20 +1655,25 @@
 )
 {
     GT_U32 clValue = 0, cwlValue = 0, memMask = 0, dataValue = 0, busCnt = 0, tHCLK = 0, tWR = 0, refreshIntervalCnt = 0, cntId;
-    GT_U32 tREFI = 0, endIf, startIf;
+    GT_U32 tCKCLK;
+    GT_U32 endIf, startIf;
+    GT_U32 tREFI = 0;
     GT_U32 busIndex = 0;
 	GT_BOOL isDllOff = GT_FALSE;
     MV_HWS_SPEED_BIN      speedBinIndex = 0;
     MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
     MV_HWS_TIP_FREQ_CONFIG_INFO		freqConfigInfo;
     MV_HWS_RESULT* flowResult = trainingResult[trainingStage];
-	GT_U32 adllTap = 0;
+	GT_U32 adllTap = 0, uiT2t, csNum;
 	GT_U32   csMask[MAX_INTERFACE_NUM];
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("dev %d access %d IF %d freq %d\n",devNum , accessType , interfaceId , frequency));
+
 	if (frequency == DDR_FREQ_LOW_FREQ) {
 		isDllOff = GT_TRUE;
 	}
+
     if (accessType == ACCESS_TYPE_MULTICAST)
     {
         startIf = 0;
@@ -1594,7 +1725,7 @@
         }
         DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n"));
         memMask = 0;
-        for(busIndex=0; busIndex < GET_TOPOLOGY_NUM_OF_BUSES(devNum) ; busIndex++)
+        for(busIndex=0; busIndex < octetsPerInterfaceNum ; busIndex++)
         {
        		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
             memMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busIndex].mirrorEnableBitmask;
@@ -1631,7 +1762,7 @@
             CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, 0x1A74, 0 , (0x7 << 8)));
 #endif
 		}
-           
+
         /*DFS  - Enter Self-Refresh*/
 		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DFS_REG, 0x4 , 0x4));
 		/* polling on self refresh entry */
@@ -1640,18 +1771,41 @@
             DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("FreqSet: DDR3 poll failed on SR entry\n"));
         }
 
-          /* PLL configuration */
-        if (configFuncInfo[devNum].tipSetFreqDividerFunc != NULL)
-        {
-            configFuncInfo[devNum].tipSetFreqDividerFunc(devNum, interfaceId, frequency);
-        }
-        /* PLL configuration End */
+		/*-----------Calculate 2T mode---------------*/
+		if (mode2T != 0xFF)
+		{
+			uiT2t = mode2T;
+		}
+		else
+		{
+			/* calculate number of CS (per interface)*/
+			CHECK_STATUS(mvCalcCsNum(devNum, interfaceId, &csNum));
+			uiT2t = (csNum == 1) ? 0 : 1;
+		}
+
+
+		if(ddr3TipDevAttrGet(devNum, MV_ATTR_INTERLEAVE_WA ) == GT_TRUE){
+			/*If configured 1:1 Ratio, use 1T mode*/
+			if(configFuncInfo[devNum].tipGetClockRatio(frequency) == 1){ /*Low freq*/
+				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, SDRAM_OPEN_PAGE_CONTROL_REG, 0x0, 0x3C0));
+				uiT2t = 0;
+			}
+			else{/*medium or target FREQ*/
+				CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, SDRAM_OPEN_PAGE_CONTROL_REG, 0x3C0, 0x3C0));
+			}
+		}
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, DDR_CONTROL_LOW_REG, uiT2t << 3,0x3 << 3));
+
+        /* PLL configuration */
+        configFuncInfo[devNum].tipSetFreqDividerFunc(devNum, interfaceId, frequency);
+
 
 		/* adjust tREFI to new frequency*/
-		tREFI = (topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? TREFI_LOW:TREFI_HIGH;
+		tREFI = (topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? TREFI_HIGH:TREFI_LOW;
         tREFI *= 1000; /*psec */
+
         /* HCLK in [ps] */
-        tHCLK = MEGA/(freqVal[frequency]/2);
+        tHCLK = MEGA/(freqVal[frequency]/configFuncInfo[devNum].tipGetClockRatio(frequency));
         refreshIntervalCnt = tREFI/tHCLK; /* no units */
         dataValue = 0x4000  | refreshIntervalCnt;
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, dataValue, 0x7FFF));
@@ -1660,8 +1814,10 @@
         /*DFS  - CL/CWL/WR parameters after exiting SR*/
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DFS_REG, (clMaskTable[clValue] << 8) , 0xF00)); 
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DFS_REG, (cwlMaskTable[cwlValue] << 12) , 0x7000));
-        tWR = speedBinTable(speedBinIndex,speedBinTableElements_tWR);
-        tWR = (tWR / 1000);
+
+        tCKCLK = (MEGA/freqVal[frequency]);
+        tWR = TIME_2_CLOCK_CYCLES(speedBinTable(speedBinIndex,speedBinTableElements_tWR), tCKCLK);
+
        /* dataValue = (clMaskTable[clValue] << 8) |  (cwlMaskTable[cwlValue] << 12) | (1 << 1) | (1 << 2) | (twrMaskTable[tWR+1] << 16);*/
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DFS_REG, (twrMaskTable[tWR+1] << 16) , 0x70000));
 	
@@ -1677,24 +1833,22 @@
 			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, 0x1A74, gRttNomCS1 , (0x7 << 8)));
 #endif
 		}
-        /* Reset Diver_b assert -> de-assert*/ 
+        /* Reset Diver_b assert -> de-assert*/
         CHECK_STATUS (mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0, 0x10000000));
-        CHECK_STATUS(hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10));  
+        CHECK_STATUS(hwsOsExactDelayPtr((GT_U8)devNum, devNum, 10));
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_CONFIGURATION_REG, 0x10000000, 0x10000000));
 
         /* Adll configuration function of process and Frequency*/
-        if (configFuncInfo[devNum].tipGetFreqConfigInfoFunc != NULL)
-        {
-			CHECK_STATUS(configFuncInfo[devNum].tipGetFreqConfigInfoFunc(devNum, frequency, &freqConfigInfo));
-        }
+        CHECK_STATUS(configFuncInfo[devNum].tipGetFreqConfigInfoFunc(devNum, frequency, &freqConfigInfo));
+
         /* TBD check milo5 using device ID ? */
-        for (busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+        for (busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
              CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum,ACCESS_TYPE_UNICAST, interfaceId,  busCnt, DDR_PHY_DATA, 0x92,   freqConfigInfo.bwPerFreq << 8 /*freqMask[devNum][frequency] << 8*/, 0x700));
              CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum,ACCESS_TYPE_UNICAST,  interfaceId,  busCnt, DDR_PHY_DATA,  0x94,  freqConfigInfo.ratePerFreq , 0x7));
         }
-        /* DUnit to Phy drive post edge, ADLL reset  assert  de-assert*/ 
+        /* DUnit to Phy drive post edge, ADLL reset  assert  de-assert*/
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DRAM_PHY_CONFIGURATION, 0, (0x80000000  | 0x40000000)));
         CHECK_STATUS(hwsOsExactDelayPtr((GT_U8)devNum, 0, 100/(freqVal[frequency]/freqVal[DDR_FREQ_LOW_FREQ])));
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DRAM_PHY_CONFIGURATION, (0x80000000  | 0x40000000), (0x80000000  | 0x40000000)));
@@ -1712,7 +1866,7 @@
 		ddr3TipSetTiming(devNum, accessType, interfaceId, frequency);
 		if (delayEnable != 0)
 		{
-			adllTap =  MEGA/(freqVal[frequency]*64);
+			adllTap =  (isDllOff == GT_TRUE)?(1000):(MEGA/(freqVal[frequency]*64));
 			ddr3TipCmdAddrInitDelay(devNum, adllTap);
 		}
 
@@ -1736,16 +1890,16 @@
         dataValue = ((clMaskTable[clValue] & 0x1) << 2) | ((clMaskTable[clValue] & 0xE)  <<  3);
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR0_REG, dataValue, (0x7 << 4) | (1 << 2)));
         /*MR2:  CWL = 10 , Auto Self-Refresh - disable */
-        dataValue = (cwlMaskTable[cwlValue] << 3);
+        dataValue = (cwlMaskTable[cwlValue] << 3)   | gRttWR;
 		/* nklein 24.10.13 - should not be here - leave value as set in
 		the init configuration dataValue |= (1 << 9); 
         dataValue |= ((topologyMap->interfaceParams[interfaceId].interfaceTemp == MV_HWS_TEMP_HIGH) ? (1 << 7) : 0);
         ****/
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3)));  /* nklein 24.10.13 - see above comment*/
+        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, MR2_REG, dataValue , (0x7<<3) | (0x3 << 9)));  /* nklein 24.10.13 - see above comment*/
         /*ODT TIMING */
         dataValue = ((clValue-cwlValue+1) << 4) |  ((clValue-cwlValue+6) << 8) |  ((clValue-1) << 12) |  ((clValue+6) << 16);
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, ODT_TIMING_LOW, dataValue, 0xFFFF0));
-        dataValue = 0x71 | ((cwlValue - 1) << 8) | ((cwlValue+5) << 12);
+        dataValue = 0x91 | ((cwlValue - 1) << 8) | ((cwlValue+5) << 12);
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, ODT_TIMING_HI_REG, dataValue, 0xFFFF));
         /* ODT Active*/
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DUNIT_ODT_CONTROL_REG, 0xF, 0xF));
@@ -1755,9 +1909,9 @@
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR0_REG, dataValue, (0x7 << 4) | (1 << 2)));
 
     /* re-write CWL */
-    dataValue = (cwlMaskTable[cwlValue] << 3);
-    CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS2_CMD, dataValue, (0x7 << 3) ));
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR2_REG, dataValue, (0x7 << 3)));
+    dataValue = (cwlMaskTable[cwlValue] << 3)  | gRttWR;
+    CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS2_CMD, dataValue, (0x7 << 3) | (0x3 << 9)));
+    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR2_REG, dataValue, (0x7 << 3) | (0x3 << 9)));
 
     /*    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, SDRAM_TIMING_HIGH_REG, 0x3E031F80, 0x3FFFFFFF));*/
         if (memMask != 0)
@@ -1789,7 +1943,7 @@
 	dataValue |= (((clValue-1)>>4) << 22) |  (((clValue+6)>>4) << 23);
 
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, ODT_TIMING_LOW, dataValue, 0xFFFF0));
-    dataValue = 0x71 | ((cwlValue - 1) << 8) | ((cwlValue+5) << 12);
+    dataValue = 0x91 | ((cwlValue - 1) << 8) | ((cwlValue+5) << 12);
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, ODT_TIMING_HI_REG, dataValue, 0xFFFF));
 	if (odtAdditional == 1) 
 	{
@@ -1950,19 +2104,20 @@
 )
 {
     GT_U32 interfaceId,busNum, csBitmask, dataVal, csNum;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-		for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+		for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
 		{
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 			csBitmask = topologyMap->interfaceParams[interfaceId].asBusParams[busNum].csBitmask;
 			if(csBitmask != effective_cs)
 			{
                 csNum = GET_CS_FROM_MASK(csBitmask);
-				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, offset + CS_REG_VALUE(effective_cs), &dataVal);
-    			mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, offset + CS_REG_VALUE(csNum), dataVal);
+				mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, offset + CS_BYTE_GAP(effective_cs), &dataVal);
+    			mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, offset + CS_BYTE_GAP(csNum), dataVal);
 			}					
 		}
 	}
@@ -2007,59 +2162,6 @@
 
 
 /*****************************************************************************
-Dynamic ODT
-******************************************************************************/
-GT_STATUS    ddr3TipDynamicOdt
-(
-    GT_U32    devNum,
-    GT_BOOL   bIsSet
-)                          
-{
-    GT_U32 mr1Value,mr2Value, interfaceId;
-
-    if (bIsSet == GT_TRUE)
-    {
-        mr1Value = 0x24;
-        mr2Value = 0;
-    }
-    else
-    {
-        mr1Value = 0;
-        mr2Value = 0x200;
-    }
-    /* MR1: set RttNom to RZQ/6 */
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR1_REG, mr1Value, 0x224));
-    /* MR2: disable dynamic ODT*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, MR2_REG, mr2Value, 0x600));
-    /*Operation command*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_OPERATION_REG, 0xC00, 0xF00));
-    /* MR1 Command */
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_OPERATION_REG, 0x4, 0x1F));
-    /* check controller back to normal */
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0, 0x1F, SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-        {
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("WL: DDR3 poll failed(1)"));
-        }
-    }
-    /* MR2 Command */
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_OPERATION_REG, 0x8, 0x1F));
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0, 0x1F, SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-        {
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("WL: DDR3 poll failed(2)"));
-        }
-    }
-    return GT_OK;
-}
-
-
-
-/*****************************************************************************
 Reset XSB Read FIFO
 ******************************************************************************/
 GT_STATUS    ddr3TipResetFifoPtr
@@ -2095,17 +2197,24 @@
 )
 {
     GT_U32 interfaceId, phyId,cs;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for (phyId=0; phyId<topologyMap->numOfBusPerInterface; phyId++)
+        for (phyId=0; phyId<octetsPerInterfaceNum; phyId++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, phyId)
-			CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, WL_PHY_REG + CS_REG_VALUE(effective_cs), PhyReg0Val));
-            CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, RL_PHY_REG + CS_REG_VALUE(effective_cs), PhyReg2Val));
-            CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, READ_CENTRALIZATION_PHY_REG + CS_REG_VALUE(effective_cs), PhyReg3Val));
-            CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + CS_REG_VALUE(effective_cs), PhyReg3Val));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, WL_PHY_REG + CS_BYTE_GAP(effective_cs), PhyReg0Val));
+            CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, RL_PHY_REG + CS_BYTE_GAP(effective_cs), PhyReg2Val));
+            CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, READ_CENTRALIZATION_PHY_REG + CS_BYTE_GAP(effective_cs), PhyReg3Val));
+            CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + CS_BYTE_GAP(effective_cs), PhyReg1Val));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x1F + CS_PBS_GAP(effective_cs), 0));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x5F + CS_PBS_GAP(effective_cs), 0));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x14 + CS_PBS_GAP(effective_cs), 0));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x54 + CS_PBS_GAP(effective_cs), 0));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x15 + CS_PBS_GAP(effective_cs), 0));
+			CHECK_STATUS(mvHwsDdr3TipBUSWrite( devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, phyId, DDR_PHY_DATA, 0x55 + CS_PBS_GAP(effective_cs), 0));
 		}
     }
 
@@ -2157,9 +2266,9 @@
     InitCntrParam   initCntrPrm;
     GT_STATUS retVal = GT_OK;
 	GT_U32 interfaceId;
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 	if(debugTraining == DEBUG_LEVEL_TRACE)
 		CHECK_STATUS(printDeviceInfo((GT_U8)devNum));
 #endif
@@ -2170,6 +2279,8 @@
 	effective_cs = 0;/*Set to 0 after each loop to avoid illegal value may be used*/
 
     freq = initFreq;
+    freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq;
+
     if (isPllBeforeInit != 0 )
     {
 		for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++) {
@@ -2212,6 +2323,16 @@
                 return GT_FAIL; 
             }
         }
+
+#if defined(MV_HWS_RX_IO_BIST) || defined(MV_HWS_RX_IO_BIST_ETP)
+        /* Run RX IO BIST */
+        retVal = mvHwsIoBistTest((GT_U8)devNum);
+        if (retVal != GT_OK)
+        {
+            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("mvHwsIoBistTest failure \n"));
+            return retVal;
+        }
+#endif
     }
 
 #ifdef STATIC_ALGO_SUPPORT
@@ -2275,7 +2396,6 @@
 	}
 	effective_cs = 0;/*Set to 0 after each loop to avoid illegal value may be used*/
 
-
     if (maskTuneFunc & SET_MEDIUM_FREQ_MASK_BIT)
     {
 	   trainingStage = SET_MEDIUM_FREQ;
@@ -2341,7 +2461,7 @@
 		}
 	}
 	effective_cs = 0;/*Set to 0 after each loop to avoid illegal value may be used*/
-	
+
     if (maskTuneFunc & READ_LEVELING_MASK_BIT)
     {
         trainingStage = READ_LEVELING;
@@ -2448,6 +2568,7 @@
 			}
 		}
     }
+
     /*if (maskTuneFunc & ADJUST_DQS_MASK_BIT)
     {
         DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("ADJUST_DQS_MASK_BIT\n"));
@@ -2509,46 +2630,6 @@
         }
     }
 
-#ifdef CONFIG_DDR4__NOT_USED
-	if (maskTuneFunc & PER_BIT_READ_LEVELING_TF_MASK_BIT)
-    {
-       trainingStage = PER_BIT_READ_LEVELING_TF;
-       DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("PER_BIT_READ_LEVELING_TF_MASK_BIT \n"));
-       retVal = ddr3TipDynamicPerBitReadLeveling(devNum, topologyMap->interfaceParams[firstActiveIf].memoryFreq);
-       if (isRegDump != 0)
-       {
-           ddr3TipRegDump(devNum);
-       }
-       if (retVal != GT_OK)
-       {
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr3TipDynamicPerBitReadLeveling TF failure \n")); 
-            if (debugMode == GT_FALSE)
-            {
-                return GT_FAIL; 
-            }
-       }
-    }
-
-    if (maskTuneFunc & SW_READ_LEVELING_MASK_BIT)
-    {
-        trainingStage = SW_READ_LEVELING;
-        DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("SW_READ_LEVELING_MASK_BIT\n"));
-		retVal = ddr4TipSoftwareReadLeveling(devNum, mediumFreq);
-        if (isRegDump != 0)
-        {
-           ddr3TipRegDump(devNum);
-        }
-        if (retVal != GT_OK)
-        {
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr4TipSoftwareReadLeveling failure \n"));
-            if (debugMode == GT_FALSE)
-            {
-                return GT_FAIL;
-            }
-        }
-    }
-#endif /* CONFIG_DDR4 */
-
 #ifdef CONFIG_DDR3
     if (maskTuneFunc & DM_PBS_TX_MASK_BIT)
     {
@@ -2578,7 +2659,6 @@
 		}
 	}
 	effective_cs = 0;/*Set to 0 after each loop to avoid illegal value may be used*/
-
  	for(effective_cs = 0; effective_cs < max_cs; effective_cs++){
 	    if (maskTuneFunc & CENTRALIZATION_RX_MASK_BIT)
 		 {
@@ -2626,79 +2706,7 @@
 
 #ifdef CONFIG_DDR4
 	for(effective_cs = 0; effective_cs < max_cs; effective_cs++){
-		if (maskTuneFunc & RECEIVER_CALIBRATION_MASK_BIT)
-		{
-		   trainingStage = RECEIVER_CALIBRATION;
-		    DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("RECEIVER_CALIBRATION_MASK_BIT\n"));
-		    retVal = ddr4TipReceiverCalibration(devNum);
-		    if (isRegDump != 0)
-		    {
-		       ddr3TipRegDump(devNum);
-		    }
-		    if (retVal != GT_OK)
-		    {
-		        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr4TipReceiverCalibration failure \n"));
-		        if (debugMode == GT_FALSE)
-		        {
-		            return GT_FAIL;
-		        }
-		    }
-		}
-		if (maskTuneFunc & WL_PHASE_CORRECTION_MASK_BIT)
-		{
-		   trainingStage = WL_PHASE_CORRECTION;
-		    DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("WL_PHASE_CORRECTION_MASK_BIT\n"));
-		    retVal = ddr4TipDynamicWriteLevelingSupp(devNum);
-		    if (isRegDump != 0)
-		    {
-		       ddr3TipRegDump(devNum);
-		    }
-		    if (retVal != GT_OK)
-		    {
-		        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr4TipDynamicWriteLevelingSupp failure\n"));
-		        if (debugMode == GT_FALSE)
-		        {
-		            return GT_FAIL;
-		        }
-		    }
-		}
-		if (maskTuneFunc & DQ_VREF_CALIBRATION_MASK_BIT)
-		{
-		   trainingStage = DQ_VREF_CALIBRATION;
-		    DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DQ_VREF_CALIBRATION_MASK_BIT\n"));
-		    retVal = ddr4TipDqVrefCalibration(devNum);
-		    if (isRegDump != 0)
-		    {
-		       ddr3TipRegDump(devNum);
-		    }
-		    if (retVal != GT_OK)
-		    {
-		        DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr4TipDqVrefCalibration failure\n"));
-		        if (debugMode == GT_FALSE)
-		        {
-		            return GT_FAIL;
-		        }
-		    }
-		}
-	}
-	effective_cs = 0;
-    if (maskTuneFunc & DQ_MAPPING_MASK_BIT)
-    {
-       trainingStage = DQ_MAPPING;
-        DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DQ_MAPPING_MASK_BIT\n"));
-        retVal = ddr4DqPinsMapping(devNum);
-        if (isRegDump != 0)
-        {
-           ddr3TipRegDump(devNum);
-        }
-        if (retVal != GT_OK)
-        {
-            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("ddr4DqPinsMapping failure\n"));
-            if (debugMode == GT_FALSE)
-            {
-                return GT_FAIL;
-            }
-        }
+    	CHECK_STATUS(ddr3TipDDR4Ddr4TrainingMainFlow(devNum));
     }
 #endif
 
@@ -2773,10 +2781,10 @@
     }
     /* print log */
     CHECK_STATUS(ddr3TipPrintLog(devNum, windowMemAddr));
-
+#ifndef MV_HWS_EXCLUDE_DEBUG_PRINTS
 	if(retVal != GT_OK)
 		CHECK_STATUS(ddr3TipPrintStabilityLog(devNum));
-
+#endif
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         isIfFail = GT_FALSE;
@@ -2794,7 +2802,15 @@
         }
     }
 
-	if ((retVal== GT_FAIL) || (isAutoTuneFail == GT_TRUE))
+	if (((retVal != GT_OK) && (isAutoTuneFail == GT_FALSE)) ||
+	    ((retVal == GT_OK) && (isAutoTuneFail == GT_TRUE)))
+	{
+		/* in case MainFlow result and trainingResult DB are not synced we issue warning message
+		   this usually means that trainingResult DB was not updated in a case of a failure */
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("Warning: Algorithm return value and Result DB are not synced (retVal 0x%x  result DB %d)\n", retVal, isAutoTuneFail));
+	}
+
+	if ((retVal != GT_OK) || (isAutoTuneFail == GT_TRUE))
 		return GT_FAIL;
 	else
 		return GT_OK;
@@ -2808,36 +2824,37 @@
     GT_U32 devNum
 )
 {
-   GT_BOOL isFail = GT_FALSE;
-   GT_U32 interfaceId = 0, memMask= 0 , busIndex = 0;
+    GT_BOOL isFail = GT_FALSE;
+    GT_U32 interfaceId = 0, memMask= 0 , busIndex = 0;
+    GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-   /*Enable init sequence */
-   CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_INIT_CONTROL_REG, 0x1,0x1));
+    /*Enable init sequence */
+    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, 0, SDRAM_INIT_CONTROL_REG, 0x1,0x1));
 
-   for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-   {
-      VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 
-      if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0, 0x1, SDRAM_INIT_CONTROL_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-      {
-         DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("polling failed IF %d \n",interfaceId)); 
-         isFail = GT_TRUE;
-         continue;
-      }
-      memMask = 0;
-      for(busIndex=0; busIndex < GET_TOPOLOGY_NUM_OF_BUSES(devNum) ; busIndex++)
-      {
-       		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
-         	memMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busIndex].mirrorEnableBitmask;
-      }
-      if (memMask != 0)
-      {
-          /*Disable MultiCS */
-         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_MULTICAST, interfaceId, CS_ENABLE_REG, 1<<3, 1<<3));
-      }
+        if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0, 0x1, SDRAM_INIT_CONTROL_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+        {
+            DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("polling failed IF %d \n",interfaceId)); 
+            isFail = GT_TRUE;
+            continue;
+        }
+        memMask = 0;
+        for(busIndex=0; busIndex < octetsPerInterfaceNum ; busIndex++)
+        {
+            VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
+            memMask |= topologyMap->interfaceParams[interfaceId].asBusParams[busIndex].mirrorEnableBitmask;
+        }
+        if (memMask != 0)
+        {
+            /*Disable MultiCS */
+            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_MULTICAST, interfaceId, CS_ENABLE_REG, 1<<3, 1<<3));
+        }
 
-   }
-   return (isFail == GT_FALSE)? GT_OK:GT_FAIL;
+    }
+    return (isFail == GT_FALSE)? GT_OK:GT_FAIL;
 }
 
 
@@ -2985,32 +3002,31 @@
 
 GT_STATUS mvHwsDdr3CsBaseAdrCalc(GT_U32 interfaceId, GT_U32 uiCs, GT_U32 *csBaseAddr)
 {
-
-	GT_U32 uiCsMemSize = 0;
+       GT_U32 uiCsMemSize = 0;
 
 #ifdef MV_DEVICE_MAX_DRAM_ADDRESS_SIZE
-	GT_U32 physicalMemSize;
-	GT_U32 maxMemSize = MV_DEVICE_MAX_DRAM_ADDRESS_SIZE;
+       GT_U32 physicalMemSize;
+       GT_U32 maxMemSize = MV_DEVICE_MAX_DRAM_ADDRESS_SIZE;
 #endif
 
-	if (mvHwsDdr3CalcMemCsSize(interfaceId,uiCs, &uiCsMemSize) != GT_OK)
-		return GT_FAIL;
+       if (mvHwsDdr3CalcMemCsSize(interfaceId,uiCs, &uiCsMemSize) != GT_OK)
+               return GT_FAIL;
 
 #ifdef MV_DEVICE_MAX_DRAM_ADDRESS_SIZE
-	/* if number of address pins doesn't allow to use max mem size that is defined in topology
-	 mem size is defined by MV_DEVICE_MAX_DRAM_ADDRESS_SIZE*/
-	physicalMemSize = mvHwsmemSize [topologyMap->interfaceParams[0].memorySize];
+       /* if number of address pins doesn't allow to use max mem size that is defined in topology
+        mem size is defined by MV_DEVICE_MAX_DRAM_ADDRESS_SIZE*/
+       physicalMemSize =  mvMemSize[topologyMap->interfaceParams[0].memorySize];
 
-	if (mvHwsDdr3GetDeviceWidth(uiCs) == 16)
-		maxMemSize = MV_DEVICE_MAX_DRAM_ADDRESS_SIZE * 2; /* 16bit mem device can be twice more - no need in less significant pin*/
+       if (mvHwsDdr3GetDeviceWidth(uiCs) == 16)
+               maxMemSize = MV_DEVICE_MAX_DRAM_ADDRESS_SIZE * 2; /* 16bit mem device can be twice more - no need in less significant pin*/
 
-	if (physicalMemSize > maxMemSize ){
-		uiCsMemSize = maxMemSize * (mvHwsDdr3GetBusWidth() / mvHwsDdr3GetDeviceWidth(interfaceId)) ;
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,  ("Updated Physical Mem size is from 0x%x to %x\n", physicalMemSize, MV_DEVICE_MAX_DRAM_ADDRESS_SIZE));
-	}
+       if (physicalMemSize > maxMemSize ){
+               uiCsMemSize = maxMemSize * (mvHwsDdr3GetBusWidth() / mvHwsDdr3GetDeviceWidth(interfaceId)) ;
+               DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,  ("Updated Physical Mem size is from 0x%x to %x\n", physicalMemSize, MV_DEVICE_MAX_DRAM_ADDRESS_SIZE));
+       }
 #endif
-	/*calculate CS base addr  */
-	*csBaseAddr = ((uiCsMemSize) * uiCs) & 0xFFFF0000;
-	return GT_OK;
+       /*calculate CS base addr  */
+       *csBaseAddr = ((uiCsMemSize) * uiCs) & 0xFFFF0000;
+       return GT_OK;
 }
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingBist.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingBist.c
index 08e99d5..ecff52a 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingBist.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingBist.c
@@ -123,19 +123,20 @@
                 {
                     CHECK_STATUS(mvHwsDdr3TipIFRead(devNum,ACCESS_TYPE_UNICAST, ifNum, ODPG_BIST_DONE, readData, MASK_ALL_BITS));
 					dataValue = readData[interfaceNum];
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
-					if ((dataValue & 0x1) == 0x0)/*in SOC type devices this bit is self clear so, if it was cleared all good*/
-                        break;
-#else
-					if ((dataValue & 0x1) == 0x1)
-                    {
-                        if (isBistResetBit != 0)
-                        {
-                            CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_UNICAST, ifNum, ODPG_BIST_DONE, (dataValue & 0xFFFFFFFE), MASK_ALL_BITS));
-                        }
-                        break;
-                    }
-#endif
+					if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+						if ((dataValue & 0x1) == 0x0)/*in SOC type devices this bit is self clear so, if it was cleared all good*/
+		                    break;
+					}
+					else{
+						if ((dataValue & 0x1) == 0x1)
+		                {
+		                    if (isBistResetBit != 0)
+		                    {
+		                        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_UNICAST, ifNum, ODPG_BIST_DONE, (dataValue & 0xFFFFFFFE), MASK_ALL_BITS));
+		                    }
+		                    break;
+		                }
+					}
                 }
                 if (pollCnt >= MaxPoll)
                 {
@@ -262,19 +263,21 @@
 
    if (operType == BIST_STOP)
    {
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
-	   CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_BIST_DONE,  (1 << 8), (1 << 8)));
-#else
-	   CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_DATA_CONTROL_REG,  (1 << 30)  , (GT_U32)(0x3 << 30)));
-#endif
+		if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_BIST_DONE,  (1 << 8), (1 << 8)));
+		}
+		else{
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_DATA_CONTROL_REG,  (1 << 30)  , (GT_U32)(0x3 << 30)));
+		}
    }
    else
    {
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ALLEYCAT3) || defined (CONFIG_ARMADA_39X)
-       CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_BIST_DONE,  1, 1));
-#else
-	   CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_DATA_CONTROL_REG,  (GT_U32)(1 << 31), (GT_U32)(1 << 31)));
-#endif
+		if (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_BIST_DONE,  1, 1));
+		}
+		else{
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,  accessType, interfaceId,  ODPG_DATA_CONTROL_REG,  (GT_U32)(1 << 31), (GT_U32)(1 << 31)));
+		}
    }
    return GT_OK;
 }
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingCentralization.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingCentralization.c
index a6e868a..03597ed 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingCentralization.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingCentralization.c
@@ -128,6 +128,7 @@
 	GT_U32 pupWinLength = 0;
     MV_HWS_SearchDirection searchDirId;
 	GT_U8 consTap = (mode == CENTRAL_TX)?(64):(0);
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
@@ -150,11 +151,12 @@
         regPhyOffset = READ_CENTRALIZATION_PHY_REG + (effective_cs * 4);
         direction = OPER_READ;
     }
+
     /* DB initialization */
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busId = 0; busId < topologyMap->numOfBusPerInterface ; busId++)
+        for(busId = 0; busId < octetsPerInterfaceNum ; busId++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
             centralizationState[interfaceId][busId] = 0;
@@ -163,6 +165,7 @@
             centralizationResult[interfaceId][busId] = 0;
         }
     }
+
     /* start flow */
     for(patternId = startPattern; patternId <= endPattern ; patternId++)
     {
@@ -171,10 +174,11 @@
                                  PARAM_NOT_CARE, direction, topologyMap->interfaceActiveMask, 
                                  0x0, maxWinSize-1, maxWinSize-1, patternId, EDGE_FPF, CS_SINGLE, 
                                  PARAM_NOT_CARE, trainingResult);
+
         for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
         {
             VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-            for(busId = 0; busId <= topologyMap->numOfBusPerInterface-1 ; busId++)
+            for(busId = 0; busId < octetsPerInterfaceNum ; busId++)
             {
         		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
 
@@ -260,6 +264,7 @@
 		                centralizationState[interfaceId][busId] = 1;
 		                if (debugMode == GT_FALSE)
 		                {
+							flowResult[interfaceId] = TEST_FAILED;
 		                    return GT_FAIL;
 		                }
 		            }
@@ -269,13 +274,11 @@
     }/*pattern*/
     for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
     {
-        if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  GT_FALSE)
-        {
-            continue;
-        }
+		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+
         isIfFail = GT_FALSE;
         flowResult[interfaceId] = TEST_SUCCESS;
-        for(busId = 0; busId <= (topologyMap->numOfBusPerInterface-1) ; busId++)
+        for(busId = 0; busId < octetsPerInterfaceNum ; busId++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
 
@@ -302,6 +305,7 @@
                     consTap   = 64;
 				}
             }
+
             /* check states */
             if (centralizationState[interfaceId][busId] == 3)
             {
@@ -322,6 +326,7 @@
                 DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_ERROR, ("fail, IF %d pup %d\n", interfaceId, busId));
                 lockSuccess = GT_FALSE;
             }
+
             if (lockSuccess == GT_TRUE)
             {
                 centralizationResult[interfaceId][busId] = (busEndWindow[mode][interfaceId][busId] + busStartWindow[mode][interfaceId][busId])/2 - consTap;
@@ -343,17 +348,20 @@
                 isIfFail = GT_TRUE;
             }
        }
+
        if (isIfFail == GT_TRUE)
        {
            flowResult[interfaceId] = TEST_FAILED;
        }
    }
 
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+   /* restore cs enable value*/
+   for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)        /* restore cs enable value*/
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, csEnableRegVal[interfaceId], MASK_ALL_BITS));
    }
+
    return isIfFail;
 }
 
@@ -379,10 +387,11 @@
    	GT_U32   csEnableRegVal[MAX_INTERFACE_NUM];
 	GT_U32 temp = 0;
     int PadNum = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-	if( ddr3TipSpecialRxRunOnceFlag != 0 )
+	if( (ddr3TipSpecialRxRunOnceFlag&(1<<effective_cs)) == 1<<effective_cs )
 		return GT_OK;
-	ddr3TipSpecialRxRunOnceFlag = 1;
+	ddr3TipSpecialRxRunOnceFlag |= 1<<effective_cs;
 
     for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
     {
@@ -395,38 +404,38 @@
 
     maxWinSize = MAX_WINDOW_SIZE_RX;
     direction = OPER_READ;
-	patternId = PATTERN_VREF;
+	patternId = PATTERN_FULL_SSO1;
 
     /* start flow */
     ddr3TipIpTrainingWrapper(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
-                             PARAM_NOT_CARE, resultType, MV_HWS_ControlElement_ADLL,
-                             PARAM_NOT_CARE, direction, topologyMap->interfaceActiveMask,
-                             0x0, maxWinSize-1, maxWinSize-1, patternId, EDGE_FPF, CS_SINGLE,
-                             PARAM_NOT_CARE, trainingResult);
+				              PARAM_NOT_CARE, resultType, MV_HWS_ControlElement_ADLL,
+				             PARAM_NOT_CARE, direction, topologyMap->interfaceActiveMask,
+				             0x0, maxWinSize-1, maxWinSize-1, patternId, EDGE_FPF, CS_SINGLE,
+				             PARAM_NOT_CARE, trainingResult);
     for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(pupId = 0; pupId <= topologyMap->numOfBusPerInterface ; pupId++)
+        for(pupId = 0; pupId <= octetsPerInterfaceNum; pupId++)
         {
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
 
             for(searchDirId = MV_HWS_Low2High ; searchDirId <= MV_HWS_High2Low ; searchDirId++)
             {
-                CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceId, ACCESS_TYPE_UNICAST,
-                            pupId, ALL_BITS_PER_PUP, searchDirId,  direction,
-                            resultType, TrainingLoadOperation_UNLOAD,
-                            CS_SINGLE, &result[searchDirId] , GT_TRUE, 0, GT_FALSE));
-                DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,("Special: pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",patternId, interfaceId, pupId,  result[searchDirId][0],result[searchDirId][1],result[searchDirId][2],result[searchDirId][3],result[searchDirId][4],result[searchDirId][5],result[searchDirId][6],result[searchDirId][7]));
+				CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceId, ACCESS_TYPE_UNICAST,
+				             pupId, ALL_BITS_PER_PUP, searchDirId,  direction,
+				            resultType, TrainingLoadOperation_UNLOAD,
+				            CS_SINGLE, &result[searchDirId] , GT_TRUE, 0, GT_FALSE));
+				DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,("Special: pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",patternId, interfaceId, pupId,  result[searchDirId][0],result[searchDirId][1],result[searchDirId][2],result[searchDirId][3],result[searchDirId][4],result[searchDirId][5],result[searchDirId][6],result[searchDirId][7]));
             }
             for(bitId = 0; bitId < BUS_WIDTH_IN_BITS  ; bitId++)
             {
-                /* check if this code is valid for 2 edge, probably not :( */
-                currentStartWindow[bitId] = GET_TAP_RESULT(result[MV_HWS_Low2High][bitId], EDGE_1);
-                currentEndWindow[bitId] = GET_TAP_RESULT(result[MV_HWS_High2Low][bitId], EDGE_1);
+				/* check if this code is valid for 2 edge, probably not :( */
+				currentStartWindow[bitId] = GET_TAP_RESULT(result[MV_HWS_Low2High][bitId], EDGE_1);
+				currentEndWindow[bitId] = GET_TAP_RESULT(result[MV_HWS_High2Low][bitId], EDGE_1);
             }
             if( !((ddr3TipIsPupLock(result[MV_HWS_Low2High], resultType)) && (ddr3TipIsPupLock(result[MV_HWS_High2Low], resultType))))
             {
-                DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_ERROR,("Special: Pup lock fail, pat %d IF %d pup %d \n",patternId, interfaceId, pupId));
+				DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_ERROR,("Special: Pup lock fail, pat %d IF %d pup %d \n",patternId, interfaceId, pupId));
 				return GT_FAIL;
             }
 
@@ -437,22 +446,22 @@
 			{
 				for( bitId = 0 ; bitId < BUS_WIDTH_IN_BITS ; bitId++)
 				{
-					PadNum = dqMapTable[bitId+pupId*BUS_WIDTH_IN_BITS + interfaceId*BUS_WIDTH_IN_BITS*topologyMap->numOfBusPerInterface];
-               		CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+PadNum, &temp));
+					PadNum = dqMapTable[bitId+pupId*BUS_WIDTH_IN_BITS + interfaceId*BUS_WIDTH_IN_BITS*octetsPerInterfaceNum];
+					CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+PadNum +  effective_cs * 0x10, &temp));
 					temp = (temp + 0xA > 31)?(31):(temp + 0xA);
-               		CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+PadNum, temp));
+					CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+PadNum + effective_cs * 0x10, temp));
 				}
 				DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,("Special: PBS:: I/F# %d , Bus# %d fix align to the Left \n", interfaceId,pupId));
 			}
 
 			if( currentEndWindowMin > 30 )/*Align rigth*/
 			{
-               	CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+4, &temp));
+				CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+4 + effective_cs * 0x10, &temp));
 				temp += 0xA;
-           		CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+4, temp));
-               	CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+5, &temp));
+				CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+4 + effective_cs * 0x10, temp));
+				CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, pupId,  DDR_PHY_DATA,  PBS_RX_PHY_REG+5 + effective_cs * 0x10, &temp));
 				temp += 0xA;
-           		CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+5, temp));
+				CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,ACCESS_TYPE_UNICAST,interfaceId, ACCESS_TYPE_UNICAST,pupId, DDR_PHY_DATA, PBS_RX_PHY_REG+5 + effective_cs * 0x10, temp));
 				DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,("Special: PBS:: I/F# %d , Bus# %d fix align to the right \n", interfaceId,pupId));
 			}
 
@@ -493,6 +502,7 @@
 )
 {
     GT_U32 interfaceId = 0, busId = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
 	devNum = devNum;
 
@@ -501,7 +511,7 @@
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busId = 0; busId < topologyMap->numOfBusPerInterface ; busId++)
+        for(busId = 0; busId < octetsPerInterfaceNum; busId++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
             mvPrintf("%d ,\n",centralizationState[interfaceId][busId]);
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingDb.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingDb.c
index 0e291b1..6c10a4e 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingDb.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingDb.c
@@ -18,7 +18,6 @@
 * FILE REVISION NUMBER:
 *       $Revision: 20 $
 ******************************************************************************/
-#ifdef CONFIG_DDR3
 
 #include "mvDdrTrainingIpDb.h"
 #include "mvDdr3TrainingIp.h"
@@ -26,7 +25,12 @@
 #include "mvDdr3TrainingIpDef.h"
 
 /************************** Globals ******************************/
-MV_HWS_TOPOLOGY_MAP *topologyMapDb[HWS_MAX_DEVICE_NUM] = {NULL};
+/*Device attributes structures*/
+MV_DDR_DEV_ATTRIBUTE ddrDevAttributes[HWS_MAX_DEVICE_NUM][MV_ATTR_LAST];  /* holds device attributes */
+GT_BOOL ddrDevAttrInitDone[HWS_MAX_DEVICE_NUM] = {0};	/* described whether device attributes were initialized */
+
+#ifdef CONFIG_DDR3
+MV_HWS_TOPOLOGY_MAP *topologyMapDb[HWS_MAX_DEVICE_NUM] = {NULL};          /* holds device DDR topology */
 
 /* list of allowed frequency listed in order of MV_HWS_DDR_FREQ */
 GT_U32 freqVal[DDR_FREQ_LIMIT] =
@@ -125,7 +129,7 @@
     1, /*5*/
     2, /*6*/
     3, /*7*/
-    10,
+    4, /*8*/
     10,
     5, /*10*/
     10,
@@ -322,6 +326,7 @@
 	0xFE
 };
 
+/************************** functions ******************************/
 
 /*Return speed Bin value for selected index and t* element*/
 GT_U32 speedBinTable
@@ -437,6 +442,85 @@
 	}
 }
 
+INLINE static GT_U32 patternTableGetSsoFullXtalkWord( GT_U8 bit, GT_U8 index)
+{
+	GT_U8 byte = (1 << bit);
+
+	if( 1 == (index&1) ){
+		byte = ~byte;
+	}
+
+	return (byte || (byte<<8) || (byte<<16) || (byte<<24));
+}
+
+INLINE static GT_U32 patternTableGetSsoXtalkFreeWord( GT_U8 bit, GT_U8 index)
+{
+	GT_U8 byte = (1 << bit);
+
+	if( 1 == (index&1) ){
+		byte = 0;
+	}
+
+	return (byte || (byte<<8) || (byte<<16) || (byte<<24));
+}
+
+INLINE static GT_U32 patternTableGetISIWord( GT_U8 index)
+{
+	GT_U8 I0 =  index%32;
+	GT_U8 I1 =  index%8;
+	GT_U32	Word;
+
+	if(I0 > 15)
+	{
+		Word =  ((I1 ==5)|(I1==7))?0xFFFFFFFF:0x0;
+	}else{
+		Word =  (I1 ==6)?0xFFFFFFFF:0x0;
+	}
+
+	Word = ((I0%16)>7)?~Word:Word;
+	return Word;
+}
+
+INLINE static GT_U32 patternTableGetSsoFullXtalkWord_16( GT_U8 bit, GT_U8 index)
+{
+	GT_U8 byte = (1 << bit);
+
+	if( 1 == (index&1) ){
+		byte = ~byte;
+	}
+
+	return (byte || (byte<<8) || ((~byte)<<16) || ((~byte)<<24));
+}
+
+INLINE static GT_U32 patternTableGetSsoXtalkFreeWord_16( GT_U8 bit, GT_U8 index)
+{
+	GT_U8 byte = (1 << bit);
+
+	if( 0 == ((index)&1) ){
+		return ((byte<<16) || (byte<<24));
+	}
+	else{
+		return (byte || (byte<<8));
+	}
+
+}
+INLINE static GT_U32 patternTableGetISIWord_16( GT_U8 index)
+{
+	GT_U8 I0 =  index%16;
+	GT_U8 I1 =  index%4;
+	GT_U32	Word;
+
+	if(I0 > 7)
+	{
+ 		Word = ( I1>1)?0x0000FFFF:0x0;
+	}else{
+		Word =  (I1 ==3)?0xFFFF0000:0x0;
+	}
+
+	Word = ((I0%8)>3)?~Word:Word;
+	return Word;
+}
+
 INLINE static GT_U32 patternTableGetVrefWord(GT_U8 index)
 {
 	if( 0 == ((patternVrefPatternTableMap[index/8] >> (index%8))&1) ){
@@ -546,13 +630,36 @@
 		case PATTERN_VREF:
 			pattern = patternTableGetVrefWord(index);
 			break;
+		case PATTERN_SSO_FULL_XTALK_DQ0:
+		case PATTERN_SSO_FULL_XTALK_DQ1:
+		case PATTERN_SSO_FULL_XTALK_DQ2:
+		case PATTERN_SSO_FULL_XTALK_DQ3:
+		case PATTERN_SSO_FULL_XTALK_DQ4:
+		case PATTERN_SSO_FULL_XTALK_DQ5:
+		case PATTERN_SSO_FULL_XTALK_DQ6:
+		case PATTERN_SSO_FULL_XTALK_DQ7:
+			pattern = patternTableGetSsoFullXtalkWord(type - PATTERN_SSO_FULL_XTALK_DQ0, index);
+			break;
+		case PATTERN_SSO_XTALK_FREE_DQ0:
+		case PATTERN_SSO_XTALK_FREE_DQ1:
+		case PATTERN_SSO_XTALK_FREE_DQ2:
+		case PATTERN_SSO_XTALK_FREE_DQ3:
+		case PATTERN_SSO_XTALK_FREE_DQ4:
+		case PATTERN_SSO_XTALK_FREE_DQ5:
+		case PATTERN_SSO_XTALK_FREE_DQ6:
+		case PATTERN_SSO_XTALK_FREE_DQ7:
+			pattern = patternTableGetSsoXtalkFreeWord(type - PATTERN_SSO_XTALK_FREE_DQ0, index);
+			break;
+		case PATTERN_ISI_XTALK_FREE:
+			pattern = patternTableGetISIWord( index);
+			break;
 		default:
 			pattern = 0;
 			break;
 		}
 	}
 	else{
-	/*16bit patterns*/	
+	/*16bit patterns*/
 		switch(type){
 		case PATTERN_PBS1:
 		case PATTERN_PBS2:
@@ -589,7 +696,13 @@
 			}
 			break;
 		case PATTERN_TEST:
-			pattern = PATTERN_0080;
+			/*pattern = PATTERN_0080;*/
+           if((index == 0) || (index == 3)){
+				pattern = 0x00000000;
+			}
+			else{
+				pattern = 0xFFFFFFFF;
+			}
 			break;
 		case PATTERN_FULL_SSO0:
 			pattern = 0x0000FFFF;
@@ -602,6 +715,29 @@
 		case PATTERN_VREF:
 			pattern = patternTableGetVrefWord16(index);
 			break;
+		case PATTERN_SSO_FULL_XTALK_DQ0:
+		case PATTERN_SSO_FULL_XTALK_DQ1:
+		case PATTERN_SSO_FULL_XTALK_DQ2:
+		case PATTERN_SSO_FULL_XTALK_DQ3:
+		case PATTERN_SSO_FULL_XTALK_DQ4:
+		case PATTERN_SSO_FULL_XTALK_DQ5:
+		case PATTERN_SSO_FULL_XTALK_DQ6:
+		case PATTERN_SSO_FULL_XTALK_DQ7:
+			pattern = patternTableGetSsoFullXtalkWord_16(type - PATTERN_SSO_FULL_XTALK_DQ0, index);
+			break;
+		case PATTERN_SSO_XTALK_FREE_DQ0:
+		case PATTERN_SSO_XTALK_FREE_DQ1:
+		case PATTERN_SSO_XTALK_FREE_DQ2:
+		case PATTERN_SSO_XTALK_FREE_DQ3:
+		case PATTERN_SSO_XTALK_FREE_DQ4:
+		case PATTERN_SSO_XTALK_FREE_DQ5:
+		case PATTERN_SSO_XTALK_FREE_DQ6:
+		case PATTERN_SSO_XTALK_FREE_DQ7:
+			pattern = patternTableGetSsoXtalkFreeWord_16(type - PATTERN_SSO_XTALK_FREE_DQ0, index);
+			break;
+		case PATTERN_ISI_XTALK_FREE:
+			pattern = patternTableGetISIWord_16( index);
+			break;
 		default:
 			pattern = 0;
 			break;
@@ -611,8 +747,9 @@
 	return pattern;
 }
 
+
 MV_HWS_TOPOLOGY_MAP*    ddr3TipGetTopologyMap
-( 
+(
     GT_U32  devNum
 )
 {
@@ -620,7 +757,7 @@
 }
 
 void    ddr3TipSetTopologyMap
-( 
+(
     GT_U32  devNum,
     MV_HWS_TOPOLOGY_MAP* topology
 )
@@ -630,3 +767,52 @@
 
 #endif /* CONFIG_DDR3 */
 
+/*****************************************************************************
+Device attributes functions
+******************************************************************************/
+void    ddr3TipDevAttrInit
+(
+    GT_U32  devNum
+)
+{
+    GT_U32 attrId;
+
+    for(attrId = 0; attrId < MV_ATTR_LAST; attrId++)
+    {
+        ddrDevAttributes[devNum][attrId] = 0xFF;
+    }
+
+    ddrDevAttrInitDone[devNum] = GT_TRUE;
+}
+
+GT_U32    ddr3TipDevAttrGet
+(
+    GT_U32                  devNum,
+    MV_DDR_DEV_ATTRIBUTE    attrId
+)
+{
+    if(ddrDevAttrInitDone[devNum] == GT_FALSE)
+    {
+        ddr3TipDevAttrInit(devNum);
+    }
+
+    return ddrDevAttributes[devNum][attrId];
+}
+
+void    ddr3TipDevAttrSet
+(
+    GT_U32                  devNum,
+    MV_DDR_DEV_ATTRIBUTE    attrId,
+    GT_U32                  value
+)
+{
+    if(ddrDevAttrInitDone[devNum] == GT_FALSE)
+    {
+        ddr3TipDevAttrInit(devNum);
+    }
+
+    ddrDevAttributes[devNum][attrId] = value;
+}
+
+
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingHwAlgos.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingHwAlgos.c
index 2d78a15..45b6be4 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingHwAlgos.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingHwAlgos.c
@@ -41,7 +41,6 @@
 #define GET_RD_SAMPLE_DELAY(data,cs) ((data >> rdSampleMask[cs]) & 0xf)
 #define GET_MAX(arg1,arg2) (arg1<arg2) ? (arg2) : (arg1);
 
-GT_U32 ckDelay = (GT_U32)-1, ckDelay_16 = (GT_U32)-1;
 GT_U32 caDelay;
 GT_BOOL	ddr3TipCentralizationSkipMinWindowCheck = GT_FALSE;
 GT_U8 currentVref[MAX_BUS_NUM][MAX_INTERFACE_NUM] ;
@@ -54,6 +53,7 @@
 GT_U8 vrefWindowSize[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 GT_U8 vrefWindowSizeTh = 12;
 
+extern GT_U32 ckDelay;
 extern MV_HWS_TOPOLOGY_MAP *topologyMap;
 extern GT_U32 csMaskReg[];
 extern GT_U32 delayEnable;
@@ -91,7 +91,8 @@
     GT_U32 dataValue;
     GT_U32 pupIndex;
     GT_32 maxPhase = MIN_VALUE, currentPhase;
-    MV_HWS_ACCESS_TYPE	    accessType = ACCESS_TYPE_UNICAST;
+    MV_HWS_ACCESS_TYPE  accessType = ACCESS_TYPE_UNICAST;
+    GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,accessType, interfaceId, DUNIT_ODT_CONTROL_REG, 0 << 8, 0x3 << 8));
     CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, accessType, interfaceId, READ_DATA_SAMPLE_DELAY, dataRead, MASK_ALL_BITS));
@@ -111,9 +112,9 @@
 			{
 				maxReadSample = ReadSample[csNum];
 			}
-            for(pupIndex=0 ; pupIndex < topologyMap->numOfBusPerInterface; pupIndex++)
+            for(pupIndex=0 ; pupIndex < octetsPerInterfaceNum; pupIndex++)
             {
-                CHECK_STATUS(mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, pupIndex, DDR_PHY_DATA, RL_PHY_REG + CS_REG_VALUE(csNum), &dataValue));
+                CHECK_STATUS(mvHwsDdr3TipBUSRead(devNum, interfaceId, ACCESS_TYPE_UNICAST, pupIndex, DDR_PHY_DATA, RL_PHY_REG + CS_BYTE_GAP(csNum), &dataValue));
 				currentPhase = ((GT_32)dataValue&0xE0)>>6;
                 if ( currentPhase >= maxPhase )
                 {
@@ -171,16 +172,18 @@
 	/*	The Vref register have non linear order. need to check what will be in futur  projects. */
 	GT_U32 vrefMap[8] = {1,2,3,4,5,6,7,0};
 	/*	state and parameter definitions */
-	GT_U32 initialStep = VREF_INITIAL_STEP;
-	GT_U32 secondStep = VREF_SECOND_STEP;/* need to be assign with minus ????? */
+	GT_U8  initialStep = VREF_INITIAL_STEP;
+	GT_U8  secondStep = VREF_SECOND_STEP;/* need to be assign with minus ????? */
 	GT_U32 algoRunFlag = 0, currrentVref = 0;
 	GT_U32 whileCount = 0;
-	GT_U32 pup = 0, interfaceId  = 0, numPup = 0, Rep = 0;
+	GT_U32 pup = 0, interfaceId  = 0, numPup = 0;
+    GT_U8  rep = 0;
 	GT_U32 dataValue = 0;
 	GT_U32 regAddr = 0xA8;
 	GT_U32 copyStartPattern, copyEndPattern;
     MV_HWS_RESULT* flowResult = ddr3TipGetResultPtr(trainingStage);
 	GT_U8 res[4];
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
 	CHECK_STATUS(ddr3TipSpecialRx(devNum));
 
@@ -196,7 +199,7 @@
 	for(interfaceId = 0 ; interfaceId < MAX_INTERFACE_NUM ; interfaceId++)
 	{
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-		for(pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+		for(pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 		{
 			currentVref[pup][interfaceId] = 0;
 			lastVref[pup][interfaceId] = 0;
@@ -216,12 +219,12 @@
 		interfaceState[interfaceId] = 0;
 	}
 
-	numPup = topologyMap->numOfBusPerInterface*MAX_INTERFACE_NUM;/*TODO set number of active interfaces*/
+	numPup = octetsPerInterfaceNum*MAX_INTERFACE_NUM;/*TODO set number of active interfaces*/
 	while((algoRunFlag <= numPup)&(whileCount<10)  )
 	{
 		whileCount++;
 
-		for(Rep = 1 ;  Rep < 4 ; Rep++)
+		for(rep = 1 ;  rep < 4 ; rep++)
 		{
 			ddr3TipCentralizationSkipMinWindowCheck = GT_TRUE;
 			ddr3TipCentralizationRx(devNum);
@@ -233,14 +236,14 @@
 				if(interfaceState[interfaceId] != 4)
 				{
 					GetValidWinRx(devNum, interfaceId,  res);
-					for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+					for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 					{
        					VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 						if(pupState[pup][interfaceId] == VREF_CONVERGE)
 						{
 							continue;
 						}
-						currentValidWindow[pup][interfaceId] = (currentValidWindow[pup][interfaceId]*(Rep-1) + 1000*res[pup])/Rep;
+						currentValidWindow[pup][interfaceId] = (currentValidWindow[pup][interfaceId]*(rep-1) + 1000*res[pup])/rep;
 					}
 				}
 			}
@@ -250,7 +253,7 @@
 		{
        		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 			DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("currentValidWindow: IF[ %d ] - ", interfaceId ));
-			for(pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+			for(pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 			{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
    				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("%d ", currentValidWindow[pup][interfaceId]));
@@ -261,7 +264,7 @@
 		for(interfaceId = 0 ; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-			for(pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+			for(pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 			{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("I/F[ %d ],pup[ %d ] STATE #%d (%d)\n", interfaceId, pup,
@@ -365,7 +368,7 @@
 	for(interfaceId = 0 ; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
 	{
    		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-		for(pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+		for(pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 		{
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
    			CHECK_STATUS(mvHwsDdr3TipBUSRead( devNum, interfaceId, ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, regAddr, &dataValue));
@@ -398,7 +401,7 @@
 	/* CA_delay is delaying the of the entire command & Address signals (include Clock signal � to overcome DGL error on the Clock versus the DQS). */
 	/*Calc ADLL Tap*/
 
-	if( (ckDelay == -1) || (ckDelay_16 == -1) )
+	if(ckDelay == MV_PARAMS_UNDEFINED)
 	{
 		DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_ERROR,("ERROR: One of ckDelay values not initialized!!!\n"));
 	}
@@ -407,15 +410,9 @@
 	{
 		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 		/*Calc Delay ps in ADLL tap*/
-		if (topologyMap->interfaceParams[interfaceId].busWidth == BUS_WIDTH_16)
-		{
-			ckNumADLLTap = ckDelay_16/adllTap;
-		}
-		else
-		{
-			ckNumADLLTap = ckDelay/adllTap;
-		}
+		ckNumADLLTap = ckDelay/adllTap;
 		caNumADLLTap = caDelay/adllTap;
+
 		data = (ckNumADLLTap & 0x3f) + ((caNumADLLTap & 0x3f) << 10);
 		/* Set the ADLL number to the CK ADLL for Interfaces for all Pup */
 		DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,("ckNumADLLTap %d caNumADLLTap %d adllTap %d\n",ckNumADLLTap,caNumADLLTap,adllTap));
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingIpEngine.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingIpEngine.c
index a55a2ee..85d0540 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingIpEngine.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingIpEngine.c
@@ -69,130 +69,253 @@
     RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG, RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
     RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG, RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
     RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG, RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
-    RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG, RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
-    RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG, RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+    RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG, RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
+    RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG, RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
 };
 
 GT_U16   maskResultsPupRegMapPup3ECC[] =
 {
     RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG, RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG, RESULT_CONTROL_BYTE_PUP_4_REG
 };
-	   
-PatternInfo patternTable_16[] = 
-{
-/* num tx phases  tx burst   delay between   rx pattern start_address   patternLen*/
-   {1,           1,          2,                 1,           0x0080,            2      }, /* PATTERN_PBS1*/            
-   {1,           1,          2,                 1,           0x00C0,            2      }, /* PATTERN_PBS2*/            
-   {1,           1,          2,                 1,           0x0100,            2      }, /* PATTERN_RL*/              
-   {0xf,       0x7,         2,               0x7,           0x0140,           16       }, /* PATTERN_STATIC_PBS*/      
-   {0xf,       0x7,         2,               0x7,           0x0190,           16       }, /* PATTERN_KILLER_DQ0*/      
-   {0xf,       0x7,         2,               0x7,           0x01D0,           16       }, /* PATTERN_KILLER_DQ1*/
-   {0xf,       0x7,         2,               0x7,           0x0210,           16       }, /* PATTERN_KILLER_DQ2*/
-   {0xf,       0x7,         2,               0x7,           0x0250,           16       }, /* PATTERN_KILLER_DQ3*/
-   {0xf,       0x7,         2,               0x7,           0x0290,           16       }, /* PATTERN_KILLER_DQ4*/
-   {0xf,       0x7,         2,               0x7,           0x02D0,           16       }, /* PATTERN_KILLER_DQ5*/
-   {0xf,       0x7,         2,               0x7,           0x0310,           16       }, /* PATTERN_KILLER_DQ6*/
-   {0xf,       0x7,         2,               0x7,           0x0350,           16       }, /* PATTERN_KILLER_DQ7*/
-   {1,           1,          2,                 1,           0x0380,            2      }, /* PATTERN_PBS3*/            
-   {1,           1,          2,                 1,           0x0000,            2      }, /* PATTERN_RL2*/             
-   {1,           1,          2,                 1,           0x0040,            2      }, /* PATTERN_TEST*/            
-   {0xf,       0x7,         2,               0x7,           0x03C0,           16       }, /* PATTERN_FULL_SSO_1T*/     
-   {0xf,       0x7,         2,               0x7,           0x0400,           16       }, /* PATTERN_FULL_SSO_2T*/     
-   {0xf,       0x7,         2,               0x7,           0x0440,           16       }, /* PATTERN_FULL_SSO_3T*/     
-   {0xf,       0x7,         2,               0x7,           0x0480,           16       }, /* PATTERN_FULL_SSO_4T*/     
-   {0xf,       0x7,         2,               0x7,           0x04C0,           16       }  /* PATTERN_VREF*/
-/*Note: actual start_address is <<3 of defined addess*/
-};   
 
 #ifdef CONFIG_DDR3
-PatternInfo patternTable_32[] = 
+PatternInfo patternTable_16[] =
 {
 /* num tx phases  tx burst   delay between   rx pattern start_address   patternLen*/
-   {3,           3,          2,                 3,           0x0080,            4       }, /* PATTERN_PBS1*/            
-   {3,           3,          2,                 3,           0x00C0,            4       }, /* PATTERN_PBS2*/            
-   {3,           3,          2,                 3,           0x0100,            4       }, /* PATTERN_RL*/              
-   {0x1f,       0xf,         2,               0xf,           0x0140,           32       }, /* PATTERN_STATIC_PBS*/      
-   {0x1f,       0xf,         2,               0xf,           0x0190,           32       }, /* PATTERN_KILLER_DQ0*/
-   {0x1f,       0xf,         2,               0xf,           0x01D0,           32       }, /* PATTERN_KILLER_DQ1*/
-   {0x1f,       0xf,         2,               0xf,           0x0210,           32       }, /* PATTERN_KILLER_DQ2*/
-   {0x1f,       0xf,         2,               0xf,           0x0250,           32       }, /* PATTERN_KILLER_DQ3*/
-   {0x1f,       0xf,         2,               0xf,           0x0290,           32       }, /* PATTERN_KILLER_DQ4*/
-   {0x1f,       0xf,         2,               0xf,           0x02D0,           32       }, /* PATTERN_KILLER_DQ5*/
-   {0x1f,       0xf,         2,               0xf,           0x0310,           32       }, /* PATTERN_KILLER_DQ6*/
-   {0x1f,       0xf,         2,               0xf,           0x0350,           32       }, /* PATTERN_KILLER_DQ7*/
-   {3,           3,          2,                 3,           0x0380,            4       }, /* PATTERN_PBS3*/            
-   {3,           3,          2,                 3,           0x0000,            4       }, /* PATTERN_RL2*/             
-   {3,           3,          2,                 3,           0x0040,            4       }, /* PATTERN_TEST*/            
-   {0x1f,       0xf,         2,               0xf,           0x03C0,           32       }, /* PATTERN_FULL_SSO_1T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0400,           32       }, /* PATTERN_FULL_SSO_2T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0440,           32       }, /* PATTERN_FULL_SSO_3T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0480,           32       }, /* PATTERN_FULL_SSO_4T*/     
-   {0x1f,       0xf,         2,               0xf,           0x04C0,           32       }  /* PATTERN_VREF*/            
+   {0x1,	1,	2,  1, 0x0080,  2 },	/* PATTERN_PBS1*/
+   {0x1,	1,	2,  1, 0x00C0,  2 },	/* PATTERN_PBS2*/
+   {0x1,	1,	2,  1, 0x0380,  2 },	/* PATTERN_PBS3*/
+   {0x1,	1,	2,  1, 0x0040,  2 },	/* PATTERN_TEST*/
+   {0x1,	1,	2,  1, 0x0100,  2 },	/* PATTERN_RL*/
+   {0x1,	1,	2,  1, 0x0000,  2 },	/* PATTERN_RL2*/
+   {0xf,	7,  2,	7, 0x0140, 16  },	/* PATTERN_STATIC_PBS*/
+   {0xf,	7,  2,	7, 0x0190, 16  },	/* PATTERN_KILLER_DQ0*/
+   {0xf,  	7,  2,	7, 0x01D0, 16  },	/* PATTERN_KILLER_DQ1*/
+   {0xf,  	7,  2,	7, 0x0210, 16  },	/* PATTERN_KILLER_DQ2*/
+   {0xf,  	7,  2,	7, 0x0250, 16  },	/* PATTERN_KILLER_DQ3*/
+   {0xf,  	7,  2,	7, 0x0290, 16  },	/* PATTERN_KILLER_DQ4*/
+   {0xf,  	7,  2,	7, 0x02D0, 16  },	/* PATTERN_KILLER_DQ5*/
+   {0xf,  	7,  2,	7, 0x0310, 16  },	/* PATTERN_KILLER_DQ6*/
+   {0xf,  	7,  2,	7, 0x0350, 16  },	/* PATTERN_KILLER_DQ7*/
+   {0xf,  	7,  2,	7, 0x04C0, 16  },	/* PATTERN_VREF*/
+   {0xf,  	7,  2,	7, 0x03C0, 16  },	/* PATTERN_FULL_SSO_1T*/
+   {0xf,  	7,  2,	7, 0x0400, 16  },	/* PATTERN_FULL_SSO_2T*/
+   {0xf,  	7,  2,	7, 0x0440, 16  },	/* PATTERN_FULL_SSO_3T*/
+   {0xf,  	7,  2,	7, 0x0480, 16  },	/* PATTERN_FULL_SSO_4T*/
+   {0xf,  	7,  2,	7, 0x6280, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
+   {0xf,  	7,  2,	7, 0x6680, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
+   {0xf,  	7,  2,	7, 0x6A80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
+   {0xf,  	7,  2,	7, 0x6E80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
+   {0xf,  	7,  2,	7, 0x7280, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
+   {0xf,  	7,  2,	7, 0x7680, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
+   {0xf,  	7,  2,	7, 0x7A80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
+   {0xf,  	7,  2,	7, 0x7E80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
+   {0xf,  	7,  2,	7, 0x8280, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
+   {0xf,  	7,  2,	7, 0x8680, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
+   {0xf,  	7,  2,	7, 0x8A80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
+   {0xf,  	7,  2,	7, 0x8E80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
+   {0xf,  	7,  2,	7, 0x9280, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
+   {0xf,  	7,  2,	7, 0x9680, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
+   {0xf,  	7,  2,	7, 0x9A80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
+   {0xf,  	7,  2,	7, 0x9E80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
+   {0xf,  	7,  2,	7, 0xA280, 16  } /* PATTERN_ISI_XTALK_FREE*/
 /*Note: actual start_address is <<3 of defined addess*/
-};   
-#else
+};
+
 PatternInfo patternTable_32[] =
 {
 /* num tx phases  tx burst   delay between   rx pattern start_address   patternLen*/
-   {3,           3,          2,                 3,           0x0080,            4       }, /* PATTERN_PBS1*/            
-   {3,           3,          2,                 3,           0x00C0,            4       }, /* PATTERN_PBS2*/            
-   {3,           3,          2,                 3,           0x0100,            4       }, /* PATTERN_RL*/              
-   {0x1f,       0xf,         2,               0xf,           0x0140,           32       }, /* PATTERN_STATIC_PBS*/      
-   {0x1f,       0xf,         2,               0xf,           0x0180,           32       }, /* PATTERN_KILLER_DQ0*/      
-   {0x1f,       0xf,         2,               0xf,           0x01C0,           32       }, /* PATTERN_KILLER_DQ1*/      
-   {0x1f,       0xf,         2,               0xf,           0x0200,           32       }, /* PATTERN_KILLER_DQ2*/      
-   {0x1f,       0xf,         2,               0xf,           0x0240,           32       }, /* PATTERN_KILLER_DQ3*/      
-   {0x1f,       0xf,         2,               0xf,           0x0280,           32       }, /* PATTERN_KILLER_DQ4*/      
-   {0x1f,       0xf,         2,               0xf,           0x02C0,           32       }, /* PATTERN_KILLER_DQ5*/      
-   {0x1f,       0xf,         2,               0xf,           0x0300,           32       }, /* PATTERN_KILLER_DQ6*/      
-   {0x1f,       0xf,         2,               0xf,           0x0340,           32       }, /* PATTERN_KILLER_DQ7*/      
-   {0x1f,       0xf,         2,               0xf,           0x1180,           32       }, /* PATTERN_KILLER_DQ0_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x11C0,           32       }, /* PATTERN_KILLER_DQ1_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x1200,           32       }, /* PATTERN_KILLER_DQ2_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x1240,           32       }, /* PATTERN_KILLER_DQ3_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x1280,           32       }, /* PATTERN_KILLER_DQ4_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x12C0,           32       }, /* PATTERN_KILLER_DQ5_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x1300,           32       }, /* PATTERN_KILLER_DQ6_EXT*/      
-   {0x1f,       0xf,         2,               0xf,           0x1340,           32       }, /* PATTERN_KILLER_DQ7_EXT*/  
-   {0x1f,       0xf,         2,               0xf,           0x04C0,           32       }, /* PATTERN_VREF*/            
-   {0x1f,       0xf,         2,               0xf,           0x14C0,           32       }, /* PATTERN_VREF_INV*/            
-   {0x1f,       0xf,         2,               0xf,           0x1500,           32       }, /* PATTERN_RESONANCE_1T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1540,           32       }, /* PATTERN_RESONANCE_2T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1580,           32       }, /* PATTERN_RESONANCE_3T*/  
-   {0x1f,       0xf,         2,               0xf,           0x15C0,           32       }, /* PATTERN_RESONANCE_4T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1600,           32       }, /* PATTERN_RESONANCE_5T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1640,           32       }, /* PATTERN_RESONANCE_6T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1680,           32       }, /* PATTERN_RESONANCE_7T*/  
-   {0x1f,       0xf,         2,               0xf,           0x16C0,           32       }, /* PATTERN_RESONANCE_8T*/  
-   {0x1f,       0xf,         2,               0xf,           0x1700,           32       }, /* PATTERN_RESONANCE_9T*/  
-   {3,           3,          2,                 3,           0x0380,            4       }, /* PATTERN_PBS3*/            
-   {3,           3,          2,                 3,           0x0000,            4       }, /* PATTERN_RL2*/             
-   {3,           3,          2,                 3,           0x0040,            4       }, /* PATTERN_TEST*/            
-   {0x1f,       0xf,         2,               0xf,           0x03C0,           32       }, /* PATTERN_FULL_SSO_1T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0400,           32       }, /* PATTERN_FULL_SSO_2T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0440,           32       }, /* PATTERN_FULL_SSO_3T*/     
-   {0x1f,       0xf,         2,               0xf,           0x0480,           32       }  /* PATTERN_FULL_SSO_4T*/     
+   {0x3,	0x3,  2,  0x3, 0x0080,  4 },	/* PATTERN_PBS1*/
+   {0x3,	0x3,  2,  0x3, 0x00C0,  4 },	/* PATTERN_PBS2*/
+   {0x3,	0x3,  2,  0x3, 0x0380,  4 },	/* PATTERN_PBS3*/
+   {0x3,	0x3,  2,  0x3, 0x0040,  4 },	/* PATTERN_TEST*/
+   {0x3,	0x3,  2,  0x3, 0x0100,  4 },	/* PATTERN_RL*/
+   {0x3,	0x3,  2,  0x3, 0x0000,  4 },	/* PATTERN_RL2*/
+   {0x1f,	0xF,  2,  0xf, 0x0140, 32  },	/* PATTERN_STATIC_PBS*/
+   {0x1f,	0xF,  2,  0xf, 0x0190, 32  },	/* PATTERN_KILLER_DQ0*/
+   {0x1f,  	0xF,  2,  0xf, 0x01D0, 32  },	/* PATTERN_KILLER_DQ1*/
+   {0x1f,  	0xF,  2,  0xf, 0x0210, 32  },	/* PATTERN_KILLER_DQ2*/
+   {0x1f,  	0xF,  2,  0xf, 0x0250, 32  },	/* PATTERN_KILLER_DQ3*/
+   {0x1f,  	0xF,  2,  0xf, 0x0290, 32  },	/* PATTERN_KILLER_DQ4*/
+   {0x1f,  	0xF,  2,  0xf, 0x02D0, 32  },	/* PATTERN_KILLER_DQ5*/
+   {0x1f,  	0xF,  2,  0xf, 0x0310, 32  },	/* PATTERN_KILLER_DQ6*/
+   {0x1f,  	0xF,  2,  0xf, 0x0350, 32  },	/* PATTERN_KILLER_DQ7*/
+   {0x1f,  	0xF,  2,  0xf, 0x04C0, 32  },	/* PATTERN_VREF*/
+   {0x1f,  	0xF,  2,  0xf, 0x03C0, 32  },	/* PATTERN_FULL_SSO_1T*/
+   {0x1f,  	0xF,  2,  0xf, 0x0400, 32  },	/* PATTERN_FULL_SSO_2T*/
+   {0x1f,  	0xF,  2,  0xf, 0x0440, 32  },	/* PATTERN_FULL_SSO_3T*/
+   {0x1f,  	0xF,  2,  0xf, 0x0480, 32  },	/* PATTERN_FULL_SSO_4T*/
+   {0x1f,  	0xF,  2,  0xf, 0x6280, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
+   {0x1f,  	0xF,  2,  0xf, 0x6680, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
+   {0x1f,  	0xF,  2,  0xf, 0x6A80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
+   {0x1f,  	0xF,  2,  0xf, 0x6E80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
+   {0x1f,  	0xF,  2,  0xf, 0x7280, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
+   {0x1f,  	0xF,  2,  0xf, 0x7680, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
+   {0x1f,  	0xF,  2,  0xf, 0x7A80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
+   {0x1f,  	0xF,  2,  0xf, 0x7E80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
+   {0x1f,  	0xF,  2,  0xf, 0x8280, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
+   {0x1f,  	0xF,  2,  0xf, 0x8680, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
+   {0x1f,  	0xF,  2,  0xf, 0x8A80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
+   {0x1f,  	0xF,  2,  0xf, 0x8E80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
+   {0x1f,  	0xF,  2,  0xf, 0x9280, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
+   {0x1f,  	0xF,  2,  0xf, 0x9680, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
+   {0x1f,  	0xF,  2,  0xf, 0x9A80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
+   {0x1f,  	0xF,  2,  0xf, 0x9E80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
+   {0x1f,  	0xF,  2,  0xf, 0xA280, 32  } /* PATTERN_ISI_XTALK_FREE*/
+
+
 /*Note: actual start_address is <<3 of defined addess*/
 };
+#else
+PatternInfo patternTable_16[] =
+{
+/* num tx phases  tx burst   delay between   rx pattern start_address   patternLen*/
+   {0x1, 	0x1,	2,  0x1, 0x0000,  2  }, /* PATTERN_PBS1*/
+   {0x1, 	0x1,	2,  0x1, 0x0080,  2  }, /* PATTERN_PBS2*/
+   {0x1, 	0x1,	2,  0x1, 0x0100,  2  }, /* PATTERN_PBS3*/
+   {0x1, 	0x1,	2,  0x1, 0x0180,  2  }, /* PATTERN_TEST*/
+   {0x1, 	0x1,	2,  0x1, 0x0200,  2  }, /* PATTERN_RL*/
+   {0x1, 	0x1,	2,  0x1, 0x0280,  2  }, /* PATTERN_RL2*/
+   {0xf,  	0x7,    2,	0x7, 0x0680, 16  }, /* PATTERN_STATIC_PBS*/
+   {0xf,  	0x7,    2,	0x7, 0x0A80, 16  }, /* PATTERN_KILLER_DQ0*/
+   {0xf,  	0x7,    2,	0x7, 0x0E80, 16  }, /* PATTERN_KILLER_DQ1*/
+   {0xf,  	0x7,    2,	0x7, 0x1280, 16  }, /* PATTERN_KILLER_DQ2*/
+   {0xf,  	0x7,    2,	0x7, 0x1680, 16  }, /* PATTERN_KILLER_DQ3*/
+   {0xf,  	0x7,    2,	0x7, 0x1A80, 16  }, /* PATTERN_KILLER_DQ4*/
+   {0xf,  	0x7,    2,	0x7, 0x1E80, 16  }, /* PATTERN_KILLER_DQ5*/
+   {0xf,  	0x7,    2,	0x7, 0x2280, 16  }, /* PATTERN_KILLER_DQ6*/
+   {0xf,  	0x7,    2,	0x7, 0x2680, 16  }, /* PATTERN_KILLER_DQ7*/
+   {0xf,  	0x7,    2,	0x7, 0x2A80, 16  }, /* PATTERN_KILLER_DQ0_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x2E80, 16  }, /* PATTERN_KILLER_DQ1_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x3280, 16  }, /* PATTERN_KILLER_DQ2_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x3680, 16  }, /* PATTERN_KILLER_DQ3_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x3A80, 16  }, /* PATTERN_KILLER_DQ4_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x3E80, 16  }, /* PATTERN_KILLER_DQ5_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x4280, 16  }, /* PATTERN_KILLER_DQ6_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x4680, 16  }, /* PATTERN_KILLER_DQ7_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x4A80, 16  }, /* PATTERN_VREF*/
+   {0xf,  	0x7,    2,	0x7, 0x4E80, 16  }, /* PATTERN_VREF_INV*/
+   {0xf,  	0x7,    2,	0x7, 0x5280, 16  }, /* PATTERN_FULL_SSO_0T*/
+   {0xf,  	0x7,    2,	0x7, 0x5680, 16  }, /* PATTERN_FULL_SSO_1T*/
+   {0xf,  	0x7,    2,	0x7, 0x5A80, 16  }, /* PATTERN_FULL_SSO_2T*/
+   {0xf,  	0x7,    2,	0x7, 0x5E80, 16  }, /* PATTERN_FULL_SSO_3T*/
+   {0xf,  	0x7,    2,	0x7, 0x6280, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
+   {0xf,  	0x7,    2,	0x7, 0x6680, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
+   {0xf,  	0x7,    2,	0x7, 0x6A80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
+   {0xf,  	0x7,    2,	0x7, 0x6E80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
+   {0xf,  	0x7,    2,	0x7, 0x7280, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
+   {0xf,  	0x7,    2,	0x7, 0x7680, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
+   {0xf,  	0x7,    2,	0x7, 0x7A80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
+   {0xf,  	0x7,    2,	0x7, 0x7E80, 16  }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
+   {0xf,  	0x7,    2,	0x7, 0x8280, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
+   {0xf,  	0x7,    2,	0x7, 0x8680, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
+   {0xf,  	0x7,    2,	0x7, 0x8A80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
+   {0xf,  	0x7,    2,	0x7, 0x8E80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
+   {0xf,  	0x7,    2,	0x7, 0x9280, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
+   {0xf,  	0x7,    2,	0x7, 0x9680, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
+   {0xf,  	0x7,    2,	0x7, 0x9A80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
+   {0xf,  	0x7,    2,	0x7, 0x9E80, 16  }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
+   {0xf,  	0x7,    2,	0x7, 0xA280, 16  }, /* PATTERN_ISI_XTALK_FREE*/
+   {0xf,  	0x7,    2,	0x7, 0xA680, 16  }, /* PATTERN_RESONANCE_1T*/
+   {0xf,  	0x7,    2,	0x7, 0xAA80, 16  }, /* PATTERN_RESONANCE_2T*/
+   {0xf,  	0x7,    2,	0x7, 0xAE80, 16  }, /* PATTERN_RESONANCE_3T*/
+   {0xf,  	0x7,    2,	0x7, 0xB280, 16  }, /* PATTERN_RESONANCE_4T*/
+   {0xf,  	0x7,    2,	0x7, 0xB680, 16  }, /* PATTERN_RESONANCE_5T*/
+   {0xf,  	0x7,    2,	0x7, 0xBA80, 16  }, /* PATTERN_RESONANCE_6T*/
+   {0xf,  	0x7,    2,	0x7, 0xBE80, 16  }, /* PATTERN_RESONANCE_7T*/
+   {0xf,  	0x7,    2,	0x7, 0xC280, 16  }, /* PATTERN_RESONANCE_8T*/
+   {0xf,  	0x7,    2,	0x7, 0xC680, 16  }  /* PATTERN_RESONANCE_9T*/
+/*Note: actual start_address is <<3 of defined addess*/
+};
+
+PatternInfo patternTable_32[] =
+{
+/* num tx phases  tx burst   delay between   rx pattern start_address   patternLen*/
+   {0x3, 	0x3,	2,  0x3, 0x0000,  4  }, /* PATTERN_PBS1*/
+   {0x3, 	0x3,	2,  0x3, 0x0080,  4  }, /* PATTERN_PBS2*/
+   {0x3, 	0x3,	2,  0x3, 0x0100,  4  }, /* PATTERN_PBS3*/
+   {0x3, 	0x3,	2,  0x3, 0x0180,  4  }, /* PATTERN_TEST*/
+   {0x3, 	0x3,	2,  0x3, 0x0200,  4  }, /* PATTERN_RL*/
+   {0x3, 	0x3,	2,  0x3, 0x0280,  4  }, /* PATTERN_RL2*/
+   {0x1f,  	0xf,    2,	0xf, 0x0680, 32  }, /* PATTERN_STATIC_PBS*/
+   {0x1f,  	0xf,    2,	0xf, 0x0A80, 32  }, /* PATTERN_KILLER_DQ0*/
+   {0x1f,  	0xf,    2,	0xf, 0x0E80, 32  }, /* PATTERN_KILLER_DQ1*/
+   {0x1f,  	0xf,    2,	0xf, 0x1280, 32  }, /* PATTERN_KILLER_DQ2*/
+   {0x1f,  	0xf,    2,	0xf, 0x1680, 32  }, /* PATTERN_KILLER_DQ3*/
+   {0x1f,  	0xf,    2,	0xf, 0x1A80, 32  }, /* PATTERN_KILLER_DQ4*/
+   {0x1f,  	0xf,    2,	0xf, 0x1E80, 32  }, /* PATTERN_KILLER_DQ5*/
+   {0x1f,  	0xf,    2,	0xf, 0x2280, 32  }, /* PATTERN_KILLER_DQ6*/
+   {0x1f,  	0xf,    2,	0xf, 0x2680, 32  }, /* PATTERN_KILLER_DQ7*/
+   {0x1f,  	0xf,    2,	0xf, 0x2A80, 32  }, /* PATTERN_KILLER_DQ0_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x2E80, 32  }, /* PATTERN_KILLER_DQ1_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x3280, 32  }, /* PATTERN_KILLER_DQ2_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x3680, 32  }, /* PATTERN_KILLER_DQ3_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x3A80, 32  }, /* PATTERN_KILLER_DQ4_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x3E80, 32  }, /* PATTERN_KILLER_DQ5_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x4280, 32  }, /* PATTERN_KILLER_DQ6_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x4680, 32  }, /* PATTERN_KILLER_DQ7_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x4A80, 32  }, /* PATTERN_VREF*/
+   {0x1f,  	0xf,    2,	0xf, 0x4E80, 32  }, /* PATTERN_VREF_INV*/
+   {0x1f,  	0xf,    2,	0xf, 0x5280, 32  }, /* PATTERN_FULL_SSO_0T*/
+   {0x1f,  	0xf,    2,	0xf, 0x5680, 32  }, /* PATTERN_FULL_SSO_1T*/
+   {0x1f,  	0xf,    2,	0xf, 0x5A80, 32  }, /* PATTERN_FULL_SSO_2T*/
+   {0x1f,  	0xf,    2,	0xf, 0x5E80, 32  }, /* PATTERN_FULL_SSO_3T*/
+   {0x1f,  	0xf,    2,	0xf, 0x6280, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
+   {0x1f,  	0xf,    2,	0xf, 0x6680, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
+   {0x1f,  	0xf,    2,	0xf, 0x6A80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
+   {0x1f,  	0xf,    2,	0xf, 0x6E80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
+   {0x1f,  	0xf,    2,	0xf, 0x7280, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
+   {0x1f,  	0xf,    2,	0xf, 0x7680, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
+   {0x1f,  	0xf,    2,	0xf, 0x7A80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
+   {0x1f,  	0xf,    2,	0xf, 0x7E80, 32  }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
+   {0x1f,  	0xf,    2,	0xf, 0x8280, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
+   {0x1f,  	0xf,    2,	0xf, 0x8680, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
+   {0x1f,  	0xf,    2,	0xf, 0x8A80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
+   {0x1f,  	0xf,    2,	0xf, 0x8E80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
+   {0x1f,  	0xf,    2,	0xf, 0x9280, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
+   {0x1f,  	0xf,    2,	0xf, 0x9680, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
+   {0x1f,  	0xf,    2,	0xf, 0x9A80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
+   {0x1f,  	0xf,    2,	0xf, 0x9E80, 32  }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
+   {0x1f,  	0xf,    2,	0xf, 0xA280, 32  }, /* PATTERN_ISI_XTALK_FREE*/
+   {0x1f,  	0xf,    2,	0xf, 0xA680, 32  }, /* PATTERN_RESONANCE_1T*/
+   {0x1f,  	0xf,    2,	0xf, 0xAA80, 32  }, /* PATTERN_RESONANCE_2T*/
+   {0x1f,  	0xf,    2,	0xf, 0xAE80, 32  }, /* PATTERN_RESONANCE_3T*/
+   {0x1f,  	0xf,    2,	0xf, 0xB280, 32  }, /* PATTERN_RESONANCE_4T*/
+   {0x1f,  	0xf,    2,	0xf, 0xB680, 32  }, /* PATTERN_RESONANCE_5T*/
+   {0x1f,  	0xf,    2,	0xf, 0xBA80, 32  }, /* PATTERN_RESONANCE_6T*/
+   {0x1f,  	0xf,    2,	0xf, 0xBE80, 32  }, /* PATTERN_RESONANCE_7T*/
+   {0x1f,  	0xf,    2,	0xf, 0xC280, 32  }, /* PATTERN_RESONANCE_8T*/
+   {0x1f,  	0xf,    2,	0xf, 0xC680, 32  }  /* PATTERN_RESONANCE_9T*/
+/*Note: actual start_address is <<3 of defined addess*/
+};
+
 #endif
 
 /*******************************************************************************/
 GT_U32                      trainDevNum;
 MV_HWS_DDR_CS               traintrainCsType;
-GT_U32                      trainPupNum; 
+GT_U32                      trainPupNum;
 MV_HWS_TRAINING_RESULT      trainResultType;
 MV_HWS_ControlElement       trainControlElement;
 MV_HWS_SearchDirection      traineSearchDir;
 MV_HWS_DIRECTION            trainDirection;
-GT_U32                      trainIfSelect; 
+GT_U32                      trainIfSelect;
 GT_U32                      trainInitValue;
 GT_U32                      trainNumberIterations;
 MV_HWS_PATTERN              trainPattern;
 MV_HWS_EdgeCompare          trainEdgeCompare;
 GT_U32                      trainCsNum;
 GT_U32                      trainIfAcess, trainIfId, trainPupAccess;
+#ifdef CONFIG_DDR4
+GT_U32                      maxPollingForDone = 100000000;  /* this counter was increased for DDR4
+                                                               due to A390 DB-GP DDR4 failure */
+#else /* DDR3 */
+#ifdef CONFIG_BOBK
+GT_U32                      maxPollingForDone = 1000;
+#else
 GT_U32                      maxPollingForDone = 1000000;
-
+#endif /* CONFIG_BOBK */
+#endif /* CONFIG_DDR4 */
 extern MV_HWS_RESULT trainingResult[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
 extern AUTO_TUNE_STAGE trainingStage;
 
@@ -245,7 +368,7 @@
 )
 {
     
-    GT_U32 maskDqNumOfRegs, maskPupNumOfRegs, indexCnt,pollCnt, regData, pupId;
+    GT_U32 maskDqNumOfRegs, maskPupNumOfRegs, indexCnt,pollCnt, regData, pupId, triggerRegAddr;
     GT_U32 txBurstSize;
     GT_U32 delayBetweenBurst;
     GT_U32 rdMode;
@@ -253,8 +376,9 @@
 	PatternInfo *patternTable = ddr3TipGetPatternTable();
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-    if (pupNum >= topologyMap->numOfBusPerInterface)
+    if (pupNum >= octetsPerInterfaceNum)
     {
         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
     }
@@ -373,8 +497,8 @@
     regData |= (0x6 << 28);
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, CALIB_OBJ_PRFA_REG, regData | (initValue << 8) , 0xff | (0xFFFF << 8)| (0xF << 24) | (GT_U32)(0xF << 28)));
 
-	maskDqNumOfRegs = topologyMap->numOfBusPerInterface * BUS_WIDTH_IN_BITS;
-	maskPupNumOfRegs = topologyMap->numOfBusPerInterface;
+	maskDqNumOfRegs = octetsPerInterfaceNum * BUS_WIDTH_IN_BITS;
+	maskPupNumOfRegs = octetsPerInterfaceNum;
 
     if (resultType == RESULT_PER_BIT)
     {
@@ -384,11 +508,11 @@
         }
 
 		/*Mask disabled buses*/
-        for(pupId = 0; pupId < topologyMap->numOfBusPerInterface ; pupId++)
+        for(pupId = 0; pupId < octetsPerInterfaceNum ; pupId++)
         {
 			if (IS_BUS_ACTIVE(topologyMap->activeBusMask, pupId) == GT_TRUE) continue;
 
-		    for(indexCnt=(maskDqNumOfRegs-pupId*8); indexCnt<(maskDqNumOfRegs-(pupId+1)*8);indexCnt++)
+		    for(indexCnt=pupId*8; indexCnt<(pupId+1)*8;indexCnt++)
 		    {
 		        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsDqRegMap[indexCnt], (1<<24), 1<<24));
 		    }
@@ -413,48 +537,51 @@
     }
 
     /*Start Training Trigger */
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_TRAINING_TRIGGER_REG, 1, 1));
-#else
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_TRAINING_STATUS_REG, 1, 1));
-#endif
+	triggerRegAddr = (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)?(ODPG_TRAINING_TRIGGER_REG):(ODPG_TRAINING_STATUS_REG);
+    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, triggerRegAddr, 1, 1));
+
     /*wait for all RFU tests to finish (or timeout)*/
 	/*WA for 16 bit mode, more investigation needed*/
     hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1); /* 1 mSec */
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-    /* Training "Done ?" */
-    for(indexCnt=0; indexCnt < MAX_INTERFACE_NUM;indexCnt++)
+    /* Training "Done ?"  for CPU contolled TIP*/
+    if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
     {
-        if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) ==  0)
-        {
-            continue;   
-        }
-        if (interfaceMask & (1<<indexCnt))
-        {
-            /*need to check results for this Dunit */
-            for(pollCnt=0;pollCnt < maxPollingForDone;pollCnt++)
-            {
-                CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, ODPG_TRAINING_STATUS_REG, &regData, MASK_ALL_BITS));
-                 if ((regData & 0x2) != 0)
-                {
-                    /*done */
-                	trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_SUCCESS;
-                    break; 
-                }  
-            }
-            if (pollCnt == maxPollingForDone)
-            {
-                trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_TIMEOUT;
-            }
-        }
-		/*Be sure that ODPG done*/
-        CHECK_STATUS(isOdpgAccessDone(devNum, indexCnt));
-    }
-
-	/*Write ODPG done in Dunit*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_STATUS_DONE_REG, 0, 0x1));
+		for(indexCnt=0; indexCnt < MAX_INTERFACE_NUM;indexCnt++)
+		{
+		    if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) ==  0)
+		    {
+		        continue;
+		    }
+		    if (interfaceMask & (1<<indexCnt))
+		    {
+		        /*need to check results for this Dunit */
+		        for(pollCnt=0;pollCnt < maxPollingForDone;pollCnt++)
+		        {
+		            CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, ODPG_TRAINING_STATUS_REG, readData, MASK_ALL_BITS));
+		            if ((readData[indexCnt] & 0x2) != 0)
+		            {
+		                /*done */
+						trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_SUCCESS;
+		                break;
+		            }
+		        }
+#ifdef CONFIG_BOBK
+                 /* WA to avoid training stucking */
+                hwsOsExactDelayPtr((GT_U8)devNum, devNum, 50); /* 50 mSec */
 #endif
+		        if (pollCnt == maxPollingForDone)
+		        {
+		            trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_TIMEOUT;
+		        }
+		    }
+			/*Be sure that ODPG done*/
+		    CHECK_STATUS(isOdpgAccessDone(devNum, indexCnt));
+		}
+
+		/*Write ODPG done in Dunit*/
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_STATUS_DONE_REG, 0, 0x1));
+	}
 
     /*wait for all Dunit tests to finish (or timeout)*/
     /* Training "Done ?" */
@@ -463,18 +590,14 @@
     {
         if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) ==  0)
         {
-            continue;   
+            continue;
         }
         if (interfaceMask & (1<<indexCnt))
         {
             /*need to check results for this Dunit */
             for(pollCnt=0;pollCnt < maxPollingForDone;pollCnt++)
             {
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-                CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, ODPG_TRAINING_TRIGGER_REG, readData, MASK_ALL_BITS));
-#else
-                CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, ODPG_TRAINING_STATUS_REG, readData, MASK_ALL_BITS));
-#endif
+                CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, triggerRegAddr, readData, MASK_ALL_BITS));
                 regData = readData[indexCnt];
                  if ((regData & 0x2) != 0)
                 {
@@ -485,11 +608,15 @@
                     }
                     else
                     {
-                        trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_FAIL;
+						trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_FAIL;
                     }
-                    break; 
-                }  
+                    break;
+                }
             }
+#ifdef CONFIG_BOBK
+            /* WA to avoid training stucking */
+             hwsOsExactDelayPtr((GT_U8)devNum, devNum, 50);
+#endif
             if (pollCnt == maxPollingForDone)
             {
                 trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_TIMEOUT;
@@ -661,6 +788,7 @@
     GT_U32 readData[MAX_INTERFACE_NUM];
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* Agreed assumption: all CS mask contain same number of bits, i.e. in multi CS, the number of CS per memory is the same for all pups */
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST,  interfaceId, CS_ENABLE_REG, (csNumType == 0) ? 1<<3 : 0, (1 << 3)));
@@ -671,7 +799,7 @@
         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("ddr3TipReadTrainingResult loadRes = NULL"));
         return GT_FAIL;
     }
-    if (pupNum >= topologyMap->numOfBusPerInterface)
+    if (pupNum >= octetsPerInterfaceNum)
     {
         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
     }
@@ -695,7 +823,7 @@
     else /*pupAccessType == ACCESS_TYPE_MULTICAST)*/
     {
         startPup = 0;
-        endPup = topologyMap->numOfBusPerInterface-1;
+        endPup = octetsPerInterfaceNum-1;
     } 
     for(pupCnt = startPup; pupCnt <= endPup ; pupCnt++)
     {
@@ -805,18 +933,16 @@
     GT_U32 interfaceId
 )
 {
-    GT_U32 pollCnt = 0, dataValue;
+    GT_U32 pollCnt = 0, dataValue, expectedVal;
     GT_U32 readData[MAX_INTERFACE_NUM];
 
     for (pollCnt = 0; pollCnt < MAX_POLLING_ITERATIONS ; pollCnt++)
     {
         CHECK_STATUS(mvHwsDdr3TipIFRead(devNum,ACCESS_TYPE_UNICAST, interfaceId, ODPG_BIST_DONE, readData, MASK_ALL_BITS));
  		dataValue = readData[interfaceId];
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-        if (((dataValue >> ODPG_BIST_DONE_BIT_OFFS )& 0x1) == ODPG_BIST_DONE_BIT_VALUE)
-#else
-        if ((dataValue & 0x1) == 0x1)
-#endif
+
+		expectedVal =  (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3)?(ODPG_BIST_DONE_BIT_VALUE_REV2):(ODPG_BIST_DONE_BIT_VALUE_REV3);
+        if (((dataValue >> ODPG_BIST_DONE_BIT_OFFS )& 0x1) == expectedVal)
         {
             dataValue = dataValue & 0xfffffffe;
             CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_BIST_DONE, dataValue, MASK_ALL_BITS));
@@ -857,18 +983,20 @@
     /* load pattern to ODPG */
     ddr3TipLoadPatternToOdpg(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, pattern, patternTable[pattern].startAddr);
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-    for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM ; interfaceId++)
-    {
-		if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  0)
-             continue;
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1498, 0x3 , 0xf));
-    }
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
+	{
+		for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM ; interfaceId++)
+		{
+			if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  0)
+		         continue;
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, SDRAM_ODT_CONTROL_HIGH_REG, 0x3 , 0xf));
+		}
 
-	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,  (0x1 << ODPG_ENABLE_OFFS)));
-#else
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,  (0x1 << ODPG_ENABLE_OFFS)));
+	}
+	else {
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, (GT_U32)(0x1 << 31),  (GT_U32)(0x1 << 31)));
-#endif
+	}
 
     hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1); /* 1 mSec */
 
@@ -883,10 +1011,10 @@
     /* return to default */
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-	/*disable odt0 for CS0 training - need to adjust for multy CS*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST,PARAM_NOT_CARE , 0x1498, 0x0 , 0xf));
-#endif
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+		/*disable odt0 for CS0 training - need to adjust for multy CS*/
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST,PARAM_NOT_CARE , 0x1498, 0x0 , 0xf));
+	}
 
     /* temporary added */
     hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1);
@@ -894,26 +1022,6 @@
 }
 
 /*****************************************************************************
-Load specific pattern to memory using CPU
-******************************************************************************/
-GT_STATUS    ddr3TipLoadPatternToMemByCpu
-(
-    GT_U32          devNum,
-    MV_HWS_PATTERN  pattern,
-    GT_U32          offset
-)
-{
-	/* avoid warnings */
-	devNum = devNum;
-	pattern = pattern;
-	offset = offset;
-
-    /* eranba - TBD */
-    return GT_OK;
-}
-
-
-/*****************************************************************************
 Training search routine
 ******************************************************************************/
 GT_STATUS    ddr3TipIpTrainingWrapperInt
@@ -943,6 +1051,7 @@
     MV_HWS_SearchDirection searchDirId , startSearch, endSearch;
     MV_HWS_EdgeCompare     edgeCompUsed;
 	GT_U8 consTap = (direction == OPER_WRITE)?(64):(0);
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     if (trainStatus == NULL)
     {
@@ -956,7 +1065,7 @@
         (searchDir > MV_HWS_High2Low) ||
         (controlElement > MV_HWS_ControlElement_DQS_SKEW) ||
         (resultType > RESULT_PER_BYTE) ||
-        (pupNum >= topologyMap->numOfBusPerInterface) ||
+        (pupNum >= octetsPerInterfaceNum) ||
         (pupAccessType > ACCESS_TYPE_MULTICAST) ||
         (interfaceId > 11)||
         (accessType > ACCESS_TYPE_MULTICAST))
@@ -1045,8 +1154,9 @@
 	GT_U8 consTap = (direction == OPER_WRITE)?(64):(0);
 	GT_U8 bitBitMask[MAX_BUS_NUM] = {0}, bitBitMaskActive = 0;
 	GT_U8 pupId;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
-    if (pupNum >= topologyMap->numOfBusPerInterface)
+    if (pupNum >= octetsPerInterfaceNum)
     {
         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
     }
@@ -1072,7 +1182,7 @@
     for(interfaceCnt = startIf; interfaceCnt <= endIf; interfaceCnt++)    
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceCnt)
-        for(pupId = 0; pupId <= (topologyMap->numOfBusPerInterface-1) ; pupId++)
+        for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
         {
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
             if (resultType == RESULT_PER_BIT)
@@ -1123,7 +1233,7 @@
                           MV_HWS_Low2High, direction, interfaceMask,
                           numIter/2, numIter/2, pattern, EDGE_FP, trainCsType, csNum,  trainStatus);
 
-		    for(pupId = 0; pupId <= (topologyMap->numOfBusPerInterface-1) ; pupId++)
+		    for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
 		    {
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
 
@@ -1146,7 +1256,7 @@
                           MV_HWS_High2Low, direction, interfaceMask,
                           numIter/2, numIter/2, pattern, EDGE_FP, trainCsType, csNum,  trainStatus);
 
-		    for(pupId = 0; pupId <= (topologyMap->numOfBusPerInterface-1) ; pupId++)
+		    for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
 		    {
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
 
@@ -1175,11 +1285,12 @@
 GT_STATUS    ddr3TipLoadPhyValues(GT_BOOL bLoad)
 {
     GT_U32  busCnt = 0,  interfaceId,  devNum = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busCnt = 0; busCnt < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busCnt++)
+        for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
         {
         	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
             if (bLoad == GT_TRUE)
@@ -1217,6 +1328,7 @@
     MV_HWS_TrainingIpStatus trainStatus[MAX_INTERFACE_NUM];
     GT_U32 *pRes = NULL;
     GT_U32 searchState = 0; 
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     ddr3TipLoadPhyValues(GT_TRUE);
 
@@ -1231,7 +1343,7 @@
             for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
             {
                 VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-                for(pupId = 0; pupId < topologyMap->numOfBusPerInterface ; pupId++)
+                for(pupId = 0; pupId < octetsPerInterfaceNum ; pupId++)
                 {
 					VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
                     CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceId, ACCESS_TYPE_UNICAST, 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingLeveling.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingLeveling.c
index 35d1c68..dcee61b 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingLeveling.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingLeveling.c
@@ -33,10 +33,14 @@
 #include "mvDdrTopologyDef.h"
 
 #define WL_ITERATION_NUM            (10)
-#define ONE_CLOCK_ERROR_SHIFT   (2)
-#define ALIGN_ERROR_SHIFT       (-2)
 #define MATRIX_MEM_ADDRESS      (0xfd000)
 
+#define NO_PHASE_SHIFT				(0)
+#define ONE_CLOCK_ERROR_SHIFT		(2)
+#define TWO_CLOCK_ERROR_SHIFT		(4)
+#define THREE_CLOCK_ERROR_SHIFT		(6)
+#define ALIGN_ERROR_SHIFT			(-2)
+
 static GT_U32 pupMaskTable[]=
 {
     0x000000FF,
@@ -50,7 +54,6 @@
 
 extern MV_HWS_RESULT trainingResult[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
 extern AUTO_TUNE_STAGE trainingStage;
-extern GT_U32 rlVersion; 
 extern MV_HWS_TOPOLOGY_MAP *topologyMap;
 extern ClValuePerFreq casLatencyTable[];
 extern GT_U32  startXsbOffset;
@@ -73,53 +76,61 @@
 (
     GT_U32   devNum
 );
-static GT_STATUS    ddr3TipWlSuppAlignErrShift
-(
-	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32 busIdDelta
-);
 
 static GT_STATUS    ddr3TipWlSuppAlignPhaseShift
 (
 	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32  offset,
-	GT_U32 busIdDelta
+    GT_U32 interfaceId,
+    GT_U32 busId
 );
 
 static GT_STATUS    ddr3TipXsbCompareTest
 (
+    GT_U32 devNum,
+    GT_U32 interfaceId,
+    GT_U32 busId,
+    GT_8 offset
+);
+
+#if 0 /* remove this if it's not in use */
+static GT_STATUS    ddr3TipWlSuppAlignErrShift
+(
 	GT_U32 devNum,
 	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32 edgeOffset,
-	GT_U32 busIdDelta
+	GT_U32 busId
 );
 
 static GT_STATUS    ddr3TipWlSuppOneClkErrShift
 (
 	GT_U32 devNum,
 	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32 busIdDelta
+	GT_U32 busId
 );
+#endif
 
 /*****************************************************************************
 mvHwsDdr3TipMaxCSGet
 ******************************************************************************/
-GT_U32 mvHwsDdr3TipMaxCSGet(void)
+GT_U32 mvHwsDdr3TipMaxCSGet(GT_U32 devNum)
 {
-  GT_U32 c_cs;
+  GT_U32 c_cs,interfaceId=0,busId=0;
+  GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
   static GT_U32 max_cs=0;
 
-  if (!max_cs){
-	 for(c_cs = 0;c_cs < NUM_OF_CS; c_cs++){
-		VALIDATE_IF_ACTIVE(topologyMap->interfaceParams[0].asBusParams[0].csBitmask, c_cs)
+  if (!max_cs)
+  {
+      CHECK_STATUS(ddr3TipGetFirstActiveIf((GT_U8)devNum, topologyMap->interfaceActiveMask, &interfaceId));
+ 	  for(busId=0; busId<octetsPerInterfaceNum; busId++)
+      {
+          VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
+          break;
+      }
+
+      for(c_cs = 0;c_cs < NUM_OF_CS; c_cs++)
+      {
+		VALIDATE_IF_ACTIVE(topologyMap->interfaceParams[interfaceId].asBusParams[busId].csBitmask, c_cs)
 		max_cs++;
-		}
+	  }
   }
   return max_cs;
 }
@@ -134,7 +145,7 @@
 )
 {
     GT_U32 data, mask;
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 	GT_U32 busNum, interfaceId, clVal;
     MV_HWS_SPEED_BIN speedBinIndex;
 	GT_U32 csEnableRegVal[MAX_INTERFACE_NUM] = {0}; /* save current CS value */
@@ -143,57 +154,7 @@
 	GT_U8   RLValues[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM] ;
 	PatternInfo *patternTable = ddr3TipGetPatternTable();
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
-
-
-	/*DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("===READ LEVELING==="));*/
-    if (rlVersion == 0)
-    {
-        /* OLD RL machine */
-        data = 0x40;
-        data |= (1<<20);
-        /* TBD multi CS */
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, data, 0x11FFFF));
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_PATTERN_BASE_ADDRESS_REG, 0, 0xFFFFFFF8));
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, (GT_U32)(1 << 31), (GT_U32)(1 << 31)));
-        for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-        {
-           VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-           trainingResult[trainingStage][interfaceId] = TEST_SUCCESS;
-           if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0, (GT_U32)(1 << 31), TRAINING_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-            {
-                DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("RL: DDR3 poll failed(1) IF %d\n", interfaceId));
-                trainingResult[trainingStage][interfaceId] = TEST_FAILED;
-                if (debugMode == GT_FALSE)
-                {
-                    return GT_FAIL;
-                }
-            }
-        }
-        /* read read-leveling result */
-        CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, dataRead, 1<<30));
-        /* exit read leveling mode */
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_SW_2_REG, 0x8, 0x9));
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_SW_1_REG, 1<<16, 1<<16));
-        /* disable RL machine all Trn_CS[3:0] , [16:0] */
-
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG,  0, 0xF1FFFF));
-
-        for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-        {
-            VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-            if ((dataRead[interfaceId]&(1<<30)) == 0)
-            {
-                DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("\nRead Leveling failed for IF %d\n", interfaceId));
-                trainingResult[trainingStage][interfaceId] = TEST_FAILED;
-                if (debugMode == GT_FALSE)
-                {
-                    return GT_FAIL; 
-                }
-            }
-        }
-        return GT_OK;
-    }
-    /* NEW RL machine */
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
 	for(effective_cs = 0; effective_cs < NUM_OF_CS; effective_cs++)
 		for(busNum = 0; busNum < MAX_BUS_NUM; busNum++)
@@ -286,50 +247,48 @@
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, (1 << 24) | (1 << 20), (1 << 24) | (1 << 20)));
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, (GT_U32)(1 << 31), (GT_U32)(1 << 31)));
     /********* trigger training *******************/
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3)  || defined(CONFIG_ARMADA_39X) /* Trigger, poll on status and disable ODPG */
-/*    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1)); */
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
 
-	  /*check for training done + results pass*/
-	  if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2, ODPG_TRAINING_STATUS_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-		  {
-			  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Done Failed\n"));
-			  return GT_FAIL;
-		  }
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-	  CHECK_STATUS(mvHwsDdr3TipIFRead(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG,  dataRead, 0x4));
-	data = dataRead[interfaceId];
-	if(data != 0x0) {
-	  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Result Failed\n"));
-	  }
-    }
-	  /*disable ODPG - Back to functional mode*/
-	  CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,  (0x1 << ODPG_DISABLE_OFFS)));
-	  if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1, ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+		  /*check for training done + results pass*/
+		  if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2, ODPG_TRAINING_STATUS_REG, MAX_POLLING_ITERATIONS) != GT_OK)
 			  {
-				  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("ODPG disable failed "));
+				  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Done Failed\n"));
 				  return GT_FAIL;
 			  }
-	  CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
-#else /* Just trigger and go check for results */
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
-#endif
-
+		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+		{
+		    VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+		  CHECK_STATUS(mvHwsDdr3TipIFRead(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG,  dataRead, 0x4));
+		data = dataRead[interfaceId];
+		if(data != 0x0) {
+		  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Result Failed\n"));
+		  }
+		}
+		  /*disable ODPG - Back to functional mode*/
+		  CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,  (0x1 << ODPG_DISABLE_OFFS)));
+		  if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1, ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+				  {
+					  DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("ODPG disable failed "));
+					  return GT_FAIL;
+				  }
+		  CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+	}
+	else {
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+	}
 		/************ double loop on bus, pup *********/
 		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 			/* check training done */
 			isAnyPupFail = GT_FALSE;
-			for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+			for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
 			{
        			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 				if (ddr3TipIfPolling(devNum, ACCESS_TYPE_UNICAST, interfaceId, (1 << 25), (1 << 25), maskResultsPupRegMap[busNum], MAX_POLLING_ITERATIONS) != GT_OK)
 				{
-					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("\nRL: DDR3 poll failed(2) for bus %d", busNum));
+					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("\nRL: DDR3 poll failed(2) for IF %d CS %d bus %d", interfaceId, effective_cs, busNum));
 					isAnyPupFail = GT_TRUE;
 				}
 				else
@@ -369,7 +328,7 @@
 		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-			for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+			for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
 			{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 				/* read result per pup from arry */
@@ -409,7 +368,7 @@
 )
 {
 	GT_U32 c_cs, interfaceId, cs_mask = 0;
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 
 /*	in TRAINIUNG reg (0x15b0) write 0x80000008 | cs_mask:
 	TrnStart
@@ -443,7 +402,7 @@
 )
 {
 	GT_U32 c_cs, interfaceId, cs_mask = 0;
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 
 	/* in TRAINIUNG reg (0x15b0) write 0x80000040 | cs_mask:
 	TrnStart
@@ -494,11 +453,12 @@
     GT_U32  data2Write[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 	PatternInfo *patternTable = ddr3TipGetPatternTable();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
-    
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
 	for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
 	{
 		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(busNum = 0; busNum <=topologyMap->numOfBusPerInterface; busNum++)
+        for(busNum = 0; busNum <=octetsPerInterfaceNum; busNum++)
 		{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 				perBitRLPupStatus[interfaceId][busNum] = 0;	
@@ -582,44 +542,43 @@
 		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, (1 << 24) | (1 << 20), (1 << 24) | (1 << 20)));
 		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG, (GT_U32)(1 << 31), (GT_U32)(1 << 31)));
 		/********* trigger training *******************/
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) || defined(CONFIG_ALLEYCAT3) /* Trigger, poll on status and disable ODPG */
-/*    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1)); */
-	    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+		if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
 
-		/*check for training done + results pass*/
-		if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2, ODPG_TRAINING_STATUS_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+			/*check for training done + results pass*/
+			if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2, ODPG_TRAINING_STATUS_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+			{
+				 DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Done Failed\n"));
+				 return GT_FAIL;
+			}
+		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
-			 DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Done Failed\n"));
-			 return GT_FAIL;
+		    VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+			CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG,  dataRead, 0x4));
+			data = dataRead[interfaceId];
+			if(data != 0x0) {
+				DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Result Failed\n"));
+			}
 		}
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-    {
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-		CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG,  dataRead, 0x4));
-		data = dataRead[interfaceId];
-		if(data != 0x0) {
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("Training Result Failed\n"));
+			/*disable ODPG - Back to functional mode*/
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,  (0x1 << ODPG_DISABLE_OFFS)));
+			if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1, ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != GT_OK)
+			{
+				DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("ODPG disable failed "));
+				return GT_FAIL;
+			}
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
 		}
-	}
-		/*disable ODPG - Back to functional mode*/
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,  (0x1 << ODPG_DISABLE_OFFS)));
-		if (ddr3TipIfPolling(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1, ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != GT_OK)
-		{
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("ODPG disable failed "));
-			return GT_FAIL;
+		else {
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
 		}
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
-#else /* Just trigger and go check for results */
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
-#endif
 
 		/************ double loop on bus, pup *********/
 		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 			/* check training done */
-			for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+			for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
 			{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 				if (perBitRLPupStatus[interfaceId][busNum] == GT_FALSE)
@@ -662,7 +621,7 @@
 			for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 			{
 				VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-				for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+				for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
 				{
 	   				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 					if (perBitRLPupStatus[interfaceId][busNum] != GT_TRUE)
@@ -684,11 +643,11 @@
 	for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
 		VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for (busNum=0; busNum<topologyMap->numOfBusPerInterface; busNum++)
+        for (busNum=0; busNum<octetsPerInterfaceNum; busNum++)
         {
 	   		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busNum)
 			if (perBitRLPupStatus[interfaceId][busNum] == GT_TRUE)
-				mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, RL_PHY_REG + CS_REG_VALUE(effective_cs), data2Write[interfaceId][busNum]);
+				mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busNum, DDR_PHY_DATA, RL_PHY_REG + CS_BYTE_GAP(effective_cs), data2Write[interfaceId][busNum]);
 			else
 				isAnyPupFail = GT_TRUE;
 		}
@@ -747,6 +706,7 @@
 {
 	GT_U32 allBusCs = 0, sameBusCs;
 	GT_U32 busCnt;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
 	devNum = devNum; /* avoid warnings */
 
@@ -758,7 +718,7 @@
 	   if they are they are not the same then it's mixed mode so all CS should be configured
 	   (when configuring the MRS)*/
 
-	for (busCnt=0; busCnt<topologyMap->numOfBusPerInterface; busCnt++)
+	for (busCnt=0; busCnt<octetsPerInterfaceNum; busCnt++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
 
@@ -781,7 +741,7 @@
 ******************************************************************************/
 GT_STATUS    ddr3TipDynamicWriteLeveling(GT_U32    devNum)
 {
-    GT_U32   regData = 0, iter, interfaceId, busCnt;
+    GT_U32   regData = 0, iter, interfaceId, busCnt, triggerRegAddr;
 	GT_U32   csEnableRegVal[MAX_INTERFACE_NUM] = {0};
     GT_U32   csMask[MAX_INTERFACE_NUM];
     GT_U32   readDataSampleDelayVals[MAX_INTERFACE_NUM] = {0};
@@ -792,14 +752,14 @@
 	GT_U8   WLValues[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U32 csMask0[MAX_INTERFACE_NUM]={0};
-	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
-    /*DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("===WRITE LEVELING==="));*/
+	GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 
-        trainingResult[trainingStage][interfaceId] = TEST_SUCCESS;
+		trainingResult[trainingStage][interfaceId] = TEST_SUCCESS;
 
         /* save Read Data Sample Delay */
         CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, READ_DATA_SAMPLE_DELAY, readDataSampleDelayVals, MASK_ALL_BITS));
@@ -808,10 +768,11 @@
         /* save current cs reg val */
         CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, csEnableRegVal, MASK_ALL_BITS));
 
-#if !defined(CONFIG_ARMADA_38X) && !defined(CONFIG_ALLEYCAT3)  && !defined(CONFIG_ARMADA_39X)
-        /* enable multi cs */
-        CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, 0, (1 << 3)));
-#endif
+		if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3)
+		{
+		    /* enable multi cs */
+		    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, 0, (1 << 3)));
+		}
     }
 
 	/************************************************************************/
@@ -849,16 +810,17 @@
 			ddr3TipCalcCsMask(devNum, interfaceId, effective_cs, &csMask[interfaceId]);
 		}
 
-	#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-		/*Enable Output buffer to relevant CS - Q on , WL on*/
-		CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS1_CMD, 0x80, 0x1080));
+		if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
+		{
+			/*Enable Output buffer to relevant CS - Q on , WL on*/
+			CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS1_CMD, 0x80, 0x1080));
 
-		/*enable odt for relevant CS*/
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498, (0x3<<(effective_cs*2)) , 0xf));
-
-	#else
-		CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS1_CMD, 0xC0, 0x12C4));
-	#endif
+			/*enable odt for relevant CS*/
+			CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498, (0x3<<(effective_cs*2)) , 0xf));
+		}
+		else {
+			CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask, MRS1_CMD, 0xC0, 0x12C4)); /*FIXME should be same as _CPU case*/
+		}
 
 		/************************************************************************/
 		/*     Phase 2: Set training IP to write leveling mode                  */
@@ -868,14 +830,12 @@
 		/************************************************************************/
 		/*     Phase 3: Trigger training                                        */
 		/************************************************************************/
-	#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-	#else
-		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
-	#endif
+		triggerRegAddr = (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3)?(ODPG_TRAINING_STATUS_REG):(ODPG_TRAINING_TRIGGER_REG);
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, triggerRegAddr, 0x1, 0x1));
 
 
-	#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
+	{
 	   for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
@@ -885,19 +845,22 @@
 			{
 				DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WL: DDR3 poll (4) failed (Data: 0x%x)\n", regData));
 			}
-	#if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498*/
 			else
 			{
-				CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG, &regData, (1 << 2)));
-				if (regData != 0)
+                #if defined(CONFIG_ARMADA_38X) /* JIRA #1498 for 16 bit with ECC */
+                if(topologyMap->activeBusMask == 0xB)
+                {
+                    break;
+                }
+                #endif
+				CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_TRIGGER_REG, dataRead, (1 << 2)));
+				if (dataRead[interfaceId] != 0)
 				{
-					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WL: WL failed IF %d regData=0x%x\n",interfaceId,regData));
+					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WL 1: WL failed IF %d regData=0x%x\n",interfaceId,dataRead[interfaceId]));
 				}
 			}
-	#endif
 		}
-	#endif
-
+	}
 		for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
@@ -908,26 +871,31 @@
 			}
 			else
 			{
-	#if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498*/
 				CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_TRAINING_STATUS_REG, dataRead, (1 << 2)));
 				regData = dataRead[interfaceId];
+                #if defined(CONFIG_ARMADA_38X) /* JIRA #1498 for 16 bit with ECC */
+                if(topologyMap->activeBusMask == 0xB)
+                {
+                    /* set data to 0 in order to skip the check */
+                    regData = 0;
+                }
+                #endif
 				if (regData != 0)
 				{
-					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WL: WL failed IF %d regData=0x%x\n",interfaceId,regData));
+					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WL 2:  WL failed IF %d regData=0x%x\n",interfaceId,regData));
 				}
-	#endif
 
 				/* check for training completion per bus */
-				for (busCnt=0; busCnt<topologyMap->numOfBusPerInterface; busCnt++)
+				for (busCnt=0; busCnt<octetsPerInterfaceNum; busCnt++)
 				{
        				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
 					/* training status */
-					CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, maskResultsPupRegMap[busCnt], dataRead, (1 << 25)));
+					CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, maskResultsPupRegMap[busCnt], dataRead, MASK_ALL_BITS));
     				regData = dataRead[interfaceId];
 					DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL: IF %d BUS %d reg 0x%x\n", interfaceId, busCnt,regData));
-					if (regData == 0)
+					if((regData & (1 << 25)) == 0 )
 					{
-						resValues[(interfaceId * topologyMap->numOfBusPerInterface) + busCnt] = GT_TRUE;
+						resValues[(interfaceId * octetsPerInterfaceNum) + busCnt] = GT_TRUE;
 					}
 					CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, maskResultsPupRegMap[busCnt], dataRead, 0xff));
 					WLValues[effective_cs][busCnt][interfaceId] = (GT_U8)dataRead[interfaceId]; /* save the read value that should be write to PHY register */
@@ -936,17 +904,47 @@
 		}
 
 		/************************************************************************/
+		/*     Phase 3.5: Validate result phase                                 */
+		/************************************************************************/
+		for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++)
+		{
+			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+			for (busCnt=0; busCnt<octetsPerInterfaceNum; busCnt++){
+
+				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
+				/*read result control register according to pup */
+				regData = WLValues[effective_cs][busCnt][interfaceId] + 16 ;/*16 is half a phase*/
+				/* write into write leveling register ([4:0] ADLL, [8:6] Phase, [15:10] (centralization) ADLL + 0x10) */
+				regData = (regData & 0x1f) | (((regData & 0xE0) >> 5) << 6) | (((regData & 0x1f) + PhyReg1Val) << 10);
+				mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA,
+									WL_PHY_REG + 0*CS_REGISTER_ADDR_OFFSET, regData);/*we always work with CS0 so the search is with WL-CS0 register in the phy*/
+
+				/*Check if data read from DRAM not changed, if so - fix the result*/
+				CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId, TRAINING_WRITE_LEVELING_REG,
+									dataRead, MASK_ALL_BITS));
+				if((dataRead[interfaceId]&(1<<(20+busCnt)))>>(20+busCnt) == 0)
+				{
+					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("WLValues was changed from 0x%X", WLValues[effective_cs][busCnt][interfaceId]));
+					WLValues[effective_cs][busCnt][interfaceId] = WLValues[effective_cs][busCnt][interfaceId] + 32;
+					DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("to 0x%X\n", WLValues[effective_cs][busCnt][interfaceId]));
+				}
+			}
+		}
+
+		/************************************************************************/
 		/*     Phase 4: Exit write leveling mode                                */
 		/************************************************************************/
 		/* disable DQs toggling */
 		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  WR_LEVELING_DQS_PATTERN_REG, 0x0, 0x1));
 
 		/* Update MRS 1 (WL off) */
-	#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-		CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask0, MRS1_CMD , 0x1000, 0x1080));  // nklein 24.10.13
-	#else
-		CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask0, MRS1_CMD, 0x1000, 0x12C4));
-	#endif
+		if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
+		{
+			CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask0, MRS1_CMD , 0x1000, 0x1080));
+		}
+		else {
+			CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask0, MRS1_CMD, 0x1000, 0x12C4)); /*FIXME should be same as _CPU case*/
+		}
 
 		/* Update MRS 1 (return to functional mode - Q on , WL off) */
 		CHECK_STATUS(ddr3TipWriteMRSCmd(devNum, csMask0, MRS1_CMD, 0x0, 0x1080));
@@ -965,11 +963,11 @@
 		{
 			VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 			testRes = 0;
-			for (busCnt=0; busCnt<topologyMap->numOfBusPerInterface; busCnt++)
+			for (busCnt=0; busCnt<octetsPerInterfaceNum; busCnt++)
 			{
 				VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
 				/* check if result == pass */
-				if (resValues[(interfaceId * topologyMap->numOfBusPerInterface) + busCnt] == 0)
+				if (resValues[(interfaceId * octetsPerInterfaceNum) + busCnt] == 0)
 				{
 					/*read result control register according to pup */
 					regData = WLValues[effective_cs][busCnt][interfaceId];
@@ -1010,10 +1008,10 @@
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, csEnableRegVal[interfaceId], MASK_ALL_BITS));
     }
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_39X)
-	/*disable modt0 for CS0 training - need to adjust for multy CS*/
-    CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498, 0x0 , 0xf));
-#endif
+	if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
+		/*disable modt0 for CS0 training - need to adjust for multy CS*/
+		CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498, 0x0 , 0xf));
+	}
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
@@ -1035,20 +1033,19 @@
     GT_32 adllOffset;
     GT_U32 interfaceId, busId, data, dataTmp;
     GT_BOOL isIfFail = GT_FALSE;
-
-    /*DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("===WRITE LEVELING SUPPLEMENTARY==="));*/
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
         isIfFail = GT_FALSE;
-        for(busId = 0; busId < GET_TOPOLOGY_NUM_OF_BUSES(devNum); busId++)
+        for(busId = 0; busId < octetsPerInterfaceNum; busId++)
         {
        		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
             writeSuppResultTable[interfaceId][busId].isPupFail = GT_TRUE;
             CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, &data));
             DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: adllOffset=0 data delay = %d \n", data));
-            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId, 0, 0) == GT_OK)
+            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId) == GT_OK)
             {
                 DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: IF %d busId %d adllOffset=0 Success !\n", interfaceId, busId));
                 continue;
@@ -1059,7 +1056,7 @@
             CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, &dataTmp));
             DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: adllOffset= %d data delay = %d \n", adllOffset, dataTmp));
 
-            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId, adllOffset, 0) == GT_OK)
+            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId) == GT_OK)
             {
                 DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: IF %d busId %d adllOffset= %d Success !\n", interfaceId, busId, adllOffset));
                 continue;
@@ -1069,7 +1066,7 @@
             CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, data + adllOffset));
             CHECK_STATUS(mvHwsDdr3TipBUSRead(  devNum, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, &dataTmp));
             DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: adllOffset= %d data delay = %d \n", adllOffset, dataTmp));
-            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId, adllOffset, 0) == GT_OK)
+            if (ddr3TipWlSuppAlignPhaseShift(devNum, interfaceId, busId) == GT_OK)
             {
                 DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: IF %d busId %d adllOffset= %d Success !\n", interfaceId, busId, adllOffset));
                 continue;
@@ -1080,11 +1077,10 @@
                 isIfFail = GT_TRUE;
             }
         }
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("WL Supp: IF %d busId %d isPupFail %d\n", interfaceId, busId, isIfFail));
 
         if (isIfFail == GT_TRUE)
         {
-            DEBUG_LEVELING(DEBUG_LEVEL_ERROR,  ("WL Supp: IF %d failed\n", interfaceId));
+            DEBUG_LEVELING(DEBUG_LEVEL_ERROR,  ("WL Supp CS# %d: IF %d failed\n", effective_cs ,interfaceId));
             trainingResult[trainingStage][interfaceId] = TEST_FAILED;
         }
         else
@@ -1108,41 +1104,60 @@
 static GT_STATUS    ddr3TipWlSuppAlignPhaseShift
 (
 	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32  offset,
-	GT_U32 busIdDelta
+    GT_U32 interfaceId,
+    GT_U32 busId
 )
 {
-     writeSuppResultTable[interfaceId][busId].stage = PHASE_SHIFT;
-     if (ddr3TipXsbCompareTest(devNum, interfaceId, busId, 0, busIdDelta) == GT_OK)
-    {
-        writeSuppResultTable[interfaceId][busId].isPupFail = GT_FALSE;
-        return GT_OK;
-    }
-    /* 1 clock error */
-    else if (ddr3TipXsbCompareTest(devNum, interfaceId, busId, ONE_CLOCK_ERROR_SHIFT,busIdDelta) == GT_OK)
-    {
-        writeSuppResultTable[interfaceId][busId].stage = CLOCK_SHIFT;
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("Supp: 1 error clock for if %d pup %d with ofsset %d success\n", interfaceId, busId, offset));
-        ddr3TipWlSuppOneClkErrShift(devNum, interfaceId, busId, 0);
-        writeSuppResultTable[interfaceId][busId].isPupFail = GT_FALSE;
-        return GT_OK;
-    }
-    /* align error */
-    else if (ddr3TipXsbCompareTest(devNum, interfaceId, busId, ALIGN_ERROR_SHIFT, busIdDelta) == GT_OK)
-    {
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("Supp: align error for if %d pup %d with ofsset %d success\n", interfaceId, busId, offset));
-        writeSuppResultTable[interfaceId][busId].stage = ALIGN_SHIFT;
-        ddr3TipWlSuppAlignErrShift(devNum, interfaceId, busId, 0);
-        writeSuppResultTable[interfaceId][busId].isPupFail = GT_FALSE;
-        return GT_OK;
-    }
-    else
-    {
-        writeSuppResultTable[interfaceId][busId].isPupFail = GT_TRUE;
-        return GT_FAIL;
-    }
+	GT_U32 originalPhase;
+    GT_U32 data, writeData;
+
+    writeSuppResultTable[interfaceId][busId].stage = PHASE_SHIFT;
+	if( GT_OK == ddr3TipXsbCompareTest(devNum, interfaceId, busId, 0))
+		return GT_OK;
+
+	/*Read the current phase */
+    CHECK_STATUS(mvHwsDdr3TipBUSRead(devNum, interfaceId,  ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, &data));
+	originalPhase = data >> 6 & 0x7;
+
+	/*--- set phase(0x0[6-8]) -2  ---*/
+	if( originalPhase >= 1){
+		if( originalPhase == 1) writeData = (data & ~0x1DF);
+		else writeData = (data & ~0x1C0) | ( (originalPhase - 2) << 6);
+		mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, writeData);
+
+		CHECK_STATUS(ddr3TipXsbCompareTest(devNum, interfaceId, busId, -2 ))
+	}
+
+	/*--- set phase(0x0[6-8]) +2  ---*/
+	if( originalPhase <= 5){
+		writeData = (data & ~0x1C0) | ( (originalPhase + 2) << 6);
+		mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, writeData);
+
+		CHECK_STATUS(ddr3TipXsbCompareTest(devNum, interfaceId, busId, 2))
+	}
+
+	/*--- set phase(0x0[6-8]) +4  ---*/
+	if( originalPhase <= 3){
+		writeData = (data & ~0x1C0) | ( (originalPhase + 4) << 6);
+		mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, writeData);
+
+		CHECK_STATUS(ddr3TipXsbCompareTest(devNum, interfaceId, busId, 4))
+	}
+
+	/*--- set phase(0x0[6-8]) +6  ---*/
+	if( originalPhase <= 1){
+		writeData = (data & ~0x1C0) | ( (originalPhase + 6) << 6);
+		mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, writeData);
+
+		CHECK_STATUS(ddr3TipXsbCompareTest(devNum, interfaceId, busId, 6))
+	}
+
+	/*Nothing sucess, go ahead*/
+
+	/*Write original WL result back*/
+	mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG + effective_cs*CS_REGISTER_ADDR_OFFSET, data);
+	writeSuppResultTable[interfaceId][busId].isPupFail = GT_TRUE;
+	return GT_FAIL;
 }
 
 /*****************************************************************************
@@ -1150,82 +1165,87 @@
 ******************************************************************************/
 static GT_STATUS    ddr3TipXsbCompareTest
 (
-	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32  edgeOffset,
-	GT_U32 busIdDelta
+    GT_U32 devNum,
+    GT_U32 interfaceId,
+    GT_U32 busId,
+    GT_8 edgeOffset
 )
 {
-    GT_U32 numOfSuccByteCompare, wordInPattern, absOffset;
-    GT_U32 wordOffset,i;
+    GT_U32 numOfSuccByteCompare, wordInPattern;
+    GT_U32 wordOffset,i,numOfWordMult;
     GT_U32 readPattern[TEST_PATTERN_LENGTH*2];
 	PatternInfo *patternTable = ddr3TipGetPatternTable();
 	GT_U32 patternTestPatternTable[8];
 
-	for(i = 0; i < 8; i++) {
+    numOfWordMult = (topologyMap->activeBusMask == 3 /*INTERFACE_BUS_MASK_16BIT*/) ? 1:2; 
+
+    	for(i = 0; i < 8; i++) {
 		patternTestPatternTable[i] = patternTableGetWord(devNum, PATTERN_TEST, (GT_U8)i);
 	}
 
+
     /* extern write, than read and compare */
-    CHECK_STATUS(ddr3TipExtWrite(devNum, interfaceId, (patternTable[PATTERN_TEST].startAddr + ((SDRAM_CS_SIZE + 1)  * effective_cs)), 1, patternTestPatternTable));
+	CHECK_STATUS(ddr3TipLoadPatternToMem(devNum, PATTERN_TEST));	
 
     CHECK_STATUS(ddr3TipResetFifoPtr(devNum));
 
-    CHECK_STATUS(ddr3TipExtRead(devNum, interfaceId, (patternTable[PATTERN_TEST].startAddr + ((SDRAM_CS_SIZE + 1)  * effective_cs)), 1, readPattern));
+    CHECK_STATUS(ddr3TipExtRead(devNum, interfaceId, ((patternTable[PATTERN_TEST].startAddr<<3) + ((SDRAM_CS_SIZE + 1)  * effective_cs)), 1, readPattern));
 
-    DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: IF %d busId %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+    DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt CS#%d: IF %d busId %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",effective_cs,
 										interfaceId, busId, readPattern[0],readPattern[1],readPattern[2],readPattern[3],
 										readPattern[4],readPattern[5],readPattern[6],readPattern[7]));
     /* compare byte per pup */
     numOfSuccByteCompare = 0;
-    for(wordInPattern = startXsbOffset; wordInPattern < (TEST_PATTERN_LENGTH*2) ; wordInPattern++)
+    for(wordInPattern = startXsbOffset; wordInPattern < (TEST_PATTERN_LENGTH*numOfWordMult) ; wordInPattern++)
     {
-        wordOffset = wordInPattern + edgeOffset;
-        if ((wordOffset > (TEST_PATTERN_LENGTH*2 - 1))||(wordOffset < 0))
+        wordOffset = wordInPattern;
+        if (wordOffset > (TEST_PATTERN_LENGTH*2 - 1))
             continue;
         if ((readPattern[wordInPattern] & pupMaskTable[busId]) == (patternTestPatternTable[wordOffset] & pupMaskTable[busId]))
         {
-            /*DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("ddr3TipDynamicWriteLevelingSupp equal to Offset pattern !! \n"));*/
+            /*DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("ddr3TipDynamicWriteLevelingSupp equal to Ofsset pattern !! \n"));*/
             numOfSuccByteCompare++;
         }
     }
-    absOffset = (edgeOffset > 0) ? edgeOffset : -edgeOffset;
-    if (numOfSuccByteCompare == ((TEST_PATTERN_LENGTH*2) - absOffset - startXsbOffset))
+    if (numOfSuccByteCompare == ((TEST_PATTERN_LENGTH*numOfWordMult) - startXsbOffset))
     {
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: IF %d busId %d numOfSuccByteCompare %d - Success \n", interfaceId, busId, numOfSuccByteCompare));
+		writeSuppResultTable[interfaceId][busId].stage = edgeOffset;
+		DEBUG_LEVELING(DEBUG_LEVEL_TRACE,("supplementary: shift to %d for if %d pup %d success\n",
+											edgeOffset, interfaceId, busId));
+		writeSuppResultTable[interfaceId][busId].isPupFail = GT_FALSE;
         return GT_OK;
     }
     else
     {
-
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: IF %d busId %d numOfSuccByteCompare %d - Fail ! \n", interfaceId, busId, numOfSuccByteCompare));
-
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: expected 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", patternTestPatternTable[0],patternTestPatternTable[1],
-                                            patternTestPatternTable[2],patternTestPatternTable[3],patternTestPatternTable[4],patternTestPatternTable[5],patternTestPatternTable[6],patternTestPatternTable[7]));
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: recieved 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", readPattern[0],readPattern[1],
-                                            readPattern[2],readPattern[3],readPattern[4],readPattern[5],readPattern[6],readPattern[7]));
-
-        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: IF %d busId %d numOfSuccByteCompare %d - Fail ! \n", interfaceId, busId, numOfSuccByteCompare));
-
-
+        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt CS# %d: IF %d busId %d numOfSuccByteCompare %d - Fail ! \n",effective_cs, 
+											interfaceId, busId, numOfSuccByteCompare));
+        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: expected 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 
+											patternTestPatternTable[0],patternTestPatternTable[1],
+                                            patternTestPatternTable[2],patternTestPatternTable[3],patternTestPatternTable[4],
+											patternTestPatternTable[5],patternTestPatternTable[6],patternTestPatternTable[7]));
+        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt: received 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 
+											readPattern[0],readPattern[1],readPattern[2],readPattern[3],
+											readPattern[4],readPattern[5],readPattern[6],readPattern[7]));
+        DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("XsbCompt CS# %d: IF %d busId %d numOfSuccByteCompare %d - Fail ! \n", effective_cs,
+											interfaceId, busId, numOfSuccByteCompare));
         return GT_FAIL;
     }
 }
 
+#if 0 /* remove this if it's not in use */
 /*****************************************************************************
-Clock error shift - function moves the write leveling delay 1cc forward
+Clock error shift - function moves the write levelling delay 1cc forward
 ******************************************************************************/
 static GT_STATUS    ddr3TipWlSuppOneClkErrShift
 (
-	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32 busIdDelta
+    GT_U32 devNum,
+    GT_U32 interfaceId,
+    GT_U32 busId
 )
 {
     GT_32 phase,  adll;
     GT_U32 data;
+
     DEBUG_LEVELING(DEBUG_LEVEL_TRACE,  ("OneClkErrShift\n"));
 
     CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId,  ACCESS_TYPE_UNICAST, busId, DDR_PHY_DATA, WL_PHY_REG, &data));
@@ -1249,7 +1269,7 @@
     else
     {
         /*phase 3*/
-        return GT_FAIL; 
+        return GT_FAIL;
     }
     return GT_OK;
 }
@@ -1259,10 +1279,9 @@
 ******************************************************************************/
 static GT_STATUS    ddr3TipWlSuppAlignErrShift
 (
-	GT_U32 devNum,
-	GT_U32 interfaceId,
-	GT_U32 busId,
-	GT_U32 busIdDelta
+    GT_U32 devNum,
+    GT_U32 interfaceId,
+    GT_U32 busId
 )
 {
     GT_32 phase, adll;
@@ -1288,7 +1307,6 @@
                 CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum,  ACCESS_TYPE_UNICAST, interfaceId,  busId, DDR_PHY_DATA,  1,  data , 0x1f));
                 return GT_OK;
             }
-            
         }
         else
         {
@@ -1310,6 +1328,7 @@
     }
     return GT_OK;
 }
+#endif
 
 /*****************************************************************************
 Dynamic write leveling sequence
@@ -1319,6 +1338,7 @@
     GT_U32 busId, dqId;
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  TRAINING_SW_2_REG, 0x1,      0x5));
     CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  TRAINING_WRITE_LEVELING_REG,  0x50,     0xFF));
@@ -1336,13 +1356,13 @@
     }
 
 	/*Mask all results*/
-    for (busId=0; busId < topologyMap->numOfBusPerInterface; busId++)
+    for (busId=0; busId < octetsPerInterfaceNum; busId++)
     {
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  maskResultsPupRegMap[busId], 0x1<<24, 0x1<<24));
     }
 
 	/*Unmask only wanted*/
-    for (busId=0; busId < topologyMap->numOfBusPerInterface; busId++)
+    for (busId=0; busId < octetsPerInterfaceNum; busId++)
     {
        	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  maskResultsPupRegMap[busId], 0, 0x1<<24));
@@ -1362,6 +1382,7 @@
     GT_U32 busId, dqId;
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* mask PBS */
     for (dqId=0; dqId<MAX_DQ_NUM; dqId++)
@@ -1370,13 +1391,13 @@
     }
 
 	/*Mask all results*/
-    for (busId=0; busId < topologyMap->numOfBusPerInterface; busId++)
+    for (busId=0; busId < octetsPerInterfaceNum; busId++)
     {
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  maskResultsPupRegMap[busId], 0x1<<24, 0x1<<24));
     }
 
 	/*Unmask only wanted*/
-    for (busId=0; busId<topologyMap->numOfBusPerInterface; busId++)
+    for (busId=0; busId<octetsPerInterfaceNum; busId++)
     {
        	VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  maskResultsPupRegMap[busId], 0, 0x1<<24));
@@ -1393,6 +1414,7 @@
     GT_U32 busId, dqId;
 	GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
 	GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* mask PBS */
     for (dqId=0; dqId<MAX_DQ_NUM; dqId++)
@@ -1401,7 +1423,7 @@
     }
 
 	/*Mask all results*/
-    for (busId=0; busId < topologyMap->numOfBusPerInterface; busId++)
+    for (busId=0; busId < octetsPerInterfaceNum; busId++)
     {
         CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,  maskResultsPupRegMap[busId], 0x1<<24, 0x1<<24));
     }
@@ -1422,6 +1444,7 @@
 GT_BOOL ddr3TipPrintWLSuppResult(GT_U32 devNum)
 {
     GT_U32 busId = 0,interfaceId = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_LEVELING(DEBUG_LEVEL_INFO,("I/F0 PUP0 Result[0 - success, 1-fail] ...\n"));
 
@@ -1430,7 +1453,7 @@
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-         for(busId=0; busId<topologyMap->numOfBusPerInterface; busId++)
+         for(busId=0; busId<octetsPerInterfaceNum; busId++)
         {
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
             DEBUG_LEVELING(DEBUG_LEVEL_INFO,("%d ,", writeSuppResultTable[interfaceId][busId].isPupFail));
@@ -1440,7 +1463,7 @@
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-         for(busId=0; busId<topologyMap->numOfBusPerInterface; busId++)
+         for(busId=0; busId<octetsPerInterfaceNum; busId++)
         {
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busId)
             DEBUG_LEVELING(DEBUG_LEVEL_INFO,("%d ,", writeSuppResultTable[interfaceId][busId].stage));
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingPbs.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingPbs.c
index c4b55de..7be6f05 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingPbs.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingPbs.c
@@ -52,12 +52,12 @@
 GT_U8 MinPBSPerPup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 GT_U8 MaxADLLPerPup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 GT_U8 MinADLLPerPup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
-GT_U32 pbsdelayPerPup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+GT_U8 pbsDelayPerPup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_CS_NUM];
 GT_U8 ADLL_SHIFT_Lock[MAX_INTERFACE_NUM][MAX_BUS_NUM] ;
 GT_U8 ADLL_SHIFT_val[MAX_INTERFACE_NUM][MAX_BUS_NUM] ;
 MV_HWS_PATTERN pbsPattern = PATTERN_VREF;
 
-extern GT_U32 mvHwsDdr3TipMaxCSGet(void);
+extern GT_U32 mvHwsDdr3TipMaxCSGet(GT_U32 devNum);
 /************************** pre declarations ******************************/
 extern MV_HWS_TOPOLOGY_MAP *topologyMap;
 extern GT_U32 maskResultsDqRegMap[];
@@ -115,6 +115,7 @@
     GT_U32   csEnableRegVal[MAX_INTERFACE_NUM];
     GT_U16 *maskResultsDqRegMap 	= ddr3TipGetMaskResultsDqReg();
     GT_U8 temp = 0;
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     /* save current cs enable reg val */
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
@@ -127,7 +128,7 @@
     }
 
     regAddr = (pbsMode == PBS_RX_MODE ) ? (READ_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET)) : (WRITE_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET));
-    readAdllValue(nominalAdll, regAddr , MASK_ALL_BITS );
+    mvHwsDdr3TipReadAdllValue(devNum,nominalAdll, regAddr, MASK_ALL_BITS );
     /* stage 1 shift ADLL */
     /*ddr3TipIpTrainingPerbitMultiCast( SearchDirection, Direction, InitValue, NumberOfIterations, pbsPattern,  SearchEDGE_ , MV_HWS_ControlElement_ADLL);*/
 
@@ -135,7 +136,7 @@
                       SearchDirection, Direction, topologyMap->interfaceActiveMask, InitValue, NumberOfIterations, pbsPattern, SearchEDGE_, CS_SINGLE, csNum, trainStatus);
 
     validationVal = (pbsMode == PBS_RX_MODE) ? 0x1f : 0;
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 		for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -149,7 +150,7 @@
     }
 
     /* EBA */
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 		for( bit = 0 ; bit < BUS_WIDTH_IN_BITS ; bit++)
@@ -190,7 +191,7 @@
 	}
 
 	/* EEBA */
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -255,7 +256,7 @@
 	}
 
 	/* Print Stage result */
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -266,7 +267,7 @@
 	}
 
     DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,("Update ADLL Shift of all pups:\n"));
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -281,7 +282,7 @@
 
     /* PBS EEBA&EBA */
 	/* Start the Per Bit Skew search */
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -305,7 +306,7 @@
     ddr3TipIpTraining(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, RESULT_PER_BIT, MV_HWS_ControlElement_DQ_SKEW,
                       SearchDirection, Direction, topologyMap->interfaceActiveMask, InitValue, NumberOfIterations, pbsPattern, SearchEDGE_, CS_SINGLE, csNum, trainStatus);
 	
- 	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+ 	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -342,7 +343,7 @@
 
     /* Check all Pup lock */
 	AllLock = 1;
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
         for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -359,7 +360,7 @@
 		/* ADLL shift for SBA */
 		SearchDirection = (pbsMode == PBS_RX_MODE) ? MV_HWS_Low2High : MV_HWS_High2Low; 
 		InitValue = (SearchDirection == MV_HWS_Low2High)?0:NumberOfIterations;
-		for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+		for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 		{
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
             for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -422,7 +423,7 @@
 	    ddr3TipIpTraining(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, RESULT_PER_BIT, MV_HWS_ControlElement_DQ_SKEW,
                       SearchDirection, Direction, topologyMap->interfaceActiveMask, InitValue, NumberOfIterations, pbsPattern, SearchEDGE_, CS_SINGLE, csNum, trainStatus);
 
-		for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+		for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 		{
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
             for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
@@ -456,14 +457,14 @@
 		}
 		/* Check all Pup state */
 		AllLock = 1;
-		for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+		for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 		{
           /*  DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,("PupState[%d][%d] = %d\n",interfaceId,pup,PupState[interfaceId][pup])); */
 		}
 	}
 	/* END OF SBA */
     /* Norm */
-	for( pup = 0 ; pup < topologyMap->numOfBusPerInterface ; pup++)
+	for( pup = 0 ; pup < octetsPerInterfaceNum ; pup++)
 	{
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 		for( bit = 0 ; bit < BUS_WIDTH_IN_BITS ; bit++)
@@ -502,7 +503,7 @@
     for( interfaceId = 0 ; interfaceId < MAX_INTERFACE_NUM ; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-		for( pup = 0 ; pup <  topologyMap->numOfBusPerInterface ; pup++)
+		for( pup = 0 ; pup <  octetsPerInterfaceNum ; pup++)
 		{
 			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
 			/*if(ADLL_SHIFT_Lock[interfaceId][pup] != 1) { continue;}*/ /* if pup not lock continue to next pup */
@@ -512,15 +513,20 @@
 			{
 				 if (dqMapTable == NULL)
 				 {
-                    DEBUG_PBS_ENGINE(DEBUG_LEVEL_ERROR,("dqMapTable not initializaed\n"));
+					DEBUG_PBS_ENGINE(DEBUG_LEVEL_ERROR,("dqMapTable not initializaed\n"));
 					return GT_FAIL;
 				 }
-				 PadNum = dqMapTable[bit+pup*BUS_WIDTH_IN_BITS + interfaceId*BUS_WIDTH_IN_BITS*topologyMap->numOfBusPerInterface];
-                 DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,("Result_MAT: %d " ,Result_MAT[interfaceId][pup][bit]));
-                 regAddr = (pbsMode == PBS_RX_MODE) ? (PBS_RX_PHY_REG + effective_cs * 0x10) : (PBS_TX_PHY_REG + effective_cs * 0x10);
-                 CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,  ACCESS_TYPE_UNICAST,   interfaceId, ACCESS_TYPE_UNICAST,  pup, DDR_PHY_DATA, regAddr+PadNum, Result_MAT[interfaceId][pup][bit]));
+				PadNum = dqMapTable[bit+pup*BUS_WIDTH_IN_BITS + interfaceId*BUS_WIDTH_IN_BITS*octetsPerInterfaceNum];
+				DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,("Result_MAT: %d " ,Result_MAT[interfaceId][pup][bit]));
+				regAddr = (pbsMode == PBS_RX_MODE) ? (PBS_RX_PHY_REG + effective_cs * 0x10) : (PBS_TX_PHY_REG + effective_cs * 0x10);
+				CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum,  ACCESS_TYPE_UNICAST,   interfaceId, ACCESS_TYPE_UNICAST,  pup, DDR_PHY_DATA, regAddr+PadNum, Result_MAT[interfaceId][pup][bit]));
 			}
-			pbsdelayPerPup[pbsMode][interfaceId][pup] = (MaxPBSPerPup[interfaceId][pup] == MinPBSPerPup[interfaceId][pup])?TYPICAL_PBS_VALUE :((MaxADLLPerPup[interfaceId][pup] - MinADLLPerPup[interfaceId][pup])*ADLLTap/(MaxPBSPerPup[interfaceId][pup] - MinPBSPerPup[interfaceId][pup]));
+
+            temp = (MaxPBSPerPup[interfaceId][pup] == MinPBSPerPup[interfaceId][pup]) ?\
+                TYPICAL_PBS_VALUE :\
+                ((MaxADLLPerPup[interfaceId][pup] - MinADLLPerPup[interfaceId][pup]) * (GT_U8)ADLLTap / (MaxPBSPerPup[interfaceId][pup] - MinPBSPerPup[interfaceId][pup]));
+
+			pbsDelayPerPup[pbsMode][interfaceId][pup][effective_cs] = temp;
 
 			if( pbsMode == PBS_TX_MODE ){ /*RX results ready, write RX also*/
 				/*Write TX results*/
@@ -540,13 +546,12 @@
 				Result_MAT_RX_DQS[interfaceId][pup][effective_cs] = (MaxPBSPerPup[interfaceId][pup] - MinPBSPerPup[interfaceId][pup])/2;
 			}
 
-            DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,(", PBS tap=%d [psec] ==> skew observed = %d\n", pbsdelayPerPup[pbsMode][interfaceId][pup], ((MaxPBSPerPup[interfaceId][pup] - MinPBSPerPup[interfaceId][pup])*pbsdelayPerPup[pbsMode][interfaceId][pup])));
+			DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,(", PBS tap=%d [psec] ==> skew observed = %d\n", temp, ((MaxPBSPerPup[interfaceId][pup] - MinPBSPerPup[interfaceId][pup])*temp)));
 		}
-	}
-
+    }
     /*Write back to the phy the default values */
     regAddr = (pbsMode == PBS_RX_MODE) ? (READ_CENTRALIZATION_PHY_REG + effective_cs * 4) : (WRITE_CENTRALIZATION_PHY_REG + effective_cs * 4);
-	writeAdllValue(nominalAdll, regAddr);
+	mvHwsDdr3TipWriteAdllValue(devNum,nominalAdll, regAddr);
 
 
    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
@@ -562,17 +567,21 @@
 
    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
    {
-      /* if (trainingResult[trainingStage][interfaceId] == TEST_FAILED) */
-	  if ( PupState[interfaceId][pup] == 1) /* meaning that there is no VW exist at all (No lock at the EBA ADLL shift at EBS) */
-	   	 return GT_FAIL;
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+		for( pup = 0 ; pup <  octetsPerInterfaceNum ; pup++)
+		{
+			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
+			/* if (trainingResult[trainingStage][interfaceId] == TEST_FAILED) */
+			if ( PupState[interfaceId][pup] == 1) /* meaning that there is no VW exist at all (No lock at the EBA ADLL shift at EBS) */
+			return GT_FAIL;
+		}
    }
+
    return GT_OK;
 
 
 }
 
-
-
 /******************************************************************************
 * Name:     ddr3TipPbsRx.
 * Desc:     PBS TX
@@ -597,7 +606,7 @@
    return ddr3TipPbs(uidevNum, PBS_TX_MODE);
 }
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 /*****************************************************************************
 Print PBS Result
 ******************************************************************************/
@@ -607,12 +616,12 @@
 )
 {
     GT_U32 currCs;
-    GT_U32 max_cs = mvHwsDdr3TipMaxCSGet();
+    GT_U32 max_cs = mvHwsDdr3TipMaxCSGet(devNum);
 
    for(currCs = 0; currCs < max_cs; currCs++)
    {
-	    ddr3TipPrintPbsResult(devNum, currCs,PBS_RX_MODE);
-	    ddr3TipPrintPbsResult(devNum, currCs,PBS_TX_MODE);
+	   ddr3TipPrintPbsResult(devNum, currCs,PBS_RX_MODE);
+	   ddr3TipPrintPbsResult(devNum, currCs,PBS_TX_MODE);
    }
    return GT_OK;
 }
@@ -629,7 +638,18 @@
 {
     GT_U32 dataValue = 0, bit = 0, interfaceId = 0, pup = 0;
     GT_U32 regAddr = (pbsMode == PBS_RX_MODE) ? (PBS_RX_PHY_REG + csNum * 0x10) : (PBS_TX_PHY_REG + csNum * 0x10);
-    mvPrintf("CS%d, %s ,PBS \n", csNum ,(pbsMode==PBS_RX_MODE)? "Rx" : "Tx");
+    GT_U32 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
+
+    mvPrintf("%s,CS%d,PBS,ADLLRATIO,,,", (pbsMode == PBS_RX_MODE)?"Rx":"Tx", csNum);
+    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+        for( pup=0; pup < octetsPerInterfaceNum; pup++)
+        {
+                mvPrintf("%d,",pbsDelayPerPup[pbsMode][interfaceId][pup][csNum]);
+        }
+	}
+    mvPrintf("\nCS%d, %s ,PBS \n", csNum ,(pbsMode==PBS_RX_MODE)? "Rx" : "Tx");
     for( bit = 0 ; bit < BUS_WIDTH_IN_BITS ; bit++)
     {
 	mvPrintf("%s, DQ",(pbsMode==PBS_RX_MODE)? "Rx" : "Tx");
@@ -637,7 +657,7 @@
         {
             VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
 	    mvPrintf("%d ,PBS,,, ",bit);
-            for( pup=0; pup <=topologyMap->numOfBusPerInterface; pup++)
+            for( pup=0; pup <=octetsPerInterfaceNum; pup++)
             {
 		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pup)
                 CHECK_STATUS(mvHwsDdr3TipBUSRead(   devNum, interfaceId, ACCESS_TYPE_UNICAST, pup,  DDR_PHY_DATA,  regAddr+bit, &dataValue));
@@ -664,11 +684,12 @@
 {
     GT_U32 interfaceId, pup, bit;
     GT_U32 regAddr = (pbsMode == PBS_RX_MODE) ? (PBS_RX_PHY_REG + effective_cs * 0x10) : (PBS_TX_PHY_REG + effective_cs * 0x10);
+	GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     for( interfaceId = 0 ; interfaceId <= MAX_INTERFACE_NUM-1 ; interfaceId++)
     {
         VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for( pup=0; pup <=topologyMap->numOfBusPerInterface; pup++)
+        for( pup=0; pup <=octetsPerInterfaceNum; pup++)
         {
 			for( bit = 0 ; bit <= BUS_WIDTH_IN_BITS+3; bit++)
 			{
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingStatic.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingStatic.c
index 07e3ed5..88fe281 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingStatic.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Driver/ddr3/mvHwsDdr3TrainingStatic.c
@@ -29,13 +29,8 @@
 #include "mvDdr3TrainingIpPrvIf.h"
 #include "mvDdr3LoggingDef.h"
 
-#ifdef CONFIG_DDR4
-#include "mvHwsDdr4Training.h"
-#endif
-
 extern MV_HWS_TOPOLOGY_MAP *topologyMap;
 extern GT_U32 clampTbl[MAX_INTERFACE_NUM];
-extern GT_U32 vref;
 
 #ifdef STATIC_ALGO_SUPPORT
 /************************** definitions ******************************/
@@ -65,7 +60,6 @@
 
 GT_U32 readReadyDelayPhaseOffset[] = { 4, 4, 4, 4, 6, 6, 6, 6 };
 
-extern GT_U32 vref;
 extern ClValuePerFreq casLatencyTable[];
 extern GT_U32 targetFreq;
 extern MV_HWS_TIP_CONFIG_FUNC_DB configFuncInfo[HWS_MAX_DEVICE_NUM];
@@ -153,10 +147,11 @@
     GT_U32 temp;
     GT_U32 boardTrace;
     TripDelayElement* pkgDelayPtr;
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     sign = (isWl) ? -1 : 1; /* in WL we calc the diff between Clock to DQs in RL we sum the round trip of Clock and DQs */
 
-    busPerInterface = GET_TOPOLOGY_NUM_OF_BUSES(devNum);
+    busPerInterface = octetsPerInterfaceNum;
 
     for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
     {
@@ -197,12 +192,13 @@
     GT_U32 phase = 0;
     GT_U32 adll = 0, adll_cen, adll_inv, adll_final;
     GT_U32 adllPeriod = MEGA / freqVal[frequency] / 64;
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("ddr3TipWriteLevelingStaticConfig\n"));
     DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("devNum 0x%x IF 0x%x freq %d (adllPeriod 0x%x)\n", devNum, interfaceId, frequency, adllPeriod));   
 
 
-	busPerInterface = GET_TOPOLOGY_NUM_OF_BUSES(devNum);
+	busPerInterface = octetsPerInterfaceNum;
 	busStartIndex = interfaceId * busPerInterface;
 	for(busIndex = busStartIndex; busIndex < (busStartIndex + busPerInterface); busIndex++)
 	{
@@ -248,8 +244,7 @@
 	MV_HWS_SPEED_BIN speedBinIndex;
 	GT_U32 rdSampleDly[MAX_CS_NUM] = { 0 };
 	GT_U32 rdReadyDel[MAX_CS_NUM]  = { 0 };
-	GT_U32  busPerInterface = GET_TOPOLOGY_NUM_OF_BUSES(devNum);
-
+	GT_U8 octetsPerInterfaceNum = ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
 
     DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("ddr3TipReadLevelingStaticConfig\n"));
     DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("devNum 0x%x ifc 0x%x freq %d\n", devNum,interfaceId, frequency));   
@@ -267,9 +262,9 @@
     }
   
 
-    busStartIndex = interfaceId * busPerInterface;
+    busStartIndex = interfaceId * octetsPerInterfaceNum;
 
-    for(busIndex=busStartIndex; busIndex < (busStartIndex + busPerInterface); busIndex+=2)
+    for(busIndex=busStartIndex; busIndex < (busStartIndex + octetsPerInterfaceNum); busIndex+=2)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
         cs = chipSelectMap[topologyMap->interfaceParams[interfaceId].asBusParams[(busIndex % 4)].csBitmask].csNum;
@@ -297,30 +292,11 @@
 		data0 =  ((phase0 << 6) + (adll0 & 0x1F));
 		data1 = ((phase1 << 6) + (adll1 & 0x1F));
 
-#if 0
-/*Check when this used in other projects*/
-		if (silicon == 0)
-		{
-			switch(topologyMap->boardId)
-			{
-				case DDR_BOARD_FUNCTIONAL:
-					data3 = functionRegValue;
-					break;
-
-				case DDR_BOARD_ETP:
-				case DDR_BOARD_CUSTOMER:
-				default:
-					data3 = s_uiMRegValue;
-					break;
-			}
-		}
-#endif
-
 		CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, (busIndex % 4), DDR_PHY_DATA, PHY_READ_DELAY(cs), data0,0x1DF));
 		CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ((busIndex + 1) % 4), DDR_PHY_DATA, PHY_READ_DELAY(cs), data1, 0x1DF));
 	}
 
-    for (busIndex = 0; busIndex < busPerInterface; busIndex++)
+    for (busIndex = 0; busIndex < octetsPerInterfaceNum; busIndex++)
     {
    		VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busIndex)
         CHECK_STATUS(ddr3TipBusReadModifyWrite(  devNum, ACCESS_TYPE_UNICAST, interfaceId, busIndex, DDR_PHY_DATA, 0x3, data3, 0x1F));
@@ -388,7 +364,7 @@
    GT_U32 indexCnt = 0;
 
    DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("ddr3TipStaticInitController\n")); 
-//   for(indexCnt = 0; indexCnt < staticInitControllerConfigLen[devNum]; indexCnt++)
+
 	while(staticInitControllerConfig[devNum][indexCnt].regAddr != 0)
    {
        	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum,ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 
@@ -408,95 +384,15 @@
     GT_U32    devNum
 )
 {
-	//DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("CLK to CTRL skew\n"));
-    //CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_UNICAST, 0x2, DDR_PHY_CONTROL, 0x90, 0x20da));
-
-	//DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("CTRL Ref Delay\n")); /* motib does not efect*/
-    //CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, 0x1, 0xf));
-     
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("Phy Init Controller 2\n")); 
     CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xA4, 0x3dfe));
-	
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("Phy Init Controller 3\n"));
     CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xA6, 0xCB2));
-	 
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("Phy Init Controller 4\n"));
     CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xA9, 0));
-    
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("Static Receiver Calibration\n"));
 	CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xD0, 0x1F));
-	 
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE, ("Static V-REF Calibration\n"));
     CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xA8, 0x434));
      
-
     return GT_OK;
 }
 
 #endif
 
-/*Design Guidelines parameters*/
-GT_U32 gZpriData = 123; //controller data - P drive strength
-GT_U32 gZnriData = 123; //controller data � N drive strength
-GT_U32 gZpriCtrl = 74; //controller C/A � P drive strength
-GT_U32 gZnriCtrl = 74; //controller C/A � N drive strength
-
-GT_U32 gZpodtData = 45; //controller data - P ODT
-GT_U32 gZnodtData = 45; //controller data - N ODT
-GT_U32 gZpodtCtrl = 45; //controller data - P ODT
-GT_U32 gZnodtCtrl = 45; //controller data - N ODT
-
-#if 0
-GT_U32 gDic = GT_TUNE_TRAINING_PARAMS_UNDEFINED; //memory drive strength
-GT_U32 uiODTConfig = GT_TUNE_TRAINING_PARAMS_UNDEFINED;
-GT_U32 gRttNom = GT_TUNE_TRAINING_PARAMS_UNDEFINED;
-#endif
-//GT_U32 gRttWr = GT_TUNE_TRAINING_PARAMS_UNDEFINED;
-
-GT_U32 uiODTConfig = 0x120012;
-GT_U32 gRttNom = 0x44;
-GT_U32 gDic = 0x2;
-
-/*****************************************************************************
-Configure phy ( called by static init controller)  for static flow
-******************************************************************************/
-GT_STATUS    ddr3TipConfigurePhy
-(
-    GT_U32    devNum
-)
-{
-    GT_U32 interfaceId, phyId;
-
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_ZRI_CALIB_PHY_REG, ((0x7f & gZpriData) << 7 | (0x7f & gZnriData))));
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, PAD_ZRI_CALIB_PHY_REG, ((0x7f & gZpriCtrl) << 7 | (0x7f & gZnriCtrl))));
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_ODT_CALIB_PHY_REG, ((0x3f & gZpodtData) << 6 | (0x3f & gZnodtData))));
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, PAD_ODT_CALIB_PHY_REG, ((0x3f & gZpodtCtrl) << 6 | (0x3f & gZnodtCtrl))));
-
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, PAD_PRE_DISABLE_PHY_REG, 0));
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, CMOS_CONFIG_PHY_REG, 0));
-    CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, CMOS_CONFIG_PHY_REG, 0));
-    for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
-	{
-		/* check if the interface is enabled */
-        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
-        for(phyId=0;phyId<topologyMap->numOfBusPerInterface; phyId++)
-        {
-   			VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, phyId)
-            /* Vref & clamp */
-            CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  phyId, DDR_PHY_DATA, PAD_CONFIG_PHY_REG,   ((clampTbl[interfaceId] << 4) | vref ), ((0x7 << 4) | 0x7) ));
-            /* clamp not relevant for control */
-            CHECK_STATUS(ddr3TipBusReadModifyWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId,  phyId, DDR_PHY_CONTROL, PAD_CONFIG_PHY_REG,    0x4 , 0x7 ));
-        }
-    }
-
-#if defined(CONFIG_ARMADA_38X) || defined (CONFIG_ARMADA_39X)
-	CHECK_STATUS(mvHwsDdr3TipBUSWrite(  devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0x90, 0x6002));
-#endif
-
-#ifdef CONFIG_DDR4
-    ddr4TipConfigurePhy(devNum);
-#endif
-
-   return GT_OK;
-}
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Os/gtOs/mvXor.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Os/gtOs/mvXor.c
index 36c5d14..f02ae98 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Os/gtOs/mvXor.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Os/gtOs/mvXor.c
@@ -71,34 +71,53 @@
 #endif
 
 static GT_U32 uiXorRegsCtrlBackup;
-static GT_U32 uiXorRegsBaseBackup[MAX_CS];
-static GT_U32 uiXorRegsMaskBackup[MAX_CS];
+static GT_U32 uiXorRegsBaseBackup[MAX_CS + 1];
+static GT_U32 uiXorRegsMaskBackup[MAX_CS + 1];
 
-extern GT_U32 mvHwsDdr3TipMaxCSGet(void);
+extern GT_U32 mvHwsDdr3TipMaxCSGet(GT_U32 devNum);
 
+/*******************************************************************************
+* mvSysXorInit
+*
+* DESCRIPTION:
+*               This function initialize the XOR unit's windows.
+* INPUT:
+*       uiNumOfCS	- number of enabled chip select
+*	uiCsEna		- bitmap of enabled chip selects:
+*				bit[i] = 1 if chip select i is enabled (for 1 <= i <= 3)
+*				bit[4] = if SRAM window is enabled
+*	csSize		- size of DRAM chip select
+*	baseDelta	- base start of the DRAM windows
+*
+*
+*******************************************************************************/
 GT_VOID mvSysXorInit(GT_U32 uiNumOfCS, GT_U32 uiCsEna, GT_U32 csSize, GT_U32 baseDelta)
 {
-	GT_U32 uiReg,ui,uiBase,uiCsCount;
+	GT_U32 uiReg, ui, uiBase, uiCsCount, sizeMask;
 
 	uiXorRegsCtrlBackup = MV_REG_READ(XOR_WINDOW_CTRL_REG(0, 0));
-	for(ui=0;ui<MAX_CS;ui++)
+	for(ui = 0; ui < MAX_CS + 1; ui++)
 		uiXorRegsBaseBackup[ui] = MV_REG_READ(XOR_BASE_ADDR_REG(0, ui));
-	for(ui=0;ui<MAX_CS;ui++)
+	for(ui = 0; ui < MAX_CS + 1; ui++)
 		uiXorRegsMaskBackup[ui] = MV_REG_READ(XOR_SIZE_MASK_REG(0, ui));
 
 	uiReg = 0;
-	for(ui=0;ui<(uiNumOfCS);ui++) {
-		uiReg |= (0x1 << (ui)); 					/* 	Enable Window x for each CS */
-		uiReg |= (0x3 << ((ui*2)+16)); 				/* 	Enable Window x for each CS */
+	for (uiCsCount = 0, ui = 0; uiCsCount < uiNumOfCS && ui < 8; ui++) {
+		if(uiCsEna & (1 << ui)) {
+			uiReg |= (0x1 << (ui));			/* Enable Window x for each CS */
+			uiReg |= (0x3 << ((ui*2)+16)); 		/* Enable Window x for each CS */
+			uiCsCount++;
+		}
 	}
 
 	MV_REG_WRITE(XOR_WINDOW_CTRL_REG(0, 0), uiReg);
 
-	uiCsCount = 0;
-	for(ui=0;ui<uiNumOfCS;ui++) {
+	for (uiCsCount = 0, ui = 0; uiCsCount < uiNumOfCS && ui < 8; ui++) {
 		if(uiCsEna & (1<<ui)) {
 			/* window x - Base - 0x00000000, Attribute 0x0E - DRAM */
 			uiBase = csSize*ui + baseDelta;
+			/* fixed size 2GB for each CS */
+			sizeMask = 0x7FFF0000;
 			switch(ui) {
 				case 0:
 					uiBase |= 0xE00;
@@ -112,12 +131,16 @@
 				case 3:
 					uiBase |= 0x700;
 					break;
+				case 4: /* SRAM */
+					uiBase = 0x40000000;
+					uiBase |= 0x1F00; /* configure as shared transaction */
+					sizeMask = 0xF0000;
 			}
 
-			MV_REG_WRITE(XOR_BASE_ADDR_REG(0, uiCsCount), uiBase);
+			MV_REG_WRITE(XOR_BASE_ADDR_REG(0, ui), uiBase);
 
 			/* window x - Size*/
-			MV_REG_WRITE(XOR_SIZE_MASK_REG(0, uiCsCount), 0x7FFF0000);
+			MV_REG_WRITE(XOR_SIZE_MASK_REG(0, ui), sizeMask);
 			uiCsCount++;
 		}
 	}
@@ -131,9 +154,9 @@
 	GT_U32 ui;
 
 	MV_REG_WRITE(XOR_WINDOW_CTRL_REG(0, 0), uiXorRegsCtrlBackup);
-	for(ui=0;ui<MAX_CS;ui++)
+	for(ui = 0; ui < MAX_CS + 1; ui++)
 		MV_REG_WRITE(XOR_BASE_ADDR_REG(0, ui), uiXorRegsBaseBackup[ui]);
-	for(ui=0;ui<MAX_CS;ui++)
+	for(ui = 0; ui < MAX_CS + 1; ui++)
 		MV_REG_WRITE(XOR_SIZE_MASK_REG(0, ui), uiXorRegsMaskBackup[ui]);
 
 	MV_REG_WRITE(XOR_ADDR_OVRD_REG(0, 0), 0);
@@ -392,9 +415,9 @@
 {
 	MV_U32 cs_c,max_cs;
 	MV_U32 uiCsEna = 0;
-    mvPrintf("DDR3 Training Sequence - Start scrubbing \n");
+    mvPrintf("DDR Training Sequence - Start scrubbing \n");
 
-	max_cs = mvHwsDdr3TipMaxCSGet();
+	max_cs = mvHwsDdr3TipMaxCSGet(0);
 	for (cs_c = 0; cs_c < max_cs; cs_c++)
 		uiCsEna |= 1 << cs_c;
 
@@ -411,7 +434,106 @@
     /* Return XOR State */
     mvSysXorFinish();
 
-    mvPrintf("DDR3 Training Sequence - End scrubbing \n");
+    mvPrintf("DDR Training Sequence - End scrubbing \n");
 }
 
+/*******************************************************************************
+* mvXorTransfer - Transfer data from source to destination on one of
+*                 three modes (XOR,CRC32,DMA)
+*
+* DESCRIPTION:
+*       This function initiates XOR channel, according to function parameters,
+*       in order to perform XOR or CRC32 or DMA transaction.
+*       To gain maximum performance the user is asked to keep the following
+*       restrictions:
+*       1) Selected engine is available (not busy).
+*       1) This module does not take into consideration CPU MMU issues.
+*          In order for the XOR engine to access the appropreate source
+*          and destination, address parameters must be given in system
+*          physical mode.
+*       2) This API does not take care of cache coherency issues. The source,
+*          destination and in case of chain the descriptor list are assumed
+*          to be cache coherent.
+*       4) Parameters validity. For example, does size parameter exceeds
+*          maximum byte count of descriptor mode (16M or 64K).
+*
+* INPUT:
+*       chan          - XOR channel number. See GT_XOR_CHANNEL enumerator.
+*       xorType       - One of three: XOR, CRC32 and DMA operations.
+*       xorChainPtr   - address of chain pointer
+*
+* OUTPUT:
+*       None.
+*
+* RETURS:
+*       GT_BAD_PARAM if parameters to function invalid, GT_OK otherwise.
+*
+*******************************************************************************/
+GT_STATUS mvXorTransfer(GT_U32 chan, MV_XOR_TYPE xorType, GT_U32 xorChainPtr)
+{
+	GT_U32 temp;
 
+	/* Parameter checking */
+	if (chan >= MV_XOR_MAX_CHAN) {
+		DB(mvPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan));
+		return GT_BAD_PARAM;
+	}
+	if (MV_ACTIVE == mvXorStateGet(chan)) {
+		DB(mvPrintf("%s: ERR. Channel is already active\n", __func__));
+		return GT_BUSY;
+	}
+	if (0x0 == xorChainPtr) {
+		DB(mvPrintf("%s: ERR. xorChainPtr is NULL pointer\n", __func__));
+		return GT_BAD_PARAM;
+	}
+
+	/* read configuration register and mask the operation mode field */
+	temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
+	temp &= ~XEXCR_OPERATION_MODE_MASK;
+
+	switch (xorType) {
+	case MV_XOR:
+		if (0 != (xorChainPtr & XEXDPR_DST_PTR_XOR_MASK)) {
+			DB(mvPrintf("%s: ERR. Invalid chain pointer (bits [5:0] must "
+				      "be cleared)\n", __func__));
+			return GT_BAD_PARAM;
+		}
+		/* set the operation mode to XOR */
+		temp |= XEXCR_OPERATION_MODE_XOR;
+		break;
+
+	case MV_DMA:
+		if (0 != (xorChainPtr & XEXDPR_DST_PTR_DMA_MASK)) {
+			DB(mvPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must "
+				      "be cleared)\n", __func__));
+			return GT_BAD_PARAM;
+		}
+		/* set the operation mode to DMA */
+		temp |= XEXCR_OPERATION_MODE_DMA;
+		break;
+
+	case MV_CRC32:
+		if (0 != (xorChainPtr & XEXDPR_DST_PTR_CRC_MASK)) {
+			DB(mvPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must "
+				      "be cleared)\n", __func__));
+			return GT_BAD_PARAM;
+		}
+		/* set the operation mode to CRC32 */
+		temp |= XEXCR_OPERATION_MODE_CRC;
+		break;
+
+	default:
+		return GT_BAD_PARAM;
+	}
+
+	/* write the operation mode to the register */
+	MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
+	/* update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
+	   Pointer Register (XExNDPR) */
+	MV_REG_WRITE(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xorChainPtr);
+
+	/* start transfer */
+	MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);
+
+	return GT_OK;
+}
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/gtBuild b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/gtBuild
index 6bfe711..beb9af2 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/gtBuild
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/gtBuild
@@ -19,7 +19,7 @@
 
 ## CPSS compilation environment #################
 #INCLUDE_PATH =
-C_FILE_LIST   = mvHwsDdr3Bc2.c
+C_FILE_LIST   = mvHwsDdr3Msys.c mvHwsDdr3Bc2.c mvHwsDdr3BobK.c
 #SUBDIRS      =
 #C_EXCLUDE_FILE_LIST =
 
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Ac3.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Ac3.c
index ec8a2a8..ed5fd73 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Ac3.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Ac3.c
@@ -47,36 +47,18 @@
 
 extern MV_BOOL ddr3IfEccEnabled(void);
 extern GT_U32 maskTuneFunc;
-extern GT_U32 rlVersion;
-extern GT_U32 delayEnable, ckDelay, ckDelay_16, caDelay;
+extern GT_U32 delayEnable, ckDelay, caDelay;
 extern GT_U32 firstActiveIf;
 extern MV_HWS_DDR_FREQ initFreq;
 extern GT_U8  debugTrainingAccess;
 extern GT_U8  debugTrainingAc3;
 extern MV_HWS_DDR_FREQ mediumFreq;
 extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
+extern GT_U32 dfsLowFreq;
+extern GT_U32 freqVal[];
 
 GT_U32  pipeMulticastMask;
 
-static GT_U16 freqVal[DDR_FREQ_LIMIT] =
-{
-    130, /*DDR_FREQ_LOW_FREQ*/
-    400, /*DDR_FREQ_400,*/
-    533, /*DDR_FREQ_533,*/
-    666, /*DDR_FREQ_667,*/
-    800, /*DDR_FREQ_800,*/
-    933, /*DDR_FREQ_933,*/
-   1066, /*DDR_FREQ_1066,*/
-    311, /*DDR_FREQ_311,*/
-    333, /*DDR_FREQ_333,*/
-    467,  /*DDR_FREQ_467,*/
-    850,  /*DDR_FREQ_850,*/
-    600,  /*DDR_FREQ_600,*/
-    300,  /*DDR_FREQ_300,*/
-	900,  /*DDR_FREQ_900*/
-	360  /*DDR_FREQ_360*/
-};
-
 static GT_U8 Ac3BwPerFreq[DDR_FREQ_LIMIT] =
 {
     0x3, /*DDR_FREQ_100*/
@@ -199,6 +181,9 @@
 	GT_U8      devNum,
 	MV_DDR3_DEVICE_INFO * infoPtr
 );
+
+GT_U8    ddr3TipClockMode( GT_U32 frequency );
+
 /************************** Server Access ******************************/
 
 GT_STATUS ddr3TipAc3ServerRegWrite
@@ -396,8 +381,9 @@
 	MV_HWS_DDR_FREQ uiDdrFreq;
 	MV_STATUS status;
 	MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
+	GT_U8 numOfBusPerInterface = 5;
 
-    GT_U32 boardOffset = boardId * AC3_NUMBER_OF_INTERFACES *topologyMap->numOfBusPerInterface;
+    GT_U32 boardOffset = boardId * AC3_NUMBER_OF_INTERFACES *numOfBusPerInterface;
 
     /* new read leveling version */
     staticConfig.siliconDelay = Ac3SiliconDelayOffset[boardId];
@@ -411,11 +397,19 @@
 	configFunc.tipSetFreqDividerFunc = ddr3TipAc3SetDivider;
 	configFunc.tipGetDeviceInfoFunc = ddr3TipAC3GetDeviceInfo;
 	configFunc.tipGetTemperature = NULL;
+	configFunc.tipGetClockRatio = ddr3TipClockMode;
 
     mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
 
 	ddr3TipRegisterDqTable(devNum, DQbitMap2Phypin);
 
+	/*Set device attributes*/
+	ddr3TipDevAttrInit(devNum);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_3);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_NEGATIVE);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, numOfBusPerInterface);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
+
 #ifdef STATIC_ALGO_SUPPORT
     ddr3TipInitStaticConfigDb(devNum, &staticConfig);
 #endif
@@ -425,12 +419,11 @@
 		return status;
 	}
 
-    rlVersion = 1;
-
-    maskTuneFunc =     (SET_MEDIUM_FREQ_MASK_BIT |
+    maskTuneFunc =     (SET_LOW_FREQ_MASK_BIT |
+						LOAD_PATTERN_MASK_BIT |
+						SET_MEDIUM_FREQ_MASK_BIT |
 						WRITE_LEVELING_MASK_BIT |
 						WRITE_LEVELING_SUPP_MASK_BIT |
-						LOAD_PATTERN_2_MASK_BIT |
 						READ_LEVELING_MASK_BIT |
 						PBS_RX_MASK_BIT |
 						PBS_TX_MASK_BIT |
@@ -448,13 +441,12 @@
 		maskTuneFunc &=	~WRITE_LEVELING_SUPP_MASK_BIT;
 	}
 
-	if( ckDelay == -1 )
-		ckDelay_16 = 200;
-	if( ckDelay == -1 )
+	if( ckDelay == MV_PARAMS_UNDEFINED )
 		ckDelay = 200;
 	delayEnable = 1;
 	caDelay = 0;
 	calibrationUpdateControl = 1;
+	freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 130;
 
 	initFreq = topologyMap->interfaceParams[interfaceId].memoryFreq;
 
@@ -571,25 +563,18 @@
     GT_U32 sarVal;
 	GT_U32 data = 0;
 	GT_U32 select = 0;
+	GT_U8 value;
 	MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
 
-	/* Dunit training clock + 1:1 mode */
-	if(frequency == DDR_FREQ_LOW_FREQ) {
-		divRatio = (1 << 30);
-		CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0xF8294,  &data, MASK_ALL_BITS ));
-		CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0xF8294,  R_MOD_W(divRatio, data, (0x3 << 30))));
+	/* Dunit training clock + 1:1/2:1 mode */
+	divRatio = (ddr3TipClockMode(frequency) << 30);
+	CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0xF8294,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0xF8294,  R_MOD_W(divRatio, data, (0x3 << 30))));
 
-		CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0x1524,  &data, MASK_ALL_BITS ));
-		CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0x1524,  R_MOD_W((0 << 15), data, (0 << 15) )));
-	}
-	else {
-		divRatio = (2 << 30);
-		CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0xF8294,  &data, MASK_ALL_BITS ));
-		CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0xF8294,  R_MOD_W(divRatio, data, (0x3 << 30))));
+	/* Configure Dunit to 1:1 in case of DLL off mode else 2:1*/
+	value = (ddr3TipClockMode(frequency) == 1)? 0 : 1;
+	CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, interfaceId, 0x1524, (value << 15), (1 << 15)));
 
-		CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0x1524,  &data, MASK_ALL_BITS ));
-		CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0x1524,  R_MOD_W((1 << 15), data, (0 << 15) )));
-	}
 	select = (frequency == topologyMap->interfaceParams[firstActiveIf].memoryFreq)?(0 << 29) : (1 << 29);//TF is the function mode so the selector have to be 0.
 	CHECK_STATUS(ddr3TipAc3ServerRegRead(devNum,  0xF8294,  &data, MASK_ALL_BITS ));
 	CHECK_STATUS(ddr3TipAc3ServerRegWrite(devNum, 0xF8294,  R_MOD_W(select, data, (0x1 << 29))));
@@ -642,6 +627,19 @@
 }
 
 /******************************************************************************
+* return 1 of core/DUNIT clock ration is 1 for given freq, 0 if clock ratios is 2:1
+*/
+GT_U8    ddr3TipClockMode( GT_U32 frequency )
+{
+	if(frequency == DDR_FREQ_LOW_FREQ){
+		return 1;
+	}
+	else{
+		return 2;
+	}
+}
+
+/******************************************************************************
 * external read from memory
 */
 GT_STATUS    ddr3TipExtRead
@@ -655,7 +653,7 @@
 {
     GT_U32 burstNum;
 
-    for(burstNum=0 ; burstNum < numOfBursts*8; burstNum++)
+    for(burstNum=0 ; burstNum < numOfBursts*4; burstNum++)// 4 per 16 bit I/F
     {
 		data[burstNum] = * (volatile unsigned int *) (regAddr + 4* burstNum);
     }
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Bc2.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Bc2.c
index f927ff7..52367af 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Bc2.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Bc2.c
@@ -32,7 +32,6 @@
 
 /************************** definitions ******************************/
 #define BC2_NUM_BYTES                   (3)
-#define BC2_NUMBER_OF_INTERFACES		5
 
 #define BC2_CLIENT_FIELD(client)		(client << 15)
 #define BC2_GET_CLIENT_FIELD(interfaceAccess,interfaceId) ((interfaceAccess == ACCESS_TYPE_MULTICAST) ? BC2_CLIENT_FIELD(MULTICAST_ID):BC2_CLIENT_FIELD(interfaceId))
@@ -47,6 +46,23 @@
 
 /************************** pre-declaration ******************************/
 
+GT_STATUS    ddr3TipBC2ExtRead
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+);
+
+GT_STATUS    ddr3TipBC2ExtWrite
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *addr
+);
 static GT_STATUS ddr3TipBc2GetMediumFreq
 (
     GT_U32          devNum,
@@ -86,7 +102,7 @@
     MV_HWS_DDR_FREQ* freq
 );
 
-GT_STATUS ddr3TipTmGetInitFreq
+static GT_STATUS ddr3TipTmGetInitFreq
 (
     GT_STATUS       devNum,
     MV_HWS_DDR_FREQ *freq
@@ -135,7 +151,6 @@
 /************************** Globals ******************************/
 
 extern GT_U32 maskTuneFunc;
-extern GT_U32 rlVersion;
 extern GT_U32 freqVal[];
 extern MV_HWS_DDR_FREQ mediumFreq;
 extern MV_HWS_TOPOLOGY_MAP *topologyMap;
@@ -147,9 +162,10 @@
 extern GT_U32 isPllBeforeInit;
 extern GT_U32 useBroadcast;
 extern GT_U32 isCbeRequired;
-extern GT_U32 delayEnable, ckDelay, ckDelay_16,caDelay;
+extern GT_U32 delayEnable, ckDelay,caDelay;
 extern GT_U8 debugTrainingAccess;
 extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
+extern GT_U32 dfsLowFreq;
 
 GT_U32 debugBc2 = 0;
 GT_U32  pipeMulticastMask;
@@ -261,24 +277,6 @@
    0x1  /*DDR_FREQ_360*/
 };
 
-GT_U32 phy1ValTable[DDR_FREQ_LIMIT] =
-{
-  0,   /* DDR_FREQ_LOW_FREQ */
-  0xf, /* DDR_FREQ_400 */
-  0xf, /* DDR_FREQ_533 */
-  0xf, /* DDR_FREQ_667 */
-  0xc, /* DDR_FREQ_800 */
-  0x8, /* DDR_FREQ_933 */
-  0x8, /* DDR_FREQ_1066 */
-  0xf, /* DDR_FREQ_311 */
-  0xf, /* DDR_FREQ_333 */
-  0xf, /* DDR_FREQ_467 */
-  0xc, /*DDR_FREQ_850*/
-  0xf, /*DDR_FREQ_600*/
-  0xf, /*DDR_FREQ_300*/
-  0x8,  /*DDR_FREQ_900*/
-  0xf  /*DDR_FREQ_360*/
-};
 
 /* Bit mapping (for PBS) */
 GT_U32 bc2DQbitMap2Phypin[] =
@@ -316,31 +314,31 @@
     /* 1st board */
     {
     0x1f, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
- {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
-    4, /* Num Of Bus Per Interface*/
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
     0xF  /* Buses mask */
     },
 
-	/* 2nd board */
+    /* 2nd board */
     {
     0x1f, /* active interfaces */
-    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                                     speed_bin             memory_width  mem_size     frequency  casL casWL      temperature */
- {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
-    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
-    4, /* Num Of Bus Per Interface*/
-    1  /* board number */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_2133N, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
+    0xF  /* Buses mask */
     }
 };
 #endif
 
+static GT_U8    ddr3TipClockMode( GT_U32 frequency );
+
 /************************** Server Access ******************************/
 
 GT_STATUS ddr3TipBc2ServerRegWrite
@@ -445,7 +443,7 @@
 /*****************************************************************************
 Enable Pipe
 ******************************************************************************/
-GT_STATUS    ddr3TipPipeEnable
+static GT_STATUS    ddr3TipPipeEnable
 (
     GT_U8                 devNum,
     MV_HWS_ACCESS_TYPE    interfaceAccess,
@@ -478,7 +476,7 @@
     return GT_OK;
 }
 
-void ddr3TipIsUnicastAccess( GT_U8 devNum,GT_U32* interfaceId, MV_HWS_ACCESS_TYPE* interfaceAccess)
+static void ddr3TipIsUnicastAccess( GT_U8 devNum,GT_U32* interfaceId, MV_HWS_ACCESS_TYPE* interfaceAccess)
 {
 	GT_U32 indexCnt, totalCnt = 0 , interfaceTmp = 0;
     MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
@@ -738,20 +736,21 @@
     GT_U32  boardId
 )
 {
-    MV_HWS_TIP_CONFIG_FUNC_DB configFunc;
-	MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
+    MV_HWS_TIP_CONFIG_FUNC_DB   configFunc;
+	MV_HWS_TOPOLOGY_MAP*        topologyMap = ddr3TipGetTopologyMap(devNum);
+    GT_TUNE_TRAINING_PARAMS     tuneParams;
 
 	if(topologyMap == NULL)
 	{
 		return GT_NOT_INITIALIZED;
 	}
 
-	ddr3TipBc2GetInterfaceMap((GT_U8)devNum);
+    ddr3TipBc2GetInterfaceMap((GT_U8)devNum);
 
 #ifdef STATIC_ALGO_SUPPORT
 	MV_HWS_TIP_STATIC_CONFIG_INFO staticConfig;
 
-    GT_U32 boardOffset = boardId * BC2_NUMBER_OF_INTERFACES *topologyMap->numOfBusPerInterface;
+    GT_U32 boardOffset = boardId * BC2_NUMBER_OF_INTERFACES * BC2_NUMBER_OF_PUP;
 
     staticConfig.siliconDelay = bc2SiliconDelayOffset[boardId];
     staticConfig.packageTraceArr = bc2PackageRoundTripDelayArray;
@@ -771,57 +770,80 @@
     configFunc.tipSetFreqDividerFunc = ddr3TipBc2SetDivider;
     configFunc.tipGetDeviceInfoFunc = ddr3TipBc2GetDeviceInfo;
 	configFunc.tipGetTemperature = NULL;
+	configFunc.tipGetClockRatio = ddr3TipClockMode;
+
+    configFunc.tipExternalRead  = ddr3TipBC2ExtRead;
+    configFunc.tipExternalWrite = ddr3TipBC2ExtWrite;
 
     mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
 
 	/* register bit mapping (for PBS) */
 	ddr3TipRegisterDqTable(devNum, bc2DQbitMap2Phypin);
 
-#if defined(CHX_FAMILY) || defined(EXMXPM_FAMILY)
-		/* for TM interface, since DFS flow is different from MSYS DFS (which is not
-		   functional) DFS is included in the flow */
+	/*Set device attributes*/
+	ddr3TipDevAttrInit(devNum);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_2);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_NEGATIVE);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, BC2_NUMBER_OF_PUP);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
 
-		   /* TBD - need to add PBS (PBS_RX_MASK_BIT | PBS_TX_MASK_BIT) */
 	maskTuneFunc = ( INIT_CONTROLLER_MASK_BIT |
                      SET_MEDIUM_FREQ_MASK_BIT |
                      WRITE_LEVELING_MASK_BIT |
                      LOAD_PATTERN_2_MASK_BIT |
                      READ_LEVELING_MASK_BIT |
-					 PBS_RX_MASK_BIT |
-					 PBS_TX_MASK_BIT |
+                     PBS_RX_MASK_BIT |
+                     PBS_TX_MASK_BIT |
                      SET_TARGET_FREQ_MASK_BIT |
                      WRITE_LEVELING_TF_MASK_BIT |
                      READ_LEVELING_TF_MASK_BIT |
                      WRITE_LEVELING_SUPP_TF_MASK_BIT |
                      CENTRALIZATION_RX_MASK_BIT |
                      CENTRALIZATION_TX_MASK_BIT);
-#else
-	maskTuneFunc = ( INIT_CONTROLLER_MASK_BIT |
-                     WRITE_LEVELING_MASK_BIT |
-                     LOAD_PATTERN_2_MASK_BIT |
-                     READ_LEVELING_MASK_BIT |
-                     CENTRALIZATION_RX_MASK_BIT |
-                     CENTRALIZATION_TX_MASK_BIT);
-#endif
 
+	/*Skip mid freq stages for 400Mhz DDR speed*/
+	if( (topologyMap->interfaceParams[firstActiveIf].memoryFreq == DDR_FREQ_400) ){
+		maskTuneFunc = (INIT_CONTROLLER_MASK_BIT |
+		                WRITE_LEVELING_MASK_BIT |
+		                LOAD_PATTERN_2_MASK_BIT |
+		                READ_LEVELING_MASK_BIT |
+		                CENTRALIZATION_RX_MASK_BIT |
+		                CENTRALIZATION_TX_MASK_BIT);
+	}
+
+    if( ckDelay == MV_PARAMS_UNDEFINED )
+        ckDelay = 150;
+    delayEnable = 1;
+    caDelay = 0;
+
+    /* update DGL parameters */
+    tuneParams.ckDelay = ckDelay;
+    tuneParams.PhyReg3Val = 0xA;
+    tuneParams.gRttNom = 0x44;
+    tuneParams.gDic = 0x2;
+    tuneParams.uiODTConfig = 0x120012;
+    tuneParams.gZpriData = 123;
+    tuneParams.gZnriData = 123;
+    tuneParams.gZpriCtrl = 74;
+    tuneParams.gZnriCtrl = 74;
+    tuneParams.gZpodtData = 45;
+    tuneParams.gZnodtData = 45;
+    tuneParams.gZpodtCtrl = 45;
+    tuneParams.gZnodtCtrl = 45;
+    tuneParams.gRttWR = 0x200;
+
+    CHECK_STATUS(ddr3TipTuneTrainingParams(devNum, &tuneParams));
+
+    /* frequency and general parameters */
     ddr3TipBc2GetMediumFreq(devNum, firstActiveIf, &mediumFreq);
     initFreq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
-    dfsLowFreq = 100;
+    freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 100;
     dfsLowPhy1 = PhyReg1Val;
     isPllBeforeInit = 0;
-    rlVersion = 1; /* new RL machine */
     useBroadcast = GT_FALSE; /* multicast */
     isCbeRequired = GT_TRUE;
 	calibrationUpdateControl = 2;
 
-	/* Delay Param */
-	if( ckDelay == -1 )
-		ckDelay = 150;
-	if( ckDelay_16 == -1 )
-		ckDelay_16 = 150;
-	delayEnable = 1;
-	caDelay = 0;
-
     return GT_OK;
 }
 
@@ -930,7 +952,7 @@
 /*****************************************************************************
 XSB External read
 ******************************************************************************/
-GT_STATUS    ddr3TipExtRead
+GT_STATUS    ddr3TipBC2ExtRead
 (
     GT_U32      devNum,
     GT_U32      interfaceId,
@@ -995,7 +1017,7 @@
 /*****************************************************************************
 XSB External write
 ******************************************************************************/
-GT_STATUS    ddr3TipExtWrite
+GT_STATUS    ddr3TipBC2ExtWrite
 (
     GT_U32      devNum,
     GT_U32      interfaceId,
@@ -1108,6 +1130,17 @@
 }
 
 /******************************************************************************
+* return 1 of core/DUNIT clock ration is 1 for given freq, 0 if clock ratios is 2:1
+*/
+static GT_U8    ddr3TipClockMode(GT_U32 frequency)
+{
+    frequency = frequency; /* avoid warnings */
+
+    return 2;
+}
+
+
+/******************************************************************************
 * Name:     ddr3TipTmSetDivider.
 * Desc:     Pll Divider of The Trafic Manager Unit
 * Args:
@@ -1230,10 +1263,12 @@
     switch (divider)
     {
         case 1:
-            writeData = 0x2;
+			/*Not 800 is a 667 only*/
+            writeData = (sarFreq==DDR_FREQ_800)?(0x2):(0x1);
             break;
         case 2:
-            writeData = 0x3;
+			/*Not 800 is a 667 only*/
+            writeData = (sarFreq==DDR_FREQ_800)?(0x3):(0x2);
             break;
         default:
             DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Error: Wrong divider %d\n", divider));
@@ -1375,7 +1410,7 @@
 /*****************************************************************************
 TM interface frequency Get
 ******************************************************************************/
-GT_STATUS ddr3TipTmGetInitFreq
+static GT_STATUS ddr3TipTmGetInitFreq
 (
 	GT_STATUS       devNum,
 	MV_HWS_DDR_FREQ *freq
@@ -1484,6 +1519,11 @@
 
     switch(sarFreq)
     {
+        case DDR_FREQ_400:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("No medium freq supported for 400Mhz\n"));
+            *freq = DDR_FREQ_400;
+            break;
+
         case DDR_FREQ_667:
 			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Medium DDR_FREQ_333\n"));
             *freq = DDR_FREQ_333;
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3BobK.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3BobK.c
new file mode 100755
index 0000000..5dc1d49
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3BobK.c
@@ -0,0 +1,1641 @@
+/*******************************************************************************
+*                Copyright 2001, Marvell International Ltd.
+* This code contains confidential information of Marvell semiconductor, inc.
+* no rights are granted herein under any patent, mask work right or copyright
+* of Marvell or any third party.
+* Marvell reserves the right at its sole discretion to request that this code
+* be immediately returned to Marvell. This code is provided "as is".
+* Marvell makes no warranties, express, implied or otherwise, regarding its
+* accuracy, completeness or performance.
+********************************************************************************
+* mvHwsDdr3BobK.c
+*
+* DESCRIPTION: DDR3 BobK configuration
+*
+* DEPENDENCIES:
+******************************************************************************/
+
+#define DEFINE_GLOBALS
+
+#include "mvDdr3TrainingIpStatic.h"
+#include "mvDdr3TrainingIpFlow.h"
+#include "mvDdrTrainingIpDb.h"
+#include "mvDdr3TrainingIp.h"
+#include "mvDdr3TrainingIpDef.h"
+#include "mvDdr3TrainingIpPrvIf.h"
+#include "mvDdr3LoggingDef.h"
+#include "mvHwsDdr3BobK.h"
+#if !defined(CPSS_BUILD)
+#include "ddr3_msys_bobk.h"
+#endif
+
+/************************** definitions ******************************/
+#define BOBK_NUM_BYTES                   (3)
+
+#define BOBK_CLIENT_FIELD(client)		(client << 15)
+#define BOBK_GET_CLIENT_FIELD(interfaceAccess,interfaceId) ((interfaceAccess == ACCESS_TYPE_MULTICAST) ? BOBK_CLIENT_FIELD(MULTICAST_ID):BOBK_CLIENT_FIELD(interfaceId))
+#define BOBK_XSB_MAPPING(interfaceId, interfaceAccess, regaddr)   (regaddr+ XSB_BASE_ADDR + BOBK_GET_CLIENT_FIELD(interfaceAccess,interfaceMap[interfaceId].client))
+
+#if defined(CPSS_BUILD)
+
+#define REG_DEVICE_SAR0_ADDR                        0xF8200
+#define REG_DEVICE_SAR1_ADDR                        0xF8204
+#define REG_DEVICE_SAR1_OVERRIDE_ADDR               0xF82D8
+#define PLL0_CNFIG_OFFSET         					21
+#define PLL0_CNFIG_MASK           					0x7
+#define PLL1_CNFIG_OFFSET         					18
+#define PLL1_CNFIG_MASK           					0x7
+
+#define CS_CBE_VALUE(csNum)   (csCbeReg[csNum])
+#endif
+
+#define BOBK_CLIENT_MAPPING(interfaceId, regaddr) ((regaddr << 2)+ CLIENT_BASE_ADDR + BOBK_CLIENT_FIELD(interfaceMap[interfaceId].client))
+
+#define TM_PLL_REG_DATA(a,b,c)  ((a << 12) + (b << 8) + (c << 2))
+#define R_MOD_W(writeData,readData,mask) ((writeData & mask) | (readData & (~mask)))
+
+#define CETUS_DEV_ID   0xBE00
+#define CAELUM_DEV_ID  0xBC00
+
+/************************** pre-declaration ******************************/
+
+static GT_STATUS ddr3TipBobKGetMediumFreq
+(
+    GT_U32          devNum,
+	GT_U32			interfaceId,
+    MV_HWS_DDR_FREQ *freq
+);
+
+GT_STATUS    ddr3TipBobKExtRead
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+);
+
+GT_STATUS    ddr3TipBobKExtWrite
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+);
+
+GT_STATUS ddr3TipBobKSetDivider
+(
+	GT_U8							devNum,
+	GT_U32                			interfaceId,
+    MV_HWS_DDR_FREQ                 freq
+);
+
+static GT_STATUS ddr3TipTmSetDivider
+(
+	GT_U8							devNum,
+	GT_U32                			interfaceId,
+    MV_HWS_DDR_FREQ                 frequency
+);
+
+static GT_STATUS ddr3TipCpuSetDivider
+(
+	GT_U8							devNum,
+	GT_U32                			interfaceId,
+    MV_HWS_DDR_FREQ                 frequency
+);
+
+GT_STATUS ddr3BobKUpdateTopologyMap
+(
+    GT_U32 devNum,
+    MV_HWS_TOPOLOGY_MAP* topologyMap
+);
+
+GT_STATUS ddr3TipBobKGetInitFreq
+(
+    GT_U8       	devNum,
+	GT_U32			interfaceId,
+    MV_HWS_DDR_FREQ* freq
+);
+
+static GT_STATUS ddr3TipTmGetInitFreq
+(
+    GT_STATUS       devNum,
+    MV_HWS_DDR_FREQ *freq
+);
+
+static GT_STATUS ddr3TipCpuGetInitFreq
+(
+    GT_STATUS       devNum,
+    MV_HWS_DDR_FREQ *freq
+);
+
+GT_STATUS    ddr3TipBobKRead
+(
+    GT_U8                 devNum,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+);
+
+GT_STATUS    ddr3TipBobKWrite
+(
+    GT_U8                 devNum,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+);
+GT_STATUS    ddr3TipBobKIFRead
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+);
+
+GT_STATUS    ddr3TipBobKIFWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+);
+
+GT_STATUS ddr3TipBobKIsfAccessDone
+(
+    GT_U32 devNum,
+    GT_U32 interfaceId
+);
+
+GT_STATUS ddr3TipBobKGetDeviceInfo
+(
+	GT_U8      devNum,
+	MV_DDR3_DEVICE_INFO * infoPtr
+);
+
+GT_STATUS    ddr3TipBobKTMWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+);
+/************************** Globals ******************************/
+
+extern GT_U32 maskTuneFunc;
+extern GT_U32 freqVal[];
+extern MV_HWS_DDR_FREQ mediumFreq;
+extern MV_HWS_TOPOLOGY_MAP *topologyMap;
+extern GT_U32 firstActiveIf;
+extern MV_HWS_DDR_FREQ initFreq;
+extern GT_U32 dfsLowFreq;
+extern GT_U32 dfsLowPhy1;
+extern GT_U32  PhyReg1Val;
+extern GT_U32 isPllBeforeInit;
+extern GT_U32 useBroadcast;
+extern GT_U32 isCbeRequired;
+extern GT_U32 delayEnable, ckDelay,caDelay;
+extern GT_U8 debugTrainingAccess;
+extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
+extern GT_U32 dfsLowFreq;
+
+GT_U32 debugBobK = 0;
+GT_U32  pipeMulticastMask;
+
+#if defined(CPSS_BUILD)
+static GT_U32 csCbeReg[]=
+{
+    0xE , 0xD, 0xB, 0x7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+GT_U32 devId, hwDdrIfMask, hwMaxDdrIfNum;
+
+static MV_DFX_ACCESS interfaceMap[] =
+{
+	/* Pipe	Client*/
+	{   0,	 16 },
+	{   3,	 18	},
+	{   1,	 10 },
+	{   3,	 1	},
+    {   0,	 0	} /* in BOBK interface 4 doesn't belong to TM*/
+};
+#endif
+static GT_U8 bobKBwPerFreq[DDR_FREQ_LIMIT] =
+{
+    0x3, /*DDR_FREQ_LOW_FREQ*/
+    0x4, /*DDR_FREQ_400*/
+    0x4, /*DDR_FREQ_533*/
+    0x5, /*DDR_FREQ_667*/
+    0x5, /*DDR_FREQ_800*/
+    0x5, /*DDR_FREQ_933,*/
+    0x5, /*DDR_FREQ_1066*/
+    0x3, /*DDR_FREQ_311*/
+    0x3, /*DDR_FREQ_333*/
+    0x4,  /*DDR_FREQ_467*/
+    0x5, /*DDR_FREQ_850*/
+    0x5,  /*DDR_FREQ_600*/
+    0x3,  /*DDR_FREQ_300*/
+	0x5, /*DDR_FREQ_900*/
+	0x3 /*DDR_FREQ_360*/
+};
+
+static GT_U8 bobKRatePerFreq[DDR_FREQ_LIMIT] =
+{
+   0x1, /*DDR_FREQ_LOW_FREQ,*/
+   0x2, /*DDR_FREQ_400,*/
+   0x2, /*DDR_FREQ_533,*/
+   0x2, /*DDR_FREQ_667,*/
+   0x2, /*DDR_FREQ_800,*/
+   0x3, /*DDR_FREQ_933,*/
+   0x3, /*DDR_FREQ_1066,*/
+   0x1, /*DDR_FREQ_311*/
+   0x1, /*DDR_FREQ_333*/
+   0x2, /*DDR_FREQ_467*/
+   0x2, /*DDR_FREQ_850*/
+   0x2, /*DDR_FREQ_600*/
+   0x1, /*DDR_FREQ_300*/
+   0x3,  /*DDR_FREQ_900*/
+   0x1  /*DDR_FREQ_360*/
+};
+
+/* Bit mapping (for PBS) */
+GT_U32 bobKDQbitMap2Phypin[] =
+{
+/*#warning "DQ mapping is updated for Interface 0 and 4 only!" !!!*/
+	    /* Interface 0 */
+        2,0,3,9,7,8,6,1 , /* dq[0:7]   */
+        3,2,1,6,0,9,7,8 , /* dq[8:15]  */
+        9,6,3,2,1,7,0,8 , /* dq[16:23] */
+        3,1,7,2,0,8,9,6 , /* dq[24:31] */
+        0,0,0,0,0,0,0,0 , /* dq[ECC]   */
+
+	    /* Interface 1 */
+	    9,0,7,2,8,6,3,1 , /* dq[0:7]   */
+	    9,0,1,6,8,3,2,7 , /* dq[8:15]  */
+	    0,7,1,9,6,2,3,8 , /* dq[16:23] */
+	    9,0,8,3,7,6,2,1 , /* dq[24:31] */
+        0,0,0,0,0,0,0,0 , /* dq[ECC]   */
+
+	    /* Interface 2 */
+	    0,0,0,0,0,0,0,0 , /* dq[0:7]   */
+	    0,0,0,0,0,0,0,0 , /* dq[8:15]  */
+	    0,0,0,0,0,0,0,0 , /* dq[16:23] */
+	    0,0,0,0,0,0,0,0 , /* dq[24:31] */
+        0,0,0,0,0,0,0,0 , /* dq[ECC]   */
+
+	    /* Interface 3 */
+	    6,2,8,9,0,1,7,3 , /* dq[0:7]   */
+	    1,3,7,9,0,2,8,6 , /* dq[8:15]  */
+	    2,0,7,1,8,9,6,3 , /* dq[16:23] */
+	    1,6,8,2,0,7,3,9 , /* dq[24:31] */
+        0,0,0,0,0,0,0,0 , /* dq[ECC]   */
+
+        /* Interface 4 */
+	    1,9,8,3,0,7,2,6 , /* dq[0:7]   */
+	    3,2,8,1,9,6,7,0 , /* dq[8:15]  */
+	    0,6,2,1,9,3,8,7 , /* dq[16:23] */
+	    0,6,1,8,3,9,7,2 , /* dq[24:31] */
+        0,1,2,3,6,7,8,9   /* dq[ECC]   */
+};
+
+#if defined(CPSS_BUILD)
+
+MV_HWS_TOPOLOGY_MAP bobKTopologyMap[] =
+{
+    /* 1st board  - CETUS*/
+    {
+    0x1, /* active interfaces */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x1,0,0,0}, {0x1,0,0,0}, {0x2,1,0,0}, {0x2,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
+    0xF  /* Buses mask */
+    },
+    /* 2nd board  - Caelum*/
+    {
+    0xB, /* active interfaces */
+    /*cs_mask, mirror, dqs_swap, ck_swap X PUPs                         speed_bin           memory_width  mem_size  frequency  casL casWL      temperature */
+ {  {{{0x2,0,0,0}, {0x2,0,0,0}, {0x1,1,0,0}, {0x1,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x2,0,0,0}, {0x2,0,0,0}, {0x1,1,0,0}, {0x1,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x2,0,0,0}, {0x2,0,0,0}, {0x1,1,0,0}, {0x1,1,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} ,
+    {{{0x1,1,0,0}, {0x1,1,0,0}, {0x2,0,0,0}, {0x2,0,0,0}, {0,0,0,0}}, SPEED_BIN_DDR_1866M, BUS_WIDTH_16 , MEM_4G, DDR_FREQ_667, 0 ,   0 , MV_HWS_TEMP_HIGH} },
+    0xF  /* Buses mask */
+    }
+};
+#endif
+
+static GT_U8    ddr3TipClockMode( GT_U32 frequency );
+
+/************************** Server Access ******************************/
+GT_STATUS ddr3TipBobKServerRegWrite
+(
+	GT_U32 devNum,
+	GT_U32 regAddr,
+	GT_U32 dataValue
+)
+{
+#ifdef ASIC_SIMULATION
+    /* avoid warnings */
+    devNum = devNum;
+    regAddr = regAddr;
+    dataValue = dataValue;
+
+	return GT_OK;
+#else
+	return hwsServerRegSetFuncPtr(devNum, regAddr, dataValue);
+#endif
+}
+
+GT_STATUS ddr3TipBobKServerRegRead
+(
+	GT_U32 devNum,
+	GT_U32 regAddr,
+	GT_U32 *dataValue,
+	GT_U32 regMask
+)
+{
+#ifdef ASIC_SIMULATION
+    /* avoid warnings */
+    devNum = devNum;
+    regAddr = regAddr;
+    regMask = regMask;
+
+	*dataValue = 0;
+#else
+	hwsServerRegGetFuncPtr(devNum, regAddr, dataValue);
+
+
+	*dataValue  = *dataValue & regMask;
+#endif
+	return GT_OK;
+}
+
+/**********************************************************************************/
+
+GT_STATUS ddr3TipBobKGetFreqConfig
+(
+	GT_U8							devNum,
+    MV_HWS_DDR_FREQ                 freq,
+	MV_HWS_TIP_FREQ_CONFIG_INFO		*freqConfigInfo
+)
+{
+    devNum = devNum; /* avoid warnings */
+
+    if (bobKBwPerFreq[freq] == 0xff)
+    {
+        return GT_NOT_SUPPORTED;
+    }
+
+    if (freqConfigInfo == NULL)
+    {
+        return GT_BAD_PARAM;
+    }
+
+    freqConfigInfo->bwPerFreq = bobKBwPerFreq[freq];
+    freqConfigInfo->ratePerFreq = bobKRatePerFreq[freq];
+
+    freqConfigInfo->isSupported = GT_TRUE;
+
+    return GT_OK;
+}
+#if defined(CPSS_BUILD)
+/*****************************************************************************
+Enable Pipe
+******************************************************************************/
+static GT_STATUS    ddr3TipPipeEnable
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_BOOL               enable
+)
+{
+    GT_U32 dataValue=0, pipeEnableMask = 0;
+
+
+    if (enable == GT_FALSE)
+    {
+        pipeEnableMask = 0;
+    }
+    else
+    {
+       if (interfaceAccess == ACCESS_TYPE_MULTICAST)
+        {
+            pipeEnableMask = pipeMulticastMask;
+        }
+        else
+        {
+            pipeEnableMask = (1 << interfaceMap[interfaceId].pipe);
+        }
+    }
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, PIPE_ENABLE_ADDR, &dataValue, MASK_ALL_BITS));
+    dataValue = (dataValue & (~0xFF)) | pipeEnableMask;
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, PIPE_ENABLE_ADDR, dataValue));
+    return GT_OK;
+}
+
+static void ddr3TipIsUnicastAccess( GT_U8 devNum,GT_U32* interfaceId, MV_HWS_ACCESS_TYPE* interfaceAccess)
+{
+	GT_U32 indexCnt, totalCnt = 0 , interfaceTmp = 0;
+    MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
+
+	if (*interfaceAccess == ACCESS_TYPE_MULTICAST)
+	{
+		for(indexCnt = 0; indexCnt < MAX_INTERFACE_NUM; indexCnt++)
+		{
+			if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) !=  0)
+			{
+				totalCnt++;
+				interfaceTmp = indexCnt;
+				continue;
+			}
+		}
+		if (totalCnt == 1) {
+			*interfaceAccess = ACCESS_TYPE_UNICAST;
+			*interfaceId = interfaceTmp;
+		}
+	}
+}
+
+/******************************************************************************
+* Name:     ddr3TipBobKSelectTMDdrController.
+* Desc:     Enable/Disable access to Marvell's server.
+* Args:     devNum     - device number
+*           enable        - whether to enable or disable the server
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKSelectTMDdrController
+(
+    GT_U8    devNum,
+    GT_BOOL  enable
+)
+{
+    GT_U32 interfaceId = 0, dataValue = 0;
+#ifndef ASIC_SIMULATION
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8240 ,  &devId, MASK_ALL_BITS));
+#else
+    devId = 0xBC00; /* CAELUM_DEV_ID */
+#endif
+    if ((devId & 0xFFFF) == CETUS_DEV_ID )
+    {
+        /* IN Cetus TM has only 1 IF #0*/
+        hwMaxDdrIfNum = 1;
+        hwDdrIfMask   = 1;
+    }
+    else if ((devId &0xFFFF) == CAELUM_DEV_ID )
+    {
+        /* in Caelum TM may use 3 IFs 0,1,and 3*/
+        hwMaxDdrIfNum = 4;
+        hwDdrIfMask   = 0xB;
+    }
+    else
+          mvPrintf ("Unsupported device ID %x\n", devId);
+
+    for (interfaceId = 0; interfaceId < hwMaxDdrIfNum; interfaceId++)
+	{
+        if(IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  0)/* if the interface doesnt exixst in HW :*/
+            continue;
+        else /* interface exist in HW*/
+        {
+            ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
+			if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  0)
+			{
+				 /*disable in-active interfaces (so they won't be accessed upon multicast)*/
+				CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), &dataValue, MASK_ALL_BITS));
+				dataValue &= ~0x40;
+				CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), dataValue));
+				continue;
+			}
+				/* Enable relevant Pipe */
+			pipeMulticastMask |= (1 << interfaceMap[interfaceId].pipe);
+			/* multicast Macro is subscribed to Multicast 0x1D */
+			CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), &dataValue, MASK_ALL_BITS));
+			dataValue |= 0x40;
+			CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_CLIENT_MAPPING(interfaceId, CLIENT_CTRL_REG), dataValue));
+
+			ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_FALSE);
+
+		}
+    }
+		/* enable access to relevant pipes (according to the pipe mask) */
+	ddr3TipPipeEnable(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, GT_TRUE);
+
+   if (enable)
+    {
+       /* Enable DDR Tuning */
+
+        CHECK_STATUS(ddr3TipBobKTMWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, READ_BUFFER_SELECT_REG,  0x8000, MASK_ALL_BITS));
+        /* configure duplicate CS */
+		CHECK_STATUS(ddr3TipBobKTMWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, CS_ENABLE_REG,  0x4A/*Haim 0x42*/, MASK_ALL_BITS));
+    }
+    else
+    {
+        /* Disable DDR Tuning Select */
+        CHECK_STATUS(ddr3TipBobKTMWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, CS_ENABLE_REG,  0x2, MASK_ALL_BITS));
+        CHECK_STATUS(ddr3TipBobKTMWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, READ_BUFFER_SELECT_REG, 0,MASK_ALL_BITS));
+   }
+   return GT_OK;
+}
+
+/*****************************************************************************
+Check if Dunit access is done
+******************************************************************************/
+
+GT_STATUS    ddr3TipBobKIsAccessDone
+(
+    GT_U8 devNum,
+    GT_32 interfaceId
+)
+{
+    GT_U32 rdData = 1, cnt = 0;
+
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), &rdData, MASK_ALL_BITS));
+	rdData &= 1;
+
+	while(rdData != 0)
+    {
+		if (cnt++ >= MAX_POLLING_ITERATIONS)
+            break;
+        CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), &rdData, MASK_ALL_BITS));
+        rdData &= 1;
+#ifdef ASIC_SIMULATION
+        rdData = 0;/* no more iterations needed */
+#endif /*ASIC_SIMULATION*/
+    }
+    if (cnt < MAX_POLLING_ITERATIONS)
+    {
+		return GT_OK;
+    }
+    else
+    {
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO,("AccessDone fail: if = %d\n",interfaceId));
+        return GT_FAIL;
+    }
+}
+
+/******************************************************************************/
+GT_STATUS    ddr3TipBobKTMRead
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+)
+{
+    GT_U32 dataValue = 0, startIf, endIf;
+    MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
+
+   	ddr3TipIsUnicastAccess(devNum, &interfaceId, &interfaceAccess);
+
+    if (interfaceAccess == ACCESS_TYPE_UNICAST)
+    {
+        startIf = interfaceId;
+        endIf = interfaceId;
+    }
+    else
+    {
+        startIf = 0;
+        endIf = MAX_INTERFACE_NUM-1;
+    }
+
+    for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
+    {
+        if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  0)
+        {
+            continue;
+        }
+        ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CTRL_1_REG) ,TRAINING_ID));
+
+        /*working with XSB client InterfaceNum  Write Interface ADDR as data to XSB address C*/
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_ADDRESS_REG), regAddr));
+        dataValue = ((GT_U32)(TARGET_INT << 19)) + (BYTE_EN << 11) + (BOBK_NUM_BYTES << 4) + (CMD_READ << 2) +(INTERNAL_ACCESS_PORT  << 1) + EXECUTING;
+        /*Write Interface COMMAND as data to XSB address 8 */
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_CMD_REG), dataValue));
+
+		CHECK_STATUS(ddr3TipBobKIsAccessDone(devNum, interfaceId));
+
+		/* consider that input data is always a vector, and for unicast the writing will be in the interface index in vector */
+        CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, ACCESS_TYPE_UNICAST, XSB_DATA_REG), &data[interfaceId], mask));
+        if (debugBobK >= 2)
+        {
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("DunitRead   0x%x: 0x%x (mask 0x%x)\n",  regAddr,  *data, mask));
+        }
+        /*ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_FALSE);*/
+    }
+    return GT_OK;
+}
+
+/******************************************************************************/
+GT_STATUS    ddr3TipBobKTMWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+)
+{
+    GT_U32 dataCmd = 0, uiDataRead = 0, uiReadInterfaceId=0;
+    GT_U32 dataRead[MAX_INTERFACE_NUM];
+	GT_U32 startIf, endIf;
+    MV_HWS_TOPOLOGY_MAP *topologyMap = ddr3TipGetTopologyMap(devNum);
+
+   	ddr3TipIsUnicastAccess(devNum, &interfaceId, &interfaceAccess);
+    if (mask != MASK_ALL_BITS)
+    {
+        /* if all bits should be written there is no need for read-modify-write */
+        if (interfaceAccess == ACCESS_TYPE_MULTICAST)
+        {
+            CHECK_STATUS(ddr3TipGetFirstActiveIf(devNum, topologyMap->interfaceActiveMask, &uiReadInterfaceId));
+        }
+        else
+        {
+            uiReadInterfaceId = interfaceId;
+        }
+        if (debugBobK >= 2)
+        {
+            DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("ddr3TipBobKTMWrite active interface = %d\n",uiReadInterfaceId));
+        }
+
+        CHECK_STATUS(ddr3TipBobKTMRead(devNum, ACCESS_TYPE_UNICAST, uiReadInterfaceId,regAddr,dataRead,MASK_ALL_BITS));
+        uiDataRead = dataRead[uiReadInterfaceId];
+        dataValue = (uiDataRead & (~mask)) | (dataValue & mask);
+    }
+    ddr3TipPipeEnable(devNum, interfaceAccess, interfaceId, GT_TRUE);
+    /* set the ID */
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CTRL_1_REG) , TRAINING_ID));
+
+    /*working with XSB multicast client , Write Interface ADDR as data to XSB address C */
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_ADDRESS_REG), regAddr));
+    /*Write Interface DATA as data to XSB address 0x10.*/
+    if (debugBobK >= 1)
+    {
+        DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Dunit Write: interface %d  access %d Address 0x%x Data 0x%x\n", interfaceId, interfaceAccess, regAddr, dataValue));
+    }
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_DATA_REG),  dataValue));
+    dataCmd = ((GT_U32)(TARGET_INT << 19)) + (BYTE_EN << 11) + (BOBK_NUM_BYTES << 4) +  (CMD_WRITE << 2) + (INTERNAL_ACCESS_PORT << 1);
+    /*Write Interface COMMAND as data to XSB address 8
+      Execute an internal write to xBar port1 */
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CMD_REG), dataCmd));
+	dataCmd |= EXECUTING;
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_CMD_REG), dataCmd));
+
+	 /*check that write is completed; the test should be done per interface */
+	if (interfaceAccess == ACCESS_TYPE_MULTICAST)
+    {
+        startIf = 0;
+        endIf = hwMaxDdrIfNum-1;
+    }
+    else
+    {
+        startIf = interfaceId;
+        endIf = interfaceId;
+    }
+
+    for(interfaceId = startIf; interfaceId <= endIf; interfaceId++)
+    {
+        VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
+		ddr3TipPipeEnable(devNum, ACCESS_TYPE_UNICAST, interfaceId, GT_TRUE);
+		CHECK_STATUS(ddr3TipBobKIsAccessDone(devNum, interfaceId));
+	}
+   /* ddr3TipPipeEnable(devNum, interfaceAccess, interfaceId, GT_FALSE);*/
+    return GT_OK;
+}
+#else /*!defined(CPSS_BUILD)*/
+/******************************************************************************
+* Name:     ddr3TipBobKWrite.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKWrite
+(
+    GT_U8                 devNum,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+)
+{
+	GT_U32 uiDataRead;
+#ifdef WIN32
+    return GT_OK;
+#endif
+    if (mask != MASK_ALL_BITS)
+    {
+		CHECK_STATUS(ddr3TipBobKRead(devNum, regAddr,  &uiDataRead, MASK_ALL_BITS));
+        dataValue = (uiDataRead & (~mask)) | (dataValue & mask);
+    }
+
+    if (debugBobK >= 1)
+    {
+       mvPrintf("Dunit Write: Address 0x%x Data 0x%x\n", regAddr, dataValue);
+    }
+
+    MV_REG_WRITE(regAddr, dataValue);
+	if (debugBobK >= 2)
+		mvPrintf("write: 0x%x = 0x%x\n",regAddr,dataValue);
+
+    return GT_OK;
+}
+
+
+
+/******************************************************************************
+* Name:     ddr3TipBobKRead.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKRead
+(
+    GT_U8                 devNum,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+)
+{
+#ifdef WIN32
+     return GT_OK;
+#endif
+
+	*data = MV_REG_READ(regAddr) & mask;
+	if (debugBobK >= 2)
+	{
+		mvPrintf("DunitRead   0x%x: 0x%x (mask 0x%x)\n",  regAddr,  *data, mask);
+	}
+
+    return GT_OK;
+}
+/******************************************************************************
+* Name:     ddr3TipBobKIFWrite.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKIFWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                dataValue,
+    GT_U32                mask
+)
+{
+    if (interfaceAccess == ACCESS_TYPE_MULTICAST)
+        interfaceId = 4;
+ 
+    return(ddr3TipBobKWrite(devNum,regAddr,dataValue,mask));
+}
+
+
+
+/******************************************************************************
+* Name:     ddr3TipBobKIFRead.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKIFRead
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+)
+{
+    if (interfaceAccess == ACCESS_TYPE_MULTICAST)
+        interfaceId = 4;
+    return ddr3TipBobKRead(devNum, regAddr, &data[interfaceId], mask);
+}
+
+#endif
+
+/******************************************************************************
+* Name:     ddr3TipBobKSelectCpuDdrController.
+* Desc:     Enable/Disable access to Marvell's server.
+* Args:     devNum     - device number
+*           enable        - whether to enable or disable the server
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS    ddr3TipBobKSelectCPUDdrController
+(
+    GT_U8    devNum,
+    GT_BOOL  enable
+)
+{
+    /* avoid warnings */
+    devNum =devNum;
+    enable = enable;
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3TipInitBobKSilicon.
+* Desc:     init Training SW DB.
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+static GT_STATUS ddr3TipInitBobKSilicon
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+)
+{
+    MV_HWS_TIP_CONFIG_FUNC_DB   configFunc;
+	MV_HWS_TOPOLOGY_MAP*        topologyMap = ddr3TipGetTopologyMap(devNum);
+    GT_TUNE_TRAINING_PARAMS     tuneParams;
+	GT_U8 numOfBusPerInterface;
+
+	if(topologyMap == NULL)
+	{
+		return GT_NOT_INITIALIZED;
+	}
+
+#if 0
+	ddr3TipBobKGetInterfaceMap((GT_U8)devNum);
+#endif
+
+    boardId = boardId; /* avoid warnings */
+
+#if defined(CPSS_BUILD)
+    numOfBusPerInterface = 4; /* TM has only 4 buses*/
+    configFunc.tipDunitReadFunc = ddr3TipBobKTMRead;
+    configFunc.tipDunitWriteFunc = ddr3TipBobKTMWrite;
+    configFunc.tipDunitMuxSelectFunc = ddr3TipBobKSelectTMDdrController;
+
+#else
+    numOfBusPerInterface = 5; /*MSYS may have 5 buses*/
+    configFunc.tipDunitReadFunc = ddr3TipBobKIFRead;
+    configFunc.tipDunitWriteFunc = ddr3TipBobKIFWrite;
+    configFunc.tipDunitMuxSelectFunc = ddr3TipBobKSelectCPUDdrController;
+#endif
+
+    configFunc.tipExternalRead  = ddr3TipBobKExtRead;
+	configFunc.tipExternalWrite = ddr3TipBobKExtWrite;
+
+    configFunc.tipGetFreqConfigInfoFunc = ddr3TipBobKGetFreqConfig;
+    configFunc.tipSetFreqDividerFunc = ddr3TipBobKSetDivider;
+    configFunc.tipGetDeviceInfoFunc = ddr3TipBobKGetDeviceInfo;
+	configFunc.tipGetTemperature = NULL;
+	configFunc.tipGetClockRatio = ddr3TipClockMode;
+
+    mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
+
+	/* register bit mapping (for PBS) */
+	ddr3TipRegisterDqTable(devNum, bobKDQbitMap2Phypin);
+
+	/*Set device attributes*/
+	ddr3TipDevAttrInit(devNum);
+#if defined(CPSS_BUILD)
+	ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_2);   /* TM DDR (Non-ECC) TIP version 2*/
+#else
+    ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_3);   /* BOBK MSYS DDR TIP version 3  */
+#endif
+	ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_NEGATIVE);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, numOfBusPerInterface);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
+
+#if defined(CPSS_BUILD)
+	maskTuneFunc = ( INIT_CONTROLLER_MASK_BIT |
+					SET_MEDIUM_FREQ_MASK_BIT |
+					WRITE_LEVELING_MASK_BIT |
+					LOAD_PATTERN_2_MASK_BIT |
+					READ_LEVELING_MASK_BIT |
+					SET_TARGET_FREQ_MASK_BIT |
+					WRITE_LEVELING_TF_MASK_BIT |
+					READ_LEVELING_TF_MASK_BIT |
+					WRITE_LEVELING_SUPP_TF_MASK_BIT |
+					CENTRALIZATION_RX_MASK_BIT |
+					CENTRALIZATION_TX_MASK_BIT);
+#else
+   maskTuneFunc =     (/*SET_LOW_FREQ_MASK_BIT |
+						LOAD_PATTERN_MASK_BIT |*/
+						SET_MEDIUM_FREQ_MASK_BIT |
+						WRITE_LEVELING_MASK_BIT |
+                        LOAD_PATTERN_2_MASK_BIT |
+						WRITE_LEVELING_SUPP_MASK_BIT |
+						READ_LEVELING_MASK_BIT |
+						PBS_RX_MASK_BIT |
+						PBS_TX_MASK_BIT |
+						SET_TARGET_FREQ_MASK_BIT |
+						WRITE_LEVELING_TF_MASK_BIT |
+						WRITE_LEVELING_SUPP_TF_MASK_BIT |
+						READ_LEVELING_TF_MASK_BIT |
+						CENTRALIZATION_RX_MASK_BIT |
+						CENTRALIZATION_TX_MASK_BIT
+						);
+#endif
+	/*Skip mid freq stages for 400Mhz DDR speed*/
+	if( (topologyMap->interfaceParams[firstActiveIf].memoryFreq == DDR_FREQ_400) ){
+		maskTuneFunc = ( WRITE_LEVELING_MASK_BIT |
+		                LOAD_PATTERN_2_MASK_BIT |
+		                READ_LEVELING_MASK_BIT |
+		                CENTRALIZATION_RX_MASK_BIT |
+		                CENTRALIZATION_TX_MASK_BIT);
+	}
+
+    if( ckDelay == MV_PARAMS_UNDEFINED )
+        ckDelay = 150;
+    delayEnable = 1;
+    caDelay = 0;
+
+    /* update DGL parameters */
+    tuneParams.ckDelay = ckDelay;
+    tuneParams.PhyReg3Val = 0xA;
+    tuneParams.gRttNom = 0x44;
+    tuneParams.gDic = 0x2;
+    tuneParams.uiODTConfig = 0x120012;
+    tuneParams.gZpriData = 123;
+    tuneParams.gZnriData = 123;
+    tuneParams.gZpriCtrl = 74;
+    tuneParams.gZnriCtrl = 74;
+    tuneParams.gZpodtData = 45;
+    tuneParams.gZnodtData = 45;
+    tuneParams.gZpodtCtrl = 45;
+    tuneParams.gZnodtCtrl = 45;
+    tuneParams.gRttWR = 0; /*0x400;0x0;*/
+
+    CHECK_STATUS(ddr3TipTuneTrainingParams(devNum, &tuneParams));
+
+    /* frequency and general parameters */
+    ddr3TipBobKGetMediumFreq(devNum, firstActiveIf, &mediumFreq);
+    initFreq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
+	freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 130;
+    dfsLowPhy1 = PhyReg1Val;
+	calibrationUpdateControl = 1;
+
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3BobKUpdateTopologyMap.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS ddr3BobKUpdateTopologyMap(GT_U32 devNum, MV_HWS_TOPOLOGY_MAP* topologyMap)
+{
+    GT_U32 interfaceId;
+    MV_HWS_DDR_FREQ freq;
+
+	DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("topologyMap->interfaceActiveMask is 0x%x\n", topologyMap->interfaceActiveMask));
+
+    for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM; interfaceId++) {
+    	if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) ==  GT_FALSE)
+    	    continue;
+		CHECK_STATUS(ddr3TipBobKGetInitFreq((GT_U8)devNum, interfaceId, &freq));
+        topologyMap->interfaceParams[interfaceId].memoryFreq = freq;
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Update topology frequency for interface %d to %d\n",interfaceId, freq));
+   	}
+
+	/* re-calc topology parameters according to topology updates (if needed) */
+	CHECK_STATUS(mvHwsDdr3TipLoadTopologyMap(devNum, topologyMap));
+
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3TipInitBobK.
+* Desc:     init Training SW DB and updates DDR topology.
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS ddr3TipInitBobK
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+)
+{
+	MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
+
+	if(NULL == topologyMap)
+	{
+		#if defined(CPSS_BUILD)
+		/* for CPSS, since topology is not always initialized, it is
+		   needed to set it to default topology */
+		topologyMap = &bobKTopologyMap[boardId];
+        mvPrintf ("board ID %d, active interface mask = %x\n",boardId,topologyMap->interfaceActiveMask);
+		#else
+		return GT_FAIL;
+		#endif
+	}
+
+	CHECK_STATUS(ddr3BobKUpdateTopologyMap(devNum, topologyMap));
+
+    ddr3TipInitBobKSilicon(devNum, boardId);
+    return GT_OK;
+}
+
+#if defined(CPSS_BUILD)
+/*****************************************************************************
+Data Reset
+******************************************************************************/
+static GT_STATUS    ddr3TipDataReset
+(
+    GT_U32                  devNum,
+    MV_HWS_ACCESS_TYPE      interfaceAccess,
+    GT_U32                  interfaceId
+)
+{
+    GT_STATUS retVal;
+    GT_U32  uiWordCnt;
+
+    for(uiWordCnt = 0; uiWordCnt < 8 ; uiWordCnt++)
+    {
+        /*Write Interface DATA as data to XSB address 0x10.*/
+        retVal = ddr3TipBobKServerRegWrite(devNum,     BOBK_XSB_MAPPING(interfaceId, interfaceAccess, XSB_DATA_REG+(uiWordCnt * 4)), 0xABCDEF12);
+        if (retVal != GT_OK)
+        {
+            return retVal;
+        }
+    }
+    return GT_OK;
+}
+
+/*****************************************************************************
+XSB External read
+******************************************************************************/
+GT_STATUS    ddr3TipBobKExtRead
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+)
+{
+    GT_U32 burstNum, wordNum , dataValue;
+	GT_U32 cntPoll;
+    MV_HWS_ACCESS_TYPE accessType = ACCESS_TYPE_UNICAST;
+    /*DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("=== EXTERNAL READ ==="));*/
+
+    ddr3TipPipeEnable((GT_U8)devNum, accessType, interfaceId, GT_TRUE);
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_CTRL_0_REG) ,EXT_TRAINING_ID));
+
+    for(burstNum=0 ; burstNum < numOfBursts; burstNum++)
+    {
+        ddr3TipDataReset(devNum, ACCESS_TYPE_UNICAST, interfaceId);
+        /*working with XSB client InterfaceNum  Write Interface ADDR as data to XSB address C*/
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_ADDRESS_REG + (burstNum * 32)), regAddr));
+        if (isCbeRequired ==  GT_TRUE)
+        {
+            /*CS_CBE_VALUE(0)*/
+            dataValue = CS_CBE_VALUE(0) << 19;
+        }
+        else
+        {
+            dataValue = (GT_U32)(TARGET_EXT << 19);
+        }
+        dataValue |= (BYTE_EN << 11) + (NUM_BYTES_IN_BURST << 4) + (ACCESS_EXT << 3);
+        /*Write Interface COMMAND as data to XSB address 8 */
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG),   dataValue));
+        dataValue |= EXECUTING;
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG),   dataValue));
+
+		for(cntPoll=0; cntPoll < MAX_POLLING_ITERATIONS; cntPoll++)
+		{
+			CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), &dataValue, 0x1));
+
+			if (dataValue == 0)
+				break;
+		}
+
+		if (cntPoll >= MAX_POLLING_ITERATIONS)
+		{
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("No Done indication for DDR Read\n", dataValue));
+			return GT_NOT_READY;
+		}
+
+        for(wordNum = 0; wordNum < EXT_ACCESS_BURST_LENGTH /*s_uiNumOfBytesInBurst/4*/; wordNum++)
+        {
+            CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_DATA_REG + (wordNum * 4)), &data[wordNum], MASK_ALL_BITS));
+            DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("ddr3TipExtRead data 0x%x \n",data[wordNum]));
+        }
+    }
+    return GT_OK;
+}
+
+
+
+/*****************************************************************************
+XSB External write
+******************************************************************************/
+GT_STATUS    ddr3TipBobKExtWrite
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *addr
+)
+{
+    GT_U32        wordNum = 0,  dataCmd = 0, burstNum=0, cntPoll = 0, dataValue  = 0;
+    MV_HWS_ACCESS_TYPE accessType = ACCESS_TYPE_UNICAST;
+
+    ddr3TipPipeEnable((GT_U8)devNum, accessType, interfaceId, GT_TRUE);
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_CTRL_0_REG) ,EXT_TRAINING_ID  ));
+    for(burstNum=0 ; burstNum < numOfBursts; burstNum++)
+    {
+        /*working with XSB multicast client , Write Interface ADDR as data to XSB address C */
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_ADDRESS_REG), regAddr + (burstNum * EXT_ACCESS_BURST_LENGTH * 4)));
+        for(wordNum = 0; wordNum < 8 ; wordNum++)
+        {
+            /*Write Interface DATA as data to XSB address 0x10.*/
+            CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_DATA_REG + (wordNum * 4)), addr[wordNum]));
+        }
+        if (isCbeRequired ==  GT_TRUE)
+        {
+            dataCmd =  CS_CBE_VALUE(0) << 19;
+        }
+        else
+        {
+            dataCmd = (GT_U32)(TARGET_EXT << 19);
+        }
+        dataCmd |= (BYTE_EN << 11) + (NUM_BYTES_IN_BURST << 4) + (ACCESS_EXT << 3) + EXT_MODE;
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId,  accessType, XSB_CMD_REG), dataCmd));
+        /* execute xsb write */
+        dataCmd |= 0x1;
+        DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("ddr3TipExtWrite dataCmd 0x%x \n", dataCmd));
+        CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, BOBK_XSB_MAPPING(interfaceId, accessType, XSB_CMD_REG), dataCmd));
+
+		for(cntPoll=0; cntPoll < MAX_POLLING_ITERATIONS; cntPoll++)
+		{
+			CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, BOBK_XSB_MAPPING( interfaceId, accessType, XSB_CMD_REG), &dataValue, 0x1));
+
+			if (dataValue == 0)
+				break;
+		}
+
+		if (cntPoll >= MAX_POLLING_ITERATIONS)
+		{
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("No Done indication for DDR Write External\n", dataValue));
+			return GT_NOT_READY;
+		}
+
+    }
+    return GT_OK;
+}
+#else
+/******************************************************************************
+* external read from memory
+*/
+GT_STATUS    ddr3TipBobKExtRead
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+)
+{
+    GT_U32 burstNum;
+
+    for(burstNum=0 ; burstNum < numOfBursts*8; burstNum++)
+    {
+		data[burstNum] = * (volatile unsigned int *) (regAddr + 4* burstNum);
+    }
+
+    return GT_OK;
+}
+
+
+/******************************************************************************
+* external write to memory
+*/
+GT_STATUS    ddr3TipBobKExtWrite
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+)
+{
+    GT_U32 burstNum;
+
+    for(burstNum=0 ; burstNum < numOfBursts*8; burstNum++)
+    {
+		*(volatile unsigned int *) (regAddr+4*burstNum) = data[burstNum];
+    }
+
+    return GT_OK;
+}
+
+#endif
+/******************************************************************************/
+/*   PLL/Frequency Functionality                                              */
+/******************************************************************************/
+
+/******************************************************************************
+* Name:     ddr3TipBonKSetDivider.
+* Desc:     Pll Divider
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS ddr3TipBobKSetDivider
+(
+	GT_U8							devNum,
+	GT_U32							interfaceId,
+    MV_HWS_DDR_FREQ                 frequency
+)
+{
+	if(interfaceId < 4)
+	{
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("TM set divider for interface %d\n",interfaceId));
+		return ddr3TipTmSetDivider(devNum, interfaceId, frequency);
+	}
+
+	else
+	{
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("CPU set divider for interface 4\n"));
+		return ddr3TipCpuSetDivider(devNum, interfaceId, frequency);
+	}
+}
+
+/******************************************************************************
+* return 1 of core/DUNIT clock ration is 1 for given freq, 0 if clock ratios is 2:1
+*/
+static GT_U8 ddr3TipClockMode( GT_U32 frequency )
+{
+	if(frequency == DDR_FREQ_LOW_FREQ){
+		return 1;
+	}
+	else{
+		return 2;
+	}
+}
+
+/******************************************************************************
+* Name:     ddr3TipTmSetDivider.
+* Desc:     Pll Divider of The Trafic Manager Unit
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+static GT_STATUS ddr3TipTmSetDivider
+(
+	GT_U8							devNum,
+	GT_U32							interfaceId,
+    MV_HWS_DDR_FREQ                 frequency
+)
+{
+    GT_U32 data = 0, writeData, divider = 0;
+    MV_HWS_DDR_FREQ sarFreq;
+
+	DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("TM PLL Config\n"));
+
+    /* avoid warnings */
+    interfaceId = interfaceId;
+    /* Calc SAR */
+   /*CHECK_STATUS(ddr3TipTmGetInitFreq(devNum, &sarFreq));*/
+    /* calc SAR */
+    ddr3TipBobKGetInitFreq(devNum, 0, &sarFreq);
+    divider = freqVal[sarFreq]/freqVal[frequency];
+
+    DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("\tSAR value %d divider %d (freqVal[%d] %d  freqVal[%d] %d\n",
+					  sarFreq, divider, sarFreq, freqVal[sarFreq], frequency, freqVal[frequency]));
+    switch (divider)
+    {
+	case 1:
+		writeData  = TM_PLL_REG_DATA(2,1,3);
+		break;
+	case 2:
+		writeData  = TM_PLL_REG_DATA(4,2,3);
+		break;
+	case 3:
+		writeData  = TM_PLL_REG_DATA(6,3,3);
+		break;
+	case 4:
+		writeData  = TM_PLL_REG_DATA(8,4,3);
+		break;
+
+	default:
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Error: ddr3TipTmSetDivider: %d divider is not supported\n", divider));
+		return GT_BAD_PARAM;
+    }
+
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8264,  &data, MASK_ALL_BITS ));
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F8264,  R_MOD_W(writeData,data,0xFF0C)));
+
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8264,  &data, MASK_ALL_BITS));
+	data |= (1<<16);
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F8264,  data));
+
+	/*hwsOsExactDelayPtr(devNum, 0, 10); */
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8264,  &data, MASK_ALL_BITS));
+	data &= ~(1<<16);
+    CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F8264,  R_MOD_W(0, data, (1<<16))));
+
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3TipCpuSetDivider.
+* Desc:     Pll Divider of the CPU(msys) Unit
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+static GT_STATUS ddr3TipCpuSetDivider
+(
+	GT_U8							devNum,
+	GT_U32							interfaceId,
+    MV_HWS_DDR_FREQ                 frequency
+)
+{
+    GT_U32 data = 0, divider = 0;
+#if 0
+    GT_U32 value, divRatio;
+#endif
+    MV_HWS_DDR_FREQ sarFreq;
+    GT_U32 writeData;
+
+	DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("CPU PLL Config\n"));
+#if 1
+    /* calc SAR */
+    ddr3TipBobKGetInitFreq(devNum, interfaceId, &sarFreq);
+    divider = freqVal[sarFreq]/freqVal[frequency];
+
+    DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("\nSAR value %d divider %d freqVal[%d] %d  freqVal[%d] %d\n",
+					  sarFreq, divider, sarFreq, freqVal[sarFreq], frequency, freqVal[frequency]));
+
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F82ec,  &data, MASK_ALL_BITS ));
+	writeData = (0x1 << 9);
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F82ec,  R_MOD_W(writeData,data, (0x1 << 9))));
+
+    switch (divider)
+    {
+        case 1:
+			/*Not 800 is a 667 only*/
+            writeData = (sarFreq==DDR_FREQ_800)?(0x2):(0x1);
+            break;
+        case 2:
+			/*Not 800 is a 667 only*/
+            writeData = (sarFreq==DDR_FREQ_800)?(0x3):(0x2);
+            break;
+        default:
+            DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Error: Wrong divider %d\n", divider));
+            return GT_BAD_PARAM;
+            break;
+    }
+
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F82e8,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0x000F82e8,  R_MOD_W(writeData,data, (0x7 << 0))));
+#else
+    /* calc SAR */
+    ddr3TipBobKGetInitFreq(devNum, interfaceId, &sarFreq);
+    divider = freqVal[sarFreq]/freqVal[frequency];
+
+    DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("\nSAR value %d divider %d freqVal[%d] %d  freqVal[%d] %d\n",
+					  sarFreq, divider, sarFreq, freqVal[sarFreq], frequency, freqVal[frequency]));
+
+	/* Configure Dunit to 1:1 in case of DLL off mode else 2:1*/
+	value = (ddr3TipClockMode(frequency) == 1)? 0 : 1;
+	CHECK_STATUS(ddr3TipBobKWrite(devNum, 0x1524, (value << 15), (1 << 15)));
+
+	/* Dunit training clock + 1:1/2:1 mode */
+	divRatio = (ddr3TipClockMode(frequency) << 16);
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF8298,  &data, MASK_ALL_BITS ));
+	/*ddr_phy_clk_divider*/
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8298,  R_MOD_W(divRatio, data, (0x3 << 16))));
+	divRatio = (frequency==initFreq)?(0):(1);
+	/*sel_pll_ddr_clk_div2*/
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8298,  R_MOD_W( divRatio<<15, data, (0x1 << 15))));
+
+	/*cpu_pll_clkdiv_reload_smooth*/
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF8270,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270,  R_MOD_W((/*0x7F<*/0x6f<11), data, (0x7F << 11))));
+
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF8268,  &data, MASK_ALL_BITS ));
+	/*cpu_pll_clkdiv_relax_en*/
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268,  R_MOD_W(/*0x7F<*/0x6f, data, 0x7F)));
+	/*cpu_pll_clkdiv_reset_mask*/
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268,  R_MOD_W((/*0x7F<*/0x6f<<7), data, (0x7F << 7))));
+
+	/*cpu_pll_ddr_clkdiv_ratio_full*/
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF826C,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF826C,  R_MOD_W((divider<<12), data, (0x3F << 12))));
+
+	/*cpu_pll_clkdiv_reload_force*/
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF8268,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8268,  R_MOD_W((0x2<<21), data, (0x7F << 21))));
+
+	/*cpu_pll_clkdiv_reload_ratio*/
+	CHECK_STATUS(ddr3TipBobKServerRegRead(devNum,  0xF8270,  &data, MASK_ALL_BITS ));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270,  R_MOD_W((0x1<<10), data, (0x1 << 10))));
+	CHECK_STATUS(ddr3TipBobKServerRegWrite(devNum, 0xF8270,  R_MOD_W(0, data, (0x1 << 10))));
+
+    DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("\tCPU PLL config Done\n"));
+#endif
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3TipBobKGetInitFreq.
+* Desc:     choose from where to extract the frequency (TM or CPU)
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+GT_STATUS ddr3TipBobKGetInitFreq
+(
+	GT_U8				devNum,
+	GT_U32				interfaceId,
+    MV_HWS_DDR_FREQ* 	sarFreq
+)
+{
+	GT_STATUS res;
+
+	if(interfaceId < 4)
+	{
+		res = ddr3TipTmGetInitFreq(devNum, sarFreq);
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM frequency for interface %d is %d\n",interfaceId, *sarFreq));
+	}
+	else
+	{
+		res = ddr3TipCpuGetInitFreq(devNum, sarFreq);
+	}
+	return res;
+}
+
+/*****************************************************************************
+TM interface frequency Get
+******************************************************************************/
+static GT_STATUS ddr3TipTmGetInitFreq
+(
+	GT_STATUS       devNum,
+	MV_HWS_DDR_FREQ *freq
+)
+{
+    GT_U32 data;
+
+    /* calc SAR */
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, 0x000F8204 ,  &data, MASK_ALL_BITS));
+    data = (data >> 15) & 0x7;
+#ifdef ASIC_SIMULATION
+    data = 2;
+#endif
+    switch(data)
+    {
+	case 0:
+		/* TM is disabled */
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM Disabled\n"));
+		*freq = DDR_FREQ_LIMIT;
+		return GT_NOT_INITIALIZED;
+
+	case 1:
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_800\n"));
+		*freq = DDR_FREQ_800;
+		break;
+
+	case 2:
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_933\n"));
+		*freq = DDR_FREQ_933;
+		break;
+
+	case 3:
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("TM DDR_FREQ_667\n"));
+		*freq = DDR_FREQ_667;
+		break;
+
+	default:
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Error: ddr3TipTmGetInitFreq: Unknown Freq SAR value 0x%x\n", data));
+		*freq = DDR_FREQ_LIMIT;
+		return GT_BAD_PARAM;
+    }
+    return GT_OK;
+}
+
+/*****************************************************************************
+CPU interface frequency Get
+******************************************************************************/
+static GT_STATUS ddr3TipCpuGetInitFreq
+(
+    GT_STATUS       devNum,
+    MV_HWS_DDR_FREQ *freq
+)
+{
+	GT_U32 data;
+
+    /* calc SAR */
+    CHECK_STATUS(ddr3TipBobKServerRegRead(devNum, REG_DEVICE_SAR1_ADDR,&data, MASK_ALL_BITS ));
+    DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("SAR1 is 0x%X\n", data));
+
+    data = (data >> PLL1_CNFIG_OFFSET) & PLL1_CNFIG_MASK;
+
+    switch(data)
+    {
+        case 0:
+		case 5:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_400\n"));
+            *freq = DDR_FREQ_400;
+            break;
+        case 1:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_533\n"));
+            *freq = DDR_FREQ_533;
+            break;
+        case 2:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_667\n"));
+            *freq = DDR_FREQ_667;
+            break;
+        case 3:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("DDR_FREQ_800\n"));
+            *freq = DDR_FREQ_800;
+            break;
+        default:
+            DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_INFO, ("Freq SAR Unknown\n"));
+            *freq = DDR_FREQ_LIMIT;
+            return GT_BAD_PARAM;
+    }
+    return GT_OK;
+}
+
+/******************************************************************************
+* Name:     ddr3TipBobKGetMediumFreq.
+* Desc:
+* Args:
+* Notes:
+* Returns:  GT_OK if success, other error code if fail.
+*/
+static GT_STATUS ddr3TipBobKGetMediumFreq
+(
+	GT_U32 devNum,
+	GT_U32 interfaceId,
+	MV_HWS_DDR_FREQ *freq
+)
+{
+    MV_HWS_DDR_FREQ sarFreq;
+
+      CHECK_STATUS(ddr3TipBobKGetInitFreq((GT_U8)devNum, interfaceId, &sarFreq));
+
+      switch(sarFreq)
+      {
+          case DDR_FREQ_400:
+              DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("No medium freq supported for 400Mhz\n"));
+              *freq = DDR_FREQ_400;
+              break;
+
+          case DDR_FREQ_667:
+              DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Medium DDR_FREQ_333\n"));
+              *freq = DDR_FREQ_333;
+              break;
+
+          case DDR_FREQ_800:
+              DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Medium DDR_FREQ_400\n"));
+              *freq = DDR_FREQ_400;
+              break;
+
+          case DDR_FREQ_933:
+              DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_TRACE, ("Medium DDR_FREQ_311\n"));
+              *freq = DDR_FREQ_311;
+              break;
+
+          default:
+              DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Error: ddr3TipBc2GetMediumFreq: Freq %d is not supported\n", sarFreq));
+              return GT_FAIL;
+      }
+    return GT_OK;
+}
+
+
+GT_STATUS ddr3TipBobKGetDeviceInfo
+(
+    GT_U8      devNum,
+    MV_DDR3_DEVICE_INFO * infoPtr
+)
+{
+    devNum = devNum; /* avoid warnings */
+
+	infoPtr->deviceId = 0xFC00;
+	infoPtr->ckDelay = ckDelay;
+
+	return GT_OK;
+}
+
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Msys.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Msys.c
new file mode 100644
index 0000000..225b353
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3Msys.c
@@ -0,0 +1,77 @@
+/*******************************************************************************
+*                Copyright 2001, Marvell International Ltd.
+* This code contains confidential information of Marvell semiconductor, inc.
+* no rights are granted herein under any patent, mask work right or copyright
+* of Marvell or any third party.
+* Marvell reserves the right at its sole discretion to request that this code
+* be immediately returned to Marvell. This code is provided "as is".
+* Marvell makes no warranties, express, implied or otherwise, regarding its
+* accuracy, completeness or performance.
+********************************************************************************
+* mvHwsDdr3Msys.c
+*
+* DESCRIPTION: DDR3 MSYS general functions*
+* DEPENDENCIES:
+******************************************************************************/
+
+#include "mvDdr3TrainingIpPrvIf.h"
+
+GT_U32 phy1ValTable[DDR_FREQ_LIMIT] =
+{
+  0,   /* DDR_FREQ_LOW_FREQ */
+  0xf, /* DDR_FREQ_400 */
+  0xf, /* DDR_FREQ_533 */
+  0xf, /* DDR_FREQ_667 */
+  0xc, /* DDR_FREQ_800 */
+  0x8, /* DDR_FREQ_933 */
+  0x8, /* DDR_FREQ_1066 */
+  0xf, /* DDR_FREQ_311 */
+  0xf, /* DDR_FREQ_333 */
+  0xf, /* DDR_FREQ_467 */
+  0xc, /*DDR_FREQ_850*/
+  0xf, /*DDR_FREQ_600*/
+  0xf, /*DDR_FREQ_300*/
+  0x8,  /*DDR_FREQ_900*/
+  0xf  /*DDR_FREQ_360*/
+};
+
+
+/**************************external ******************************/
+extern MV_HWS_TIP_CONFIG_FUNC_DB configFuncInfo[HWS_MAX_DEVICE_NUM];
+
+/******************************************************************************
+XSB External read
+******************************************************************************/
+GT_STATUS    ddr3TipExtRead
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *data
+)
+{
+    return configFuncInfo[devNum].tipExternalRead(devNum,interfaceId,regAddr,numOfBursts,data);
+}
+
+
+
+/*****************************************************************************
+XSB External write
+******************************************************************************/
+GT_STATUS    ddr3TipExtWrite
+(
+    GT_U32      devNum,
+    GT_U32      interfaceId,
+    GT_U32      regAddr,
+    GT_U32      numOfBursts,
+    GT_U32      *addr
+)
+{
+    return configFuncInfo[devNum].tipExternalWrite(devNum,interfaceId,regAddr,numOfBursts,addr);
+}
+
+
+
+
+
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3NP5.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3NP5.c
index 2657f8c..7dced03 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3NP5.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3NP5.c
@@ -64,7 +64,6 @@
 /************************** pre-declaration ******************************/
 /* Read 1st active interface */
 extern GT_U32 maskTuneFunc;
-extern GT_U32 rlVersion;
 extern MV_HWS_DDR_FREQ mediumFreq;
 extern MV_HWS_DDR_FREQ lowFreq;
 extern GT_U32 isPllBeforeInit;
@@ -72,8 +71,9 @@
 extern MV_HWS_DDR_FREQ initFreq;
 extern GT_U32 odtAdditional;
 extern GT_U8  debugTraining;
-extern GT_U32 delayEnable, ckDelay, caDelay, ckDelay_16;
+extern GT_U32 delayEnable, ckDelay, caDelay;
 extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
+extern GT_U32 dfsLowFreq;
 
 extern GT_STATUS ddr3TipRegWrite
 (
@@ -899,8 +899,9 @@
     MV_HWS_TIP_STATIC_CONFIG_INFO staticConfig;
     MV_HWS_TIP_CONFIG_FUNC_DB configFunc;
     MV_HWS_XSB_INFO         xsbInfo;
+	GT_U8 numOfBusPerInterface = 4;
 
-    GT_U32 boardOffset = boardId * NP5_NUMBER_OF_INTERFACES *np5TopologyMap[boardId].numOfBusPerInterface;
+    GT_U32 boardOffset = boardId * NP5_NUMBER_OF_INTERFACES *numOfBusPerInterface;
 
 	DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("register functions \n"));
 
@@ -917,6 +918,13 @@
 
     mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
 
+	/*Set device attributes*/
+	ddr3TipDevAttrInit(devNum);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_1);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_NEGATIVE);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, numOfBusPerInterface);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
+
 #ifdef STATIC_ALGO_SUPPORT
     ddr3TipInitStaticConfigDb(devNum, &staticConfig);
 #endif
@@ -943,7 +951,6 @@
     lowFreq = DDR_FREQ_LOW_FREQ;
     mediumFreq = DDR_FREQ_667;
     isPllBeforeInit = 1;
-    rlVersion = 0;
     initFreq = DDR_FREQ_667;
 	debugTraining = DEBUG_LEVEL_INFO;
 	odtAdditional = 0;
@@ -951,10 +958,9 @@
 	delayEnable = 0;
 	if( ckDelay == -1 )
 		ckDelay = 150;
-	if( ckDelay_16 == -1 )
-		ckDelay_16 = 0;
 	caDelay = 0;
 	calibrationUpdateControl = 1;
+	freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 100;
 
     return GT_OK;
 }
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3a38x.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3a38x.c
index 24e9cb1..412104a 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3a38x.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Silicon/mvHwsDdr3a38x.c
@@ -25,6 +25,7 @@
 #include "ddr3_a38x_tip_training_static.h"
 #include "ddr3_hws_sil_training.h"
 #include "mvXor.h"
+#include "mvSysEnvLib.h"
 
 #include "mvHwsDdr3A38x.h"
 #include "mvSiliconIf.h"
@@ -41,9 +42,13 @@
 extern GT_U8  debugTrainingA38x;
 extern GT_U32 firstActiveIf;
 extern MV_HWS_DDR_FREQ initFreq;
-extern GT_U32 delayEnable, ckDelay, ckDelay_16, caDelay;
-GT_U32  pipeMulticastMask;
+extern GT_U32 delayEnable, ckDelay, caDelay;
+extern GT_U32 dfsLowFreq;
 
+extern GT_U32 mode2T;
+
+GT_U32  pipeMulticastMask;
+GT_BOOL ddr3AsyncModeAtTF = GT_FALSE;
 #define A38X_NUM_BYTES                  (3)
 #define A38X_NUMBER_OF_INTERFACES		5
 
@@ -56,42 +61,14 @@
 extern MV_BOOL ddr3IfEccEnabled(void);
 /************************** pre-declaration ******************************/
 extern GT_U32 maskTuneFunc;
-extern GT_U32 rlVersion;
 extern GT_BOOL rlMidFreqWA;
 extern GT_U8 calibrationUpdateControl; /*2 external only, 1 is internal only*/
+extern GT_U32 freqVal[];
 
-
-#ifdef CONFIG_DDR3
-static GT_U16 freqVal[DDR_FREQ_LIMIT] =
-{
-    130, /*DDR_FREQ_LOW_FREQ*/
-    400, /*DDR_FREQ_400,*/
-    533, /*DDR_FREQ_533,*/
-    666, /*DDR_FREQ_667,*/
-    800, /*DDR_FREQ_800,*/
-    933, /*DDR_FREQ_933,*/
-   1066, /*DDR_FREQ_1066,*/
-    311, /*DDR_FREQ_311,*/
-    333, /*DDR_FREQ_333,*/
-    467, /*DDR_FREQ_467,*/
-    850, /*DDR_FREQ_850,*/
-    600, /*DDR_FREQ_600,*/
-    300, /*DDR_FREQ_300,*/
-	900,  /*DDR_FREQ_900*/
-	360,  /*DDR_FREQ_360*/
-	1000  /*DDR_FREQ_1000*/
-};
-#else /* CONFIG_DDR4 */
-static GT_U16 freqVal[DDR_FREQ_LIMIT] =
-{
-    130,    /* DDR_FREQ_LOW_FREQ */
-    666,    /* DDR_FREQ_667 */
-    800,    /* DDR_FREQ_800 */
-    933,    /* DDR_FREQ_933 */
-    1066,  /* DDR_FREQ_1066 */
-	900  	/*DDR_FREQ_900*/
-};
+#ifdef CONFIG_DDR4
+extern GT_U8	vrefCalibrationWA; /*1 means SSTL & POD gets the same Vref and a WA is needed*/
 #endif
+
 extern MV_HWS_DDR_FREQ mediumFreq;
 
 extern GT_STATUS ddr3TipRegWrite
@@ -134,6 +111,9 @@
     GT_STATUS       devNum,
     MV_HWS_DDR_FREQ *freq
 );
+
+GT_U8    ddr3TipClockMode( GT_U32 frequency );
+
 #ifdef CONFIG_DDR3
 GT_STATUS ddr3TipA38xGetMediumFreq
 (
@@ -177,6 +157,7 @@
     0x5, /*DDR_FREQ_1066*/
 #ifdef CONFIG_DDR4
 	0x5, /*DDR_FREQ_900*/
+	0x5, /*DDR_FREQ_1000*/
 #endif
 #ifdef CONFIG_DDR3
     0x3, /*DDR_FREQ_311*/
@@ -193,7 +174,6 @@
 
 static GT_U8 A38xRatePerFreq[DDR_FREQ_LIMIT] =
 {
-/*TBD*/
     0x1, /*DDR_FREQ_100*/
 #ifdef CONFIG_DDR3
     0x2, /*DDR_FREQ_400*/
@@ -205,6 +185,7 @@
     0x3, /*DDR_FREQ_1066*/
 #ifdef CONFIG_DDR4
 	0x2, /*DDR_FREQ_900*/
+	0x2, /*DDR_FREQ_1000*/
 #endif
 #ifdef CONFIG_DDR3
     0x1, /*DDR_FREQ_311*/
@@ -219,7 +200,7 @@
 #endif
 };
 
-static GT_U16 A38xVcoFreqPerSar[] =
+static GT_U16 A38xVcoFreqPerSarRefClk25Mhz[] =
 {
 	666, /*0*/
 	1332,
@@ -254,16 +235,65 @@
 	800
 };
 
-#ifdef CONFIG_ARMADA_38X_Z1_OBSOLETE
-GT_U32 DQbitMap2Phypin[] =
+static GT_U16 A38xVcoFreqPerSarRefClk40Mhz[] =
 {
-    1, 0,  2, 3,  6, 7, 8,  9, 	//0
-    0, 1, 10, 3,  6, 7, 8,  9,	//1
-    8, 1,  2, 0, 10, 9, 6,  7,	//2
-    0, 1,  2, 3,  7, 8, 6, 10,	//3
-    0, 1,  2, 3,  6, 7, 8,  9,	//4
+	666, /*0*/
+	1332,
+	800,
+	800, /*0x3*/
+	1066,
+	1066, /*0x5*/
+	1200,
+	2400,
+	1332,
+	1332,
+	1500,/*10*/
+	1600, /*0xB*/
+	1600,
+	1600,
+	1700,
+	1560, /*0xF*/
+	1866,
+	1866,
+	1800,
+	2000,
+	2000,/*20*/
+	4000,
+	2132,
+	2132,
+	2300,
+	2300,
+	2400,
+	2400,
+	2500,
+	2500,
+	1800 /*30 - 0x1E*/
 };
-#else
+
+GT_U16 A38xODTSlope[] =
+{
+	21443,
+	1452,
+	482,
+	240,
+	141,
+	90,
+	67,
+	52
+};
+
+GT_U16 A38xODTIntercept[] =
+{
+	1517,
+	328,
+	186,
+	131,
+	100,
+	80,
+	69,
+	61
+};
+
 GT_U32 DQbitMap2Phypin[] =
 {
 	1, 0, 2, 6, 9, 8, 3, 7,	//0
@@ -272,7 +302,6 @@
 	1, 0, 6, 2, 8, 3, 7, 9,	//3
 	0, 1, 2, 9, 7, 8, 3, 6,	//4
 };
-#endif
 
 /**********************************************************************************/
 
@@ -285,8 +314,14 @@
 	GT_32 reg = 0;
 
 	/* Initiates TSEN hardware reset once */
-	if ((MV_REG_READ(TSEN_CONF_REG) & TSEN_CONF_RST_MASK) == 0)
-		MV_REG_BIT_SET(TSEN_CONF_REG, TSEN_CONF_RST_MASK);
+	if ((MV_REG_READ(TSEN_CONTROL_MSB_REG) & TSEN_CONTROL_MSB_RST_MASK) == 0) {
+		MV_REG_BIT_SET(TSEN_CONTROL_MSB_REG, TSEN_CONTROL_MSB_RST_MASK);
+		/* set Tsen Tc Trim to correct default value (errata #132698) */
+		reg = MV_REG_READ(TSEN_CONTROL_LSB_REG);
+		reg &= ~TSEN_CONTROL_LSB_TC_TRIM_MASK;
+		reg |= 0x3 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET;
+		MV_REG_WRITE(TSEN_CONTROL_LSB_REG, reg);
+	}
 	mvOsDelay(10);
 
 	/* Check if the readout field is valid */
@@ -501,6 +536,7 @@
 	MV_HWS_DDR_FREQ uiDdrFreq;
 	MV_STATUS status;
 	MV_HWS_TOPOLOGY_MAP* topologyMap = ddr3TipGetTopologyMap(devNum);
+	GT_U8 numOfBusPerInterface = 5;
 
     /* new read leveling version */
     configFunc.tipDunitReadFunc = ddr3TipA38xIFRead;
@@ -510,15 +546,27 @@
 	configFunc.tipSetFreqDividerFunc = ddr3TipA38xSetDivider;
 	configFunc.tipGetDeviceInfoFunc = ddr3TipA38xGetDeviceInfo;
 	configFunc.tipGetTemperature = ddr3CtrlGetJuncTemp;
+	configFunc.tipGetClockRatio = ddr3TipClockMode;
 
     mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
 
 	ddr3TipRegisterDqTable(devNum, DQbitMap2Phypin);
 
+	/*Set device attributes*/
+	ddr3TipDevAttrInit(devNum);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_TIP_REV, MV_TIP_REV_4);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_POSITIVE);
+	ddr3TipDevAttrSet(devNum, MV_ATTR_OCTET_PER_INTERFACE, numOfBusPerInterface);
+#ifdef CONFIG_ARMADA_39X
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_TRUE);
+#else
+	ddr3TipDevAttrSet(devNum, MV_ATTR_INTERLEAVE_WA, GT_FALSE);
+#endif
+
 #ifdef STATIC_ALGO_SUPPORT
 	{
 		MV_HWS_TIP_STATIC_CONFIG_INFO staticConfig;
-    	GT_U32 boardOffset = boardId * A38X_NUMBER_OF_INTERFACES *topologyMap->numOfBusPerInterface;
+    	GT_U32 boardOffset = boardId * A38X_NUMBER_OF_INTERFACES *numOfBusPerInterface;
 
 		staticConfig.siliconDelay = A38xSiliconDelayOffset[boardId];
 		staticConfig.packageTraceArr = A38xPackageRoundTripDelayArray;
@@ -532,13 +580,11 @@
 		return status;
 	}
 
-    rlVersion = 1;
 #ifdef CONFIG_DDR3
     maskTuneFunc =     (SET_LOW_FREQ_MASK_BIT |
 						LOAD_PATTERN_MASK_BIT |
 						SET_MEDIUM_FREQ_MASK_BIT |
 						WRITE_LEVELING_MASK_BIT |
-//						LOAD_PATTERN_2_MASK_BIT |
 						WRITE_LEVELING_SUPP_MASK_BIT |
 						READ_LEVELING_MASK_BIT |
 						PBS_RX_MASK_BIT |
@@ -588,18 +634,36 @@
 		);
 
 	rlMidFreqWA = GT_FALSE;
+
+	/*detect if VrefCalib WA needed by device ID(a382 didn't need this WA)*/
+	if( ((MV_REG_READ(DEV_ID_REG) & 0xFFFF0000) >> 16) == 0x6811){
+		mvPrintf("vrefCalibrationWA disabled\n");
+		vrefCalibrationWA = 0;
+	}
+
+#if 0
+	/*detect if VrefCalib WA needed by revision ID(a390 A0 didn't need this WA)*/
+	if( ( ((MV_REG_READ(DEV_ID_REG) & 0xFFFF0000) >> 16) == 0x6920) &&
+		(((MV_REG_READ(DEV_VERSION_ID_REG) & REVISON_ID_MASK) >> REVISON_ID_OFFS) == 0x6) ){
+		mvPrintf("vrefCalibrationWA disabled\n");
+		vrefCalibrationWA = 0;
+	}
+#endif
 #endif
 
-	if( ckDelay == -1 )
+	if( ckDelay == MV_PARAMS_UNDEFINED )
 		ckDelay = 160;
-	if( ckDelay_16 == -1 )
-		ckDelay_16 = 160;
 	caDelay = 0;
 	delayEnable = 1;
-
+	freqVal[DDR_FREQ_LOW_FREQ] = dfsLowFreq = 120;
 	calibrationUpdateControl = 1;
 
-	initFreq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
+#ifdef CONFIG_ARMADA_38X
+    /* For a38x Only, change to 2T mode to resolve low freq instability */
+    mode2T = 1;
+#endif
+
+    initFreq = topologyMap->interfaceParams[firstActiveIf].memoryFreq;
 
 #ifdef CONFIG_DDR3
     ddr3TipA38xGetMediumFreq(devNum, &mediumFreq);
@@ -645,51 +709,89 @@
     MV_HWS_DDR_FREQ *freq
 )
 {
-	GT_U32 uiReg;
+	GT_U32 uiReg, refClkSatR;
 
     /* Read sample at reset setting */
     uiReg = (MV_REG_READ(REG_DEVICE_SAR1_ADDR)>> RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) & RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
-    switch(uiReg) {
+
+	refClkSatR = MV_REG_READ(DEVICE_SAMPLE_AT_RESET2_REG);
+	if(((refClkSatR >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) == DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ){
+		switch(uiReg) {
+	#ifdef CONFIG_DDR3
+		case 0x1:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 333Mhz configured(%d)\n", uiReg));
+		case 0x0:
+		    *freq = DDR_FREQ_333;
+		    break;
+		case 0x3:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 400Mhz configured(%d)\n", uiReg));
+		case 0x2:
+		    *freq = DDR_FREQ_400;
+		    break;
+		case 0xd:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 533Mhz configured(%d)\n", uiReg));
+		case 0x4:
+		    *freq = DDR_FREQ_533;
+		    break;
+		case 0x6:
+		    *freq = DDR_FREQ_600;
+		    break;
+	#endif
+		case 0x11:
+		case 0x14:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 667Mhz configured(%d)\n", uiReg));
+		case 0x8:
+		    *freq = DDR_FREQ_667;
+		    break;
+		case 0x15:
+		case 0x1b:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 800Mhz configured(%d)\n", uiReg));
+		case 0xC:
+		    *freq = DDR_FREQ_800;
+		    break;
+		case 0x10:
+		    *freq = DDR_FREQ_933;
+		    break;
+		case 0x12:
+		    *freq = DDR_FREQ_900;
+		    break;
 #ifdef CONFIG_DDR3
-    case 0x0:
-    case 0x1:
-        *freq = DDR_FREQ_333;
-        break;
-    case 0x2:
-    case 0x3:
-        *freq = DDR_FREQ_400;
-        break;
-    case 0x4:
-    case 0xd:
-        *freq = DDR_FREQ_533;
-        break;
-    case 0x6:
-        *freq = DDR_FREQ_600;
-        break;
+		case 0x13:
+		    *freq = DDR_FREQ_933;
+			ddr3AsyncModeAtTF = GT_TRUE;
+		    break;
+#else
+		case 0x13:
+		    *freq = DDR_FREQ_1000;
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("Warning: Unsupported freq mode for 1000Mhz configured(%d)\n", uiReg));
+		    break;
 #endif
-    case 0x8:
-	case 0x11:
-	case 0x14:
-        *freq = DDR_FREQ_667;
-        break;
-	case 0xC:
-	case 0x15:
-	case 0x1b:
-        *freq = DDR_FREQ_800;
-        break;
-	case 0x10:
-        *freq = DDR_FREQ_933;
-        break;
-	case 0x12:
-        *freq = DDR_FREQ_900;
-        break;
-	case 0x13:
-        *freq = DDR_FREQ_900;
-        break;
-    default:
-        *freq = 0;
-	    return MV_NOT_SUPPORTED;
-    }
+		default:
+		    *freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	}
+	else{ /*REFCLK 40 MHZ case*/
+		switch(uiReg) {
+	#ifdef CONFIG_DDR3
+		case 0x3:
+		    *freq = DDR_FREQ_400;
+		    break;
+		case 0x5:
+		    *freq = DDR_FREQ_533;
+		    break;
+	#endif
+		case 0xB:
+		    *freq = DDR_FREQ_800;
+		    break;
+		case 0x1E:
+		    *freq = DDR_FREQ_900;
+		    break;
+		default:
+		    *freq = 0;
+			return MV_NOT_SUPPORTED;
+    	}
+	}
     return GT_OK;
 }
 
@@ -700,50 +802,75 @@
     MV_HWS_DDR_FREQ *freq
 )
 {
-	GT_U32 uiReg;
+	GT_U32 uiReg, refClkSatR;
 
     /* Read sample at reset setting */
     uiReg = (MV_REG_READ(REG_DEVICE_SAR1_ADDR)>> RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) & RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
-    switch(uiReg) {
-    case 0x0:
-    case 0x1:
-        *freq = DDR_FREQ_333; /*Medium is same as TF to run PBS in this freq*/
-        break;
-    case 0x2:
-    case 0x3:
-        *freq = DDR_FREQ_400; /*Medium is same as TF to run PBS in this freq*/
-        break;
-    case 0x4:
-    case 0xd:
-        *freq = DDR_FREQ_533;
-        break;
-    case 0x8:
-	case 0x11:
-	case 0x14:
-        *freq = DDR_FREQ_333;
-        break;
-	case 0xC:
-	case 0x15:
-	case 0x1b:
-        *freq = DDR_FREQ_400;
-        break;
-    case 0x6:
-        *freq = DDR_FREQ_300;
-        break;
-	case 0x12:
-        *freq = DDR_FREQ_360;
-        break;
-	case 0x13:
-        *freq = DDR_FREQ_400;
-        break;
-    default:
-        *freq = 0;
-	    return MV_NOT_SUPPORTED;
-    }
+
+	refClkSatR = MV_REG_READ(DEVICE_SAMPLE_AT_RESET2_REG);
+	if(((refClkSatR >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) == DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ){
+		switch(uiReg) {
+		case 0x1:
+		case 0x0:
+		    *freq = DDR_FREQ_333; /*Medium is same as TF to run PBS in this freq*/
+		    break;
+		case 0x3:
+		case 0x2:
+		    *freq = DDR_FREQ_400; /*Medium is same as TF to run PBS in this freq*/
+		    break;
+		case 0xd:
+		case 0x4:
+		    *freq = DDR_FREQ_533;/*Medium is same as TF to run PBS in this freq*/
+		    break;
+		case 0x8:
+		case 0x11:
+		case 0x14:
+		case 0x10:
+		    *freq = DDR_FREQ_333;
+		    break;
+		case 0x15:
+		case 0x1b:
+		case 0xC:
+		    *freq = DDR_FREQ_400;
+		    break;
+		case 0x6:
+		    *freq = DDR_FREQ_300;
+		    break;
+		case 0x12:
+		    *freq = DDR_FREQ_360;
+		    break;
+		case 0x13:
+		    *freq = DDR_FREQ_400;
+		    break;
+		default:
+		    *freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	}
+	else{ /*REFCLK 40 MHZ case*/
+		switch(uiReg) {
+		case 0x3:
+		    *freq = DDR_FREQ_400;/*Medium is same as TF to run PBS in this freq*/
+		    break;
+		case 0x5:
+		    *freq = DDR_FREQ_533;/*Medium is same as TF to run PBS in this freq*/
+		    break;
+		case 0xB:
+		    *freq = DDR_FREQ_400;
+		    break;
+		case 0x1E:
+		    *freq = DDR_FREQ_360;
+		    break;
+		default:
+		    *freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	}
     return GT_OK;
 }
 #endif
 
+
 GT_U32 ddr3TipGetInitFreq()
 {
     MV_HWS_DDR_FREQ freq;
@@ -763,7 +890,7 @@
 )
 {
 	GT_U32 divider = 0;
-    GT_U32 sarVal;
+    GT_U32 sarVal, refClkSatR;
 
 	if (interfaceId != 0) {
 		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, ("A38x does not support interface 0x%x\n", interfaceId));
@@ -773,52 +900,81 @@
 	/* get VCO freq index */
 	sarVal = (MV_REG_READ(REG_DEVICE_SAR1_ADDR)>> RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) & RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
 
-    divider = A38xVcoFreqPerSar[sarVal]/freqVal[frequency];
-
-	/*Set Sync mode*/
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x20220, 0x0, 0x1000));
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE42F4, 0x0, 0x200));
-
-	/* cpupll_clkdiv_reset_mask */ 
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0x1f, 0xFF));
-
-	/* cpupll_clkdiv_reload_smooth */ 
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, (0x2 << 8), (0xFF << 8)));
-
-	/* cpupll_clkdiv_relax_en */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, (0x2 << 24), (0xFF << 24)));
-
-	/* write the divider */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4268, (divider << 8), (0x3F << 8)));
-
-	/* set cpupll_clkdiv_reload_ratio */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, (1 << 8), (1 << 8)));
-
-	/* undet cpupll_clkdiv_reload_ratio */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0, (1 << 8)));
-
-	/* clear cpupll_clkdiv_reload_force */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, 0, (0xFF << 8)));
-
-	/* clear cpupll_clkdiv_relax_en */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, 0, (0xFF << 24)));
-
-	/* clear cpupll_clkdiv_reset_mask */
-	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0, 0xFF));
-
-	/* Dunit training clock + 1:1 mode */
-	if((frequency == DDR_FREQ_LOW_FREQ) || (freqVal[frequency] <= 400)) {
-		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x18488, (1 << 16), (1 << 16)));
-		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1524, (0 << 15), (1 << 15)));
+	refClkSatR = MV_REG_READ(DEVICE_SAMPLE_AT_RESET2_REG);
+	if(((refClkSatR >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) == DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ){
+    	divider = A38xVcoFreqPerSarRefClk25Mhz[sarVal]/freqVal[frequency];
 	}
-	else {
-		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x18488, 0, (1 << 16)));
-		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1524, (1 << 15), (1 << 15)));
+	else{
+    	divider = A38xVcoFreqPerSarRefClk40Mhz[sarVal]/freqVal[frequency];
 	}
 
+	if( (ddr3AsyncModeAtTF == GT_TRUE) && (freqVal[frequency] > 400) ){
+
+		/*Set Async Mode*/
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x20220, 0x1000, 0x1000));
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE42F4, 0x200, 0x200));
+
+		/*Wait for Asunc mode setup*/
+		mvOsDelay(5);
+
+		/*Set KNL values*/
+		if( frequency == DDR_FREQ_933){
+			CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE42F0, 0x804A002, 0xFFFFFFFF));
+		}
+	}
+	else{
+		/*Set Sync mode*/
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x20220, 0x0, 0x1000));
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE42F4, 0x0, 0x200));
+
+		/* cpupll_clkdiv_reset_mask */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0x1f, 0xFF));
+
+		/* cpupll_clkdiv_reload_smooth */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, (0x2 << 8), (0xFF << 8)));
+
+		/* cpupll_clkdiv_relax_en */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, (0x2 << 24), (0xFF << 24)));
+
+		/* write the divider */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4268, (divider << 8), (0x3F << 8)));
+
+		/* set cpupll_clkdiv_reload_ratio */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, (1 << 8), (1 << 8)));
+
+		/* undet cpupll_clkdiv_reload_ratio */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0, (1 << 8)));
+
+		/* clear cpupll_clkdiv_reload_force */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, 0, (0xFF << 8)));
+
+		/* clear cpupll_clkdiv_relax_en */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4260, 0, (0xFF << 24)));
+
+		/* clear cpupll_clkdiv_reset_mask */
+		CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0xE4264, 0, 0xFF));
+	}
+
+	/* Dunit training clock + 1:1/2:1 mode */
+	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x18488, ((ddr3TipClockMode(frequency) & 0x1) << 16), (1 << 16)));
+	CHECK_STATUS(ddr3TipA38xIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, 0x1524, ((ddr3TipClockMode(frequency)-1) << 15), (1 << 15)));
+
 	return GT_OK;
 }
 
+/******************************************************************************
+* return 1 of core/DUNIT clock ration is 1 for given freq, 0 if clock ratios is 2:1
+*/
+GT_U8    ddr3TipClockMode( GT_U32 frequency )
+{
+	if((frequency == DDR_FREQ_LOW_FREQ) || (freqVal[frequency] <= 400)){
+		return 1;
+	}
+	else{
+		return 2;
+	}
+}
+
 
 /******************************************************************************
 * external read from memory
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_hws_hw_training.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_hws_hw_training.c
index 817b84e..be3b0e8 100644
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_hws_hw_training.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_hws_hw_training.c
@@ -111,11 +111,10 @@
 
 MV_STATUS ddr3HwsHwTraining(void)
 {
-
 	MV_HWS_ALGO_TYPE algoMode = ALGO_TYPE_DYNAMIC;
 	MV_STATUS status;
 	InitCntrParam initParam;
-	
+
 	status = ddr3SiliconPreInit();
 	if (MV_OK != status) {
 		mvPrintf("DDR3 Pre silicon Config - FAILED 0x%x\n", status);
@@ -123,12 +122,12 @@
 	}
 
 	initParam.doMrsPhy = GT_TRUE;
-#if defined(CONFIG_ARMADA_38X)  || defined(CONFIG_ARMADA_39X)
+#if !defined (CONFIG_BOBCAT2)
 	initParam.isCtrl64Bit = GT_FALSE;
 #else
 	initParam.isCtrl64Bit = GT_TRUE;
 #endif
-#if defined (CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+#if !defined (CONFIG_BOBCAT2)
     initParam.initPhy = GT_TRUE;
 #else
     initParam.initPhy = GT_FALSE;
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bc2_training.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bc2_training.c
index 6e3f107..a760388 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bc2_training.c
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bc2_training.c
@@ -222,7 +222,6 @@
 	MV_STATUS status;
 
 	genericInitController = 1;
-	mvPrintf(">>> setting genericInitController = 1\n");
 
 	//status = ddr3TipInitBc2Silicon(0, 1);
 	status = ddr3TipInitBc2(0, 0);
@@ -354,8 +353,6 @@
 
 	serverBaseAddr = MV_REG_READ(REG_XBAR_WIN_5_BASE_ADDR);
 
-	mvPrintf("configureServerWindows: Server base is 0x%x\n", serverBaseAddr);
-
 	/* init server access */
 	hwsServerRegSetFuncPtr = serverRegSet; 
 	hwsServerRegGetFuncPtr = serverRegGet;
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bobk_training.c b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bobk_training.c
new file mode 100755
index 0000000..c7364fd
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/src/Soc/ddr3_msys_bobk_training.c
@@ -0,0 +1,341 @@
+/*******************************************************************************
+*                Copyright 2001, Marvell International Ltd.
+* This code contains confidential information of Marvell semiconductor, inc.
+* no rights are granted herein under any patent, mask work right or copyright
+* of Marvell or any third party.
+* Marvell reserves the right at its sole discretion to request that this code
+* be immediately returned to Marvell. This code is provided "as is".
+* Marvell makes no warranties, express, implied or otherwise, regarding its
+* accuracy, completeness or performance.
+********************************************************************************
+* ddr3_msys_training.c
+*
+* DESCRIPTION: 
+*
+*
+* DEPENDENCIES:
+*
+* FILE REVISION NUMBER:
+*       $Revision: 1 $
+***************************************************************************/
+
+#include "mv_os.h"
+#include "ddr3_msys_bobk.h"
+#include "ddr3_msys_bobk_config.h"
+#include "ddr3_hws_sil_training.h"
+#include "mvSiliconIf.h"
+#include "mvDdr3TrainingIpPrvIf.h"
+#include "mvHwsDdr3BobK.h"
+#include "soc_spec.h"
+#include "printf.h"
+
+/************************** globals ***************************************/
+
+extern MV_SERVER_REG_ACCESS_SET hwsServerRegSetFuncPtr;
+extern MV_SERVER_REG_ACCESS_GET hwsServerRegGetFuncPtr;
+
+GT_U32 serverBaseAddr = 0;
+/* the following global variables are set in ddr3TipDynamicReadLeveling */
+
+
+extern GT_U32 genericInitController;
+extern GT_U32 debugBobK;
+
+/************************** pre-declarations ******************************/
+GT_STATUS    ddr3DunitAccessRead
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId, 
+    GT_U32                regAddr, 
+    GT_U32                *data,
+    GT_U32                mask 
+);
+
+GT_STATUS    ddr3DunitAccessWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId, 
+    GT_U32                regAddr, 
+    GT_U32                dataValue,
+    GT_U32                mask 
+);
+
+GT_STATUS ddr3DunitAccessInit
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+);
+
+MV_VOID configureServerWindows(void);
+
+extern GT_STATUS ddr3TipBobKGetFreqConfig
+(
+	GT_U8							devNum,
+    MV_HWS_DDR_FREQ                 freq,
+	MV_HWS_TIP_FREQ_CONFIG_INFO		*freqConfigInfo
+);
+
+extern GT_STATUS ddr3TipBobKSetDivider
+(
+	GT_U8							devNum,
+	GT_U32							interfaceId,
+    MV_HWS_DDR_FREQ                 freq
+);
+
+extern GT_STATUS ddr3TipInitBobKSilicon
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+);
+extern GT_STATUS ddr3TipBobKGetInitFreq
+(
+    GT_STATUS       devNum,
+	GT_U32			interfaceId,
+    MV_HWS_DDR_FREQ *freq
+);
+
+GT_STATUS    ddr3TipBobKSelectCPUDdrController
+(
+    GT_U8    devNum,
+    GT_BOOL  enable
+);
+
+/***************************************************************************/
+
+/******************************************************************************
+* Name:     serverRegSet.
+* Desc:     definition of server write prototype
+* Args:     TBD
+* Notes:
+* Returns:  OK if success, other error code if fail.
+*/
+GT_STATUS serverRegSet
+(
+    GT_U8 devNum,
+    GT_U32 addr,
+    GT_U32 data
+)
+{
+	if(serverBaseAddr == 0) {
+		mvPrintf("Server windows were not initialized\n", 0);
+		return GT_NOT_INITIALIZED;
+	}
+
+	*((volatile unsigned int*)(serverBaseAddr+addr)) = data;
+    //mvPrintf("serverRegSet 0x%x =0x%x\n",addr,data);
+
+	return GT_OK;
+}
+
+/******************************************************************************
+* Name:     serverRegGet.
+* Desc:     definition of server read prototype
+* Args:     TBD
+* Notes:    
+* Returns:  OK if success, other error code if fail.
+*/
+GT_STATUS serverRegGet
+(
+    GT_U8 devNum, 
+    GT_U32 addr, 
+    GT_U32 *data
+)
+{
+	if(serverBaseAddr == 0) {
+		mvPrintf("Server windows were not initialized\n", 0);
+		return GT_NOT_INITIALIZED;
+	}
+
+	*data = (*((volatile unsigned int*)(serverBaseAddr+addr)));
+	//mvPrintf("serverRegGet 0x%x =0x%x\n",addr,*data);
+
+	return GT_OK;
+}
+
+MV_STATUS ddr3SiliconPreInit(void)
+{
+    MV_STATUS status;
+	/* initialize window to server */
+	configureServerWindows();
+
+#if 0
+	MV_U32 uiReg;
+	/* set dupicate CS configuration */
+	serverRegGet(0, 0xf8288, &uiReg);
+	uiReg |= (1 << 17);
+	serverRegSet(0, 0xf8288, uiReg);
+#endif
+
+    status = ddr3SiliconInit();
+	if (MV_OK != status) {
+		mvPrintf("DDR3 silicon init - FAILED 0x%x\n", status);
+		return status;
+	}
+
+	return MV_OK;
+}
+
+MV_STATUS ddr3SiliconPostInit(void)
+{
+	return MV_OK;
+}
+
+/******************************************************************************
+ * Name:     ddr3TipInitSilicon
+ * Desc:     initiate silicon parameters
+ * Args:
+ * Notes:
+ * Returns:  required value
+ */
+MV_STATUS ddr3SiliconInit(void) {
+
+	MV_STATUS status;
+
+	genericInitController = 1;
+
+	status = ddr3TipInitBobK(0, 0);
+	if (MV_OK != status) {
+		mvPrintf("DDR3 Msys silicon init - FAILED 0x%x\n", status);
+		return status;
+	}
+
+	return MV_OK;
+}
+
+MV_STATUS ddr3PostRunAlg(void)
+{
+    MV_U32 readDelay[5];
+	GT_U32 gReadSampleDelay = 0x19191919;
+	GT_U32 gReadReadyDelay = 0x19191919;
+
+    CHECK_STATUS(mvHwsDdr3TipIFRead(0, ACCESS_TYPE_UNICAST, 4, REG_READ_DATA_SAMPLE_DELAYS_ADDR,
+                                    readDelay, MASK_ALL_BITS));
+
+    gReadSampleDelay = readDelay[4];
+
+    CHECK_STATUS(mvHwsDdr3TipIFRead(0, ACCESS_TYPE_UNICAST, 4, REG_READ_DATA_READY_DELAYS_ADDR, 
+                                    readDelay, MASK_ALL_BITS));
+
+    gReadReadyDelay = readDelay[4];
+
+    CHECK_STATUS(ddr3TipBobKSelectCPUDdrController(0, GT_FALSE)); // set mux to msys
+
+    MV_REG_WRITE(REG_READ_DATA_SAMPLE_DELAYS_ADDR, gReadSampleDelay);
+    MV_REG_WRITE(REG_READ_DATA_READY_DELAYS_ADDR, gReadReadyDelay);
+	return MV_OK;
+}
+
+/********************************************/
+/*********** Msys D-Unit Access    **********/
+/********************************************/
+
+
+GT_STATUS    ddr3DunitAccessWrite
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId, 
+    GT_U32                regAddr, 
+    GT_U32                dataValue,
+    GT_U32                mask 
+)
+{
+	GT_U32 uiDataRead;
+    GT_U32 dataRead[MAX_INTERFACE_NUM];
+#ifdef WIN32
+    mvPrintf(DEBUG_LEVEL_TRACE,"ddr3DunitAccessWrite   0x%x: 0x%x (mask 0x%x)\n", regAddr, dataValue);
+    return GT_OK;
+#endif
+    if (mask != MASK_ALL_BITS)
+    {
+        if (debugBobK >= 2)
+        {
+            mvPrintf("ddr3DunitAccessWrite active interface = %d\n",interfaceId);
+        }
+        CHECK_STATUS(ddr3DunitAccessRead(devNum, ACCESS_TYPE_UNICAST,interfaceId, regAddr,  dataRead, MASK_ALL_BITS));
+        uiDataRead = dataRead[interfaceId];
+        dataValue = (uiDataRead & (~mask)) | (dataValue & mask);
+    }
+
+    if (debugBobK >= 1)
+    {
+        mvPrintf("0x%x: 0x%x\n", regAddr, dataValue);
+    }
+
+    MV_REG_WRITE(regAddr, dataValue);
+
+    return GT_OK;
+}
+
+GT_STATUS    ddr3DunitAccessRead
+(
+    GT_U8                 devNum,
+    MV_HWS_ACCESS_TYPE    interfaceAccess,
+    GT_U32                interfaceId,
+    GT_U32                regAddr,
+    GT_U32                *data,
+    GT_U32                mask
+)
+{
+#ifdef WIN32
+     mvPrintf("ddr3DunitAccessRead   0x%x: 0x%x (mask 0x%x)\n", regAddr, *data);
+     return GT_OK;
+#endif
+
+	data[interfaceId] = MV_REG_READ(regAddr) & mask;
+
+    return GT_OK;
+}
+
+GT_STATUS ddr3DunitAccessInit
+(
+    GT_U32  devNum,
+    GT_U32  boardId
+)
+{
+	MV_HWS_TIP_CONFIG_FUNC_DB configFunc;
+
+    configFunc.tipDunitReadFunc = ddr3DunitAccessRead;
+    configFunc.tipDunitWriteFunc = ddr3DunitAccessWrite;
+    configFunc.tipDunitMuxSelectFunc = ddr3TipBobKSelectCPUDdrController;
+    configFunc.tipSetFreqDividerFunc = ddr3TipBobKSetDivider;
+    configFunc.tipGetFreqConfigInfoFunc = ddr3TipBobKGetFreqConfig;
+
+    mvHwsDdr3TipInitConfigFunc(devNum, &configFunc);
+
+	return GT_OK;
+}
+
+MV_VOID configureServerWindows(void)
+{
+	static MV_BOOL configDone = MV_FALSE;
+
+	if(configDone == MV_TRUE)
+		return;
+
+    serverBaseAddr = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(1));
+
+    /* init server access */
+	hwsServerRegSetFuncPtr = serverRegSet;
+	hwsServerRegGetFuncPtr = serverRegGet;
+
+	configDone = MV_TRUE;
+}
+
+/*****************************************************************************/
+GT_U32 ddr3TipGetInitFreq()
+{
+    MV_HWS_DDR_FREQ freq;
+
+	configureServerWindows();
+
+	ddr3TipBobKGetInitFreq(0, 0, &freq); /* In BobK interface 0 is the CPU interface*/
+
+	return freq;
+
+}
+
+
+
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 37c7e32..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_ddr/lib/ddr3_training_a39x.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a39x.lib
index f95dbe6..fb4c74d 100644
--- a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a39x.lib
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_a39x.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_ac3.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_ac3.lib
index 2d4b165..23d4406 100644
--- a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_ac3.lib
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_ac3.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_bc2.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_bc2.lib
index b931dee..5a0c8b8 100644
--- a/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_bc2.lib
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr3_training_msys_bc2.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38x.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38x.lib
new file mode 100644
index 0000000..170b95b
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38x.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38xsub.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38xsub.lib
new file mode 100644
index 0000000..3e86ab7
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a38xsub.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39x.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39x.lib
index 1e6443c..d701989 100644
--- a/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39x.lib
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39x.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39xsub.lib b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39xsub.lib
new file mode 100644
index 0000000..db2fef2
--- /dev/null
+++ b/tools/marvell/bin_hdr/src_ddr/lib/ddr4_training_a39xsub.lib
Binary files differ
diff --git a/tools/marvell/bin_hdr/src_init/a38x/generalInit.c b/tools/marvell/bin_hdr/src_init/a38x/generalInit.c
index e37a848..f0889d1 100644
--- a/tools/marvell/bin_hdr/src_init/a38x/generalInit.c
+++ b/tools/marvell/bin_hdr/src_init/a38x/generalInit.c
@@ -70,6 +70,8 @@
 #include "generalInit.h"
 #include "printf.h"
 #include "mvSysEnvLib.h"
+#include "soc_spec.h"
+#include "bin_hdr_twsi.h"
 
 /******************************************************************************************
 * mvDeviceIdConfig - set SoC Unit configuration and device ID according to detected flavour
@@ -116,22 +118,196 @@
         MV_REG_WRITE(MPP_CONTROL_REG(2), regData);
 }
 
+/* update RTC (Read Timing Control) values of PCIe memory wrappers.
+ * use slower memory Read Timing, to allow more efficient energy consumption, in order to lower
+ * the minimum VDD of the memory.
+ * This will lead to more robust memory when voltage drop occurs (VDDSEG)
+ */
+MV_VOID mvRtcConfig()
+{
+	MV_U32 i, pipeSelectVal;
+
+	/* Activate pipe0 for read/write transaction, and set XBAR client number #1 */
+	pipeSelectVal = 0x1 << DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS \
+			| 0x1 << DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS;
+	MV_REG_WRITE(DFX_REG_BASE, pipeSelectVal);
+
+	/* Set new RTC value for all memory wrappers */
+	for (i = 0; i < RTC_MEMORY_WRAPPER_COUNT; i++)
+		MV_REG_WRITE(RTC_MEMORY_WRAPPER_REG(i), RTC_MEMORY_WRAPPER_CTRL_VAL);
+
+}
+
+#ifdef CONFIG_ARMADA_38X
+
+/*******************************************************************************
+* isSkippingAVSFromEfuse
+*
+* DESCRIPTION:
+*	read 'avsskip' field in EEPROM to detect whether to skip AVS
+*	selection from EFUSE, in order to add option to skip AVS selection
+*	with problematic AVS values in EEPROM
+* RETURN:
+*	MV_TRUE, if avsskip is 1
+*	MV_FALSE, otherwise.
+*
+*******************************************************************************/
+MV_BOOL isSkippingAVSFromEfuse()
+{
+	MV_TWSI_SLAVE twsiSlave;
+	MV_U8 data;
+
+	twsiSlave.slaveAddr.address = 0x57; // EEPROM Address
+	twsiSlave.slaveAddr.type = ADDR7_BIT;
+	twsiSlave.validOffset = MV_TRUE;
+	twsiSlave.moreThen256 = MV_TRUE;
+	twsiSlave.offset = 2;		/* SW EEPROM, register 2, bit 7 */
+
+	if (mvTwsiRead(0, &twsiSlave, &data, 1) != MV_OK) {
+		mvPrintf("%s: TWSI Read of 'avsskip' failed\n", __func__);
+		return MV_TRUE; /* skip AVS from EFUSE in case of error */
+	}
+	data >>= 7; /* BIT 7 */
+	if (data == 1)
+		return MV_TRUE;
+	else
+		return MV_FALSE;
+}
+
+/*******************************************************************************
+* mvGetAvsValFromEfuse
+*
+* DESCRIPTION:
+*	read AVS value written to eFuse that corresponds to satrFreq
+*	there are 3 AVS values written in eFuse that corresponds to the frequencies
+*	that lower or equal to 1600MHz, 1866MHz and 2000MHz.
+*	Bit mapping of EFUSE_AVS_AND_BIN_REG:
+*	+-------+-----+--------------+------------------+----------------+
+*	| Field | Bin | AVS_Val 2GHz | AVS_Val 1.866GHz | AVS_Val 1.6GHz |
+*	+-------+-----+--------------+------------------+----------------+
+*	| bits  | 4-5 | 6-13         | 14-21            | 22-29          |
+*	+-------+-----+--------------+------------------+----------------+
+*
+*	Bit mapping of EFUSE_AVS_VERSION_REG:
+*	+-------+---------+
+*	| Field | Version |
+*	+-------+---------+
+*	| bits  | 24-27   |
+*	+-------+---------+
+* INPUT:
+*	satrFreq	- controller CPU frequency
+*
+* OUTPUT:
+*	avsVal		- AVS value in eFuse corresponding to satrFreq
+*
+* RETURN:
+*	MV_TRUE, if AVS value exits in eFuse (if version is not equal 0).
+*	MV_FALSE, otherwise.
+*
+*******************************************************************************/
+MV_BOOL mvGetAvsValFromEfuse(MV_U32 satrFreq, MV_U32 *avsVal)
+{
+	MV_U32 versionVal, binVal, avsRegControlVal;
+	MV_BOARD_AVS_EFUSE_MAP efuse_freq_val[] = EFUSE_FREQ_VAL_INFO;
+	int i;
+
+#ifndef CONFIG_AVS_FROM_EFUSE
+	mvPrintf("AVS selection from EFUSE disabled (Skip reading EFUSE values)\n");
+	return MV_FALSE;
+#endif
+
+#ifndef CONFIG_CUSTOMER_BOARD_SUPPORT
+	/* For Marvell boards only:
+	 * AVS configuration from EFUSE can be skipped for Marvell boards, for:
+		- Already existing SoCs which EFUSE was not pre-burnt with AVS values
+		- SoCs with invalid AVS EFUSE values */
+	if (isSkippingAVSFromEfuse() == MV_TRUE) {
+		mvPrintf("Skipping AVS selection from EFUSE (SatR field 'avsskip' = Yes)\n");
+		return MV_FALSE;
+	}
+#endif
+
+	/* Set Memory I/O window */
+	MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(EFUSE_WIN_ID), EFUSE_WIN_CTRL_VAL);
+	MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(EFUSE_WIN_ID), EFUSE_WIN_BASE_VAL);
+	MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(EFUSE_WIN_ID), 0);
+	MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(EFUSE_WIN_ID), 0);
+
+	/* check version value
+	 * if it is equal to 0 then AVS value does not exist */
+	versionVal = (MV_EFUSE_REG_READ(EFUSE_AVS_VERSION_REG) &
+			(EFUSE_AVS_VERSION_MASK << EFUSE_AVS_VERSION_OFFSET)) >> EFUSE_AVS_VERSION_OFFSET;
+	if (versionVal == 0) {
+		mvPrintf("AVS from eFuse version is not supported (%u)\n", versionVal);
+		return MV_FALSE;
+	}
+
+	/* read Bin value
+	 * bin value indicates highest frequency the device meets:
+	 * - 0x3: 1600MHz
+	 * - 0x2: 1866MHz
+	 * - 0x1: 2000MHz */
+	binVal = (MV_EFUSE_REG_READ(EFUSE_AVS_AND_BIN_REG) &
+			(EFUSE_AVS_BIN_MASK << EFUSE_AVS_BIN_OFFSET)) >> EFUSE_AVS_BIN_OFFSET;
+
+	/* fetch AVS_Val according to frequency
+	 * check if selected S@R value that corresponds to frequency 1866,2000,
+	 * or below 1600MHz (1st cell is 1600) */
+	for (i = 0; i < EFUSE_FREQ_VAL_SIZE; ++i) {
+		/* check that S@R freq mode is permitted on chip:
+		 * check if Bin val from eFuse is lower/equal than the bin value
+		 * corresponding with this S@R freq */
+		if (satrFreq == efuse_freq_val[i].cpu_freq_mode
+				|| (i == 0 && satrFreq < efuse_freq_val[i].cpu_freq_mode)) {
+			if (binVal > efuse_freq_val[i].avs_bin_value) {
+				/* for security check, S@R frequency is not allowed by Bin field
+				 * write default value of AVS 1.25V, and halt the CPU (empty infinite loop)
+				 */
+				mvPrintf("ERROR: AVS from EFUSE does not support current CPU frequncy (%u MHz)\n",
+						efuse_freq_val[i].cpu_freq);
+				mvPrintf("Please configure lower frequency mode in S@R\n");
+				avsRegControlVal = MV_REG_READ(AVS_ENABLED_CONTROL);
+				avsRegControlVal |= ((MV_AVS_DEFAULT_VALUE << AVS_LOW_VDD_LIMIT_OFFS)
+							| (MV_AVS_DEFAULT_VALUE << AVS_HIGH_VDD_LIMIT_OFFS));
+				MV_REG_WRITE(AVS_ENABLED_CONTROL, avsRegControlVal);
+				/* halt the CPU */
+				while (1)
+					;
+			}
+			/* if Bin value permits selected frequency mode,
+			 * read it's corresponding AVS value from EFUSE */
+			*avsVal = (MV_EFUSE_REG_READ(EFUSE_AVS_AND_BIN_REG) &
+					(EFUSE_AVS_VAL_MASK << EFUSE_AVS_VAL_OFFSET_AT_IND(i))) >>
+								EFUSE_AVS_VAL_OFFSET_AT_IND(i);
+			break;
+		}
+	}
+	if (i == EFUSE_FREQ_VAL_SIZE && satrFreq > efuse_freq_val[0].cpu_freq_mode) {
+		/* check if chip is configured to CPU frequency
+		 * that is unsupported by AVS @ EFUSE mapping */
+		mvPrintf("ERROR: selected CPU frequency (mode 0x%X) is not supported\n", satrFreq);
+		return MV_FALSE;
+	}
+	mvPrintf("Selected AVS value from eFuse: 0x%X (corresponding to frequency %uMHz) ",
+			*avsVal, efuse_freq_val[i].cpu_freq);
+	mvPrintf("EFUSE version %u\n", versionVal);
+	return MV_TRUE;
+}
+#endif /* CONFIG_ARMADA_38X */
+
 MV_STATUS mvGeneralInit(void)
 {
 	MV_U32 regData;
-
-	/* Update AVS debug control register */
-        MV_REG_WRITE(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
-
-        regData = MV_REG_READ(AVS_ENABLED_CONTROL);
-        regData &= ~(AVS_LOW_VDD_LIMIT_MASK | AVS_HIGH_VDD_LIMIT_MASK);
-	regData |= (AVS_LOW_VDD_LIMIT_VAL | AVS_HIGH_VDD_LIMIT_VAL);
-        MV_REG_WRITE(AVS_ENABLED_CONTROL, regData);
-
-	mvMppConfig();
+#ifdef CONFIG_ARMADA_38X
+	MV_U32 avsVal;
+#endif
+	mvMppConfig(); /* MPP must be configured prior to UART/I2C access */
 
 	/* - Init the TWSI before all I2C transaction */
 	DEBUG_INIT_FULL_S("mvGeneralInit: Init TWSI interface.\n");
+	/* I2C/TWSI unit must be initialized before mvUartInit is called,
+	 * since UART port is selected according to board ID
+	 * (read Board ID from EEPROM via I2C) */
 	mvHwsTwsiInitWrapper();
 
 #if !defined(MV_NO_PRINT)
@@ -139,9 +315,56 @@
 	mvPrintf("\n\nGeneral initialization - Version: " GENERAL_VERION "\n");
 #endif
 
+	/* Update AVS debug control register */
+	MV_REG_WRITE(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
+	MV_REG_WRITE(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
+
+	regData = MV_REG_READ(AVS_ENABLED_CONTROL);
+	regData &= ~(AVS_LOW_VDD_LIMIT_MASK | AVS_HIGH_VDD_LIMIT_MASK);
+
+#ifdef CONFIG_ARMADA_38X
+	/* 1. Armada38x was signed off for 1600/800 at 1.15V (AVS)
+	 * 2. Based on ATE/system correlation, in order to achieve higher speeds (1866MHz, 2000MHz),
+	 *    we need to overdrive the chip to 1.25V (AVS)
+	 *  3.1. If AVS values are not written on eFuse, The write to AVS is
+	 *      based on S@R (CPU <= 1600MHz --> AVS@ 1.15V)
+	 *  3.2. If AVS values are written to eFuse (version field is different than zero)
+	 *      This means that every frequency have corresponding AVS value written to eFuse,
+	 *      (corresponds to frequency below 1600MHz, equals 1866MHz or equals 2000MHz)
+	 *      Then write the corresponding AVS value.
+	 *      For security check, Bin value is burnt, that tells which is the maximum
+	 *      allowed frequency. If the S@R frequency higher than the maximum, the chip is
+	 *      halted (empty infinite loop), and 1.25V is written to AVS
+	 */
+	{
+		MV_U32 satrFreq;
+		satrFreq = (MV_REG_READ(DEVICE_SAMPLE_AT_RESET1_REG) >> SAR_FREQ_OFFSET) & SAR_FREQ_MASK;
+
+		if (mvGetAvsValFromEfuse(satrFreq, &avsVal) == MV_TRUE) {
+			regData |= ((avsVal << AVS_LOW_VDD_LIMIT_OFFS) | (avsVal << AVS_HIGH_VDD_LIMIT_OFFS));
+			MV_REG_WRITE(AVS_ENABLED_CONTROL, regData);
+		} else {
+			/*Set AVS value only for normative core freq(1600Mhz and less),
+			 * for high freq leave default value*/
+			if (satrFreq <= 0xD) {
+				regData |= ((AVS_LIMIT_VAL_SLOW << AVS_LOW_VDD_LIMIT_OFFS) |
+						(AVS_LIMIT_VAL_SLOW << AVS_HIGH_VDD_LIMIT_OFFS));
+				MV_REG_WRITE(AVS_ENABLED_CONTROL, regData);
+				mvPrintf("Overriding default AVS value to: 0x%X\n", AVS_LIMIT_VAL_SLOW);
+			}
+		}
+	}
+#else
+		regData |= ( (AVS_LIMIT_VAL << AVS_LOW_VDD_LIMIT_OFFS) | (AVS_LIMIT_VAL << AVS_HIGH_VDD_LIMIT_OFFS));
+		MV_REG_WRITE(AVS_ENABLED_CONTROL, regData);
+#endif
+
+	mvRtcConfig(); /* update RTC (Read Timing Control) values of PCIe memory wrappers*/
+
 	/* Device general configuration was not supported on a38x Z0 revision */
 	if (mvSysEnvDeviceRevGet() != MV_88F68XX_Z1_ID)
 		mvDeviceIdConfig();
+	mvSysEnvUsbVbusReset();
 
 	return MV_OK;
 }
diff --git a/tools/marvell/bin_hdr/src_init/a38x/generalInit.h b/tools/marvell/bin_hdr/src_init/a38x/generalInit.h
index 40dedc2..0b58006 100644
--- a/tools/marvell/bin_hdr/src_init/a38x/generalInit.h
+++ b/tools/marvell/bin_hdr/src_init/a38x/generalInit.h
@@ -65,6 +65,11 @@
 #ifndef __INCmvGeneralInith
 #define __INCmvGeneralInith
 
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+/* Virtual Reduced flavor Device ID is defined by REDUCED_FLAVOR value */
+//#define REDUCED_FLAVOR 0x383 /* 0x383: A383 - 6W21 */
+//#define REDUCED_FLAVOR 0x384 /* 0x384: A384 - 6W23 */
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
 #define GENERAL_VERION "1.0.0"
 
 #endif /* __INCmvGeneralInith */
diff --git a/tools/marvell/bin_hdr/src_init/msys/generalInit.c b/tools/marvell/bin_hdr/src_init/msys/generalInit.c
index a761177..23df43c 100755
--- a/tools/marvell/bin_hdr/src_init/msys/generalInit.c
+++ b/tools/marvell/bin_hdr/src_init/msys/generalInit.c
@@ -69,6 +69,7 @@
 #include "util.h"
 #include "mvSiliconIf.h"
 #include "generalInit.h"
+#include "mvSysEnvLib.h"
 
 #if defined(MV_MSYS_AC3)
 #include "ddr3_msys_ac3.h"
@@ -172,6 +173,7 @@
 	mvUartInit();
 	DEBUG_INIT_S("\n\nGeneral initialization - Version: " GENERAL_VERION "\n");
 #endif
+	mvHwsTwsiInitWrapper();
 
 	return MV_OK;
 }
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.c b/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.c
index ec325a1..4faea5e 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.c
@@ -177,7 +177,7 @@
 		if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
 			continue;
 
-		if ((serdesType != PEX0) &&
+		if ((serdesIdx != 0) &&
 				((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
 				 (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
 		{
@@ -197,7 +197,7 @@
 
 	for (serdesIdx = 0; serdesIdx < maxLaneNum; serdesIdx++) {
 		serdesType = serdesMap[serdesIdx].serdesType;
-		if ((serdesType != PEX0) &&
+		if ((serdesIdx != 0) &&
 				((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
 				 (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
 		{
@@ -244,7 +244,7 @@
 		if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
 			continue;
 
-		if ((serdesType != PEX0) &&
+		if ((serdesIdx != 0) &&
 				((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
 				 (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
 		{
@@ -324,7 +324,7 @@
 		if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
 			continue;
 
-		if ((serdesType != PEX0) &&
+		if ((serdesIdx != 0) &&
 				((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
 				 (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
 		{
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.h b/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.h
index 860150e..6357c4c 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.h
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvCtrlPex.h
@@ -89,6 +89,8 @@
 #define MAX_PEX_BUSSES                          256
 
 #define PEX_CAPABILITIES_REG(pexIf)			    ((MV_PEX_IF_REGS_BASE(pexIf)) + 0x60)
+#define PEX_LINK_CAPABILITIES_REG(pexIf)		((MV_PEX_IF_REGS_BASE(pexIf)) + 0x6C)
+#define PEX_LINK_CTRL_STATUS_REG(pexIf) 		((MV_PEX_IF_REGS_BASE(pexIf)) + 0x70)
 #define PEX_LINK_CTRL_STATUS2_REG(pexIf)        ((MV_PEX_IF_REGS_BASE(pexIf)) + 0x90)
 #define PEX_CTRL_REG(pexIf)                     ((MV_PEX_IF_REGS_BASE(pexIf)) + 0x1A00)
 #define PEX_STATUS_REG(pexIf)                   ((MV_PEX_IF_REGS_BASE(pexIf)) + 0x1A04)
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-38x.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-38x.c
index 63a6bd2..637acea 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-38x.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-38x.c
@@ -128,19 +128,21 @@
 /***************************************************************************/
 MV_U32 mvHwsSerdesGetMaxLane(MV_VOID)
 {
-    switch (mvSysEnvDeviceIdGet()) {
-    case MV_6811: /* A381/A3282: 6811/6821: single/dual cpu */
-        return 4;
-    case MV_6810:
-        return 5;
-    case MV_6820:
-    case MV_6828:
-        return 6;
-    default:    /* not the right module */
-        mvPrintf("%s: Device ID Error, using 4 SerDes lanes\n", __func__);
-        return 4;
-        }
-    return 6;
+	switch (mvSysEnvDeviceIdGet()) {
+	case MV_6811: /* A381/A3282: 6811/6821: single/dual cpu */
+	case MV_6W22: /* 6W22=A383 */
+	case MV_6W23: /* 6W23=A384 */
+		return 4;
+	case MV_6810:
+		return 5;
+	case MV_6820:
+	case MV_6828:
+		return 6;
+	default:    /* not the right module */
+		mvPrintf("%s: Device ID Error, using 4 SerDes lanes\n", __func__);
+		return 4;
+	}
+	return 6;
 }
 
 /***************************************************************************/
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-39x.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-39x.c
index 1c7be94..722b01b 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-39x.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec-39x.c
@@ -230,7 +230,10 @@
 
 		/* Executing power up, ref clock set, speed config and TX config */
 		switch (serdesType) {
-        case SGMII3:
+        case SGMIIv3_0:
+	case SGMIIv3_1:
+	case SGMIIv3_2:
+	case SGMIIv3_3:
 			CHECK_STATUS(mvSeqExec(serdesNum, SGMII_POWER_UP_SEQ));
 			CHECK_STATUS(mvHwsRefClockSet(serdesNum, serdesType, refClock));
 			CHECK_STATUS(mvSeqExec(serdesNum, speedSeqId));
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
index 2ecd3d4..03e8573 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.c
@@ -118,9 +118,11 @@
 /* SerdesLaneInUseCount contains the exact amount of serdes lanes needed per type */
 MV_U8 SerdesLaneInUseCount[MAX_UNITS_ID][MAX_UNIT_NUMB] =
 {
+	/* if PEX0 is defines as PEXx4 it can use 4 lanes; in PEXx1 only 1
+	the value for PEX 0 is updated in mvHwsSerdesTopologyVerify function */
 	/* 0  1  2  3    */
-	{  1, 1, 1, 1 },  /* PEX     */
-	{  1, 1, 1, 1 },  /* ETH_GIG */
+	{  4, 1, 1, 1 },  /* PEX     */
+	{  1, 1, 1, 1 },  /* ETH_SGMII */
 	{  1, 1, 0, 0 },  /* USB3H   */
 	{  1, 1, 1, 0 },  /* USB3D   */
 	{  1, 1, 1, 1 },  /* SATA    */
@@ -136,56 +138,61 @@
 MV_U8 commonPhysSelectorsSerdesRev2Map[LAST_SERDES_TYPE][MAX_SERDES_LANES] =
 {
 	/* 0      1      2       3       4       5       6 */
-	{ 0x1,   0x1,    NA,	 NA,	 NA,	 NA,     NA   },  /* PEX0 */
-	{ NA,    NA,     0x1,	 NA,	 0x1,	 NA,     0x1  },  /* PEX1 */
-	{ NA,    NA,     NA,	 NA,	 0x7,	 0x1,    NA	  },  /* PEX2 */
-	{ NA,    NA,     NA,	 0x1,	 NA,	 NA,     NA	  },  /* PEX3 */
-	{ 0x2,   0x3,    NA,	 NA,	 NA,	 NA,     NA	  },  /* SATA0 */
-	{ NA,    NA,     0x3,	 NA,	 NA,	 NA,     NA	  },  /* SATA1 */
-	{ NA,    NA,     NA,	 NA,	 0x6,	 0x2,    NA	  },  /* SATA2 */
-	{ NA,	 NA,     NA,	 0x3,	 NA,	 NA,     NA	  },  /* SATA3 */
-	{ 0x3,   0x4,    NA,     NA,	 NA,	 NA,     NA	  },  /* SGMII0 */
-	{ NA,    0x5,    0x4,    NA,	 0x3,	 NA,     NA	  },  /* SGMII1 */
-	{ NA,    NA,     NA,	 0x4,	 NA,	 0x3,    NA	  },  /* SGMII2 */
-	{ NA,    0x7,    NA,	 NA,	 NA,	 NA,     NA	  },  /* QSGMII */
-	{ NA,    0x6,    NA,	 NA,	 0x4,	 NA,     NA	  },  /* USB3_HOST0 */
-	{ NA,    NA,     NA,	 0x5,	 NA,	 0x4,    NA	  },  /* USB3_HOST1 */
-	{ NA,    NA,     NA,	 0x6,	 0x5,	 0x5,    NA	  },  /* USB3_DEVICE */
+	{ 0x1,   0x1,    NA,	 NA,	 NA,	 NA,     NA	},  /* PEX0 */
+	{ NA,    NA,     0x1,	 NA,	 0x1,	 NA,     0x1	},  /* PEX1 */
+	{ NA,    NA,     NA,	 NA,	 0x7,	 0x1,    NA	},  /* PEX2 */
+	{ NA,    NA,     NA,	 0x1,	 NA,	 NA,     NA	},  /* PEX3 */
+	{ 0x2,   0x3,    NA,	 NA,	 NA,	 NA,     NA	},  /* SATA0 */
+	{ NA,    NA,     0x3,	 NA,	 NA,	 NA,     NA	},  /* SATA1 */
+	{ NA,    NA,     NA,	 NA,	 0x6,	 0x2,    NA	},  /* SATA2 */
+	{ NA,	 NA,     NA,	 0x3,	 NA,	 NA,     NA	},  /* SATA3 */
+	{ 0x3,   0x4,    NA,     NA,	 NA,	 NA,     NA	},  /* SGMII0 */
+	{ NA,    0x5,    0x4,    NA,	 0x3,	 NA,     NA	},  /* SGMII1 */
+	{ NA,    NA,     NA,	 0x4,	 NA,	 0x3,    NA	},  /* SGMII2 */
+	{ NA,    0x7,    NA,	 NA,	 NA,	 NA,     NA	},  /* QSGMII */
+	{ NA,    0x6,    NA,	 NA,	 0x4,	 NA,     NA	},  /* USB3_HOST0 */
+	{ NA,    NA,     NA,	 0x5,	 NA,	 0x4,    NA	},  /* USB3_HOST1 */
+	{ NA,    NA,     NA,	 0x6,	 0x5,	 0x5,    NA	},  /* USB3_DEVICE */
 #ifdef MV88F69XX
-	{ NA,    NA,     0x5,	 NA,	 0x8,	 NA,     0x2  },  /* SGMII3 */
+	{ 0x4,	 0x8,    NA,	 NA,	 NA,	 NA,     NA   },  /* SGMIIv3-0 */
+	{ NA,    0x9,    0x5,	 NA,	 NA,	 NA,     NA   },  /* SGMIIv3-1 */
+	{ NA,    NA,     NA,	 0x7,	 NA,	 0x6,    NA   },  /* SGMIIv3-2 */
+	{ NA,    NA,     NA,	 NA,	 0x8,	 NA,     0x2  },  /* SGMIIv3-3 */
 	{ NA,    NA,     NA,	 0x8,	 0x9,	 0x8,    0x4  },  /* XAUI */
 	{ NA,    NA,     NA,	 NA,	 NA,	 0x8,    0x4  },  /* RXAUI */
 #endif
-	{ 0x0,   0x0,    0x0,	 0x0,	 0x0,	 0x0,    NA	  }   /* DEFAULT_SERDES */
+	{ 0x0,   0x0,    0x0,	 0x0,	 0x0,	 0x0,    NA   }   /* DEFAULT_SERDES */
 };
 
 /* Selector mapping for PEX by 4 confiuration */
 MV_U8 commonPhysSelectorsPexBy4Lanes[] = { 0x1, 0x2, 0x2, 0x2 };
 
 static const char *serdesTypeToString[] = {
-	"PCIe0",
-	"PCIe1",
-	"PCIe2",
-	"PCIe3",
-	"SATA0",
-	"SATA1",
-	"SATA2",
-	"SATA3",
-	"SGMII0",
-	"SGMII1",
-	"SGMII2",
-	"QSGMII",
-	"USB3 HOST0",
-	"USB3 HOST1",
+	"PCIe0      ",
+	"PCIe1      ",
+	"PCIe2      ",
+	"PCIe3      ",
+	"SATA0      ",
+	"SATA1      ",
+	"SATA2      ",
+	"SATA3      ",
+	"SGMII0     ",
+	"SGMII1     ",
+	"SGMII2     ",
+	"QSGMII     ",
+	"USB3 HOST0 ",
+	"USB3 HOST1 ",
 	"USB3 DEVICE",
-    "SGMII3",
-    "XAUI",
-    "RXAUI",
+	"SGMIIv3-0  ",
+	"SGMIIv3-1  ",
+	"SGMIIv3-2  ",
+	"SGMIIv3-3  ",
+	"XAUI       ",
+	"RXAUI      ",
 	"DEFAULT SERDES",
 	"LAST_SERDES_TYPE"
 };
 
-
 typedef struct serdesUnitData {
 	MV_U8 serdesUnitId;
 	MV_U8 serdesUnitNum;
@@ -200,16 +207,19 @@
 	{	SATA_UNIT_ID,	1,	},
 	{	SATA_UNIT_ID,	2,	},
 	{	SATA_UNIT_ID,	3,	},
-	{	ETH_GIG_UNIT_ID,0,	},
-	{	ETH_GIG_UNIT_ID,1,	},
-	{	ETH_GIG_UNIT_ID,2,	},
+	{	SGMII_UNIT_ID,0,	},
+	{	SGMII_UNIT_ID,1,	},
+	{	SGMII_UNIT_ID,2,	},
 	{	QSGMII_UNIT_ID,	0,	},
 	{	USB3H_UNIT_ID,	0,	},
 	{	USB3H_UNIT_ID,	1,	},
 	{	USB3D_UNIT_ID,	0,	},
-    {	ETH_GIG_UNIT_ID,3,	},
-    {	XAUI_UNIT_ID,	0,	},
-    {	RXAUI_UNIT_ID,	0,	},
+	{	SGMII_UNIT_ID,0,	},
+	{	SGMII_UNIT_ID,1,	},
+	{	SGMII_UNIT_ID,2,	},
+	{	SGMII_UNIT_ID,3,	},
+	{	XAUI_UNIT_ID,	0,	},
+	{	RXAUI_UNIT_ID,	0,	},
 };
 
 
@@ -248,7 +258,7 @@
 	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,           0x90006,	{ 0x80002,		0x80002 }, 		0,          0       },  /* Power Up */
 	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,		    0x7800,		{ 0x6000,		0x6000  }, 		0,		    0       },  /* Unreset */
 	{ POWER_AND_PLL_CTRL_REG,	 	    0x800,		    0x0E0,		{ 0x0,			0x80    }, 		0,		    0       },  /* Phy Selector */
-    { MISC_REG,			 		        0x800,		    0x440,		{ 0x440,	    0x400	},      0,	        0	    }   /* Ref clock source select */ 
+    { MISC_REG,			 		        0x800,		    0x440,		{ 0x440,	    0x400	},      0,	        0	    }   /* Ref clock source select */
 };
 
 /* SATA and SGMII - speed config seq */
@@ -338,7 +348,7 @@
     { G2_SETTINGS_1_REG,			0x800,	  0x3FF,	{ 0x3D2		},	0,	    0	},  /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
     { G3_SETTINGS_0_REG,			0x800,	  0xFFFF,	{ 0xE6E		},	0,	    0	},  /* G3_TX SLEW, EMPH1 and AMP */
     { G3_SETTINGS_1_REG,			0x800,	  0x47FF,	{ 0x7D2		},	0,	    0	},  /* G3_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI & DFE_En Gen3, DC wander calibration dis */
-    { PCIE_REG0,        			0x800,    0x1000,	{ 0x0		},	0,	    0   },  /* Bit[12]=0x0 – idle_sync_en */
+    { PCIE_REG0,        			0x800,    0x1000,	{ 0x0		},	0,	    0   },  /* Bit[12]=0x0  idle_sync_en */
     { RX_REG2,          			0x800,    0xF0,		{ 0x70,		},	0,	    0   },  /* Dtl Clamping disable and Dtl clamping Sel(6000ppm) */
     { VTHIMPCAL_CTRL_REG,			0x800,	  0xFF00,	{ 0x3000	},	0,	    0	}, /* tximpcal_th and rximpcal_th */
     { DFE_REG0,         			0x800,    0xA00F,	{ 0x800A	},	0,	    0   }, /* DFE_STEP_FINE_FX[3:0] =0xA */
@@ -381,20 +391,20 @@
 	{ COMMON_PHY_CONFIGURATION4_REG,    0x28,			0x3,			{ 0x1,		    0x1         },		0,          0	    },
 	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,			0x7800,			{ 0x6000,	    0xE000      },		0,          0	    },
 	{ GLOBAL_CLK_CTRL,				    0x800,			0xD,			{ 0x5,		    0x1         },		0,          0	    },
-	{ MISC_REG,	   					    0x800,          0x4C0,	     	{ 0x80,         0x4C0 	    }, 	    0,	        0       }  /* Ref clock source select */ 
+	{ MISC_REG,	   					    0x800,          0x4C0,	     	{ 0x80,         0x4C0 	    }, 	    0,	        0       }  /* Ref clock source select */
 };
 
 /* PEX and USB3 - power up seq for Serdes Rev 2.1 */
 MV_OP_PARAMS pexAndUsb3PowerUpSerdesRev2Params[] =
 {
 	/* unitunitBaseReg                  unitOffset      mask            PEX data        USB3 data       waitTime    numOfLoops */
-	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,		    0x3FC7F806,     { 0x4471804,    0x4479804   },      0,          0	    },
-	{ COMMON_PHY_CONFIGURATION2_REG,    0x28,			0x5C,		    { 0x58,		    0x58        },		0,          0	    },
-	{ COMMON_PHY_CONFIGURATION4_REG,    0x28,			0x3,			{ 0x1,		    0x1         },		0,          0	    },
-	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,			0x7800,			{ 0x6000,	    0xE000      },		0,          0	    },
-	{ GLOBAL_CLK_CTRL,				    0x800,			0xD,			{ 0x5,		    0x1         },		0,          0	    },
-	{ GLOBAL_MISC_CTRL,				    0x800,			0xC0,			{ 0x0,		    NO_DATA     },		0,          0	    },
-	{ MISC_REG,	   					    0x800,	    	0x4C0,	     	{ 0x80,         0x4C0 	    }, 	    0,	        0		}  /* Ref clock source select */ 
+	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,	0x3FC7F806,     { 0x4471804,    0x4479804   },		0,          0	    },
+	{ COMMON_PHY_CONFIGURATION2_REG,    0x28,	0x5C,		{ 0x58,		    0x58    },		0,          0	    },
+	{ COMMON_PHY_CONFIGURATION4_REG,    0x28,	0x3,		{ 0x1,		    0x1     },		0,          0	    },
+	{ COMMON_PHY_CONFIGURATION1_REG,    0x28,	0x7800,		{ 0x6000,	    0xE000  },		0,          0	    },
+	{ GLOBAL_CLK_CTRL,		    0x800,	0x3D,		{ 0x35,		    0x21    },		0,          0	    },
+	{ GLOBAL_MISC_CTRL,		    0x800,	0xC0,		{ 0x0,		    NO_DATA },		0,          0	    },
+	{ MISC_REG,	   		    0x800,   	0x4C0,		{ 0x80,		    0x4C0   },		0,	    0	    }  /* Ref clock source select */
 };
 
 /* PEX and USB3 - speed config seq */
@@ -419,14 +429,24 @@
 
 MV_OP_PARAMS usb3ElectricalConfigSerdesRev2Params[] =
 {
-	{ LANE_CFG4_REG,			0x800,		0x80,		{ 0x80      },		0,			0	 	}, /* Spread Spectrum Clock Enable */
-	{ G2_SETTINGS_2_REG,		0x800,		0xFE40,		{ 0x4440    },		0,          0	 	}, /* G2_TX_SSC_AMP[6:0]=4.5kPPM and TX emphasis mode=mV */
-	{ G2_SETTINGS_1_REG,		0x800,		0x3FF,		{ 0x3D2     },		0,          0	 	}, /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
-	{ RX_REG2,				 	0x800,		0xF0,		{ 0x70      },		0,          0	 	}, /* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
-	{ REF_REG0,		 			0x800,		0x38,		{ 0x20      },		0,          0	 	}, /* vco_cal_vth_sel */
-    { LANE_CFG5_REG,			0x800,		0x4,		{ 0x4       },		0,			0	 	}, /* Spread Spectrum Clock Enable */
-};
+	{ LANE_CFG4_REG,		0x800,		0xC2,		{ 0xC0		},	0,	0 	}, /* Bit[7]=0x1 - Spread Spectrum Clock Enable,Bit[6]-0x1- CFG_DFE_OVERRIDE,Bit[1]-0x0-PIN_DFE_PAT_DIS, */
+	{ LANE_CFG5_REG,		0x800,		0x3,		{ 0x3		},		0,	0 	}, /* Bit[1]=0x1 - CFG_SQ_DET_SEL,Bit[0]=0x1-CFG_RX_INIT_SEL, */
+	{ G2_SETTINGS_2_REG,		0x800,		0xFE40,		{ 0x4440	},		0,      0 	}, /* Bits[15:9]= 0x22 -G2_TX_SSC_AMP[6:0]=4.5kPPM,Bits[6] = 0x1 - TX emphasis mode=mV */
+	{ G2_SETTINGS_3_REG,		0x800,		0xFF,		{ 0xEF		},		0,      0 	}, /* Bit[7] =0x1  FFE Setting Force;Bits[6:4]=0x6  FFE_RES;Bits[3:0] = 0xF  FFE_CAP; */
+	{ G2_SETTINGS_4_REG,		0x800,		0x300,		{ 0x300		},		0,      0 	}, /* Bits[9:8]=0x0 -  G2_DFE_RES[1:0]*/
+	{ PLLINTP_REG1,	        	0x800,		0x300,		{ 0x300		},		0,      0 	}, /* Bits[9:8]=0x3  HPF_Bw[1:0] */
+	{ VTHIMPCAL_CTRL_REG,		0x800,		0xFF00,		{ 0x3000	},		0,	0 	}, /* Bits[15:12]= 0x3 - tximpcal_th;Bits[11:8] = 0x0 - RXIMPCAL_TH */
+	{ LANE_CFG5_REG,		0x800,		0x3,		{ 0x3		},		0,	0 	}, /* Bit[1]=0x1 - CFG_SQ_DET_SEL,Bit[0]=0x1-CFG_RX_INIT_SEL, */
+	{ MISC_REG,	            	0x800,		0x42F,		{ 0x42A		},		0,      0 	}, /* Bit[10]=0x1 - REFCLK_SEL(=25Mhz);Bit[5]=0x1  ICP_FORCE_En;Bits[3:0]=0xA  ICP=0xA(210uA); */
+	{ POWER_AND_PLL_CTRL_REG,	0x800,		0x1F,		{ 0x02		},		0,      0 	}, /* Bits[4:0] =0x2 - REF_FREF_SEL(=25Mhz) */
+	{ G2_SETTINGS_1_REG,		0x800,		0x3FF,		{ 0x3D2		},		0,      0 	}, /* Bits[9:8]=0x3- G2_RX_SELMUFF;Bits[7:6]=0x3- G2_RX_SELMUFI;Bits[5:3]=0x2  G2_RX_SELMUPF;Bits[2:0]=0x2 -  G2_RX_SELMUPI*/
+	{ RX_REG2,			0x800,		0xF0,		{ 0x70		},		0,      0 	}, /* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
+	{ PCIE_REG1,			0x800,		0xF80,		{ 0xD00		},		0,      0 	}, /* Bits[11:7]=0x1a -  tx_amp_pipe_v0[4:0] */
+	{ REF_REG0,		 	0x800,		0x38,		{ 0x20		},		0,      0 	}, /* vco_cal_vth_sel */
+	{ LANE_CFG0_REG,		0x800,		0x1,		{ 0x1		},		0,	0 	}, /* Bit[0]=0x1- PRD_TXDEEMPH0 */
+	{ GLOBAL_TEST_CTRL,		0x800,		0x4,		{ 0x4		},		0,      0 	}, /* Bit[4]=0x1-MODE_MARGIN_OVERRIDE */
 
+};
 /* PEX and USB3 - TX config seq */
 
 /* For PEXx1: the pexAndUsb3TxConfigParams1/2/3 configurations should run
@@ -438,9 +458,6 @@
     /* unitBaseReg    unitOffset    mask        PEX data    USB3 data   waitTime    numOfLoops */
     { GLOBAL_CLK_CTRL,  0x800,      0x1,        { 0x0,      0x0     },      0,          0       },
     { 0x0,              0x0,        0x0,        { 0x0,      0x0     },      10,         0       }, /* 10ms delay */
-    { RX_REG3,          0x800,      0xFF,       { 0xDC,     NO_DATA },      0,          0       }, /* os_ph_offset_force (align 90) */
-    { RX_REG3,          0x800,      0x100,      { 0x100,    NO_DATA },      0,          0       }, /* Set os_ph_valid */
-    { RX_REG3,          0x800,      0x100,      { 0x0,      NO_DATA },      0,          0       }, /* Unset os_ph_valid */
 };
 
 MV_OP_PARAMS pexAndUsb3TxConfigParams2[] =
@@ -452,18 +469,21 @@
 MV_OP_PARAMS pexAndUsb3TxConfigParams3[] =
 {
 	/* unitBaseReg    unitOffset   	mask        PEX data    USB3 data   waitTime    numOfLoops */
-	{ RESET_DFE_REG,   	0x800,		0x401,      { 0x0,      0x0     }, 	    0,          0		}, /* Sft Reset pulse */
-	{ 0x0,		   		0x0,		0x0,	    { 0x0,      0x0     }, 	    10,	        0		}  /* 10ms delay */
+	{ RESET_DFE_REG,    0x800,	0x401,      { 0x0,      0x0     },	0,          0		}, /* Sft Reset pulse */
+	{ 0x0,		    0x0,	0x0,	    { 0x0,      0x0     }, 	10,	    0		}, /* 10ms delay */
+	{ RX_REG3,          0x800,      0xFF,       { 0xDC,     0xD8    },      0,          0           }, /* os_ph_offset_force (align 90) */
+	{ RX_REG3,          0x800,      0x100,      { 0x100,    0x100   },      0,          0           }, /* Set os_ph_valid */
+	{ RX_REG3,          0x800,      0x100,      { 0x0,      0x0     },      0,          0           }, /* Unset os_ph_valid */
 };
 
 /* PEX by 4 config seq */
 MV_OP_PARAMS pexBy4ConfigParams[] =
 {
 	/* unitunitBaseReg      unitOffset   mask           data                			waitTime   numOfLoops */
-	{ GLOBAL_CLK_SRC_HI,	0x800,       0x7,      { 0x5, 0x0, 0x0, 0x2 			},     	0,          0       },
-    { LANE_ALIGN_REG0,      0x800,       0x1000,   { 0x0, 0x0, 0x0, 0x0 			},     	0,	        0       }, /* Lane Alignement enable */
-	{ CALIBRATION_CTRL_REG,	0x800,       0x1000,   { 0x1000, 0x1000, 0x1000, 0x1000 },		0,	        0       }, /* Max PLL phy config */
-	{ LANE_CFG1_REG,		0x800,       0x600,    { 0x600, 0x600, 0x600, 0x600 	},		0,	        0       }, /* Max PLL pipe config */
+	{ GLOBAL_CLK_SRC_HI,	0x800,       0x7,      { 0x5, 0x0, 0x0, 0x2 			},     	0,		0       },
+	{ LANE_ALIGN_REG0,      0x800,       0x1000,   { 0x0, 0x0, 0x0, 0x0 			},     	0,		0       }, /* Lane Alignement enable */
+	{ CALIBRATION_CTRL_REG,	0x800,       0x1000,   { 0x1000, 0x1000, 0x1000, 0x1000		},	0,	        0       }, /* Max PLL phy config */
+	{ LANE_CFG1_REG,	0x800,       0x600,    { 0x600, 0x600, 0x600, 0x600 		},	0,	        0       }, /* Max PLL pipe config */
 };
 
 /* USB3 device donfig seq */
@@ -548,9 +568,21 @@
 	{ 0xC000C ,        0x0 /*NA*/,	0x1000000,  {0x1000000},  0,        0}, /* Phy0 register 3  - TX Channel control 0 */
 	{ 0xC200C ,        0x0 /*NA*/,	0x1000000,  {0x1000000},  0,        0}, /* Phy0 register 3  - TX Channel control 0 */
 	{ 0xC400C ,        0x0 /*NA*/,	0x1000000,  {0x1000000},  0,        0}, /* Phy0 register 3  - TX Channel control 0 */
-	{ 0xC0008 ,        0x0 /*NA*/,	0x80800000, {0x80800000}, 1,     1000}, /* check PLLCAL_DONE is set and IMPCAL_DONE is set*/
-	{ 0xC0018 ,        0x0 /*NA*/,	0x80000000, {0x80000000}, 1,     1000}, /* check REG_SQCAL_DONE  is set*/
-	{ 0xC0000 ,        0x0 /*NA*/,	0x80000000, {0x80000000}, 1,     1000}  /* check PLL_READY  is set*/
+	{ 0xC000C ,        0x0 /*NA*/,	0xf000,     {0x1000},     0,        0}, /* Decrease the amplitude of the low speed eye to meet the spec */
+	{ 0xC200C ,        0x0 /*NA*/,	0xf000,     {0x1000},     0,        0}, /* Decrease the amplitude of the low speed eye to meet the spec */
+	{ 0xC400C ,        0x0 /*NA*/,	0xf000,     {0x1000},     0,        0}, /* Decrease the amplitude of the low speed eye to meet the spec */
+	{ 0xC0008 ,        0x0 /*NA*/,	0x700,      {0x600},      0,        0}, /* Change the High speed impedance threshold */
+	{ 0xC2008 ,        0x0 /*NA*/,	0x700,      {0x600},      0,        0}, /* Change the High speed impedance threshold */
+	{ 0xC4008 ,        0x0 /*NA*/,	0x700,      {0x600},      0,        0}, /* Change the High speed impedance threshold */
+	{ 0xC0014 ,        0x0 /*NA*/,	0xf,        {0x8},        0,        0}, /* Change the squelch level of the receiver to meet the receiver electrical measurements(squelch and receiver sensitivity tests) */
+	{ 0xC2014 ,        0x0 /*NA*/,	0xf,        {0x8},        0,        0}, /* Change the squelch level of the receiver to meet the receiver electrical measurements(squelch and receiver sensitivity tests) */
+	{ 0xC4014 ,        0x0 /*NA*/,	0xf,        {0x8},        0,        0}, /* Change the squelch level of the receiver to meet the receiver electrical measurements(squelch and receiver sensitivity tests) */
+	{ 0xC0008 ,        0x0 /*NA*/,	0x80800000, {0x80800000}, 1,     1000}, /* Check PLLCAL_DONE is set and IMPCAL_DONE is set*/
+	{ 0xC0018 ,        0x0 /*NA*/,	0x80000000, {0x80000000}, 1,     1000}, /* Check REG_SQCAL_DONE  is set*/
+	{ 0xC0000 ,        0x0 /*NA*/,	0x80000000, {0x80000000}, 1,     1000}, /* Check PLL_READY  is set*/
+	{ 0xC0008 ,        0x0 /*NA*/,	0x2000,     {0x2000},     0,        0}, /* Start calibrate of high seed impedance */
+	{ 0x0 ,            0x0 /*NA*/,	0x0,        {0x0},        10,       0},
+	{ 0xC0008 ,        0x0 /*NA*/,	0x2000,     {0x0},        0,        0}, /* De-assert  the calibration signal */
 };
 
 /*****************/
@@ -561,7 +593,9 @@
 MV_OP_PARAMS qsgmiiPortPowerUpParams[] =
 {
 	/* unitBaseReg                    unitOffset   	mask         QSGMII data		waitTime   numOfLoops */
-	{ QSGMII_CONTROL_REG1,				0x0,  		0x40000000,	{ 0x40000000	}, 	   0,		  0 },	  /* Connect the QSGMII to Gigabit Ethernet units */
+	{ QSGMII_CONTROL_REG1,				0x0,  		0x44000000,	{ 0x44000000	}, 	   0,		  0 },	  /* Connect QSGMII to Gigabit Ethernet units;
+                                                                                                             Set sampling edge of Tx QSGMII to be positive
+                                                                                                             to achive port the stability - JIRA-1282    */
 	{ COMMON_PHY_CONFIGURATION1_REG,	0x28,  		0xF0006,	{ 0x80002		}, 	   0,		  0 },	  /* Power Up */
 	{ COMMON_PHY_CONFIGURATION1_REG,	0x28,		0x7800,	    { 0x6000		}, 	   0,		  0 },	  /* Unreset */
 	{ POWER_AND_PLL_CTRL_REG,			0x800,		0xFF,	    { 0xFC81		}, 	   0,		  0 },	  /* Phy Selector */
@@ -591,9 +625,9 @@
 	{ GLUE_REG,			              0x800,	  0x1800,     { 0x800		},     0,	       0		   },
 	{ RESET_DFE_REG,		          0x800,	  0x401,	  { 0x401		},     0,	       0		   }, /* Sft Reset pulse */
 	{ RESET_DFE_REG,		          0x800,	  0x401,	  { 0x0			},     0,	       0		   }, /* Sft Reset pulse */
-    { LANE_ALIGN_REG0,                0x800,	  0x1000,	  { 0x1000		},     0,	       0		   }, /* Lane align */
-    { COMMON_PHY_CONFIGURATION1_REG,  0x28,		  0x70000,    { 0x70000		},     0,	       0		   }, /* Power up PLL, RX and TX */
-    { COMMON_PHY_CONFIGURATION1_REG,  0x28,		  0x80000,    { 0x80000		},     0,	       0		   }  /* Tx driver output idle */
+	{ LANE_ALIGN_REG0,                0x800,	  0x1000,	  { 0x1000		},     0,	       0		   }, /* Lane align */
+	{ COMMON_PHY_CONFIGURATION1_REG,  0x28,		  0x70000,    { 0x70000		},     0,	       0		   }, /* Power up PLL, RX and TX */
+	{ COMMON_PHY_CONFIGURATION1_REG,  0x28,		  0x80000,    { 0x80000		},     0,	       0		   }  /* Tx driver output idle */
 };
 
 MV_OP_PARAMS qsgmiiPortTxConfigParams2[] =
@@ -641,8 +675,7 @@
 
 MV_U32 mvHwsSerdesTopologyVerify(SERDES_TYPE serdesType, MV_U32 serdesId, SERDES_MODE serdesMode)
 {
-
-	MV_U32 testResult = 0;
+	MV_U32 testResult = TOPOLOGY_TEST_OK;
 	MV_U8 serdMaxNumb,unitNumb;
 	MV_UNIT_ID unitId;
 
@@ -654,42 +687,43 @@
 	unitNumb =serdesTypeToUnitInfo[serdesType].serdesUnitNum;
 	serdMaxNumb = mvSysEnvUnitMaxNumGet(unitId);
 
-	if (SerdesLaneInUseCount[unitId][unitNumb] != 0) {		/* if didn't exceed amount of required Serdes lanes for current type */
-		SerdesLaneInUseCount[unitId][unitNumb]--;			/* update amount of required Serdes lanes for current type */
-
-		if (SerdesLaneInUseCount[unitId][unitNumb] == 0){	/* if reached the exact amount of required Serdes lanes for current type */
-		if (((serdesType <= PEX3)) && ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4)))
-			serdesUnitCount[PEX_UNIT_ID] +=2;				/* PCiex4 uses 2 SerDes */
-		else
-			serdesUnitCount[unitId]++;
-
-		if (serdesUnitCount[unitId] > serdMaxNumb)			/* test SoC unit count limitation */
-			testResult = WRONG_NUMBER_OF_UNITS;
-		else if (unitNumb >= serdMaxNumb)					/* test SoC unit number limitation */
-			testResult = UNIT_NUMBER_VIOLATION;
-		}
-	}
-	else
-	{
+	if (SerdesLaneInUseCount[unitId][unitNumb] == 0) {
 		testResult = SERDES_ALREADY_IN_USE;
-		if (testResult == SERDES_ALREADY_IN_USE)
-		{
-			mvPrintf("%s: Error: serdes lane %d is configured to type %s: type already in use\n", __func__, serdesId, serdesTypeToString[serdesType]);
-			return MV_FAIL;
+	} else {
+	/* if didn't exceed amount of required Serdes lanes for current type */
+		if (serdesType == PEX0){
+		   if(serdesMode != PEX_END_POINT_x4){
+			   if(serdesMode != PEX_ROOT_COMPLEX_x4){
+		    /* SerdesLaneInUseCount for PEX0 = 4 , but if it is PCIex1 only 1 lane may be used  */
+			SerdesLaneInUseCount[unitId][unitNumb] = 1;
+			}
+		   }
 		}
-		else if (testResult == WRONG_NUMBER_OF_UNITS)
-		{
-			mvPrintf("%s: Warning: serdes lane %d is set to type %s.\n", __func__, serdesId,serdesTypeToString[serdesType]);
-			mvPrintf("%s: Maximum supported lanes are already set to this type (limit = %d)\n", __func__, serdMaxNumb);
-			return MV_FAIL;
-		}
+		SerdesLaneInUseCount[unitId][unitNumb]--;			/* update amount of required Serdes lanes for current type */
+        if (SerdesLaneInUseCount[unitId][unitNumb] == 0)/* if reached the exact amount of required Serdes lanes for current type */
+        {
+		    if((serdesType <= PEX3) && ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4)))
+			    serdesUnitCount[PEX_UNIT_ID] +=2;				/* PCiex4 uses 2 SerDes */
+		    else
+                serdesUnitCount[unitId]++;
 
-		else if (testResult == UNIT_NUMBER_VIOLATION)
-		{
-			mvPrintf("%s: Warning: serdes lane %d type is %s: current device support only %d units of this type.\n", __func__, serdesId, serdesTypeToString[serdesType],serdMaxNumb );
-			return MV_FAIL;
+            if (serdesUnitCount[unitId] > serdMaxNumb)			/* test SoC unit count limitation */
+                testResult = WRONG_NUMBER_OF_UNITS;
 		}
 	}
+
+	if (testResult == SERDES_ALREADY_IN_USE) {
+		mvPrintf("%s: Error: serdes lane %d is configured ", __func__, serdesId);
+		mvPrintf("to type %s: type already in use\n", serdesTypeToString[serdesType]);
+		return MV_FAIL;
+	} else if (testResult == WRONG_NUMBER_OF_UNITS) {
+		mvPrintf("%s: Warning: serdes lane %d is ", __func__, serdesId);
+		mvPrintf("set to type %s.\n", serdesTypeToString[serdesType]);
+		mvPrintf("%s: Maximum supported lanes are ", __func__);
+		mvPrintf("already set to this type (limit = %d)\n", serdMaxNumb);
+		return MV_FAIL;
+	}
+
 	return MV_OK;
 }
 
@@ -708,7 +742,13 @@
  }
 
 }
-
+MV_VOID mvHwsSerdesPCIX4TopologyVerify(MV_VOID )
+{
+	if (SerdesLaneInUseCount[PEX_UNIT_ID][0] != 0) {
+		mvPrintf("%s: Warning: wrong number of lanes is set to PEX0 - %d\n", __func__, SerdesLaneInUseCount[PEX_UNIT_ID][0]);
+		mvPrintf("%s: PCIex4 has to be defined on 4 lanes\n", __func__);
+	}
+}
 MV_STATUS mvHwsSerdesSeqDbInit(MV_VOID)
 {
 	DEBUG_INIT_FULL_S("\n### serdesSeq38xInit ###\n");
@@ -917,7 +957,7 @@
 		serdesSeqDb[USB3_ELECTRICAL_CONFIG_SEQ].opParamsPtr = usb3ElectricalConfigSerdesRev2Params;
 		serdesSeqDb[USB3_ELECTRICAL_CONFIG_SEQ].cfgSeqSize  = sizeof(usb3ElectricalConfigSerdesRev2Params) / sizeof(MV_OP_PARAMS);
 	}
-	serdesSeqDb[USB3_ELECTRICAL_CONFIG_SEQ].dataArrIdx = USB3;
+	serdesSeqDb[USB3_ELECTRICAL_CONFIG_SEQ].dataArrIdx = FIRST_CELL;
 
 	/* USB3_TX_CONFIG_SEQ sequence init */
 	serdesSeqDb[USB3_TX_CONFIG_SEQ1].opParamsPtr = pexAndUsb3TxConfigParams1;
@@ -1023,7 +1063,10 @@
 	case SGMII1:
 	case SGMII2:
 #ifdef MV88F69XX
-    case SGMII3:
+    case SGMIIv3_0:
+    case SGMIIv3_1:
+    case SGMIIv3_2:
+    case SGMIIv3_3:
 #endif
         if (baudRate == __1_25Gbps)
 			seqId = SGMII__1_25_SPEED_CONFIG_SEQ;
@@ -1067,33 +1110,34 @@
 
 MV_VOID printTopologyDetails(SERDES_MAP  *serdesMapArray)
 {
-	MV_U32 laneNum;
+	MV_U32 laneNum, pexBy4Lane=0;
 
-	DEBUG_INIT_S("board SerDes lanes topology details:\n");
+	mvPrintf("board SerDes lanes topology details:\n");
 
-	DEBUG_INIT_S(" | Lane #  | Speed |  Type       |\n");
-	DEBUG_INIT_S(" --------------------------------\n");
+	mvPrintf(" | Lane # | Speed|    Type     |\n");
+	mvPrintf(" ------------------------------|\n");
 	for (laneNum = 0; laneNum < mvHwsSerdesGetMaxLane(); laneNum++) {
 		if (serdesMapArray[laneNum].serdesType == DEFAULT_SERDES)
 		{
 			continue;
 		}
-		DEBUG_INIT_S(" |   ");
-		DEBUG_INIT_D(mvHwsGetPhysicalSerdesNum(laneNum), 1);
-		DEBUG_INIT_S("    |  ");
-		DEBUG_INIT_D(serdesMapArray[laneNum].serdesSpeed, 2);
-		DEBUG_INIT_S("   |  ");
-		DEBUG_INIT_S((char *)serdesTypeToString[serdesMapArray[laneNum].serdesType]);
-		DEBUG_INIT_S("\t|\n");
+		mvPrintf (" |   %d    |  %d   |  ",mvHwsGetPhysicalSerdesNum(laneNum),serdesMapArray[laneNum].serdesSpeed);
+		if ((serdesMapArray[laneNum].serdesMode == PEX_END_POINT_x4) || (serdesMapArray[laneNum].serdesMode == PEX_ROOT_COMPLEX_x4)){
+			mvPrintf ("PCIe0x4-%01d  ",pexBy4Lane++ );
+		}
+		else{
+			mvPrintf ("%s",serdesTypeToString[serdesMapArray[laneNum].serdesType]);
+		}
+		mvPrintf("|\n");
 	}
-	DEBUG_INIT_S(" --------------------------------\n");
+	mvPrintf(" -------------------------------\n");
 }
 
 
 /***************************************************************************/
 MV_STATUS mvHwsPreSerdesInitConfig(MV_VOID)
 {
-    MV_U32 data;
+    MV_U32 data, refClkSatR;
 
     /* configure Core PLL */
     /*
@@ -1103,8 +1147,13 @@
     bits[24:21]=0x7(Core-PLL VCO Band)
     bits[28:25]=0x1(Core-PLL Rlf)
     bits[31:29]=0x2(Core-PLL charge-pump adjust)
+    (the configuration valid only for refclk 25Mhz, for 40Mhz better default configuration at this time)
     */
-    MV_REG_WRITE(CORE_PLL_PARAMETERS_REG, 0x42E9F003);
+	refClkSatR = MV_REG_READ(DEVICE_SAMPLE_AT_RESET2_REG);
+	if(((refClkSatR >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) == DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ){
+		/*Skip the configuration in REFLK 40Mhz mode*/
+		MV_REG_WRITE(CORE_PLL_PARAMETERS_REG, 0x42E9F003);
+	}
 
     /* Enable PLL Configuration */
     data = MV_REG_READ(CORE_PLL_CONFIG_REG);
@@ -1172,6 +1221,90 @@
 	return MV_OK;
 }
 
+MV_VOID mvHwsUpdateSerdesPhySelectorsOptions  ( MV_VOID)
+{
+	MV_U32 devId, currType,currLane;
+
+    /* update selectors options according to Device limitation*/
+	if ( mvSysEnvDeviceRevGet() == MV_88F69XX_Z1_ID) /* for Z1 SGMII(v3)_0  cannot be defined on lane6 */
+	   commonPhysSelectorsSerdesRev2Map[SGMIIv3_0][6] = NA;
+
+	/* Read HW device ID from S@R */
+	devId = mvSysEnvDeviceIdGet();
+
+    switch (devId)
+    {
+	case MV_6810:
+        /* lane 4 is not in use in 6810*/
+        for (currType = 0;currType < LAST_SERDES_TYPE; currType++)
+            commonPhysSelectorsSerdesRev2Map[currType][4] = NA;
+        /* SATA 2 and SATA 3 are not functional in 6810*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+        {
+            commonPhysSelectorsSerdesRev2Map[SATA3][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA2][currLane] = NA;
+        }
+        break;
+	case MV_6811:
+        /* no QSGMII in 6811*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+            commonPhysSelectorsSerdesRev2Map[QSGMII][currLane] = NA;
+        /* SATA 2 and SATA 3 and SGMII2 are not functional in 6811*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+        {
+            commonPhysSelectorsSerdesRev2Map[SATA3][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA2][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SGMII2][currLane] = NA;
+        }
+
+        /* no lanes 4 and 5 in 6811 */
+        for (currType = 0;currType < LAST_SERDES_TYPE; currType++)
+        {
+            commonPhysSelectorsSerdesRev2Map[currType][4] = NA;
+            commonPhysSelectorsSerdesRev2Map[currType][5] = NA;
+        }
+        break;
+	case MV_6820:
+        /* SATA 2 and SATA 3 are not functional in 6820*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+        {
+            commonPhysSelectorsSerdesRev2Map[SATA3][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA2][currLane] = NA;
+        }
+        break;
+	case MV_6828:
+        /* no limitations in 6828 */
+        break;
+    case /* 4 */	MV_NONE:
+        break;
+    case /* 5 */MV_6920:
+        /* no SATA ,USB3_HOST1, USB3_DEVICE,QSGMII*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+        {
+            commonPhysSelectorsSerdesRev2Map[SATA0][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA1][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA2][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA3][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[USB3_HOST1][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[USB3_DEVICE][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[QSGMII][currLane] = NA;
+        }
+         break;
+    case/* 6 */	MV_6928:
+        /* no limitations in 6928 */
+        break;
+
+    case 7/* MV_6925 */:
+        /* SATA 2 and SATA 3 are not functional in 6925*/
+        for (currLane =0; currLane < MAX_SERDES_LANES; currLane++)
+        {
+            commonPhysSelectorsSerdesRev2Map[SATA3][currLane] = NA;
+            commonPhysSelectorsSerdesRev2Map[SATA2][currLane] = NA;
+        }
+	    break;
+    }
+
+}
 /***************************************************************************/
 MV_STATUS mvHwsPowerUpSerdesLanes(SERDES_MAP  *serdesConfigMap)
 {
@@ -1188,6 +1321,9 @@
 
 	DEBUG_INIT_FULL_S("\n### mvHwsPowerUpSerdesLanes ###\n");
 
+    /* update Table of selectors options according to Device limitation*/
+    mvHwsUpdateSerdesPhySelectorsOptions();
+
 	/* COMMON PHYS SELECTORS register configuration */
 	DEBUG_INIT_FULL_S("mvHwsPowerUpSerdesLanes: Updating COMMON PHYS SELECTORS reg\n");
 	CHECK_STATUS(mvHwsUpdateSerdesPhySelectors(serdesConfigurationMap));
@@ -1259,6 +1395,32 @@
 	return mvHwsCtrlHighSpeedSerdesPhyConfig(); // stub
 }
 
+/**************************************************************************
+* updateUsb3DeviceConfig
+* DESCRIPTION: Update USB3 configuration register if USB3 device is enabled
+* INPUT:
+*	topologyConfigPtr - pointer to the Serdes mapping
+*
+***************************************************************************/
+void updateUsb3DeviceConfig(SERDES_MAP *serdesMapArray)
+{
+	MV_U32 laneNum;
+	for (laneNum = 0; laneNum < mvHwsSerdesGetMaxLane(); laneNum++) {
+		if (serdesMapArray[laneNum].serdesType == USB3_DEVICE) {
+			/* write 0x1 to USB3_CONFIG_REG[0:1]
+			 * BIT0 (USB3 Device UTMI En)	0 : USB3 Device disabled.
+			 *				    (USB2 on UTMI0, and USB3 Host1 on UTMI2)
+			 *			     -> 1 : USB3 Device enabled
+			 *
+			 * BIT1 (USB3 Device UTMI Mux)	-> 0 : UTMI2: USB3 Device is on UTMI2
+			 *				   1 : UTMI0: USB3 Device is on UTMI0 */
+			MV_REG_BIT_RESET(USB3_CONFIG_REG, BIT1);
+			MV_REG_BIT_SET(USB3_CONFIG_REG, BIT0);
+			return;
+		}
+	}
+}
+
 /***************************************************************************/
 static MV_STATUS mvSerdesPexUsb3PipeDelayWA(MV_U32 serdesNum, MV_U8 serdesType)
 {
@@ -1387,10 +1549,11 @@
 #ifdef DB_LINK_CHECK
 	int i;
 #endif
-	MV_U32 sataIdx, pexIdx, sataPort;
+	MV_U32 sataIdx, pexIdx,sataPort;
 	SERDES_SEQ speedSeqId;
 	MV_U32 regData;
 	MV_BOOL isPexBy1;
+	MV_U32	boardId = mvBoardIdGet();
 
 	DEBUG_INIT_FULL_S("\n### mvSerdesPowerUpCtrl ###\n");
 
@@ -1423,51 +1586,55 @@
 			isPexBy1 = (serdesMode == PEX_ROOT_COMPLEX_x1) || (serdesMode == PEX_END_POINT_x1);
 			pexIdx = serdesType - PEX0;
 
-			if ((isPexBy1 == MV_TRUE) || (serdesType == PEX0))
+			if ((isPexBy1 == MV_TRUE) || ((serdesType == PEX0) && (serdesNum == 0)))
 			{
-				/* For PEX by 4, init only the PEX 0 */
+				/* the following should be done for PEXx1 and for PEX by 4-for the first lane only */
 				regData = MV_REG_READ(SOC_CONTROL_REG1);
-				if (isPexBy1 == MV_TRUE) {
+				if (isPexBy1 == MV_TRUE)
 					regData |= 0x4000;
-				}
-				else{
+				else
 					regData &= ~0x4000;
-				}
 				MV_REG_WRITE(SOC_CONTROL_REG1, regData);
 
-				regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
+				/* Setup link width bit[9:4] */
+				regData = MV_REG_READ(PEX_LINK_CAPABILITIES_REG(pexIdx));
 				regData &= ~0x3F0;
-				if (isPexBy1 == MV_TRUE) {
+				if (isPexBy1 == MV_TRUE)
 					regData |= 0x10;
-				}
-				else {
+				else
 					regData |= 0x40;
-				}
-				MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
+				MV_REG_WRITE(PEX_LINK_CAPABILITIES_REG(pexIdx), regData);
 
-				regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
+				/* Setup maximum link speed bit[3:0] */
+				regData = MV_REG_READ(PEX_LINK_CAPABILITIES_REG(pexIdx));
 				regData &= ~0xF;
-				regData |= 0x2;
-				MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
+				if ((boardId == DB_AMC_6820_ID) && (pexIdx == 0) &&
+					mvBoardForcePcieGen1Get()) {
+					/* The WA is required for BC2 A0, so SatR is coded accordingly */
+					mvPrintf("Forcing Link to GEN1 on PCIe-%d\n", pexIdx);
+					regData |= 0x1; /* GEN1, 2.5G */
+				} else
+					regData |= 0x2; /* GEN2, 5G */
+				MV_REG_WRITE(PEX_LINK_CAPABILITIES_REG(pexIdx), regData);
 
-				regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70));
+				/* Setup common clock configuration bit[6] */
+				regData = MV_REG_READ(PEX_LINK_CTRL_STATUS_REG(pexIdx));
 				regData &= ~0x40;
 				regData |= 0x40;
-				MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70), regData);
+				MV_REG_WRITE(PEX_LINK_CTRL_STATUS_REG(pexIdx), regData);
 			}
 
             CHECK_STATUS(mvSeqExec(serdesNum, PEX_POWER_UP_SEQ));
-            if (isPexBy1 == MV_FALSE) {
-                /* for PEX by 4 - use the PEX index as the seq array index */
-                serdesSeqDb[PEX_BY_4_CONFIG_SEQ].dataArrIdx = pexIdx;
+             if (isPexBy1 == MV_FALSE) {
+                /* for PEX by 4 - use the serdesNum as the seq array index */
+                serdesSeqDb[PEX_BY_4_CONFIG_SEQ].dataArrIdx = serdesNum;
                 CHECK_STATUS(mvSeqExec(serdesNum, PEX_BY_4_CONFIG_SEQ));
             }
-
-            CHECK_STATUS(mvHwsRefClockSet(serdesNum, serdesType, refClock));
+	    CHECK_STATUS(mvHwsRefClockSet(serdesNum, serdesType, refClock));
             CHECK_STATUS(mvSeqExec(serdesNum, speedSeqId));
             CHECK_STATUS(mvSeqExec(serdesNum, PEX_ELECTRICAL_CONFIG_SEQ));
 
-			if (isPexBy1 == MV_TRUE) {
+	   if (isPexBy1 == MV_TRUE) {
 				CHECK_STATUS(mvSeqExec(serdesNum, PEX_TX_CONFIG_SEQ2));
 				CHECK_STATUS(mvSeqExec(serdesNum, PEX_TX_CONFIG_SEQ3));
 				CHECK_STATUS(mvSeqExec(serdesNum, PEX_TX_CONFIG_SEQ1));
@@ -1620,7 +1787,10 @@
 			CHECK_STATUS(mvSeqExec(serdesNum, QSGMII_TX_CONFIG_SEQ1));
 			CHECK_STATUS(mvSeqExec(serdesNum, QSGMII_TX_CONFIG_SEQ2));
             break;
-		case SGMII3:
+		case SGMIIv3_0:
+		case SGMIIv3_1:
+		case SGMIIv3_2:
+		case SGMIIv3_3:
 		case XAUI:
         case RXAUI:
             CHECK_STATUS(mvSerdesPowerUpCtrlExt(serdesNum, serdesPowerUp, serdesType, baudRate, serdesMode, refClock));
@@ -1644,7 +1814,7 @@
 /***************************************************************************/
 MV_STATUS mvHwsUpdateSerdesPhySelectors(SERDES_MAP* serdesConfigMap)
 {
-	MV_U32 laneData, serdesIdx,serdesLaneHwNum, regData = 0;
+	MV_U32 laneData, serdesIdx,serdesLaneHwNum,devId,regData = 0;
 	SERDES_TYPE serdesType;
 	SERDES_MODE serdesMode;
 	MV_U8       selectBitOff;
@@ -1659,6 +1829,8 @@
 	} else {
 		selectBitOff = 4;
 	}
+    /* Read HW device ID from S@R */
+	devId = mvSysEnvDeviceIdGet();
 
 	/* Updating bits 0-17 in the COMMON PHYS SELECTORS register according to the serdes types */
 	for (serdesIdx = 0; serdesIdx < mvHwsSerdesGetMaxLane(); serdesIdx++) {
@@ -1666,12 +1838,19 @@
 		serdesMode = serdesConfigMap[serdesIdx].serdesMode;
 		serdesLaneHwNum = mvHwsGetPhysicalSerdesNum(serdesIdx);
 
-		laneData = mvHwsSerdesGetPhySelectorVal(serdesLaneHwNum, serdesType);
+        if (((devId == MV_6810) || (devId == MV_6811)) &&
+           ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4)))
+        {
+            mvPrintf("%s: Warning: PCIeX4 mode is not supported in this device \n",__func__);
+			serdesConfigMap[serdesIdx].serdesType = DEFAULT_SERDES;
+        }
 
 		if(serdesType == DEFAULT_SERDES) {
 			continue;
 		}
-		if (mvHwsSerdesTopologyVerify(serdesType,serdesIdx,serdesMode) != MV_OK){
+        laneData = mvHwsSerdesGetPhySelectorVal(serdesLaneHwNum, serdesType);
+
+        if (mvHwsSerdesTopologyVerify(serdesType,serdesIdx,serdesMode) != MV_OK){
 			serdesConfigMap[serdesIdx].serdesType = DEFAULT_SERDES;
 			mvPrintf("%s: SerDes lane #%d is  disabled\n",__func__, serdesLaneHwNum);
 			updatedTopologyPrint = MV_TRUE;
@@ -1679,8 +1858,8 @@
 		}
 		/* Checking if the board topology configuration includes PEXx4 - for the next step */
 		if ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4)) {
-            /* update lane data to the 3 next SERDES lanes */
-            laneData = commonPhysSelectorsPexBy4Lanes[serdesLaneHwNum];
+			 /* update lane data to the 3 next SERDES lanes */
+			laneData = commonPhysSelectorsPexBy4Lanes[serdesLaneHwNum];
 			if (serdesType == PEX0) {
 				isPEXx4 = MV_TRUE;
 			}
@@ -1696,7 +1875,9 @@
 		/* Updating the data that will be written to COMMON_PHYS_SELECTORS_REG */
 		regData |= (laneData << (selectBitOff * serdesLaneHwNum));
 	}
-
+	/* check that number of used lanes for PEXx4 if used is right */
+	if (isPEXx4)
+		mvHwsSerdesPCIX4TopologyVerify();
 	/* check that number of used lanes for XAUI and RXAUI (if used) is right */
 	mvHwsSerdesXAUITopologyVerify();
 
@@ -1790,7 +1971,10 @@
         }
         break;
 #ifdef MV88F69XX
-	case SGMII3:
+	case SGMIIv3_0:
+	case SGMIIv3_1:
+        case SGMIIv3_2:
+	case SGMIIv3_3:
 	case XAUI:
 	case RXAUI:
         if (refClock == REF_CLOCK__25MHz) {
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.h b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.h
index 768adf7..1423807 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.h
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedEnvSpec.h
@@ -117,7 +117,10 @@
 	USB3_HOST0,
 	USB3_HOST1,
 	USB3_DEVICE,
-	SGMII3,
+	SGMIIv3_0,
+	SGMIIv3_1,
+	SGMIIv3_2,
+	SGMIIv3_3,
 	XAUI,
 	RXAUI,
 	DEFAULT_SERDES,
@@ -601,4 +604,13 @@
 * RETURNS:              True if lane is active
 ***************************************************************************/
 MV_BOOL mvHwsIsSerdesActive(MV_U8 laneNum);
+
+/**************************************************************************
+* updateUsb3DeviceConfig
+* DESCRIPTION: Update USB3 configuration register if USB3 device is enabled
+* INPUT:
+*	topologyConfigPtr - pointer to the Serdes mapping
+*
+***************************************************************************/
+void updateUsb3DeviceConfig(SERDES_MAP *serdesMapArray);
 #endif /* _MV_HIGHSPEED_ENV_SPEC_H */
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 85966f7..c267219 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-38x.c
@@ -94,6 +94,14 @@
 	{ SATA2,		__3Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ USB3_HOST1,	__5Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 },
+{	/* SolidRun ClearFog-A1 REV2.0 Topology */
+	{ SATA0,	__3Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ SGMII1,	__1_25Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ PEX1,	  	__5Gbps,	PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+	{ 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 },
@@ -126,6 +134,7 @@
 		serdesMapArray[laneNum].swapTx      =  CustomerBoardTopologyConfig[boardIdIndex][laneNum].swapTx;
 	}
 
+	updateUsb3DeviceConfig(serdesMapArray);
 	return MV_OK;
 }
 
@@ -137,6 +146,7 @@
 {
 	loadTopologyCustomer,   	  /* Customer Board 0 */
 	loadTopologyCustomer,   	  /* Customer Board 1*/
+	loadTopologyCustomer,   	  /* SolidRun ClearFog Board */
 	loadTopologyCustomer,   	  /* GFCH100 */
 };
 
@@ -262,52 +272,52 @@
 /* Configuration options */
 SERDES_MAP DbConfigDefault[MAX_SERDES_LANES] =
 {
-	{ SATA0,	 __3Gbps,   	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ PEX0, 	 __5Gbps,   	   PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
-	{ PEX1, 	 __5Gbps,   	   PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
-	{ SATA3,	 __3Gbps,   	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST0, __5Gbps,  	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST1, __5Gbps,  	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
+	{ SATA0,	__3Gbps,   	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ PEX0, 	__5Gbps,   	   PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+	{ PEX1, 	__5Gbps,   	   PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
+	{ SATA3,	__3Gbps,   	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST0,	__5Gbps,  	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST1,	__5Gbps,  	   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 };
 
 SERDES_MAP DbConfigSLM1363_C[MAX_SERDES_LANES] =
 {
 	{ PEX0, 	 	 __5Gbps,  				PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
-	{ DEFAULT_SERDES, LAST_SERDES_SPEED,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ DEFAULT_SERDES,	LAST_SERDES_SPEED,			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ PEX1, 	  	__5Gbps,  				PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ PEX3, 	  	__5Gbps,  				PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ SATA2,	  	__3Gbps,  				SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ DEFAULT_SERDES, LAST_SERDES_SPEED,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ DEFAULT_SERDES,	LAST_SERDES_SPEED,			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 };
 
 SERDES_MAP DbConfigSLM1363_D[MAX_SERDES_LANES] =
 {
 	{ PEX0, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-	{ PEX1, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-	{ PEX2, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-	{ PEX3, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST0, __5Gbps,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST1, __5Gbps,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
+	{ PEX0, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+	{ PEX0, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+	{ PEX0, 	  __5Gbps,  	PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST0,	  __5Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST1,	  __5Gbps,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 };
 
 SERDES_MAP DbConfigSLM1363_E[MAX_SERDES_LANES] =
 {
 	{ PEX0, 	  		__5Gbps,  			PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST0,   	__5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST0,		  	__5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ SATA1,	  		__3Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST1,     	__5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ USB3_HOST1,			__5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ DEFAULT_SERDES, 		LAST_SERDES_SPEED,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ SATA2,	  		__3Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 };
 
 SERDES_MAP DbConfigSLM1363_F[MAX_SERDES_LANES] =
 {
 	{ PEX0, 	  		__5Gbps,  			PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
-	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ DEFAULT_SERDES, 		LAST_SERDES_SPEED,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ PEX1, 	  		__5Gbps,  			PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ PEX3, 	  		__5Gbps,  			PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ SATA2,	  	 	__3Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ USB3_HOST1,       __5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
+	{ USB3_HOST1,			__5Gbps,  			SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 };
 
 SERDES_MAP DbConfigSLM1364_D[MAX_SERDES_LANES] =
@@ -327,17 +337,17 @@
 	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ SGMII2,     		__3_125Gbps,  	  	  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ PEX2, 	  		__5Gbps,  	  		  PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE }
+	{ PEX2, 	  	__5Gbps,  		  PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE }
 };
 
 SERDES_MAP DbConfigSLM1364_F[MAX_SERDES_LANES] =
 {
-	{ SGMII0,	 		 __3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ SGMII0,	 	__3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ SGMII1,	  		__3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ SGMII2,	  		__3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ SGMII1,	  	__3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
+	{ SGMII2,	  	__3_125Gbps,		  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ DEFAULT_SERDES, 	LAST_SERDES_SPEED,	  SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-	{ PEX2,		  		__5Gbps,		  	  PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE }
+	{ PEX2,		  	__5Gbps,	  	  PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE }
 };
 
 /**************************************************************************/
@@ -407,9 +417,9 @@
 SERDES_MAP DbAmcConfigDefault[MAX_SERDES_LANES] =
 {
 /* 0 */ { PEX0, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-/* 1 */ { PEX1, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-/* 2 */ { PEX2, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
-/* 3 */ { PEX3, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+/* 1 */ { PEX0, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+/* 2 */ { PEX0, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
+/* 3 */ { PEX0, 		__5Gbps,		PEX_ROOT_COMPLEX_x4,		MV_FALSE,	MV_FALSE },
 /* 4 */ { SGMII1,		__3_125Gbps,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 /* 5 */ { SGMII2,		__3_125Gbps,		SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 };
@@ -715,8 +725,68 @@
 	MV_U32 DevId = mvSysEnvDeviceIdGet();
 	MV_U32 BoardId = mvBoardIdGet();
 
+	if (BoardId == DB_BP_6821_ID) {
+		switch (topologyMode) {
+		case DB_381_CONFIG_DEFAULT:
+			if (DevId != MV_6W22)
+				return MV_OK;
+			/* DB-88F6821-BP on 6W22: if lane1 is SATA0 or SGMII-1 or QSGMII set to default */
+			/* --> device only supports 1 SATA, 1 SGMII and no QSGMII interface */
+			if (topologyConfigPtr[1].serdesType == SGMII1) {
+				mvPrintf("Device 6W22 supports only one SGMII interface: SGMII-1 @ lane1 disabled\n");
+				topologyConfigPtr[1] = DefaultLane;
+			} else if  (topologyConfigPtr[1].serdesType == QSGMII) {
+				mvPrintf("Device 6W22 does not support QSGMII interface: QSGMII @ lane1 disabled\n");
+				topologyConfigPtr[1] = DefaultLane;
+			}
+			/* DB-88F6821-BP on 6W22: if lane1 is SATA1 or SGMII-1 or QSGMII set to default */
+			/* --> device only supports 1 SATA and 1 SGMII interface */
+			if (topologyConfigPtr[2].serdesType == SATA1) {
+				mvPrintf("Device 6W22 supports only one SATA ");
+				mvPrintf("interface: SATA Port 1 @ lane2 disabled\n");
+				topologyConfigPtr[2] = DefaultLane;
+			} else if (topologyConfigPtr[2].serdesType == SGMII1) {
+				mvPrintf("Device 6W22 supports only one SGMII ");
+				mvPrintf("interface: SGMII-1 @ lane2 disabled\n");
+				topologyConfigPtr[2] = DefaultLane;
+			}
+			/* DB-88F6821-BP: default for Lane3=USB3_HOST1 --> 6W22 supports only one USB3 Host*/
+			/* --> device only supports 1 SATA, SGMII and no QSGMII interface */
+			mvPrintf("Device 6W22 supports only one USB3 Host interface: USB3 Port 1 @ lane3 disabled\n");
+			topologyConfigPtr[3] = DefaultLane;
+			break;
+		case DB_CONFIG_SLM1427:
+			/* DB-88F6821-BP on 6W22: default for Lane2=SATA1,Lane3=USB3_HOST1 */
+			/* --> device supports only 1 SATA and 1 USB3 interface */
+			if (DevId == MV_6W22) {
+				mvPrintf("Device 6W22 supports only one SATA ");
+				mvPrintf("interface: SATA Port 1 @ lane2 disabled\n");
+				topologyConfigPtr[2] = DefaultLane;
+				mvPrintf("Device 6W22 supports only one USB3 ");
+				mvPrintf("interface: USB3 Port 1 @ lane3 disabled\n");
+				topologyConfigPtr[3] = DefaultLane;
+			}
+			break;
+		case DB_CONFIG_SLM1426:
+			/* DB-88F6821-BP on 6W22: default for Lane2=SATA1,Lane3=SGMII-2 */
+			/* --> device supports only 1 SATA and 1 SGMII interface */
+			if (DevId == MV_6W22) {
+				mvPrintf("Device 6W22 supports only one SATA ");
+				mvPrintf("interface: SATA Port 1 @ lane2 disabled\n");
+				topologyConfigPtr[2] = DefaultLane;
+				mvPrintf("Device 6W22 supports only one SGMII ");
+				mvPrintf("interface: SGMII-2 @ lane3 disabled\n");
+				topologyConfigPtr[3] = DefaultLane;
+			}
+			break;
+		default:
+			break;
+		}
+		return MV_OK;
+	}
 	switch(topologyMode) {
 	case DB_CONFIG_DEFAULT:
+	/* update for DB-GP, DB-AP, DB-AMC, And for DB with default topology */
 		switch(DevId) {
 		case MV_6810:
 			/* DB-AP : default for Lane3=SGMII2 --> 6810 supports only 2 SGMII interfaces: lane 3 disabled */
@@ -741,11 +811,82 @@
 				topologyConfigPtr[4] = DefaultLane;
 			}
 			break;
+		case MV_6W23:
+			if (BoardId == DB_GP_68XX_ID) {
+				/* DB-GP on 6W23: if lane 2 changed to SATA1 by SatR change to default
+				 * --> 6W23 supports only one SATA interface */
+				if (topologyConfigPtr[2].serdesType == SATA1) {
+					mvPrintf("Device 6W23 supports only one ");
+					mvPrintf("SATA interface: SATA Port 1 @ lane2 disabled\n");
+					topologyConfigPtr[2] = DefaultLane;
+				}
+				/* DB-GP on 6W23: default for Lane3=SATA3,Lane4=SATA2 -->
+				 * 6W23 supports only 1 SATA interface */
+				/* default for Lane5=USB3_HOST1 --> 6W23 support only 4 SerDes lanes */
+				mvPrintf("Device 6W23 supports only one SATA interface: SATA ");
+				mvPrintf("Port 3 @ lane3 disabled\n");
+				topologyConfigPtr[3] = DefaultLane;
+				mvPrintf("Device 6W23 supports only one SATA interface: SATA ");
+				mvPrintf("Port 2 @ lane4 disabled\n");
+				topologyConfigPtr[4] = DefaultLane;
+				mvPrintf("Device 6W23 supports only 4 SerDes lanes: USB3-Host ");
+				mvPrintf("Port 1 @ lane5 disabled\n");
+				topologyConfigPtr[5] = DefaultLane;
+			} else if (BoardId == DB_68XX_ID) {
+				/* DB-BP on 6W23: if lane is SGMII-1 or QSGMII set to default */
+				/* --> device only supports 1 SGMII and no QSGMII interface */
+				if (topologyConfigPtr[1].serdesType == SGMII1) {
+					mvPrintf("Device 6W23 supports only one SGMII ");
+					mvPrintf("interface: SGMII-1 @ lane1 disabled\n");
+					topologyConfigPtr[1] = DefaultLane;
+				} else if  (topologyConfigPtr[1].serdesType == QSGMII) {
+					mvPrintf("Device 6W23 does not support QSGMII ");
+					mvPrintf("interface: QSGMII @ lane1 disabled\n");
+					topologyConfigPtr[1] = DefaultLane;
+				}
+				/* DB-BP on 6W23: if lane1 is SATA1 or SGMII-1 or QSGMII set to default */
+				/* --> device only supports 1 SATA and 1 SGMII interface */
+				if (topologyConfigPtr[2].serdesType == SATA1) {
+					mvPrintf("Device 6W23 supports only one SATA ");
+					mvPrintf("interface: SATA Port 1 @ lane2 disabled\n");
+					topologyConfigPtr[2] = DefaultLane;
+				} else if (topologyConfigPtr[2].serdesType == SGMII1) {
+					mvPrintf("Device 6W23 supports only one SGMII ");
+					mvPrintf("interface: SGMII-1 @ lane2 disabled\n");
+					topologyConfigPtr[2] = DefaultLane;
+				}
+				/* DB-GP on 6W23: default to Lane3=SATA3
+				 * --> 6W23 supports only one SATA interface */
+				mvPrintf("Device 6W23 supports only one ");
+				mvPrintf("SATA interface: SATA Port 3 @ lane3 disabled\n");
+				topologyConfigPtr[3] = DefaultLane;
+				/* default for Lane4=USB3_HOST0,Lane5=USB3_HOST1
+				 * --> 6W23 support only 4 SerDes lanes */
+				mvPrintf("Device 6W23 supports only 4 SerDes lanes: USB3-Host ");
+				mvPrintf("Port 0 @ lane4 disabled\n");
+				topologyConfigPtr[4] = DefaultLane;
+				mvPrintf("Device 6W23 supports only 4 SerDes lanes: USB3-Host ");
+				mvPrintf("Port 1 @ lane5 disabled\n");
+				topologyConfigPtr[5] = DefaultLane;
+			} else if (BoardId == DB_AP_68XX_ID) {
+				/* DB-AP on 6W23: default for Lane1=SGMII-1, Lane3=SGMII-2 */
+				/* --> device only supports 1 SGMII interface */
+				mvPrintf("Device 6W23 supports only one SGMII interface: SGMII-1 @ lane1 disabled\n");
+				topologyConfigPtr[1] = DefaultLane;
+				mvPrintf("Device 6W23 supports only one SGMII interface: SGMII-2 @ lane3 disabled\n");
+				topologyConfigPtr[3] = DefaultLane;
+				/* default for Lane4=USB3_HOST0,Lane5=PEX2
+				 * --> 6W23 support only 4 SerDes lanes */
+				mvPrintf("Device 6W23 supports only 4 SerDes lanes: ");
+				mvPrintf("USB3-Host Port 0 @ lane4 disabled\n");
+				topologyConfigPtr[4] = DefaultLane;
+				mvPrintf("Device 6W23 supports only 4 SerDes lanes:  Port 1 @ lane5 disabled\n");
+				topologyConfigPtr[5] = DefaultLane;
+			}
 		default:
 			break;
 		}
 		break;
-
 	default:
 		mvPrintf("mvSysEnvUpdateDeviceToplogy: selected topology is not supported by this routine\n");
 		break;
@@ -767,14 +908,17 @@
 	/* Getting the relevant topology mode (index) */
 	topologyMode = topologyConfigDB381ModeGet();
 	topologyConfigPtr = topologyConfigDB381[topologyMode];
-
+	/* if not detected any SerDes Site module, read 'SatR' lane setup */
+	if (topologyMode == DB_381_CONFIG_DEFAULT)
+		updateTopologySatR(topologyConfigPtr);
+	/* Update the default board topology device flavours */
+	CHECK_STATUS(mvHwsUpdateDeviceToplogy(topologyConfigPtr, topologyMode));
 	/* Read USB3.0 mode: HOST/DEVICE */
 	if (loadTopologyUSBModeGet(&twsiData) == MV_OK) {
 		usb3Host0OrDevice = (twsiData & 0x1);
 		if (usb3Host0OrDevice == 0) /* Only one USB3 device is enabled */
 			usb3Host1OrDevice = ((twsiData >> 1) & 0x1);
 	}
-
 	/* Updating the topology map */
 	for (laneNum = 0; laneNum < mvHwsSerdesGetMaxLane(); laneNum++) {
 		serdesMapArray[laneNum].serdesMode  = topologyConfigPtr[laneNum].serdesMode;
@@ -782,20 +926,26 @@
 		serdesMapArray[laneNum].serdesType  = topologyConfigPtr[laneNum].serdesType;
 		serdesMapArray[laneNum].swapRx      = topologyConfigPtr[laneNum].swapRx;
 		serdesMapArray[laneNum].swapTx      = topologyConfigPtr[laneNum].swapTx;
-
 		/* Update USB3 device if needed*/
-		if (usb3Host0OrDevice == 1 && serdesMapArray[laneNum].serdesType == USB3_HOST0)
-			serdesMapArray[laneNum].serdesType = USB3_DEVICE;
+		if (usb3Host0OrDevice == 1 && serdesMapArray[laneNum].serdesType == USB3_HOST0) {
+			if (mvSysEnvDeviceIdGet() != MV_6W22) {
+				serdesMapArray[laneNum].serdesType = USB3_DEVICE;
+			} else {
+				/* Device 6W22: Disable USB3-->device doesn't support device mode */
+				mvPrintf("Device 6W22 supports only USB3 Host ");
+				mvPrintf("mode: USB3 Port 0 @ lane%u disabled\n", laneNum);
+				serdesMapArray[laneNum] = DefaultLane;
+			}
+		}
 
 		if (usb3Host1OrDevice == 1 && serdesMapArray[laneNum].serdesType == USB3_HOST1)
 			serdesMapArray[laneNum].serdesType = USB3_DEVICE;
 	}
-	/* if not detected any SerDes Site module, read 'SatR' lane setup */
-	if (topologyMode == DB_381_CONFIG_DEFAULT)
-		updateTopologySatR(serdesMapArray);
 
 	/* update 'sgmiispeed' settings */
 	updateTopologySgmiiSpeed(serdesMapArray);
+	/* update USB3 config register */
+	updateUsb3DeviceConfig(serdesMapArray);
 
 	return MV_OK;
 }
@@ -808,7 +958,6 @@
 	SERDES_MAP* topologyConfigPtr;
 	MV_U8 twsiData;
 	MV_U8 usb3Host0OrDevice = 0, usb3Host1OrDevice = 0;
-
 	mvPrintf("\nInitialize DB-88F6820-BP board topology\n");
 
 	/* Getting the relevant topology mode (index) */
@@ -818,7 +967,9 @@
 		topologyMode = DB_CONFIG_DEFAULT;
 
 	topologyConfigPtr = topologyConfigDB[topologyMode];
-
+	/* if not detected any SerDes Site module, read 'SatR' lane setup */
+	if (topologyMode == DB_CONFIG_DEFAULT)
+		updateTopologySatR(topologyConfigPtr);
 	/* Update the default board topology device flavours */
 	CHECK_STATUS(mvHwsUpdateDeviceToplogy(topologyConfigPtr, topologyMode));
 
@@ -837,24 +988,28 @@
 		serdesMapArray[laneNum].swapRx      = topologyConfigPtr[laneNum].swapRx;
 		serdesMapArray[laneNum].swapTx      = topologyConfigPtr[laneNum].swapTx;
 
-		/* Update USB3 device if needed - relevant for lane 3,4,5 only */
-		if (laneNum >= 3)
-		{
-			if ((serdesMapArray[laneNum].serdesType == USB3_HOST0) &&
-				(usb3Host0OrDevice == 1))
-					serdesMapArray[laneNum].serdesType = USB3_DEVICE;
-
-			if ((serdesMapArray[laneNum].serdesType == USB3_HOST1) &&
-				(usb3Host1OrDevice == 1))
-					serdesMapArray[laneNum].serdesType = USB3_DEVICE;
+		/* Update USB3 device if needed */
+		if ((serdesMapArray[laneNum].serdesType == USB3_HOST0) &&
+			(usb3Host0OrDevice == 1)) {
+			if (mvSysEnvDeviceIdGet() != MV_6W23) {
+				serdesMapArray[laneNum].serdesType = USB3_DEVICE;
+			} else {
+				/* Device 6W23: Disable USB3-->device doesn't support device mode */
+				mvPrintf("Device 6W23 supports only USB3 Host ");
+				mvPrintf("mode: USB3 Port 0 @ lane%u disabled\n", laneNum);
+				serdesMapArray[laneNum] = DefaultLane;
+			}
 		}
+
+		if ((serdesMapArray[laneNum].serdesType == USB3_HOST1) &&
+			(usb3Host1OrDevice == 1))
+				serdesMapArray[laneNum].serdesType = USB3_DEVICE;
 	}
-	/* if not detected any SerDes Site module, read 'SatR' lane setup */
-	if (topologyMode == DB_CONFIG_DEFAULT)
-		updateTopologySatR(serdesMapArray);
 
 	/* update 'sgmiispeed' settings */
 	updateTopologySgmiiSpeed(serdesMapArray);
+	/* update USB3 config register */
+	updateUsb3DeviceConfig(serdesMapArray);
 
 	return MV_OK;
 }
@@ -906,7 +1061,8 @@
 		topologyConfigPtr[5].serdesSpeed =  isSgmii ? __3_125Gbps : __5Gbps;;
 		topologyConfigPtr[5].serdesMode = SERDES_DEFAULT_MODE;
 	}
-
+	/* update 'gpserdes1/2' lane configuration */
+	updateTopologySatR(topologyConfigPtr);
 	/* Update the default board topology device flavours */
 	CHECK_STATUS(mvHwsUpdateDeviceToplogy(topologyConfigPtr, DB_CONFIG_DEFAULT));
 
@@ -919,8 +1075,7 @@
 		serdesMapArray[laneNum].swapTx      = topologyConfigPtr[laneNum].swapTx;
 	}
 
-	/* update 'gpserdes1/2/3' lane configuration , and 'sgmiispeed' for SGMII lanes */
-	updateTopologySatR(serdesMapArray);
+	/* update 'sgmiispeed' for SGMII lanes */
 	updateTopologySgmiiSpeed(serdesMapArray);
 
 	return MV_OK;
@@ -948,8 +1103,6 @@
 		serdesMapArray[laneNum].swapTx      = topologyConfigPtr[laneNum].swapTx;
 	}
 
-	updateTopologySgmiiSpeed(serdesMapArray);
-
 	return MV_OK;
 }
 
diff --git a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-39x.c b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-39x.c
index a060510..e49808d 100755
--- a/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-39x.c
+++ b/tools/marvell/bin_hdr/src_phy/a38x/mvHighSpeedTopologySpec-39x.c
@@ -188,7 +188,10 @@
     __5Gbps,    /* USB3_HOST0 */
     __5Gbps,    /* USB3_HOST1 */
     __5Gbps,    /* USB3_DEVICE */
-    __1_25Gbps, /* SGMII3 */
+    __1_25Gbps, /* SGMIIv3_0 */
+    __1_25Gbps, /* SGMIIv3_1 */
+    __1_25Gbps, /* SGMIIv3_2 */
+    __1_25Gbps, /* SGMIIv3_03 */
     __3_125Gbps,/* XAUI */
     __6_25Gbps, /* RXAUI */
 };
@@ -196,14 +199,14 @@
 /* Selector to Serdes type mapping */
 SERDES_TYPE commonPhysType[MAX_SERDES_LANES][MAX_SELECTOR_VAL] =
 {
-/*	 0X0   0x1    0x2      0x3     0x4               0x5         0x6      0x7     0x8     0x9 */
-{ DEFAULT_SERDES, PEX0, SATA0,          SGMII0, SGMII0,      NA,          NA,          NA,     NA,     NA     },  /* Lane 0 */
-{ DEFAULT_SERDES, PEX0, PEX1,           SATA0,  SGMII0,      SGMII1,      USB3_HOST0,  QSGMII, SGMII0, SGMII1 },  /* Lane 1 */
-{ DEFAULT_SERDES, PEX1, PEX2,           SATA1,  SGMII1,      SGMII1,      NA,          NA,     NA,     NA     },  /* Lane 2 */
-{ DEFAULT_SERDES, PEX3, PEX3,           SATA3,  SGMII2,      USB3_HOST1,  USB3_DEVICE, SGMII2, XAUI,   NA     },  /* Lane 3 */
-{ DEFAULT_SERDES, PEX1, DEFAULT_SERDES, SGMII1, USB3_HOST0,  USB3_DEVICE, SATA2,       PEX2,   SGMII3, XAUI   },  /* Lane 4 */
-{ DEFAULT_SERDES, PEX2, SATA2,          SGMII2, USB3_HOST1,  USB3_DEVICE, SGMII2,      NA,     XAUI,   NA     },  /* Lane 5 */
-{ DEFAULT_SERDES, PEX1, SGMII3,         NA,     XAUI,        NA,          NA,          NA,     NA,     NA     },  /* Lane 6 */
+/*	 0X0	   0x1   0x2		0x3     0x4          0x5         0x6	       0x7		0x8		0x9		*/
+{ DEFAULT_SERDES, PEX0, SATA0,          SGMII0, SGMIIv3_0,   NA,          NA,          NA,		NA,		NA,		},  /* Lane 0 */
+{ DEFAULT_SERDES, PEX0, PEX1,           SATA0,  SGMII0,      SGMII1,      USB3_HOST0,  QSGMII,		SGMIIv3_0,	SGMIIv3_1,	},  /* Lane 1 */
+{ DEFAULT_SERDES, PEX1, PEX2,           SATA1,  SGMII1,      SGMIIv3_1,   NA,          NA,		NA,		NA ,		},  /* Lane 2 */
+{ DEFAULT_SERDES, PEX3, PEX3,           SATA3,  SGMII2,      USB3_HOST1,  USB3_DEVICE, SGMIIv3_2,	XAUI,		NA,		},  /* Lane 3 */
+{ DEFAULT_SERDES, PEX1, DEFAULT_SERDES, SGMII1, USB3_HOST0,  USB3_DEVICE, SATA2,       PEX2,		SGMIIv3_3,	XAUI,		},  /* Lane 4 */
+{ DEFAULT_SERDES, PEX2, SATA2,          SGMII2, USB3_HOST1,  USB3_DEVICE, SGMIIv3_2,   NA,		XAUI,		NA,		},  /* Lane 5 */
+{ DEFAULT_SERDES, PEX1, SGMIIv3_0,      NA,     XAUI,        NA,          NA,          NA,		NA,		NA,		},  /* Lane 6 */
 };
 
 /*************************************/
@@ -219,7 +222,7 @@
 	{ SGMII2,       __1_25Gbps,		   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
 	{ PEX2,         __5Gbps,		   PEX_ROOT_COMPLEX_x1,		MV_FALSE,	MV_FALSE },
 	{ RXAUI,        __6_25Gbps,		   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE },
-    { RXAUI,        __6_25Gbps,		   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
+	{ RXAUI,        __6_25Gbps,		   SERDES_DEFAULT_MODE,		MV_FALSE,	MV_FALSE }
 };
 
 /*************************** Functions implementation *************************/
@@ -303,6 +306,8 @@
         selectorVal = mvSysEnvConfigGet(configId);
         serdesType = commonPhysType[serdesNum][selectorVal];
 
+
+
         if (selectorVal > MAX_SELECTOR_VAL) {
             mvPrintf("mvSysUpdateLaneConfig: Error: Selector value %0x%x (Serdes %d) is bigger then max value (0x%x)\n",
 					 selectorVal, serdesNum, MAX_SELECTOR_VAL);
@@ -317,7 +322,7 @@
 
 		serdesTopology[serdesNum].serdesType  = serdesType;
 		serdesTopology[serdesNum].serdesSpeed = defaultSerdesSpeedMap[serdesType];
-        serdesTopology[serdesNum].serdesMode  = SERDES_DEFAULT_MODE; /* set to default */
+		serdesTopology[serdesNum].serdesMode  = SERDES_DEFAULT_MODE; /* set to default */
 		serdesTopology[serdesNum].swapRx      = MV_FALSE;
 		serdesTopology[serdesNum].swapTx      = MV_FALSE;
 
@@ -327,11 +332,20 @@
 		   is PEXx4, otherwise it will be PEXx1 (this is done after all
 		   Serdes types are updated). */
         if(serdesTopology[serdesNum].serdesType <= PEX3) {
-            serdesTopology[serdesNum].serdesMode = (selectorVal == 0x2) ?
+            serdesTopology[serdesNum].serdesMode = (selectorVal == 0x2) ? /* for lanes 1,2,and 3 selector valaue has value=1 for PEXx1 and value=2 for PEXx4,
+									     for lane 0 - it is always 1, so serdesMode will be updated later , when lane 1 is handled */
                 PEX_ROOT_COMPLEX_x4 : PEX_ROOT_COMPLEX_x1;
         }
 
-        /* The Selector mapping for lanes 5 and 6 can be either XAUI or RXAUI mode type
+	if ((serdesNum >= 1 ) && (serdesTopology[serdesNum].serdesMode == PEX_ROOT_COMPLEX_x4)){
+
+		if(serdesTopology[serdesNum].serdesType == PEX1)
+			/* set right mode for previous lane 0 too - see comment above */
+			serdesTopology[serdesNum-1].serdesMode = PEX_ROOT_COMPLEX_x4;
+		/* set serdes type for x4 lanes 1,2,3 - only PEX0 can be set as PEXx4  */
+		serdesTopology[serdesNum].serdesType = PEX0;
+	}
+	/* The Selector mapping for lanes 5 and 6 can be either XAUI or RXAUI mode type
            and it is depends on previous lanes 4.
 		   If the Selector value for lanes 4 is 0x9, then the Serdes type for lanes
 		   5 and 6 is XAUI, otherwise the Serdes type for lanes 5 and 6 is RXAUI */
diff --git a/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.c b/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.c
index 40407e6..58a8545 100755
--- a/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.c
+++ b/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.c
@@ -113,6 +113,8 @@
 	{ USB_REG_UNIT,    0x50804,     0x3,        { 0x2        }, 0,        0 }, /* Phy offset 0x1 - PLL_CONTROL1  */
 	{ USB_REG_UNIT,    0x5080C,     0x3000000,  { 0x2000000  }, 0,        0 }, /* Phy offset 0x3 - TX Channel control 0  */
 	{ USB_REG_UNIT,    0x50800,     0x1FF007F,  { 0x600005   }, 0,        0 }, /* Phy offset 0x0 - PLL_CONTROL0  */
+	{ USB_REG_UNIT,    0x5080C,     0x000F000,  { 0x0001000  }, 0,        0 }, /* DRV_EN_LS  0x1 - TX Channel control 0  */
+	{ USB_REG_UNIT,    0x50814,     0x000000F,  { 0x000000D  }, 0,        0 }, /* SQ_THRESH  0xD - TX Channel control 0  */
 	{ USB_REG_UNIT,    0x5080C,     0x3000000,  { 0x3000000  }, 0,        0 }, /* Phy offset 0x3 - TX Channel control 0  */
 	{ USB_REG_UNIT,    0x50804,     0x3,        { 0x3        }, 0,        0 }, /* Phy offset 0x1 - PLL_CONTROL1  */
 	{ USB_REG_UNIT,    0x50808,     0x80800000, { 0x80800000 }, 1,     1000 }, /* check PLLCAL_DONE is set and IMPCAL_DONE is set*/
@@ -272,6 +274,67 @@
 MV_STATUS boardTopologyLoad(SERDES_MAP  *serdesMapArray);
 
 /*************************** Functions implementation *************************/
+/*********************************************************************************************
+mvHwsIndirectRegRead
+ *
+ * DESCRIPTION:         Indirect readfrom COMPHY_M_PIPE_R2P3_28HPM_REG_MIDAS_INTERNAL_PCIE001
+*			registers via PEX_PHY_INDIRECT_ACC_REG
+* INPUT:   		devNum    - device number
+*	                regAddr   - register address
+*			dataValue - pointer to read data
+*
+ * OUTPUT:              None.
+ * RETURNS:             MV_OK           -   for success
+ *			MV_FAIL         -   for failure
+ ***************************************************************************/
+MV_U32 mvHwsIndirectRegRead
+(
+    MV_U32              devNum,
+    MV_U32              regAddr,
+    MV_U32              *dataValue
+
+)
+{
+	MV_U32 data;
+
+	data = (1 << PHY_ACCESS_MODE_OFFSET) + (regAddr << PHY_ADDRESS_OFFSET) ;
+	MV_REG_WRITE(PEX_PHY_INDIRECT_ACC_REG,data);
+	*dataValue = MV_REG_READ (PEX_PHY_INDIRECT_ACC_REG);
+
+	return MV_OK;
+}
+
+/*********************************************************************************************
+mvHwsIndirectRegWrite
+ *
+ * DESCRIPTION:		Indirect write to COMPHY_M_PIPE_R2P3_28HPM_REG_MIDAS_INTERNAL_PCIE001
+*			registers via PEX_PHY_INDIRECT_ACC_REG
+* INPUT:   		devNum    - device number
+*	                regAddr   - register address
+*			dataValue - data to write
+*			mask	  - mask
+* OUTPUT:		None.
+* RETURNS:		MV_OK           -   for success
+*			MV_FAIL         -   for failure
+***************************************************************************/
+MV_U32 mvHwsIndirectRegWrite
+(
+    MV_U32              devNum,
+    MV_U32              regAddr,
+    MV_U32              dataValue,
+    MV_U32              mask
+
+)
+{
+	MV_U32 readData,data;
+
+	mvHwsIndirectRegRead (devNum,regAddr,&readData);
+	dataValue = ((readData & (~mask)) | (dataValue & mask)) & 0xFFFF;
+	data = (0 << PHY_ACCESS_MODE_OFFSET) + (regAddr << PHY_ADDRESS_OFFSET) +  dataValue;
+	MV_REG_WRITE(PEX_PHY_INDIRECT_ACC_REG,data);
+	return MV_OK;
+}
+
 
 /**************************************************************************
  * mvHwsSerdesLastLaneGet -
@@ -376,10 +439,47 @@
 }
 
 /****************************************************************************/
+/* AC3: set PCIe Comphy register optimizations after ETP */
+MV_VOID mvCtrlPexImpedanceCalibration(MV_VOID)
+{
+	MV_U32 uiReg = 0;
+
+	/* MAC soft reset */
+	/* Reg 0x41a60, Deassert soft_reset[20] to 0x0*/
+	uiReg = MV_REG_READ(PEX_DBG_CTRL_REG(0));
+	uiReg &= ~(0x1 << 20);
+	MV_REG_WRITE(PEX_DBG_CTRL_REG(0), uiReg);
+	/*Pipe reset */
+	mvHwsIndirectRegWrite (0,GLOB_CLK_CTRL,0x1,0x1);
+
+	/*Pex Tx and RX impedance adjust and recalibrate */
+	mvHwsIndirectRegWrite (0,VTHIMPCAL_CTRL_REG,(TX_AND_RX_IMPEDANCE_THRESHIOLD << IMPEDANCE_THRESHIOLD_OFFSET),(0xFF <<IMPEDANCE_THRESHIOLD_OFFSET)); /* set threshold */
+
+	mvHwsIndirectRegWrite (0,CAL_REG3,(0x1 << RX_CALIBRATION_OFFSET),(0x1 <<RX_CALIBRATION_OFFSET));  /* calibrate Rx */
+	mvHwsIndirectRegWrite (0,CAL_REG3,(0x0 << RX_CALIBRATION_OFFSET),(0x1 <<RX_CALIBRATION_OFFSET));
+	mvOsDelay(5);
+	mvHwsIndirectRegWrite (0,CAL_REG3,(0x1 << TX_CALIBRATION_OFFSET),(0x1 <<TX_CALIBRATION_OFFSET));/* calibrate Tx */
+	mvHwsIndirectRegWrite (0,CAL_REG3,(0x0 << TX_CALIBRATION_OFFSET),(0x1 <<TX_CALIBRATION_OFFSET));
+
+	/*Pex slew rate control disable */
+	mvHwsIndirectRegWrite (0,G2_SETTING_0,(0x0 << TX_SLEW_CNTRL_ENABLE_OFFSET),(0x1 << TX_SLEW_CNTRL_ENABLE_OFFSET));
+}
+/****************************************************************************/
 /* AC3: set PCIe mode as End Point */
 MV_STATUS mvCtrlPexEndPointConfig(MV_VOID)
 {
-	return MV_OK; /*no EP config for AC3*/
+	MV_U32 uiReg = 0;
+
+	/* Reg 0x41a00, Set ConfRoot_Complex to 0x0 to define end point mode*/
+	uiReg = MV_REG_READ(PEX_CTRL_REG(0));
+	uiReg &= ~(0x1 << CONF_ROOT_COMPLEX_OFFSET);
+
+	MV_REG_WRITE(PEX_CTRL_REG(0), uiReg);
+	mvCtrlPexImpedanceCalibration();
+	/* unreset - set bit 0 to 0 in GLOB_CLK_CTR */
+	mvHwsIndirectRegWrite (0,GLOB_CLK_CTRL,0x0,0x1);
+
+	return MV_OK;
 }
 
 /****************************************************************************/
@@ -388,20 +488,33 @@
 {
 	MV_U32 uiReg = 0;
 	/* Reg 0x18204, Set PCIe0nEn[0] to 0x0*/
+
 	uiReg = MV_REG_READ(SOC_CTRL_REG);
 	uiReg &= ~(0x1 << 0);
 	uiReg |= (0x0 << 0);
 	MV_REG_WRITE(SOC_CTRL_REG, uiReg);
 
+	/* Reg 0x41a00, Set ConfRoot_Complex to 0x1 to define Root Complex mode*/
+	uiReg = MV_REG_READ(PEX_CTRL_REG(0));
+	uiReg &= ~(0x1 << CONF_ROOT_COMPLEX_OFFSET);
+	uiReg |= (0x1 << CONF_ROOT_COMPLEX_OFFSET);
+	MV_REG_WRITE(PEX_CTRL_REG(0), uiReg);
+
+	mvCtrlPexImpedanceCalibration();
+
 	/* Reg 0x40060, Set DevType[23:20] to 0x4(Root Complex)*/
 	uiReg = MV_REG_READ(PEX_CAPABILITIES_REG(0));
 	uiReg &= ~(0xF << 20);
 	uiReg |= (0x4 << 20);
 	MV_REG_WRITE(PEX_CAPABILITIES_REG(0), uiReg);
 
+	/* unreset - set bit 0 to 0 in GLOB_CLK_CTR */
+	mvHwsIndirectRegWrite (0,GLOB_CLK_CTRL,0x0,0x1);
+
 	/* Reg 0x41a60, Assert soft_reset[20] to 0x1,
-					Set DisLinkRestartRegRst[19] to 0x1,
-					Set ConfMskLnkRestart[16] to 0x1*/
+	   Set DisLinkRestartRegRst[19] to 0x1,
+	   Set ConfMskLnkRestart[16] to 0x1*/
+
 	uiReg = MV_REG_READ(PEX_DBG_CTRL_REG(0));
 	uiReg &= 0xFFE6FFFF;
 	uiReg |= 190000;
@@ -409,8 +522,8 @@
 
 	/* Reg 0x41a00, Set ConfRoot_Complex to 0x1*/
 	uiReg = MV_REG_READ(PEX_CTRL_REG(0));
-	uiReg &= ~(0x1 << 1);
-	uiReg |= (0x1 << 1);
+	uiReg &= ~(0x1 << CONF_ROOT_COMPLEX_OFFSET);
+	uiReg |= (0x1 << CONF_ROOT_COMPLEX_OFFSET);
 	MV_REG_WRITE(PEX_CTRL_REG(0), uiReg);
 
 	/* Reg 0x41a60, Deassert soft_reset[20] to 0x0*/
@@ -768,6 +881,15 @@
 {
 	MV_TWSI_SLAVE	twsiSlave;
 
+	/* Polarity is relevant only for DB board:
+	 * PCIe Polarity inversion is relevant only for PCIe slots.
+	 * only AC3 DB board use PCIe with slot,
+	 * other boards use PCIe to connect dual MSYS cpus*/
+#if defined CONFIG_ALLEYCAT3
+	if (mvBoardIdGet() != DB_AC3_ID)
+		return MV_OK;
+#endif
+
 	/* Initializing twsiSlave in order to read from the TWSI address */
 	twsiSlave.slaveAddr.address = 0x18;	/* Address of AC3 CPLD */
 	twsiSlave.slaveAddr.type = ADDR7_BIT;
diff --git a/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.h b/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.h
index 46c3a21..a7f12c0 100755
--- a/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.h
+++ b/tools/marvell/bin_hdr/src_phy/msys/mvHighSpeedEnvSpec.h
@@ -78,9 +78,28 @@
 #define LAST_LANE_NUM			21
 #endif
 
-#define MV_SERDES_28NM_REV_1	0x0
-#define MV_SERDES_28NM_REV_3	0x1
+#define MV_SERDES_28NM_REV_1				0x0
+#define MV_SERDES_28NM_REV_3				0x1
 
+
+#define CONF_ROOT_COMPLEX_OFFSET			1
+#define PEX_PHY_INDIRECT_ACC_REG			0x41b00
+#define PHY_ACCESS_MODE_OFFSET				31
+#define PHY_ADDRESS_OFFSET				16
+/* COMPHY_M_PIPE_R2P3_28HPM_REG_MIDAS_INTERNAL_PCIE001 registers -
+  with indirect access via PEX_PHY_INDIRECT_ACC_REG */
+#define G2_SETTING_0					0x00F
+#define PHYTST_REG0					0x015
+#define VTHIMPCAL_CTRL_REG				0x041
+#define CAL_REG3					0x057
+#define GLOB_CLK_CTRL					0x1C1
+
+#define TX_AND_RX_IMPEDANCE_THRESHIOLD			0x11
+
+#define IMPEDANCE_THRESHIOLD_OFFSET			8
+#define RX_CALIBRATION_OFFSET				7
+#define TX_CALIBRATION_OFFSET				14
+#define TX_SLEW_CNTRL_ENABLE_OFFSET			15
 /********************************* Enum ********************************/
 typedef enum {
 	PEX0,
diff --git a/tools/marvell/bin_hdr/src_pm/a38x/suspendWakeup.c b/tools/marvell/bin_hdr/src_pm/a38x/suspendWakeup.c
index 3ebeeb6..e1c5a0d 100755
--- a/tools/marvell/bin_hdr/src_pm/a38x/suspendWakeup.c
+++ b/tools/marvell/bin_hdr/src_pm/a38x/suspendWakeup.c
@@ -82,9 +82,6 @@
 * Notes:
 * Returns:	None.
 */
-#define BOOT_INFO_ADDR				(0x3000)
-#define SUSPEND_MAGIC_WORD			(0xDEADB002)
-#define REGISTER_LIST_END			(0xFFFFFFFF)
 MV_STATUS suspendWakeup(void)
 {
 	int *boot_info = (int*)(BOOT_INFO_ADDR);
diff --git a/tools/marvell/doimage_mv/doimage.c b/tools/marvell/doimage_mv/doimage.c
index 99861a9..e376807 100644
--- a/tools/marvell/doimage_mv/doimage.c
+++ b/tools/marvell/doimage_mv/doimage.c
@@ -1481,7 +1481,7 @@
 	int			i;
 	int 		override[2];
 	char 		*buf_in = NULL;
-	int 		err = 1;
+	int 		err = 0;
 
 	/* check if the output image exist */
 	printf(" ");
@@ -1641,10 +1641,8 @@
 			fprintf(stderr, "Error writing %s file \n", opt->fname.out);
 			goto end;
 		}
-
-		fprintf(stdout, "====>>>> %s was created\n", opt->fname_arr[IMG_FILE_INDX]);
-
 	} /* if (opt->header_mode != HDR_ONLY) */
+	fprintf(stdout, "====>>>> %s was created\n", opt->fname_arr[IMG_FILE_INDX]);
 
 end:
 	/* close handles */
diff --git a/tools/marvell/doimage_mv/hdrparser.c b/tools/marvell/doimage_mv/hdrparser.c
index b7c230f..5b38539 100755
--- a/tools/marvell/doimage_mv/hdrparser.c
+++ b/tools/marvell/doimage_mv/hdrparser.c
@@ -79,7 +79,7 @@
 #include "polarssl/rsa.h"
 //#include "polarssl/aes.h"
 
-#define VERSION_NUMBER	"2.0"
+#define VERSION_NUMBER	"2.01"
 
 /* Security context */
 typedef struct secCtx_t {
@@ -481,7 +481,7 @@
 	secCtx.rsa.len = (mpi_msb(&secCtx.rsa.N) + 7) >> 3; /* key length in bytes */
 
 	/* Key length should include 4 bytes of the data block header */
-	rsaKeyLen = (((pSecHdr->cskArray[csk_idx]).Key)[csk_idx] << 8) + ((pSecHdr->cskArray[csk_idx]).Key)[3] + 4;
+	rsaKeyLen = (((pSecHdr->cskArray[csk_idx]).Key)[2] << 8) + ((pSecHdr->cskArray[csk_idx]).Key)[3] + 4;
 	sha2((unsigned char *)((pSecHdr->cskArray[csk_idx]).Key), rsaKeyLen, buf32, 0);
 	fprintf(stdout, "----------------------------------------------------------\n");
 	fprintf(stdout,"RSA key SHA256 digest for eFuse (CSK-%d):\n  BE FULL: ", csk_idx);