aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2013-06-06 06:47:31 -0400
committerMike Turquette <mturquette@linaro.org>2013-06-11 21:00:32 -0400
commit408a24f8227f259eea97c6b4f66d1592e2f651b6 (patch)
tree005327b8ed61bca47e149f2e4e6db91e62753117 /drivers/clk
parentc09e32bb67a9fba318ae4387eaabba21e0d07a87 (diff)
clk: tegra: Use override bits when needed
PLLM has override bits in the PMC. Use those when PLLM_OVERRIDE_ENABLE is set. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> Tested-by: Stephen Warren <swarren@nvidia.com> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/tegra/clk-pll.c82
1 files changed, 49 insertions, 33 deletions
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 393b60c9c49d..197074a57754 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -117,10 +117,6 @@
117#define PLLCX_MISC2_DEFAULT 0x30211200 117#define PLLCX_MISC2_DEFAULT 0x30211200
118#define PLLCX_MISC3_DEFAULT 0x200 118#define PLLCX_MISC3_DEFAULT 0x200
119 119
120#define PMC_PLLM_WB0_OVERRIDE 0x1dc
121#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
122#define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27)
123
124#define PMC_SATA_PWRGT 0x1ac 120#define PMC_SATA_PWRGT 0x1ac
125#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) 121#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
126#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) 122#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
@@ -128,10 +124,12 @@
128#define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) 124#define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
129#define pll_readl_base(p) pll_readl(p->params->base_reg, p) 125#define pll_readl_base(p) pll_readl(p->params->base_reg, p)
130#define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) 126#define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
127#define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset)
131 128
132#define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) 129#define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
133#define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) 130#define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
134#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) 131#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
132#define pll_override_writel(val, offset, p) writel(val, p->pmc + offset)
135 133
136#define mask(w) ((1 << (w)) - 1) 134#define mask(w) ((1 << (w)) - 1)
137#define divm_mask(p) mask(p->params->div_nmp->divm_width) 135#define divm_mask(p) mask(p->params->div_nmp->divm_width)
@@ -413,29 +411,61 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
413 struct tegra_clk_pll_freq_table *cfg) 411 struct tegra_clk_pll_freq_table *cfg)
414{ 412{
415 u32 val; 413 u32 val;
414 struct tegra_clk_pll_params *params = pll->params;
415 struct div_nmp *div_nmp = params->div_nmp;
416
417 if ((pll->flags & TEGRA_PLLM) &&
418 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
419 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
420 val = pll_override_readl(params->pmc_divp_reg, pll);
421 val &= ~(divp_mask(pll) << div_nmp->override_divp_shift);
422 val |= cfg->p << div_nmp->override_divp_shift;
423 pll_override_writel(val, params->pmc_divp_reg, pll);
424
425 val = pll_override_readl(params->pmc_divnm_reg, pll);
426 val &= ~(divm_mask(pll) << div_nmp->override_divm_shift) |
427 ~(divn_mask(pll) << div_nmp->override_divn_shift);
428 val |= (cfg->m << div_nmp->override_divm_shift) |
429 (cfg->n << div_nmp->override_divn_shift);
430 pll_override_writel(val, params->pmc_divnm_reg, pll);
431 } else {
432 val = pll_readl_base(pll);
416 433
417 val = pll_readl_base(pll); 434 val &= ~((divm_mask(pll) << div_nmp->divm_shift) |
435 (divn_mask(pll) << div_nmp->divn_shift) |
436 (divp_mask(pll) << div_nmp->divp_shift));
418 437
419 val &= ~((divm_mask(pll) << pll->params->div_nmp->divm_shift) | 438 val |= ((cfg->m << div_nmp->divm_shift) |
420 (divn_mask(pll) << pll->params->div_nmp->divn_shift) | 439 (cfg->n << div_nmp->divn_shift) |
421 (divp_mask(pll) << pll->params->div_nmp->divp_shift)); 440 (cfg->p << div_nmp->divp_shift));
422 val |= ((cfg->m << pll->params->div_nmp->divm_shift) |
423 (cfg->n << pll->params->div_nmp->divn_shift) |
424 (cfg->p << pll->params->div_nmp->divp_shift));
425 441
426 pll_writel_base(val, pll); 442 pll_writel_base(val, pll);
443 }
427} 444}
428 445
429static void _get_pll_mnp(struct tegra_clk_pll *pll, 446static void _get_pll_mnp(struct tegra_clk_pll *pll,
430 struct tegra_clk_pll_freq_table *cfg) 447 struct tegra_clk_pll_freq_table *cfg)
431{ 448{
432 u32 val; 449 u32 val;
450 struct tegra_clk_pll_params *params = pll->params;
451 struct div_nmp *div_nmp = params->div_nmp;
452
453 if ((pll->flags & TEGRA_PLLM) &&
454 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
455 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
456 val = pll_override_readl(params->pmc_divp_reg, pll);
457 cfg->p = (val >> div_nmp->override_divp_shift) & divp_mask(pll);
458
459 val = pll_override_readl(params->pmc_divnm_reg, pll);
460 cfg->m = (val >> div_nmp->override_divm_shift) & divm_mask(pll);
461 cfg->n = (val >> div_nmp->override_divn_shift) & divn_mask(pll);
462 } else {
463 val = pll_readl_base(pll);
433 464
434 val = pll_readl_base(pll); 465 cfg->m = (val >> div_nmp->divm_shift) & divm_mask(pll);
435 466 cfg->n = (val >> div_nmp->divn_shift) & divn_mask(pll);
436 cfg->m = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll)); 467 cfg->p = (val >> div_nmp->divp_shift) & divp_mask(pll);
437 cfg->n = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll)); 468 }
438 cfg->p = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll));
439} 469}
440 470
441static void _update_pll_cpcon(struct tegra_clk_pll *pll, 471static void _update_pll_cpcon(struct tegra_clk_pll *pll,
@@ -883,7 +913,6 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
883 struct tegra_clk_pll *pll = to_clk_pll(hw); 913 struct tegra_clk_pll *pll = to_clk_pll(hw);
884 unsigned long flags = 0; 914 unsigned long flags = 0;
885 int state, ret = 0; 915 int state, ret = 0;
886 u32 val;
887 916
888 if (pll->lock) 917 if (pll->lock)
889 spin_lock_irqsave(pll->lock, flags); 918 spin_lock_irqsave(pll->lock, flags);
@@ -902,21 +931,7 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
902 if (ret < 0) 931 if (ret < 0)
903 goto out; 932 goto out;
904 933
905 val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); 934 _update_pll_mnp(pll, &cfg);
906 if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) {
907 val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
908 val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) :
909 (val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK);
910 writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
911
912 val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
913 val &= ~(divn_mask(pll) | divm_mask(pll));
914 val |= (cfg.m << pll->params->div_nmp->divm_shift) |
915 (cfg.n << pll->params->div_nmp->divn_shift);
916 writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE);
917 } else
918 _update_pll_mnp(pll, &cfg);
919
920 935
921out: 936out:
922 if (pll->lock) 937 if (pll->lock)
@@ -1460,6 +1475,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
1460 1475
1461 pll_flags |= TEGRA_PLL_BYPASS; 1476 pll_flags |= TEGRA_PLL_BYPASS;
1462 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; 1477 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
1478 pll_flags |= TEGRA_PLLM;
1463 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, 1479 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
1464 freq_table, lock); 1480 freq_table, lock);
1465 if (IS_ERR(pll)) 1481 if (IS_ERR(pll))