1/* Initializes CPU and basic hardware such as memory 2 * controllers, IRQ controller and system timer 0. 3 * 4 * (C) Copyright 2007 5 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 * 25 */ 26 27#include <common.h> 28#include <asm/asi.h> 29#include <asm/leon.h> 30 31#include <config.h> 32 33DECLARE_GLOBAL_DATA_PTR; 34 35/* reset CPU (jump to 0, without reset) */ 36void start(void); 37 38struct { 39 gd_t gd_area; 40 bd_t bd; 41} global_data; 42 43/* 44 * Breath some life into the CPU... 45 * 46 * Set up the memory map, 47 * initialize a bunch of registers. 48 * 49 * Run from FLASH/PROM: 50 * - until memory controller is set up, only registers available 51 * - no global variables available for writing 52 * - constants available 53 */ 54 55void cpu_init_f(void) 56{ 57 LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; 58 59 /* initialize the IRQMP */ 60 leon2->Interrupt_Force = 0; 61 leon2->Interrupt_Pending = 0; 62 leon2->Interrupt_Clear = 0xfffe; /* clear all old pending interrupts */ 63 leon2->Interrupt_Mask = 0xfffe0000; /* mask all IRQs */ 64 65 /* cache */ 66 67 /* I/O port setup */ 68#ifdef LEON2_IO_PORT_DIR 69 leon2->PIO_Direction = LEON2_IO_PORT_DIR; 70#endif 71#ifdef LEON2_IO_PORT_DATA 72 leon2->PIO_Data = LEON2_IO_PORT_DATA; 73#endif 74#ifdef LEON2_IO_PORT_INT 75 leon2->PIO_Interrupt = LEON2_IO_PORT_INT; 76#else 77 leon2->PIO_Interrupt = 0; 78#endif 79} 80 81void cpu_init_f2(void) 82{ 83 84} 85 86/* 87 * initialize higher level parts of CPU like time base and timers 88 */ 89int cpu_init_r(void) 90{ 91 LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; 92 93 /* initialize prescaler common to all timers to 1MHz */ 94 leon2->Scaler_Counter = leon2->Scaler_Reload = 95 (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; 96 97 return (0); 98} 99 100/* Uses Timer 0 to get accurate 101 * pauses. Max 2 raised to 32 ticks 102 * 103 */ 104void cpu_wait_ticks(unsigned long ticks) 105{ 106 unsigned long start = get_timer(0); 107 while (get_timer(start) < ticks) ; 108} 109 110/* initiate and setup timer0 interrupt to 1MHz 111 * Return irq number for timer int or a negative number for 112 * dealing with self 113 */ 114int timer_interrupt_init_cpu(void) 115{ 116 LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; 117 118 /* 1ms ticks */ 119 leon2->Timer_Counter_1 = 0; 120 leon2->Timer_Reload_1 = 999; /* (((1000000 / 100) - 1)) */ 121 leon2->Timer_Control_1 = 122 (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD); 123 124 return LEON2_TIMER1_IRQNO; 125} 126 127/* 128 * This function is intended for SHORT delays only. 129 */ 130unsigned long cpu_usec2ticks(unsigned long usec) 131{ 132 /* timer set to 1kHz ==> 1 clk tick = 1 msec */ 133 if (usec < 1000) 134 return 1; 135 return (usec / 1000); 136} 137 138unsigned long cpu_ticks2usec(unsigned long ticks) 139{ 140 /* 1tick = 1usec */ 141 return ticks * 1000; 142} 143