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