aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2013-09-02 08:22:02 -0400
committerPeter De Schrijver <pdeschrijver@nvidia.com>2013-11-26 11:46:18 -0500
commit343a607cb79259429afbb9820bf524d33084e66c (patch)
tree508757a525821d7aad6c6d24caa72447c95907bf
parentd5ff89a82a6d272d210db68a9487877682c94a24 (diff)
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: Peter De Schrijver <pdeschrijver@nvidia.com>
-rw-r--r--drivers/clk/tegra/clk-periph.c1
-rw-r--r--drivers/clk/tegra/clk-tegra114.c57
-rw-r--r--drivers/clk/tegra/clk-tegra20.c36
-rw-r--r--drivers/clk/tegra/clk-tegra30.c39
-rw-r--r--drivers/clk/tegra/clk.c44
-rw-r--r--drivers/clk/tegra/clk.h16
6 files changed, 85 insertions, 108 deletions
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 735b0243261c..5102d5e58c04 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -197,6 +197,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
197 periph->divider.reg = div ? (clk_base + offset) : NULL; 197 periph->divider.reg = div ? (clk_base + offset) : NULL;
198 periph->gate.clk_base = clk_base; 198 periph->gate.clk_base = clk_base;
199 periph->gate.regs = bank; 199 periph->gate.regs = bank;
200 periph->gate.enable_refcnt = periph_clk_enb_refcnt;
200 201
201 clk = clk_register(NULL, &periph->hw); 202 clk = clk_register(NULL, &periph->hw);
202 if (IS_ERR(clk)) 203 if (IS_ERR(clk))
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 8507067d5dd6..9729af823eaf 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -57,8 +57,6 @@
57#define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ 57#define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */
58#define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) 58#define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT)
59 59
60#define CLK_OUT_ENB_NUM 6
61
62#define TEGRA114_CLK_PERIPH_BANKS 5 60#define TEGRA114_CLK_PERIPH_BANKS 5
63 61
64#define PLLC_BASE 0x80 62#define PLLC_BASE 0x80
@@ -266,8 +264,6 @@ static struct cpu_clk_suspend_context {
266} tegra114_cpu_clk_sctx; 264} tegra114_cpu_clk_sctx;
267#endif 265#endif
268 266
269static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
270
271static void __iomem *clk_base; 267static void __iomem *clk_base;
272static void __iomem *pmc_base; 268static void __iomem *pmc_base;
273 269
@@ -712,59 +708,53 @@ static unsigned long tegra114_input_freq[] = {
712 _clk_num, _gate_flags, _clk_id) \ 708 _clk_num, _gate_flags, _clk_id) \
713 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 709 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
714 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 710 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
715 _clk_num, periph_clk_enb_refcnt, _gate_flags,\ 711 _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
716 _clk_id, _parents##_idx, 0)
717 712
718#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ 713#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
719 _clk_num, _gate_flags, _clk_id, flags)\ 714 _clk_num, _gate_flags, _clk_id, flags)\
720 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 715 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
721 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ 716 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
722 _clk_num, periph_clk_enb_refcnt, _gate_flags,\ 717 _clk_num, _gate_flags, _clk_id, _parents##_idx, flags)
723 _clk_id, _parents##_idx, flags)
724 718
725#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ 719#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
726 _clk_num, _gate_flags, _clk_id) \ 720 _clk_num, _gate_flags, _clk_id) \
727 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 721 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
728 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ 722 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
729 _clk_num, periph_clk_enb_refcnt, _gate_flags,\ 723 _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
730 _clk_id, _parents##_idx, 0)
731 724
732#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ 725#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
733 _clk_num, _gate_flags, _clk_id, flags)\ 726 _clk_num, _gate_flags, _clk_id, flags)\
734 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 727 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
735 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 728 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
736 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 729 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
737 periph_clk_enb_refcnt, _gate_flags, _clk_id, \ 730 _gate_flags, _clk_id, _parents##_idx, flags)
738 _parents##_idx, flags)
739 731
740#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ 732#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\
741 _clk_num, _gate_flags, _clk_id) \ 733 _clk_num, _gate_flags, _clk_id) \
742 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 734 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
743 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 735 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
744 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 736 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
745 periph_clk_enb_refcnt, _gate_flags, _clk_id, \ 737 _gate_flags, _clk_id, _parents##_idx, 0)
746 _parents##_idx, 0)
747 738
748#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ 739#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
749 _clk_num, _clk_id) \ 740 _clk_num, _clk_id) \
750 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 741 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
751 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ 742 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART | \
752 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 743 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
753 periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) 744 0, _clk_id, _parents##_idx, 0)
754 745
755#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ 746#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\
756 _clk_num, _clk_id) \ 747 _clk_num, _clk_id) \
757 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 748 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
758 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ 749 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\
759 _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\ 750 _clk_num, 0, _clk_id, _parents##_idx, 0)
760 _parents##_idx, 0)
761 751
762#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ 752#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
763 _mux_shift, _mux_mask, _clk_num, \ 753 _mux_shift, _mux_mask, _clk_num, \
764 _gate_flags, _clk_id) \ 754 _gate_flags, _clk_id) \
765 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ 755 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
766 _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ 756 _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\
767 _clk_num, periph_clk_enb_refcnt, _gate_flags, \ 757 _clk_num, _gate_flags, \
768 _clk_id, _parents##_idx, 0) 758 _clk_id, _parents##_idx, 0)
769 759
770#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ 760#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \
@@ -772,16 +762,14 @@ static unsigned long tegra114_input_freq[] = {
772 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ 762 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \
773 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 763 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
774 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 764 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
775 periph_clk_enb_refcnt, _gate_flags, _clk_id, \ 765 _gate_flags, _clk_id, _parents##_idx, 0)
776 _parents##_idx, 0)
777 766
778#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ 767#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\
779 _gate_flags, _clk_id) \ 768 _gate_flags, _clk_id) \
780 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ 769 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \
781 _offset, 16, 0xE01F, 0, 0, 8, 1, \ 770 _offset, 16, 0xE01F, 0, 0, 8, 1, \
782 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 771 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
783 periph_clk_enb_refcnt, _gate_flags , _clk_id, \ 772 _gate_flags , _clk_id, mux_d_audio_clk_idx, 0)
784 mux_d_audio_clk_idx, 0)
785 773
786struct utmi_clk_param { 774struct utmi_clk_param {
787 /* Oscillator Frequency in KHz */ 775 /* Oscillator Frequency in KHz */
@@ -946,8 +934,7 @@ static const struct clk_div_table pll_re_div_table[] = {
946 { .val = 0, .div = 0 }, 934 { .val = 0, .div = 0 },
947}; 935};
948 936
949static struct clk *clks[TEGRA114_CLK_CLK_MAX]; 937static struct clk **clks;
950static struct clk_onecell_data clk_data;
951 938
952static unsigned long osc_freq; 939static unsigned long osc_freq;
953static unsigned long pll_ref_freq; 940static unsigned long pll_ref_freq;
@@ -2229,7 +2216,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
2229static void __init tegra114_clock_init(struct device_node *np) 2216static void __init tegra114_clock_init(struct device_node *np)
2230{ 2217{
2231 struct device_node *node; 2218 struct device_node *node;
2232 int i;
2233 2219
2234 clk_base = of_iomap(np, 0); 2220 clk_base = of_iomap(np, 0);
2235 if (!clk_base) { 2221 if (!clk_base) {
@@ -2251,10 +2237,11 @@ static void __init tegra114_clock_init(struct device_node *np)
2251 return; 2237 return;
2252 } 2238 }
2253 2239
2254 if (tegra114_osc_clk_init(clk_base) < 0) 2240 clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS);
2241 if (!clks)
2255 return; 2242 return;
2256 2243
2257 if (tegra_clk_set_periph_banks(TEGRA114_CLK_PERIPH_BANKS) < 0) 2244 if (tegra114_osc_clk_init(clk_base) < 0)
2258 return; 2245 return;
2259 2246
2260 tegra114_fixed_clk_init(clk_base); 2247 tegra114_fixed_clk_init(clk_base);
@@ -2264,19 +2251,7 @@ static void __init tegra114_clock_init(struct device_node *np)
2264 tegra114_pmc_clk_init(pmc_base); 2251 tegra114_pmc_clk_init(pmc_base);
2265 tegra114_super_clk_init(clk_base); 2252 tegra114_super_clk_init(clk_base);
2266 2253
2267 for (i = 0; i < ARRAY_SIZE(clks); i++) { 2254 tegra_add_of_provider(np);
2268 if (IS_ERR(clks[i])) {
2269 pr_err
2270 ("Tegra114 clk %d: register failed with %ld\n",
2271 i, PTR_ERR(clks[i]));
2272 }
2273 if (!clks[i])
2274 clks[i] = ERR_PTR(-EINVAL);
2275 }
2276
2277 clk_data.clks = clks;
2278 clk_data.clk_num = ARRAY_SIZE(clks);
2279 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
2280 2255
2281 tegra_clk_apply_init_table = tegra114_clock_apply_init_table; 2256 tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
2282 2257
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 929a46278d83..6bf5c339ab43 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -25,8 +25,6 @@
25 25
26#include "clk.h" 26#include "clk.h"
27 27
28#define CLK_OUT_ENB_NUM 3
29
30#define OSC_CTRL 0x50 28#define OSC_CTRL 0x50
31#define OSC_CTRL_OSC_FREQ_MASK (3<<30) 29#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
32#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) 30#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
@@ -170,8 +168,6 @@ static struct cpu_clk_suspend_context {
170} tegra20_cpu_clk_sctx; 168} tegra20_cpu_clk_sctx;
171#endif 169#endif
172 170
173static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
174
175static void __iomem *clk_base; 171static void __iomem *clk_base;
176static void __iomem *pmc_base; 172static void __iomem *pmc_base;
177 173
@@ -182,21 +178,21 @@ static DEFINE_SPINLOCK(sysrate_lock);
182 _clk_num, _gate_flags, _clk_id) \ 178 _clk_num, _gate_flags, _clk_id) \
183 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 179 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
184 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 180 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
185 _clk_num, periph_clk_enb_refcnt, \ 181 _clk_num, \
186 _gate_flags, _clk_id) 182 _gate_flags, _clk_id)
187 183
188#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ 184#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
189 _clk_num, _gate_flags, _clk_id) \ 185 _clk_num, _gate_flags, _clk_id) \
190 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 186 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
191 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \ 187 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \
192 _clk_num, periph_clk_enb_refcnt, _gate_flags, \ 188 _clk_num, _gate_flags, \
193 _clk_id) 189 _clk_id)
194 190
195#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ 191#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
196 _clk_num, _gate_flags, _clk_id) \ 192 _clk_num, _gate_flags, _clk_id) \
197 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 193 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
198 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ 194 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
199 _clk_num, periph_clk_enb_refcnt, _gate_flags, \ 195 _clk_num, _gate_flags, \
200 _clk_id) 196 _clk_id)
201 197
202#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ 198#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
@@ -204,7 +200,7 @@ static DEFINE_SPINLOCK(sysrate_lock);
204 _gate_flags, _clk_id) \ 200 _gate_flags, _clk_id) \
205 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 201 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
206 _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ 202 _mux_shift, _mux_width, 0, 0, 0, 0, 0, \
207 _clk_num, periph_clk_enb_refcnt, _gate_flags, \ 203 _clk_num, _gate_flags, \
208 _clk_id) 204 _clk_id)
209 205
210/* IDs assigned here must be in sync with DT bindings definition 206/* IDs assigned here must be in sync with DT bindings definition
@@ -226,8 +222,7 @@ enum tegra20_clk {
226 pll_x, cop, audio, pll_ref, twd, clk_max, 222 pll_x, cop, audio, pll_ref, twd, clk_max,
227}; 223};
228 224
229static struct clk *clks[clk_max]; 225static struct clk **clks;
230static struct clk_onecell_data clk_data;
231 226
232static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { 227static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
233 { 12000000, 600000000, 600, 12, 0, 8 }, 228 { 12000000, 600000000, 600, 12, 0, 8 },
@@ -808,7 +803,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
808 TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3), 803 TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, i2c3),
809 TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc), 804 TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, dvc),
810 TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi), 805 TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, hdmi),
811 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), 806 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),
812}; 807};
813 808
814static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { 809static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
@@ -1232,7 +1227,6 @@ static const struct of_device_id pmc_match[] __initconst = {
1232 1227
1233static void __init tegra20_clock_init(struct device_node *np) 1228static void __init tegra20_clock_init(struct device_node *np)
1234{ 1229{
1235 int i;
1236 struct device_node *node; 1230 struct device_node *node;
1237 1231
1238 clk_base = of_iomap(np, 0); 1232 clk_base = of_iomap(np, 0);
@@ -1253,7 +1247,8 @@ static void __init tegra20_clock_init(struct device_node *np)
1253 BUG(); 1247 BUG();
1254 } 1248 }
1255 1249
1256 if (tegra_clk_set_periph_banks(TEGRA20_CLK_PERIPH_BANKS) < 0) 1250 clks = tegra_clk_init(clk_max, TEGRA20_CLK_PERIPH_BANKS);
1251 if (!clks)
1257 return; 1252 return;
1258 1253
1259 tegra20_osc_clk_init(); 1254 tegra20_osc_clk_init();
@@ -1264,22 +1259,9 @@ static void __init tegra20_clock_init(struct device_node *np)
1264 tegra20_periph_clk_init(); 1259 tegra20_periph_clk_init();
1265 tegra20_audio_clk_init(); 1260 tegra20_audio_clk_init();
1266 1261
1267
1268 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1269 if (IS_ERR(clks[i])) {
1270 pr_err("Tegra20 clk %d: register failed with %ld\n",
1271 i, PTR_ERR(clks[i]));
1272 BUG();
1273 }
1274 if (!clks[i])
1275 clks[i] = ERR_PTR(-EINVAL);
1276 }
1277
1278 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); 1262 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
1279 1263
1280 clk_data.clks = clks; 1264 tegra_add_of_provider(np);
1281 clk_data.clk_num = ARRAY_SIZE(clks);
1282 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1283 1265
1284 tegra_clk_apply_init_table = tegra20_clock_apply_init_table; 1266 tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
1285 1267
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index a66bdabb5c5c..c5db42217ba8 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -26,8 +26,6 @@
26 26
27#include "clk.h" 27#include "clk.h"
28 28
29#define CLK_OUT_ENB_NUM 5
30
31#define OSC_CTRL 0x50 29#define OSC_CTRL 0x50
32#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) 30#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
33#define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28) 31#define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28)
@@ -236,8 +234,6 @@ static struct cpu_clk_suspend_context {
236} tegra30_cpu_clk_sctx; 234} tegra30_cpu_clk_sctx;
237#endif 235#endif
238 236
239static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
240
241static void __iomem *clk_base; 237static void __iomem *clk_base;
242static void __iomem *pmc_base; 238static void __iomem *pmc_base;
243static unsigned long input_freq; 239static unsigned long input_freq;
@@ -253,41 +249,41 @@ static DEFINE_SPINLOCK(sysrate_lock);
253 _clk_num, _gate_flags, _clk_id) \ 249 _clk_num, _gate_flags, _clk_id) \
254 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 250 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
255 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 251 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
256 _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) 252 _clk_num, _gate_flags, _clk_id)
257 253
258#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ 254#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
259 _clk_num, _gate_flags, _clk_id) \ 255 _clk_num, _gate_flags, _clk_id) \
260 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 256 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
261 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ 257 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
262 _clk_num, periph_clk_enb_refcnt, \ 258 _clk_num, \
263 _gate_flags, _clk_id) 259 _gate_flags, _clk_id)
264 260
265#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ 261#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
266 _clk_num, _gate_flags, _clk_id) \ 262 _clk_num, _gate_flags, _clk_id) \
267 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 263 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
268 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ 264 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
269 _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id) 265 _clk_num, _gate_flags, _clk_id)
270 266
271#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ 267#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
272 _clk_num, _gate_flags, _clk_id) \ 268 _clk_num, _gate_flags, _clk_id) \
273 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 269 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
274 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ 270 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \
275 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 271 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
276 periph_clk_enb_refcnt, _gate_flags, _clk_id) 272 _gate_flags, _clk_id)
277 273
278#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ 274#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
279 _clk_num, _clk_id) \ 275 _clk_num, _clk_id) \
280 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 276 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
281 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \ 277 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART | \
282 TEGRA_DIVIDER_ROUND_UP, _clk_num, \ 278 TEGRA_DIVIDER_ROUND_UP, _clk_num, \
283 periph_clk_enb_refcnt, 0, _clk_id) 279 0, _clk_id)
284 280
285#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ 281#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
286 _mux_shift, _mux_width, _clk_num, \ 282 _mux_shift, _mux_width, _clk_num, \
287 _gate_flags, _clk_id) \ 283 _gate_flags, _clk_id) \
288 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ 284 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
289 _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ 285 _mux_shift, _mux_width, 0, 0, 0, 0, 0,\
290 _clk_num, periph_clk_enb_refcnt, _gate_flags, \ 286 _clk_num, _gate_flags, \
291 _clk_id) 287 _clk_id)
292 288
293/* 289/*
@@ -318,8 +314,7 @@ enum tegra30_clk {
318 hclk, pclk, clk_out_1_mux = 300, clk_max 314 hclk, pclk, clk_out_1_mux = 300, clk_max
319}; 315};
320 316
321static struct clk *clks[clk_max]; 317static struct clk **clks;
322static struct clk_onecell_data clk_data;
323 318
324/* 319/*
325 * Structure defining the fields for USB UTMI clocks Parameters. 320 * Structure defining the fields for USB UTMI clocks Parameters.
@@ -1432,7 +1427,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
1432 TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1), 1427 TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, extern1),
1433 TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2), 1428 TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, extern2),
1434 TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3), 1429 TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, extern3),
1435 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), 1430 TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, 0, pwm),
1436}; 1431};
1437 1432
1438static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { 1433static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
@@ -1899,7 +1894,6 @@ static const struct of_device_id pmc_match[] __initconst = {
1899static void __init tegra30_clock_init(struct device_node *np) 1894static void __init tegra30_clock_init(struct device_node *np)
1900{ 1895{
1901 struct device_node *node; 1896 struct device_node *node;
1902 int i;
1903 1897
1904 clk_base = of_iomap(np, 0); 1898 clk_base = of_iomap(np, 0);
1905 if (!clk_base) { 1899 if (!clk_base) {
@@ -1919,7 +1913,8 @@ static void __init tegra30_clock_init(struct device_node *np)
1919 BUG(); 1913 BUG();
1920 } 1914 }
1921 1915
1922 if (tegra_clk_set_periph_banks(TEGRA30_CLK_PERIPH_BANKS) < 0) 1916 clks = tegra_clk_init(clk_max, TEGRA30_CLK_PERIPH_BANKS);
1917 if (!clks)
1923 return; 1918 return;
1924 1919
1925 tegra30_osc_clk_init(); 1920 tegra30_osc_clk_init();
@@ -1930,21 +1925,9 @@ static void __init tegra30_clock_init(struct device_node *np)
1930 tegra30_audio_clk_init(); 1925 tegra30_audio_clk_init();
1931 tegra30_pmc_clk_init(); 1926 tegra30_pmc_clk_init();
1932 1927
1933 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1934 if (IS_ERR(clks[i])) {
1935 pr_err("Tegra30 clk %d: register failed with %ld\n",
1936 i, PTR_ERR(clks[i]));
1937 BUG();
1938 }
1939 if (!clks[i])
1940 clks[i] = ERR_PTR(-EINVAL);
1941 }
1942
1943 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); 1928 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
1944 1929
1945 clk_data.clks = clks; 1930 tegra_add_of_provider(np);
1946 clk_data.clk_num = ARRAY_SIZE(clks);
1947 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1948 1931
1949 tegra_clk_apply_init_table = tegra30_clock_apply_init_table; 1932 tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
1950 1933
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 07f76df2583b..3a95a8757ebc 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -62,7 +62,11 @@
62static struct tegra_cpu_car_ops dummy_car_ops; 62static struct tegra_cpu_car_ops dummy_car_ops;
63struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; 63struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
64 64
65int *periph_clk_enb_refcnt;
65static int periph_banks; 66static int periph_banks;
67static struct clk **clks;
68static int clk_num;
69static struct clk_onecell_data clk_data;
66 70
67static struct tegra_clk_periph_regs periph_regs[] = { 71static struct tegra_clk_periph_regs periph_regs[] = {
68 [0] = { 72 [0] = {
@@ -119,14 +123,25 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid)
119 } 123 }
120} 124}
121 125
122int __init tegra_clk_set_periph_banks(int num) 126struct clk ** __init tegra_clk_init(int num, int banks)
123{ 127{
124 if (num > ARRAY_SIZE(periph_regs)) 128 if (WARN_ON(banks > ARRAY_SIZE(periph_regs)))
125 return -EINVAL; 129 return NULL;
130
131 periph_clk_enb_refcnt = kzalloc(32 * banks *
132 sizeof(*periph_clk_enb_refcnt), GFP_KERNEL);
133 if (!periph_clk_enb_refcnt)
134 return NULL;
126 135
127 periph_banks = num; 136 periph_banks = banks;
128 137
129 return 0; 138 clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL);
139 if (!clks)
140 kfree(periph_clk_enb_refcnt);
141
142 clk_num = num;
143
144 return clks;
130} 145}
131 146
132void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, 147void __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 } 193 }
179} 194}
180 195
196void __init tegra_add_of_provider(struct device_node *np)
197{
198 int i;
199
200 for (i = 0; i < clk_num; i++) {
201 if (IS_ERR(clks[i])) {
202 pr_err
203 ("Tegra clk %d: register failed with %ld\n",
204 i, PTR_ERR(clks[i]));
205 }
206 if (!clks[i])
207 clks[i] = ERR_PTR(-EINVAL);
208 }
209
210 clk_data.clks = clks;
211 clk_data.clk_num = clk_num;
212 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
213}
214
181tegra_clk_apply_init_table_func tegra_clk_apply_init_table; 215tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
182 216
183void __init tegra_clocks_apply_init_table(void) 217void __init tegra_clocks_apply_init_table(void)
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 730d37b39488..997357ef059e 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -37,6 +37,8 @@ struct tegra_clk_sync_source {
37 container_of(_hw, struct tegra_clk_sync_source, hw) 37 container_of(_hw, struct tegra_clk_sync_source, hw)
38 38
39extern const struct clk_ops tegra_clk_sync_source_ops; 39extern const struct clk_ops tegra_clk_sync_source_ops;
40extern int *periph_clk_enb_refcnt;
41
40struct clk *tegra_clk_register_sync_source(const char *name, 42struct clk *tegra_clk_register_sync_source(const char *name,
41 unsigned long fixed_rate, unsigned long max_rate); 43 unsigned long fixed_rate, unsigned long max_rate);
42 44
@@ -442,7 +444,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
442 444
443#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ 445#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
444 _div_shift, _div_width, _div_frac_width, \ 446 _div_shift, _div_width, _div_frac_width, \
445 _div_flags, _clk_num, _enb_refcnt, \ 447 _div_flags, _clk_num,\
446 _gate_flags, _table) \ 448 _gate_flags, _table) \
447 { \ 449 { \
448 .mux = { \ 450 .mux = { \
@@ -460,7 +462,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
460 .gate = { \ 462 .gate = { \
461 .flags = _gate_flags, \ 463 .flags = _gate_flags, \
462 .clk_num = _clk_num, \ 464 .clk_num = _clk_num, \
463 .enable_refcnt = _enb_refcnt, \
464 }, \ 465 }, \
465 .mux_ops = &clk_mux_ops, \ 466 .mux_ops = &clk_mux_ops, \
466 .div_ops = &tegra_clk_frac_div_ops, \ 467 .div_ops = &tegra_clk_frac_div_ops, \
@@ -482,7 +483,7 @@ struct tegra_periph_init_data {
482#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ 483#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
483 _mux_shift, _mux_mask, _mux_flags, _div_shift, \ 484 _mux_shift, _mux_mask, _mux_flags, _div_shift, \
484 _div_width, _div_frac_width, _div_flags, \ 485 _div_width, _div_frac_width, _div_flags, \
485 _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ 486 _clk_num, _gate_flags, _clk_id, _table, \
486 _flags) \ 487 _flags) \
487 { \ 488 { \
488 .name = _name, \ 489 .name = _name, \
@@ -493,7 +494,6 @@ struct tegra_periph_init_data {
493 _mux_flags, _div_shift, \ 494 _mux_flags, _div_shift, \
494 _div_width, _div_frac_width, \ 495 _div_width, _div_frac_width, \
495 _div_flags, _clk_num, \ 496 _div_flags, _clk_num, \
496 _enb_refcnt, \
497 _gate_flags, _table), \ 497 _gate_flags, _table), \
498 .offset = _offset, \ 498 .offset = _offset, \
499 .con_id = _con_id, \ 499 .con_id = _con_id, \
@@ -504,11 +504,11 @@ struct tegra_periph_init_data {
504#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ 504#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
505 _mux_shift, _mux_width, _mux_flags, _div_shift, \ 505 _mux_shift, _mux_width, _mux_flags, _div_shift, \
506 _div_width, _div_frac_width, _div_flags, \ 506 _div_width, _div_frac_width, _div_flags, \
507 _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ 507 _clk_num, _gate_flags, _clk_id) \
508 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ 508 TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
509 _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ 509 _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
510 _div_shift, _div_width, _div_frac_width, _div_flags, \ 510 _div_shift, _div_width, _div_frac_width, _div_flags, \
511 _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ 511 _clk_num, _gate_flags, _clk_id,\
512 NULL, 0) 512 NULL, 0)
513 513
514/** 514/**
@@ -586,7 +586,9 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
586 struct clk *clks[], int clk_max); 586 struct clk *clks[], int clk_max);
587 587
588struct tegra_clk_periph_regs *get_reg_bank(int clkid); 588struct tegra_clk_periph_regs *get_reg_bank(int clkid);
589int tegra_clk_set_periph_banks(int num); 589struct clk **tegra_clk_init(int num, int periph_banks);
590
591void tegra_add_of_provider(struct device_node *np);
590 592
591void tegra114_clock_tune_cpu_trimmers_high(void); 593void tegra114_clock_tune_cpu_trimmers_high(void);
592void tegra114_clock_tune_cpu_trimmers_low(void); 594void tegra114_clock_tune_cpu_trimmers_low(void);