@ -17,15 +17,41 @@ DECLARE_GLOBAL_DATA_PTR;
# define GENERATED_SOURCE_MAX 6
# define GENERATED_MAX_DIV 255
struct generated_clk_priv {
/**
* generated_clk_bind ( ) - for the generated clock driver
* Recursively bind its children as clk devices .
*
* @ return : 0 on success , or negative error code on failure
*/
static int generated_clk_bind ( struct udevice * dev )
{
return at91_clk_sub_device_bind ( dev , " generic-clk " ) ;
}
static const struct udevice_id generated_clk_match [ ] = {
{ . compatible = " atmel,sama5d2-clk-generated " } ,
{ }
} ;
U_BOOT_DRIVER ( generated_clk ) = {
. name = " generated-clk " ,
. id = UCLASS_MISC ,
. of_match = generated_clk_match ,
. bind = generated_clk_bind ,
} ;
/*-------------------------------------------------------------*/
struct generic_clk_priv {
u32 num_parents ;
} ;
static ulong generated_clk_get_rate ( struct clk * clk )
static ulong generic _clk_get_rate ( struct clk * clk )
{
struct pmc_platdata * plat = dev_get_platdata ( clk - > dev ) ;
struct at91_pmc * pmc = plat - > reg_base ;
struct clk parent ;
ulong clk_rate ;
u32 tmp , gckdiv ;
u8 parent_id ;
int ret ;
@ -36,18 +62,22 @@ static ulong generated_clk_get_rate(struct clk *clk)
AT91_PMC_PCR_GCKCSS_MASK ;
gckdiv = ( tmp > > AT91_PMC_PCR_GCKDIV_OFFSET ) & AT91_PMC_PCR_GCKDIV_MASK ;
ret = clk_get_by_index ( clk - > dev , parent_id , & parent ) ;
ret = clk_get_by_index ( dev_get_parent ( clk - > dev ) , parent_id , & parent ) ;
if ( ret )
return 0 ;
return clk_get_rate ( & parent ) / ( gckdiv + 1 ) ;
clk_rate = clk_get_rate ( & parent ) / ( gckdiv + 1 ) ;
clk_free ( & parent ) ;
return clk_rate ;
}
static ulong generated_clk_set_rate ( struct clk * clk , ulong rate )
static ulong generic _clk_set_rate ( struct clk * clk , ulong rate )
{
struct pmc_platdata * plat = dev_get_platdata ( clk - > dev ) ;
struct at91_pmc * pmc = plat - > reg_base ;
struct generated _clk_priv * priv = dev_get_priv ( clk - > dev ) ;
struct generic _clk_priv * priv = dev_get_priv ( clk - > dev ) ;
struct clk parent , best_parent ;
ulong tmp_rate , best_rate = rate , parent_rate ;
int tmp_diff , best_diff = - 1 ;
@ -58,7 +88,7 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate)
int ret ;
for ( i = 0 ; i < priv - > num_parents ; i + + ) {
ret = clk_get_by_index ( clk - > dev , i , & parent ) ;
ret = clk_get_by_index ( dev_get_parent ( clk - > dev ) , i , & parent ) ;
if ( ret )
return ret ;
@ -111,18 +141,20 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate)
return 0 ;
}
static struct clk_ops generated_clk_ops = {
. get_rate = generated_clk_get_rate ,
. set_rate = generated_clk_set_rate ,
static struct clk_ops generic_clk_ops = {
. of_xlate = at91_clk_of_xlate ,
. get_rate = generic_clk_get_rate ,
. set_rate = generic_clk_set_rate ,
} ;
static int generated _clk_ofdata_to_platdata ( struct udevice * dev )
static int generic _clk_ofdata_to_platdata ( struct udevice * dev )
{
struct generated _clk_priv * priv = dev_get_priv ( dev ) ;
struct generic _clk_priv * priv = dev_get_priv ( dev ) ;
u32 cells [ GENERATED_SOURCE_MAX ] ;
u32 num_parents ;
num_parents = fdtdec_get_int_array_count ( gd - > fdt_blob , dev - > of_offset ,
num_parents = fdtdec_get_int_array_count ( gd - > fdt_blob ,
dev_get_parent ( dev ) - > of_offset ,
" clocks " , cells ,
GENERATED_SOURCE_MAX ) ;
@ -134,29 +166,12 @@ static int generated_clk_ofdata_to_platdata(struct udevice *dev)
return 0 ;
}
static int generated_clk_bind ( struct udevice * dev )
{
return at91_pmc_clk_node_bind ( dev ) ;
}
static int generated_clk_probe ( struct udevice * dev )
{
return at91_pmc_core_probe ( dev ) ;
}
static const struct udevice_id generated_clk_match [ ] = {
{ . compatible = " atmel,sama5d2-clk-generated " } ,
{ }
} ;
U_BOOT_DRIVER ( generated_clk ) = {
. name = " generated-clk " ,
U_BOOT_DRIVER ( generic_clk ) = {
. name = " generic-clk " ,
. id = UCLASS_CLK ,
. of_match = generated_clk_match ,
. bind = generated_clk_bind ,
. probe = generated_clk_probe ,
. ofdata_to_platdata = generated_clk_ofdata_to_platdata ,
. priv_auto_alloc_size = sizeof ( struct generated_clk_priv ) ,
. probe = at91_clk_probe ,
. ofdata_to_platdata = generic_clk_ofdata_to_platdata ,
. priv_auto_alloc_size = sizeof ( struct generic_clk_priv ) ,
. platdata_auto_alloc_size = sizeof ( struct pmc_platdata ) ,
. ops = & generated _clk_ops ,
. ops = & generic_clk_ops ,
} ;