diff options
| -rw-r--r-- | drivers/clk/clk-divider.c | 2 | ||||
| -rw-r--r-- | drivers/clk/st/clkgen-pll.c | 4 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-pll.c | 64 |
3 files changed, 47 insertions, 23 deletions
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 4637697c139f..3fbee4540228 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
| @@ -147,7 +147,7 @@ static bool _is_valid_div(struct clk_divider *divider, unsigned int div) | |||
| 147 | static int _round_up_table(const struct clk_div_table *table, int div) | 147 | static int _round_up_table(const struct clk_div_table *table, int div) |
| 148 | { | 148 | { |
| 149 | const struct clk_div_table *clkt; | 149 | const struct clk_div_table *clkt; |
| 150 | int up = _get_table_maxdiv(table); | 150 | int up = INT_MAX; |
| 151 | 151 | ||
| 152 | for (clkt = table; clkt->div; clkt++) { | 152 | for (clkt = table; clkt->div; clkt++) { |
| 153 | if (clkt->div == div) | 153 | if (clkt->div == div) |
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index bca0a0badbfa..a886702f7c8b 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c | |||
| @@ -521,8 +521,10 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, | |||
| 521 | gate->lock = odf_lock; | 521 | gate->lock = odf_lock; |
| 522 | 522 | ||
| 523 | div = kzalloc(sizeof(*div), GFP_KERNEL); | 523 | div = kzalloc(sizeof(*div), GFP_KERNEL); |
| 524 | if (!div) | 524 | if (!div) { |
| 525 | kfree(gate); | ||
| 525 | return ERR_PTR(-ENOMEM); | 526 | return ERR_PTR(-ENOMEM); |
| 527 | } | ||
| 526 | 528 | ||
| 527 | div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; | 529 | div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; |
| 528 | div->reg = reg + pll_data->odf[odf].offset; | 530 | div->reg = reg + pll_data->odf[odf].offset; |
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index e1769addf435..6aad8abc69a2 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
| @@ -58,9 +58,9 @@ | |||
| 58 | #define PLLDU_LFCON_SET_DIVN 600 | 58 | #define PLLDU_LFCON_SET_DIVN 600 |
| 59 | 59 | ||
| 60 | #define PLLE_BASE_DIVCML_SHIFT 24 | 60 | #define PLLE_BASE_DIVCML_SHIFT 24 |
| 61 | #define PLLE_BASE_DIVCML_WIDTH 4 | 61 | #define PLLE_BASE_DIVCML_MASK 0xf |
| 62 | #define PLLE_BASE_DIVP_SHIFT 16 | 62 | #define PLLE_BASE_DIVP_SHIFT 16 |
| 63 | #define PLLE_BASE_DIVP_WIDTH 7 | 63 | #define PLLE_BASE_DIVP_WIDTH 6 |
| 64 | #define PLLE_BASE_DIVN_SHIFT 8 | 64 | #define PLLE_BASE_DIVN_SHIFT 8 |
| 65 | #define PLLE_BASE_DIVN_WIDTH 8 | 65 | #define PLLE_BASE_DIVN_WIDTH 8 |
| 66 | #define PLLE_BASE_DIVM_SHIFT 0 | 66 | #define PLLE_BASE_DIVM_SHIFT 0 |
| @@ -183,6 +183,14 @@ | |||
| 183 | #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ | 183 | #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ |
| 184 | mask(p->params->div_nmp->divp_width)) | 184 | mask(p->params->div_nmp->divp_width)) |
| 185 | 185 | ||
| 186 | #define divm_shift(p) (p)->params->div_nmp->divm_shift | ||
| 187 | #define divn_shift(p) (p)->params->div_nmp->divn_shift | ||
| 188 | #define divp_shift(p) (p)->params->div_nmp->divp_shift | ||
| 189 | |||
| 190 | #define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p)) | ||
| 191 | #define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p)) | ||
| 192 | #define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p)) | ||
| 193 | |||
| 186 | #define divm_max(p) (divm_mask(p)) | 194 | #define divm_max(p) (divm_mask(p)) |
| 187 | #define divn_max(p) (divn_mask(p)) | 195 | #define divn_max(p) (divn_mask(p)) |
| 188 | #define divp_max(p) (1 << (divp_mask(p))) | 196 | #define divp_max(p) (1 << (divp_mask(p))) |
| @@ -476,13 +484,12 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, | |||
| 476 | } else { | 484 | } else { |
| 477 | val = pll_readl_base(pll); | 485 | val = pll_readl_base(pll); |
| 478 | 486 | ||
| 479 | val &= ~((divm_mask(pll) << div_nmp->divm_shift) | | 487 | val &= ~(divm_mask_shifted(pll) | divn_mask_shifted(pll) | |
| 480 | (divn_mask(pll) << div_nmp->divn_shift) | | 488 | divp_mask_shifted(pll)); |
| 481 | (divp_mask(pll) << div_nmp->divp_shift)); | ||
| 482 | 489 | ||
| 483 | val |= ((cfg->m << div_nmp->divm_shift) | | 490 | val |= (cfg->m << divm_shift(pll)) | |
| 484 | (cfg->n << div_nmp->divn_shift) | | 491 | (cfg->n << divn_shift(pll)) | |
| 485 | (cfg->p << div_nmp->divp_shift)); | 492 | (cfg->p << divp_shift(pll)); |
| 486 | 493 | ||
| 487 | pll_writel_base(val, pll); | 494 | pll_writel_base(val, pll); |
| 488 | } | 495 | } |
| @@ -730,11 +737,12 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
| 730 | if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { | 737 | if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { |
| 731 | /* configure dividers */ | 738 | /* configure dividers */ |
| 732 | val = pll_readl_base(pll); | 739 | val = pll_readl_base(pll); |
| 733 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 740 | val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) | |
| 734 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | 741 | divm_mask_shifted(pll)); |
| 735 | val |= sel.m << pll->params->div_nmp->divm_shift; | 742 | val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT); |
| 736 | val |= sel.n << pll->params->div_nmp->divn_shift; | 743 | val |= sel.m << divm_shift(pll); |
| 737 | val |= sel.p << pll->params->div_nmp->divp_shift; | 744 | val |= sel.n << divn_shift(pll); |
| 745 | val |= sel.p << divp_shift(pll); | ||
| 738 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | 746 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; |
| 739 | pll_writel_base(val, pll); | 747 | pll_writel_base(val, pll); |
| 740 | } | 748 | } |
| @@ -745,10 +753,11 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
| 745 | pll_writel_misc(val, pll); | 753 | pll_writel_misc(val, pll); |
| 746 | 754 | ||
| 747 | val = readl(pll->clk_base + PLLE_SS_CTRL); | 755 | val = readl(pll->clk_base + PLLE_SS_CTRL); |
| 756 | val &= ~PLLE_SS_COEFFICIENTS_MASK; | ||
| 748 | val |= PLLE_SS_DISABLE; | 757 | val |= PLLE_SS_DISABLE; |
| 749 | writel(val, pll->clk_base + PLLE_SS_CTRL); | 758 | writel(val, pll->clk_base + PLLE_SS_CTRL); |
| 750 | 759 | ||
| 751 | val |= pll_readl_base(pll); | 760 | val = pll_readl_base(pll); |
| 752 | val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); | 761 | val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); |
| 753 | pll_writel_base(val, pll); | 762 | pll_writel_base(val, pll); |
| 754 | 763 | ||
| @@ -1292,10 +1301,11 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
| 1292 | pll_writel(val, PLLE_SS_CTRL, pll); | 1301 | pll_writel(val, PLLE_SS_CTRL, pll); |
| 1293 | 1302 | ||
| 1294 | val = pll_readl_base(pll); | 1303 | val = pll_readl_base(pll); |
| 1295 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 1304 | val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) | |
| 1296 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | 1305 | divm_mask_shifted(pll)); |
| 1297 | val |= sel.m << pll->params->div_nmp->divm_shift; | 1306 | val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT); |
| 1298 | val |= sel.n << pll->params->div_nmp->divn_shift; | 1307 | val |= sel.m << divm_shift(pll); |
| 1308 | val |= sel.n << divn_shift(pll); | ||
| 1299 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | 1309 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; |
| 1300 | pll_writel_base(val, pll); | 1310 | pll_writel_base(val, pll); |
| 1301 | udelay(1); | 1311 | udelay(1); |
| @@ -1410,6 +1420,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | |||
| 1410 | return clk; | 1420 | return clk; |
| 1411 | } | 1421 | } |
| 1412 | 1422 | ||
| 1423 | static struct div_nmp pll_e_nmp = { | ||
| 1424 | .divn_shift = PLLE_BASE_DIVN_SHIFT, | ||
| 1425 | .divn_width = PLLE_BASE_DIVN_WIDTH, | ||
| 1426 | .divm_shift = PLLE_BASE_DIVM_SHIFT, | ||
| 1427 | .divm_width = PLLE_BASE_DIVM_WIDTH, | ||
| 1428 | .divp_shift = PLLE_BASE_DIVP_SHIFT, | ||
| 1429 | .divp_width = PLLE_BASE_DIVP_WIDTH, | ||
| 1430 | }; | ||
| 1431 | |||
| 1413 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | 1432 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, |
| 1414 | void __iomem *clk_base, void __iomem *pmc, | 1433 | void __iomem *clk_base, void __iomem *pmc, |
| 1415 | unsigned long flags, struct tegra_clk_pll_params *pll_params, | 1434 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
| @@ -1420,6 +1439,10 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | |||
| 1420 | 1439 | ||
| 1421 | pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; | 1440 | pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; |
| 1422 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1441 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
| 1442 | |||
| 1443 | if (!pll_params->div_nmp) | ||
| 1444 | pll_params->div_nmp = &pll_e_nmp; | ||
| 1445 | |||
| 1423 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | 1446 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); |
| 1424 | if (IS_ERR(pll)) | 1447 | if (IS_ERR(pll)) |
| 1425 | return ERR_CAST(pll); | 1448 | return ERR_CAST(pll); |
| @@ -1557,9 +1580,8 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
| 1557 | int m; | 1580 | int m; |
| 1558 | 1581 | ||
| 1559 | m = _pll_fixed_mdiv(pll_params, parent_rate); | 1582 | m = _pll_fixed_mdiv(pll_params, parent_rate); |
| 1560 | val = m << PLL_BASE_DIVM_SHIFT; | 1583 | val = m << divm_shift(pll); |
| 1561 | val |= (pll_params->vco_min / parent_rate) | 1584 | val |= (pll_params->vco_min / parent_rate) << divn_shift(pll); |
| 1562 | << PLL_BASE_DIVN_SHIFT; | ||
| 1563 | pll_writel_base(val, pll); | 1585 | pll_writel_base(val, pll); |
| 1564 | } | 1586 | } |
| 1565 | 1587 | ||
