aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/tegra/clk-pll.c60
-rw-r--r--drivers/clk/tegra/clk.h32
2 files changed, 53 insertions, 39 deletions
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 85bec1dd87d8..3b778d3c828e 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -134,15 +134,24 @@
134#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) 134#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
135 135
136#define mask(w) ((1 << (w)) - 1) 136#define mask(w) ((1 << (w)) - 1)
137#define divm_mask(p) mask(p->divm_width) 137#define divm_mask(p) mask(p->params->div_nmp->divm_width)
138#define divn_mask(p) mask(p->divn_width) 138#define divn_mask(p) mask(p->params->div_nmp->divn_width)
139#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ 139#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \
140 mask(p->divp_width)) 140 mask(p->params->div_nmp->divp_width))
141 141
142#define divm_max(p) (divm_mask(p)) 142#define divm_max(p) (divm_mask(p))
143#define divn_max(p) (divn_mask(p)) 143#define divn_max(p) (divn_mask(p))
144#define divp_max(p) (1 << (divp_mask(p))) 144#define divp_max(p) (1 << (divp_mask(p)))
145 145
146static struct div_nmp default_nmp = {
147 .divn_shift = PLL_BASE_DIVN_SHIFT,
148 .divn_width = PLL_BASE_DIVN_WIDTH,
149 .divm_shift = PLL_BASE_DIVM_SHIFT,
150 .divm_width = PLL_BASE_DIVM_WIDTH,
151 .divp_shift = PLL_BASE_DIVP_SHIFT,
152 .divp_width = PLL_BASE_DIVP_WIDTH,
153};
154
146static void clk_pll_enable_lock(struct tegra_clk_pll *pll) 155static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
147{ 156{
148 u32 val; 157 u32 val;
@@ -407,12 +416,12 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
407 416
408 val = pll_readl_base(pll); 417 val = pll_readl_base(pll);
409 418
410 val &= ~((divm_mask(pll) << pll->divm_shift) | 419 val &= ~((divm_mask(pll) << pll->params->div_nmp->divm_shift) |
411 (divn_mask(pll) << pll->divn_shift) | 420 (divn_mask(pll) << pll->params->div_nmp->divn_shift) |
412 (divp_mask(pll) << pll->divp_shift)); 421 (divp_mask(pll) << pll->params->div_nmp->divp_shift));
413 val |= ((cfg->m << pll->divm_shift) | 422 val |= ((cfg->m << pll->params->div_nmp->divm_shift) |
414 (cfg->n << pll->divn_shift) | 423 (cfg->n << pll->params->div_nmp->divn_shift) |
415 (cfg->p << pll->divp_shift)); 424 (cfg->p << pll->params->div_nmp->divp_shift));
416 425
417 pll_writel_base(val, pll); 426 pll_writel_base(val, pll);
418} 427}
@@ -424,9 +433,9 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll,
424 433
425 val = pll_readl_base(pll); 434 val = pll_readl_base(pll);
426 435
427 cfg->m = (val >> pll->divm_shift) & (divm_mask(pll)); 436 cfg->m = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll));
428 cfg->n = (val >> pll->divn_shift) & (divn_mask(pll)); 437 cfg->n = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll));
429 cfg->p = (val >> pll->divp_shift) & (divp_mask(pll)); 438 cfg->p = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll));
430} 439}
431 440
432static void _update_pll_cpcon(struct tegra_clk_pll *pll, 441static void _update_pll_cpcon(struct tegra_clk_pll *pll,
@@ -646,9 +655,9 @@ static int clk_plle_enable(struct clk_hw *hw)
646 val = pll_readl_base(pll); 655 val = pll_readl_base(pll);
647 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); 656 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
648 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); 657 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
649 val |= sel.m << pll->divm_shift; 658 val |= sel.m << pll->params->div_nmp->divm_shift;
650 val |= sel.n << pll->divn_shift; 659 val |= sel.n << pll->params->div_nmp->divn_shift;
651 val |= sel.p << pll->divp_shift; 660 val |= sel.p << pll->params->div_nmp->divp_shift;
652 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; 661 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
653 pll_writel_base(val, pll); 662 pll_writel_base(val, pll);
654 } 663 }
@@ -679,9 +688,9 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
679 u32 divn = 0, divm = 0, divp = 0; 688 u32 divn = 0, divm = 0, divp = 0;
680 u64 rate = parent_rate; 689 u64 rate = parent_rate;
681 690
682 divp = (val >> pll->divp_shift) & (divp_mask(pll)); 691 divp = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll));
683 divn = (val >> pll->divn_shift) & (divn_mask(pll)); 692 divn = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll));
684 divm = (val >> pll->divm_shift) & (divm_mask(pll)); 693 divm = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll));
685 divm *= divp; 694 divm *= divp;
686 695
687 rate *= divn; 696 rate *= divn;
@@ -902,7 +911,8 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
902 911
903 val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); 912 val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
904 val &= ~(divn_mask(pll) | divm_mask(pll)); 913 val &= ~(divn_mask(pll) | divm_mask(pll));
905 val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift); 914 val |= (cfg.m << pll->params->div_nmp->divm_shift) |
915 (cfg.n << pll->params->div_nmp->divn_shift);
906 writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE); 916 writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE);
907 } else 917 } else
908 _update_pll_mnp(pll, &cfg); 918 _update_pll_mnp(pll, &cfg);
@@ -1180,8 +1190,8 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
1180 val = pll_readl_base(pll); 1190 val = pll_readl_base(pll);
1181 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); 1191 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
1182 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); 1192 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
1183 val |= sel.m << pll->divm_shift; 1193 val |= sel.m << pll->params->div_nmp->divm_shift;
1184 val |= sel.n << pll->divn_shift; 1194 val |= sel.n << pll->params->div_nmp->divn_shift;
1185 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; 1195 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
1186 pll_writel_base(val, pll); 1196 pll_writel_base(val, pll);
1187 udelay(1); 1197 udelay(1);
@@ -1242,12 +1252,8 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
1242 pll->flags = pll_flags; 1252 pll->flags = pll_flags;
1243 pll->lock = lock; 1253 pll->lock = lock;
1244 1254
1245 pll->divp_shift = PLL_BASE_DIVP_SHIFT; 1255 if (!pll_params->div_nmp)
1246 pll->divp_width = PLL_BASE_DIVP_WIDTH; 1256 pll_params->div_nmp = &default_nmp;
1247 pll->divn_shift = PLL_BASE_DIVN_SHIFT;
1248 pll->divn_width = PLL_BASE_DIVN_WIDTH;
1249 pll->divm_shift = PLL_BASE_DIVM_SHIFT;
1250 pll->divm_width = PLL_BASE_DIVM_WIDTH;
1251 1257
1252 return pll; 1258 return pll;
1253} 1259}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 11278a80e63e..d70eb2d2957f 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -128,6 +128,25 @@ struct pdiv_map {
128}; 128};
129 129
130/** 130/**
131 * struct div_nmp - offset and width of m,n and p fields
132 *
133 * @divn_shift: shift to the feedback divider bit field
134 * @divn_width: width of the feedback divider bit field
135 * @divm_shift: shift to the input divider bit field
136 * @divm_width: width of the input divider bit field
137 * @divp_shift: shift to the post divider bit field
138 * @divp_width: width of the post divider bit field
139 */
140struct div_nmp {
141 u8 divn_shift;
142 u8 divn_width;
143 u8 divm_shift;
144 u8 divm_width;
145 u8 divp_shift;
146 u8 divp_width;
147};
148
149/**
131 * struct clk_pll_params - PLL parameters 150 * struct clk_pll_params - PLL parameters
132 * 151 *
133 * @input_min: Minimum input frequency 152 * @input_min: Minimum input frequency
@@ -166,6 +185,7 @@ struct tegra_clk_pll_params {
166 int lock_delay; 185 int lock_delay;
167 int max_p; 186 int max_p;
168 struct pdiv_map *pdiv_tohw; 187 struct pdiv_map *pdiv_tohw;
188 struct div_nmp *div_nmp;
169}; 189};
170 190
171/** 191/**
@@ -179,12 +199,6 @@ struct tegra_clk_pll_params {
179 * @flags: PLL flags 199 * @flags: PLL flags
180 * @fixed_rate: PLL rate if it is fixed 200 * @fixed_rate: PLL rate if it is fixed
181 * @lock: register lock 201 * @lock: register lock
182 * @divn_shift: shift to the feedback divider bit field
183 * @divn_width: width of the feedback divider bit field
184 * @divm_shift: shift to the input divider bit field
185 * @divm_width: width of the input divider bit field