aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/tegra/clk-tegra20.c
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 /drivers/clk/tegra/clk-tegra20.c
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>
Diffstat (limited to 'drivers/clk/tegra/clk-tegra20.c')
-rw-r--r--drivers/clk/tegra/clk-tegra20.c36
1 files changed, 9 insertions, 27 deletions
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