2007-11-01 04:57:55 +03:00
/*
* Copyright ( C ) 2000 , 2001 Broadcom Corporation
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# include <linux/clocksource.h>
2015-03-07 21:30:34 +03:00
# include <linux/sched_clock.h>
2007-11-01 04:57:55 +03:00
# include <asm/addrspace.h>
# include <asm/io.h>
# include <asm/time.h>
# include <asm/sibyte/sb1250.h>
# include <asm/sibyte/sb1250_regs.h>
# include <asm/sibyte/sb1250_int.h>
# include <asm/sibyte/sb1250_scd.h>
# define SB1250_HPT_NUM 3
# define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
/*
* The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
* again .
*/
2015-03-07 21:30:32 +03:00
static inline cycle_t sb1250_hpt_get_cycles ( void )
2007-11-01 04:57:55 +03:00
{
unsigned int count ;
2015-03-07 21:30:32 +03:00
void __iomem * addr ;
2007-11-01 04:57:55 +03:00
2015-03-07 21:30:32 +03:00
addr = IOADDR ( A_SCD_TIMER_REGISTER ( SB1250_HPT_NUM , R_SCD_TIMER_CNT ) ) ;
count = G_SCD_TIMER_CNT ( __raw_readq ( addr ) ) ;
2007-11-01 04:57:55 +03:00
return SB1250_HPT_VALUE - count ;
}
2015-03-07 21:30:32 +03:00
static cycle_t sb1250_hpt_read ( struct clocksource * cs )
{
return sb1250_hpt_get_cycles ( ) ;
}
2007-11-01 04:57:55 +03:00
struct clocksource bcm1250_clocksource = {
2007-11-13 03:35:13 +03:00
. name = " bcm1250-counter-3 " ,
2013-01-22 15:59:30 +04:00
. rating = 200 ,
2007-11-01 04:57:55 +03:00
. read = sb1250_hpt_read ,
. mask = CLOCKSOURCE_MASK ( 23 ) ,
. flags = CLOCK_SOURCE_IS_CONTINUOUS ,
} ;
2015-03-07 21:30:34 +03:00
static u64 notrace sb1250_read_sched_clock ( void )
{
return sb1250_hpt_get_cycles ( ) ;
}
2007-11-01 04:57:55 +03:00
void __init sb1250_clocksource_init ( void )
{
struct clocksource * cs = & bcm1250_clocksource ;
/* Setup hpt using timer #3 but do not enable irq for it */
__raw_writeq ( 0 ,
IOADDR ( A_SCD_TIMER_REGISTER ( SB1250_HPT_NUM ,
R_SCD_TIMER_CFG ) ) ) ;
__raw_writeq ( SB1250_HPT_VALUE ,
IOADDR ( A_SCD_TIMER_REGISTER ( SB1250_HPT_NUM ,
R_SCD_TIMER_INIT ) ) ) ;
__raw_writeq ( M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS ,
IOADDR ( A_SCD_TIMER_REGISTER ( SB1250_HPT_NUM ,
R_SCD_TIMER_CFG ) ) ) ;
2010-04-27 07:23:11 +04:00
clocksource_register_hz ( cs , V_SCD_TIMER_FREQ ) ;
2015-03-07 21:30:34 +03:00
sched_clock_register ( sb1250_read_sched_clock , 23 , V_SCD_TIMER_FREQ ) ;
2007-11-01 04:57:55 +03:00
}