Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / arch / m68k / cpu / mcf547x_8x / slicetimer.c
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 #include <init.h>
9 #include <irq_func.h>
10 #include <linux/delay.h>
11
12 #include <asm/timer.h>
13 #include <asm/immap.h>
14 #include <asm/io.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 static ulong timestamp;
19
20 #if defined(CONFIG_SLTTMR)
21 #ifndef CONFIG_SYS_UDELAY_BASE
22 #       error   "uDelay base not defined!"
23 #endif
24
25 #if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK)
26 #       error   "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!"
27 #endif
28 extern void dtimer_intr_setup(void);
29
30 void __udelay(unsigned long usec)
31 {
32         slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
33         u32 now, freq;
34
35         /* 1 us period */
36         freq = CONFIG_SYS_TIMER_PRESCALER;
37
38         /* Disable */
39         out_be32(&timerp->cr, 0);
40         out_be32(&timerp->tcnt, usec * freq);
41         out_be32(&timerp->cr, SLT_CR_TEN);
42
43         now = in_be32(&timerp->cnt);
44         while (now != 0)
45                 now = in_be32(&timerp->cnt);
46
47         setbits_be32(&timerp->sr, SLT_SR_ST);
48         out_be32(&timerp->cr, 0);
49 }
50
51 void dtimer_interrupt(void *not_used)
52 {
53         slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
54
55         /* check for timer interrupt asserted */
56         if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) {
57                 setbits_be32(&timerp->sr, SLT_SR_ST);
58                 timestamp++;
59                 return;
60         }
61 }
62
63 int timer_init(void)
64 {
65         slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
66
67         timestamp = 0;
68
69         /* disable timer */
70         out_be32(&timerp->cr, 0);
71         out_be32(&timerp->tcnt, 0);
72         /* clear status */
73         out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST);
74
75         /* initialize and enable timer interrupt */
76         irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0);
77
78         /* Interrupt every ms */
79         out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER);
80
81         dtimer_intr_setup();
82
83         /* set a period of 1us, set timer mode to restart and
84            enable timer and interrupt */
85         out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN);
86         return 0;
87 }
88
89 ulong get_timer(ulong base)
90 {
91         return (timestamp - base);
92 }
93
94 #endif                          /* CONFIG_SLTTMR */