blob: c4988f9031c59475493ab865bd55c346ea5602f3 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
TsiChungLiew8999e6b2008-01-15 13:37:34 -06002/*
Alison Wang027f76f2012-03-26 21:49:07 +00003 * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc.
TsiChungLiew8999e6b2008-01-15 13:37:34 -06004 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
TsiChungLiew8999e6b2008-01-15 13:37:34 -06005 */
6
7#include <common.h>
Simon Glass97589732020-05-10 11:40:02 -06008#include <init.h>
Simon Glass9b61c7c2019-11-14 12:57:41 -07009#include <irq_func.h>
TsiChungLiew8999e6b2008-01-15 13:37:34 -060010
11#include <asm/timer.h>
12#include <asm/immap.h>
Alison Wang027f76f2012-03-26 21:49:07 +000013#include <asm/io.h>
TsiChungLiew8999e6b2008-01-15 13:37:34 -060014
15DECLARE_GLOBAL_DATA_PTR;
16
17static ulong timestamp;
18
19#if defined(CONFIG_SLTTMR)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020020#ifndef CONFIG_SYS_UDELAY_BASE
TsiChungLiew8999e6b2008-01-15 13:37:34 -060021# error "uDelay base not defined!"
22#endif
23
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020024#if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK)
TsiChungLiew8999e6b2008-01-15 13:37:34 -060025# error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!"
26#endif
27extern void dtimer_intr_setup(void);
28
Ingo van Lilf0f778a2009-11-24 14:09:21 +010029void __udelay(unsigned long usec)
TsiChungLiew8999e6b2008-01-15 13:37:34 -060030{
Alison Wang027f76f2012-03-26 21:49:07 +000031 slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060032 u32 now, freq;
33
34 /* 1 us period */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020035 freq = CONFIG_SYS_TIMER_PRESCALER;
TsiChungLiew8999e6b2008-01-15 13:37:34 -060036
Alison Wang027f76f2012-03-26 21:49:07 +000037 /* Disable */
38 out_be32(&timerp->cr, 0);
39 out_be32(&timerp->tcnt, usec * freq);
40 out_be32(&timerp->cr, SLT_CR_TEN);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060041
Alison Wang027f76f2012-03-26 21:49:07 +000042 now = in_be32(&timerp->cnt);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060043 while (now != 0)
Alison Wang027f76f2012-03-26 21:49:07 +000044 now = in_be32(&timerp->cnt);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060045
Alison Wang027f76f2012-03-26 21:49:07 +000046 setbits_be32(&timerp->sr, SLT_SR_ST);
47 out_be32(&timerp->cr, 0);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060048}
49
50void dtimer_interrupt(void *not_used)
51{
Alison Wang027f76f2012-03-26 21:49:07 +000052 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060053
54 /* check for timer interrupt asserted */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020055 if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) {
Alison Wang027f76f2012-03-26 21:49:07 +000056 setbits_be32(&timerp->sr, SLT_SR_ST);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060057 timestamp++;
58 return;
59 }
60}
61
Jason Jin1dd491e2011-08-19 10:02:32 +080062int timer_init(void)
TsiChungLiew8999e6b2008-01-15 13:37:34 -060063{
Alison Wang027f76f2012-03-26 21:49:07 +000064 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060065
66 timestamp = 0;
67
Alison Wang027f76f2012-03-26 21:49:07 +000068 /* disable timer */
69 out_be32(&timerp->cr, 0);
70 out_be32(&timerp->tcnt, 0);
71 /* clear status */
72 out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060073
74 /* initialize and enable timer interrupt */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020075 irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060076
77 /* Interrupt every ms */
Alison Wang027f76f2012-03-26 21:49:07 +000078 out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060079
80 dtimer_intr_setup();
81
82 /* set a period of 1us, set timer mode to restart and
83 enable timer and interrupt */
Alison Wang027f76f2012-03-26 21:49:07 +000084 out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN);
Jason Jin1dd491e2011-08-19 10:02:32 +080085 return 0;
TsiChungLiew8999e6b2008-01-15 13:37:34 -060086}
87
TsiChungLiew8999e6b2008-01-15 13:37:34 -060088ulong get_timer(ulong base)
89{
90 return (timestamp - base);
91}
92
TsiChungLiew8999e6b2008-01-15 13:37:34 -060093#endif /* CONFIG_SLTTMR */