uboot/arch/sparc/cpu/leon2/cpu_init.c
<<
>>
Prefs
   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