1/* 2 * (C) Copyright 2002 3 * Lineo, Inc. <www.lineo.com> 4 * Bernhard Kuhn <bkuhn@lineo.com> 5 * 6 * (C) Copyright 2002 7 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 8 * Marius Groeger <mgroeger@sysgo.de> 9 * 10 * (C) Copyright 2002 11 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 12 * Alex Zuepke <azu@sysgo.de> 13 * 14 * See file CREDITS for list of people who contributed to this 15 * project. 16 * 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License as 19 * published by the Free Software Foundation; either version 2 of 20 * the License, or (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 30 * MA 02111-1307 USA 31 */ 32 33#include <common.h> 34/*#include <asm/io.h>*/ 35#include <asm/arch/hardware.h> 36/*#include <asm/proc/ptrace.h>*/ 37 38/* the number of clocks per CONFIG_SYS_HZ */ 39#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) 40 41/* macro to read the 16 bit timer */ 42#define READ_TIMER (tmr->TC_CV & 0x0000ffff) 43AT91PS_TC tmr; 44 45static ulong timestamp; 46static ulong lastinc; 47 48int timer_init (void) 49{ 50 tmr = AT91C_BASE_TC0; 51 52 /* enables TC1.0 clock */ 53 *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */ 54 55 *AT91C_TCB0_BCR = 0; 56 *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; 57 tmr->TC_CCR = AT91C_TC_CLKDIS; 58#define AT91C_TC_CMR_CPCTRG (1 << 14) 59 /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */ 60 tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG; 61 62 tmr->TC_IDR = ~0ul; 63 tmr->TC_RC = TIMER_LOAD_VAL; 64 lastinc = 0; 65 tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; 66 timestamp = 0; 67 68 return (0); 69} 70 71/* 72 * timer without interrupts 73 */ 74 75void reset_timer (void) 76{ 77 reset_timer_masked (); 78} 79 80ulong get_timer (ulong base) 81{ 82 return get_timer_masked () - base; 83} 84 85void set_timer (ulong t) 86{ 87 timestamp = t; 88} 89 90void udelay (unsigned long usec) 91{ 92 udelay_masked(usec); 93} 94 95void reset_timer_masked (void) 96{ 97 /* reset time */ 98 lastinc = READ_TIMER; 99 timestamp = 0; 100} 101 102ulong get_timer_raw (void) 103{ 104 ulong now = READ_TIMER; 105 106 if (now >= lastinc) { 107 /* normal mode */ 108 timestamp += now - lastinc; 109 } else { 110 /* we have an overflow ... */ 111 timestamp += now + TIMER_LOAD_VAL - lastinc; 112 } 113 lastinc = now; 114 115 return timestamp; 116} 117 118ulong get_timer_masked (void) 119{ 120 return get_timer_raw()/TIMER_LOAD_VAL; 121} 122 123void udelay_masked (unsigned long usec) 124{ 125 ulong tmo; 126 ulong endtime; 127 signed long diff; 128 129 tmo = CONFIG_SYS_HZ_CLOCK / 1000; 130 tmo *= usec; 131 tmo /= 1000; 132 133 endtime = get_timer_raw () + tmo; 134 135 do { 136 ulong now = get_timer_raw (); 137 diff = endtime - now; 138 } while (diff >= 0); 139} 140 141/* 142 * This function is derived from PowerPC code (read timebase as long long). 143 * On ARM it just returns the timer value. 144 */ 145unsigned long long get_ticks(void) 146{ 147 return get_timer(0); 148} 149 150/* 151 * This function is derived from PowerPC code (timebase clock frequency). 152 * On ARM it returns the number of timer ticks per second. 153 */ 154ulong get_tbclk (void) 155{ 156 ulong tbclk; 157 158 tbclk = CONFIG_SYS_HZ; 159 return tbclk; 160} 161