/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * =======================================================================
 * The ncc_init routine is responsible for configuring the initial value
 * for all NCC ASIC registers.  This routine will autosize ROM and RAM
 * and configure the appropriate chip select registers and set up PORTA/B/C.
 *
 * Called by the startup code (INIT.s) to initializes the chip selects for 
 * ram and to determine the amount of ram installed on this unit.
 *
 *                                                                        
 *                                                                        
 * Edit Date/Ver   Edit Description
 * ==============  ===================================================
 * JAD  05/27/98   I changed the BSIZE configuration for  the chip select configuration from 
 *                 16 cycles to 4.  This setting provides a  much better optimization for 
 *                 100BT Ethernet DMA Transmitter.
 * JAD  06/04/98   I changed the flash_id variable type from INT8 to WORD8.  The INT8 was
 *                 causing a compiler problem when comparing to 0xFF.
 * JAD  07/17/98   I changed the configuration for PCI interfaces to operate using FULL bus
 *                 speed instead of 1/2 Bus Speed.  The updated versions of the NETA12-1 device
 *                 can operate PCI interfaces at Full Bus Speed.
 * JAD  08/07/98   I made a change to prevent the ENI Shared Register from being loaded or used
 *                 in an EIO environment.
 * JAD  08/10/98   I changed the BSIZE configuration for CS1 back from 4 to 16 for REV0 chips 
 *                 only.  The REV0 chips require the larger BSIZE, however, the REV1 chips are
 *                 better with the smaller BSIZE. 
 * JAD  11/30/98   Disabled CS0 burst on the Ricoh Stinger board.
 * JAD  03/01/99   Add features in support of the NETA15 and NETA40 chips.
 *
 * LZ   10/06/99   Ported to NET_OS. Green Hill Software compiler
 *                 take out all the #ifdef(many card) and code.
 * LZ   04/17/00   Fixed a bug, in chip select 0 optional register for 32-bit mode 2M size,
 *                 should be 0xf3e00000 instead of 0xf3800000.
 * LZ   05/22/00   Added comments here and there, took out a lot unused functions.
 * LZ   06/06/00   Added code to disable CS3 if APP_USE_NVRAM flag is set to 0 in appconfig.h.
 * PMJ  11/21/00   Added the sysClock public API definition PLL_CONTROL_REGISTER_N_VALUE to 
 *                 set up the PLLCNT value.
 * GPL  12/28/00   CSOR Mask set for 0xffffe instead of 0xffffc for 8K NVRAM 
 * JFU  1/3/01     Updated pllval value to E3E based on hardware group's recommendation
 * LZ   01/17/01   RAM chip select option register's bcyc field is changed if the clock is 
 *                 faster than 33 Mhz.
 * LZ  04/20/01    added #include <narmled.h> to use general LED driver in narmled.c
 *                 enable use of port C pin 1 & pin 2 for LED green and red.
 * PMJ 04/30/01    Additions to support the 50-* chip.  Replaced the old and slow memory
 *                 test with a fast one (written in assembler).  Cleaned up find_top_of_ram,
 *                 added BSP_INITIALIZATION_DEBUG.  This definition should be added to the 
 *                 bsp.bld file.
 * PMJ 05/01/01    Removed a wait state and enabled the RSYNC bit for operation at 33 Mhz.
 * PMJ 05/02/01    Corrected support for EDO RAM boards, sensed and converted from Fast Page 
 *                 mode to EDO RAM on chip revs greater than 50-0.
 * PMJ 05/04/01    Clarified logic for generating debugger flag.
 * LZ  05/08/01    Fixed the flash size to be "32-bit 2M" or "16-bit 1M".
 * PMJ 05/09/01    Removed imaging based code (RSTIO) and unnecessary global data for 
 *                 update_frame_type and ncc_rev0_ethernet_reset.
 * PMJ 05/25/01    Adjustments from H/W group recommendations to the Chip select settings.
 * PMJ 05/31/01    Updates per suggested settings from H/W group to NVRAM -- Chip select 3.
 * PMJ 06/05/01    Incorporated the table approach to initialization.  See the Settings.c.
 *                 file for the Flash based NetarmInitData table.
 * PMJ 06/12/01    Add a 2 msec delay after setting the PLL register.
 * PMJ 06/14/01    Removed redundant rom_base variable and used ROM_BASE symbol instead.
 * PMJ 06/28/01    Turned on CS0 Valid bit to enable debug Flash Write.
 * NGUR 07/16/01   Set PORTC3 as input if 1284 is not present
 * NGUR 07/16/01   Set PORTA and port PORTB for SPI
 * ngur 07/16/01   use #ifdef NETOS_LED in void led_signal (int times)
 * PMJ 07/19/01    Added a Dynamic RAM Refresh Count adjustment based on NAgetXtalFreq().
 * PMJ 09/06/01    Corrected problems in find_top_of_ram() which failed to correctly size
 *                 RAM on an EDO DPO NIC to 4MBytes.
 * PMJ 10/12/01    Re-incorporated BSP configuration parameters BSP_NVRAM_SIZE and 
 *                 BSP_NVRAM_BASE.
 * PMJ 10/23/01    Extended find_top_of_ram() to detect ram sizes less than 128M.
 * PMJ 10/24/01    Removed line to enable Flash when in the debugger.
 * PMJ 10/26/01    Corrected problem with sensing RAM size in 2nd Chip select bank (i.e.
 *                 seen on EDO development boards).
 * SW  03/04/02    Remove the use of bit field                
 * CHG 04/11/02    Fixed bug in call to NAFastMemoryTest().  The original code tested the
 *                 stack area of memory.  Changed it to start the test at the end of
 *                 the stack.  Original code worked because the call is at the end of
 *                 ncc_init() and the local variables were stored in registers at that
 *                 point, but changes to the code in ncc_init() could cause it to die in
 *                 in the memory test.  
 * LZ  04/22/02    Made changes for GNU tools.
 * DXL 07/26/02    Set burst terminate in PORTA4 for SDRAM hardware reset for NET+20 and NET+50 bga
 *                 PortB5 used to determine if REVD board or new board
 *
 */

#ifndef ncc_init_h

#define ncc_init_h

#include <Npttypes.h>

#ifdef __cplusplus
extern "C"
{
#endif
/*ad*
 * Return values for RAM APIs
 *
 * @external
 * @include 	<ncc_init.h>
 * @category BSP:RAM
 * @since 6.0
 * @name ram_errors     "RAM API Return Values"
 *
 * @param NCC_RAM_DETECTED        RAM has been detected on the indicated chip select
 * @param NCC_NO_RAM              No RAM has been detected on the indicated chip select
*ad*/
#define NCC_RAM_DETECTED        0
#define NCC_NO_RAM              1

/*
 * Error codes used during initialization.
 */
#define NCC_LED_BLINK_DELAY  200000000 
#define NCC_MEMORY_TEST_FAIL 1
#define NCC_NOT_ENOUGH_RAM   2

#ifndef BSP_ARM9
/*
 * Data structure used to store initialization data.
 */
typedef struct 
{  
    BOOLEAN software_reset;
    BOOLEAN debugger;
} romstart_data_t;

extern romstart_data_t *nccPrivateData;

#else

typedef struct 
{  
    BOOLEAN software_reset;
    BOOLEAN debugger;
} romstart_data_t;


extern romstart_data_t *nccPrivateData;


#define NA_NUM_CHIP_SELECTS 4

/*
 * Data structure used to store the mask and base address for each
 * chip select.
 */
typedef struct
{
    unsigned int base;
    unsigned int mask;
} DynamicRam_t;

typedef struct
{
   DynamicRam_t cs[NA_NUM_CHIP_SELECTS];
} DynamicRamTable_t;


#endif

/*
 * The following macro is used to access the initdata section, which
 * is defined in the linker file, the name of the variable is dependent
 * on whether we are using Green Hills or the GNU build envirorment.
 * This linker file directive is from image.ldr (GNU) or image.lx (GHS), this
 * contains the section of memory which is used to store any
 * information which needs to be accessed by your application later,
 * after the memory test.  
 */
#ifdef NETOS_GNU_TOOLS
   	extern char btext[];   			/* begin of Code section, please see linker files */
    extern char gnu_nccdata[];
    extern char gnu_initdata[];
    extern char     data_start[];

    extern char     _endtext[];       /* begin of Code section, see linker files image.ldr */
    extern char     heap_limit[];
    extern char     heap_start[];
#elif defined NETOS_ARM_TOOLS && defined BSP_ARM9
    extern char Image$$initdata$$ZI$$Base[];
    extern char Image$$nccdata$$ZI$$Base[];
    extern char Image$$RAM_EXEC$$Base[];
    extern char Image$$RAM_EXEC$$Base[];
    extern char Image$$netosstack$$ZI$$Base[];
    extern char Image$$netosstack$$ZI$$Base[];
    extern char Image$$HEAP$$ZI$$Base;
    extern char Image$$HEAP$$ZI$$Limit[];
#else
    extern char __ghsbegin_nccdata[];
    extern char __ghsbegin_initdata[];
    extern char __ghsbegin_picbase[];     /* begin of Code section, please see linker files */

    extern char __ghsbegin_pidbase[];       /* begin of Code section, please see linker files */
    extern char __ghsbegin_text[];          /* begin of Code section, please see linker files */
    extern char __ghsbegin_intercall[];     /* begin of Code section, please see linker files */
    extern char __ghsbegin_heap[];          /* begin of Heap section, please see linker files */
    extern char __ghsend_heap[];            /* end of Heap section, please see linker files */
    extern char __ghsend_stack[];       /* begin of ttb section, please see linker files */
    extern char __ghsbegin_secinfo[];       /* begin of secinfo section, please see linker files */
#endif 
extern unsigned long heap_adjustment;

/*
 * Use these macro's to acces the init data section.
 */
#ifdef NETOS_GNU_TOOLS
   #define INIT_DATA_ADDRESS gnu_initdata
#elif NETOS_ARM_TOOLS && defined BSP_ARM9
   #define INIT_DATA_ADDRESS Image$$initdata$$ZI$$Base
#else    
   #define INIT_DATA_ADDRESS __ghsbegin_initdata
#endif

#ifdef NETOS_GNU_TOOLS
    extern char gnu_ncc_initdata[];
#elif NETOS_ARM_TOOLS && defined BSP_ARM9
    extern char Image$$ncc_initdata$$ZI$$Base[];
#else
    extern char __ghsbegin_ncc_initdata[];
#endif 


/*
 * This is the stack size used for nccInit() this must
 * equal the supervisor stack size TMP_SVC_STACK_SIZE
 * defined in the file init.s
 */
#define NCC_INIT_STACK_SIZE 0x500

/*
 * Use these macro's to acces the init data section.
 */
#ifdef NETOS_GNU_TOOLS
   #define NCC_INIT_DATA_ADDRESS gnu_ncc_initdata
#elif defined NETOS_ARM_TOOLS && defined BSP_ARM9
   #define NCC_INIT_DATA_ADDRESS Image$$ncc_initdata$$ZI$$Base 
#else    
   #define NCC_INIT_DATA_ADDRESS __ghsbegin_ncc_initdata
#endif

#ifdef BSP_ARM9

#ifdef NETOS_GNU_TOOLS
   extern char gnu_sleep_data[];
   #define NA_SLEEP_DATA_ADDRESS gnu_sleep_data
#elif defined NETOS_ARM_TOOLS && defined BSP_ARM9
   extern char Image$$sleep_data$$ZI$$Base[];
   #define NA_SLEEP_DATA_ADDRESS Image$$sleep_data$$ZI$$Base
#else    
   extern char __ghsbegin_sleep_data[];
   #define NA_SLEEP_DATA_ADDRESS __ghsbegin_sleep_data
#endif

#endif  /* BSP_ARM9 */

/*
 * Functions used to send out printf's during startup, before the
 * OS is loaded.
 */
extern void  bsp_printf(char *outString);    
extern int   mprintf(const char *f, ...);
extern void  setupSimpleSerial(void);

extern int customizeMemoryTest(unsigned long *start, unsigned long ramSize); 

#if defined NETOS_MEMORY_TEST
   void nccRunMemoryTest(unsigned long *start, unsigned long *end, int iterations);
   int NS9XXXRamTest(unsigned long *start, unsigned long *end);
#endif


/*
 *
 *  Function: int nccChipType(void)
 *
 *  Description:
 *
 *      Determine the chip type by look at the chip revision code in the
 *      System Status Register in the GEN module.  Each chip revision is
 *      allocated 4 revision codes.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      -1               cannot identify chip type
 *      NETA15
 *      NETA40
 *      NETA50
 *      NETA20M
 *      NETA20UM
 *
 */
int nccChipType(void);

unsigned short nccRomImageBuild(void);


/*
 *
 *  Function: int nccChipType(void)
 *
 *  Description:
 *     This routine is called by the BSP before the C library is loaded to
 *     indicate that a fatal error has occured.
 *     
 *
 *  Parameters:
 *      NCC_NOT_ENOUGH_RAM
 *      NCC_MEMORY_TEST_FAIL
 *
 *  Return Values:
 *
 *      none
 *
 */
void nccInitializationFailed(int reason);



/*
 *
 *  Function: WORD32 nccDetermineRamSize(WORD32 *csarAddress, WORD32 *csorAddress, WORD32 baseAddress, WORD32 maxSize)
 *
 *  Description:
 *
 *      This routine determines how much RAM is attached to a chip select and sets the
 *      address mask accordingly.  This is done by setting the mask to the maximum supported
 *      size and incrementally testing RAM until we hit a word that causes the word at the 
 *      base to be changed.  At that point, we know that we have hit the end of the RAM
 *      part.
 *
 *  Parameters:
 *
 *      csarAddress     Address Register for the CS
 *      csorAddress     Option Register for the CS
 *      baseAddress     start of CS's memory
 *      maxSize         maximum possible size for the chip select
 *
 *  Return Values:
 *
 *      size of RAM attached to the chip select
 *
 */
#ifndef BSP_ARM9
WORD32 nccDetermineRamSize(WORD32 volatile *csarAddress, WORD32 volatile *csorAddress, WORD32 baseAddress, WORD32 maxSize);
#else
WORD32 nccDetermineRamSize(WORD32 baseAddress, WORD32 maxSize, WORD32 csBaseRegAddr, 
                           WORD32 csMaskRegAddr);
#endif



/*
 *
 *  Function: nccCopyCSSetup (WORD32 *csarDest, WORD32 *csorDest, WORD32 *csarSrc, WORD32 *csorSrc, WORD32 baseAddress)
 *
 *  Description:
 *
 *      This routine copies the settings from one chip select to another.  The base
 *      address of the destination chip select is set to the value indicated by the
 *      parameter base.  If SDRAM is being setup, then the setup is done in two steps
 *      to make sure the SDRAM mode register is setup correctly.
 *
 *      The reason why you will want to use this function to copy CS settings rather
 *      than nccDetermineRamType() is that the memory controller can only support one
 *      type of RAM at a time.  So, once it is setup for memory on one chip select, 
 *      you should not run nccDetermineRamType() again as it will cycle through the
 *      possible RAM types when it tries to determine what type of RAM is attached.
 *      This means that you can only support one type of RAM at a time.  See the
 *      description of the DMODE field of the CSBAR register in the H/W Reference
 *      manual for more information.
 *
 *  Parameters:
 *
 *      csarDest    pointer to destination CSBAR register
 *      csorDest    pointer to destination CSOR register
 *      csarSrc     pointer to destination CSBAR register
 *      csorSrc     pointer to destination CSOR register
 *      baseAddress base address for memory attached to chip select
 *
 *  Return Values:
 *
 *      NCC_RAM_DETECTED        RAM has been detected and the chip select setup to support it
 *      NCC_NO_RAM              No RAM was detected.  The chip select has been disabled.
 *
 */

int nccCopyCSSetup (WORD32 volatile *csarDest, WORD32 volatile *csorDest, WORD32 volatile *csarSrc, WORD32 volatile *csorSrc, WORD32 baseAddress);





/*
 *
 *  Function: int nccDetermineRamType(WORD32 *csarAddress, WORD32 *csorAddress, WORD32 baseAddress, WORD32 size)
 *
 *  Description:
 *
 *      This routine deterimines the type of RAM attached to a chip select.  It does 
 *      this by configuring the chip select for various RAM types and testing to see
 *      which one works.  The following RAM types are supported:  32-bit wide SDRAM,
 *      16-bit wide SDRAM, 32-bit wide Fast Page RAM, 16-bit wide Fast Page RAM, 
 *      32-bit wide EDO RAM, and 16-bit wide EDO RAM.
 *
 *      There are known bugs in the NET+15/40 and NET+20/50 memory controllers that we 
 *      have to work around. The NET+15/40 does not support EDO DRAM mode.  We can
 *      support EDO RAM by setting up the memory controller for fast page RAM.
 *      On the NET+20/50, we use the value of the cs1EdoMode field in NetarmInitData 
 *      to determine if EDO or FP RAM is attached.  In all cases, we use values in
 *      NetarmInitData in Settings.c to determine how to configure the CS for the 
 *      RAM part.
 *
 *      There is an additional concern which is not a bug.  There is no way 
 *      to tell the difference between EDO RAM and Fast Page RAM.  However, if we
 *      set up the memory controller for FP RAM, but really have EDO RAM, it will
 *      work for a while and then fail.  So, if NetarmInitData is setup to indicate
 *      that we have EDO RAM, we will NOT look for FP RAM.
 *
 *      The chip select is configured to support each type of memory and then
 *      a simple memory test is run.  We know we have found the RAM type when we find 
 *      a configuration that passes the memory test.
 *
 *      The chip select is left configured to support the RAM when this function exits.
 *      If no RAM is found, then the chip select is left disabled.
 *
 *  Note:
 *
 *      Do not use this function once a chip select has been configured to support 
 *      dynamic RAM.  Once the RAM type has been determined on one chip select, use
 *      the nccCopyCSSetup() function to copy settings from one chip select to 
 *      another.  The reason for this is that the memory controller can only support
 *      one type of dynamic RAM at a time.  This function cycles through the 
 *      different memory types until it finds one that works.  So calling this
 *      function after dynamic memory has been setup on a chip select may have
 *      unpredictable results.  See the description of the DMODE field of the CSBAR
 *      register in the H/W Reference Manual.
 *
 *  Parameters:
 *
 *      csarAddress     address of chip select address register
 *      csorAddress     address of chip select option register
 *      baseAddress    address to locate memory at.
 *      size            amount of RAM to configure the chip select for
 *
 *  Return Values:
 *
 *      NCC_RAM_DETECTED        RAM has been detected and the chip select setup to support it
 *      NCC_NO_RAM              No RAM was detected.  The chip select has been disabled.
 *
 */

int nccDetermineRamType(WORD32 volatile *csarAddress, WORD32 volatile *csorAddress, WORD32 baseAddress, WORD32 size);






/*  Function: void ncc_init (WORD32 *svc_stk_addr, WORD32 svc_stk_size, WORD32 undefR14)
 *
 *  Description:
 *      Called before main(), to:
 *       o initialize all the internal NCC hardware registers,
 *       o setup Port A,B,C,
 *       o determine the amount of RAM and configure CS1 and CS2 accordingly,
 *       o CS3 is programed to support NVRAM,
 *       o RAM is tested.
 *
 *  Parameters:
 *  
 *      *svc_stk_addr   - starting location of supervisor stack
 *       svc_stk_size   - size of supervisor stack frame
 *      undefR14        - value of R14 for undefined mode.  Use to indicate software restart
 * 
 *
 * Return Values:
 *     The address of the top of ram.
 */

WORD32 ncc_init (WORD32 *svc_stk_addr, WORD32 svc_stk_size, WORD32 undefR14);
  
#ifdef BSP_ARM9
    void nccSetCSDefault(WORD32 dynCS, WORD32 baseAddress, WORD32 maxSize);
	void nccSetCSDisable(WORD32 dynCS);
	void nccCopyDynCfgReg(unsigned long volatile *toReg, unsigned long volatile *fromReg);
    int nccCheckIfRamExists(WORD32 baseAddress);
    int nccCheckForSoftwareRestart(void);
#endif

    int are_we_in_debugger(void);

/* extern functions from ncc_init.c */
extern int NAFastMemoryTest(WORD32 from,  WORD32 to);
extern int checkAppUseNvram(void);
extern void NARamSetupAbortHandler(void);

extern void NAWaitDisableSleep(void);

#ifdef BSP_ARM9
extern BOOLEAN NAPDIsSleepWakeup(void);
#else
#define NAPDIsSleepWakeup()   FALSE
#endif

#ifdef __cplusplus
}
#endif

#endif







