#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
#define CYGONCE_HAL_PLATFORM_SETUP_H
/*=============================================================================
//
//      hal_platform_setup.h
//
//      Platform specific support for HAL (assembly code)
//
//=============================================================================
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
// -------------------------------------------                              
// This file is part of eCos, the Embedded Configurable Operating System.   
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 eCosCentric Limited     
//
// eCos is free software; you can redistribute it and/or modify it under    
// the terms of the GNU General Public License as published by the Free     
// Software Foundation; either version 2 or (at your option) any later      
// version.                                                                 
//
// eCos is distributed in the hope that it will be useful, but WITHOUT      
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
// for more details.                                                        
//
// You should have received a copy of the GNU General Public License        
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
//
// As a special exception, if other files instantiate templates or use      
// macros or inline functions from this file, or you compile this file      
// and link it with other works to produce a work based on this file,       
// this file does not by itself cause the resulting work to be covered by   
// the GNU General Public License. However the source code for this file    
// must still be made available in accordance with section (3) of the GNU   
// General Public License v2.                                               
//
// This exception does not invalidate any other reasons why a work based    
// on this file might be covered by the GNU General Public License.         
// -------------------------------------------                              
// ####ECOSGPLCOPYRIGHTEND####                                              
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    eCosCentric
// Contributors: 
// Date:         2004-12-08
// Purpose:      KwikByte KB9200 platform specific support routines
// Description: 
// Usage:        #include <cyg/hal/hal_platform_setup.h>
//               Only used by "vectors.S"         
//
//####DESCRIPTIONEND####
//
//===========================================================================*/

#include <pkgconf/system.h>             // System-wide configuration info
#include <pkgconf/hal_arm.h>
#include <pkgconf/hal_arm_arm9.h>
#include <pkgconf/hal_arm_arm9_at91rm9200.h>

#include CYGBLD_HAL_VARIANT_H           // Variant specific configuration
#include CYGBLD_HAL_PLATFORM_H          // Platform specific configuration
#include <cyg/hal/hal_mmu.h>            // MMU definitions
#include <cyg/hal/kb9200.h>             // Platform specific hardware definitions
#include <cyg/hal/at91rm9200_init.inc>  // AT91RM9200 common init helper macros

//===========================================================================*/

// This macro represents the initial startup code for the platform.
// Much of it has been adapted from the "hw_init2.c" code provided
// with the micro-monitor for the CSB337 but has now been substantially 
// modified.
        

        .macro  _platform_setup1

//--------------------------------------------------------------------------------
// Set up the CPU
        
        at91rm9200_init_cpu

//--------------------------------------------------------------------------------
        // Set CS0 for access to flash
        // 7 wait states, 8-bits, 1 setup, 0 hold, 1 float
        // NB this should be 9 wait states, 8-bits, 1 setup, 1 hold, 1 float on the KB9202,
        // but since this is commented out, there's no point catering for that.
        // This needs to be set now before the clocks, otherwise we may be running too fast
        // for the Flash

        ldr     r1,=_EBI_SMC2_CSR0
        ldr     r2,=0x01004187            
        str     r2,[r1]

//--------------------------------------------------------------------------------
// Get the clock running

        // Enable PLLA for 180Mhz
        // 10MHz Main/5 x 90
        // DIVA         = 5
        // PLLACOUNT    = 127
        // OUTA         = 2 == 150..240MHz
        // MULA         = 89 == multiplier-1

        // Enable PLLB at 96MHz for USB
        // USB really wants 48MHz, so we set the USB_96M bit
        // resulting in a USB clock of 48MHz
        // 96MHz == 10MHz Main/5 * 48
        // DIVB          = 5
        // PLLBCOUNT     = 127
        // OUTB          = 0 == 80..160MHz
        // MULB          = 47 == multiplier-1
#define PLLA_VAL 0x2059BF05
#define PLLB_VAL 0x102F7F05
        
        at91rm9200_init_clocks PLLA_VAL,PLLB_VAL

#if !defined(CYG_HAL_STARTUP_SRAM)                    

        // Set PCK0 to PLLA/4 - 45Mhz

        ldr     r1,=_PMC_PCKR0
        ldr     r2,=(_PMC_MCKR_CSS_PLLA_CLK|_PMC_MCKR_PRES_CLK_4)
        str     r2,[r1]

#endif // !defined(CYG_HAL_STARTUP_SRAM)        

//--------------------------------------------------------------------------------            
// GPIO Initialization
// Initialize the GPIO - just the basics for now

        // Port C
        // enable d16-31 on portc to be alternate function a (databus)
        // also ensures PC6 enabled as a GPIO line, not as its peripheral A function
        // as NWAIT input to the SMC.

        ldr     r1,=AT91RM9200_PIOC
#if defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202)  || \
    defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202B) || \
    defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202C)
        // KB9202 needs A23 to be routed to flash, not GPIO
        // KB9202 LCD is on PC23
        // KB9202 LEDs are on PC18/19/20
        // 
        // These are probably safe for KB9200/KB9201 too, but I don't have
        // the KB9201 schematics to confirm, so will leave it ifdeffed.
        ldr     r2,=0xFF630080
#else
        ldr     r2,=0xFFFF0000
#endif
        str     r2,[r1,#_PIO_ASR]
        str     r2,[r1,#_PIO_PDR]
        mvn     r2,r2
        str     r2,[r1,#_PIO_PER]

        ldr     r2,=0xFFFFFFFF          // all gpio = input (except on kb9202 see below)
        str     r2,[r1,#_PIO_ODR]
#if defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202)  || \
    defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202B) || \
    defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202C)
        // kb9202 LCD backlight is on PC23 and is an output
        // LEDs are on PC18/19/20 and are outputs
        ldr     r2,=0x009c0000
        str     r2,[r1,#_PIO_OER]
        // Drive PC23 low (backlight off) and PC18/19/20 high (LEDs all off)
        ldr     r2,=0x00800000
        str     r2,[r1,#_PIO_CODR]
        ldr     r2,=0x001c0000
        str     r2,[r1,#_PIO_SODR]
#endif

        // Port A
//      // enable ethernet and DTXD/DRXD
//      // ethernet = PA16-7, DTXD = PA31

        ldr     r1,=AT91RM9200_PIOA
        ldr     r2,=0xC007FF80
        str     r2,[r1,#_PIO_ASR]
        str     r2,[r1,#_PIO_PDR]

        // Port B
        // PB27 = peripheral, PB19-12 = Ethernet, all else = GPIO
            
        ldr     r1,=AT91RM9200_PIOB
        ldr     r2,=0x0fDFF000
        str     r2,[r1,#_PIO_PDR]
        mvn     r2,r2
        str     r2,[r1,#_PIO_PER]

        ldr     r2,=0x08000000          // Function A, PB27 = PCK0
        str     r2,[r1,#_PIO_ASR]
        ldr     r2,=0x000FF000          // Function B, PB19-12 = Ethernet
        str     r2,[r1,#_PIO_BSR]

        ldr     r2,=0x00000007          // PIO_OER: all GPIO = input, except PB0-2
        str     r2,[r1,#_PIO_OER]
        str     r2,[r1,#_PIO_SODR]      // PIO_SODR: first drive PB0-2 high
        ldr     r2,=0x00000004
        str     r2,[r1,#_PIO_CODR]      // PIO_CODR: then drive PB0 low


//--------------------------------------------------------------------------------                    
// SDRAM Initialization
        
#if !defined(CYG_HAL_STARTUP_SRAM)                    

        // SDRAM configuration registers. Values derived from KwikByte software.
#if defined(CYGHWR_HAL_ARM_ARM9_KB920x_BOARD_VARIANT_KB9202C)
#define SDRAM_CR 0x3211295a
#define SDRAM_REFRESH 0x1A4
#define AT91RM9200_SDRAM_16_BITS
#else
#define SDRAM_CR 0x32112959
#define SDRAM_REFRESH 0x1A4
#endif
            
        at91rm9200_init_sdram SDRAM_CR, KB9200_SDRAM_PHYS_BASE, SDRAM_REFRESH

#endif // !defined(CYG_HAL_STARTUP_SRAM)        

//--------------------------------------------------------------------------------
// Handle ROM->RAM copy in ROMRAM startups and initialize the MMU

// To handle ROMRAM placement, we mask our current PC to find the base of the
// image (we know we're near the start), and OR in the physical base of the
// ROM, in order to find where we are to be copying from.

#define IMAGE_BASE_MASK      0xFF01FFFF   // Bits to ignore
#define ROM_IMAGE_PHYS_BASE  0x60000000   // Phys Base of Flash

        // This will cause hal_mmu_init to be called
        at91rm9200_init_mmu IMAGE_BASE_MASK, ROM_IMAGE_PHYS_BASE, KB9200_SDRAM_PHYS_BASE

        .endm

//--------------------------------------------------------------------------------
                
#define PLATFORM_SETUP1 _platform_setup1
#define CYGSEM_HAL_ROM_RESET_USES_JUMP

#endif // CYGONCE_HAL_PLATFORM_SETUP_H
//-----------------------------------------------------------------------------
// end of hal_platform_setup.h
