#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 Free Software Foundation, Inc.
// Copyright (C) 2003, 2004, 2005, 2006 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:         2005-07-29
// Purpose:      Atmel SAM9261-EK 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_sam9.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/sam9261ek.h>               // Platform specific hardware definitions
#include <cyg/hal/sam9_init.inc>             // SAM9 common init helper macros

//===========================================================================*/
// User LED display

        .macro  ldrc reg,val
#ifdef __thumb__
        ldr     \reg,=\val
#else
        mov     \reg,#\val
#endif
        .endm

        .macro _led y
        ldr     r0,=SAM9_PIOA
        ldrc    r1,0x240
        str     r1,[r0,#_PIO_SODR]
        ldrc    r1,((\y&1)<<6)|((\y&2)<<8)
        str     r1,[r0,#_PIO_CODR]

#if 1
        ldr     r0,=2000000
1:      sub     r0,r0,#1
        cmp     r0,#0
        bne     1b
#endif        
        .endm
        
#define CYGHWR_LED_MACRO _led \x

//================================================================================
// This macro implements the initial startup code for the platform. Mostly it
// consists of calls on macros defined in the generic SAM9 HAL.        

        .macro  _platform_setup1


//1:
//        b       1b
        
//--------------------------------------------------------------------------------
// Set up the CPU

        sam9_init_cpu

//--------------------------------------------------------------------------------
// Get the clocks running
//
// The AT91Bootstrap loader will have set the clocks up to the default
// speed, but we reinitialize here in case we want to run at a different 
// speed.

        // Enable PLLA at 198Mhz (really 198.656MHz) for PCK
        // 198MHz ~= 18.432MHz Main/9 x 97
        // DIVA         = 9
        // PLLACOUNT    = 63
        // OUTA         = 2 == 150..240MHz
        // MULA         = 96 == multiplier-1

        // Enable PLLB at 96MHz for USB (really 96.110MHz)
        // USB really wants 48MHz, so we set the USB_96M bit
        // resulting in a USB clock of 48.055MHz
        // 96MHz ~= 18.432MHz Main/14 x 73
        // DIVB          = 14
        // PLLBCOUNT     = 62
        // OUTB          = 0 == 80..160MHz
        // MULB          = 72 == multiplier-1
        
#define PLLA_VAL 0x2060BF09
#define PLLB_VAL 0x10483F0E

        sam9_init_clocks PLLA_VAL,PLLB_VAL
                           
//--------------------------------------------------------------------------------            
// GPIO Initialization
//
// Some setup has been done by AT91Bootstrap, this completes the process.
        
                           
        // Port C
        sam9_pio_set_port       SAM9_PIOC
        sam9_pio_set_perA       0xFFFF0000      // PC16-31:     D16-31
        sam9_pio_set_output     0x0000C000      // PC14-15:     NAND flash CE/RB
        sam9_pio_set_perB       0x00000003      // PC0-1:       NAND flash OE/WE              
        sam9_pio_set_output     0x00000400      // PC10:        DM9000 reset
        sam9_pio_set_interrupt  0x00000800      // PC11:        DM9000 interrupt
                
        // Port A
        sam9_pio_set_port       SAM9_PIOA
        sam9_pio_set_perA       0x0000003F      // PA0-6:       SPI0
        sam9_pio_set_perA       0x00000600      // PA9-10:      DEBUG port
        sam9_pio_set_output     0x00806000      // PA13-14,23:  LEDs 2 green + 1 yellow power
        sam9_pio_set_input      0x0F000000      // PA24-27:     Push buttons

        // Port B
        sam9_pio_set_port       SAM9_PIOB
        // Port B is mostly the LCD controller which we don't currently use.
                        
        _led 3
        _led 0
      
//--------------------------------------------------------------------------------                    
// Set up memory controllers for DM9000 ethernet MAC.
//
// These values come from those used for Linux.                

        // Set up CS2 on Matrix
        ldr     r0,=SAM9_MATRIX
        ldr     r1,=(AT91_MATRIX_SCFG_DEFMSTR_TYPE_FIXED_DEFMSTR| AT91_MATRIX_SCFG_FIXED_DEFMSTR_ARM926D)
        ldr     r2,[r0]
        orr     r2,r2,r1
        str     r2,[r0]

        // Set up CS2 on SMC
        ldr     r0,=(SAM9_SMC+AT91_SMC_CS2)
        ldr     r1,=0x00020002
        str     r1,[r0,#AT91_SMC_SETUP]
        ldr     r1,=0x08040804
        str     r1,[r0,#AT91_SMC_PULSE]
        ldr     r1,=0x00100010
        str     r1,[r0,#AT91_SMC_CYCLE]
        ldr     r1,=0x00011103
        str     r1,[r0,#AT91_SMC_MODE]

//--------------------------------------------------------------------------------                    
// SDRAM Initialization
//

#ifndef CYG_HAL_STARTUP_RAM

#define SDRAM_CR (AT91_SDRAMC_CR_NC_9 | AT91_SDRAMC_CR_NR_13 | AT91_SDRAMC_CR_CAS_2 |          \
                  AT91_SDRAMC_CR_NB_4_BANKS | AT91_SDRAMC_CR_DBW_32 | AT91_SDRAMC_CR_TWR(2) |  \
                  AT91_SDRAMC_CR_TRC(7) | AT91_SDRAMC_CR_TRP(2) | AT91_SDRAMC_CR_TRCD(2) |     \
                  AT91_SDRAMC_CR_TRAS(5) | AT91_SDRAMC_CR_TXSR(8))

#define SDRAM_REFRESH ((CYGARC_HAL_ARM_ARM9_SAM9_MCK*7)/1000000)

#define SDRAM_MODE ((2<<4)<<2)  // CL=2, Sequential burst, length=1

        sam9_init_sdram SDRAM_CR, SAM9261EK_SDRAM_PHYS_BASE, SDRAM_REFRESH, SDRAM_MODE
#endif
        
        _led 1        
//--------------------------------------------------------------------------------
// 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 virtual base of the
// ROM, in order to find where we are to be copying from.
//        
// At present the initial image is loaded from Dataflash into SRAM, so there is
// no need to support ROMRAM startup. However, we still need to supply the 
// following parameters for the sam9_init_mmu macro.

#define IMAGE_BASE_MASK      0xFF01FFFF   // Bits to ignore
#define ROM_IMAGE_VIRT_BASE  0x60000000   // Virtual Base of Flash

        // This will cause hal_mmu_init to be called
        sam9_init_mmu IMAGE_BASE_MASK, ROM_IMAGE_VIRT_BASE, SAM9261EK_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
