clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/*
* Copyright ( c ) 2012 , NVIDIA CORPORATION . All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope 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 .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/clk.h>
# include <linux/clk-provider.h>
2013-01-11 13:16:26 +05:30
# include <linux/of.h>
# include <linux/clk/tegra.h>
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# include "clk.h"
2013-01-11 13:16:26 +05:30
/* Global data of Tegra CPU CAR ops */
2013-04-03 17:40:35 +03:00
static struct tegra_cpu_car_ops dummy_car_ops ;
struct tegra_cpu_car_ops * tegra_cpu_car_ops = & dummy_car_ops ;
2013-01-11 13:16:26 +05:30
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
void __init tegra_init_dup_clks ( struct tegra_clk_duplicate * dup_list ,
struct clk * clks [ ] , int clk_max )
{
struct clk * clk ;
for ( ; dup_list - > clk_id < clk_max ; dup_list + + ) {
clk = clks [ dup_list - > clk_id ] ;
dup_list - > lookup . clk = clk ;
clkdev_add ( & dup_list - > lookup ) ;
}
}
void __init tegra_init_from_table ( struct tegra_clk_init_table * tbl ,
struct clk * clks [ ] , int clk_max )
{
struct clk * clk ;
for ( ; tbl - > clk_id < clk_max ; tbl + + ) {
clk = clks [ tbl - > clk_id ] ;
if ( IS_ERR_OR_NULL ( clk ) )
return ;
if ( tbl - > parent_id < clk_max ) {
struct clk * parent = clks [ tbl - > parent_id ] ;
if ( clk_set_parent ( clk , parent ) ) {
pr_err ( " %s: Failed to set parent %s of %s \n " ,
__func__ , __clk_get_name ( parent ) ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
}
if ( tbl - > rate )
if ( clk_set_rate ( clk , tbl - > rate ) ) {
pr_err ( " %s: Failed to set rate %lu of %s \n " ,
__func__ , tbl - > rate ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
if ( tbl - > state )
if ( clk_prepare_enable ( clk ) ) {
pr_err ( " %s: Failed to enable %s \n " , __func__ ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
}
}
2013-01-11 13:16:26 +05:30
static const struct of_device_id tegra_dt_clk_match [ ] = {
{ . compatible = " nvidia,tegra20-car " , . data = tegra20_clock_init } ,
{ . compatible = " nvidia,tegra30-car " , . data = tegra30_clock_init } ,
{ }
} ;
void __init tegra_clocks_init ( void )
{
of_clk_init ( tegra_dt_clk_match ) ;
}
2013-03-25 13:22:24 -06:00
tegra_clk_apply_init_table_func tegra_clk_apply_init_table ;
void __init tegra_clocks_apply_init_table ( void )
{
if ( ! tegra_clk_apply_init_table )
return ;
tegra_clk_apply_init_table ( ) ;
}