ddr3libv2: rx io bist test support

    - added support for RX IO BIST.
    - to enable it define (in gtBUild or Makefile)
        MV_HWS_RX_IO_BIST for data signals
        MV_HWS_RX_IO_BIST_ETP for cmd/addr signals

Change-Id: I75866c70abc14aaa7762e31c702d57bc3127549b
Signed-off-by: hayim <hayim@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/23079
Tested-by: Star_Automation <star@marvell.com>
Tested-by: Star_New_DDR <star-new-ddr@marvell.com>
Reviewed-by: Margarita Granov <margra@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/24153
Reviewed-by: Omri Itach <omrii@marvell.com>
diff --git a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile
index b8dad0c..eeacd5d 100755
--- a/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile
+++ b/tools/marvell/bin_hdr/src_ddr/ddr3libv2/Makefile
@@ -121,6 +121,11 @@
 #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 #############################################
 
 
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 168922d..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
@@ -24,6 +24,11 @@
 
 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
+
 ##################################################
 ##################################################
 include $(PROJ_BASE)/gtTopMake
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 6e7028c..5eb50e3 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
@@ -208,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[] =
@@ -2314,6 +2318,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