2006-03-15 15:54:37 +00:00
/*
* linux / arch / arm / mach - sa1100 / clock . c
*/
# include <linux/module.h>
# include <linux/kernel.h>
2008-11-08 20:48:27 +00:00
# include <linux/device.h>
2006-03-15 15:54:37 +00:00
# include <linux/list.h>
# include <linux/errno.h>
# include <linux/err.h>
# include <linux/string.h>
# include <linux/clk.h>
# include <linux/spinlock.h>
2007-04-22 10:08:58 +01:00
# include <linux/mutex.h>
2011-11-30 14:32:36 +08:00
# include <linux/io.h>
# include <linux/clkdev.h>
2006-03-15 15:54:37 +00:00
2008-08-05 16:14:15 +01:00
# include <mach/hardware.h>
2014-12-03 18:35:29 +01:00
# include <mach/generic.h>
2006-03-15 15:54:37 +00:00
2011-11-30 14:32:36 +08:00
struct clkops {
void ( * enable ) ( struct clk * ) ;
void ( * disable ) ( struct clk * ) ;
2014-12-03 18:35:29 +01:00
unsigned long ( * get_rate ) ( struct clk * ) ;
2011-11-30 14:32:36 +08:00
} ;
2006-03-15 15:54:37 +00:00
struct clk {
2011-11-30 14:32:36 +08:00
const struct clkops * ops ;
2006-03-15 15:54:37 +00:00
unsigned int enabled ;
} ;
2011-11-30 14:32:36 +08:00
# define DEFINE_CLK(_name, _ops) \
struct clk clk_ # # _name = { \
. ops = _ops , \
}
static DEFINE_SPINLOCK ( clocks_lock ) ;
static void clk_gpio27_enable ( struct clk * clk )
2008-11-08 20:48:27 +00:00
{
/*
* First , set up the 3.6864 MHz clock on GPIO 27 for the SA - 1111 :
* ( SA - 1110 Developer ' s Manual , section 9.1 .2 .1 )
*/
GAFR | = GPIO_32_768kHz ;
GPDR | = GPIO_32_768kHz ;
TUCR = TUCR_3_6864MHz ;
}
2011-11-30 14:32:36 +08:00
static void clk_gpio27_disable ( struct clk * clk )
2008-11-08 20:48:27 +00:00
{
TUCR = 0 ;
GPDR & = ~ GPIO_32_768kHz ;
GAFR & = ~ GPIO_32_768kHz ;
}
2014-12-03 18:35:29 +01:00
static void clk_cpu_enable ( struct clk * clk )
{
}
static void clk_cpu_disable ( struct clk * clk )
{
}
static unsigned long clk_cpu_get_rate ( struct clk * clk )
{
return sa11x0_getspeed ( 0 ) * 1000 ;
}
2006-03-15 15:54:37 +00:00
int clk_enable ( struct clk * clk )
{
unsigned long flags ;
2011-11-30 14:32:36 +08:00
if ( clk ) {
spin_lock_irqsave ( & clocks_lock , flags ) ;
if ( clk - > enabled + + = = 0 )
clk - > ops - > enable ( clk ) ;
spin_unlock_irqrestore ( & clocks_lock , flags ) ;
}
2006-03-15 15:54:37 +00:00
return 0 ;
}
EXPORT_SYMBOL ( clk_enable ) ;
void clk_disable ( struct clk * clk )
{
unsigned long flags ;
2011-11-30 14:32:36 +08:00
if ( clk ) {
WARN_ON ( clk - > enabled = = 0 ) ;
spin_lock_irqsave ( & clocks_lock , flags ) ;
if ( - - clk - > enabled = = 0 )
clk - > ops - > disable ( clk ) ;
spin_unlock_irqrestore ( & clocks_lock , flags ) ;
}
2006-03-15 15:54:37 +00:00
}
EXPORT_SYMBOL ( clk_disable ) ;
2014-12-03 18:35:29 +01:00
unsigned long clk_get_rate ( struct clk * clk )
{
if ( clk & & clk - > ops & & clk - > ops - > get_rate )
return clk - > ops - > get_rate ( clk ) ;
return 0 ;
}
EXPORT_SYMBOL ( clk_get_rate ) ;
2011-11-30 14:32:36 +08:00
const struct clkops clk_gpio27_ops = {
. enable = clk_gpio27_enable ,
. disable = clk_gpio27_disable ,
} ;
2014-12-03 18:35:29 +01:00
const struct clkops clk_cpu_ops = {
. enable = clk_cpu_enable ,
. disable = clk_cpu_disable ,
. get_rate = clk_cpu_get_rate ,
} ;
2011-11-30 14:32:36 +08:00
static DEFINE_CLK ( gpio27 , & clk_gpio27_ops ) ;
2014-12-03 18:35:29 +01:00
static DEFINE_CLK ( cpu , & clk_cpu_ops ) ;
2014-12-21 16:07:43 +01:00
static unsigned long clk_36864_get_rate ( struct clk * clk )
{
return 3686400 ;
}
static struct clkops clk_36864_ops = {
2016-08-19 12:44:29 +01:00
. enable = clk_cpu_enable ,
. disable = clk_cpu_disable ,
2014-12-21 16:07:43 +01:00
. get_rate = clk_36864_get_rate ,
} ;
static DEFINE_CLK ( 36864 , & clk_36864_ops ) ;
2011-11-30 14:32:36 +08:00
static struct clk_lookup sa11xx_clkregs [ ] = {
CLKDEV_INIT ( " sa1111.0 " , NULL , & clk_gpio27 ) ,
CLKDEV_INIT ( " sa1100-rtc " , NULL , NULL ) ,
2014-12-03 18:35:29 +01:00
CLKDEV_INIT ( " sa11x0-fb " , NULL , & clk_cpu ) ,
CLKDEV_INIT ( " sa11x0-pcmcia " , NULL , & clk_cpu ) ,
2014-12-03 18:35:53 +01:00
/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
CLKDEV_INIT ( " 1800 " , NULL , & clk_cpu ) ,
2014-12-21 16:07:43 +01:00
CLKDEV_INIT ( NULL , " OSTIMER0 " , & clk_36864 ) ,
2011-11-30 14:32:36 +08:00
} ;
2016-08-19 12:47:54 +01:00
int __init sa11xx_clk_init ( void )
2006-03-15 15:54:37 +00:00
{
2011-11-30 14:32:36 +08:00
clkdev_add_table ( sa11xx_clkregs , ARRAY_SIZE ( sa11xx_clkregs ) ) ;
return 0 ;
2006-03-15 15:54:37 +00:00
}