2015-06-15 13:15:26 +02:00
# include <linux/kernel.h>
# include <linux/init.h>
2015-06-15 14:34:03 +02:00
# include <linux/clocksource.h>
# include <linux/clockchips.h>
# include <linux/sched_clock.h>
2015-06-15 13:15:26 +02:00
# include <linux/interrupt.h>
# include <linux/irq.h>
# include <linux/io.h>
# include <asm/mach/time.h>
# include "soc.h"
/*************************************************************************
* Timer handling for EP93xx
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* The ep93xx has four internal timers . Timers 1 , 2 ( both 16 bit ) and
* 3 ( 32 bit ) count down at 508 kHz , are self - reloading , and can generate
* an interrupt on underflow . Timer 4 ( 40 bit ) counts down at 983.04 kHz ,
* is free - running , and can ' t generate interrupts .
*
* The 508 kHz timers are ideal for use for the timer interrupt , as the
* most common values of HZ divide 508 kHz nicely . We pick one of the 16
* bit timers ( timer 1 ) since we don ' t need more than 16 bits of reload
* value as long as HZ > = 8.
*
* The higher clock rate of timer 4 makes it a better choice than the
* other timers for use in gettimeoffset ( ) , while the fact that it can ' t
* generate interrupts means we don ' t have to worry about not being able
* to use this timer for something else . We also use timer 4 for keeping
* track of lost jiffies .
*/
# define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
# define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
# define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
# define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
# define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
# define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
# define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
# define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
# define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
# define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
# define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
# define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
# define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
# define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
# define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
# define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
# define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
# define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
# define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
2015-06-15 14:34:03 +02:00
# define EP93XX_TIMER123_RATE 508469
# define EP93XX_TIMER4_RATE 983040
2015-06-15 13:15:26 +02:00
2015-06-15 14:34:03 +02:00
static u64 notrace ep93xx_read_sched_clock ( void )
{
u64 ret ;
ret = __raw_readl ( EP93XX_TIMER4_VALUE_LOW ) ;
ret | = ( ( u64 ) ( __raw_readl ( EP93XX_TIMER4_VALUE_HIGH ) & 0xff ) < < 32 ) ;
return ret ;
}
cycle_t ep93xx_clocksource_read ( struct clocksource * c )
{
u64 ret ;
ret = __raw_readl ( EP93XX_TIMER4_VALUE_LOW ) ;
ret | = ( ( u64 ) ( __raw_readl ( EP93XX_TIMER4_VALUE_HIGH ) & 0xff ) < < 32 ) ;
return ( cycle_t ) ret ;
}
static int ep93xx_clkevt_set_next_event ( unsigned long next ,
struct clock_event_device * evt )
{
/* Default mode: periodic, off, 508 kHz */
u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
EP93XX_TIMER123_CONTROL_CLKSEL ;
/* Clear timer */
__raw_writel ( tmode , EP93XX_TIMER1_CONTROL ) ;
/* Set next event */
__raw_writel ( next , EP93XX_TIMER1_LOAD ) ;
__raw_writel ( tmode | EP93XX_TIMER123_CONTROL_ENABLE ,
EP93XX_TIMER1_CONTROL ) ;
return 0 ;
}
2015-06-15 13:15:26 +02:00
2015-06-15 14:34:03 +02:00
static void ep93xx_clkevt_set_mode ( enum clock_event_mode mode ,
struct clock_event_device * evt )
{
/* Disable timer */
__raw_writel ( 0 , EP93XX_TIMER1_CONTROL ) ;
}
static struct clock_event_device ep93xx_clockevent = {
. name = " timer1 " ,
. features = CLOCK_EVT_FEAT_ONESHOT ,
. set_mode = ep93xx_clkevt_set_mode ,
. set_next_event = ep93xx_clkevt_set_next_event ,
. rating = 300 ,
} ;
2015-06-15 13:15:26 +02:00
static irqreturn_t ep93xx_timer_interrupt ( int irq , void * dev_id )
{
2015-06-15 14:34:03 +02:00
struct clock_event_device * evt = dev_id ;
2015-06-15 13:15:26 +02:00
/* Writing any value clears the timer interrupt */
__raw_writel ( 1 , EP93XX_TIMER1_CLEAR ) ;
2015-06-15 14:34:03 +02:00
evt - > event_handler ( evt ) ;
2015-06-15 13:15:26 +02:00
return IRQ_HANDLED ;
}
static struct irqaction ep93xx_timer_irq = {
. name = " ep93xx timer " ,
. flags = IRQF_TIMER | IRQF_IRQPOLL ,
. handler = ep93xx_timer_interrupt ,
2015-06-15 14:34:03 +02:00
. dev_id = & ep93xx_clockevent ,
2015-06-15 13:15:26 +02:00
} ;
void __init ep93xx_timer_init ( void )
{
2015-06-15 14:34:03 +02:00
/* Enable and register clocksource and sched_clock on timer 4 */
2015-06-15 13:15:26 +02:00
__raw_writel ( EP93XX_TIMER4_VALUE_HIGH_ENABLE ,
EP93XX_TIMER4_VALUE_HIGH ) ;
2015-06-15 14:34:03 +02:00
clocksource_mmio_init ( NULL , " timer4 " ,
EP93XX_TIMER4_RATE , 200 , 40 ,
ep93xx_clocksource_read ) ;
sched_clock_register ( ep93xx_read_sched_clock , 40 ,
EP93XX_TIMER4_RATE ) ;
2015-06-15 13:15:26 +02:00
2015-06-15 14:34:03 +02:00
/* Set up clockevent on timer 1 */
2015-06-15 13:15:26 +02:00
setup_irq ( IRQ_EP93XX_TIMER1 , & ep93xx_timer_irq ) ;
2015-06-15 14:34:03 +02:00
// FIXME: timer one is 16 bits 1-ffff use timer 3 1-ffffffff */
clockevents_config_and_register ( & ep93xx_clockevent ,
EP93XX_TIMER123_RATE ,
1 ,
0xffffU ) ;
2015-06-15 13:15:26 +02:00
}