2019-05-28 19:57:24 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-05-27 12:30:12 +04:00
/*
* Copyright ( C ) ST - Ericsson SA 2011
*
* Author : Mattias Wallin < mattias . wallin @ stericsson . com > for ST - Ericsson
* Author : Sundar Iyer for ST - Ericsson
* sched_clock implementation is based on :
* plat - nomadik / timer . c Linus Walleij < linus . walleij @ stericsson . com >
*
* DBx500 - PRCMU Timer
* The PRCMU has 5 timers which are available in a always - on
* power domain . We use the Timer 4 for our always - on clock
2013-01-21 16:09:32 +04:00
* source on DB8500 .
2011-05-27 12:30:12 +04:00
*/
2015-12-01 17:00:24 +03:00
# include <linux/of.h>
# include <linux/of_address.h>
2011-05-27 12:30:12 +04:00
# include <linux/clockchips.h>
# define RATE_32K 32768
2021-03-23 00:39:03 +03:00
# define TIMER_MODE_CONTINUOUS 0x1
2011-05-27 12:30:12 +04:00
# define TIMER_DOWNCOUNT_VAL 0xffffffff
# define PRCMU_TIMER_REF 0
# define PRCMU_TIMER_DOWNCOUNT 0x4
# define PRCMU_TIMER_MODE 0x8
2011-10-03 11:30:20 +04:00
static void __iomem * clksrc_dbx500_timer_base ;
2011-05-27 12:30:12 +04:00
2016-12-21 22:32:01 +03:00
static u64 notrace clksrc_dbx500_prcmu_read ( struct clocksource * cs )
2011-05-27 12:30:12 +04:00
{
2013-01-21 16:09:31 +04:00
void __iomem * base = clksrc_dbx500_timer_base ;
2011-05-27 12:30:12 +04:00
u32 count , count2 ;
do {
2013-01-21 16:09:31 +04:00
count = readl_relaxed ( base + PRCMU_TIMER_DOWNCOUNT ) ;
count2 = readl_relaxed ( base + PRCMU_TIMER_DOWNCOUNT ) ;
2011-05-27 12:30:12 +04:00
} while ( count2 ! = count ) ;
/* Negate because the timer is a decrementing counter */
return ~ count ;
}
static struct clocksource clocksource_dbx500_prcmu = {
. name = " dbx500-prcmu-timer " ,
2018-11-15 16:32:02 +03:00
. rating = 100 ,
2011-05-27 12:30:12 +04:00
. read = clksrc_dbx500_prcmu_read ,
. mask = CLOCKSOURCE_MASK ( 32 ) ,
2018-11-15 16:32:02 +03:00
. flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP ,
2011-05-27 12:30:12 +04:00
} ;
2016-06-02 20:44:34 +03:00
static int __init clksrc_dbx500_prcmu_init ( struct device_node * node )
2011-05-27 12:30:12 +04:00
{
2015-12-01 17:00:24 +03:00
clksrc_dbx500_timer_base = of_iomap ( node , 0 ) ;
2011-10-03 11:30:20 +04:00
2011-05-27 12:30:12 +04:00
/*
* The A9 sub system expects the timer to be configured as
2021-03-23 00:39:03 +03:00
* a continuous looping timer .
2011-05-27 12:30:12 +04:00
* The PRCMU should configure it but if it for some reason
* don ' t we do it here .
*/
if ( readl ( clksrc_dbx500_timer_base + PRCMU_TIMER_MODE ) ! =
2021-03-23 00:39:03 +03:00
TIMER_MODE_CONTINUOUS ) {
writel ( TIMER_MODE_CONTINUOUS ,
2011-05-27 12:30:12 +04:00
clksrc_dbx500_timer_base + PRCMU_TIMER_MODE ) ;
writel ( TIMER_DOWNCOUNT_VAL ,
clksrc_dbx500_timer_base + PRCMU_TIMER_REF ) ;
}
2016-06-02 20:44:34 +03:00
return clocksource_register_hz ( & clocksource_dbx500_prcmu , RATE_32K ) ;
2011-05-27 12:30:12 +04:00
}
2017-05-26 17:56:11 +03:00
TIMER_OF_DECLARE ( dbx500_prcmu , " stericsson,db8500-prcmu-timer-4 " ,
2015-12-01 17:00:24 +03:00
clksrc_dbx500_prcmu_init ) ;