#include <stdio.h>
#ifdef USE_VXWORKS /* IXDP425 */
#include <vxWorks.h>
#include <taskLib.h>
#else
#include <v2pthread.h>
#define UINT32 unsigned int
extern int taskDelay(int);
#endif

extern void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);
extern int testPIORead (int BmeNum, unsigned long addr);
extern void tpw (int BmeNum, unsigned long addr, unsigned long data);
/*--------------------------------------------------------*/
void InitSdramCPE4 (int open)
{

  printf("initsdram viper %x\n",open);
  if (open == 1)
     testPIOWrite (1,0xe0038000,0x0000107c);
    else
     testPIOWrite (1,0xe0038000,0x0000007c);
  testPIOWrite (1,0xe0038004,0x00000134);   //for 41 Mhz 
  testPIOWrite (1,0xe003800c,0x00000000);
  testPIOWrite (1,0xe0038008,0x00000000);
  testPIOWrite (1,0xe0038008,0x00000000);
  testPIOWrite (1,0xe0038010,0x00000000);

}

void InitSdramM (int x16, int OpenPage, int which)
{

  UINT32 CtrlData = ((OpenPage&0x1)<<11) | ((x16&0x1)<<8) | 0x7b;
  printf ("\tprogramming EMI_CTRL to: 0x%x\n",CtrlData);

#if 1
    printf("\n <<<>>> Setting CO5 SDRAM Clock <<<>>>\n\n");
#endif 

  testPIOWrite (which,0xe0038000,CtrlData);
  testPIOWrite (which,0xe0038020,0x00000004);
  testPIOWrite (which,0xe0038004,0x00000877);   //for 140Mhz memclk 
  testPIOWrite (which,0xe003800c,0x00000000);
  testPIOWrite (which,0xe0038008,0x00000000);
  testPIOWrite (which,0xe0038010,0x00000000);
#ifdef CO_20_DIAGS
 testPIOWrite (which,0x40000100,0x00000000);
#endif

}
/*--------------------------------------------------------*/
void WriteSdramM (int StartAddr, int NumBytes, UINT32 StartData)
{
  UINT32 SdramAddr;
  UINT32 data;
  //int BaseAddr;
  int SdramMaxAddr;
  int i;

  data = StartData;
  SdramMaxAddr = StartAddr + NumBytes;
  for (i=StartAddr; i<SdramMaxAddr; i=i+4)
    {
    SdramAddr = i & 0xffffffff;
    testPIOWrite (1,SdramAddr,data);
    /*printf ("SDRAM Address : 0x%x\t WriteData : 0x%x\n",SdramAddr, data);*/
    data++;
    }
}
/*--------------------------------------------------------*/
int ReadSdramM (int StartAddr, int NumBytes, UINT32 StartData)
{
  UINT32 SdramAddr;
  UINT32 data,ExpData;
  //int BaseAddr;
  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 = testPIORead (1,SdramAddr);
    if (NumBytes == 1) {
        data = data & 0xff000000;
        ExpData = ExpData & 0xff000000;}
    else if (NumBytes == 2) {
        data = data & 0xffff0000;
        ExpData = ExpData & 0xffff0000;}
    else if (NumBytes == 3) {
        data = data & 0xffffff00;
        ExpData = ExpData & 0xffffff00;}

    if (data != ExpData)
      {
        flag = 1;
        IK_PRINTF ("SDRAM Data mismatch @Addr :0x%lx  ReadData:0x%lx ExpectedData:0x%lx\n",SdramAddr, data, ExpData);
      }
    ExpData++;
    NumBytes = NumBytes-4;
    }
  if (!flag)
    {
      IK_PRINTF ("SDRAM Data read/compare OK .........\n");
    }
  else
    {
      IK_PRINTF ("SDRAM Data compare ERROR .........\n");
    }
  
  return (flag);
}
/*--------------------------------------------------------*/
void SdramDmaM (UINT32 StartData)
{
  int i = 0;
  UINT32 data1 = 0x0;

  WriteSdramM (0x40000000, 25, StartData);  /*write SDRAM 100 locations*/
   
  testPIOWrite (1,0xe0030040,0x80000000);  /*set software DMA request*/
  testPIOWrite (1,0xe0030080,0x40000000);  /*set source address*/
  testPIOWrite (1,0xe00300c0,0x400000f0);  /*set dest address*/
  testPIOWrite (1,0xe0030000,0x00631001);  /*Load DMA ccr register to start DMA*/
  taskDelay(10);
  while (!(data1 & 0x100))  /*polling for DMA done bit*/
    {
    taskDelay(10);
    data1 = testPIORead (1,0xe0030000);
    i++;
    if (i == 300)
      {
        i = 0;
        IK_PRINTF ("********* Time out in DMA done polling1 ********\n");
        break;
      }
    }

  ReadSdramM (0x400000f0,25,StartData);
}
/*--------------------------------------------------------*/
void regress_sdram_dmaM (void)
{
  int NumBytes = 0;
  int i = 0;
  UINT32 StartData = 0x55aa6699;
  UINT32 CCR;
  int flag = 0;
  UINT32 data1 = 0;
  
  InitSdramM(0,0, 1);

  for (NumBytes=1; NumBytes<=100; NumBytes++)
    {
        WriteSdramM (0x40000000, NumBytes, StartData);  /* first write SDRAM "i" locations*/
        testPIOWrite (1,0xe0030040,0x80000000);  /*set software DMA request*/
    testPIOWrite (1,0xe0030080,0x40000000);  /*set source address*/
    testPIOWrite (1,0xe00300c0,0x40000100);  /*set dest address*/
    CCR = ((NumBytes-1) << 16) | 0x1001;
    testPIOWrite (1,0xe0030000,CCR);  /*Load DMA ccr register to start DMA*/
    taskDelay(10);
    while (!(data1 & 0x100))  /*polling for DMA done bit*/
          {
        taskDelay(10);
        data1 = testPIORead (1,0xe0030000);
        i++;
        if (i == 300)
          {
            i = 0;
            IK_PRINTF ("**** Time out in DMA done polling, Numbytes = %d ****\n",NumBytes);
            break;
          }
          }
    flag = ReadSdramM (0x40000100,NumBytes,StartData);
    if (!flag)
      {
        IK_PRINTF ("SDRAM %d - byte DMA passed\n",NumBytes);
      }
    else
      {
        IK_PRINTF ("**** SDRAM %d - byte DMA FAILED ****\n",NumBytes); 
        break;
      }
    IK_PRINTF ("\n");
    StartData = StartData + 0x1;
    }
}

#if 1
void set_clkM (int which) 
{
#ifdef CO_30_DIAGS
    InitSdramM (1, 1, which);
#endif
    tpw (which,0xe0070008,0x11c);
    tpw (which,0xe0070008,0x31c);
    tpw (which,0xe0070024,0x104);
    tpw (which,0xe0070024,0x304);
    printf ("\tCore clock for BME Number %d set to 157 Mhz and mem clk to 143 Mhz\n", which);

}
#else
void set_clkM (int which) {
    int i;
    for(i=0; i<30;i++){
    tpw (which,0xe0070008,0x4f);
    tpw (which,0xe0070008,0x14f);
    tpw (which,0xe0070024,0x43);
    tpw (which,0xe0070024,0x143);
    }
    printf ("\tCore clock for BME Number %d set to 166 Mhz and mem clk to 140 Mhz\n", which);
}
#endif
