2011-09-14 09:10:54 +02:00
/*
* Copyright ( C ) ST - Ericsson SA 2011
*
* License Terms : GNU General Public License v2
* Author : Mattias Wallin < mattias . wallin @ stericsson . com > for ST - Ericsson
*/
# include <linux/io.h>
2011-10-03 09:30:20 +02:00
# include <linux/errno.h>
2011-09-14 09:10:54 +02:00
# include <linux/clksrc-dbx500-prcmu.h>
2012-03-16 09:53:24 +00:00
# include <linux/of.h>
2012-04-24 10:04:46 +01:00
# include <linux/of_address.h>
2012-10-18 14:01:25 +02:00
# include <linux/platform_data/clocksource-nomadik-mtu.h>
2011-09-14 09:10:54 +02:00
2012-01-10 19:44:19 +00:00
# include <asm/smp_twd.h>
2011-09-14 09:10:54 +02:00
# include <mach/setup.h>
# include <mach/hardware.h>
2012-03-15 11:05:39 +00:00
# include <mach/irqs.h>
2011-09-14 09:10:54 +02:00
2012-01-10 19:44:19 +00:00
# ifdef CONFIG_HAVE_ARM_TWD
static DEFINE_TWD_LOCAL_TIMER ( u8500_twd_local_timer ,
U8500_TWD_BASE , IRQ_LOCALTIMER ) ;
static void __init ux500_twd_init ( void )
{
struct twd_local_timer * twd_local_timer ;
int err ;
2012-04-13 13:16:31 +02:00
/* Use this to switch local timer base if changed in new ASICs */
twd_local_timer = & u8500_twd_local_timer ;
2012-01-10 19:44:19 +00:00
2012-03-16 09:53:24 +00:00
if ( of_have_populated_dt ( ) )
twd_local_timer_of_register ( ) ;
else {
err = twd_local_timer_register ( twd_local_timer ) ;
if ( err )
pr_err ( " twd_local_timer_register failed %d \n " , err ) ;
}
2012-01-10 19:44:19 +00:00
}
# else
# define ux500_twd_init() do { } while(0)
# endif
2012-04-24 10:04:46 +01:00
const static struct of_device_id prcmu_timer_of_match [ ] __initconst = {
{ . compatible = " stericsson,db8500-prcmu-timer-4 " , } ,
{ } ,
} ;
2011-09-14 09:10:54 +02:00
static void __init ux500_timer_init ( void )
{
2012-01-11 09:46:59 +01:00
void __iomem * mtu_timer_base ;
2011-10-03 09:30:20 +02:00
void __iomem * prcmu_timer_base ;
2012-04-24 10:04:46 +01:00
void __iomem * tmp_base ;
struct device_node * np ;
2011-10-03 09:30:20 +02:00
2012-09-03 15:10:23 +02:00
if ( cpu_is_u8500_family ( ) | | cpu_is_ux540_family ( ) ) {
2012-01-11 09:46:59 +01:00
mtu_timer_base = __io_address ( U8500_MTU0_BASE ) ;
2011-10-03 09:30:20 +02:00
prcmu_timer_base = __io_address ( U8500_PRCMU_TIMER_4_BASE ) ;
2011-09-14 09:10:54 +02:00
} else {
ux500_unknown_soc ( ) ;
}
2012-04-24 10:04:46 +01:00
/* TODO: Once MTU has been DT:ed place code above into else. */
if ( of_have_populated_dt ( ) ) {
2012-06-15 09:27:54 +01:00
# ifdef CONFIG_OF
2012-04-24 10:04:46 +01:00
np = of_find_matching_node ( NULL , prcmu_timer_of_match ) ;
if ( ! np )
2012-06-15 09:27:54 +01:00
# endif
2012-04-24 10:04:46 +01:00
goto dt_fail ;
tmp_base = of_iomap ( np , 0 ) ;
if ( ! tmp_base )
goto dt_fail ;
prcmu_timer_base = tmp_base ;
}
dt_fail :
/* Doing it the old fashioned way. */
2011-09-14 09:10:54 +02:00
/*
* Here we register the timerblocks active in the system .
* Localtimers ( twd ) is started when both cpu is up and running .
* MTU register a clocksource , clockevent and sched_clock .
* Since the MTU is located in the VAPE power domain
* it will be cleared in sleep which makes it unsuitable .
* We however need it as a timer tick ( clockevent )
* during boot to calibrate delay until twd is started .
* RTC - RTT have problems as timer tick during boot since it is
* depending on delay which is not yet calibrated . RTC - RTT is in the
* always - on powerdomain and is used as clockevent instead of twd when
* sleeping .
2012-04-13 13:16:31 +02:00
* The PRCMU timer 4 register a clocksource and
2011-09-14 09:10:54 +02:00
* sched_clock with higher rating then MTU since is always - on .
*
*/
2012-10-18 11:06:02 +02:00
nmdk_timer_init ( mtu_timer_base , IRQ_MTU0 ) ;
2011-10-03 09:30:20 +02:00
clksrc_dbx500_prcmu_init ( prcmu_timer_base ) ;
2012-01-10 19:44:19 +00:00
ux500_twd_init ( ) ;
2011-09-14 09:10:54 +02:00
}
2011-09-21 07:47:02 +02:00
static void ux500_timer_reset ( void )
{
nmdk_clkevt_reset ( ) ;
nmdk_clksrc_reset ( ) ;
}
2011-09-14 09:10:54 +02:00
struct sys_timer ux500_timer = {
. init = ux500_timer_init ,
2011-09-21 07:47:02 +02:00
. resume = ux500_timer_reset ,
2011-09-14 09:10:54 +02:00
} ;