uboot/board/armltd/integratorcp/integratorcp.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   4 * Marius Groeger <mgroeger@sysgo.de>
   5 *
   6 * (C) Copyright 2002
   7 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
   8 *
   9 * (C) Copyright 2003
  10 * Texas Instruments, <www.ti.com>
  11 * Kshitij Gupta <Kshitij@ti.com>
  12 *
  13 * (C) Copyright 2004
  14 * ARM Ltd.
  15 * Philippe Robin, <philippe.robin@arm.com>
  16 *
  17 * See file CREDITS for list of people who contributed to this
  18 * project.
  19 *
  20 * This program is free software; you can redistribute it and/or
  21 * modify it under the terms of the GNU General Public License as
  22 * published by the Free Software Foundation; either version 2 of
  23 * the License, or (at your option) any later version.
  24 *
  25 * This program is distributed in the hope that it will be useful,
  26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28 * GNU General Public License for more details.
  29 *
  30 * You should have received a copy of the GNU General Public License
  31 * along with this program; if not, write to the Free Software
  32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  33 * MA 02111-1307 USA
  34 */
  35
  36#include <common.h>
  37#include <div64.h>
  38
  39DECLARE_GLOBAL_DATA_PTR;
  40
  41void flash__init (void);
  42void ether__init (void);
  43void peripheral_power_enable (void);
  44
  45#if defined(CONFIG_SHOW_BOOT_PROGRESS)
  46void show_boot_progress(int progress)
  47{
  48        printf("Boot reached stage %d\n", progress);
  49}
  50#endif
  51
  52#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
  53
  54/*
  55 * Miscellaneous platform dependent initialisations
  56 */
  57
  58int board_init (void)
  59{
  60        /* arch number of Integrator Board */
  61        gd->bd->bi_arch_number = MACH_TYPE_CINTEGRATOR;
  62
  63        /* adress of boot parameters */
  64        gd->bd->bi_boot_params = 0x00000100;
  65
  66        gd->flags = 0;
  67
  68#ifdef CONFIG_CM_REMAP
  69extern void cm_remap(void);
  70        cm_remap();     /* remaps writeable memory to 0x00000000 */
  71#endif
  72
  73        icache_enable ();
  74
  75        flash__init ();
  76        ether__init ();
  77        return 0;
  78}
  79
  80
  81int misc_init_r (void)
  82{
  83        setenv("verify", "n");
  84        return (0);
  85}
  86
  87/******************************
  88 Routine:
  89 Description:
  90******************************/
  91void flash__init (void)
  92{
  93}
  94/*************************************************************
  95 Routine:ether__init
  96 Description: take the Ethernet controller out of reset and wait
  97              for the EEPROM load to complete.
  98*************************************************************/
  99void ether__init (void)
 100{
 101}
 102
 103/******************************
 104 Routine:
 105 Description:
 106******************************/
 107int dram_init (void)
 108{
 109        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 110        gd->bd->bi_dram[0].size  = PHYS_SDRAM_1_SIZE;
 111
 112#ifdef CONFIG_CM_SPD_DETECT
 113    {
 114extern void dram_query(void);
 115        unsigned long cm_reg_sdram;
 116        unsigned long sdram_shift;
 117
 118        dram_query();   /* Assembler accesses to CM registers */
 119                        /* Queries the SPD values             */
 120
 121        /* Obtain the SDRAM size from the CM SDRAM register */
 122
 123        cm_reg_sdram = *(volatile ulong *)(CM_BASE + OS_SDRAM);
 124        /*   Register         SDRAM size
 125         *
 126         *   0xXXXXXXbbb000bb    16 MB
 127         *   0xXXXXXXbbb001bb    32 MB
 128         *   0xXXXXXXbbb010bb    64 MB
 129         *   0xXXXXXXbbb011bb   128 MB
 130         *   0xXXXXXXbbb100bb   256 MB
 131         *
 132         */
 133        sdram_shift              = ((cm_reg_sdram & 0x0000001C)/4)%4;
 134        gd->bd->bi_dram[0].size  = 0x01000000 << sdram_shift;
 135
 136    }
 137#endif /* CM_SPD_DETECT */
 138
 139        return 0;
 140}
 141
 142/* The Integrator/CP timer1 is clocked at 1MHz
 143 * can be divided by 16 or 256
 144 * and can be set up as a 32-bit timer
 145 */
 146/* U-Boot expects a 32 bit timer, running at CONFIG_SYS_HZ */
 147/* Keep total timer count to avoid losing decrements < div_timer */
 148static unsigned long long total_count = 0;
 149static unsigned long long lastdec;       /* Timer reading at last call     */
 150static unsigned long long div_clock = 1; /* Divisor applied to timer clock */
 151static unsigned long long div_timer = 1; /* Divisor to convert timer reading
 152                                          * change to U-Boot ticks
 153                                          */
 154/* CONFIG_SYS_HZ = CONFIG_SYS_HZ_CLOCK/(div_clock * div_timer) */
 155static ulong timestamp;         /* U-Boot ticks since startup         */
 156
 157#define TIMER_LOAD_VAL ((ulong)0xFFFFFFFF)
 158#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+4))
 159
 160/* all function return values in U-Boot ticks i.e. (1/CONFIG_SYS_HZ) sec
 161 *  - unless otherwise stated
 162 */
 163
 164/* starts up a counter
 165 * - the Integrator/CP timer can be set up to issue an interrupt */
 166int interrupt_init (void)
 167{
 168        /* Load timer with initial value */
 169        *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL;
 170        /* Set timer to be
 171         *      enabled           1
 172         *      periodic          1
 173         *      no interrupts     0
 174         *      X                 0
 175         *      divider 1        00 == less rounding error
 176         *      32 bit            1
 177         *      wrapping          0
 178         */
 179        *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = 0x000000C2;
 180        /* init the timestamp */
 181        total_count = 0ULL;
 182        reset_timer_masked();
 183
 184        div_timer  = (unsigned long long)(CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ);
 185        div_timer /= div_clock;
 186
 187        return (0);
 188}
 189
 190/*
 191 * timer without interrupts
 192 */
 193void reset_timer (void)
 194{
 195        reset_timer_masked ();
 196}
 197
 198ulong get_timer (ulong base_ticks)
 199{
 200        return get_timer_masked () - base_ticks;
 201}
 202
 203void set_timer (ulong ticks)
 204{
 205        timestamp   = ticks;
 206        total_count = (unsigned long long)ticks * div_timer;
 207}
 208
 209/* delay usec useconds */
 210void udelay (unsigned long usec)
 211{
 212        ulong tmo, tmp;
 213
 214        /* Convert to U-Boot ticks */
 215        tmo  = usec * CONFIG_SYS_HZ;
 216        tmo /= (1000000L);
 217
 218        tmp  = get_timer_masked();      /* get current timestamp */
 219        tmo += tmp;                     /* form target timestamp */
 220
 221        while (get_timer_masked () < tmo) {/* loop till event */
 222                /*NOP*/;
 223        }
 224}
 225
 226void reset_timer_masked (void)
 227{
 228        /* capure current decrementer value    */
 229        lastdec   = (unsigned long long)READ_TIMER;
 230        /* start "advancing" time stamp from 0 */
 231        timestamp = 0L;
 232}
 233
 234/* converts the timer reading to U-Boot ticks          */
 235/* the timestamp is the number of ticks since reset    */
 236ulong get_timer_masked (void)
 237{
 238        /* get current count */
 239        unsigned long long now = (unsigned long long)READ_TIMER;
 240
 241        if(now > lastdec) {
 242                /* Must have wrapped */
 243                total_count += lastdec + TIMER_LOAD_VAL + 1 - now;
 244        } else {
 245                total_count += lastdec - now;
 246        }
 247        lastdec   = now;
 248
 249        /* Reuse "now" */
 250        now = total_count;
 251        do_div(now, div_timer);
 252        timestamp = now;
 253
 254        return timestamp;
 255}
 256
 257/* waits specified delay value and resets timestamp */
 258void udelay_masked (unsigned long usec)
 259{
 260        udelay(usec);
 261}
 262
 263/*
 264 * This function is derived from PowerPC code (read timebase as long long).
 265 * On ARM it just returns the timer value.
 266 */
 267unsigned long long get_ticks(void)
 268{
 269        return (unsigned long long)get_timer(0);
 270}
 271
 272/*
 273 * Return the timebase clock frequency
 274 * i.e. how often the timer decrements
 275 */
 276ulong get_tbclk (void)
 277{
 278        return (ulong)(((unsigned long long)CONFIG_SYS_HZ_CLOCK)/div_clock);
 279}
 280