#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 SHARCRAM  0x01200000
#define D48REG    0x01300000

#define SDRAM_EEPROM_CTRL_STAT  0x40000400


#define SDRAM_SCL    0x1
#define SDRAM_SDA    0x2
#define SDRAM_SDA_OE 0x4


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

int sdram_eeprom_stop (int p) ;
int sdram_eeprom_start (int p) ;
int sdram_eeprom_write (int p,  u_int32_t write_data) ;
int sdram_eeprom_read (int p,  u_int32_t* read_data) ;
int sdram_eeprom_read_noack (int p,  u_int32_t* read_data) ;

/****************************************************************************/
int main(int argc, char* argv[])
{
int i;
int p_sharc;
u_int32_t data ;
u_int32_t addr ;

u_int32_t no_row_addresses ;
u_int32_t no_column_addresses ;
u_int32_t no_module_banks ;

int  no_of_Mbyte ;

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

  addr = SDRAM_EEPROM_CTRL_STAT ;


 sdram_eeprom_start (p_sharc) ;
 sdram_eeprom_write (p_sharc, 0xA0) ; /* device Write cmd  */
 sdram_eeprom_write (p_sharc, 0x00) ; /* write address */

 sdram_eeprom_start (p_sharc) ;

 sdram_eeprom_write (p_sharc, 0xA1) ; /* device Read cmd  */

 no_row_addresses     =   0 ;
 no_column_addresses  =   0 ;
 no_module_banks      =   0 ;

 for (i=0;i<6;i++)  {
     sdram_eeprom_read (p_sharc, &data) ;
     if (i == 0x3) no_row_addresses = data ;
     if (i == 0x4) no_column_addresses = data ;
     if (i == 0x5) no_module_banks = data ;
   }

 sdram_eeprom_read_noack (p_sharc, &data) ;
 sdram_eeprom_stop (p_sharc) ;

 no_of_Mbyte = 0 ;
 if ((no_row_addresses == 12) && (no_column_addresses == 9)  && (no_module_banks == 1))   no_of_Mbyte = 64 ;
 if ((no_row_addresses == 12) && (no_column_addresses == 9)  && (no_module_banks == 2))   no_of_Mbyte = 128 ;
 if ((no_row_addresses == 13) && (no_column_addresses == 10) && (no_module_banks == 1))   no_of_Mbyte = 256 ;
 if ((no_row_addresses == 13) && (no_column_addresses == 10) && (no_module_banks == 2))   no_of_Mbyte = 512 ;

 printf("   no_of_Mbyte %d \n", no_of_Mbyte );      

close(p_sharc);

return no_of_Mbyte ;
}






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

int sdram_eeprom_stop (int p)
{
  int return_code ;
  u_int32_t data ;
  u_int32_t addr ;

  addr = SDRAM_EEPROM_CTRL_STAT;

/* STOP:     */
  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SCL ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SDA + SDRAM_SCL ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SDA  ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  return 0 ;
}



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

int sdram_eeprom_start (int p)
{
  int return_code ;
  u_int32_t data ;
  u_int32_t addr ;

  addr = SDRAM_EEPROM_CTRL_STAT ;
 /* START:     */
  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SDA ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SDA + SDRAM_SCL ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE + SDRAM_SCL ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SDA_OE ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  return 0 ;
}



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

int sdram_eeprom_write (int p,  u_int32_t write_data)
{
  int return_code ;
  u_int32_t data ;
  u_int32_t help_data ;
  u_int32_t addr ;
  int i ;

  for (i=0;i<0x2000;i++)
   {
    addr = addr + i ;
   }

  addr = SDRAM_EEPROM_CTRL_STAT;

  help_data = write_data ;

  for (i=0;i<8;i++)
   {
     if ((write_data & 0x80) == 0x80) {
          data = SDRAM_SDA_OE + SDRAM_SDA  ; 
         }
         else {
          data = SDRAM_SDA_OE   ; 
         }  
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

      data = data + SDRAM_SCL ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

      data = data - SDRAM_SCL ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      write_data = write_data << 1 ;
   }

  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = SDRAM_SCL ; 
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  data = 0x0 ;
  return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  return 0 ;
}




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

int sdram_eeprom_read (int p,  u_int32_t* read_data)
{
  int return_code ;
  u_int32_t data ;
  u_int32_t help_data ;
  u_int32_t addr ;
  int i ;

  for (i=0;i<0x2000;i++)
   {
    addr = addr + i ;
   }

  addr = SDRAM_EEPROM_CTRL_STAT;

  help_data = 0 ;

  for (i=0;i<8;i++)
   {
      data = 0x0 ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SCL ; 
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

      return_code = s3100_sharc_read(p, addr, &data, 0x1) ;

      help_data = help_data << 1 ;
      help_data = help_data + ((data & 0x100) >> 8) ;  
   }

  *read_data =  help_data  ;

      data = SDRAM_SDA_OE ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SDA_OE + SDRAM_SCL ; 
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SDA_OE ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
 
      data = 0x0 ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  return 0 ;
}

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

int sdram_eeprom_read_noack (int p,  u_int32_t* read_data)
{
  int return_code ;
  u_int32_t data ;
  u_int32_t help_data ;
  u_int32_t addr ;
  int i ;

  for (i=0;i<0x2000;i++)
   {
    addr = addr + i ;
   }

  addr = SDRAM_EEPROM_CTRL_STAT;

  help_data = 0 ;

  for (i=0;i<8;i++)
   {
      data = 0x0 ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SCL ; 
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

      return_code = s3100_sharc_read(p, addr, &data, 0x1) ;
      help_data = help_data << 1 ;
      help_data = help_data + ((data & 0x100) >> 8) ;  
   }

  *read_data =  help_data  ;

      data = SDRAM_SDA_OE + SDRAM_SDA ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SDA_OE + SDRAM_SDA + SDRAM_SCL ; 
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = SDRAM_SDA_OE + SDRAM_SDA ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;
      data = 0x0 ;
      return_code = s3100_sharc_write(p, addr, &data, 0x1) ;

  return 0 ;
}





























