#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include "dev/pci/sis1100_var.h"
#include "sis3100_vme_calls.h"




#define SDRAM_WRITE_MODE_SGL	 0x0      
#define SDRAM_WRITE_MODE_BLT	 0x1      
#define SDRAM_READ_MODE_SGL	 0x0      
#define SDRAM_READ_MODE_BLT	 0x1      


/*===========================================================================*/
/* Globals					  			     */
/*===========================================================================*/

#define MAX_NUMBER_OF_PRINTS 0x10      
#define MAX_NUMBER_LWORDS 0x400000        /* 4MByte */

u_int32_t wblt_data[MAX_NUMBER_LWORDS] ;
u_int32_t rblt_data[MAX_NUMBER_LWORDS] ;

u_int32_t test1_data[16] ;




/*===========================================================================*/
/* Prototypes					  			     */
/*===========================================================================*/

int sdram_tests(int ip_sdram, u_int32_t sdram_start_addr, u_int32_t no_of_lwords, int vme_write_mode, int vme_read_mode ) ;


/****************************************************************************/
int main(int argc, char* argv[])
{


int p_sdram;

u_int32_t addr ;
u_int32_t no_of_lwords ;

int return_code ;

int sdram_wr_mode, sdram_rd_mode ;
int loop_cnt ;
int no_loops ;




test1_data[0]   =   0x12345678 ;
test1_data[1]   =   0x87654321 ;
test1_data[2]   =   0x11224488 ;
test1_data[3]   =   0x88442211 ;
test1_data[4]   =   0xAA559966 ;
test1_data[5]   =   0x66AA5599 ;
test1_data[6]   =   0x9966AA55 ;
test1_data[7]   =   0x559966AA ;
test1_data[8]   =   0xffffffff ;
test1_data[9]   =   0x00000000 ;
test1_data[10]  =   0xFF00FF00 ;
test1_data[11]  =   0x00FF00FF ;
test1_data[12]  =   0xFFFF0000 ;
test1_data[13]  =   0x0000FFFF ;
test1_data[14]  =   0xF0F0F0F0 ;
test1_data[15]  =   0x0F0F0F0F ;


/* open SDRAM */
   if ((p_sdram=open("/tmp/sis3100sdram", O_RDWR, 0))<0) {
     printf("error on sdram open");
     return -1;
   }

if (argc<5)
  {
   printf("usage:  SDRAM_START_ADDRESS  NO_OF_LWORDS  SDRAM_WRITE_MODE  SDRAM_READ_MODE  [NO_OF_LOOPS]\n");
   printf("usage:  SDRAM_WRITE_SGL = 0   \n");
   printf("usage:  SDRAM_WRITE_BLT = 1   \n");
   printf("usage:  SDRAM_READ_SGL  = 0   \n");
   printf("usage:  SDRAM_READ_BLT  = 1   \n");
  return -1;
  }

addr         = strtoul(argv[1],NULL,0);
no_of_lwords = strtoul(argv[2],NULL,0) ;
sdram_wr_mode  = strtoul(argv[3],NULL,0) ;
sdram_rd_mode  = strtoul(argv[4],NULL,0);

no_loops = 0x1 ;
if (argc>5)
  {
    no_loops = strtoul(argv[5],NULL,0) ;
  }


/******************************************************************/
/*                                                                */
/* Test SDRAM RAM from PCI                    */
/*                                                                */
/******************************************************************/


loop_cnt = 0x0 ;
do
 {
    return_code = sdram_tests(p_sdram, addr, no_of_lwords, sdram_wr_mode, sdram_rd_mode) ;
    if (return_code != 0)  {
        printf("Error in sdram_test:  start_addr = 0x%08x   no_of_lwords = 0x%08x\n", addr, no_of_lwords );         
        return -1 ;
       }
    loop_cnt = loop_cnt + 1 ;

    if ((loop_cnt & 0xFF) == 0x0 )
     {
       printf(" loop counter = 0x%08x \n ", loop_cnt);
     }
} while ((return_code >= 0) && (loop_cnt != no_loops)) ;

    printf("Test SDRAM_TEST from PCI    OK\n");         



close(p_sdram);

return 0 ;
}








/***************************************************/
      

int sdram_tests(int ip_sdram, u_int32_t sdram_start_addr, u_int32_t no_of_lwords, int sdram_write_mode, int sdram_read_mode ) 

{

u_int32_t addr, data ;

int i;
int error_cnt ;
int return_code ;



if (no_of_lwords > MAX_NUMBER_LWORDS)  {
     printf("no_of_lwords (0x%08x) must be lower then MAX_NUMBER_LWORDS (0x%08x)\n",no_of_lwords, MAX_NUMBER_LWORDS);
     return -1;
   }

if (no_of_lwords == 0)  {
     printf("no_of_lwords (0x%08x) must be higher then 1 \n",no_of_lwords);
     return -1;
   }
/* check address if 4,8, bzw 8,10 */


/******************************************************************/
/*                                                                */
/* step 1:   write increment pattern                              */
/*                                                                */
/******************************************************************/
    /* prepare data */
    for (i=0;i<no_of_lwords;i++)    { wblt_data[i] = i ;  }

/*
#define SDRAM_WRITE_MODE_SGL	 0x0      
#define SDRAM_WRITE_MODE_BLT	 0x1      
#define SDRAM_READ_MODE_SGL	 0x0      
#define SDRAM_READ_MODE_BLT	 0x1      
*/

    /* SDRAM write data */
    addr =  sdram_start_addr ;                     
    switch (sdram_write_mode) {
     case SDRAM_WRITE_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_write(ip_sdram, addr, &wblt_data[i], 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_WRITE_MODE_BLT: 
		  return_code = s3100_sdram_write(ip_sdram, addr, wblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
        printf("Error in sdram_memory_test:  not defined SDRAM_WRITE_MODE \n");         
        return -1;
    } /* end switch */




  /* read data */
    addr =  sdram_start_addr ;                     
    switch (sdram_read_mode) {
     case SDRAM_READ_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_read(ip_sdram, addr, &data, 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          rblt_data[i] = data  ;
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_READ_MODE_BLT: 
          return_code = s3100_sdram_read(ip_sdram, addr, rblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
           printf("Error in sdram_memory_test:  not defined SDRAM_READ_MODE \n");         
           return -1;
    } /* end switch */




     /* check data */
     error_cnt =  0 ;
     for (i=0;(i)<no_of_lwords;i++)
       {
          if (wblt_data[i] != rblt_data[i])  
           {
             printf(" Error at i = : 0x%08x    written = : 0x%08x   read = : 0x%08x\n", i, wblt_data[i], rblt_data[i]);
             error_cnt = error_cnt + 1;
             if (error_cnt > MAX_NUMBER_OF_PRINTS) return -1 ;
           }
       }



/******************************************************************/
/*                                                                */
/* step 2:   bit shift pattern                                    */
/*                                                                */
/******************************************************************/
    /* prepare data */
    for (i=0;i<no_of_lwords;i++)    { wblt_data[i] = (0x1 << (i&0x1f)) ;  }
/*   for (i=0;i<no_of_lwords;i++)    { printf("w = 0x%08x \n", wblt_data[i]);  } */



    /* SDRAM write data */
    addr =  sdram_start_addr ;                     
    switch (sdram_write_mode) {
     case SDRAM_WRITE_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_write(ip_sdram, addr, &wblt_data[i], 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_WRITE_MODE_BLT: 
		  return_code = s3100_sdram_write(ip_sdram, addr, wblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
        printf("Error in sdram_memory_test:  not defined SDRAM_WRITE_MODE \n");         
        return -1;
    } /* end switch */




  /* read data */
    addr =  sdram_start_addr ;                     
    switch (sdram_read_mode) {
     case SDRAM_READ_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_read(ip_sdram, addr, &data, 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          rblt_data[i] = data  ;
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_READ_MODE_BLT: 
          return_code = s3100_sdram_read(ip_sdram, addr, rblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
           printf("Error in sdram_memory_test:  not defined SDRAM_READ_MODE \n");         
           return -1;
    } /* end switch */





     /* check data */
     error_cnt =  0 ;
     for (i=0;(i)<no_of_lwords;i++)
       {
          if (wblt_data[i] != rblt_data[i])  
           {
             printf(" Error at i = : 0x%08x    written = : 0x%08x   read = : 0x%08x\n", i, wblt_data[i], rblt_data[i]);
             error_cnt = error_cnt + 1;
             if (error_cnt > MAX_NUMBER_OF_PRINTS) return -1 ;
           }
       }


/******************************************************************/
/*                                                                */
/* step 3:    pattern                                             */
/*                                                                */
/******************************************************************/
    /* prepare data */
    for (i=0;i<no_of_lwords;i++)    { wblt_data[i] =  test1_data[i&0xf] ;  }
/*    for (i=0;i<no_of_lwords;i++)    { printf("w = 0x%08x \n", wblt_data[i]);  }  */


    /* SDRAM write data */
    addr =  sdram_start_addr ;                     
    switch (sdram_write_mode) {
     case SDRAM_WRITE_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_write(ip_sdram, addr, &wblt_data[i], 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_WRITE_MODE_BLT: 
		  return_code = s3100_sdram_write(ip_sdram, addr, wblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
        printf("Error in sdram_memory_test:  not defined SDRAM_WRITE_MODE \n");         
        return -1;
    } /* end switch */




  /* read data */
    addr =  sdram_start_addr ;                     
    switch (sdram_read_mode) {
     case SDRAM_READ_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_read(ip_sdram, addr, &data, 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          rblt_data[i] = data  ;
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_READ_MODE_BLT: 
          return_code = s3100_sdram_read(ip_sdram, addr, rblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
           printf("Error in sdram_memory_test:  not defined SDRAM_READ_MODE \n");         
           return -1;
    } /* end switch */






     /* check data */
     error_cnt =  0 ;
     for (i=0;(i)<no_of_lwords;i++)
       {
          if (wblt_data[i] != rblt_data[i])  
           {
             printf(" Error at i = : 0x%08x    written = : 0x%08x   read = : 0x%08x\n", i, wblt_data[i], rblt_data[i]);
             error_cnt = error_cnt + 1;
             if (error_cnt > MAX_NUMBER_OF_PRINTS) return -1 ;
           }
       }




/******************************************************************/
/*                                                                */
/* step 4:    random                                              */
/*                                                                */
/******************************************************************/
    /* prepare data */
    for (i=0;i<no_of_lwords;i++)    { wblt_data[i] =  random() ;  }
/*    for (i=0;i<no_of_lwords;i++)    { printf("w = 0x%08x \n", wblt_data[i]);  }   */




    /* SDRAM write data */
    addr =  sdram_start_addr ;                     
    switch (sdram_write_mode) {
     case SDRAM_WRITE_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_write(ip_sdram, addr, &wblt_data[i], 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_WRITE_MODE_BLT: 
		  return_code = s3100_sdram_write(ip_sdram, addr, wblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_write:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
        printf("Error in sdram_memory_test:  not defined SDRAM_WRITE_MODE \n");         
        return -1;
    } /* end switch */




  /* read data */
    addr =  sdram_start_addr ;                     
    switch (sdram_read_mode) {
     case SDRAM_READ_MODE_SGL: 
       for (i=0; i<no_of_lwords; i++)  {
          return_code = s3100_sdram_read(ip_sdram, addr, &data, 0x1) ;
          if (return_code != 4) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
          rblt_data[i] = data  ;
          addr = addr + 4;
       } /* for */
      break;
     case SDRAM_READ_MODE_BLT: 
          return_code = s3100_sdram_read(ip_sdram, addr, rblt_data, no_of_lwords) ;
          if (return_code != (no_of_lwords*4)) {
             printf("s3100_sdram_read:  return_code = 0x%08x  at address = 0x%08x\n", return_code, addr );         
             return -1 ;
           }
      break;
     default:
           printf("Error in sdram_memory_test:  not defined SDRAM_READ_MODE \n");         
           return -1;
    } /* end switch */



     /* check data */
     error_cnt =  0 ;
     for (i=0;(i)<no_of_lwords;i++)
       {
          if (wblt_data[i] != rblt_data[i])  
           {
             printf(" Error at i = : 0x%08x    written = : 0x%08x   read = : 0x%08x\n", i, wblt_data[i], rblt_data[i]);
             error_cnt = error_cnt + 1;
             if (error_cnt > MAX_NUMBER_OF_PRINTS) return -1 ;
           }
       }



error_cnt = 0 ;

  if (error_cnt == 0) {
     return 0 ; }
    else {
     return -1 ;}

}































