2010-03-01 05:07:47 +01:00
/*
* Copyright ( C ) 2010 ST - Ericsson
* Copyright ( C ) 2009 STMicroelectronics
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
/**
* struct clkops - ux500 clock operations
* @ enable : function to enable the clock
* @ disable : function to disable the clock
* @ get_rate : function to get the current clock rate
*
* This structure contains function pointers to functions that will be used to
* control the clock . All of these functions are optional . If get_rate is
* NULL , the rate in the struct clk will be used .
*/
struct clkops {
void ( * enable ) ( struct clk * ) ;
void ( * disable ) ( struct clk * ) ;
unsigned long ( * get_rate ) ( struct clk * ) ;
} ;
/**
* struct clk - ux500 clock structure
* @ ops : pointer to clkops struct used to control this clock
* @ name : name , for debugging
* @ enabled : refcount . positive if enabled , zero if disabled
2010-05-26 07:38:54 +01:00
* @ get_rate : custom callback for getting the clock rate
* @ data : custom per - clock data for example for the get_rate
* callback
2010-03-01 05:07:47 +01:00
* @ rate : fixed rate for clocks which don ' t implement
* ops - > getrate
* @ prcmu_cg_off : address offset of the combined enable / disable register
* ( used on u8500v1 )
* @ prcmu_cg_bit : bit in the combined enable / disable register ( used on
* u8500v1 )
* @ prcmu_cg_mgt : address of the enable / disable register ( used on
* u8500ed )
* @ cluster : peripheral cluster number
* @ prcc_bus : bit for the bus clock in the peripheral ' s CLKRST
* @ prcc_kernel : bit for the kernel clock in the peripheral ' s CLKRST .
* - 1 if no kernel clock exists .
* @ parent_cluster : pointer to parent ' s cluster clk struct
* @ parent_periph : pointer to parent ' s peripheral clk struct
*
* Peripherals are organised into clusters , and each cluster has an associated
* bus clock . Some peripherals also have a parent peripheral clock .
*
* In order to enable a clock for a peripheral , we need to enable :
* ( 1 ) the parent cluster ( bus ) clock at the PRCMU level
* ( 2 ) the parent peripheral clock ( if any ) at the PRCMU level
* ( 3 ) the peripheral ' s bus & kernel clock at the PRCC level
*
* ( 1 ) and ( 2 ) are handled by defining clk structs ( DEFINE_PRCMU_CLK ) for each
* of the cluster and peripheral clocks , and hooking these as the parents of
* the individual peripheral clocks .
*
* ( 3 ) is handled by specifying the bits in the PRCC control registers required
* to enable these clocks and modifying them in the - > enable and
* - > disable callbacks of the peripheral clocks ( DEFINE_PRCC_CLK ) .
*
* This structure describes both the PRCMU - level clocks and PRCC - level clocks .
* The prcmu_ * fields are only used for the PRCMU clocks , and the cluster ,
* prcc , and parent pointers are only used for the PRCC - level clocks .
*/
struct clk {
const struct clkops * ops ;
const char * name ;
unsigned int enabled ;
2010-05-26 07:38:54 +01:00
unsigned long ( * get_rate ) ( struct clk * ) ;
void * data ;
2010-03-01 05:07:47 +01:00
unsigned long rate ;
struct list_head list ;
/* These three are only for PRCMU clks */
unsigned int prcmu_cg_off ;
unsigned int prcmu_cg_bit ;
unsigned int prcmu_cg_mgt ;
/* The rest are only for PRCC clks */
int cluster ;
unsigned int prcc_bus ;
unsigned int prcc_kernel ;
struct clk * parent_cluster ;
struct clk * parent_periph ;
2010-12-03 18:18:39 +01:00
# if defined(CONFIG_DEBUG_FS)
struct dentry * dent ; /* For visible tree hierarchy */
struct dentry * dent_bus ; /* For visible tree hierarchy */
# endif
2010-03-01 05:07:47 +01:00
} ;
# define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \
struct clk clk_ # # _name = { \
. name = # _name , \
. ops = & clk_prcmu_ops , \
. prcmu_cg_off = _cg_off , \
. prcmu_cg_bit = _cg_bit , \
. prcmu_cg_mgt = PRCM_ # # _reg # # _MGT \
}
# define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \
struct clk clk_ # # _name = { \
. name = # _name , \
. ops = & clk_prcmu_ops , \
. prcmu_cg_off = _cg_off , \
. prcmu_cg_bit = _cg_bit , \
. rate = _rate , \
. prcmu_cg_mgt = PRCM_ # # _reg # # _MGT \
}
# define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \
struct clk clk_ # # _name = { \
. name = # _name , \
. ops = & clk_prcc_ops , \
. cluster = _pclust , \
. prcc_bus = _bus_en , \
. prcc_kernel = _kernel_en , \
. parent_cluster = & clk_per # # _pclust # # clk , \
. parent_periph = _kernclk \
}
2010-05-26 07:38:54 +01:00
# define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
struct clk clk_ # # _name = { \
. name = # _name , \
. ops = & clk_prcc_ops , \
. cluster = _pclust , \
. prcc_bus = _bus_en , \
. prcc_kernel = _kernel_en , \
. parent_cluster = & clk_per # # _pclust # # clk , \
. parent_periph = _kernclk , \
. get_rate = _callback , \
. data = ( void * ) _data \
}
2010-03-01 05:07:47 +01:00
# define CLK(_clk, _devname, _conname) \
{ \
. clk = & clk_ # # _clk , \
. dev_id = _devname , \
. con_id = _conname , \
}
2010-05-26 07:38:54 +01:00
int __init clk_db8500_ed_fixup ( void ) ;
int __init clk_init ( void ) ;