Commit 343a607c authored by Peter De Schrijver's avatar Peter De Schrijver

clk: tegra: common periph_clk_enb_refcnt and clks

This patch makes periph_clk_enb_refcnt a global array, dynamically allocated
at boottime. It simplifies the macros somewhat and allows clocks common to
several Tegra SoCs to be defined in a separate files. Also the clks array
becomes global and dynamically allocated which allows the DT registration to
be moved to a generic funcion.
Signed-off-by: default avatarPeter De Schrijver <pdeschrijver@nvidia.com>
parent d5ff89a8
...@@ -197,6 +197,7 @@ static struct clk *_tegra_clk_register_periph(const char *name, ...@@ -197,6 +197,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
periph->divider.reg = div ? (clk_base + offset) : NULL; periph->divider.reg = div ? (clk_base + offset) : NULL;
periph->gate.clk_base = clk_base; periph->gate.clk_base = clk_base;
periph->gate.regs = bank; periph->gate.regs = bank;
periph->gate.enable_refcnt = periph_clk_enb_refcnt;
clk = clk_register(NULL, &periph->hw); clk = clk_register(NULL, &periph->hw);
if (IS_ERR(clk)) if (IS_ERR(clk))
......
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
#define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */
#define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT)
#define CLK_OUT_ENB_NUM 6
#define TEGRA114_CLK_PERIPH_BANKS 5 #define TEGRA114_CLK_PERIPH_BANKS 5
#define PLLC_BASE 0x80 #define PLLC_BASE 0x80
...@@ -266,8 +264,6 @@ static struct cpu_clk_suspend_context { ...@@ -266,8 +264,6 @@ static struct cpu_clk_suspend_context {
} tegra114_cpu_clk_sctx; } tegra114_cpu_clk_sctx;
#endif #endif
static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
static void __iomem *clk_base; static void __iomem *clk_base;
static void __iomem *pmc_base; static void __iomem *pmc_base;
...@@ -712,59 +708,53 @@ static unsigned long tegra114_input_freq[] = { ...@@ -712,59 +708,53 @@ static unsigned long tegra114_input_freq[] = {
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
_clk_id, _parents##_idx, 0)
#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _gate_flags, _clk_id, flags)\ _clk_num, _gate_flags, _clk_id, flags)\
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
_clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_num, _gate_flags, _clk_id, _parents##_idx, flags)
_clk_id, _parents##_idx, flags)
#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
_clk_num, periph_clk_enb_refcnt, _gate_flags,\ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
_clk_id, _parents##_idx, 0)
#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _gate_flags, _clk_id, flags)\ _clk_num, _gate_flags, _clk_id, flags)\
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _gate_flags, _clk_id, _parents##_idx, flags)
_parents##_idx, flags)
#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _gate_flags, _clk_id, _parents##_idx, 0)
_parents##_idx, 0)
#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _clk_id) \ _clk_num, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) 0, _clk_id, _parents##_idx, 0)
#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _clk_id) \ _clk_num, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\
_clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ _clk_num, 0, _clk_id, _parents##_idx, 0)
_parents##_idx, 0)
#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
_mux_shift, _mux_mask, _clk_num, \ _mux_shift, _mux_mask, _clk_num, \
_gate_flags, _clk_id) \ _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
_mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\
_clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_num, _gate_flags, \
_clk_id, _parents##_idx, 0) _clk_id, _parents##_idx, 0)
#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \
...@@ -772,16 +762,14 @@ static unsigned long tegra114_input_freq[] = { ...@@ -772,16 +762,14 @@ static unsigned long tegra114_input_freq[] = {
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \
29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, _gate_flags, _clk_id, \ _gate_flags, _clk_id, _parents##_idx, 0)
_parents##_idx, 0)
#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\
_gate_flags, _clk_id) \ _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \
_offset, 16, 0xE01F, 0, 0, 8, 1, \ _offset, 16, 0xE01F, 0, 0, 8, 1, \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, _gate_flags , _clk_id, \ _gate_flags , _clk_id, mux_d_audio_clk_idx, 0)
mux_d_audio_clk_idx, 0)
struct utmi_clk_param { struct utmi_clk_param {
/* Oscillator Frequency in KHz */ /* Oscillator Frequency in KHz */
...@@ -946,8 +934,7 @@ static const struct clk_div_table pll_re_div_table[] = { ...@@ -946,8 +934,7 @@ static const struct clk_div_table pll_re_div_table[] = {
{ .val = 0, .div = 0 }, { .val = 0, .div = 0 },
}; };
static struct clk *clks[TEGRA114_CLK_CLK_MAX]; static struct clk **clks;
static struct clk_onecell_data clk_data;
static unsigned long osc_freq; static unsigned long osc_freq;
static unsigned long pll_ref_freq; static unsigned long pll_ref_freq;
...@@ -2229,7 +2216,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); ...@@ -2229,7 +2216,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
static void __init tegra114_clock_init(struct device_node *np) static void __init tegra114_clock_init(struct device_node *np)
{ {
struct device_node *node; struct device_node *node;
int i;
clk_base = of_iomap(np, 0); clk_base = of_iomap(np, 0);
if (!clk_base) { if (!clk_base) {
...@@ -2251,10 +2237,11 @@ static void __init tegra114_clock_init(struct device_node *np) ...@@ -2251,10 +2237,11 @@ static void __init tegra114_clock_init(struct device_node *np)
return; return;
} }
if (tegra114_osc_clk_init(clk_base) < 0) clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS);
if (!clks)
return; return;
if (tegra_clk_set_periph_banks(TEGRA114_CLK_PERIPH_BANKS) < 0) if (tegra114_osc_clk_init(clk_base) < 0)
return; return;
tegra114_fixed_clk_init(clk_base); tegra114_fixed_clk_init(clk_base);
...@@ -2264,19 +2251,7 @@ static void __init tegra114_clock_init(struct device_node *np) ...@@ -2264,19 +2251,7 @@ static void __init tegra114_clock_init(struct device_node *np)
tegra114_pmc_clk_init(pmc_base); tegra114_pmc_clk_init(pmc_base);
tegra114_super_clk_init(clk_base); tegra114_super_clk_init(clk_base);
for (i = 0; i < ARRAY_SIZE(clks); i++) { tegra_add_of_provider(np);
if (IS_ERR(clks[i])) {
pr_err
("Tegra114 clk %d: register failed with %ld\n",
i, PTR_ERR(clks[i]));
}
if (!clks[i])
clks[i] = ERR_PTR(-EINVAL);
}
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
tegra_clk_apply_init_table = tegra114_clock_apply_init_table; tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
......
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
#include "clk.h" #include "clk.h"
#define CLK_OUT_ENB_NUM 3
#define OSC_CTRL 0x50 #define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_MASK (3<<30) #define OSC_CTRL_OSC_FREQ_MASK (3<<30)
#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) #define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
...@@ -170,8 +168,6 @@ static struct cpu_clk_suspend_context { ...@@ -170,8 +168,6 @@ static struct cpu_clk_suspend_context {
} tegra20_cpu_clk_sctx; } tegra20_cpu_clk_sctx;
#endif #endif
static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
static void __iomem *clk_base; static void __iomem *clk_base;
static void __iomem *pmc_base; static void __iomem *pmc_base;
...@@ -182,21 +178,21 @@ static DEFINE_SPINLOCK(sysrate_lock); ...@@ -182,21 +178,21 @@ static DEFINE_SPINLOCK(sysrate_lock);
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, \ _clk_num, \
_gate_flags, _clk_id) _gate_flags, _clk_id)
#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \
_clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_num, _gate_flags, \
_clk_id) _clk_id)
#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_num, _gate_flags, \
_clk_id) _clk_id)
#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
...@@ -204,7 +200,7 @@ static DEFINE_SPINLOCK(sysrate_lock); ...@@ -204,7 +200,7 @@ static DEFINE_SPINLOCK(sysrate_lock);
_gate_flags, _clk_id) \ _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
_mux_shift, _mux_width, 0, 0, 0, 0, 0, \ _mux_shift, _mux_width, 0, 0, 0, 0, 0, \
_clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_num, _gate_flags, \
_clk_id) _clk_id)
/* IDs assigned here must be in sync with DT bindings definition /* IDs assigned here must be in sync with DT bindings definition
...@@ -226,8 +222,7 @@ enum tegra20_clk { ...@@ -226,8 +222,7 @@ enum tegra20_clk {
pll_x, cop, audio, pll_ref, twd, clk_max, pll_x, cop, audio, pll_ref, twd, clk_max,
}; };
static struct clk *clks[clk_max]; static struct clk **clks;
static struct clk_onecell_data clk_data;
static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
{ 12000000, 600000000, 600, 12, 0, 8 }, { 12000000, 600000000, 600, 12, 0, 8 },
...@@ -808,7 +803,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { ...@@ -808,7 +803,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3),
TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc), TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc),
TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi),
TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, pwm),
}; };
static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
...@@ -1232,7 +1227,6 @@ static const struct of_device_id pmc_match[] __initconst = { ...@@ -1232,7 +1227,6 @@ static const struct of_device_id pmc_match[] __initconst = {
static void __init tegra20_clock_init(struct device_node *np) static void __init tegra20_clock_init(struct device_node *np)
{ {
int i;
struct device_node *node; struct device_node *node;
clk_base = of_iomap(np, 0); clk_base = of_iomap(np, 0);
...@@ -1253,7 +1247,8 @@ static void __init tegra20_clock_init(struct device_node *np) ...@@ -1253,7 +1247,8 @@ static void __init tegra20_clock_init(struct device_node *np)
BUG(); BUG();
} }
if (tegra_clk_set_periph_banks(TEGRA20_CLK_PERIPH_BANKS) < 0) clks = tegra_clk_init(clk_max, TEGRA20_CLK_PERIPH_BANKS);
if (!clks)
return; return;
tegra20_osc_clk_init(); tegra20_osc_clk_init();
...@@ -1264,22 +1259,9 @@ static void __init tegra20_clock_init(struct device_node *np) ...@@ -1264,22 +1259,9 @@ static void __init tegra20_clock_init(struct device_node *np)
tegra20_periph_clk_init(); tegra20_periph_clk_init();
tegra20_audio_clk_init(); tegra20_audio_clk_init();
for (i = 0; i < ARRAY_SIZE(clks); i++) {
if (IS_ERR(clks[i])) {
pr_err("Tegra20 clk %d: register failed with %ld\n",
i, PTR_ERR(clks[i]));
BUG();
}
if (!clks[i])
clks[i] = ERR_PTR(-EINVAL);
}
tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
clk_data.clks = clks; tegra_add_of_provider(np);
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
tegra_clk_apply_init_table = tegra20_clock_apply_init_table; tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#include "clk.h" #include "clk.h"
#define CLK_OUT_ENB_NUM 5
#define OSC_CTRL 0x50 #define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
#define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28) #define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28)
...@@ -236,8 +234,6 @@ static struct cpu_clk_suspend_context { ...@@ -236,8 +234,6 @@ static struct cpu_clk_suspend_context {
} tegra30_cpu_clk_sctx; } tegra30_cpu_clk_sctx;
#endif #endif
static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
static void __iomem *clk_base; static void __iomem *clk_base;
static void __iomem *pmc_base; static void __iomem *pmc_base;
static unsigned long input_freq; static unsigned long input_freq;
...@@ -253,41 +249,41 @@ static DEFINE_SPINLOCK(sysrate_lock); ...@@ -253,41 +249,41 @@ static DEFINE_SPINLOCK(sysrate_lock);
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) _clk_num, _gate_flags, _clk_id)
#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, \ _clk_num, \
_gate_flags, _clk_id) _gate_flags, _clk_id)
#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
_clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) _clk_num, _gate_flags, _clk_id)
#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, _gate_flags, _clk_id) _gate_flags, _clk_id)
#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
_clk_num, _clk_id) \ _clk_num, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \
TEGRA_DIVIDER_ROUND_UP, _clk_num, \ TEGRA_DIVIDER_ROUND_UP, _clk_num, \
periph_clk_enb_refcnt, 0, _clk_id) 0, _clk_id)
#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
_mux_shift, _mux_width, _clk_num, \ _mux_shift, _mux_width, _clk_num, \
_gate_flags, _clk_id) \ _gate_flags, _clk_id) \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
_mux_shift, _mux_width, 0, 0, 0, 0, 0,\ _mux_shift, _mux_width, 0, 0, 0, 0, 0,\
_clk_num, periph_clk_enb_refcnt, _gate_flags, \ _clk_num, _gate_flags, \
_clk_id) _clk_id)
/* /*
...@@ -318,8 +314,7 @@ enum tegra30_clk { ...@@ -318,8 +314,7 @@ enum tegra30_clk {
hclk, pclk, clk_out_1_mux = 300, clk_max hclk, pclk, clk_out_1_mux = 300, clk_max
}; };
static struct clk *clks[clk_max]; static struct clk **clks;
static struct clk_onecell_data clk_data;
/* /*
* Structure defining the fields for USB UTMI clocks Parameters. * Structure defining the fields for USB UTMI clocks Parameters.
...@@ -1432,7 +1427,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { ...@@ -1432,7 +1427,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1), TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1),
TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2), TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2),
TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3), TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3),
TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, 0, pwm), TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, 0, pwm),
}; };
static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
...@@ -1899,7 +1894,6 @@ static const struct of_device_id pmc_match[] __initconst = { ...@@ -1899,7 +1894,6 @@ static const struct of_device_id pmc_match[] __initconst = {
static void __init tegra30_clock_init(struct device_node *np) static void __init tegra30_clock_init(struct device_node *np)
{ {
struct device_node *node; struct device_node *node;
int i;
clk_base = of_iomap(np, 0); clk_base = of_iomap(np, 0);
if (!clk_base) { if (!clk_base) {
...@@ -1919,7 +1913,8 @@ static void __init tegra30_clock_init(struct device_node *np) ...@@ -1919,7 +1913,8 @@ static void __init tegra30_clock_init(struct device_node *np)
BUG(); BUG();
} }
if (tegra_clk_set_periph_banks(TEGRA30_CLK_PERIPH_BANKS) < 0) clks = tegra_clk_init(clk_max, TEGRA30_CLK_PERIPH_BANKS);
if (!clks)
return; return;
tegra30_osc_clk_init(); tegra30_osc_clk_init();
...@@ -1930,21 +1925,9 @@ static void __init tegra30_clock_init(struct device_node *np) ...@@ -1930,21 +1925,9 @@ static void __init tegra30_clock_init(struct device_node *np)
tegra30_audio_clk_init(); tegra30_audio_clk_init();
tegra30_pmc_clk_init(); tegra30_pmc_clk_init();
for (i = 0; i < ARRAY_SIZE(clks); i++) {
if (IS_ERR(clks[i])) {
pr_err("Tegra30 clk %d: register failed with %ld\n",
i, PTR_ERR(clks[i]));
BUG();
}
if (!clks[i])
clks[i] = ERR_PTR(-EINVAL);
}
tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
clk_data.clks = clks; tegra_add_of_provider(np);
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
tegra_clk_apply_init_table = tegra30_clock_apply_init_table; tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
......
...@@ -62,7 +62,11 @@ ...@@ -62,7 +62,11 @@
static struct tegra_cpu_car_ops dummy_car_ops; static struct tegra_cpu_car_ops dummy_car_ops;
struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
int *periph_clk_enb_refcnt;
static int periph_banks; static int periph_banks;
static struct clk **clks;
static int clk_num;
static struct clk_onecell_data clk_data;
static struct tegra_clk_periph_regs periph_regs[] = { static struct tegra_clk_periph_regs periph_regs[] = {
[0] = { [0] = {
...@@ -119,14 +123,25 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid) ...@@ -119,14 +123,25 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid)
} }
} }
int __init tegra_clk_set_periph_banks(int num) struct clk ** __init tegra_clk_init(int num, int banks)
{ {
if (num > ARRAY_SIZE(periph_regs)) if (WARN_ON(banks > ARRAY_SIZE(periph_regs)))
return -EINVAL; return NULL;
periph_clk_enb_refcnt = kzalloc(32 * banks *
sizeof(*periph_clk_enb_refcnt), GFP_KERNEL);
if (!periph_clk_enb_refcnt)
return NULL;
periph_banks = num; periph_banks = banks;
return 0; clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL);
if (!clks)
kfree(periph_clk_enb_refcnt);
clk_num = num;
return clks;
} }
void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
...@@ -178,6 +193,25 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, ...@@ -178,6 +193,25 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
} }
} }
void __init tegra_add_of_provider(struct device_node *np)
{
int i;
for (i = 0; i < clk_num; i++) {
if (IS_ERR(clks[i])) {
pr_err
("Tegra clk %d: register failed with %ld\n",
i, PTR_ERR(clks[i]));
}
if (!clks[i])
clks[i] = ERR_PTR(-EINVAL);
}
clk_data.clks = clks;
clk_data.clk_num = clk_num;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
tegra_clk_apply_init_table_func tegra_clk_apply_init_table; tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
void __init tegra_clocks_apply_init_table(void) void __init tegra_clocks_apply_init_table(void)
......
...@@ -37,6 +37,8 @@ struct tegra_clk_sync_source { ...@@ -37,6 +37,8 @@ struct tegra_clk_sync_source {
container_of(_hw, struct tegra_clk_sync_source, hw) container_of(_hw, struct tegra_clk_sync_source, hw)
extern const struct clk_ops tegra_clk_sync_source_ops; extern const struct clk_ops tegra_clk_sync_source_ops;
extern int *periph_clk_enb_refcnt;
struct clk *tegra_clk_register_sync_source(const char *name, struct clk *tegra_clk_register_sync_source(const char *name,
unsigned long fixed_rate, unsigned long max_rate); unsigned long fixed_rate, unsigned long max_rate);
...@@ -442,7 +444,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, ...@@ -442,7 +444,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
_div_shift, _div_width, _div_frac_width, \ _div_shift, _div_width, _div_frac_width, \
_div_flags, _clk_num, _enb_refcnt, \ _div_flags, _clk_num,\
_gate_flags, _table) \ _gate_flags, _table) \
{ \ { \
.mux = { \ .mux = { \
...@@ -460,7 +462,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, ...@@ -460,7 +462,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
.gate = { \ .gate = { \
.flags = _gate_flags, \ .flags = _gate_flags, \
.clk_num = _clk_num, \ .clk_num = _clk_num, \
.enable_refcnt = _enb_refcnt, \
}, \ }, \
.mux_ops = &clk_mux_ops, \ .mux_ops = &clk_mux_ops, \
.div_ops = &tegra_clk_frac_div_ops, \ .div_ops = &tegra_clk_frac_div_ops, \
...@@ -482,7 +483,7 @@ struct tegra_periph_init_data { ...@@ -482,7 +483,7 @@ struct tegra_periph_init_data {
#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
_mux_shift, _mux_mask, _mux_flags, _div_shift, \ _mux_shift, _mux_mask, _mux_flags, _div_shift, \
_div_width, _div_frac_width, _div_flags, \ _div_width, _div_frac_width, _div_flags, \
_clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ _clk_num, _gate_flags, _clk_id, _table, \
_flags) \ _flags) \
{ \ { \
.name = _name, \ .name = _name, \
...@@ -493,7 +494,6 @@ struct tegra_periph_init_data { ...@@ -493,7 +494,6 @@ struct tegra_periph_init_data {
_mux_flags, _div_shift, \ _mux_flags, _div_shift, \
_div_width, _div_frac_width, \ _div_width, _div_frac_width, \
_div_flags, _clk_num, \ _div_flags, _clk_num, \
_enb_refcnt, \
_gate_flags, _table), \ _gate_flags, _table), \
.offset = _offset, \ .offset = _offset, \
.con_id = _con_id, \ .con_id = _con_id, \
...@@ -504,11 +504,11 @@ struct tegra_periph_init_data { ...@@ -504,11 +504,11 @@ struct tegra_periph_init_data {
#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
_mux_shift, _mux_width, _mux_flags, _div_shift, \ _mux_shift, _mux_width, _mux_flags, _div_shift, \
_div_width, _div_frac_width, _div_flags, \ _div_width, _div_frac_width, _div_flags, \
_clk_num, _enb_refcnt, _gate_flags, _clk_id) \ _clk_num, _gate_flags, _clk_id) \
TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
_mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
_div_shift, _div_width, _div_frac_width, _div_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \
_clk_num, _enb_refcnt, _gate_flags, _clk_id,\ _clk_num, _gate_flags, _clk_id,\
NULL, 0) NULL, 0)
/** /**
...@@ -586,7 +586,9 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, ...@@ -586,7 +586,9 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
struct clk *clks[], int clk_max); struct clk *clks[], int clk_max);
struct tegra_clk_periph_regs *get_reg_bank(int clkid); struct tegra_clk_periph_regs *get_reg_bank(int clkid);
int tegra_clk_set_periph_banks(int num); struct clk **tegra_clk_init(int num, int periph_banks);
void tegra_add_of_provider(struct device_node *np);
void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_high(void);
void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_low(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment