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