1 /* 2 * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. 3 * TsiChung Liew (Tsi-Chung.Liew@freescale.com) 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 10 #include <asm/timer.h> 11 #include <asm/immap.h> 12 #include <asm/io.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 static ulong timestamp; 17 18 #if defined(CONFIG_SLTTMR) 19 #ifndef CONFIG_SYS_UDELAY_BASE 20 # error "uDelay base not defined!" 21 #endif 22 23 #if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK) 24 # error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!" 25 #endif 26 extern void dtimer_intr_setup(void); 27 28 void __udelay(unsigned long usec) 29 { 30 slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); 31 u32 now, freq; 32 33 /* 1 us period */ 34 freq = CONFIG_SYS_TIMER_PRESCALER; 35 36 /* Disable */ 37 out_be32(&timerp->cr, 0); 38 out_be32(&timerp->tcnt, usec * freq); 39 out_be32(&timerp->cr, SLT_CR_TEN); 40 41 now = in_be32(&timerp->cnt); 42 while (now != 0) 43 now = in_be32(&timerp->cnt); 44 45 setbits_be32(&timerp->sr, SLT_SR_ST); 46 out_be32(&timerp->cr, 0); 47 } 48 49 void dtimer_interrupt(void *not_used) 50 { 51 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 52 53 /* check for timer interrupt asserted */ 54 if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { 55 setbits_be32(&timerp->sr, SLT_SR_ST); 56 timestamp++; 57 return; 58 } 59 } 60 61 int timer_init(void) 62 { 63 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); 64 65 timestamp = 0; 66 67 /* disable timer */ 68 out_be32(&timerp->cr, 0); 69 out_be32(&timerp->tcnt, 0); 70 /* clear status */ 71 out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST); 72 73 /* initialize and enable timer interrupt */ 74 irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); 75 76 /* Interrupt every ms */ 77 out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER); 78 79 dtimer_intr_setup(); 80 81 /* set a period of 1us, set timer mode to restart and 82 enable timer and interrupt */ 83 out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN); 84 return 0; 85 } 86 87 ulong get_timer(ulong base) 88 { 89 return (timestamp - base); 90 } 91 92 #endif /* CONFIG_SLTTMR */ 93