#include <stdio.h>

void atm_fast_mbup () 
{ 
  UINT32 ccr_status;
  UINT32 temp0, addr;
  UINT32 temp1, DmaSize;
  int i=0;
  int j=0;
  UINT32 mod, data;
  int cws, ncw, numch, LoopCnt;
  
  printf("Enter the Loop count:");
  scanf ("%d", &LoopCnt);
  printf("%d\n", LoopCnt);
  printf ("\n");

  printf("Enter the codeword size:");
  scanf ("%d", &cws);
  printf("%d\n", cws);
  printf ("\n");

  printf("Enter number of codewords per frame:");
  scanf ("%d", &ncw);
  printf("%d\n", ncw);
  printf ("\n");

  printf("Enter number of channels:");
  scanf ("%d", &numch);
  printf("%d\n", numch);
  printf ("\n");

  DmaSize = (cws * ncw * numch);
  if (!numch || !cws || !ncw || (DmaSize > 0x1fff)) 
    printf ("\t***** ERROR: NumCh/CodeWordSize/NumCodeWords is incorrect\n");
  else {
  printf ("************************************************\n");
  printf ("\tATM/FAST TC LOOP BACK TEST CONFIGURATION: \n");
  printf ("\tCodeword size -> %d\n",  cws);
  printf ("\tNumber of Codewords -> %d\n",  ncw);
  printf ("\tNumber of Channels -> %d\n",  numch);
  printf ("************************************************\n");

  //////////////////////////////////////
  // Initialize SEMAPHORE, FRM_CMD_COUNT, CRC to 0
  rmw_reg (0xe000843c, 0x0, 1);
  rmw_reg (0xe000843c, 0x0, 0);
  rmw_reg (0xe0008430, 0x0, 0);
  
//#if 0
  //////////////////////////////////////
  // load fmc I$
  load_fmc_icache_mbup ();

  //////////////////////////////////////
  // TNI Programming
  for (j=0; j<numch; j++) {
    addr = 0xe0000000 | (j*4);
    mod = (0x2000000*j) | 0x80000000;
    pio_write( addr, mod);                  // tni fast channel port register
  }
  
  for (j=0; j<numch; j++) {
    addr = 0xe0000200 | (j*4);
    mod = (0x4000000*j) | 0x80000000;
    pio_write( addr, mod);                  // PHYs channel number register
  }

  for (j=0; j<numch; j++) {
    addr = 0xe0000400 | (j*4);
    pio_write( addr, 0x80000000);           // PHYs control register
  }
  
  //////////////////////////////////////
  // XFI Programming
  for (j=0; j<numch; j++) {
    addr = 0xe0040100 | (j*4);
    pio_write( addr, 0x00000000);           // xfifo fast context table A
  }
  
  for (j=0; j<numch; j++) {
    addr = 0xe0040000 | (j*4);
    data = 0x19 | (0x200*j);
    pio_write( addr, data);                 // xfifo fast context table B
  }
  //////////////////////////////////////
  // TOFT Programming
  pio_write( 0xe0048400, 0x00000005);       // tone order fifo context table

  //////////////////////////////////////
  // Initialize SEMAPHORE, DMC_CMD_COUNT, DMC_CMD_TYPE to 0
  rmw_reg (0xe002043c, 0x0, 1);
  rmw_reg (0xe002043c, 0x0, 0);
  rmw_reg (0xe002042c, 0x0, 0);
 
  //////////////////////////////////////
  // Enable BFIFO demapper fifo
  pio_write( 0xe0060000, 0x00000003);       // demapper fifo context table

  //////////////////////////////////////
  // BFI programming
  for (j=0; j<numch; j++) {
    addr = 0xe0060200 | (j*4);
    pio_write( addr, 0x00000000);           // bfifo fast context table B
  }
  
  for (j=0; j<numch; j++) {
    addr = 0xe0060100 | (j*4);
    data = 0x19 | (0x200*j);
    pio_write( addr, data);                 // bfifo fast context table A
  }
  //////////////////////////////////////
  // RNI programming
  for (j=0; j<numch; j++) {
    addr = 0xe0028100 | (j*4);
    pio_write( addr, 0x80000000);           // rni PHY control register
  }
  //////////////////////////////////////
  // CFI programming
  if (numch == 1)
      pio_write(0xe0068100, 0x0);
  else
      for (j=0; j<numch/2; j++) {
          addr = 0xe0068100 | (j*4);
          pio_write( addr, 0x0);            // even numbered PHYs bank B register
          addr = 0xe0068300 | (j*4);
          pio_write( addr, 0x0);            // odd numbered PHYs bank B register
      }
  
  if (numch == 1)
      pio_write(0xe0068000, 0x19);
  else
      for (j=0; j<numch/2; j++) {
          data = 0x19 | (0x400*j);
          addr = 0xe0068000 | (j*4);
          pio_write( addr, data);           // even numbered PHYs bank A register
          data = 0x1019 | (0x400*j);
          addr = 0xe0068200 | (j*4);
          pio_write( addr, data);           // odd numbered PHYs bank A register
      }
  //////////////////////////////////////
  // load dmc D$, I$
  load_dmc_icache_mbup ();

  load_dmc_dcache_mbup (numch);

  //////////////////////////////////////
  // load fmc D$
  load_fmc_dcache_mbup (numch);
  

  addr = 0xe0008440;
  for (j=0; j<numch; j++) {
    //////////// FMC commands ////////////
    // Set State
    pio_write (addr, (0x01000000 + 0x200000*j));  addr = addr + 4;
    pio_write (addr, 0x41000020);                 addr = addr + 4;

    mod = 0x10001 * j;
    //////////////////////////////////////
    // Send CodeWordSize bytes from xfifo to tone order fifo
    for (i=0;i<ncw;i++) {
      pio_write( addr, (0x80008200 | mod));       addr = addr + 4;
      pio_write( addr, (0x02700000 | (cws-16)));  addr = addr + 4;
    }

    //////////////////////////////////////////
    // Save State
    pio_write( addr, (0x00000100 + 0x20*j));      addr = addr + 4;
    pio_write( addr, 0x42000020);                 addr = addr + 4;
  }

  ///////////// DMC commands ///////////////
  addr = 0xe0020440;
  for (j=0; j<numch; j++) {
    // Set state
    pio_write( addr, (0x01000000 + 0x200000*j));  addr = addr + 4;
    pio_write( addr, 0x04000020);                 addr = addr + 4;

    mod = 0x10001 * j;
    for (i=0;i<ncw;i++) {
      // Read 0x4a bytes from demapper into bfifo_fast
      pio_write( addr, (0x00008900 | j));         addr = addr + 4;
      pio_write( addr, (0x40010000 | cws));       addr = addr + 4;
      // Set RSChkBtyes for next codeword
      pio_write( addr, 0x00100000);               addr = addr + 4;
      pio_write( addr, (0x40400000 | cws));       addr = addr + 4;
      // Read 0x4a bytes from bfifo_fast into rs_decoder
      pio_write( addr, (0x89008c00 | mod));       addr = addr + 4;
      pio_write( addr, (0x40300000 | cws));       addr = addr + 4;
      // Read 0x3a bytes from rs_decoder into cfifo_inlv
      pio_write( addr, (0x8c008b00 | mod));       addr = addr + 4;
      pio_write( addr, (0x02200000 | (cws-16)));  addr = addr + 4;
    }
    //////////////////////////////////////////
    // Save State
    pio_write( addr, (0x00000100 +0x20*j));       addr = addr + 4;
    pio_write( addr, 0x18000020);                 addr = addr + 4;
  }
  
  //////////////////////////////////////
  // Initialize TOFT-Demapper fifo DMA
  init_dma ();

  taskDelay (10);
  //////////////////////////////////////
  //enable dmc & fmc
  pio_write( 0xe0020000, 0x00010001);       // enable DMC
  pio_write( 0xe0008000, 0x00010001);       // enable FMC

//#if 0
  for (i=0; i<LoopCnt; i++) {
    // Set CMD_TYPE=DO_FRM_CMD
    rmw_reg (0xe000842c, 0x10000, 0);
    
    // Set the FMC command count & semaphore
    pio_write (0xe000843c, ((((2+ncw)*numch) << 16) | 0x1));
  
    // check FMC/DMC semaphore for clear
    poll_reg (0xe002043c, 0x0000ffff,0,0);
    poll_reg (0xe000843c, 0x0000ffff,0,0);
    poll_toft (DmaSize);

    // Set DMC Command type
    rmw_reg (0xe002042c, 0x10000, 0);
  
    // Set DMC command count & Semaphore
    pio_write (0xe002043c, ((((ncw*4+2)*numch) << 16) | 0x1));
//#endif
  }
  }
}   /*end of test*/
