diff options
Diffstat (limited to 'drivers/clk/tegra/clk-pll.c')
-rw-r--r-- | drivers/clk/tegra/clk-pll.c | 417 |
1 files changed, 316 insertions, 101 deletions
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 197074a57754..0d20241e0770 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -77,7 +77,23 @@ | |||
77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) | 77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) |
78 | 78 | ||
79 | #define PLLE_SS_CTRL 0x68 | 79 | #define PLLE_SS_CTRL 0x68 |
80 | #define PLLE_SS_DISABLE (7 << 10) | 80 | #define PLLE_SS_CNTL_BYPASS_SS BIT(10) |
81 | #define PLLE_SS_CNTL_INTERP_RESET BIT(11) | ||
82 | #define PLLE_SS_CNTL_SSC_BYP BIT(12) | ||
83 | #define PLLE_SS_CNTL_CENTER BIT(14) | ||
84 | #define PLLE_SS_CNTL_INVERT BIT(15) | ||
85 | #define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\ | ||
86 | PLLE_SS_CNTL_SSC_BYP) | ||
87 | #define PLLE_SS_MAX_MASK 0x1ff | ||
88 | #define PLLE_SS_MAX_VAL 0x25 | ||
89 | #define PLLE_SS_INC_MASK (0xff << 16) | ||
90 | #define PLLE_SS_INC_VAL (0x1 << 16) | ||
91 | #define PLLE_SS_INCINTRV_MASK (0x3f << 24) | ||
92 | #define PLLE_SS_INCINTRV_VAL (0x20 << 24) | ||
93 | #define PLLE_SS_COEFFICIENTS_MASK \ | ||
94 | (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK) | ||
95 | #define PLLE_SS_COEFFICIENTS_VAL \ | ||
96 | (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) | ||
81 | 97 | ||
82 | #define PLLE_AUX_PLLP_SEL BIT(2) | 98 | #define PLLE_AUX_PLLP_SEL BIT(2) |
83 | #define PLLE_AUX_ENABLE_SWCTL BIT(4) | 99 | #define PLLE_AUX_ENABLE_SWCTL BIT(4) |
@@ -121,6 +137,36 @@ | |||
121 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) | 137 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) |
122 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) | 138 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) |
123 | 139 | ||
140 | #define PLLSS_MISC_KCP 0 | ||
141 | #define PLLSS_MISC_KVCO 0 | ||
142 | #define PLLSS_MISC_SETUP 0 | ||
143 | #define PLLSS_EN_SDM 0 | ||
144 | #define PLLSS_EN_SSC 0 | ||
145 | #define PLLSS_EN_DITHER2 0 | ||
146 | #define PLLSS_EN_DITHER 1 | ||
147 | #define PLLSS_SDM_RESET 0 | ||
148 | #define PLLSS_CLAMP 0 | ||
149 | #define PLLSS_SDM_SSC_MAX 0 | ||
150 | #define PLLSS_SDM_SSC_MIN 0 | ||
151 | #define PLLSS_SDM_SSC_STEP 0 | ||
152 | #define PLLSS_SDM_DIN 0 | ||
153 | #define PLLSS_MISC_DEFAULT ((PLLSS_MISC_KCP << 25) | \ | ||
154 | (PLLSS_MISC_KVCO << 24) | \ | ||
155 | PLLSS_MISC_SETUP) | ||
156 | #define PLLSS_CFG_DEFAULT ((PLLSS_EN_SDM << 31) | \ | ||
157 | (PLLSS_EN_SSC << 30) | \ | ||
158 | (PLLSS_EN_DITHER2 << 29) | \ | ||
159 | (PLLSS_EN_DITHER << 28) | \ | ||
160 | (PLLSS_SDM_RESET) << 27 | \ | ||
161 | (PLLSS_CLAMP << 22)) | ||
162 | #define PLLSS_CTRL1_DEFAULT \ | ||
163 | ((PLLSS_SDM_SSC_MAX << 16) | PLLSS_SDM_SSC_MIN) | ||
164 | #define PLLSS_CTRL2_DEFAULT \ | ||
165 | ((PLLSS_SDM_SSC_STEP << 16) | PLLSS_SDM_DIN) | ||
166 | #define PLLSS_LOCK_OVERRIDE BIT(24) | ||
167 | #define PLLSS_REF_SRC_SEL_SHIFT 25 | ||
168 | #define PLLSS_REF_SRC_SEL_MASK (3 << PLLSS_REF_SRC_SEL_SHIFT) | ||
169 | |||
124 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) | 170 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) |
125 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) | 171 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) |
126 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) | 172 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) |
@@ -134,7 +180,7 @@ | |||
134 | #define mask(w) ((1 << (w)) - 1) | 180 | #define mask(w) ((1 << (w)) - 1) |
135 | #define divm_mask(p) mask(p->params->div_nmp->divm_width) | 181 | #define divm_mask(p) mask(p->params->div_nmp->divm_width) |
136 | #define divn_mask(p) mask(p->params->div_nmp->divn_width) | 182 | #define divn_mask(p) mask(p->params->div_nmp->divn_width) |
137 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ | 183 | #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ |
138 | mask(p->params->div_nmp->divp_width)) | 184 | mask(p->params->div_nmp->divp_width)) |
139 | 185 | ||
140 | #define divm_max(p) (divm_mask(p)) | 186 | #define divm_max(p) (divm_mask(p)) |
@@ -154,10 +200,10 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) | |||
154 | { | 200 | { |
155 | u32 val; | 201 | u32 val; |
156 | 202 | ||
157 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) | 203 | if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) |
158 | return; | 204 | return; |
159 | 205 | ||
160 | if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) | 206 | if (!(pll->params->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) |
161 | return; | 207 | return; |
162 | 208 | ||
163 | val = pll_readl_misc(pll); | 209 | val = pll_readl_misc(pll); |
@@ -171,13 +217,13 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) | |||
171 | u32 val, lock_mask; | 217 | u32 val, lock_mask; |
172 | void __iomem *lock_addr; | 218 | void __iomem *lock_addr; |
173 | 219 | ||
174 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { | 220 | if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) { |
175 | udelay(pll->params->lock_delay); | 221 | udelay(pll->params->lock_delay); |
176 | return 0; | 222 | return 0; |
177 | } | 223 | } |
178 | 224 | ||
179 | lock_addr = pll->clk_base; | 225 | lock_addr = pll->clk_base; |
180 | if (pll->flags & TEGRA_PLL_LOCK_MISC) | 226 | if (pll->params->flags & TEGRA_PLL_LOCK_MISC) |
181 | lock_addr += pll->params->misc_reg; | 227 | lock_addr += pll->params->misc_reg; |
182 | else | 228 | else |
183 | lock_addr += pll->params->base_reg; | 229 | lock_addr += pll->params->base_reg; |
@@ -204,7 +250,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) | |||
204 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 250 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
205 | u32 val; | 251 | u32 val; |
206 | 252 | ||
207 | if (pll->flags & TEGRA_PLLM) { | 253 | if (pll->params->flags & TEGRA_PLLM) { |
208 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 254 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
209 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) | 255 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) |
210 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; | 256 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; |
@@ -223,12 +269,12 @@ static void _clk_pll_enable(struct clk_hw *hw) | |||
223 | clk_pll_enable_lock(pll); | 269 | clk_pll_enable_lock(pll); |
224 | 270 | ||
225 | val = pll_readl_base(pll); | 271 | val = pll_readl_base(pll); |
226 | if (pll->flags & TEGRA_PLL_BYPASS) | 272 | if (pll->params->flags & TEGRA_PLL_BYPASS) |
227 | val &= ~PLL_BASE_BYPASS; | 273 | val &= ~PLL_BASE_BYPASS; |
228 | val |= PLL_BASE_ENABLE; | 274 | val |= PLL_BASE_ENABLE; |
229 | pll_writel_base(val, pll); | 275 | pll_writel_base(val, pll); |
230 | 276 | ||
231 | if (pll->flags & TEGRA_PLLM) { | 277 | if (pll->params->flags & TEGRA_PLLM) { |
232 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 278 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
233 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | 279 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; |
234 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 280 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
@@ -241,12 +287,12 @@ static void _clk_pll_disable(struct clk_hw *hw) | |||
241 | u32 val; | 287 | u32 val; |
242 | 288 | ||
243 | val = pll_readl_base(pll); | 289 | val = pll_readl_base(pll); |
244 | if (pll->flags & TEGRA_PLL_BYPASS) | 290 | if (pll->params->flags & TEGRA_PLL_BYPASS) |
245 | val &= ~PLL_BASE_BYPASS; | 291 | val &= ~PLL_BASE_BYPASS; |
246 | val &= ~PLL_BASE_ENABLE; | 292 | val &= ~PLL_BASE_ENABLE; |
247 | pll_writel_base(val, pll); | 293 | pll_writel_base(val, pll); |
248 | 294 | ||
249 | if (pll->flags & TEGRA_PLLM) { | 295 | if (pll->params->flags & TEGRA_PLLM) { |
250 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 296 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
251 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | 297 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; |
252 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 298 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
@@ -326,7 +372,7 @@ static int _get_table_rate(struct clk_hw *hw, | |||
326 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 372 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
327 | struct tegra_clk_pll_freq_table *sel; | 373 | struct tegra_clk_pll_freq_table *sel; |
328 | 374 | ||
329 | for (sel = pll->freq_table; sel->input_rate != 0; sel++) | 375 | for (sel = pll->params->freq_table; sel->input_rate != 0; sel++) |
330 | if (sel->input_rate == parent_rate && | 376 | if (sel->input_rate == parent_rate && |
331 | sel->output_rate == rate) | 377 | sel->output_rate == rate) |
332 | break; | 378 | break; |
@@ -389,12 +435,11 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
389 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || | 435 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || |
390 | (1 << p_div) > divp_max(pll) | 436 | (1 << p_div) > divp_max(pll) |
391 | || cfg->output_rate > pll->params->vco_max) { | 437 | || cfg->output_rate > pll->params->vco_max) { |
392 | pr_err("%s: Failed to set %s rate %lu\n", | ||
393 | __func__, __clk_get_name(hw->clk), rate); | ||
394 | WARN_ON(1); | ||
395 | return -EINVAL; | 438 | return -EINVAL; |
396 | } | 439 | } |
397 | 440 | ||
441 | cfg->output_rate >>= p_div; | ||
442 | |||
398 | if (pll->params->pdiv_tohw) { | 443 | if (pll->params->pdiv_tohw) { |
399 | ret = _p_div_to_hw(hw, 1 << p_div); | 444 | ret = _p_div_to_hw(hw, 1 << p_div); |
400 | if (ret < 0) | 445 | if (ret < 0) |
@@ -414,7 +459,7 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, | |||
414 | struct tegra_clk_pll_params *params = pll->params; | 459 | struct tegra_clk_pll_params *params = pll->params; |
415 | struct div_nmp *div_nmp = params->div_nmp; | 460 | struct div_nmp *div_nmp = params->div_nmp; |
416 | 461 | ||
417 | if ((pll->flags & TEGRA_PLLM) && | 462 | if ((params->flags & TEGRA_PLLM) && |
418 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | 463 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & |
419 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | 464 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { |
420 | val = pll_override_readl(params->pmc_divp_reg, pll); | 465 | val = pll_override_readl(params->pmc_divp_reg, pll); |
@@ -450,7 +495,7 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, | |||
450 | struct tegra_clk_pll_params *params = pll->params; | 495 | struct tegra_clk_pll_params *params = pll->params; |
451 | struct div_nmp *div_nmp = params->div_nmp; | 496 | struct div_nmp *div_nmp = params->div_nmp; |
452 | 497 | ||
453 | if ((pll->flags & TEGRA_PLLM) && | 498 | if ((params->flags & TEGRA_PLLM) && |
454 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | 499 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & |
455 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | 500 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { |
456 | val = pll_override_readl(params->pmc_divp_reg, pll); | 501 | val = pll_override_readl(params->pmc_divp_reg, pll); |
@@ -479,11 +524,11 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, | |||
479 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); | 524 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); |
480 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; | 525 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; |
481 | 526 | ||
482 | if (pll->flags & TEGRA_PLL_SET_LFCON) { | 527 | if (pll->params->flags & TEGRA_PLL_SET_LFCON) { |
483 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); | 528 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); |
484 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) | 529 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) |
485 | val |= 1 << PLL_MISC_LFCON_SHIFT; | 530 | val |= 1 << PLL_MISC_LFCON_SHIFT; |
486 | } else if (pll->flags & TEGRA_PLL_SET_DCCON) { | 531 | } else if (pll->params->flags & TEGRA_PLL_SET_DCCON) { |
487 | val &= ~(1 << PLL_MISC_DCCON_SHIFT); | 532 | val &= ~(1 << PLL_MISC_DCCON_SHIFT); |
488 | if (rate >= (pll->params->vco_max >> 1)) | 533 | if (rate >= (pll->params->vco_max >> 1)) |
489 | val |= 1 << PLL_MISC_DCCON_SHIFT; | 534 | val |= 1 << PLL_MISC_DCCON_SHIFT; |
@@ -505,7 +550,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
505 | 550 | ||
506 | _update_pll_mnp(pll, cfg); | 551 | _update_pll_mnp(pll, cfg); |
507 | 552 | ||
508 | if (pll->flags & TEGRA_PLL_HAS_CPCON) | 553 | if (pll->params->flags & TEGRA_PLL_HAS_CPCON) |
509 | _update_pll_cpcon(pll, cfg, rate); | 554 | _update_pll_cpcon(pll, cfg, rate); |
510 | 555 | ||
511 | if (state) { | 556 | if (state) { |
@@ -524,11 +569,11 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
524 | unsigned long flags = 0; | 569 | unsigned long flags = 0; |
525 | int ret = 0; | 570 | int ret = 0; |
526 | 571 | ||
527 | if (pll->flags & TEGRA_PLL_FIXED) { | 572 | if (pll->params->flags & TEGRA_PLL_FIXED) { |
528 | if (rate != pll->fixed_rate) { | 573 | if (rate != pll->params->fixed_rate) { |
529 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | 574 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", |
530 | __func__, __clk_get_name(hw->clk), | 575 | __func__, __clk_get_name(hw->clk), |
531 | pll->fixed_rate, rate); | 576 | pll->params->fixed_rate, rate); |
532 | return -EINVAL; | 577 | return -EINVAL; |
533 | } | 578 | } |
534 | return 0; | 579 | return 0; |
@@ -536,6 +581,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
536 | 581 | ||
537 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && | 582 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && |
538 | _calc_rate(hw, &cfg, rate, parent_rate)) { | 583 | _calc_rate(hw, &cfg, rate, parent_rate)) { |
584 | pr_err("%s: Failed to set %s rate %lu\n", __func__, | ||
585 | __clk_get_name(hw->clk), rate); | ||
539 | WARN_ON(1); | 586 | WARN_ON(1); |
540 | return -EINVAL; | 587 | return -EINVAL; |
541 | } | 588 | } |
@@ -559,18 +606,16 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
559 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 606 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
560 | struct tegra_clk_pll_freq_table cfg; | 607 | struct tegra_clk_pll_freq_table cfg; |
561 | 608 | ||
562 | if (pll->flags & TEGRA_PLL_FIXED) | 609 | if (pll->params->flags & TEGRA_PLL_FIXED) |
563 | return pll->fixed_rate; | 610 | return pll->params->fixed_rate; |
564 | 611 | ||
565 | /* PLLM is used for memory; we do not change rate */ | 612 | /* PLLM is used for memory; we do not change rate */ |
566 | if (pll->flags & TEGRA_PLLM) | 613 | if (pll->params->flags & TEGRA_PLLM) |
567 | return __clk_get_rate(hw->clk); | 614 | return __clk_get_rate(hw->clk); |
568 | 615 | ||
569 | if (_get_table_rate(hw, &cfg, rate, *prate) && | 616 | if (_get_table_rate(hw, &cfg, rate, *prate) && |
570 | _calc_rate(hw, &cfg, rate, *prate)) { | 617 | _calc_rate(hw, &cfg, rate, *prate)) |
571 | WARN_ON(1); | ||
572 | return -EINVAL; | 618 | return -EINVAL; |
573 | } | ||
574 | 619 | ||
575 | return cfg.output_rate; | 620 | return cfg.output_rate; |
576 | } | 621 | } |
@@ -586,17 +631,19 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | |||
586 | 631 | ||
587 | val = pll_readl_base(pll); | 632 | val = pll_readl_base(pll); |
588 | 633 | ||
589 | if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) | 634 | if ((pll->params->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) |
590 | return parent_rate; | 635 | return parent_rate; |
591 | 636 | ||
592 | if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { | 637 | if ((pll->params->flags & TEGRA_PLL_FIXED) && |
638 | !(val & PLL_BASE_OVERRIDE)) { | ||
593 | struct tegra_clk_pll_freq_table sel; | 639 | struct tegra_clk_pll_freq_table sel; |
594 | if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { | 640 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, |
641 | parent_rate)) { | ||
595 | pr_err("Clock %s has unknown fixed frequency\n", | 642 | pr_err("Clock %s has unknown fixed frequency\n", |
596 | __clk_get_name(hw->clk)); | 643 | __clk_get_name(hw->clk)); |
597 | BUG(); | 644 | BUG(); |
598 | } | 645 | } |
599 | return pll->fixed_rate; | 646 | return pll->params->fixed_rate; |
600 | } | 647 | } |
601 | 648 | ||
602 | _get_pll_mnp(pll, &cfg); | 649 | _get_pll_mnp(pll, &cfg); |
@@ -664,7 +711,7 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
664 | u32 val; | 711 | u32 val; |
665 | int err; | 712 | int err; |
666 | 713 | ||
667 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | 714 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) |
668 | return -EINVAL; | 715 | return -EINVAL; |
669 | 716 | ||
670 | clk_pll_disable(hw); | 717 | clk_pll_disable(hw); |
@@ -680,7 +727,7 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
680 | return err; | 727 | return err; |
681 | } | 728 | } |
682 | 729 | ||
683 | if (pll->flags & TEGRA_PLLE_CONFIGURE) { | 730 | if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { |
684 | /* configure dividers */ | 731 | /* configure dividers */ |
685 | val = pll_readl_base(pll); | 732 | val = pll_readl_base(pll); |
686 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 733 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); |
@@ -744,7 +791,7 @@ const struct clk_ops tegra_clk_plle_ops = { | |||
744 | .enable = clk_plle_enable, | 791 | .enable = clk_plle_enable, |
745 | }; | 792 | }; |
746 | 793 | ||
747 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | 794 | #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) |
748 | 795 | ||
749 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | 796 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, |
750 | unsigned long parent_rate) | 797 | unsigned long parent_rate) |
@@ -755,6 +802,48 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | |||
755 | return 1; | 802 | return 1; |
756 | } | 803 | } |
757 | 804 | ||
805 | static unsigned long _clip_vco_min(unsigned long vco_min, | ||
806 | unsigned long parent_rate) | ||
807 | { | ||
808 | return DIV_ROUND_UP(vco_min, parent_rate) * parent_rate; | ||
809 | } | ||
810 | |||
811 | static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, | ||
812 | void __iomem *clk_base, | ||
813 | unsigned long parent_rate) | ||
814 | { | ||
815 | u32 val; | ||
816 | u32 step_a, step_b; | ||
817 | |||
818 | switch (parent_rate) { | ||
819 | case 12000000: | ||
820 | case 13000000: | ||
821 | case 26000000: | ||
822 | step_a = 0x2B; | ||
823 | step_b = 0x0B; | ||
824 | break; | ||
825 | case 16800000: | ||
826 | step_a = 0x1A; | ||
827 | step_b = 0x09; | ||
828 | break; | ||
829 | case 19200000: | ||
830 | step_a = 0x12; | ||
831 | step_b = 0x08; | ||
832 | break; | ||
833 | default: | ||
834 | pr_err("%s: Unexpected reference rate %lu\n", | ||
835 | __func__, parent_rate); | ||
836 | WARN_ON(1); | ||
837 | return -EINVAL; | ||
838 | } | ||
839 | |||
840 | val = step_a << pll_params->stepa_shift; | ||
841 | val |= step_b << pll_params->stepb_shift; | ||
842 | writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); | ||
843 | |||
844 | return 0; | ||
845 | } | ||
846 | |||
758 | static int clk_pll_iddq_enable(struct clk_hw *hw) | 847 | static int clk_pll_iddq_enable(struct clk_hw *hw) |
759 | { | 848 | { |
760 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 849 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
@@ -1173,7 +1262,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
1173 | unsigned long flags = 0; | 1262 | unsigned long flags = 0; |
1174 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); | 1263 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); |
1175 | 1264 | ||
1176 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | 1265 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) |
1177 | return -EINVAL; | 1266 | return -EINVAL; |
1178 | 1267 | ||
1179 | if (pll->lock) | 1268 | if (pll->lock) |
@@ -1217,6 +1306,18 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
1217 | if (ret < 0) | 1306 | if (ret < 0) |
1218 | goto out; | 1307 | goto out; |
1219 | 1308 | ||
1309 | val = pll_readl(PLLE_SS_CTRL, pll); | ||
1310 | val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); | ||
1311 | val &= ~PLLE_SS_COEFFICIENTS_MASK; | ||
1312 | val |= PLLE_SS_COEFFICIENTS_VAL; | ||
1313 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1314 | val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); | ||
1315 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1316 | udelay(1); | ||
1317 | val &= ~PLLE_SS_CNTL_INTERP_RESET; | ||
1318 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1319 | udelay(1); | ||
1320 | |||
1220 | /* TODO: enable hw control of xusb brick pll */ | 1321 | /* TODO: enable hw control of xusb brick pll */ |
1221 | 1322 | ||
1222 | out: | 1323 | out: |
@@ -1248,9 +1349,8 @@ static void clk_plle_tegra114_disable(struct clk_hw *hw) | |||
1248 | #endif | 1349 | #endif |
1249 | 1350 | ||
1250 | static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, | 1351 | static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, |
1251 | void __iomem *pmc, unsigned long fixed_rate, | 1352 | void __iomem *pmc, struct tegra_clk_pll_params *pll_params, |
1252 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1353 | spinlock_t *lock) |
1253 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1254 | { | 1354 | { |
1255 | struct tegra_clk_pll *pll; | 1355 | struct tegra_clk_pll *pll; |
1256 | 1356 | ||
@@ -1261,10 +1361,7 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, | |||
1261 | pll->clk_base = clk_base; | 1361 | pll->clk_base = clk_base; |
1262 | pll->pmc = pmc; | 1362 | pll->pmc = pmc; |
1263 | 1363 | ||
1264 | pll->freq_table = freq_table; | ||
1265 | pll->params = pll_params; | 1364 | pll->params = pll_params; |
1266 | pll->fixed_rate = fixed_rate; | ||
1267 | pll->flags = pll_flags; | ||
1268 | pll->lock = lock; | 1365 | pll->lock = lock; |
1269 | 1366 | ||
1270 | if (!pll_params->div_nmp) | 1367 | if (!pll_params->div_nmp) |
@@ -1293,17 +1390,15 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, | |||
1293 | 1390 | ||
1294 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | 1391 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, |
1295 | void __iomem *clk_base, void __iomem *pmc, | 1392 | void __iomem *clk_base, void __iomem *pmc, |
1296 | unsigned long flags, unsigned long fixed_rate, | 1393 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
1297 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1394 | spinlock_t *lock) |
1298 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1299 | { | 1395 | { |
1300 | struct tegra_clk_pll *pll; | 1396 | struct tegra_clk_pll *pll; |
1301 | struct clk *clk; | 1397 | struct clk *clk; |
1302 | 1398 | ||
1303 | pll_flags |= TEGRA_PLL_BYPASS; | 1399 | pll_params->flags |= TEGRA_PLL_BYPASS; |
1304 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1400 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1305 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1401 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); |
1306 | freq_table, lock); | ||
1307 | if (IS_ERR(pll)) | 1402 | if (IS_ERR(pll)) |
1308 | return ERR_CAST(pll); | 1403 | return ERR_CAST(pll); |
1309 | 1404 | ||
@@ -1317,17 +1412,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | |||
1317 | 1412 | ||
1318 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | 1413 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, |
1319 | void __iomem *clk_base, void __iomem *pmc, | 1414 | void __iomem *clk_base, void __iomem *pmc, |
1320 | unsigned long flags, unsigned long fixed_rate, | 1415 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
1321 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1416 | spinlock_t *lock) |
1322 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1323 | { | 1417 | { |
1324 | struct tegra_clk_pll *pll; | 1418 | struct tegra_clk_pll *pll; |
1325 | struct clk *clk; | 1419 | struct clk *clk; |
1326 | 1420 | ||
1327 | pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; | 1421 | pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; |
1328 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1422 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1329 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1423 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); |
1330 | freq_table, lock); | ||
1331 | if (IS_ERR(pll)) | 1424 | if (IS_ERR(pll)) |
1332 | return ERR_CAST(pll); | 1425 | return ERR_CAST(pll); |
1333 | 1426 | ||
@@ -1339,8 +1432,8 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | |||
1339 | return clk; | 1432 | return clk; |
1340 | } | 1433 | } |
1341 | 1434 | ||
1342 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | 1435 | #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) |
1343 | const struct clk_ops tegra_clk_pllxc_ops = { | 1436 | static const struct clk_ops tegra_clk_pllxc_ops = { |
1344 | .is_enabled = clk_pll_is_enabled, | 1437 | .is_enabled = clk_pll_is_enabled, |
1345 | .enable = clk_pll_iddq_enable, | 1438 | .enable = clk_pll_iddq_enable, |
1346 | .disable = clk_pll_iddq_disable, | 1439 | .disable = clk_pll_iddq_disable, |
@@ -1349,7 +1442,7 @@ const struct clk_ops tegra_clk_pllxc_ops = { | |||
1349 | .set_rate = clk_pllxc_set_rate, | 1442 | .set_rate = clk_pllxc_set_rate, |
1350 | }; | 1443 | }; |
1351 | 1444 | ||
1352 | const struct clk_ops tegra_clk_pllm_ops = { | 1445 | static const struct clk_ops tegra_clk_pllm_ops = { |
1353 | .is_enabled = clk_pll_is_enabled, | 1446 | .is_enabled = clk_pll_is_enabled, |
1354 | .enable = clk_pll_iddq_enable, | 1447 | .enable = clk_pll_iddq_enable, |
1355 | .disable = clk_pll_iddq_disable, | 1448 | .disable = clk_pll_iddq_disable, |
@@ -1358,7 +1451,7 @@ const struct clk_ops tegra_clk_pllm_ops = { | |||
1358 | .set_rate = clk_pllm_set_rate, | 1451 | .set_rate = clk_pllm_set_rate, |
1359 | }; | 1452 | }; |
1360 | 1453 | ||
1361 | const struct clk_ops tegra_clk_pllc_ops = { | 1454 | static const struct clk_ops tegra_clk_pllc_ops = { |
1362 | .is_enabled = clk_pll_is_enabled, | 1455 | .is_enabled = clk_pll_is_enabled, |
1363 | .enable = clk_pllc_enable, | 1456 | .enable = clk_pllc_enable, |
1364 | .disable = clk_pllc_disable, | 1457 | .disable = clk_pllc_disable, |
@@ -1367,7 +1460,7 @@ const struct clk_ops tegra_clk_pllc_ops = { | |||
1367 | .set_rate = clk_pllc_set_rate, | 1460 | .set_rate = clk_pllc_set_rate, |
1368 | }; | 1461 | }; |
1369 | 1462 | ||
1370 | const struct clk_ops tegra_clk_pllre_ops = { | 1463 | static const struct clk_ops tegra_clk_pllre_ops = { |
1371 | .is_enabled = clk_pll_is_enabled, | 1464 | .is_enabled = clk_pll_is_enabled, |
1372 | .enable = clk_pll_iddq_enable, | 1465 | .enable = clk_pll_iddq_enable, |
1373 | .disable = clk_pll_iddq_disable, | 1466 | .disable = clk_pll_iddq_disable, |
@@ -1376,7 +1469,7 @@ const struct clk_ops tegra_clk_pllre_ops = { | |||
1376 | .set_rate = clk_pllre_set_rate, | 1469 | .set_rate = clk_pllre_set_rate, |
1377 | }; | 1470 | }; |
1378 | 1471 | ||
1379 | const struct clk_ops tegra_clk_plle_tegra114_ops = { | 1472 | static const struct clk_ops tegra_clk_plle_tegra114_ops = { |
1380 | .is_enabled = clk_pll_is_enabled, | 1473 | .is_enabled = clk_pll_is_enabled, |
1381 | .enable = clk_plle_tegra114_enable, | 1474 | .enable = clk_plle_tegra114_enable, |
1382 | .disable = clk_plle_tegra114_disable, | 1475 | .disable = clk_plle_tegra114_disable, |
@@ -1386,21 +1479,46 @@ const struct clk_ops tegra_clk_plle_tegra114_ops = { | |||
1386 | 1479 | ||
1387 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | 1480 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, |
1388 | void __iomem *clk_base, void __iomem *pmc, | 1481 | void __iomem *clk_base, void __iomem *pmc, |
1389 | unsigned long flags, unsigned long fixed_rate, | 1482 | unsigned long flags, |
1390 | struct tegra_clk_pll_params *pll_params, | 1483 | struct tegra_clk_pll_params *pll_params, |
1391 | u32 pll_flags, | ||
1392 | struct tegra_clk_pll_freq_table *freq_table, | ||
1393 | spinlock_t *lock) | 1484 | spinlock_t *lock) |
1394 | { | 1485 | { |
1395 | struct tegra_clk_pll *pll; | 1486 | struct tegra_clk_pll *pll; |
1396 | struct clk *clk; | 1487 | struct clk *clk, *parent; |
1488 | unsigned long parent_rate; | ||
1489 | int err; | ||
1490 | u32 val, val_iddq; | ||
1491 | |||
1492 | parent = __clk_lookup(parent_name); | ||
1493 | if (!parent) { | ||
1494 | WARN(1, "parent clk %s of %s must be registered first\n", | ||
1495 | name, parent_name); | ||
1496 | return ERR_PTR(-EINVAL); | ||
1497 | } | ||
1397 | 1498 | ||
1398 | if (!pll_params->pdiv_tohw) | 1499 | if (!pll_params->pdiv_tohw) |
1399 | return ERR_PTR(-EINVAL); | 1500 | return ERR_PTR(-EINVAL); |
1400 | 1501 | ||
1401 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1502 | parent_rate = __clk_get_rate(parent); |
1402 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1503 | |
1403 | freq_table, lock); | 1504 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1505 | |||
1506 | err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); | ||
1507 | if (err) | ||
1508 | return ERR_PTR(err); | ||
1509 | |||
1510 | val = readl_relaxed(clk_base + pll_params->base_reg); | ||
1511 | val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); | ||
1512 | |||
1513 | if (val & PLL_BASE_ENABLE) | ||
1514 | WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); | ||
1515 | else { | ||
1516 | val_iddq |= BIT(pll_params->iddq_bit_idx); | ||
1517 | writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); | ||
1518 | } | ||
1519 | |||
1520 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | ||
1521 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1404 | if (IS_ERR(pll)) | 1522 | if (IS_ERR(pll)) |
1405 | return ERR_CAST(pll); | 1523 | return ERR_CAST(pll); |
1406 | 1524 | ||
@@ -1414,19 +1532,19 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | |||
1414 | 1532 | ||
1415 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | 1533 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, |
1416 | void __iomem *clk_base, void __iomem *pmc, | 1534 | void __iomem *clk_base, void __iomem *pmc, |
1417 | unsigned long flags, unsigned long fixed_rate, | 1535 | unsigned long flags, |
1418 | struct tegra_clk_pll_params *pll_params, | 1536 | struct tegra_clk_pll_params *pll_params, |
1419 | u32 pll_flags, | ||
1420 | struct tegra_clk_pll_freq_table *freq_table, | ||
1421 | spinlock_t *lock, unsigned long parent_rate) | 1537 | spinlock_t *lock, unsigned long parent_rate) |
1422 | { | 1538 | { |
1423 | u32 val; | 1539 | u32 val; |
1424 | struct tegra_clk_pll *pll; | 1540 | struct tegra_clk_pll *pll; |
1425 | struct clk *clk; | 1541 | struct clk *clk; |
1426 | 1542 | ||
1427 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; | 1543 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; |
1428 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1544 | |
1429 | freq_table, lock); | 1545 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1546 | |||
1547 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1430 | if (IS_ERR(pll)) | 1548 | if (IS_ERR(pll)) |
1431 | return ERR_CAST(pll); | 1549 | return ERR_CAST(pll); |
1432 | 1550 | ||
@@ -1461,23 +1579,32 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
1461 | 1579 | ||
1462 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | 1580 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, |
1463 | void __iomem *clk_base, void __iomem *pmc, | 1581 | void __iomem *clk_base, void __iomem *pmc, |
1464 | unsigned long flags, unsigned long fixed_rate, | 1582 | unsigned long flags, |
1465 | struct tegra_clk_pll_params *pll_params, | 1583 | struct tegra_clk_pll_params *pll_params, |
1466 | u32 pll_flags, | ||
1467 | struct tegra_clk_pll_freq_table *freq_table, | ||
1468 | spinlock_t *lock) | 1584 | spinlock_t *lock) |
1469 | { | 1585 | { |
1470 | struct tegra_clk_pll *pll; | 1586 | struct tegra_clk_pll *pll; |
1471 | struct clk *clk; | 1587 | struct clk *clk, *parent; |
1588 | unsigned long parent_rate; | ||
1472 | 1589 | ||
1473 | if (!pll_params->pdiv_tohw) | 1590 | if (!pll_params->pdiv_tohw) |
1474 | return ERR_PTR(-EINVAL); | 1591 | return ERR_PTR(-EINVAL); |
1475 | 1592 | ||
1476 | pll_flags |= TEGRA_PLL_BYPASS; | 1593 | parent = __clk_lookup(parent_name); |
1477 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1594 | if (!parent) { |
1478 | pll_flags |= TEGRA_PLLM; | 1595 | WARN(1, "parent clk %s of %s must be registered first\n", |
1479 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1596 | name, parent_name); |
1480 | freq_table, lock); | 1597 | return ERR_PTR(-EINVAL); |
1598 | } | ||
1599 | |||
1600 | parent_rate = __clk_get_rate(parent); | ||
1601 | |||
1602 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
1603 | |||
1604 | pll_params->flags |= TEGRA_PLL_BYPASS; | ||
1605 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | ||
1606 | pll_params->flags |= TEGRA_PLLM; | ||
1607 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1481 | if (IS_ERR(pll)) | 1608 | if (IS_ERR(pll)) |
1482 | return ERR_CAST(pll); | 1609 | return ERR_CAST(pll); |
1483 | 1610 | ||
@@ -1491,10 +1618,8 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | |||
1491 | 1618 | ||
1492 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | 1619 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, |
1493 | void __iomem *clk_base, void __iomem *pmc, | 1620 | void __iomem *clk_base, void __iomem *pmc, |
1494 | unsigned long flags, unsigned long fixed_rate, | 1621 | unsigned long flags, |
1495 | struct tegra_clk_pll_params *pll_params, | 1622 | struct tegra_clk_pll_params *pll_params, |
1496 | u32 pll_flags, | ||
1497 | struct tegra_clk_pll_freq_table *freq_table, | ||
1498 | spinlock_t *lock) | 1623 | spinlock_t *lock) |
1499 | { | 1624 | { |
1500 | struct clk *parent, *clk; | 1625 | struct clk *parent, *clk; |
@@ -1507,20 +1632,21 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | |||
1507 | return ERR_PTR(-EINVAL); | 1632 | return ERR_PTR(-EINVAL); |
1508 | 1633 | ||
1509 | parent = __clk_lookup(parent_name); | 1634 | parent = __clk_lookup(parent_name); |
1510 | if (IS_ERR(parent)) { | 1635 | if (!parent) { |
1511 | WARN(1, "parent clk %s of %s must be registered first\n", | 1636 | WARN(1, "parent clk %s of %s must be registered first\n", |
1512 | name, parent_name); | 1637 | name, parent_name); |
1513 | return ERR_PTR(-EINVAL); | 1638 | return ERR_PTR(-EINVAL); |
1514 | } | 1639 | } |
1515 | 1640 | ||
1516 | pll_flags |= TEGRA_PLL_BYPASS; | 1641 | parent_rate = __clk_get_rate(parent); |
1517 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1642 | |
1518 | freq_table, lock); | 1643 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1644 | |||
1645 | pll_params->flags |= TEGRA_PLL_BYPASS; | ||
1646 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1519 | if (IS_ERR(pll)) | 1647 | if (IS_ERR(pll)) |
1520 | return ERR_CAST(pll); | 1648 | return ERR_CAST(pll); |
1521 | 1649 | ||
1522 | parent_rate = __clk_get_rate(parent); | ||
1523 | |||
1524 | /* | 1650 | /* |
1525 | * Most of PLLC register fields are shadowed, and can not be read | 1651 | * Most of PLLC register fields are shadowed, and can not be read |
1526 | * directly from PLL h/w. Hence, actual PLLC boot state is unknown. | 1652 | * directly from PLL h/w. Hence, actual PLLC boot state is unknown. |
@@ -1567,17 +1693,15 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | |||
1567 | struct clk *tegra_clk_register_plle_tegra114(const char *name, | 1693 | struct clk *tegra_clk_register_plle_tegra114(const char *name, |
1568 | const char *parent_name, | 1694 | const char *parent_name, |
1569 | void __iomem *clk_base, unsigned long flags, | 1695 | void __iomem *clk_base, unsigned long flags, |
1570 | unsigned long fixed_rate, | ||
1571 | struct tegra_clk_pll_params *pll_params, | 1696 | struct tegra_clk_pll_params *pll_params, |
1572 | struct tegra_clk_pll_freq_table *freq_table, | ||
1573 | spinlock_t *lock) | 1697 | spinlock_t *lock) |
1574 | { | 1698 | { |
1575 | struct tegra_clk_pll *pll; | 1699 | struct tegra_clk_pll *pll; |
1576 | struct clk *clk; | 1700 | struct clk *clk; |
1577 | u32 val, val_aux; | 1701 | u32 val, val_aux; |
1578 | 1702 | ||
1579 | pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params, | 1703 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1580 | TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock); | 1704 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); |
1581 | if (IS_ERR(pll)) | 1705 | if (IS_ERR(pll)) |
1582 | return ERR_CAST(pll); | 1706 | return ERR_CAST(pll); |
1583 | 1707 | ||
@@ -1587,11 +1711,13 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, | |||
1587 | val_aux = pll_readl(pll_params->aux_reg, pll); | 1711 | val_aux = pll_readl(pll_params->aux_reg, pll); |
1588 | 1712 | ||
1589 | if (val & PLL_BASE_ENABLE) { | 1713 | if (val & PLL_BASE_ENABLE) { |
1590 | if (!(val_aux & PLLE_AUX_PLLRE_SEL)) | 1714 | if ((val_aux & PLLE_AUX_PLLRE_SEL) || |
1715 | (val_aux & PLLE_AUX_PLLP_SEL)) | ||
1591 | WARN(1, "pll_e enabled with unsupported parent %s\n", | 1716 | WARN(1, "pll_e enabled with unsupported parent %s\n", |
1592 | (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref"); | 1717 | (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : |
1718 | "pll_re_vco"); | ||
1593 | } else { | 1719 | } else { |
1594 | val_aux |= PLLE_AUX_PLLRE_SEL; | 1720 | val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); |
1595 | pll_writel(val, pll_params->aux_reg, pll); | 1721 | pll_writel(val, pll_params->aux_reg, pll); |
1596 | } | 1722 | } |
1597 | 1723 | ||
@@ -1603,3 +1729,92 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, | |||
1603 | return clk; | 1729 | return clk; |
1604 | } | 1730 | } |
1605 | #endif | 1731 | #endif |
1732 | |||
1733 | #ifdef CONFIG_ARCH_TEGRA_124_SOC | ||
1734 | static const struct clk_ops tegra_clk_pllss_ops = { | ||
1735 | .is_enabled = clk_pll_is_enabled, | ||
1736 | .enable = clk_pll_iddq_enable, | ||
1737 | .disable = clk_pll_iddq_disable, | ||
1738 | .recalc_rate = clk_pll_recalc_rate, | ||
1739 | .round_rate = clk_pll_ramp_round_rate, | ||
1740 | .set_rate = clk_pllxc_set_rate, | ||
1741 | }; | ||
1742 | |||
1743 | struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, | ||
1744 | void __iomem *clk_base, unsigned long flags, | ||
1745 | struct tegra_clk_pll_params *pll_params, | ||
1746 | spinlock_t *lock) | ||
1747 | { | ||
1748 | struct tegra_clk_pll *pll; | ||
1749 | struct clk *clk, *parent; | ||
1750 | struct tegra_clk_pll_freq_table cfg; | ||
1751 | unsigned long parent_rate; | ||
1752 | u32 val; | ||
1753 | int i; | ||
1754 | |||
1755 | if (!pll_params->div_nmp) | ||
1756 | return ERR_PTR(-EINVAL); | ||
1757 | |||
1758 | parent = __clk_lookup(parent_name); | ||
1759 | if (!parent) { | ||
1760 | WARN(1, "parent clk %s of %s must be registered first\n", | ||
1761 | name, parent_name); | ||
1762 | return ERR_PTR(-EINVAL); | ||
1763 | } | ||
1764 | |||
1765 | pll_params->flags = TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_USE_LOCK; | ||
1766 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); | ||
1767 | if (IS_ERR(pll)) | ||
1768 | return ERR_CAST(pll); | ||
1769 | |||
1770 | val = pll_readl_base(pll); | ||
1771 | val &= ~PLLSS_REF_SRC_SEL_MASK; | ||
1772 | pll_writel_base(val, pll); | ||
1773 | |||
1774 | parent_rate = __clk_get_rate(parent); | ||
1775 | |||
1776 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
1777 | |||
1778 | /* initialize PLL to minimum rate */ | ||
1779 | |||
1780 | cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); | ||
1781 | cfg.n = cfg.m * pll_params->vco_min / parent_rate; | ||
1782 | |||
1783 | for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) | ||
1784 | ; | ||
1785 | if (!i) { | ||
1786 | kfree(pll); | ||
1787 | return ERR_PTR(-EINVAL); | ||
1788 | } | ||
1789 | |||
1790 | cfg.p = pll_params->pdiv_tohw[i-1].hw_val; | ||
1791 | |||
1792 | _update_pll_mnp(pll, &cfg); | ||
1793 | |||
1794 | pll_writel_misc(PLLSS_MISC_DEFAULT, pll); | ||
1795 | pll_writel(PLLSS_CFG_DEFAULT, pll_params->ext_misc_reg[0], pll); | ||
1796 | pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[1], pll); | ||
1797 | pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[2], pll); | ||
1798 | |||
1799 | val = pll_readl_base(pll); | ||
1800 | if (val & PLL_BASE_ENABLE) { | ||
1801 | if (val & BIT(pll_params->iddq_bit_idx)) { | ||
1802 | WARN(1, "%s is on but IDDQ set\n", name); | ||
1803 | kfree(pll); | ||
1804 | return ERR_PTR(-EINVAL); | ||
1805 | } | ||
1806 | } else | ||
1807 | val |= BIT(pll_params->iddq_bit_idx); | ||
1808 | |||
1809 | val &= ~PLLSS_LOCK_OVERRIDE; | ||
1810 | pll_writel_base(val, pll); | ||
1811 | |||
1812 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | ||
1813 | &tegra_clk_pllss_ops); | ||
1814 | |||
1815 | if (IS_ERR(clk)) | ||
1816 | kfree(pll); | ||
1817 | |||
1818 | return clk; | ||
1819 | } | ||
1820 | #endif | ||