1 /* 2 * (C) Copyright 2007, 2012 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 #include <asm/io.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 static ulong timestamp; 33 34 #if defined(CONFIG_SLTTMR) 35 #ifndef CONFIG_SYS_UDELAY_BASE 36 # error "uDelay base not defined!" 37 #endif 38 39 #if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK) 40 # error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!" 41 #endif 42 extern void dtimer_intr_setup(void); 43 44 void __udelay(unsigned long usec) 45 { 46 slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); 47 u32 now, freq; 48 49 /* 1 us period */ 50 freq = CONFIG_SYS_TIMER_PRESCALER; 51 52 /* Disable */ 53 out_be32(&timerp->cr, 0); 54 out_be32(&timerp->tcnt, usec * freq); 55 out_be32(&timerp->cr, SLT_CR_TEN); 56 57 now = in_be32(&timerp->cnt); 58 while (now != 0) 59 now = in_be32(&timerp->cnt); 60 61 setbits_be32(&timerp->sr, SLT_SR_ST); 62 out_be32(&timerp->cr, 0); 63 } 64 65 void dtimer_interrupt(void *not_used) 66 { 67 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 68 69 /* check for timer interrupt asserted */ 70 if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { 71 setbits_be32(&timerp->sr, SLT_SR_ST); 72 timestamp++; 73 return; 74 } 75 } 76 77 int timer_init(void) 78 { 79 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 80 81 timestamp = 0; 82 83 /* disable timer */ 84 out_be32(&timerp->cr, 0); 85 out_be32(&timerp->tcnt, 0); 86 /* clear status */ 87 out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST); 88 89 /* initialize and enable timer interrupt */ 90 irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); 91 92 /* Interrupt every ms */ 93 out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER); 94 95 dtimer_intr_setup(); 96 97 /* set a period of 1us, set timer mode to restart and 98 enable timer and interrupt */ 99 out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN); 100 return 0; 101 } 102 103 ulong get_timer(ulong base) 104 { 105 return (timestamp - base); 106 } 107 108 #endif /* CONFIG_SLTTMR */ 109