Commit 3ff6e0d8 authored by Yadwinder Singh Brar's avatar Yadwinder Singh Brar Committed by Mike Turquette

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: default avatarDoug Anderson <dianders@chromium.org>
Signed-off-by: default avatarYadwinder Singh Brar <yadi.brar@samsung.com>
Signed-off-by: default avatarMike Turquette <mturquette@linaro.org>
parent 5ca8fbd8
...@@ -986,13 +986,13 @@ static __initdata struct of_device_id ext_clk_match[] = { ...@@ -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 = { ...@@ -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 = { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment