1 /* 2 * (C) Copyright 2007 Freescale Semiconductor, Inc. 3 * TsiChung Liew (Tsi-Chung.Liew@freescale.com) 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 26 #include <asm/timer.h> 27 #include <asm/immap.h> 28 29 DECLARE_GLOBAL_DATA_PTR; 30 31 static ulong timestamp; 32 33 #if defined(CONFIG_SLTTMR) 34 #ifndef CONFIG_SYS_UDELAY_BASE 35 # error "uDelay base not defined!" 36 #endif 37 38 #if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK) 39 # error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!" 40 #endif 41 extern void dtimer_intr_setup(void); 42 43 void __udelay(unsigned long usec) 44 { 45 volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); 46 u32 now, freq; 47 48 /* 1 us period */ 49 freq = CONFIG_SYS_TIMER_PRESCALER; 50 51 timerp->cr = 0; /* Disable */ 52 timerp->tcnt = usec * freq; 53 timerp->cr = SLT_CR_TEN; 54 55 now = timerp->cnt; 56 while (now != 0) 57 now = timerp->cnt; 58 59 timerp->sr |= SLT_SR_ST; 60 timerp->cr = 0; 61 } 62 63 void dtimer_interrupt(void *not_used) 64 { 65 volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 66 67 /* check for timer interrupt asserted */ 68 if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { 69 timerp->sr |= SLT_SR_ST; 70 timestamp++; 71 return; 72 } 73 } 74 75 int timer_init(void) 76 { 77 volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 78 79 timestamp = 0; 80 81 timerp->cr = 0; /* disable timer */ 82 timerp->tcnt = 0; 83 timerp->sr = SLT_SR_BE | SLT_SR_ST; /* clear status */ 84 85 /* initialize and enable timer interrupt */ 86 irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); 87 88 /* Interrupt every ms */ 89 timerp->tcnt = 1000 * CONFIG_SYS_TIMER_PRESCALER; 90 91 dtimer_intr_setup(); 92 93 /* set a period of 1us, set timer mode to restart and 94 enable timer and interrupt */ 95 timerp->cr = SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN; 96 return 0; 97 } 98 99 ulong get_timer(ulong base) 100 { 101 return (timestamp - base); 102 } 103 104 #endif /* CONFIG_SLTTMR */ 105