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