#ifdef CO_30_DIAGS

/************** INCLUDE FILES ****************************/
#include <stdio.h>
#include <bmehwapi.h>
#include <diags_defines.h>

/************** LOCAL MACROS *****************************/

/************** GLOBAL VARIABLES *************************/

/************** EXTERN FUNCTIONS AND VARIABLES ***********/
int testPIORead1 (int BmeNum, unsigned long addr);
int testPIORead (int BmeNum, unsigned long addr);
void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);
void bmeHwResetApi (int BmeNum);
void F (int bup_bme, int addr, int num, int data);


/************** LOCAL FUNCTION PROTOTYPES ****************/


/********************************************************/
/*              LOCAL FUNCTION DEFINITIONS              */
/********************************************************/

/********************************************************/
/*            EXPORTED FUNCTION DEFINITIONS             */
/********************************************************/

/*--------------------------------------------------------*/
#if 0
void bup_InitSdramCO (int bmeNum, int x16, int OpenPage)
{
	UINT32 CtrlData = ((OpenPage&0x1)<<11) | ((x16&0x1)<<8) | 0x7b;
    DBG4(("\tprogramming EMI_CTRL to: 0x%lx\n", CtrlData))
	testPIOWrite (bmeNum, EMI_MCR(0), CtrlData);
	testPIOWrite (bmeNum, EMI_BIR(0), 0x00000004);
	testPIOWrite (bmeNum, EMI_RPR(0), 0x00000877);	  //for 140Mhz memclk 
	testPIOWrite (bmeNum, EMI_PCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_RCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_SCR(0), 0x00000000);
}
#endif
//-----------------------------------------------------------
void bup_InitSdramCORand (int bmeNum, int CtrlData, int ba)
{
	testPIOWrite (bmeNum, EMI_MCR(0), CtrlData);
	testPIOWrite (bmeNum, EMI_BIR(0), ba);
	testPIOWrite (bmeNum, EMI_RPR(0), 0x00000877);	  //for 140Mhz memclk 
	testPIOWrite (bmeNum, EMI_PCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_RCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_SCR(0), 0x00000000);
}
/*--------------------------------------------------------*/
void bup_WriteSdramCO (int bmeNum, int StartAddr, int NumBytes, UINT32 StartData)
{
	UINT32 SdramAddr;
	UINT32 data;
	int SdramMaxAddr;
	int i;

	data = StartData;
	SdramMaxAddr = StartAddr + NumBytes;
	for (i=StartAddr; i<SdramMaxAddr; i=i+4)
	{
		SdramAddr = i & 0xffffffff;
		testPIOWrite (bmeNum, SdramAddr, data);
		DBG4(("\tSDRAM Address : 0x%lx\t WriteData : 0x%lx\n", SdramAddr, data))
		data++;
	}
}
/*--------------------------------------------------------*/
int bup_ReadSdramCO (int bmeNum, int StartAddr, int NumBytes, UINT32 StartData)
{
	UINT32 SdramAddr;
	UINT32 data, ExpData;
	int SdramMaxAddr;
	int i;
	int flag = 0;

	data = 0xbad;
	ExpData = StartData;
	SdramMaxAddr = StartAddr + NumBytes;
	for (i=StartAddr; i<SdramMaxAddr; i=i+4)
	{
		SdramAddr = i & 0xffffffff;
		data = testPIORead1 (bmeNum, SdramAddr);

		if (NumBytes == 1)
		{
#if HOST_ENDIANESS==BIG_ENDIAN
			data = data & 0xff000000; // when one byte is left, it is the MS byte on a big endian processor
			ExpData = ExpData & 0xff000000;
#elif HOST_ENDIANESS==LITTLE_ENDIAN
			data = data & 0x000000ff; // when one byte is left, it is the LS byte on a little endian processor
			ExpData = ExpData & 0x000000ff;
#else
#error Endianess has to be defined!
#endif
		}
		else if (NumBytes == 2)
		{
#if HOST_ENDIANESS==BIG_ENDIAN
			data = data & 0xffff0000;
			ExpData = ExpData & 0xffff0000;
#else
			data = data & 0x0000ffff;
			ExpData = ExpData & 0x0000ffff;
#endif
		}
		else if (NumBytes == 3)
		{
#if HOST_ENDIANESS==BIG_ENDIAN
			data = data & 0xffffff00;
			ExpData = ExpData & 0xffffff00;
#else
			data = data & 0x00ffffff;
			ExpData = ExpData & 0x00ffffff;
#endif
		}

		if (data != ExpData)
		{
			flag = 1;
			break;
		}
		ExpData++;
		NumBytes = NumBytes-4;
	}
	if (!flag)
	{
		DBG4(("\tSDRAM Data read/compare OK .........\n"))
	}
	else
	{
		DBG0(("\tSDRAM Data compare ERROR ......... NumBytes left = %d\n", NumBytes))
	}
	return(flag);
}
//---------------------------------------------------------------
void bup_SdramBasic (int bmeNum)
{
	int testfail;
    int startAddress, numBytes, startDataValue;

    startAddress = BME_SDRAM_MEMBASE;
    numBytes = 1000;
    startDataValue = 0x11223344;

	bup_WriteSdramCO (bmeNum, startAddress, numBytes, startDataValue);

	testfail = bup_ReadSdramCO (bmeNum, startAddress, numBytes, startDataValue);

	if (testfail)
	{
		DBG0(("*************************************************\n")) 
		DBG0(("\tBme %d: SDRAM basic test FAILED\n", bmeNum))
		DBG0(("*************************************************\n"))
	}
	else
	{
		DBG1(("*************************************************\n"))
		DBG1(("\tSDRAM basic test PASSED\n"))
		DBG1(("*************************************************\n"))
	}

}

int bup_dma (int bmeNum, int dmaChn, int srcAddr, int srcType, int dstAddr, int dstType, int NumBytes)
{
	int i = 0;
	UINT32 data1;
	UINT32 CcrReg;

	testPIOWrite (bmeNum, DMA_ECR(0, dmaChn), DMA_ECR_SW_REQ);  /*set software DMA request*/
    testPIORead (bmeNum , DMA_ECR(0, dmaChn));
	testPIOWrite (bmeNum, DMA_SAR(0, dmaChn), srcAddr);  /*set source address*/
    testPIORead (bmeNum , DMA_SAR(0, dmaChn));
	testPIOWrite (bmeNum, DMA_DAR(0, dmaChn), dstAddr);    /*set dest address*/
    testPIORead (bmeNum , DMA_DAR(0, dmaChn));

	if ((data1 = testPIORead1 (bmeNum , DMA_CCR(0, dmaChn))) & (0x3 << 6))
    {
        DBG0(("Channel not free!!!\n"))
    }

//	CcrReg = DMA_CCR_CH_EN | DMA_CCR_START | ((NumBytes - 1) << 16);
	CcrReg = DMA_CCR_CH_EN | ((NumBytes - 1) << 16);
	testPIOWrite (bmeNum, DMA_CCR(0, dmaChn), CcrReg);  /*Load DMA ccr register */

	data1 = testPIORead1 (bmeNum , DMA_CCR(0, dmaChn));
    DBG2(("DMA ch %d programmed for transfer size 0x%lx\n", dmaChn, (data1>>16)+1))

	testPIOWrite (bmeNum, DMA_CCR(0, dmaChn), data1 | 0x11);  /* start DMA*/

	BUP_DELAY_MS(20);
	data1 = testPIORead1 (bmeNum , DMA_CCR(0, dmaChn));
	while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
	{

		BUP_DELAY_MS(20);
		data1 = testPIORead1 (bmeNum , DMA_CCR(0, dmaChn));
		i++;
		if (i == DMA_WAIT_LOOP_TIMEOUT)
		{
			i = 0;
			DBG0(("Bme %d: **** bup_dma() - Dma done TIMEOUT. CCR = 0x%lx ****\n", bmeNum, data1))
			break;
		}
	}
	//CcrReg = ~DMA_CCR_CH_EN & ~DMA_CCR_START & ~DMA_CCR_DONE;
	//testPIOWrite (bmeNum, DMA_CCR(0, dmaChn), CcrReg);

	// Remove warnings
	srcType++;
	dstType++;

	return data1;
}

/*--------------------------------------------------------*/
int bup_SdramDma (int bmeNum, int NumBytes, UINT32 StartData, int whichDMA)
{
	int i = 0;
	UINT32 data1;
	UINT32 CcrReg;
	int fail = 0;
    int startAddress, sourceAddr, destAddr;

    startAddress = DMA_TEST_START_ADDR;
    sourceAddr = startAddress;
    destAddr = DMA_TEST_DEST_ADDR;

	bup_WriteSdramCO (bmeNum, startAddress, NumBytes, StartData);  /*write SDRAM 100 locations*/
    F (bmeNum, destAddr, (NumBytes/4)+1, 0xFFFFFFFF);
 
	testPIOWrite (bmeNum, DMA_ECR(0, whichDMA), DMA_ECR_SW_REQ);  /*set software DMA request*/
	testPIOWrite (bmeNum, DMA_SAR(0, whichDMA), sourceAddr);  /*set source address*/
	testPIOWrite (bmeNum, DMA_DAR(0, whichDMA), destAddr);    /*set dest address*/

	if ((data1 = testPIORead1 (bmeNum , DMA_CCR(0, whichDMA))) & (0x3 << 6))
    {
        DBG0(("Channel not free!!!\n"))
    }

//	CcrReg = DMA_CCR_CH_EN | DMA_CCR_START | ((NumBytes - 1) << 16);
	CcrReg = DMA_CCR_CH_EN | ((NumBytes - 1) << 16);
	testPIOWrite (bmeNum, DMA_CCR(0, whichDMA), CcrReg);  /*Load DMA ccr register */

	data1 = testPIORead1 (bmeNum , DMA_CCR(0, whichDMA));
    DBG2(("dma ch %d programmed for transfer size %ld+1\n", whichDMA, data1>>16));

	testPIOWrite (bmeNum, DMA_CCR(0, whichDMA), data1 | DMA_CCR_START);  /* start DMA*/

	BUP_DELAY_MS(20);
	data1 = testPIORead1 (bmeNum , DMA_CCR(0, whichDMA));
	while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
	{

		BUP_DELAY_MS(20);
		data1 = testPIORead1 (bmeNum , DMA_CCR(0, whichDMA));
		i++;
		if (i == DMA_WAIT_LOOP_TIMEOUT)
		{
			i = 0;
			DBG0(("Bme %d: **** bup_SdramDma() - Dma done TIMEOUT. CCR = 0x%lx ****\n", bmeNum, data1))
			break;
		}
	}
	CcrReg = ~DMA_CCR_CH_EN & ~DMA_CCR_START & ~DMA_CCR_DONE;
	testPIOWrite (bmeNum, DMA_CCR(0, whichDMA), CcrReg);

	fail = bup_ReadSdramCO (bmeNum, destAddr, NumBytes, StartData);
	return fail;
}
/*--------------------------------------------------------*/
int bup_regress_dma (int bmeNum)
{
	int flag = 0, error = 0;
	int numBytes;
	UINT32 startData = 0x12345678; //some random number
#if defined(CO_20) || defined(CO_30)
	int numDmaChannels = 7;
#else
	int numDmaChannels = 3;
#endif

    numBytes = 5001;
	while (numDmaChannels >= 0)
	{
		flag = bup_SdramDma (bmeNum, numBytes, startData, numDmaChannels);
        error |= flag;
		if (flag)
		{
            DBG0(("Bme %d: %d bytes DMA FAILED on dma channel %d\n", bmeNum, numBytes, numDmaChannels))
			//break;
		} else {
            DBG2(("Bme %d: %d bytes DMA test passed on dma channel %d\n", bmeNum, numBytes, numDmaChannels))
        }
		numDmaChannels--;
		startData++;
	}
	return error;
}
/*--------------------------------------------------------*/
int bup_sdram_dma_1_100bytes (int bmeNum)
{
	int NumBytes = 0;
	int i = 0;
	UINT32 StartData = 0x55aa6699; //some random value
	UINT32 CCRval;
	int flag = 0;
	UINT32 data1 = 0;
	int test_fail = 0;

	// DMA from 0x40000000 to 0x40000100
	for (NumBytes=1; NumBytes<=100; NumBytes++)
	{
		bup_WriteSdramCO (bmeNum, DMA_TEST_START_ADDR, NumBytes, StartData);  /* first write SDRAM "i" locations*/
		testPIOWrite (bmeNum, DMA_ECR(0, DMA_CH_0), DMA_ECR_SW_REQ);	 /*set software DMA request*/
		testPIOWrite (bmeNum, DMA_SAR(0, DMA_CH_0), DMA_TEST_START_ADDR);	 /*set source address*/
		testPIOWrite (bmeNum, DMA_DAR(0, DMA_CH_0), DMA_TEST_START_ADDR+0x100);	 /*set dest address*/
	    CCRval = DMA_CCR_CH_EN | DMA_CCR_START | ((NumBytes-1) << 16);
		//CCRval = ((NumBytes-1) << 16) | 0x1001;
		testPIOWrite (bmeNum, DMA_CCR(0, DMA_CH_0), CCRval);  /*Load DMA ccr register to start DMA*/

		BUP_DELAY_MS(20);
		data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
	    while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
		{
			BUP_DELAY_MS(20);
			data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
			i++;
			if (i == DMA_WAIT_LOOP_TIMEOUT)
			{
				i = 0;
			    DBG0(("Bme %d: **** bup_sdram_dma_1_100bytes - Dma done TIMEOUT 1. CCR = 0x%lx ****\n", bmeNum, data1))
				break;
			}
		}

		// DMA from 0x40000100 to 0x40000200
		testPIOWrite (bmeNum, DMA_ECR(0, DMA_CH_0), DMA_ECR_SW_REQ);	 /*set software DMA request*/
		testPIOWrite (bmeNum, DMA_SAR(0, DMA_CH_0), DMA_TEST_START_ADDR+0x100);	 /*set source address*/
		testPIOWrite (bmeNum, DMA_DAR(0, DMA_CH_0), DMA_TEST_START_ADDR+0x200);	 /*set dest address*/
	    CCRval = DMA_CCR_CH_EN | DMA_CCR_START | ((NumBytes-1) << 16);
		testPIOWrite (bmeNum, DMA_CCR(0, DMA_CH_0), CCRval);  /*Load DMA ccr register to start DMA*/

		BUP_DELAY_MS(20);
		data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
	    while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
		{
			BUP_DELAY_MS(20);
			data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
			i++;
			if (i == DMA_WAIT_LOOP_TIMEOUT)
			{
				i = 0;
			    DBG0(("Bme %d: **** bup_sdram_dma_1_100bytes - DMA done TIMEOUT 2. CCR = 0x%lx ****\n", bmeNum, data1))
				break;
			}
		}

		// Read back the data from 0x40000200
		flag = bup_ReadSdramCO (bmeNum, DMA_TEST_START_ADDR+0x200, NumBytes, StartData);
		if (flag)
		{
			test_fail = 1;
			break;
		}
		StartData = StartData + 0x1;
	}
	return test_fail;
}
/*--------------------------------------------------------*/
int bup_SdramFifoDma(int bmeNum)
{
	int i = 0;
	UINT32 data1 = 0x0;
	UINT32 CcrReg;
	int flag = 0;
	int NumBytes = 256;
    int startData = 0x11223344; //some random value
#ifndef CO_50
	testPIOWrite (bmeNum, BFI_CBIT_A, 0x47);  //bfifo cbft_a
	testPIOWrite (bmeNum, BFI_CBIT_B, 0x00);  //bfifo cbft_b
#endif	

	bup_WriteSdramCO (bmeNum, DMA_TEST_START_ADDR, NumBytes, startData);  /*write SDRAM 100 locations*/

	//dma from sdram to bfifo interleave
	testPIOWrite (bmeNum, DMA_ECR(0, DMA_CH_0), DMA_ECR_SW_REQ);	 /*set software DMA request*/
	testPIOWrite (bmeNum, DMA_SAR(0, DMA_CH_0), DMA_TEST_START_ADDR);	 /*set source address*/
	testPIOWrite (bmeNum, DMA_DAR(0, DMA_CH_0), ADDRESS_BFIFOINTERLEAVE);	 /*set dest address*/
	CcrReg = DMA_CCR_CH_EN | DMA_CCR_DEST_FIFO | DMA_CCR_START | ((NumBytes - 1) << 16);
	//CcrReg = 0x00001001 | (NumBytes << 16);
	testPIOWrite (bmeNum, DMA_CCR(0, DMA_CH_0), CcrReg);	 /*Load DMA ccr register to start DMA*/

	BUP_DELAY_MS(20);
	data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
    while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
	{
		BUP_DELAY_MS(200);
		data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
		i++;
		if (i == 10)
		{
			i = 0;
			DBG0(("Bme %d: **** bup_SdramFifoDma - Dma done TIMEOUT 1. CCR = 0x%lx ****\n", bmeNum, data1))
			break;
		}
	}
	//dma from bfifo interleave to sdram back
	testPIOWrite (bmeNum, DMA_ECR(0, DMA_CH_0), DMA_ECR_SW_REQ);	 /*set software DMA request*/
	testPIOWrite (bmeNum, DMA_SAR(0, DMA_CH_0), ADDRESS_BFIFOINTERLEAVE);	 /*set source address*/
	testPIOWrite (bmeNum, DMA_DAR(0, DMA_CH_0), DMA_TEST_DEST_ADDR);	 /*set dest address*/
	CcrReg = DMA_CCR_CH_EN | DMA_CCR_SRC_FIFO | DMA_CCR_START | ((NumBytes - 1) << 16);
	//CcrReg = 0x00001001 | (NumBytes << 16);
	testPIOWrite (bmeNum, DMA_CCR(0, DMA_CH_0), CcrReg);	 /*Load DMA ccr register to start DMA*/

	BUP_DELAY_MS(20);
	data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
    while (!(data1 & DMA_CCR_DONE))  /*polling for DMA done bit*/
	{
		BUP_DELAY_MS(200);
		data1 = testPIORead1 (bmeNum, DMA_CCR(0, DMA_CH_0));
		i++;
		if (i == 10)
		{
			i = 0;
			DBG0(("Bme %d: **** bup_SdramFifoDma - DMA done TIMEOUT 2. CCR = 0x%lx ****\n", bmeNum, data1))
			break;
		}
	}

	flag = bup_ReadSdramCO (bmeNum, DMA_TEST_DEST_ADDR, NumBytes, 0x11223344);
	return flag;
}

//---------------------------------------------------------------
int bup_SdramRandom (int bmeNum)
{
	int i;
	int RandData;
	int testfail=0;
	unsigned int CtrlData;
	int ba;


	DBG2(("\tSetting random EMI Control values:\n"))
	for (i=0; i<10; i++)
	{
		bmeHwResetApi (bmeNum);	//reset CO fpga
		BUP_DELAY_MS (100);

		CtrlData = rand ();
		ba = (CtrlData & 0x7000) >> 12;	 //take 3 bits for bank interleaving
		CtrlData = (CtrlData & 0x97e) | 0x100;
		DBG2(("\t%d. EMI_CTRL: 0x%x  \tBank Interleave: 0x%x", i, CtrlData, ba))
		bup_InitSdramCORand(bmeNum, CtrlData, ba);
		BUP_DELAY_MS(20);
		RandData = rand ();
		DBG2(("\tStart Data: 0x%x\n", RandData))
		
		testfail = bup_SdramDma (bmeNum, 8191, RandData, 0);

//	DBG1(("."))
		if (testfail)
			break;
	}
	if (testfail)
	{
		DBG0(("\n******************************************************\n")) 
		DBG0(("\tBme %d: SDRAM random test FAILED\n", bmeNum ))
		DBG0(("EMI control register: 0x%x \t Bank Interleaving: 0x%x\n", CtrlData, ba))
		DBG0(("******************************************************\n"))

        return -1;
	}
	else
	{
		DBG1(("Bme %d: External Memory Interface Test Passed\n", bmeNum))

        return 0;
	}
}
//-------------------------------------------------------------------
void bup_SdramBurstRefresh (int bmeNum)
{
    int startData = 0x11223344; //some random value
    int MemRefreshTestStartAddr = BME_SDRAM_MEMBASE;
    int numBytes = 8000;

	testPIOWrite (bmeNum, EMI_MCR(0), 0x58);
	testPIOWrite (bmeNum, EMI_BIR(0), 0x0);
	testPIOWrite (bmeNum, EMI_RPR(0), 0x50000f2e);	  // 6 refreshes every 93 us, for 31Mhz memclk 
	testPIOWrite (bmeNum, EMI_PCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_RCR(0), 0x00000000);
	testPIOWrite (bmeNum, EMI_SCR(0), 0x00000000);

	bup_WriteSdramCO (bmeNum, MemRefreshTestStartAddr, numBytes, startData);	//write 8000 bytes to memory

	DBG1(("**********************************************************\n")) 
	DBG1(("     Please read back and verify the data next day by,\n"))
	DBG1(("     SdramVerifyCO (0x40000000, 8000, 0x11223344)\n"))
	DBG1(("**********************************************************\n")) 
}
/*--------------------------------------------------------*/
void bup_SdramVerifyCO (int bmeNum, int StartAddr, int NumBytes, UINT32 StartData)
{
	int testfail = 0;

	testfail = bup_ReadSdramCO (bmeNum, StartAddr, NumBytes, StartData);
	if (!testfail)
	{
		DBG1(("****************************************************\n")) 
		DBG1(("\tSDRAM Data read/compare OK .........\n"))
		DBG1(("****************************************************\n")) 
	}
	else
	{
		DBG0(("****************************************************\n")) 
		DBG0(("\tBme %d: SDRAM Data compare ERROR .........\n", bmeNum))
		DBG0(("****************************************************\n")) 
	}
}
#endif //CO_30_DIAGS
