blob: eaab060cda2425dcb9c44b391a7afb926a3843d7 [file] [log] [blame]
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +05301/*
Peter De Schrijverdba40722013-04-03 17:40:36 +03002 * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved.
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +05303 *
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
104static 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
Peter De Schrijver7ba28812013-04-03 17:40:38 +0300111 if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE))
112 return;
113
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530114 val = pll_readl_misc(pll);
115 val |= BIT(pll->params->lock_enable_bit_idx);
116 pll_writel_misc(val, pll);
117}
118
Peter De Schrijverdba40722013-04-03 17:40:36 +0300119static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll)
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530120{
121 int i;
Peter De Schrijverdba40722013-04-03 17:40:36 +0300122 u32 val, lock_bit;
123 void __iomem *lock_addr;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530124
125 if (!(pll->flags & TEGRA_PLL_USE_LOCK)) {
126 udelay(pll->params->lock_delay);
127 return 0;
128 }
129
Peter De Schrijverdba40722013-04-03 17:40:36 +0300130 lock_addr = pll->clk_base;
131 if (pll->flags & TEGRA_PLL_LOCK_MISC)
132 lock_addr += pll->params->misc_reg;
133 else
134 lock_addr += pll->params->base_reg;
135
136 lock_bit = BIT(pll->params->lock_bit_idx);
137
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530138 for (i = 0; i < pll->params->lock_delay; i++) {
139 val = readl_relaxed(lock_addr);
Peter De Schrijverdba40722013-04-03 17:40:36 +0300140 if (val & lock_bit) {
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530141 udelay(PLL_POST_LOCK_DELAY);
142 return 0;
143 }
144 udelay(2); /* timeout = 2 * lock time */
145 }
146
147 pr_err("%s: Timed out waiting for pll %s lock\n", __func__,
148 __clk_get_name(pll->hw.clk));
149
150 return -1;
151}
152
153static int clk_pll_is_enabled(struct clk_hw *hw)
154{
155 struct tegra_clk_pll *pll = to_clk_pll(hw);
156 u32 val;
157
158 if (pll->flags & TEGRA_PLLM) {
159 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
160 if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
161 return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
162 }
163
164 val = pll_readl_base(pll);
165
166 return val & PLL_BASE_ENABLE ? 1 : 0;
167}
168
Peter De Schrijverdba40722013-04-03 17:40:36 +0300169static void _clk_pll_enable(struct clk_hw *hw)
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530170{
171 struct tegra_clk_pll *pll = to_clk_pll(hw);
172 u32 val;
173
174 clk_pll_enable_lock(pll);
175
176 val = pll_readl_base(pll);
Peter De Schrijverdd935872013-04-03 17:40:37 +0300177 if (pll->flags & TEGRA_PLL_BYPASS)
178 val &= ~PLL_BASE_BYPASS;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530179 val |= PLL_BASE_ENABLE;
180 pll_writel_base(val, pll);
181
182 if (pll->flags & TEGRA_PLLM) {
183 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
184 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
185 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
186 }
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530187}
188
189static void _clk_pll_disable(struct clk_hw *hw)
190{
191 struct tegra_clk_pll *pll = to_clk_pll(hw);
192 u32 val;
193
194 val = pll_readl_base(pll);
Peter De Schrijverdd935872013-04-03 17:40:37 +0300195 if (pll->flags & TEGRA_PLL_BYPASS)
196 val &= ~PLL_BASE_BYPASS;
197 val &= ~PLL_BASE_ENABLE;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530198 pll_writel_base(val, pll);
199
200 if (pll->flags & TEGRA_PLLM) {
201 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
202 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
203 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
204 }
205}
206
207static int clk_pll_enable(struct clk_hw *hw)
208{
209 struct tegra_clk_pll *pll = to_clk_pll(hw);
210 unsigned long flags = 0;
211 int ret;
212
213 if (pll->lock)
214 spin_lock_irqsave(pll->lock, flags);
215
Peter De Schrijverdba40722013-04-03 17:40:36 +0300216 _clk_pll_enable(hw);
217
218 ret = clk_pll_wait_for_lock(pll);
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530219
220 if (pll->lock)
221 spin_unlock_irqrestore(pll->lock, flags);
222
223 return ret;
224}
225
226static void clk_pll_disable(struct clk_hw *hw)
227{
228 struct tegra_clk_pll *pll = to_clk_pll(hw);
229 unsigned long flags = 0;
230
231 if (pll->lock)
232 spin_lock_irqsave(pll->lock, flags);
233
234 _clk_pll_disable(hw);
235
236 if (pll->lock)
237 spin_unlock_irqrestore(pll->lock, flags);
238}
239
240static int _get_table_rate(struct clk_hw *hw,
241 struct tegra_clk_pll_freq_table *cfg,
242 unsigned long rate, unsigned long parent_rate)
243{
244 struct tegra_clk_pll *pll = to_clk_pll(hw);
245 struct tegra_clk_pll_freq_table *sel;
246
247 for (sel = pll->freq_table; sel->input_rate != 0; sel++)
248 if (sel->input_rate == parent_rate &&
249 sel->output_rate == rate)
250 break;
251
252 if (sel->input_rate == 0)
253 return -EINVAL;
254
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530255 cfg->input_rate = sel->input_rate;
256 cfg->output_rate = sel->output_rate;
257 cfg->m = sel->m;
258 cfg->n = sel->n;
259 cfg->p = sel->p;
260 cfg->cpcon = sel->cpcon;
261
262 return 0;
263}
264
265static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
266 unsigned long rate, unsigned long parent_rate)
267{
268 struct tegra_clk_pll *pll = to_clk_pll(hw);
269 unsigned long cfreq;
270 u32 p_div = 0;
271
272 switch (parent_rate) {
273 case 12000000:
274 case 26000000:
275 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
276 break;
277 case 13000000:
278 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
279 break;
280 case 16800000:
281 case 19200000:
282 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
283 break;
284 case 9600000:
285 case 28800000:
286 /*
287 * PLL_P_OUT1 rate is not listed in PLLA table
288 */
289 cfreq = parent_rate/(parent_rate/1000000);
290 break;
291 default:
292 pr_err("%s Unexpected reference rate %lu\n",
293 __func__, parent_rate);
294 BUG();
295 }
296
297 /* Raise VCO to guarantee 0.5% accuracy */
298 for (cfg->output_rate = rate; cfg->output_rate < 200 * cfreq;
299 cfg->output_rate <<= 1)
300 p_div++;
301
Peter De Schrijverdba40722013-04-03 17:40:36 +0300302 cfg->p = p_div;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530303 cfg->m = parent_rate / cfreq;
304 cfg->n = cfg->output_rate / cfreq;
305 cfg->cpcon = OUT_OF_TABLE_CPCON;
306
307 if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
Peter De Schrijverdba40722013-04-03 17:40:36 +0300308 (1 << p_div) > divp_max(pll)
309 || cfg->output_rate > pll->params->vco_max) {
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530310 pr_err("%s: Failed to set %s rate %lu\n",
311 __func__, __clk_get_name(hw->clk), rate);
312 return -EINVAL;
313 }
314
Peter De Schrijverdba40722013-04-03 17:40:36 +0300315 if (pll->flags & TEGRA_PLLU)
316 cfg->p ^= 1;
317
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530318 return 0;
319}
320
Peter De Schrijverdba40722013-04-03 17:40:36 +0300321static void _update_pll_mnp(struct tegra_clk_pll *pll,
322 struct tegra_clk_pll_freq_table *cfg)
323{
324 u32 val;
325
326 val = pll_readl_base(pll);
327
328 val &= ~((divm_mask(pll) << pll->divm_shift) |
329 (divn_mask(pll) << pll->divn_shift) |
330 (divp_mask(pll) << pll->divp_shift));
331 val |= ((cfg->m << pll->divm_shift) |
332 (cfg->n << pll->divn_shift) |
333 (cfg->p << pll->divp_shift));
334
335 pll_writel_base(val, pll);
336}
337
338static void _get_pll_mnp(struct tegra_clk_pll *pll,
339 struct tegra_clk_pll_freq_table *cfg)
340{
341 u32 val;
342
343 val = pll_readl_base(pll);
344
345 cfg->m = (val >> pll->divm_shift) & (divm_mask(pll));
346 cfg->n = (val >> pll->divn_shift) & (divn_mask(pll));
347 cfg->p = (val >> pll->divp_shift) & (divp_mask(pll));
348}
349
350static void _update_pll_cpcon(struct tegra_clk_pll *pll,
351 struct tegra_clk_pll_freq_table *cfg,
352 unsigned long rate)
353{
354 u32 val;
355
356 val = pll_readl_misc(pll);
357
358 val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
359 val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
360
361 if (pll->flags & TEGRA_PLL_SET_LFCON) {
362 val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
363 if (cfg->n >= PLLDU_LFCON_SET_DIVN)
364 val |= 1 << PLL_MISC_LFCON_SHIFT;
365 } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
366 val &= ~(1 << PLL_MISC_DCCON_SHIFT);
367 if (rate >= (pll->params->vco_max >> 1))
368 val |= 1 << PLL_MISC_DCCON_SHIFT;
369 }
370
371 pll_writel_misc(val, pll);
372}
373
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530374static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
375 unsigned long rate)
376{
377 struct tegra_clk_pll *pll = to_clk_pll(hw);
Peter De Schrijverdba40722013-04-03 17:40:36 +0300378 int state, ret = 0;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530379
380 state = clk_pll_is_enabled(hw);
381
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530382 if (state)
Peter De Schrijverdba40722013-04-03 17:40:36 +0300383 _clk_pll_disable(hw);
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530384
Peter De Schrijverdba40722013-04-03 17:40:36 +0300385 _update_pll_mnp(pll, cfg);
386
387 if (pll->flags & TEGRA_PLL_HAS_CPCON)
388 _update_pll_cpcon(pll, cfg, rate);
389
390 if (state) {
391 _clk_pll_enable(hw);
392 ret = clk_pll_wait_for_lock(pll);
393 }
394
395 return ret;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530396}
397
398static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
399 unsigned long parent_rate)
400{
401 struct tegra_clk_pll *pll = to_clk_pll(hw);
Peter De Schrijverdba40722013-04-03 17:40:36 +0300402 struct tegra_clk_pll_freq_table cfg, old_cfg;
403 unsigned long flags = 0;
404 int ret = 0;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530405
406 if (pll->flags & TEGRA_PLL_FIXED) {
407 if (rate != pll->fixed_rate) {
408 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
409 __func__, __clk_get_name(hw->clk),
410 pll->fixed_rate, rate);
411 return -EINVAL;
412 }
413 return 0;
414 }
415
416 if (_get_table_rate(hw, &cfg, rate, parent_rate) &&
417 _calc_rate(hw, &cfg, rate, parent_rate))
418 return -EINVAL;
419
Peter De Schrijverdba40722013-04-03 17:40:36 +0300420 if (pll->lock)
421 spin_lock_irqsave(pll->lock, flags);
422
423 _get_pll_mnp(pll, &old_cfg);
424
425 if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p)
426 ret = _program_pll(hw, &cfg, rate);
427
428 if (pll->lock)
429 spin_unlock_irqrestore(pll->lock, flags);
430
431 return ret;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530432}
433
434static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
435 unsigned long *prate)
436{
437 struct tegra_clk_pll *pll = to_clk_pll(hw);
438 struct tegra_clk_pll_freq_table cfg;
439 u64 output_rate = *prate;
440
441 if (pll->flags & TEGRA_PLL_FIXED)
442 return pll->fixed_rate;
443
444 /* PLLM is used for memory; we do not change rate */
445 if (pll->flags & TEGRA_PLLM)
446 return __clk_get_rate(hw->clk);
447
448 if (_get_table_rate(hw, &cfg, rate, *prate) &&
449 _calc_rate(hw, &cfg, rate, *prate))
450 return -EINVAL;
451
452 output_rate *= cfg.n;
Peter De Schrijverdba40722013-04-03 17:40:36 +0300453 do_div(output_rate, cfg.m * (1 << cfg.p));
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530454
455 return output_rate;
456}
457
458static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
459 unsigned long parent_rate)
460{
461 struct tegra_clk_pll *pll = to_clk_pll(hw);
Peter De Schrijverdba40722013-04-03 17:40:36 +0300462 struct tegra_clk_pll_freq_table cfg;
463 u32 val;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530464 u64 rate = parent_rate;
465
Peter De Schrijverdba40722013-04-03 17:40:36 +0300466 val = pll_readl_base(pll);
467
Peter De Schrijverdd935872013-04-03 17:40:37 +0300468 if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS))
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530469 return parent_rate;
470
471 if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) {
472 struct tegra_clk_pll_freq_table sel;
473 if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) {
474 pr_err("Clock %s has unknown fixed frequency\n",
475 __clk_get_name(hw->clk));
476 BUG();
477 }
478 return pll->fixed_rate;
479 }
480
Peter De Schrijverdba40722013-04-03 17:40:36 +0300481 _get_pll_mnp(pll, &cfg);
482
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530483 if (pll->flags & TEGRA_PLLU)
Peter De Schrijverdba40722013-04-03 17:40:36 +0300484 cfg.p ^= 1;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530485
Peter De Schrijverdba40722013-04-03 17:40:36 +0300486 cfg.m *= 1 << cfg.p;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530487
Peter De Schrijverdba40722013-04-03 17:40:36 +0300488 rate *= cfg.n;
489 do_div(rate, cfg.m);
490
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530491 return rate;
492}
493
494static int clk_plle_training(struct tegra_clk_pll *pll)
495{
496 u32 val;
497 unsigned long timeout;
498
499 if (!pll->pmc)
500 return -ENOSYS;
501
502 /*
503 * PLLE is already disabled, and setup cleared;
504 * create falling edge on PLLE IDDQ input.
505 */
506 val = readl(pll->pmc + PMC_SATA_PWRGT);
507 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
508 writel(val, pll->pmc + PMC_SATA_PWRGT);
509
510 val = readl(pll->pmc + PMC_SATA_PWRGT);
511 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
512 writel(val, pll->pmc + PMC_SATA_PWRGT);
513
514 val = readl(pll->pmc + PMC_SATA_PWRGT);
515 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
516 writel(val, pll->pmc + PMC_SATA_PWRGT);
517
518 val = pll_readl_misc(pll);
519
520 timeout = jiffies + msecs_to_jiffies(100);
521 while (1) {
522 val = pll_readl_misc(pll);
523 if (val & PLLE_MISC_READY)
524 break;
525 if (time_after(jiffies, timeout)) {
526 pr_err("%s: timeout waiting for PLLE\n", __func__);
527 return -EBUSY;
528 }
529 udelay(300);
530 }
531
532 return 0;
533}
534
535static int clk_plle_enable(struct clk_hw *hw)
536{
537 struct tegra_clk_pll *pll = to_clk_pll(hw);
538 unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk));
539 struct tegra_clk_pll_freq_table sel;
540 u32 val;
541 int err;
542
543 if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
544 return -EINVAL;
545
546 clk_pll_disable(hw);
547
548 val = pll_readl_misc(pll);
549 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
550 pll_writel_misc(val, pll);
551
552 val = pll_readl_misc(pll);
553 if (!(val & PLLE_MISC_READY)) {
554 err = clk_plle_training(pll);
555 if (err)
556 return err;
557 }
558
559 if (pll->flags & TEGRA_PLLE_CONFIGURE) {
560 /* configure dividers */
561 val = pll_readl_base(pll);
562 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
563 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
564 val |= sel.m << pll->divm_shift;
565 val |= sel.n << pll->divn_shift;
566 val |= sel.p << pll->divp_shift;
567 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
568 pll_writel_base(val, pll);
569 }
570
571 val = pll_readl_misc(pll);
572 val |= PLLE_MISC_SETUP_VALUE;
573 val |= PLLE_MISC_LOCK_ENABLE;
574 pll_writel_misc(val, pll);
575
576 val = readl(pll->clk_base + PLLE_SS_CTRL);
577 val |= PLLE_SS_DISABLE;
578 writel(val, pll->clk_base + PLLE_SS_CTRL);
579
580 val |= pll_readl_base(pll);
581 val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
582 pll_writel_base(val, pll);
583
Peter De Schrijverdba40722013-04-03 17:40:36 +0300584 clk_pll_wait_for_lock(pll);
585
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530586 return 0;
587}
588
589static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
590 unsigned long parent_rate)
591{
592 struct tegra_clk_pll *pll = to_clk_pll(hw);
593 u32 val = pll_readl_base(pll);
594 u32 divn = 0, divm = 0, divp = 0;
595 u64 rate = parent_rate;
596
597 divp = (val >> pll->divp_shift) & (divp_mask(pll));
598 divn = (val >> pll->divn_shift) & (divn_mask(pll));
599 divm = (val >> pll->divm_shift) & (divm_mask(pll));
600 divm *= divp;
601
602 rate *= divn;
603 do_div(rate, divm);
604 return rate;
605}
606
607const struct clk_ops tegra_clk_pll_ops = {
608 .is_enabled = clk_pll_is_enabled,
609 .enable = clk_pll_enable,
610 .disable = clk_pll_disable,
611 .recalc_rate = clk_pll_recalc_rate,
612 .round_rate = clk_pll_round_rate,
613 .set_rate = clk_pll_set_rate,
614};
615
616const struct clk_ops tegra_clk_plle_ops = {
617 .recalc_rate = clk_plle_recalc_rate,
618 .is_enabled = clk_pll_is_enabled,
619 .disable = clk_pll_disable,
620 .enable = clk_plle_enable,
621};
622
Peter De Schrijverdba40722013-04-03 17:40:36 +0300623static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
624 void __iomem *pmc, unsigned long fixed_rate,
625 struct tegra_clk_pll_params *pll_params, u32 pll_flags,
626 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530627{
628 struct tegra_clk_pll *pll;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530629
630 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
631 if (!pll)
632 return ERR_PTR(-ENOMEM);
633
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530634 pll->clk_base = clk_base;
635 pll->pmc = pmc;
636
637 pll->freq_table = freq_table;
638 pll->params = pll_params;
639 pll->fixed_rate = fixed_rate;
640 pll->flags = pll_flags;
641 pll->lock = lock;
642
643 pll->divp_shift = PLL_BASE_DIVP_SHIFT;
644 pll->divp_width = PLL_BASE_DIVP_WIDTH;
645 pll->divn_shift = PLL_BASE_DIVN_SHIFT;
646 pll->divn_width = PLL_BASE_DIVN_WIDTH;
647 pll->divm_shift = PLL_BASE_DIVM_SHIFT;
648 pll->divm_width = PLL_BASE_DIVM_WIDTH;
649
Peter De Schrijverdba40722013-04-03 17:40:36 +0300650 return pll;
651}
652
653static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
654 const char *name, const char *parent_name, unsigned long flags,
655 const struct clk_ops *ops)
656{
657 struct clk_init_data init;
658
659 init.name = name;
660 init.ops = ops;
661 init.flags = flags;
662 init.parent_names = (parent_name ? &parent_name : NULL);
663 init.num_parents = (parent_name ? 1 : 0);
664
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530665 /* Data in .init is copied by clk_register(), so stack variable OK */
666 pll->hw.init = &init;
667
Peter De Schrijverdba40722013-04-03 17:40:36 +0300668 return clk_register(NULL, &pll->hw);
669}
670
671struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
672 void __iomem *clk_base, void __iomem *pmc,
673 unsigned long flags, unsigned long fixed_rate,
674 struct tegra_clk_pll_params *pll_params, u32 pll_flags,
675 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
676{
677 struct tegra_clk_pll *pll;
678 struct clk *clk;
679
Peter De Schrijverdd935872013-04-03 17:40:37 +0300680 pll_flags |= TEGRA_PLL_BYPASS;
Peter De Schrijver7ba28812013-04-03 17:40:38 +0300681 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
Peter De Schrijverdba40722013-04-03 17:40:36 +0300682 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
683 freq_table, lock);
684 if (IS_ERR(pll))
685 return ERR_CAST(pll);
686
687 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
688 &tegra_clk_pll_ops);
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530689 if (IS_ERR(clk))
690 kfree(pll);
691
692 return clk;
693}
694
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530695struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
696 void __iomem *clk_base, void __iomem *pmc,
697 unsigned long flags, unsigned long fixed_rate,
Peter De Schrijverdba40722013-04-03 17:40:36 +0300698 struct tegra_clk_pll_params *pll_params, u32 pll_flags,
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530699 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
700{
Peter De Schrijverdba40722013-04-03 17:40:36 +0300701 struct tegra_clk_pll *pll;
702 struct clk *clk;
Peter De Schrijverdba40722013-04-03 17:40:36 +0300703
Peter De Schrijverdd935872013-04-03 17:40:37 +0300704 pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
Peter De Schrijver7ba28812013-04-03 17:40:38 +0300705 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
Peter De Schrijverdba40722013-04-03 17:40:36 +0300706 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
707 freq_table, lock);
708 if (IS_ERR(pll))
709 return ERR_CAST(pll);
710
711 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
712 &tegra_clk_plle_ops);
713 if (IS_ERR(clk))
714 kfree(pll);
715
716 return clk;
Prashant Gaikwad8f8f4842013-01-11 13:16:20 +0530717}