Commit | Line | Data |
---|---|---|
8f8f484b | 1 | /* |
dba4072a | 2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. |
8f8f484b PG |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms and conditions of the GNU General Public License, | |
6 | * version 2, as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope it will be useful, but WITHOUT | |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
11 | * more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | */ | |
16 | ||
17 | #include <linux/slab.h> | |
18 | #include <linux/io.h> | |
19 | #include <linux/delay.h> | |
20 | #include <linux/err.h> | |
21 | #include <linux/clk-provider.h> | |
22 | #include <linux/clk.h> | |
23 | ||
24 | #include "clk.h" | |
25 | ||
26 | #define PLL_BASE_BYPASS BIT(31) | |
27 | #define PLL_BASE_ENABLE BIT(30) | |
28 | #define PLL_BASE_REF_ENABLE BIT(29) | |
29 | #define PLL_BASE_OVERRIDE BIT(28) | |
30 | ||
31 | #define PLL_BASE_DIVP_SHIFT 20 | |
32 | #define PLL_BASE_DIVP_WIDTH 3 | |
33 | #define PLL_BASE_DIVN_SHIFT 8 | |
34 | #define PLL_BASE_DIVN_WIDTH 10 | |
35 | #define PLL_BASE_DIVM_SHIFT 0 | |
36 | #define PLL_BASE_DIVM_WIDTH 5 | |
37 | #define PLLU_POST_DIVP_MASK 0x1 | |
38 | ||
39 | #define PLL_MISC_DCCON_SHIFT 20 | |
40 | #define PLL_MISC_CPCON_SHIFT 8 | |
41 | #define PLL_MISC_CPCON_WIDTH 4 | |
42 | #define PLL_MISC_CPCON_MASK ((1 << PLL_MISC_CPCON_WIDTH) - 1) | |
43 | #define PLL_MISC_LFCON_SHIFT 4 | |
44 | #define PLL_MISC_LFCON_WIDTH 4 | |
45 | #define PLL_MISC_LFCON_MASK ((1 << PLL_MISC_LFCON_WIDTH) - 1) | |
46 | #define PLL_MISC_VCOCON_SHIFT 0 | |
47 | #define PLL_MISC_VCOCON_WIDTH 4 | |
48 | #define PLL_MISC_VCOCON_MASK ((1 << PLL_MISC_VCOCON_WIDTH) - 1) | |
49 | ||
50 | #define OUT_OF_TABLE_CPCON 8 | |
51 | ||
52 | #define PMC_PLLP_WB0_OVERRIDE 0xf8 | |
53 | #define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12) | |
54 | #define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11) | |
55 | ||
56 | #define PLL_POST_LOCK_DELAY 50 | |
57 | ||
58 | #define PLLDU_LFCON_SET_DIVN 600 | |
59 | ||
60 | #define PLLE_BASE_DIVCML_SHIFT 24 | |
61 | #define PLLE_BASE_DIVCML_WIDTH 4 | |
62 | #define PLLE_BASE_DIVP_SHIFT 16 | |
63 | #define PLLE_BASE_DIVP_WIDTH 7 | |
64 | #define PLLE_BASE_DIVN_SHIFT 8 | |
65 | #define PLLE_BASE_DIVN_WIDTH 8 | |
66 | #define PLLE_BASE_DIVM_SHIFT 0 | |
67 | #define PLLE_BASE_DIVM_WIDTH 8 | |
68 | ||
69 | #define PLLE_MISC_SETUP_BASE_SHIFT 16 | |
70 | #define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT) | |
71 | #define PLLE_MISC_LOCK_ENABLE BIT(9) | |
72 | #define PLLE_MISC_READY BIT(15) | |
73 | #define PLLE_MISC_SETUP_EX_SHIFT 2 | |
74 | #define PLLE_MISC_SETUP_EX_MASK (3 << PLLE_MISC_SETUP_EX_SHIFT) | |
75 | #define PLLE_MISC_SETUP_MASK (PLLE_MISC_SETUP_BASE_MASK | \ | |
76 | PLLE_MISC_SETUP_EX_MASK) | |
77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) | |
78 | ||
79 | #define PLLE_SS_CTRL 0x68 | |
80 | #define PLLE_SS_DISABLE (7 << 10) | |
81 | ||
82 | #define PMC_SATA_PWRGT 0x1ac | |
83 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) | |
84 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) | |
85 | ||
86 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) | |
87 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) | |
88 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) | |
89 | ||
90 | #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) | |
91 | #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) | |
92 | #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) | |
93 | ||
94 | #define mask(w) ((1 << (w)) - 1) | |
95 | #define divm_mask(p) mask(p->divm_width) | |
96 | #define divn_mask(p) mask(p->divn_width) | |
97 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ | |
98 | mask(p->divp_width)) | |
99 | ||
100 | #define divm_max(p) (divm_mask(p)) | |
101 | #define divn_max(p) (divn_mask(p)) | |
102 | #define divp_max(p) (1 << (divp_mask(p))) | |
103 | ||
104 | static void clk_pll_enable_lock(struct tegra_clk_pll *pll) | |
105 | { | |
106 | u32 val; | |
107 | ||
108 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) | |
109 | return; | |
110 | ||
111 | val = pll_readl_misc(pll); | |
112 | val |= BIT(pll->params->lock_enable_bit_idx); | |
113 | pll_writel_misc(val, pll); | |
114 | } | |
115 | ||
dba4072a | 116 | static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) |
8f8f484b PG |
117 | { |
118 | int i; | |
dba4072a PDS |
119 | u32 val, lock_bit; |
120 | void __iomem *lock_addr; | |
8f8f484b PG |
121 | |
122 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { | |
123 | udelay(pll->params->lock_delay); | |
124 | return 0; | |
125 | } | |
126 | ||
dba4072a PDS |
127 | lock_addr = pll->clk_base; |
128 | if (pll->flags & TEGRA_PLL_LOCK_MISC) | |
129 | lock_addr += pll->params->misc_reg; | |
130 | else | |
131 | lock_addr += pll->params->base_reg; | |
132 | ||
133 | lock_bit = BIT(pll->params->lock_bit_idx); | |
134 | ||
8f8f484b PG |
135 | for (i = 0; i < pll->params->lock_delay; i++) { |
136 | val = readl_relaxed(lock_addr); | |
dba4072a | 137 | if (val & lock_bit) { |
8f8f484b PG |
138 | udelay(PLL_POST_LOCK_DELAY); |
139 | return 0; | |
140 | } | |
141 | udelay(2); /* timeout = 2 * lock time */ | |
142 | } | |
143 | ||
144 | pr_err("%s: Timed out waiting for pll %s lock\n", __func__, | |
145 | __clk_get_name(pll->hw.clk)); | |
146 | ||
147 | return -1; | |
148 | } | |
149 | ||
150 | static int clk_pll_is_enabled(struct clk_hw *hw) | |
151 | { | |
152 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
153 | u32 val; | |
154 | ||
155 | if (pll->flags & TEGRA_PLLM) { | |
156 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | |
157 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) | |
158 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; | |
159 | } | |
160 | ||
161 | val = pll_readl_base(pll); | |
162 | ||
163 | return val & PLL_BASE_ENABLE ? 1 : 0; | |
164 | } | |
165 | ||
dba4072a | 166 | static void _clk_pll_enable(struct clk_hw *hw) |
8f8f484b PG |
167 | { |
168 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
169 | u32 val; | |
170 | ||
171 | clk_pll_enable_lock(pll); | |
172 | ||
173 | val = pll_readl_base(pll); | |
dd93587b PDS |
174 | if (pll->flags & TEGRA_PLL_BYPASS) |
175 | val &= ~PLL_BASE_BYPASS; | |
8f8f484b PG |
176 | val |= PLL_BASE_ENABLE; |
177 | pll_writel_base(val, pll); | |
178 | ||
179 | if (pll->flags & TEGRA_PLLM) { | |
180 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | |
181 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | |
182 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | |
183 | } | |
8f8f484b PG |
184 | } |
185 | ||
186 | static void _clk_pll_disable(struct clk_hw *hw) | |
187 | { | |
188 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
189 | u32 val; | |
190 | ||
191 | val = pll_readl_base(pll); | |
dd93587b PDS |
192 | if (pll->flags & TEGRA_PLL_BYPASS) |
193 | val &= ~PLL_BASE_BYPASS; | |
194 | val &= ~PLL_BASE_ENABLE; | |
8f8f484b PG |
195 | pll_writel_base(val, pll); |
196 | ||
197 | if (pll->flags & TEGRA_PLLM) { | |
198 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | |
199 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | |
200 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | |
201 | } | |
202 | } | |
203 | ||
204 | static int clk_pll_enable(struct clk_hw *hw) | |
205 | { | |
206 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
207 | unsigned long flags = 0; | |
208 | int ret; | |
209 | ||
210 | if (pll->lock) | |
211 | spin_lock_irqsave(pll->lock, flags); | |
212 | ||
dba4072a PDS |
213 | _clk_pll_enable(hw); |
214 | ||
215 | ret = clk_pll_wait_for_lock(pll); | |
8f8f484b PG |
216 | |
217 | if (pll->lock) | |
218 | spin_unlock_irqrestore(pll->lock, flags); | |
219 | ||
220 | return ret; | |
221 | } | |
222 | ||
223 | static void clk_pll_disable(struct clk_hw *hw) | |
224 | { | |
225 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
226 | unsigned long flags = 0; | |
227 | ||
228 | if (pll->lock) | |
229 | spin_lock_irqsave(pll->lock, flags); | |
230 | ||
231 | _clk_pll_disable(hw); | |
232 | ||
233 | if (pll->lock) | |
234 | spin_unlock_irqrestore(pll->lock, flags); | |
235 | } | |
236 | ||
237 | static int _get_table_rate(struct clk_hw *hw, | |
238 | struct tegra_clk_pll_freq_table *cfg, | |
239 | unsigned long rate, unsigned long parent_rate) | |
240 | { | |
241 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
242 | struct tegra_clk_pll_freq_table *sel; | |
243 | ||
244 | for (sel = pll->freq_table; sel->input_rate != 0; sel++) | |
245 | if (sel->input_rate == parent_rate && | |
246 | sel->output_rate == rate) | |
247 | break; | |
248 | ||
249 | if (sel->input_rate == 0) | |
250 | return -EINVAL; | |
251 | ||
8f8f484b PG |
252 | cfg->input_rate = sel->input_rate; |
253 | cfg->output_rate = sel->output_rate; | |
254 | cfg->m = sel->m; | |
255 | cfg->n = sel->n; | |
256 | cfg->p = sel->p; | |
257 | cfg->cpcon = sel->cpcon; | |
258 | ||
259 | return 0; | |
260 | } | |
261 | ||
262 | static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |
263 | unsigned long rate, unsigned long parent_rate) | |
264 | { | |
265 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
266 | unsigned long cfreq; | |
267 | u32 p_div = 0; | |
268 | ||
269 | switch (parent_rate) { | |
270 | case 12000000: | |
271 | case 26000000: | |
272 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; | |
273 | break; | |
274 | case 13000000: | |
275 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; | |
276 | break; | |
277 | case 16800000: | |
278 | case 19200000: | |
279 | cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; | |
280 | break; | |
281 | case 9600000: | |
282 | case 28800000: | |
283 | /* | |
284 | * PLL_P_OUT1 rate is not listed in PLLA table | |
285 | */ | |
286 | cfreq = parent_rate/(parent_rate/1000000); | |
287 | break; | |
288 | default: | |
289 | pr_err("%s Unexpected reference rate %lu\n", | |
290 | __func__, parent_rate); | |
291 | BUG(); | |
292 | } | |
293 | ||
294 | /* Raise VCO to guarantee 0.5% accuracy */ | |
295 | for (cfg->output_rate = rate; cfg->output_rate < 200 * cfreq; | |
296 | cfg->output_rate <<= 1) | |
297 | p_div++; | |
298 | ||
dba4072a | 299 | cfg->p = p_div; |
8f8f484b PG |
300 | cfg->m = parent_rate / cfreq; |
301 | cfg->n = cfg->output_rate / cfreq; | |
302 | cfg->cpcon = OUT_OF_TABLE_CPCON; | |
303 | ||
304 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || | |
dba4072a PDS |
305 | (1 << p_div) > divp_max(pll) |
306 | || cfg->output_rate > pll->params->vco_max) { | |
8f8f484b PG |
307 | pr_err("%s: Failed to set %s rate %lu\n", |
308 | __func__, __clk_get_name(hw->clk), rate); | |
309 | return -EINVAL; | |
310 | } | |
311 | ||
dba4072a PDS |
312 | if (pll->flags & TEGRA_PLLU) |
313 | cfg->p ^= 1; | |
314 | ||
8f8f484b PG |
315 | return 0; |
316 | } | |
317 | ||
dba4072a PDS |
318 | static void _update_pll_mnp(struct tegra_clk_pll *pll, |
319 | struct tegra_clk_pll_freq_table *cfg) | |
8f8f484b | 320 | { |
dba4072a | 321 | u32 val; |
8f8f484b | 322 | |
dba4072a | 323 | val = pll_readl_base(pll); |
8f8f484b | 324 | |
8f8f484b PG |
325 | val &= ~((divm_mask(pll) << pll->divm_shift) | |
326 | (divn_mask(pll) << pll->divn_shift) | | |
327 | (divp_mask(pll) << pll->divp_shift)); | |
328 | val |= ((cfg->m << pll->divm_shift) | | |
329 | (cfg->n << pll->divn_shift) | | |
dba4072a PDS |
330 | (cfg->p << pll->divp_shift)); |
331 | ||
332 | pll_writel_base(val, pll); | |
333 | } | |
334 | ||
335 | static void _get_pll_mnp(struct tegra_clk_pll *pll, | |
336 | struct tegra_clk_pll_freq_table *cfg) | |
337 | { | |
338 | u32 val; | |
339 | ||
340 | val = pll_readl_base(pll); | |
341 | ||
342 | cfg->m = (val >> pll->divm_shift) & (divm_mask(pll)); | |
343 | cfg->n = (val >> pll->divn_shift) & (divn_mask(pll)); | |
344 | cfg->p = (val >> pll->divp_shift) & (divp_mask(pll)); | |
345 | } | |
346 | ||
347 | static void _update_pll_cpcon(struct tegra_clk_pll *pll, | |
348 | struct tegra_clk_pll_freq_table *cfg, | |
349 | unsigned long rate) | |
350 | { | |
351 | u32 val; | |
352 | ||
353 | val = pll_readl_misc(pll); | |
354 | ||
355 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); | |
356 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; | |
357 | ||
358 | if (pll->flags & TEGRA_PLL_SET_LFCON) { | |
359 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); | |
360 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) | |
361 | val |= 1 << PLL_MISC_LFCON_SHIFT; | |
362 | } else if (pll->flags & TEGRA_PLL_SET_DCCON) { | |
363 | val &= ~(1 << PLL_MISC_DCCON_SHIFT); | |
364 | if (rate >= (pll->params->vco_max >> 1)) | |
365 | val |= 1 << PLL_MISC_DCCON_SHIFT; | |
8f8f484b PG |
366 | } |
367 | ||
dba4072a PDS |
368 | pll_writel_misc(val, pll); |
369 | } | |
370 | ||
371 | static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |
372 | unsigned long rate) | |
373 | { | |
374 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
375 | int state, ret = 0; | |
376 | ||
8f8f484b PG |
377 | state = clk_pll_is_enabled(hw); |
378 | ||
dba4072a | 379 | if (state) |
8f8f484b | 380 | _clk_pll_disable(hw); |
8f8f484b | 381 | |
dba4072a | 382 | _update_pll_mnp(pll, cfg); |
8f8f484b | 383 | |
dba4072a PDS |
384 | if (pll->flags & TEGRA_PLL_HAS_CPCON) |
385 | _update_pll_cpcon(pll, cfg, rate); | |
8f8f484b | 386 | |
dba4072a PDS |
387 | if (state) { |
388 | _clk_pll_enable(hw); | |
389 | ret = clk_pll_wait_for_lock(pll); | |
390 | } | |
8f8f484b | 391 | |
dba4072a | 392 | return ret; |
8f8f484b PG |
393 | } |
394 | ||
395 | static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |
396 | unsigned long parent_rate) | |
397 | { | |
398 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
dba4072a PDS |
399 | struct tegra_clk_pll_freq_table cfg, old_cfg; |
400 | unsigned long flags = 0; | |
401 | int ret = 0; | |
8f8f484b PG |
402 | |
403 | if (pll->flags & TEGRA_PLL_FIXED) { | |
404 | if (rate != pll->fixed_rate) { | |
405 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | |
406 | __func__, __clk_get_name(hw->clk), | |
407 | pll->fixed_rate, rate); | |
408 | return -EINVAL; | |
409 | } | |
410 | return 0; | |
411 | } | |
412 | ||
413 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && | |
414 | _calc_rate(hw, &cfg, rate, parent_rate)) | |
415 | return -EINVAL; | |
416 | ||
dba4072a PDS |
417 | if (pll->lock) |
418 | spin_lock_irqsave(pll->lock, flags); | |
419 | ||
420 | _get_pll_mnp(pll, &old_cfg); | |
421 | ||
422 | if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p) | |
423 | ret = _program_pll(hw, &cfg, rate); | |
424 | ||
425 | if (pll->lock) | |
426 | spin_unlock_irqrestore(pll->lock, flags); | |
427 | ||
428 | return ret; | |
8f8f484b PG |
429 | } |
430 | ||
431 | static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |
432 | unsigned long *prate) | |
433 | { | |
434 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
435 | struct tegra_clk_pll_freq_table cfg; | |
436 | u64 output_rate = *prate; | |
437 | ||
438 | if (pll->flags & TEGRA_PLL_FIXED) | |
439 | return pll->fixed_rate; | |
440 | ||
441 | /* PLLM is used for memory; we do not change rate */ | |
442 | if (pll->flags & TEGRA_PLLM) | |
443 | return __clk_get_rate(hw->clk); | |
444 | ||
445 | if (_get_table_rate(hw, &cfg, rate, *prate) && | |
446 | _calc_rate(hw, &cfg, rate, *prate)) | |
447 | return -EINVAL; | |
448 | ||
449 | output_rate *= cfg.n; | |
dba4072a | 450 | do_div(output_rate, cfg.m * (1 << cfg.p)); |
8f8f484b PG |
451 | |
452 | return output_rate; | |
453 | } | |
454 | ||
455 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | |
456 | unsigned long parent_rate) | |
457 | { | |
458 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
dba4072a PDS |
459 | struct tegra_clk_pll_freq_table cfg; |
460 | u32 val; | |
8f8f484b PG |
461 | u64 rate = parent_rate; |
462 | ||
dba4072a PDS |
463 | val = pll_readl_base(pll); |
464 | ||
dd93587b | 465 | if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) |
8f8f484b PG |
466 | return parent_rate; |
467 | ||
468 | if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { | |
469 | struct tegra_clk_pll_freq_table sel; | |
470 | if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { | |
471 | pr_err("Clock %s has unknown fixed frequency\n", | |
472 | __clk_get_name(hw->clk)); | |
473 | BUG(); | |
474 | } | |
475 | return pll->fixed_rate; | |
476 | } | |
477 | ||
dba4072a PDS |
478 | _get_pll_mnp(pll, &cfg); |
479 | ||
8f8f484b | 480 | if (pll->flags & TEGRA_PLLU) |
dba4072a | 481 | cfg.p ^= 1; |
8f8f484b | 482 | |
dba4072a PDS |
483 | cfg.m *= 1 << cfg.p; |
484 | ||
485 | rate *= cfg.n; | |
486 | do_div(rate, cfg.m); | |
8f8f484b | 487 | |
8f8f484b PG |
488 | return rate; |
489 | } | |
490 | ||
491 | static int clk_plle_training(struct tegra_clk_pll *pll) | |
492 | { | |
493 | u32 val; | |
494 | unsigned long timeout; | |
495 | ||
496 | if (!pll->pmc) | |
497 | return -ENOSYS; | |
498 | ||
499 | /* | |
500 | * PLLE is already disabled, and setup cleared; | |
501 | * create falling edge on PLLE IDDQ input. | |
502 | */ | |
503 | val = readl(pll->pmc + PMC_SATA_PWRGT); | |
504 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | |
505 | writel(val, pll->pmc + PMC_SATA_PWRGT); | |
506 | ||
507 | val = readl(pll->pmc + PMC_SATA_PWRGT); | |
508 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; | |
509 | writel(val, pll->pmc + PMC_SATA_PWRGT); | |
510 | ||
511 | val = readl(pll->pmc + PMC_SATA_PWRGT); | |
512 | val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | |
513 | writel(val, pll->pmc + PMC_SATA_PWRGT); | |
514 | ||
515 | val = pll_readl_misc(pll); | |
516 | ||
517 | timeout = jiffies + msecs_to_jiffies(100); | |
518 | while (1) { | |
519 | val = pll_readl_misc(pll); | |
520 | if (val & PLLE_MISC_READY) | |
521 | break; | |
522 | if (time_after(jiffies, timeout)) { | |
523 | pr_err("%s: timeout waiting for PLLE\n", __func__); | |
524 | return -EBUSY; | |
525 | } | |
526 | udelay(300); | |
527 | } | |
528 | ||
529 | return 0; | |
530 | } | |
531 | ||
532 | static int clk_plle_enable(struct clk_hw *hw) | |
533 | { | |
534 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
535 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); | |
536 | struct tegra_clk_pll_freq_table sel; | |
537 | u32 val; | |
538 | int err; | |
539 | ||
540 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | |
541 | return -EINVAL; | |
542 | ||
543 | clk_pll_disable(hw); | |
544 | ||
545 | val = pll_readl_misc(pll); | |
546 | val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); | |
547 | pll_writel_misc(val, pll); | |
548 | ||
549 | val = pll_readl_misc(pll); | |
550 | if (!(val & PLLE_MISC_READY)) { | |
551 | err = clk_plle_training(pll); | |
552 | if (err) | |
553 | return err; | |
554 | } | |
555 | ||
556 | if (pll->flags & TEGRA_PLLE_CONFIGURE) { | |
557 | /* configure dividers */ | |
558 | val = pll_readl_base(pll); | |
559 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | |
560 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | |
561 | val |= sel.m << pll->divm_shift; | |
562 | val |= sel.n << pll->divn_shift; | |
563 | val |= sel.p << pll->divp_shift; | |
564 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | |
565 | pll_writel_base(val, pll); | |
566 | } | |
567 | ||
568 | val = pll_readl_misc(pll); | |
569 | val |= PLLE_MISC_SETUP_VALUE; | |
570 | val |= PLLE_MISC_LOCK_ENABLE; | |
571 | pll_writel_misc(val, pll); | |
572 | ||
573 | val = readl(pll->clk_base + PLLE_SS_CTRL); | |
574 | val |= PLLE_SS_DISABLE; | |
575 | writel(val, pll->clk_base + PLLE_SS_CTRL); | |
576 | ||
577 | val |= pll_readl_base(pll); | |
578 | val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); | |
579 | pll_writel_base(val, pll); | |
580 | ||
dba4072a PDS |
581 | clk_pll_wait_for_lock(pll); |
582 | ||
8f8f484b PG |
583 | return 0; |
584 | } | |
585 | ||
586 | static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, | |
587 | unsigned long parent_rate) | |
588 | { | |
589 | struct tegra_clk_pll *pll = to_clk_pll(hw); | |
590 | u32 val = pll_readl_base(pll); | |
591 | u32 divn = 0, divm = 0, divp = 0; | |
592 | u64 rate = parent_rate; | |
593 | ||
594 | divp = (val >> pll->divp_shift) & (divp_mask(pll)); | |
595 | divn = (val >> pll->divn_shift) & (divn_mask(pll)); | |
596 | divm = (val >> pll->divm_shift) & (divm_mask(pll)); | |
597 | divm *= divp; | |
598 | ||
599 | rate *= divn; | |
600 | do_div(rate, divm); | |
601 | return rate; | |
602 | } | |
603 | ||
604 | const struct clk_ops tegra_clk_pll_ops = { | |
605 | .is_enabled = clk_pll_is_enabled, | |
606 | .enable = clk_pll_enable, | |
607 | .disable = clk_pll_disable, | |
608 | .recalc_rate = clk_pll_recalc_rate, | |
609 | .round_rate = clk_pll_round_rate, | |
610 | .set_rate = clk_pll_set_rate, | |
611 | }; | |
612 | ||
613 | const struct clk_ops tegra_clk_plle_ops = { | |
614 | .recalc_rate = clk_plle_recalc_rate, | |
615 | .is_enabled = clk_pll_is_enabled, | |
616 | .disable = clk_pll_disable, | |
617 | .enable = clk_plle_enable, | |
618 | }; | |
619 | ||
dba4072a PDS |
620 | static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, |
621 | void __iomem *pmc, unsigned long fixed_rate, | |
622 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | |
623 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | |
8f8f484b PG |
624 | { |
625 | struct tegra_clk_pll *pll; | |
8f8f484b PG |
626 | |
627 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | |
628 | if (!pll) | |
629 | return ERR_PTR(-ENOMEM); | |
630 | ||
8f8f484b PG |
631 | pll->clk_base = clk_base; |
632 | pll->pmc = pmc; | |
633 | ||
634 | pll->freq_table = freq_table; | |
635 | pll->params = pll_params; | |
636 | pll->fixed_rate = fixed_rate; | |
637 | pll->flags = pll_flags; | |
638 | pll->lock = lock; | |
639 | ||
640 | pll->divp_shift = PLL_BASE_DIVP_SHIFT; | |
641 | pll->divp_width = PLL_BASE_DIVP_WIDTH; | |
642 | pll->divn_shift = PLL_BASE_DIVN_SHIFT; | |
643 | pll->divn_width = PLL_BASE_DIVN_WIDTH; | |
644 | pll->divm_shift = PLL_BASE_DIVM_SHIFT; | |
645 | pll->divm_width = PLL_BASE_DIVM_WIDTH; | |
646 | ||
dba4072a PDS |
647 | return pll; |
648 | } | |
649 | ||
650 | static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, | |
651 | const char *name, const char *parent_name, unsigned long flags, | |
652 | const struct clk_ops *ops) | |
653 | { | |
654 | struct clk_init_data init; | |
655 | ||
656 | init.name = name; | |
657 | init.ops = ops; | |
658 | init.flags = flags; | |
659 | init.parent_names = (parent_name ? &parent_name : NULL); | |
660 | init.num_parents = (parent_name ? 1 : 0); | |
661 | ||
8f8f484b PG |
662 | /* Data in .init is copied by clk_register(), so stack variable OK */ |
663 | pll->hw.init = &init; | |
664 | ||
dba4072a | 665 | return clk_register(NULL, &pll->hw); |
8f8f484b PG |
666 | } |
667 | ||
668 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | |
669 | void __iomem *clk_base, void __iomem *pmc, | |
670 | unsigned long flags, unsigned long fixed_rate, | |
dba4072a | 671 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, |
8f8f484b PG |
672 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) |
673 | { | |
dba4072a PDS |
674 | struct tegra_clk_pll *pll; |
675 | struct clk *clk; | |
676 | ||
dd93587b | 677 | pll_flags |= TEGRA_PLL_BYPASS; |
dba4072a PDS |
678 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, |
679 | freq_table, lock); | |
680 | if (IS_ERR(pll)) | |
681 | return ERR_CAST(pll); | |
682 | ||
683 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | |
684 | &tegra_clk_pll_ops); | |
685 | if (IS_ERR(clk)) | |
686 | kfree(pll); | |
687 | ||
688 | return clk; | |
8f8f484b PG |
689 | } |
690 | ||
691 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | |
692 | void __iomem *clk_base, void __iomem *pmc, | |
693 | unsigned long flags, unsigned long fixed_rate, | |
dba4072a | 694 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, |
8f8f484b PG |
695 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) |
696 | { | |
dba4072a PDS |
697 | struct tegra_clk_pll *pll; |
698 | struct clk *clk; | |
dba4072a | 699 | |
dd93587b | 700 | pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; |
dba4072a PDS |
701 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, |
702 | freq_table, lock); | |
703 | if (IS_ERR(pll)) | |
704 | return ERR_CAST(pll); | |
705 | ||
706 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | |
707 | &tegra_clk_plle_ops); | |
708 | if (IS_ERR(clk)) | |
709 | kfree(pll); | |
710 | ||
711 | return clk; | |
8f8f484b | 712 | } |