xref: /rk3399_rockchip-uboot/arch/m68k/cpu/mcf547x_8x/slicetimer.c (revision 3765b3e7bd0f8e46914d417f29cbcb0c72b1acf7)
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