blob: dc076fc6e8147895ce444c7525ea13144487a219 [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>
Simon Glass3ba929a2020-10-30 21:38:53 -060010#include <asm/global_data.h>
Simon Glassdbd79542020-05-10 11:40:11 -060011#include <linux/delay.h>
TsiChungLiew8999e6b2008-01-15 13:37:34 -060012
13#include <asm/timer.h>
14#include <asm/immap.h>
Alison Wang027f76f2012-03-26 21:49:07 +000015#include <asm/io.h>
TsiChungLiew8999e6b2008-01-15 13:37:34 -060016
17DECLARE_GLOBAL_DATA_PTR;
18
19static ulong timestamp;
20
21#if defined(CONFIG_SLTTMR)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020022#ifndef CONFIG_SYS_UDELAY_BASE
TsiChungLiew8999e6b2008-01-15 13:37:34 -060023# error "uDelay base not defined!"
24#endif
25
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020026#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 -060027# error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!"
28#endif
29extern void dtimer_intr_setup(void);
30
Ingo van Lilf0f778a2009-11-24 14:09:21 +010031void __udelay(unsigned long usec)
TsiChungLiew8999e6b2008-01-15 13:37:34 -060032{
Alison Wang027f76f2012-03-26 21:49:07 +000033 slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060034 u32 now, freq;
35
36 /* 1 us period */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020037 freq = CONFIG_SYS_TIMER_PRESCALER;
TsiChungLiew8999e6b2008-01-15 13:37:34 -060038
Alison Wang027f76f2012-03-26 21:49:07 +000039 /* Disable */
40 out_be32(&timerp->cr, 0);
41 out_be32(&timerp->tcnt, usec * freq);
42 out_be32(&timerp->cr, SLT_CR_TEN);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060043
Alison Wang027f76f2012-03-26 21:49:07 +000044 now = in_be32(&timerp->cnt);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060045 while (now != 0)
Alison Wang027f76f2012-03-26 21:49:07 +000046 now = in_be32(&timerp->cnt);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060047
Alison Wang027f76f2012-03-26 21:49:07 +000048 setbits_be32(&timerp->sr, SLT_SR_ST);
49 out_be32(&timerp->cr, 0);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060050}
51
52void dtimer_interrupt(void *not_used)
53{
Alison Wang027f76f2012-03-26 21:49:07 +000054 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060055
56 /* check for timer interrupt asserted */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020057 if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) {
Alison Wang027f76f2012-03-26 21:49:07 +000058 setbits_be32(&timerp->sr, SLT_SR_ST);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060059 timestamp++;
60 return;
61 }
62}
63
Jason Jin1dd491e2011-08-19 10:02:32 +080064int timer_init(void)
TsiChungLiew8999e6b2008-01-15 13:37:34 -060065{
Alison Wang027f76f2012-03-26 21:49:07 +000066 slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060067
68 timestamp = 0;
69
Alison Wang027f76f2012-03-26 21:49:07 +000070 /* disable timer */
71 out_be32(&timerp->cr, 0);
72 out_be32(&timerp->tcnt, 0);
73 /* clear status */
74 out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060075
76 /* initialize and enable timer interrupt */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020077 irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060078
79 /* Interrupt every ms */
Alison Wang027f76f2012-03-26 21:49:07 +000080 out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER);
TsiChungLiew8999e6b2008-01-15 13:37:34 -060081
82 dtimer_intr_setup();
83
84 /* set a period of 1us, set timer mode to restart and
85 enable timer and interrupt */
Alison Wang027f76f2012-03-26 21:49:07 +000086 out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN);
Jason Jin1dd491e2011-08-19 10:02:32 +080087 return 0;
TsiChungLiew8999e6b2008-01-15 13:37:34 -060088}
89
TsiChungLiew8999e6b2008-01-15 13:37:34 -060090ulong get_timer(ulong base)
91{
92 return (timestamp - base);
93}
94
TsiChungLiew8999e6b2008-01-15 13:37:34 -060095#endif /* CONFIG_SLTTMR */