/**************************************************************
$Workfile:   bsp.c  $
***************************************************************
**
**	Filename    : bsp.c
**	Description : c source file defining the BME interrupts
**	Author	    : jeya
**	Date	    : 27 Feb 2001
**	Notes	    :
**  References  : Host Interface Controller Block Definition Doc
						  prepared by Weiluo
**	Revision History :
**
****************************************************************/

/***************************************************************
**
** FIRMWARE, Copyright (C) 2000-2002
** Ikanos Communication, Fremont, CA
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of
** Ikanos Communication
**
$Revision: 1.1 $
$Date: 2006/10/16 04:34:51 $
***************************************************************/

/*  FlashEraseSector and FlashWrite reworked to use Ikanos
	 types (U8, U32) instead of WindRiver "equivalents" of
	 UIN32 and UINT8.

	 Problem is UINT32 is defined to be "unsigned int".

	 That's formally correct for the PowerPC.

	 But it introduces problems when porting.

	 Support one wants to format & print a UINT32.  The correct
	 printf format specifier is %d.  But on 16-bit systems, that
	 is not correct.  Rather, one should use %ld.  But passing
	 a UINT32 to %ld causes the compiler on the PowerPC to warn
	 about a mismatch.  As well it should.  On a 16-bit system,
	 %ld is the wrong format specifier for an unsigned int.

	 Ikanos defines U32 to be unsigned long.  Now the correct
	 format specifier is %ld on both 32-bit and 16-bit systems.

	 With FlashEraseSector and FlashWrite, the header file used
	 U32 and U8.  The instantiation (this file) used UINT32 and
	 UINT8.  For various reasons the header file was NOT included
	 in the instantiation file.  The two never saw each other and
	 no one was the wiser.  But now, to get uSdelay (portable
	 microsecond delay interface) included, the header file DOES
	 need to be included.  The compiler refuses to instatiate a
	 function whose definition used unsigned longs and whose
	 instantiation used unsigned ints.

	 Thus the change.						*/

/* Include files                 */
#ifdef USE_VXWORKS    /* IXDP425 */
#include "vxWorks.h"
#include "vme.h"
#include "memLib.h"
#include "cacheLib.h"
#include "sysLib.h"
#include "config.h"
#include "string.h"
#include "intLib.h"
#include "logLib.h"
#endif
#include "stdio.h"
#ifdef USE_VXWORKS
#include "taskLib.h"
#include "vxLib.h"
#include "tyLib.h"
#include "arch/ppc/vxPpcLib.h"
#include "private/vmLibP.h"
#include "drv/multi/mdpm860Siu.h"
#include "sysLed.h"
#include "drv/mem/eeprom.h"
#ifdef   INCLUDE_NETWORK
	 #include "sysNet.h"
#endif  /* INCLUDE_NETWORK */
#include "hsiMdpPro8xxT.h"
#else
#include <unistd.h> /* IXDP425 */
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#endif
#include "apitype.h"
#include "bsp.h"
#include "ipos.h"
#ifdef MPC_855 /* IXDP425 */
#define BME_INTERFACE

#ifdef BME_INTERFACE
	 #include "bme.h"
#endif /* BME_INTERFACE */
#endif /* BME_INTERFACE */

void UtopiaTxDisable (U8 bBmeNum);
#if !defined(P2CO) && !defined(BME_CPE_20) && defined(INI_SUPPORT)
void iniISR ();
extern void iposPtmfReset(void);
#endif  //P2CO

#define IK_PRINTF printf
/*****************************************************************************/
/*                                                                          */
/* Function : sysConfigPortPinsForBMEInterface() 	 						*/
/*                                                                          */
/* Purpose. : Initialize Port D Pins - PD3, PD4 PD5 PD6 Configuration           */
/*                                                                          */
/* Returns. : NONE                                                          */
/* Notes... :                                                               */
/****************************************************************************/
void sysConfigPortPinsForBMEInterface ( void )
{
#ifdef MPC_855 /* IXDP425 */
	 /* Get the physical location of the IMMR register */
	 int immrVal = vxImmrGet() ;

	 /* D3 pin is for rel_cpu of BME */
	 /* D4 pin is for Hardware Reset of BME */
	 /* D5 pin is for INI hw reset */
	 /* D6 pin is for FPGA hw reset */
	 /* D7 pin is for MEM_MAP */
	 *PDPAR ( immrVal ) &= (~(PD3 | PD4 | PD5 | PD6 | PD7 | PD8 | PD9 | PD14 | PD15)); /* D3, D4, D5, D6 as general I/O pins */
	 *PDDIR ( immrVal ) |= (PD3 | PD4 | PD5 | PD6 | PD7 | PD8 | PD9 | PD14 | PD15); /* D3, D4, D5, D6 as output pins */
	 *PDDAT ( immrVal ) |= (PD3 | PD4 | PD5 | PD6 | PD7 | PD8 | PD9 | PD14 | PD15);  /* D3, D4, D5, D6 value high */

	 *PBPAR ( immrVal ) &= (~(PB14 | PB15 | PB16 | PB17 | PB18 | PB20 | PB21 | PB22 | PB23));	/* D3, D4, D5, D6 as general I/O pins */
	 *PBDIR ( immrVal ) |= (PB14 | PB15 | PB16 | PB17 | PB18 | PB20 | PB21 | PB22 | PB23);	/* D3, D4, D5, D6 as output pins */
	 *PBDAT ( immrVal ) |= (PB14 | PB15 | PB16 | PB17 | PB18 | PB20 | PB21 | PB22 | PB23);   /* D3, D4, D5, D6 value high */

#ifndef P2CPE
// 	*PAPAR ( immrVal ) &= (~(PA15 | PA14 | PA13 | PA12 | PA11 | PA10 | PA9 | PA8 | PA7 |
	 *PADIR ( immrVal ) |= PA9;
	 *PADAT ( immrVal ) |= PA9;
#endif

#ifdef EIGHT_PORT_DB
	 *PAPAR ( immrVal ) &= ~(PA9|PA12);	/* A9 as general I/O pins */
	 *PADIR ( immrVal ) |= (PA9|PA12);	/* A9 as output pins */
	 *PADAT ( immrVal ) |= (PA9|PA12);	/* A9 high */
#endif

	 return;
#endif
}

/********************************************************************************/
/*	Name 	   : bmeHWReset							 							*/
/*	Purpose    : To send hardware reset signal to BME thru port D pin.			*/
/*	Parameters : None															*/
/*	Return	   : void															*/
/********************************************************************************/
void fusiv_bmeHWRest();
void fusiv_relBmeCpu(unsigned char enable);
void bmeHWReset (void)
{
#ifdef MPC_855 /* IXDP425 */
	 /*int i=0,immrVal = vxImmrGet();*/
	 int immrVal = vxImmrGet();

	 /* set PD4 bit in PDDAT reg */
	*PDDAT (immrVal) &= ~PD4;

	 uSdelay( 200 );					/* microseconds */
	 /*for (i=0;i<1000;i++){}	original hard coded loop */

	*PDDAT (immrVal) |= PD4;

	 return;
#else
    fusiv_bmeHWRest();
/* Add the IXDP425 relcpu and porst line handling using proper GPIO access */
#endif
}

void bme2HWReset (void)
{
#ifdef MPC_855 /* IXDP425 */
	 /*int i=0,immrVal = vxImmrGet();*/
	 int immrVal = vxImmrGet();
#if (defined CO_20 || defined CO_30)
	 *PDDAT (immrVal) &= ~PD5;
	 uSdelay( 200 );					/* microseconds */
	 *PDDAT (immrVal) |= PD5;
#else
	/* set PD8 bit in PDDAT reg */
	*PDDAT (immrVal) &= ~PD8;

	uSdelay( 200 );				 /* microseconds */
	/*for (i=0;i<1000;i++){}	original hard coded loop */

	*PDDAT (immrVal) |= PD8;
#endif

	 return;
#endif
}

void bmeHwResetApi (int BmeNum)
{
#ifdef MPC_855 /* IXDP425 */
	 /*int i=0,immrVal = vxImmrGet();*/
	 int immrVal = vxImmrGet();

#if defined(P2CO) && defined(SIM16P)
	 UtopiaTxDisable(BmeNum);
#endif

	 switch (BmeNum)
	 {
	 case 1:
	//IK_PRINTF ("\nReseting BME 1");
		  /* set PD4 bit in PDDAT reg */

	*PDDAT (immrVal) &= ~PD4;

		  uSdelay( 100 );					 /* microseconds */
		  /*for (i=0;i<500;i++){}		original hard coded loop */

#if defined(P2CPE) && defined(INI_SUPPORT)
//  iposPtmfReset();
#endif //P2CO

		  uSdelay( 100 );						/* microseconds */
		  /*for (i=0;i<500;i++){}		original hard coded loop */

	*PDDAT (immrVal) |= PD4;
		  break;

	 case 2:
	//IK_PRINTF ("\nReseting BME 2");

#ifdef CO_4P_BOARD
		  /* set PD4 bit in PDDAT reg */
		  *PDDAT (immrVal) &= ~PD8;
#else
		  *PDDAT (immrVal) &= ~PD5;
#endif

		  uSdelay( 200 );					 /* microseconds */
		  /*for (i=0;i<1000;i++){}	original hard coded loop */

#ifdef CO_4P_BOARD
		  *PDDAT (immrVal) |= PD8;
#else
		  *PDDAT (immrVal) |= PD5;
#endif

		  break;

	 case 3:
		  /* set PD4 bit in PDDAT reg */
		  *PDDAT (immrVal) &= ~PD12;

		  uSdelay( 200 );					 /* microseconds */
		  /*for (i=0;i<1000;i++){}	original hard coded loop */

		  *PDDAT (immrVal) |= PD12;

		  break;

	 case 4:
		  /* set PD4 bit in PDDAT reg */
		  *PDDAT (immrVal) &= ~PD13;

		  uSdelay( 200 );					 /* microseconds */
		  /*for (i=0;i<1000;i++){}	original hard coded loop */

		  *PDDAT (immrVal) |= PD13;

		  break;

	 default:
	IK_PRINTF ("\nUndefined BME number");
		  break;
	 }

	 return;
#else
/* Add the IXDP425 relcpu and porst line handling using proper GPIO access */
   // printf("VDSL app bmeHwReset \n");
    fusiv_bmeHWRest();
#endif
} /* bmeHwResetApi */


/********************************************************************************/
/*	Name 	   : iniHWReset							 							*/
/*	Purpose    : To send hardware reset signal to INI thru port D pin.			*/
/*	Parameters : None															*/
/*	Return	   : void															*/
/********************************************************************************/
void iniHWReset (void)
{
#ifdef MPC_855 /* IXDP425 */
	/*int i=0,immrVal = vxImmrGet();*/
	int immrVal = vxImmrGet();

	/* set PD5 bit in PDDAT reg */
	*PDDAT (immrVal) &= ~PD5;

	uSdelay( 200 );				 /* microseconds */
	/*for (i=0;i<1000;i++){}	original hard coded loop */

	*PDDAT (immrVal) |= PD5;

	return;
#endif
}

/********************************************************************************/
/*	Name 	   : fpgaHWReset							 							*/
/*	Purpose    : To send hardware reset signal to BME thru port D pin.			*/
/*	Parameters : None															*/
/*	Return	   : void															*/
/********************************************************************************/
void fpgaHWReset (void)
{
#ifdef MPC_855 /* IXDP425 */
	/*int i=0,immrVal = vxImmrGet();*/
	int immrVal = vxImmrGet();

	/* set PD6 bit in PDDAT reg */
#ifdef EIGHT_PORT_DB
   *PADAT (immrVal) &= ~PA9;
#else
	*PDDAT (immrVal) &= ~PD6;
#endif

	uSdelay( 200 );				 /* microseconds */
	/*for (i=0;i<1000;i++){}	original hard coded loop */

#ifdef EIGHT_PORT_DB
	*PADAT (immrVal) |= PA9;
#else
	*PDDAT (immrVal) |= PD6;
#endif

	return;
#endif
}

/****************************************************************************/
/*                                                                          */
/* Function : sysBMEInterfaceInit( )                                        */
/*                                                                          */
/* Purpose. : Initializes BME memory mapped interface                       */
/*                                                                          */
/* Returns. : N/A                                                            */
/*                                                                          */
/* Notes... : None                                                          */
/*                                                                          */
/****************************************************************************/
void sysBMEInterfaceInit (void)
{
#ifdef MPC_855 /* IXDP425 */
/* Get the physical location of the IMMR register */
	 int immrVal = vxImmrGet() ;

	 unsigned long brRegVal1,brRegVal6;
	 unsigned long orRegVal1,orRegVal6;

	 /* configure BR1 reg values */
	 /*
	 base addr      : 00 - 16 : 0000 1000 0000 0000 0 -> 0x08000000
	 address type   : 17 - 19 : 000
	 port size      : 20 - 21 : 01 -> 8 bit port size
	 parity         : 22 - 22 : 0 -> disabled
	 write protect  : 23 - 23 : 0 -> read & write access are allowed
	 machine select : 24 -  25 : 00 -> GPCM
	 reserved 	   : 26 - 30 : 00000
	 valid		   : 31 - 31 : 1 -> valid contents
	 */
	 brRegVal1 = 0x08000401;
	 brRegVal6 = 0x09000401;  /* 0000 1001 0000 0000 0 */

	 /* configure OR1 reg values */
	 /*
	 address mask   : 00 - 16 : 1111 1111 1111 1111 0 -> 0xffff0000 mask all higher bits
	 addr type mask : 17 - 19 : 000
	 csnt/sam       : 20 - 20 : 0/1 -> chip select negation time / start address multiplex
	 acs/g5la/g5ls  : 21 - 22 : 11 -> cs is output half a clock after the address lines
	 bih	       : 23 - 23 : 1 -> burst inhibit - bank doesn't support burst accesses
	 scy	       : 24 - 27 : 0000/1111 -> 15 wait states - select cycle length ( GPCM only )
	 seta	       : 28 - 28 : 1/0 -> select external transfer acknowledge ( GPCM only )
	 trlx 	       : 29 - 29 : 0/1 -> timing relaxed ( GPCM only )
	 ehtr	       : 30 - 30 : 0 -> extended hold time on read ( GPCM only )
	 reserved       : 31 - 31 : 0
	 */

	 /* to set max wait states, csnt = 0b1,  acs = 0b11, scy = 0b1111, trlx = 0b1 */
	 /* max cycle length = 4 + 2*SCY = 4 +2*15 = 34 wait states */


	 orRegVal1 = 0xffff0708; /* waiting for external ack - TA */

	 orRegVal6 = 0xffff0708; /* waiting for external ack - TA */

#if 0
	 orRegVal1 = 0xffff0ff4; /* internal ack - max wait cycles */

	 orRegVal6 = 0xffff0ff4; /* internal ack - max wait cycles */
#endif


	 *OR1(immrVal) = orRegVal1;
	 *BR1(immrVal) = brRegVal1;

	 *OR6(immrVal) = orRegVal6;
	 *BR6(immrVal) = brRegVal6;

	 return;
#endif
}

/****************************************************************************/
/*                                                                          */
/* Function.. : relBmeCpu( )                                                */
/*                                                                          */
/* Purpose... : Holds or releases BME CPU                                   */
/*																			*/
/* Parameters : unsigned char - enable. If enable is 1, releases BME CPU.   */
/*				Else holds BME CPU.											*/
/*                                                                          */
/* Returns... : N/A                                                         */
/*                                                                          */
/* Notes..... : None                                                        */
/*                                                                          */
/****************************************************************************/
void relBmeCpu (unsigned char enable)
{
#ifdef MPC_855 /* IXDP425 */
	 /* Get the physical location of the IMMR register */
	 int immrVal = vxImmrGet() ;

	 if (enable)
	 {
		*PDDAT ( immrVal ) &= (~PD3); /* D3 value low */
//		IK_PRINTF ("\nBME release done successfully!");
		}
	else 	{
		*PDDAT ( immrVal ) |= PD3; /* D3 value high */
		//IK_PRINTF ("\nBME hold done successfully!");
		}

	 return;
#else
/* Add the IXDP425 relcpu GPIO handling */
        fusiv_relBmeCpu(enable);

#endif
}

void relCpu (int BmeNum, unsigned char enable)
{
#ifdef MPC_855 /* IXDP425 */
	 /* Get the physical location of the IMMR register */
	 int immrVal = vxImmrGet() ;

	 switch (BmeNum)
	 {
	 case 1:
		  if (enable)
		  {
		*PDDAT ( immrVal ) &= (~PD3); /* D3 value low */
		//IK_PRINTF ("\nBME 1 release done successfully!");
		}
	else 	{
		*PADAT ( immrVal ) |= PA9; /* D3 value high */
		//IK_PRINTF ("\nBME 1 hold done successfully!");
		}
		  break;

	 }
	 return;
#else
        fusiv_relBmeCpu(enable);
	return;
#endif
}

/****************************************************************************/
/*                                                                          */
/* Function.. : getRelCpuStatus ()                                          */
/*                                                                          */
/* Purpose... : Returns status of BME RelCpu pin                            */
/*																			*/
/* Parameters : No inputs yet; has to be ported for multi-BME case          */
/*				Now works only for BME 1.					                */
/*                                                                          */
/* Returns... : 1 if BME is running, 0 if BME is in hold state              */
/*                                                                          */
/* Notes..... : This function has to be ported for every new board          */
/*              Now it works only for CO2 reference board for 1 BME build   */
/*                                                                          */
/****************************************************************************/

unsigned int getRelCpuStatus (void)
{
#ifdef MPC_855 /* IXDP425 */
#if !defined(CO_20_EMULATION_BOARD) && !defined(CO_30_EMULATION)
	int immrVal = vxImmrGet ();
	int relCpuStatus;

	relCpuStatus = *PDDAT (immrVal);
	relCpuStatus &= PD3;

	if (relCpuStatus)
		return 0; //return 0 if BME in hold state
	else
		return 1; //return 1 if BME in running state
#endif
#endif
    return 0;
}

#ifndef NO_SET_PROD_MODE
/****************************************************************************/
/*                                                                          */
/* Function.. : setProdMode( )                                                */
/*                                                                          */
/* Purpose... : Holds or releases BME CPU                                   */
/*																			*/
/* Parameters : unsigned char - enable. If enable is 1, releases BME CPU.   */
/*				Else holds BME CPU.											*/
/*                                                                          */
/* Returns... : N/A                                                         */
/*                                                                          */
/* Notes..... : None                                                        */
/*                                                                          */
/****************************************************************************/
void setProdMode (unsigned char enable)
{
#ifdef MPC_855 /* IXDP425 */
	 /* Get the physical location of the IMMR register */
	 int immrVal = vxImmrGet() ;

	 if (enable)
	 {
#ifdef EIGHT_PORT_DB
		  *PADAT ( immrVal ) |= (PA12); /* D3 value high */
#else
		  *PDDAT ( immrVal ) |= (PD7); /* D3 value high */
		//IK_PRINTF ("\nMEM_MAP set to high");
#endif
	 }
	 else
	 {
#ifdef EIGHT_PORT_DB
		  *PADAT ( immrVal ) &= (~PA12);	/* D3 value low */
#else
		  *PDDAT ( immrVal ) &= (~PD7); /* D3 value low */
		//IK_PRINTF ("\nMEM_MAP set to low");
#endif
	 }

	 return;
#endif
}
#endif

/* Flash algorithm for AMD_29F080_N_8_32_I.c */
#ifdef MPC_855 /* IXDP425 */
typedef union tFLASH
{
	 UINT32 Integer;
	 UINT32 Float;
} tFLASH;

#define MASKSHIFTOP1	>>
#define MASKSHIFTOP2	<<
//=====================================================================
// IOSync - this can be a macro, a function call, or an assembler macro.
// IOSync is invoked in order to force all pending I/O operations to
// complete.  The flash program and erase operations make use of this
// to insure commands sent to the flash devices are sent in the correct
// order.
//=====================================================================
#define IOSync()	asm ("	eieio")
#define ReadUnaligned(x)	*(UINT32 *)(x)
#endif
//#ifdef CO_4P_BOARD
#if 0
static const tFLASH Unlock1 =   { 0x55555555};
static const tFLASH Unlock2 =   { 0xaaaaaaaa};
static const tFLASH Erase1 =    { 0x01010101};
static const tFLASH Erase2 =    { 0x0c0c0c0c};
static const tFLASH Program =   { 0x05050505};
static const tFLASH ReadArray = { 0x0f0f0f0f};
static const tFLASH Erased =    { (UINT32)-1};
//#else
static const tFLASH Unlock1 =   { 0xAAAAAAAA};
static const tFLASH Unlock2 =   { 0x55555555};
static const tFLASH Erase1 =    { 0x80808080};
static const tFLASH Erase2 =    { 0x30303030};
static const tFLASH Program =   { 0xA0A0A0A0};
static const tFLASH ReadArray = { 0xF0F0F0F0};
static const tFLASH Erased =    { (UINT32)-1};
#endif
#ifdef MPC_855 /* IXDP425 */
static tFLASH Unlock1 = { 0xAAAAAAAA};
static tFLASH Unlock2 = { 0x55555555};
static tFLASH Erase1 =  { 0x80808080};
static tFLASH Erase2 =  { 0x30303030};
static tFLASH Program = { 0xA0A0A0A0};
static tFLASH ReadArray =   { 0xF0F0F0F0};
static tFLASH Erased =  { (UINT32)-1};

void checkFlash (volatile UINT32 * pChip)
{
	 (UINT32)pChip &= ~(0x400000 - 1);
	 *pChip = 0x55555555;
	 IOSync();
	 *pChip = 0xaaaaaaaa;
	 IOSync();
	 *pChip = 0x09090909;
	 IOSync();
	 if (*(pChip + 1) == 0x1c1c1c1c)
	 {
		  Unlock1.Float = 0x55555555;
		  Unlock2.Float = 0xaaaaaaaa;
		  Erase1.Float = 0x01010101;
		  Erase2.Float = 0x0c0c0c0c;
		  Program.Float = 0x05050505;
		  ReadArray.Float = 0x0f0f0f0f;
		  *pChip = 0x0f0f0f0f;
		  IOSync();
    IK_PRINTF("\nIt is flipped");
  }
	 else
    IK_PRINTF("\nNot flipped");

}

#endif
/*extern UINT32 FlashWrite(volatile UINT8 *pDest, UINT8 *pSource,
		  UINT32 Length)*/

/* reworked to use Ikanos types: U8 and U32
	UINT32 and UINT8 are from Wind River     */

extern U32 FlashWrite(volatile U8 *pDest, U8 *pSource,
							 U32 Length)
{
#ifdef MPC_855 /* IXDP425 */
	 volatile UINT8 *pChip = (volatile UINT8 *)((unsigned int)pDest
															  & ~(0x400000 - 1));
	 unsigned int OriginalLength = Length;
	 UINT32 Mask;
	 tFLASH Data;
	 unsigned short n;
	 int TimedOut=10000;

//	IK_PRINTF ("\nFlash write 0x%x",pDest);

/*	SetFlashTimer(5000);		// 5 second timeout
*/	while(Length)
	{
		  n = ((unsigned int)pDest & (4 - 1));
		  if (n)
		  {
				pDest -= n;
				pSource -= n;
				Mask = (UINT32)-1 MASKSHIFTOP1 (8 * n);
		  }
		  else
				Mask = (UINT32)-1;

		  if ((n + Length) < 4)
				Mask &= (UINT32)-1 MASKSHIFTOP2 (8 * (4 - (n + Length)));

		  Data.Integer = ReadUnaligned(pSource) & Mask;
		Data.Integer |= *(volatile UINT32 *)pDest & (~Mask);
		  pSource += 4;
		  *(volatile UINT32 *)(pChip + 0x15554) = Unlock1.Float;
		  IOSync();
		  *(volatile UINT32 *)(pChip + 0xAAA8) = Unlock2.Float;
		  IOSync();
		  *(volatile UINT32 *)(pChip + 0x15554) = Program.Float;
		  IOSync();
		  *(volatile UINT32 *)pDest = Data.Float;


		  while ((*(volatile UINT32 *)pDest != Data.Integer) && (TimedOut!=0))
				TimedOut--;

	if (TimedOut<0) IK_PRINTF ("\nflash write timedout");

//		IK_PRINTF ("\n %x %x",*(volatile UINT32 *)pDest,Data.Integer);
		  pDest += 4;
		Length -= min((U32)(4 - n), Length);
	}

/*	KillTimer(&FlashTimer);
*/  *(volatile UINT32 *)(pDest - 4) = ReadArray.Float;
	 return OriginalLength - Length;
#endif
        return 0;
}

/*extern UINT32 FlashEraseSector(volatile UINT8 *pSector)*/

/* reworked to use Ikanos types: U8 and U32
	UINT32 and UINT8 are from Wind River     */

extern U32 FlashEraseSector(volatile U8 *pSector)
{
#ifdef MPC_855 /* IXDP425 */
	 UINT32 TimedOut=0xffffff;

	 volatile UINT8 *pChip = (volatile UINT8 *)((unsigned int)pSector
															  & ~(0x400000 - 1));
//IK_PRINTF ("\nFlash erase 0x%x pChip 0x%x ",pSector,pChip);
/*
	 SetFlashTimer(5000);
*/
	 *(volatile UINT32 *)(pChip + 0x15554) = Unlock1.Float;
	 IOSync();
	 *(volatile UINT32 *)(pChip + 0xAAA8) = Unlock2.Float;
	 IOSync();
	 *(volatile UINT32 *)(pChip + 0x15554) = Erase1.Float;
	 IOSync();
	 *(volatile UINT32 *)(pChip + 0x15554) = Unlock1.Float;
	 IOSync();
	 *(volatile UINT32 *)(pChip + 0xAAA8) = Unlock2.Float;
	 IOSync();
	 *(volatile UINT32 *)pSector = Erase2.Float;
	 IOSync();

	 while ((*(volatile UINT32 *)pSector != Erased.Integer) && (TimedOut!=0))
		  TimedOut--;

//	if (TimedOut<0) IK_PRINTF ("\nflash erase timedout");
	 /*KillTimer(&FlashTimer);*/

//	IK_PRINTF ("\n *pSector %x Erased.Int %x",*(volatile UINT32 *)pSector, Erased.Integer);

	 *(volatile UINT32 *)pSector = ReadArray.Float;
	return (*(volatile UINT32 *)pSector != Erased.Integer);
#endif
        return 0;
}

void hostIntInit(void)
{
#ifdef MPC_855 /* IXDP425 */
	 UINT32 oSimask;
	 UINT32 oSiel;
	 UINT32 regBase;

	 regBase = vxImmrGet();
	 // NOTE: SIMASK and SIEL register settings for below interrupts still set in BSP

	 /* connect bme interrupt to IRQ1 external interrupt pin */
	 /* IRQ1 as BME Level Interrupt */
//#ifdef BME_USE_LEVEL_INTR
//	intConnect (IV_LEVEL1, bmeISR1, SIMASK_LVM1);
//	intConnect (IV_LEVEL3, bme2ISR, SIMASK_LVM3);
//	intConnect (IV_LEVEL4, bme3ISR, SIMASK_LVM4);
//	intConnect (IV_LEVEL6, bme4ISR, SIMASK_LVM6);
//#else
	 intConnect (IV_IRQ1, NULL, SIMASK_IRM1);
	 intConnect (IV_IRQ3, NULL, SIMASK_IRM3);
	 intConnect (IV_IRQ4, NULL, SIMASK_IRM4);
	 intConnect (IV_IRQ6, NULL, SIMASK_IRM6);
//#endif

#if !defined(P2CO) && !defined(BME_CPE_20) && defined(INI_SUPPORT)
	 /* IRQ2 as INI Level Interrupt */
	 intConnect (IV_IRQ2, iniISR, SIMASK_IRM2);

#endif //P2CO

//	oSimask=* SIMASK(regBase) & ~(SIMASK_IRM1 | SIMASK_LVM1 |
//                                SIMASK_IRM2 | SIMASK_LVM2 |
//                                SIMASK_IRM3 | SIMASK_LVM3 |
//                                SIMASK_IRM4 | SIMASK_LVM4 |
//                                SIMASK_IRM6 | SIMASK_LVM6);
	 oSimask=* SIMASK(regBase) & ~(SIMASK_IRM1 | SIMASK_IRM2 |
											 SIMASK_IRM3 | SIMASK_IRM4 |
											 SIMASK_IRM6);
	 oSiel=* SIEL(regBase) & ~(SIEL_ED1 | SIEL_WM1 | SIEL_ED2 | SIEL_WM2 |
										SIEL_ED3 | SIEL_WM3 | SIEL_ED4 | SIEL_WM4 |
										SIEL_ED6 | SIEL_WM6);

	 * SIMASK(regBase) = oSimask;	// Disable interrupt first
//#ifdef BME_USE_LEVEL_INTR
	 * SIEL(regBase) = oSiel | SIEL_ED2; /* IRQ1<---Not support message buffering, edge triggered */
//	* SIMASK(regBase) = (oSimask | SIMASK_LVM1 | SIMASK_IRM2 | SIMASK_LVM3);
//#else
	 * SIEL(regBase) = oSiel | SIEL_ED1 | SIEL_ED2 | SIEL_ED3 | SIEL_ED4 | SIEL_ED6; /* IRQ1<---Not support message buffering, edge triggered */
//	* SIMASK(regBase) = (oSimask | SIMASK_IRM1 | SIMASK_IRM2 | SIMASK_IRM3);
	 * SIMASK(regBase) = (oSimask | SIMASK_IRM2);
//#endif
#endif
}

int ledNumIni=0;

#if !defined(P2CO) && !defined(BME_CPE_20) && defined(INI_SUPPORT)

extern void handleIniInt();

void iniISR ()
{
#ifdef MPC_855 /* IXDP425 */
	 int immrVal = vxImmrGet() ;
	 extern void disableIniInt( void );

	 /* Acknowledge interrupt */
	 *SIPEND(immrVal) |= SIPEND_IRQ2;

	 ledNumIni++;
	 if (ledNumIni>255) ledNumIni=0;
	 sysLedBarOn (ledNumIni,SINGLE_LED);

	 disableIniInt();

	 handleIniInt();
#endif
}

#endif //P2CO

/******************************************************************************
*                                                                             *
* Function.. : HostEpldInterfaceInit                        	                *
*                                                   	                        *
* Purpose... : Initialise EPLD Address space                        	        *
*									                                                            *
* Parameters : Address Offset from the FPGA base address (CS4) and data byte  *
*              to be written to the FPGA                                      *
*                                                                             *
* Returns... : N/A                                                            *
*                                                                             *
******************************************************************************/

void HostEpldInterfaceInit (void)
{
#ifdef MPC_855 /* IXDP425 */
	 /* Get the physical location of the IMMR register                           */
	 int immrVal = vxImmrGet() ;

	 unsigned long brRegVal4, orRegVal4;

	 /* configure BR4 reg values                                                 */
	 /*
	 base addr      : 00 - 16  : 0000 0111 0000 0000 0 -> 0x07000000
	 address type   : 17 - 19  : 000
	 port size      : 20 - 21  : 01 -> 8 bit port size
	 parity         : 22       : 0 -> disabled
	 write protect  : 23       : 0 -> read & write access are allowed
	 machine select : 24 - 25  : 00 -> GPCM
	 reserved 	     : 26 - 30  : 00000
	 valid		       : 31 - 31  : 1 -> valid contents  	                         	*/

	 brRegVal4 = 0x07000401;	 /* 0000 0111 0000 0000 0000 0100 0000 0001       */

	 /* configure OR4 reg values                                                 */
	 /*
	 address mask   : 00 - 16 : 1111 1111 1111 1111 0 -> 0xffff0000
																		mask all higher bits
	 addr type mask : 17 - 19 : 000
	 CSNT/SAM       : 20      : 0/1 -> chip select negation time
	 acs/g5la/g5ls  : 21 - 22 : 11 ->  cs is output half a clock after the
												address lines
	 bih	           : 23      : 1 ->   burst inhibit - bank doesn't support
												burst accesses
	 scy	           : 24 - 27 : 0000-> 15 wait states - select cycle length
												( GPCM only )
	 seta	         : 28      : 0 ->   External transfer acknowledge Disabled
												( GPCM only )
	 trlx 	         : 29      : 1 ->   timing NOT relaxed ( GPCM only )
	 ehtr	         : 30      : 0 -> extended hold time on read ( GPCM only )
	 reserved       : 31      : 0 	                                              */

//  orRegVal4 = 0xffff0704;
	 orRegVal4 = 0xffff8720;

	 *OR4(immrVal) = orRegVal4;
	 *BR4(immrVal) = brRegVal4;
#endif
}

void
HostAfeAddrSet(U8 bData)
{
#ifdef MPC_855 /* IXDP425 */
	 U8 *baseAddr;

	 baseAddr = (U8 *) 0x07000010;
	 *baseAddr = bData;

#if defined(P2CO) && defined(SIM16P)
	 baseAddr = (U8 *) 0x07000020;
	 *baseAddr = bData;
#endif
#endif

}


U32
HostEpldRead(U8 bOffset)
{
	 U8 *baseAddr;

	 baseAddr = (U8 *) 0x07000000 + bOffset;
	 return(*baseAddr);
}


U32
HostEpldWrite(U8 bOffset, U8 bData)
{
	 U8 *baseAddr;

	 baseAddr = (U8 *) 0x07000000 + bOffset;
	 *baseAddr = bData;
	 return(0);
}

//#if defined(BME_CPE_20)
/***************************************************************************/
void HostFpgaWrite(U8 boffset,U8 bdata)
{
#if defined (CPE20_REF_BOARD) || defined (CO_30_EMULATION)
	 U8 *baseAddr;

	 baseAddr = (U8 *) 0x09000000 + boffset;
	 *baseAddr = bdata;

#endif // defined (CPE20_REF_BOARD)
}
/***************************************************************************/
//#endif

void UtopiaTxDisable (U8 bBmeNum)
{
	 U8 *baseAddr;
	 U8 bData;

	 baseAddr = (U8 *) 0x07000000 + 4;
	 bData = *baseAddr;

	 switch (bBmeNum)
	 {
	 case 1:
		  bData &= 0xfe;
		  break;

	 case 2:
		  bData &= 0xfd;
		  break;

	 default:
		  bData = 0;
	 }

	 *baseAddr = bData;

  IK_PRINTF ("\n Utopia TX Disable: %x", (*baseAddr));
	 return;

}

void UtopiaTxEnable (U8 bBmeNum)
{
	 U8 *baseAddr;
	 U8 bData;

	 baseAddr = (U8 *) 0x07000000 + 4;
	 bData = *baseAddr;

	 switch (bBmeNum)
	 {
	 case 1:
		  bData |= 0x01;
		  break;

	 case 2:
		  bData |= 0x02;
		  break;

	 default:
		  bData = 0xff;
	 }

	 *baseAddr = bData;

  IK_PRINTF ("\n Utopia TX Enable %x", (*baseAddr));
	 return;
}

#ifdef SW_HIC_DTACK

#define OR_OFFSET 0x104
#define SETA_BIT_MASK 0x00000008

void
setupForSwHICDelay( void )
{
        volatile unsigned long *pCurCSReg;
        unsigned long curRegVal;
        unsigned char curPollMode = 0x01;
        int immrVal = vxImmrGet ();

        // Configure either internal or external TA

        pCurCSReg = (volatile unsigned long *)(immrVal + (OR_OFFSET + 8));
        *pCurCSReg &= ~SETA_BIT_MASK;
        // Configure SCY to max of 15 cycles
        *pCurCSReg |= (0x0F << 4);

        IK_PRINTF( "Poll Mode of operation configured!!!\n" );
}
#endif /* SW_HIC_DTACK */
