clk: meson: clk-pll: drop hard-coded rates from pll tables
Putting hard-coded rates inside the parameter tables assumes that the parent is known and will never change. That's a big assumption we should not make. We have everything we need to recalculate the output rate using the parent rate and the rest of the parameters. Let's do so and drop the rates from the tables. Acked-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
This commit is contained in:
parent
87173557d2
commit
dd601dbc01
|
@ -134,36 +134,36 @@ static struct clk_regmap axg_sys_pll = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(960000000, 40, 1),
|
||||
PLL_RATE(984000000, 41, 1),
|
||||
PLL_RATE(1008000000, 42, 1),
|
||||
PLL_RATE(1032000000, 43, 1),
|
||||
PLL_RATE(1056000000, 44, 1),
|
||||
PLL_RATE(1080000000, 45, 1),
|
||||
PLL_RATE(1104000000, 46, 1),
|
||||
PLL_RATE(1128000000, 47, 1),
|
||||
PLL_RATE(1152000000, 48, 1),
|
||||
PLL_RATE(1176000000, 49, 1),
|
||||
PLL_RATE(1200000000, 50, 1),
|
||||
PLL_RATE(1224000000, 51, 1),
|
||||
PLL_RATE(1248000000, 52, 1),
|
||||
PLL_RATE(1272000000, 53, 1),
|
||||
PLL_RATE(1296000000, 54, 1),
|
||||
PLL_RATE(1320000000, 55, 1),
|
||||
PLL_RATE(1344000000, 56, 1),
|
||||
PLL_RATE(1368000000, 57, 1),
|
||||
PLL_RATE(1392000000, 58, 1),
|
||||
PLL_RATE(1416000000, 59, 1),
|
||||
PLL_RATE(1440000000, 60, 1),
|
||||
PLL_RATE(1464000000, 61, 1),
|
||||
PLL_RATE(1488000000, 62, 1),
|
||||
PLL_RATE(1512000000, 63, 1),
|
||||
PLL_RATE(1536000000, 64, 1),
|
||||
PLL_RATE(1560000000, 65, 1),
|
||||
PLL_RATE(1584000000, 66, 1),
|
||||
PLL_RATE(1608000000, 67, 1),
|
||||
PLL_RATE(1632000000, 68, 1),
|
||||
static const struct pll_params_table axg_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(40, 1),
|
||||
PLL_PARAMS(41, 1),
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
PLL_PARAMS(65, 1),
|
||||
PLL_PARAMS(66, 1),
|
||||
PLL_PARAMS(67, 1),
|
||||
PLL_PARAMS(68, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -207,7 +207,7 @@ static struct clk_regmap axg_gp0_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_gp0_pll_rate_table,
|
||||
.table = axg_gp0_pll_params_table,
|
||||
.init_regs = axg_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_gp0_init_regs),
|
||||
},
|
||||
|
@ -275,7 +275,7 @@ static struct clk_regmap axg_hifi_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_gp0_pll_rate_table,
|
||||
.table = axg_gp0_pll_params_table,
|
||||
.init_regs = axg_hifi_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_hifi_init_regs),
|
||||
.flags = CLK_MESON_PLL_ROUND_CLOSEST,
|
||||
|
@ -631,11 +631,10 @@ static struct clk_regmap axg_mpll3 = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct pll_rate_table axg_pcie_pll_rate_table[] = {
|
||||
static const struct pll_params_table axg_pcie_pll_params_table[] = {
|
||||
{
|
||||
.rate = 1600000000,
|
||||
.m = 200,
|
||||
.n = 3,
|
||||
.m = 200,
|
||||
.n = 3,
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
@ -682,7 +681,7 @@ static struct clk_regmap axg_pcie_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_pcie_pll_rate_table,
|
||||
.table = axg_pcie_pll_params_table,
|
||||
.init_regs = axg_pcie_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_pcie_init_regs),
|
||||
},
|
||||
|
|
|
@ -45,7 +45,7 @@ meson_clk_pll_data(struct clk_regmap *clk)
|
|||
}
|
||||
|
||||
static unsigned long __pll_params_to_rate(unsigned long parent_rate,
|
||||
const struct pll_rate_table *pllt,
|
||||
const struct pll_params_table *pllt,
|
||||
u16 frac,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
struct pll_rate_table pllt;
|
||||
struct pll_params_table pllt;
|
||||
u16 frac;
|
||||
|
||||
pllt.n = meson_parm_read(clk->map, &pll->n);
|
||||
|
@ -81,7 +81,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
|||
|
||||
static u16 __pll_params_with_frac(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
const struct pll_rate_table *pllt,
|
||||
const struct pll_params_table *pllt,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
u16 frac_max = (1 << pll->frac.width);
|
||||
|
@ -97,29 +97,50 @@ static u16 __pll_params_with_frac(unsigned long rate,
|
|||
return min((u16)val, (u16)(frac_max - 1));
|
||||
}
|
||||
|
||||
static const struct pll_rate_table *
|
||||
static bool meson_clk_pll_is_better(unsigned long rate,
|
||||
unsigned long best,
|
||||
unsigned long now,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
|
||||
MESON_PARM_APPLICABLE(&pll->frac)) {
|
||||
/* Round down */
|
||||
if (now < rate && best < now)
|
||||
return true;
|
||||
} else {
|
||||
/* Round Closest */
|
||||
if (abs(now - rate) < abs(best - rate))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct pll_params_table *
|
||||
meson_clk_get_pll_settings(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
const struct pll_rate_table *table = pll->table;
|
||||
unsigned int i = 0;
|
||||
const struct pll_params_table *table = pll->table;
|
||||
unsigned long best = 0, now = 0;
|
||||
unsigned int i, best_i = 0;
|
||||
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
/* Find the first table element exceeding rate */
|
||||
while (table[i].rate && table[i].rate <= rate)
|
||||
i++;
|
||||
for (i = 0; table[i].n; i++) {
|
||||
now = __pll_params_to_rate(parent_rate, &table[i], 0, pll);
|
||||
|
||||
if (i != 0) {
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac) ||
|
||||
!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
|
||||
(abs(rate - table[i - 1].rate) <
|
||||
abs(rate - table[i].rate)))
|
||||
i--;
|
||||
/* If we get an exact match, don't bother any further */
|
||||
if (now == rate) {
|
||||
return &table[i];
|
||||
} else if (meson_clk_pll_is_better(rate, best, now, pll)) {
|
||||
best = now;
|
||||
best_i = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (struct pll_rate_table *)&table[i];
|
||||
return (struct pll_params_table *)&table[best_i];
|
||||
}
|
||||
|
||||
static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -127,16 +148,18 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
const struct pll_rate_table *pllt =
|
||||
meson_clk_get_pll_settings(rate, pll);
|
||||
const struct pll_params_table *pllt =
|
||||
meson_clk_get_pll_settings(rate, *parent_rate, pll);
|
||||
unsigned long round;
|
||||
u16 frac;
|
||||
|
||||
if (!pllt)
|
||||
return meson_clk_pll_recalc_rate(hw, *parent_rate);
|
||||
|
||||
if (!MESON_PARM_APPLICABLE(&pll->frac)
|
||||
|| rate == pllt->rate)
|
||||
return pllt->rate;
|
||||
round = __pll_params_to_rate(*parent_rate, pllt, 0, pll);
|
||||
|
||||
if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round)
|
||||
return round;
|
||||
|
||||
/*
|
||||
* The rate provided by the setting is not an exact match, let's
|
||||
|
@ -214,7 +237,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
const struct pll_rate_table *pllt;
|
||||
const struct pll_params_table *pllt;
|
||||
unsigned int enabled;
|
||||
unsigned long old_rate;
|
||||
u16 frac = 0;
|
||||
|
@ -224,7 +247,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
old_rate = rate;
|
||||
|
||||
pllt = meson_clk_get_pll_settings(rate, pll);
|
||||
pllt = meson_clk_get_pll_settings(rate, parent_rate, pll);
|
||||
if (!pllt)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -43,15 +43,13 @@ static inline void meson_parm_write(struct regmap *map, struct parm *p,
|
|||
}
|
||||
|
||||
|
||||
struct pll_rate_table {
|
||||
unsigned long rate;
|
||||
struct pll_params_table {
|
||||
u16 m;
|
||||
u16 n;
|
||||
};
|
||||
|
||||
#define PLL_RATE(_r, _m, _n) \
|
||||
#define PLL_PARAMS(_m, _n) \
|
||||
{ \
|
||||
.rate = (_r), \
|
||||
.m = (_m), \
|
||||
.n = (_n), \
|
||||
}
|
||||
|
@ -67,7 +65,7 @@ struct meson_clk_pll_data {
|
|||
struct parm rst;
|
||||
const struct reg_sequence *init_regs;
|
||||
unsigned int init_count;
|
||||
const struct pll_rate_table *table;
|
||||
const struct pll_params_table *table;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,67 +18,67 @@
|
|||
|
||||
static DEFINE_SPINLOCK(meson_clk_lock);
|
||||
|
||||
static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(768000000, 32, 1),
|
||||
PLL_RATE(792000000, 33, 1),
|
||||
PLL_RATE(816000000, 34, 1),
|
||||
PLL_RATE(840000000, 35, 1),
|
||||
PLL_RATE(864000000, 36, 1),
|
||||
PLL_RATE(888000000, 37, 1),
|
||||
PLL_RATE(912000000, 38, 1),
|
||||
PLL_RATE(936000000, 39, 1),
|
||||
PLL_RATE(960000000, 40, 1),
|
||||
PLL_RATE(984000000, 41, 1),
|
||||
PLL_RATE(1008000000, 42, 1),
|
||||
PLL_RATE(1032000000, 43, 1),
|
||||
PLL_RATE(1056000000, 44, 1),
|
||||
PLL_RATE(1080000000, 45, 1),
|
||||
PLL_RATE(1104000000, 46, 1),
|
||||
PLL_RATE(1128000000, 47, 1),
|
||||
PLL_RATE(1152000000, 48, 1),
|
||||
PLL_RATE(1176000000, 49, 1),
|
||||
PLL_RATE(1200000000, 50, 1),
|
||||
PLL_RATE(1224000000, 51, 1),
|
||||
PLL_RATE(1248000000, 52, 1),
|
||||
PLL_RATE(1272000000, 53, 1),
|
||||
PLL_RATE(1296000000, 54, 1),
|
||||
PLL_RATE(1320000000, 55, 1),
|
||||
PLL_RATE(1344000000, 56, 1),
|
||||
PLL_RATE(1368000000, 57, 1),
|
||||
PLL_RATE(1392000000, 58, 1),
|
||||
PLL_RATE(1416000000, 59, 1),
|
||||
PLL_RATE(1440000000, 60, 1),
|
||||
PLL_RATE(1464000000, 61, 1),
|
||||
PLL_RATE(1488000000, 62, 1),
|
||||
static const struct pll_params_table gxbb_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(32, 1),
|
||||
PLL_PARAMS(33, 1),
|
||||
PLL_PARAMS(34, 1),
|
||||
PLL_PARAMS(35, 1),
|
||||
PLL_PARAMS(36, 1),
|
||||
PLL_PARAMS(37, 1),
|
||||
PLL_PARAMS(38, 1),
|
||||
PLL_PARAMS(39, 1),
|
||||
PLL_PARAMS(40, 1),
|
||||
PLL_PARAMS(41, 1),
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(1008000000, 42, 1),
|
||||
PLL_RATE(1032000000, 43, 1),
|
||||
PLL_RATE(1056000000, 44, 1),
|
||||
PLL_RATE(1080000000, 45, 1),
|
||||
PLL_RATE(1104000000, 46, 1),
|
||||
PLL_RATE(1128000000, 47, 1),
|
||||
PLL_RATE(1152000000, 48, 1),
|
||||
PLL_RATE(1176000000, 49, 1),
|
||||
PLL_RATE(1200000000, 50, 1),
|
||||
PLL_RATE(1224000000, 51, 1),
|
||||
PLL_RATE(1248000000, 52, 1),
|
||||
PLL_RATE(1272000000, 53, 1),
|
||||
PLL_RATE(1296000000, 54, 1),
|
||||
PLL_RATE(1320000000, 55, 1),
|
||||
PLL_RATE(1344000000, 56, 1),
|
||||
PLL_RATE(1368000000, 57, 1),
|
||||
PLL_RATE(1392000000, 58, 1),
|
||||
PLL_RATE(1416000000, 59, 1),
|
||||
PLL_RATE(1440000000, 60, 1),
|
||||
PLL_RATE(1464000000, 61, 1),
|
||||
PLL_RATE(1488000000, 62, 1),
|
||||
PLL_RATE(1512000000, 63, 1),
|
||||
PLL_RATE(1536000000, 64, 1),
|
||||
PLL_RATE(1560000000, 65, 1),
|
||||
PLL_RATE(1584000000, 66, 1),
|
||||
static const struct pll_params_table gxl_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
PLL_PARAMS(65, 1),
|
||||
PLL_PARAMS(66, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -380,7 +380,7 @@ static struct clk_regmap gxbb_gp0_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = gxbb_gp0_pll_rate_table,
|
||||
.table = gxbb_gp0_pll_params_table,
|
||||
.init_regs = gxbb_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(gxbb_gp0_init_regs),
|
||||
},
|
||||
|
@ -432,7 +432,7 @@ static struct clk_regmap gxl_gp0_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = gxl_gp0_pll_rate_table,
|
||||
.table = gxl_gp0_pll_params_table,
|
||||
.init_regs = gxl_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(gxl_gp0_init_regs),
|
||||
},
|
||||
|
|
|
@ -29,22 +29,22 @@ struct meson8b_clk_reset {
|
|||
void __iomem *base;
|
||||
};
|
||||
|
||||
static const struct pll_rate_table sys_pll_rate_table[] = {
|
||||
PLL_RATE(1200000000, 50, 1),
|
||||
PLL_RATE(1224000000, 51, 1),
|
||||
PLL_RATE(1248000000, 52, 1),
|
||||
PLL_RATE(1272000000, 53, 1),
|
||||
PLL_RATE(1296000000, 54, 1),
|
||||
PLL_RATE(1320000000, 55, 1),
|
||||
PLL_RATE(1344000000, 56, 1),
|
||||
PLL_RATE(1368000000, 57, 1),
|
||||
PLL_RATE(1392000000, 58, 1),
|
||||
PLL_RATE(1416000000, 59, 1),
|
||||
PLL_RATE(1440000000, 60, 1),
|
||||
PLL_RATE(1464000000, 61, 1),
|
||||
PLL_RATE(1488000000, 62, 1),
|
||||
PLL_RATE(1512000000, 63, 1),
|
||||
PLL_RATE(1536000000, 64, 1),
|
||||
static const struct pll_params_table sys_pll_params_table[] = {
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -196,7 +196,7 @@ static struct clk_regmap meson8b_sys_pll_dco = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = sys_pll_rate_table,
|
||||
.table = sys_pll_params_table,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll_dco",
|
||||
|
|
Loading…
Reference in New Issue