clk: samsung: Add support to register rate_table for samsung plls
This patch defines a common rate_table which will contain recommended p, m, s, k values for supported rates that needs to be changed for changing corresponding PLL's rate. Reviewed-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
This commit is contained in:
parent
5ca8fbd8d1
commit
3ff6e0d8d6
6 changed files with 75 additions and 28 deletions
|
@ -986,13 +986,13 @@ static __initdata struct of_device_id ext_clk_match[] = {
|
||||||
|
|
||||||
struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
|
struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
|
||||||
[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
||||||
APLL_CON0, "fout_apll"),
|
APLL_CON0, "fout_apll", NULL),
|
||||||
[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
|
[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
|
||||||
E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
|
E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll", NULL),
|
||||||
[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||||
EPLL_CON0, "fout_epll"),
|
EPLL_CON0, "fout_epll", NULL),
|
||||||
[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
|
[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
|
||||||
VPLL_CON0, "fout_vpll"),
|
VPLL_CON0, "fout_vpll", NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* register exynos4 clocks */
|
/* register exynos4 clocks */
|
||||||
|
|
|
@ -493,19 +493,19 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
|
||||||
|
|
||||||
struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
|
struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
|
||||||
[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
||||||
APLL_CON0, "fout_apll"),
|
APLL_CON0, "fout_apll", NULL),
|
||||||
[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
||||||
MPLL_CON0, "fout_mpll"),
|
MPLL_CON0, "fout_mpll", NULL),
|
||||||
[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
|
[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
|
||||||
BPLL_CON0),
|
BPLL_CON0, NULL),
|
||||||
[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
|
[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
|
||||||
GPLL_CON0),
|
GPLL_CON0, NULL),
|
||||||
[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
|
[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
|
||||||
CPLL_CON0),
|
CPLL_CON0, NULL),
|
||||||
[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||||
EPLL_CON0),
|
EPLL_CON0, NULL),
|
||||||
[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
|
[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
|
||||||
VPLL_LOCK, VPLL_CON0),
|
VPLL_LOCK, VPLL_CON0, NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __initdata struct of_device_id ext_clk_match[] = {
|
static __initdata struct of_device_id ext_clk_match[] = {
|
||||||
|
|
|
@ -729,27 +729,27 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
|
||||||
|
|
||||||
struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
|
struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
|
||||||
[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
||||||
APLL_CON0),
|
APLL_CON0, NULL),
|
||||||
[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
||||||
MPLL_CON0),
|
MPLL_CON0, NULL),
|
||||||
[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
|
[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
|
||||||
DPLL_CON0),
|
DPLL_CON0, NULL),
|
||||||
[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||||
EPLL_CON0),
|
EPLL_CON0, NULL),
|
||||||
[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
|
[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
|
||||||
RPLL_CON0),
|
RPLL_CON0, NULL),
|
||||||
[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
|
[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
|
||||||
IPLL_CON0),
|
IPLL_CON0, NULL),
|
||||||
[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
|
[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
|
||||||
SPLL_CON0),
|
SPLL_CON0, NULL),
|
||||||
[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
|
[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
|
||||||
VPLL_CON0),
|
VPLL_CON0, NULL),
|
||||||
[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
||||||
MPLL_CON0),
|
MPLL_CON0, NULL),
|
||||||
[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
|
[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
|
||||||
BPLL_CON0),
|
BPLL_CON0, NULL),
|
||||||
[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
|
[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
|
||||||
KPLL_CON0),
|
KPLL_CON0, NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __initdata struct of_device_id ext_clk_match[] = {
|
static __initdata struct of_device_id ext_clk_match[] = {
|
||||||
|
|
|
@ -18,6 +18,8 @@ struct samsung_clk_pll {
|
||||||
void __iomem *lock_reg;
|
void __iomem *lock_reg;
|
||||||
void __iomem *con_reg;
|
void __iomem *con_reg;
|
||||||
enum samsung_pll_type type;
|
enum samsung_pll_type type;
|
||||||
|
unsigned int rate_count;
|
||||||
|
const struct samsung_pll_rate_table *rate_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
|
#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
|
||||||
|
@ -350,7 +352,7 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
|
||||||
struct samsung_clk_pll *pll;
|
struct samsung_clk_pll *pll;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
int ret;
|
int ret, len;
|
||||||
|
|
||||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||||
if (!pll) {
|
if (!pll) {
|
||||||
|
@ -364,6 +366,21 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
|
||||||
init.parent_names = &pll_clk->parent_name;
|
init.parent_names = &pll_clk->parent_name;
|
||||||
init.num_parents = 1;
|
init.num_parents = 1;
|
||||||
|
|
||||||
|
if (pll_clk->rate_table) {
|
||||||
|
/* find count of rates in rate_table */
|
||||||
|
for (len = 0; pll_clk->rate_table[len].rate != 0; )
|
||||||
|
len++;
|
||||||
|
|
||||||
|
pll->rate_count = len;
|
||||||
|
pll->rate_table = kmemdup(pll_clk->rate_table,
|
||||||
|
pll->rate_count *
|
||||||
|
sizeof(struct samsung_pll_rate_table),
|
||||||
|
GFP_KERNEL);
|
||||||
|
WARN(!pll->rate_table,
|
||||||
|
"%s: could not allocate rate table for %s\n",
|
||||||
|
__func__, pll_clk->name);
|
||||||
|
}
|
||||||
|
|
||||||
switch (pll_clk->type) {
|
switch (pll_clk->type) {
|
||||||
/* clk_ops for 35xx and 2550 are similar */
|
/* clk_ops for 35xx and 2550 are similar */
|
||||||
case pll_35xx:
|
case pll_35xx:
|
||||||
|
|
|
@ -19,6 +19,33 @@ enum samsung_pll_type {
|
||||||
pll_2650,
|
pll_2650,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PLL_35XX_RATE(_rate, _m, _p, _s) \
|
||||||
|
{ \
|
||||||
|
.rate = (_rate), \
|
||||||
|
.mdiv = (_m), \
|
||||||
|
.pdiv = (_p), \
|
||||||
|
.sdiv = (_s), \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLL_36XX_RATE(_rate, _m, _p, _s, _k) \
|
||||||
|
{ \
|
||||||
|
.rate = (_rate), \
|
||||||
|
.mdiv = (_m), \
|
||||||
|
.pdiv = (_p), \
|
||||||
|
.sdiv = (_s), \
|
||||||
|
.kdiv = (_k), \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Rate table should be kept sorted in descending order. */
|
||||||
|
|
||||||
|
struct samsung_pll_rate_table {
|
||||||
|
unsigned int rate;
|
||||||
|
unsigned int pdiv;
|
||||||
|
unsigned int mdiv;
|
||||||
|
unsigned int sdiv;
|
||||||
|
unsigned int kdiv;
|
||||||
|
};
|
||||||
|
|
||||||
enum pll45xx_type {
|
enum pll45xx_type {
|
||||||
pll_4500,
|
pll_4500,
|
||||||
pll_4502,
|
pll_4502,
|
||||||
|
|
|
@ -283,10 +283,12 @@ struct samsung_pll_clock {
|
||||||
int con_offset;
|
int con_offset;
|
||||||
int lock_offset;
|
int lock_offset;
|
||||||
enum samsung_pll_type type;
|
enum samsung_pll_type type;
|
||||||
|
const struct samsung_pll_rate_table *rate_table;
|
||||||
const char *alias;
|
const char *alias;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
|
#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \
|
||||||
|
_rtable, _alias) \
|
||||||
{ \
|
{ \
|
||||||
.id = _id, \
|
.id = _id, \
|
||||||
.type = _typ, \
|
.type = _typ, \
|
||||||
|
@ -296,16 +298,17 @@ struct samsung_pll_clock {
|
||||||
.flags = CLK_GET_RATE_NOCACHE, \
|
.flags = CLK_GET_RATE_NOCACHE, \
|
||||||
.con_offset = _con, \
|
.con_offset = _con, \
|
||||||
.lock_offset = _lock, \
|
.lock_offset = _lock, \
|
||||||
|
.rate_table = _rtable, \
|
||||||
.alias = _alias, \
|
.alias = _alias, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLL(_typ, _id, _name, _pname, _lock, _con) \
|
#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
|
||||||
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
||||||
_lock, _con, NULL)
|
_lock, _con, _rtable, _name)
|
||||||
|
|
||||||
#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias) \
|
#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
|
||||||
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
||||||
_lock, _con, _alias)
|
_lock, _con, _rtable, _alias)
|
||||||
|
|
||||||
extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
|
extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
|
||||||
unsigned long nr_clks, unsigned long *rdump,
|
unsigned long nr_clks, unsigned long *rdump,
|
||||||
|
|
Loading…
Add table
Reference in a new issue