Skip to content

Commit

Permalink
Merge branch 'topic/pll-fixes' into next/drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
Neil Armstrong committed Mar 13, 2018
2 parents f5edaef + 6c00e7b commit 867a5a1
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 201 deletions.
121 changes: 26 additions & 95 deletions drivers/clk/meson/axg.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,98 +21,6 @@

static DEFINE_SPINLOCK(meson_clk_lock);

static const struct pll_rate_table sys_pll_rate_table[] = {
PLL_RATE(24000000, 56, 1, 2),
PLL_RATE(48000000, 64, 1, 2),
PLL_RATE(72000000, 72, 1, 2),
PLL_RATE(96000000, 64, 1, 2),
PLL_RATE(120000000, 80, 1, 2),
PLL_RATE(144000000, 96, 1, 2),
PLL_RATE(168000000, 56, 1, 1),
PLL_RATE(192000000, 64, 1, 1),
PLL_RATE(216000000, 72, 1, 1),
PLL_RATE(240000000, 80, 1, 1),
PLL_RATE(264000000, 88, 1, 1),
PLL_RATE(288000000, 96, 1, 1),
PLL_RATE(312000000, 52, 1, 2),
PLL_RATE(336000000, 56, 1, 2),
PLL_RATE(360000000, 60, 1, 2),
PLL_RATE(384000000, 64, 1, 2),
PLL_RATE(408000000, 68, 1, 2),
PLL_RATE(432000000, 72, 1, 2),
PLL_RATE(456000000, 76, 1, 2),
PLL_RATE(480000000, 80, 1, 2),
PLL_RATE(504000000, 84, 1, 2),
PLL_RATE(528000000, 88, 1, 2),
PLL_RATE(552000000, 92, 1, 2),
PLL_RATE(576000000, 96, 1, 2),
PLL_RATE(600000000, 50, 1, 1),
PLL_RATE(624000000, 52, 1, 1),
PLL_RATE(648000000, 54, 1, 1),
PLL_RATE(672000000, 56, 1, 1),
PLL_RATE(696000000, 58, 1, 1),
PLL_RATE(720000000, 60, 1, 1),
PLL_RATE(744000000, 62, 1, 1),
PLL_RATE(768000000, 64, 1, 1),
PLL_RATE(792000000, 66, 1, 1),
PLL_RATE(816000000, 68, 1, 1),
PLL_RATE(840000000, 70, 1, 1),
PLL_RATE(864000000, 72, 1, 1),
PLL_RATE(888000000, 74, 1, 1),
PLL_RATE(912000000, 76, 1, 1),
PLL_RATE(936000000, 78, 1, 1),
PLL_RATE(960000000, 80, 1, 1),
PLL_RATE(984000000, 82, 1, 1),
PLL_RATE(1008000000, 84, 1, 1),
PLL_RATE(1032000000, 86, 1, 1),
PLL_RATE(1056000000, 88, 1, 1),
PLL_RATE(1080000000, 90, 1, 1),
PLL_RATE(1104000000, 92, 1, 1),
PLL_RATE(1128000000, 94, 1, 1),
PLL_RATE(1152000000, 96, 1, 1),
PLL_RATE(1176000000, 98, 1, 1),
PLL_RATE(1200000000, 50, 1, 0),
PLL_RATE(1224000000, 51, 1, 0),
PLL_RATE(1248000000, 52, 1, 0),
PLL_RATE(1272000000, 53, 1, 0),
PLL_RATE(1296000000, 54, 1, 0),
PLL_RATE(1320000000, 55, 1, 0),
PLL_RATE(1344000000, 56, 1, 0),
PLL_RATE(1368000000, 57, 1, 0),
PLL_RATE(1392000000, 58, 1, 0),
PLL_RATE(1416000000, 59, 1, 0),
PLL_RATE(1440000000, 60, 1, 0),
PLL_RATE(1464000000, 61, 1, 0),
PLL_RATE(1488000000, 62, 1, 0),
PLL_RATE(1512000000, 63, 1, 0),
PLL_RATE(1536000000, 64, 1, 0),
PLL_RATE(1560000000, 65, 1, 0),
PLL_RATE(1584000000, 66, 1, 0),
PLL_RATE(1608000000, 67, 1, 0),
PLL_RATE(1632000000, 68, 1, 0),
PLL_RATE(1656000000, 68, 1, 0),
PLL_RATE(1680000000, 68, 1, 0),
PLL_RATE(1704000000, 68, 1, 0),
PLL_RATE(1728000000, 69, 1, 0),
PLL_RATE(1752000000, 69, 1, 0),
PLL_RATE(1776000000, 69, 1, 0),
PLL_RATE(1800000000, 69, 1, 0),
PLL_RATE(1824000000, 70, 1, 0),
PLL_RATE(1848000000, 70, 1, 0),
PLL_RATE(1872000000, 70, 1, 0),
PLL_RATE(1896000000, 70, 1, 0),
PLL_RATE(1920000000, 71, 1, 0),
PLL_RATE(1944000000, 71, 1, 0),
PLL_RATE(1968000000, 71, 1, 0),
PLL_RATE(1992000000, 71, 1, 0),
PLL_RATE(2016000000, 72, 1, 0),
PLL_RATE(2040000000, 72, 1, 0),
PLL_RATE(2064000000, 72, 1, 0),
PLL_RATE(2088000000, 72, 1, 0),
PLL_RATE(2112000000, 73, 1, 0),
{ /* sentinel */ },
};

static struct meson_clk_pll axg_fixed_pll = {
.m = {
.reg_off = HHI_MPLL_CNTL,
Expand All @@ -129,6 +37,11 @@ static struct meson_clk_pll axg_fixed_pll = {
.shift = 16,
.width = 2,
},
.frac = {
.reg_off = HHI_MPLL_CNTL2,
.shift = 0,
.width = 12,
},
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "fixed_pll",
Expand All @@ -151,11 +64,9 @@ static struct meson_clk_pll axg_sys_pll = {
},
.od = {
.reg_off = HHI_SYS_PLL_CNTL,
.shift = 10,
.shift = 16,
.width = 2,
},
.rate_table = sys_pll_rate_table,
.rate_count = ARRAY_SIZE(sys_pll_rate_table),
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "sys_pll",
Expand Down Expand Up @@ -381,6 +292,11 @@ static struct meson_clk_mpll axg_mpll0 = {
.shift = 25,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 0,
.width = 1,
},
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
Expand Down Expand Up @@ -411,6 +327,11 @@ static struct meson_clk_mpll axg_mpll1 = {
.shift = 14,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 1,
.width = 1,
},
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll1",
Expand Down Expand Up @@ -441,6 +362,11 @@ static struct meson_clk_mpll axg_mpll2 = {
.shift = 14,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 2,
.width = 1,
},
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll2",
Expand Down Expand Up @@ -471,6 +397,11 @@ static struct meson_clk_mpll axg_mpll3 = {
.shift = 0,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 3,
.width = 1,
},
.lock = &meson_clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll3",
Expand Down
7 changes: 7 additions & 0 deletions drivers/clk/meson/clk-mpll.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ static int mpll_set_rate(struct clk_hw *hw,
reg = PARM_SET(p->width, p->shift, reg, n2);
writel(reg, mpll->base + p->reg_off);

p = &mpll->misc;
if (p->width != 0) {
reg = readl(mpll->base + p->reg_off);
reg = PARM_SET(p->width, p->shift, reg, 1);
writel(reg, mpll->base + p->reg_off);
}

if (mpll->lock)
spin_unlock_irqrestore(mpll->lock, flags);
else
Expand Down
41 changes: 32 additions & 9 deletions drivers/clk/meson/clk-pll.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/slab.h>
Expand All @@ -51,9 +52,8 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
{
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
struct parm *p;
unsigned long parent_rate_mhz = parent_rate / 1000000;
unsigned long rate_mhz;
u16 n, m, frac = 0, od, od2 = 0;
u64 rate;
u16 n, m, frac = 0, od, od2 = 0, od3 = 0;
u32 reg;

p = &pll->n;
Expand All @@ -74,17 +74,23 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
od2 = PARM_GET(p->width, p->shift, reg);
}

p = &pll->od3;
if (p->width) {
reg = readl(pll->base + p->reg_off);
od3 = PARM_GET(p->width, p->shift, reg);
}

rate = (u64)m * parent_rate;

p = &pll->frac;
if (p->width) {
reg = readl(pll->base + p->reg_off);
frac = PARM_GET(p->width, p->shift, reg);
rate_mhz = (parent_rate_mhz * m + \
(parent_rate_mhz * frac >> 12)) * 2 / n;
rate_mhz = rate_mhz >> od >> od2;
} else
rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;

return rate_mhz * 1000000;
rate += mul_u64_u32_shr(parent_rate, frac, p->width);
}

return div_u64(rate, n) >> od >> od2 >> od3;
}

static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
Expand All @@ -94,6 +100,13 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
const struct pll_rate_table *rate_table = pll->rate_table;
int i;

/*
* if the table is missing, just return the current rate
* since we don't have the other available frequencies
*/
if (!rate_table)
return meson_clk_pll_recalc_rate(hw, *parent_rate);

for (i = 0; i < pll->rate_count; i++) {
if (rate <= rate_table[i].rate)
return rate_table[i].rate;
Expand All @@ -109,6 +122,9 @@ static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_
const struct pll_rate_table *rate_table = pll->rate_table;
int i;

if (!rate_table)
return NULL;

for (i = 0; i < pll->rate_count; i++) {
if (rate == rate_table[i].rate)
return &rate_table[i];
Expand Down Expand Up @@ -215,6 +231,13 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
writel(reg, pll->base + p->reg_off);
}

p = &pll->od3;
if (p->width) {
reg = readl(pll->base + p->reg_off);
reg = PARM_SET(p->width, p->shift, reg, rate_set->od3);
writel(reg, pll->base + p->reg_off);
}

p = &pll->frac;
if (p->width) {
reg = readl(pll->base + p->reg_off);
Expand Down
3 changes: 3 additions & 0 deletions drivers/clk/meson/clkc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct pll_rate_table {
u16 n;
u16 od;
u16 od2;
u16 od3;
u16 frac;
};

Expand Down Expand Up @@ -92,6 +93,7 @@ struct meson_clk_pll {
struct parm frac;
struct parm od;
struct parm od2;
struct parm od3;
const struct pll_setup_params params;
const struct pll_rate_table *rate_table;
unsigned int rate_count;
Expand Down Expand Up @@ -119,6 +121,7 @@ struct meson_clk_mpll {
struct parm n2;
struct parm en;
struct parm ssen;
struct parm misc;
spinlock_t *lock;
};

Expand Down
Loading

0 comments on commit 867a5a1

Please sign in to comment.