mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
Small number of user-visible regression fixes for clock drivers. There
is a memory leak fix for an ST platform, an infinite Loop Of Doom fix for the recent changes to the basic clock divider (hopefully the last fix for those recent changes) and some Tegra PLL changes which keep PCI from being hosed on that platform. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJThtlQAAoJEKI6nJvDJaTU4aUQALJuaJjFli8Q8DX1mBQYIHh6 v1cyLJYBygmFUQ3FWSar7qZMu6ub+uuu/RLOUQfqZheG99imnVulPdeC+SlcEzqm BHiUsIu+rBtveOF0a0f/1G+heuqS5rmv+oHNDUWABekVQ9lwy+1dXkh+4Kw7eA+3 YEX85ypfJuYnGh9aA6/dt9Ldw29RtdXfdeX9LhOCLV5GZ4e61fBcUCoCID4rnzqQ viXkqpbjnONnd0ShtnkN+NsIJTn1bgu13EDLcFFyXDfjNucyhINR1FDveWe1OsaZ iWHZGVgyXRzV8bBgCrjfVtwP4vQlaiACKmF30jffYqkxK+DxdB55hiCER1WpRg37 PrRDFRpzXTT0HHovldvlhoUnpRS3055RO+NiD4hIV6WzhTsbLlz1a5EY0gBQRM4U dLRxnSpVlR2Vfvhkr54Hrc+AT4j/IMnRlZfUQu6MsuQ76YD153BAUwfMffJbuumC iwphEOnJNIcssNeSngDQDJlgXINfucaLnSAjnG01U+qQmFqlqdVWHKTdXRRuW48P cdkYRENm4JzwUIyq9sa1rXtRMd7pNwXCmngmXwNe5z8TdhMiNszHCpR9aY9zCIgC HNIqp1Mqru+1KEUGRzbLo1gy+uy3JbwQSfw603upFga7Xsyjz7qDacjx1g0qe3Wd dp9/GjPKFGD2KydD/XIb =MU0S -----END PGP SIGNATURE----- Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux Pull clock fixes from Mike Turquette: "Small number of user-visible regression fixes for clock drivers. There is a memory leak fix for an ST platform, an infinite Loop Of Doom fix for the recent changes to the basic clock divider (hopefully the last fix for those recent changes) and some Tegra PLL changes which keep PCI from being hosed on that platform" * tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux: clk: st: Fix memory leak clk: divider: Fix table round up function clk: tegra: Fix enabling of PLLE clk: tegra: Introduce divider mask and shift helpers clk: tegra: Fix PLLE programming
This commit is contained in:
commit
15a7b60ea1
@ -147,7 +147,7 @@ static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
|
|||||||
static int _round_up_table(const struct clk_div_table *table, int div)
|
static int _round_up_table(const struct clk_div_table *table, int div)
|
||||||
{
|
{
|
||||||
const struct clk_div_table *clkt;
|
const struct clk_div_table *clkt;
|
||||||
int up = _get_table_maxdiv(table);
|
int up = INT_MAX;
|
||||||
|
|
||||||
for (clkt = table; clkt->div; clkt++) {
|
for (clkt = table; clkt->div; clkt++) {
|
||||||
if (clkt->div == div)
|
if (clkt->div == div)
|
||||||
|
@ -521,8 +521,10 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
|
|||||||
gate->lock = odf_lock;
|
gate->lock = odf_lock;
|
||||||
|
|
||||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||||
if (!div)
|
if (!div) {
|
||||||
|
kfree(gate);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
|
div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
|
||||||
div->reg = reg + pll_data->odf[odf].offset;
|
div->reg = reg + pll_data->odf[odf].offset;
|
||||||
|
@ -58,9 +58,9 @@
|
|||||||
#define PLLDU_LFCON_SET_DIVN 600
|
#define PLLDU_LFCON_SET_DIVN 600
|
||||||
|
|
||||||
#define PLLE_BASE_DIVCML_SHIFT 24
|
#define PLLE_BASE_DIVCML_SHIFT 24
|
||||||
#define PLLE_BASE_DIVCML_WIDTH 4
|
#define PLLE_BASE_DIVCML_MASK 0xf
|
||||||
#define PLLE_BASE_DIVP_SHIFT 16
|
#define PLLE_BASE_DIVP_SHIFT 16
|
||||||
#define PLLE_BASE_DIVP_WIDTH 7
|
#define PLLE_BASE_DIVP_WIDTH 6
|
||||||
#define PLLE_BASE_DIVN_SHIFT 8
|
#define PLLE_BASE_DIVN_SHIFT 8
|
||||||
#define PLLE_BASE_DIVN_WIDTH 8
|
#define PLLE_BASE_DIVN_WIDTH 8
|
||||||
#define PLLE_BASE_DIVM_SHIFT 0
|
#define PLLE_BASE_DIVM_SHIFT 0
|
||||||
@ -183,6 +183,14 @@
|
|||||||
#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\
|
#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\
|
||||||
mask(p->params->div_nmp->divp_width))
|
mask(p->params->div_nmp->divp_width))
|
||||||
|
|
||||||
|
#define divm_shift(p) (p)->params->div_nmp->divm_shift
|
||||||
|
#define divn_shift(p) (p)->params->div_nmp->divn_shift
|
||||||
|
#define divp_shift(p) (p)->params->div_nmp->divp_shift
|
||||||
|
|
||||||
|
#define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p))
|
||||||
|
#define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p))
|
||||||
|
#define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p))
|
||||||
|
|
||||||
#define divm_max(p) (divm_mask(p))
|
#define divm_max(p) (divm_mask(p))
|
||||||
#define divn_max(p) (divn_mask(p))
|
#define divn_max(p) (divn_mask(p))
|
||||||
#define divp_max(p) (1 << (divp_mask(p)))
|
#define divp_max(p) (1 << (divp_mask(p)))
|
||||||
@ -476,13 +484,12 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
|
|||||||
} else {
|
} else {
|
||||||
val = pll_readl_base(pll);
|
val = pll_readl_base(pll);
|
||||||
|
|
||||||
val &= ~((divm_mask(pll) << div_nmp->divm_shift) |
|
val &= ~(divm_mask_shifted(pll) | divn_mask_shifted(pll) |
|
||||||
(divn_mask(pll) << div_nmp->divn_shift) |
|
divp_mask_shifted(pll));
|
||||||
(divp_mask(pll) << div_nmp->divp_shift));
|
|
||||||
|
|
||||||
val |= ((cfg->m << div_nmp->divm_shift) |
|
val |= (cfg->m << divm_shift(pll)) |
|
||||||
(cfg->n << div_nmp->divn_shift) |
|
(cfg->n << divn_shift(pll)) |
|
||||||
(cfg->p << div_nmp->divp_shift));
|
(cfg->p << divp_shift(pll));
|
||||||
|
|
||||||
pll_writel_base(val, pll);
|
pll_writel_base(val, pll);
|
||||||
}
|
}
|
||||||
@ -730,11 +737,12 @@ static int clk_plle_enable(struct clk_hw *hw)
|
|||||||
if (pll->params->flags & TEGRA_PLLE_CONFIGURE) {
|
if (pll->params->flags & TEGRA_PLLE_CONFIGURE) {
|
||||||
/* configure dividers */
|
/* configure dividers */
|
||||||
val = pll_readl_base(pll);
|
val = pll_readl_base(pll);
|
||||||
val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
|
val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) |
|
||||||
val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
|
divm_mask_shifted(pll));
|
||||||
val |= sel.m << pll->params->div_nmp->divm_shift;
|
val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT);
|
||||||
val |= sel.n << pll->params->div_nmp->divn_shift;
|
val |= sel.m << divm_shift(pll);
|
||||||
val |= sel.p << pll->params->div_nmp->divp_shift;
|
val |= sel.n << divn_shift(pll);
|
||||||
|
val |= sel.p << divp_shift(pll);
|
||||||
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
|
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
|
||||||
pll_writel_base(val, pll);
|
pll_writel_base(val, pll);
|
||||||
}
|
}
|
||||||
@ -745,10 +753,11 @@ static int clk_plle_enable(struct clk_hw *hw)
|
|||||||
pll_writel_misc(val, pll);
|
pll_writel_misc(val, pll);
|
||||||
|
|
||||||
val = readl(pll->clk_base + PLLE_SS_CTRL);
|
val = readl(pll->clk_base + PLLE_SS_CTRL);
|
||||||
|
val &= ~PLLE_SS_COEFFICIENTS_MASK;
|
||||||
val |= PLLE_SS_DISABLE;
|
val |= PLLE_SS_DISABLE;
|
||||||
writel(val, pll->clk_base + PLLE_SS_CTRL);
|
writel(val, pll->clk_base + PLLE_SS_CTRL);
|
||||||
|
|
||||||
val |= pll_readl_base(pll);
|
val = pll_readl_base(pll);
|
||||||
val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
|
val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
|
||||||
pll_writel_base(val, pll);
|
pll_writel_base(val, pll);
|
||||||
|
|
||||||
@ -1292,10 +1301,11 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
|
|||||||
pll_writel(val, PLLE_SS_CTRL, pll);
|
pll_writel(val, PLLE_SS_CTRL, pll);
|
||||||
|
|
||||||
val = pll_readl_base(pll);
|
val = pll_readl_base(pll);
|
||||||
val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
|
val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) |
|
||||||
val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
|
divm_mask_shifted(pll));
|
||||||
val |= sel.m << pll->params->div_nmp->divm_shift;
|
val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT);
|
||||||
val |= sel.n << pll->params->div_nmp->divn_shift;
|
val |= sel.m << divm_shift(pll);
|
||||||
|
val |= sel.n << divn_shift(pll);
|
||||||
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
|
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
|
||||||
pll_writel_base(val, pll);
|
pll_writel_base(val, pll);
|
||||||
udelay(1);
|
udelay(1);
|
||||||
@ -1410,6 +1420,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
|
|||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct div_nmp pll_e_nmp = {
|
||||||
|
.divn_shift = PLLE_BASE_DIVN_SHIFT,
|
||||||
|
.divn_width = PLLE_BASE_DIVN_WIDTH,
|
||||||
|
.divm_shift = PLLE_BASE_DIVM_SHIFT,
|
||||||
|
.divm_width = PLLE_BASE_DIVM_WIDTH,
|
||||||
|
.divp_shift = PLLE_BASE_DIVP_SHIFT,
|
||||||
|
.divp_width = PLLE_BASE_DIVP_WIDTH,
|
||||||
|
};
|
||||||
|
|
||||||
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
|
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
|
||||||
void __iomem *clk_base, void __iomem *pmc,
|
void __iomem *clk_base, void __iomem *pmc,
|
||||||
unsigned long flags, struct tegra_clk_pll_params *pll_params,
|
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,
|
|||||||
|
|
||||||
pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
|
pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
|
||||||
pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
|
pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
|
||||||
|
|
||||||
|
if (!pll_params->div_nmp)
|
||||||
|
pll_params->div_nmp = &pll_e_nmp;
|
||||||
|
|
||||||
pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
|
pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
|
||||||
if (IS_ERR(pll))
|
if (IS_ERR(pll))
|
||||||
return ERR_CAST(pll);
|
return ERR_CAST(pll);
|
||||||
@ -1557,9 +1580,8 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
|
|||||||
int m;
|
int m;
|
||||||
|
|
||||||
m = _pll_fixed_mdiv(pll_params, parent_rate);
|
m = _pll_fixed_mdiv(pll_params, parent_rate);
|
||||||
val = m << PLL_BASE_DIVM_SHIFT;
|
val = m << divm_shift(pll);
|
||||||
val |= (pll_params->vco_min / parent_rate)
|
val |= (pll_params->vco_min / parent_rate) << divn_shift(pll);
|
||||||
<< PLL_BASE_DIVN_SHIFT;
|
|
||||||
pll_writel_base(val, pll);
|
pll_writel_base(val, pll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user