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@xxxxxxxxxxxx> Signed-off-by: Yadwinder Singh Brar <yadi.brar@xxxxxxxxxxx> --- drivers/clk/samsung/clk-exynos4.c | 8 ++++---- drivers/clk/samsung/clk-exynos5250.c | 14 +++++++------- drivers/clk/samsung/clk-exynos5420.c | 22 +++++++++++----------- drivers/clk/samsung/clk-pll.c | 22 ++++++++++++++++++++-- drivers/clk/samsung/clk-pll.h | 27 +++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 14 +++++++++----- 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index ba25a1b..ceee66c 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -997,13 +997,13 @@ static __initdata struct of_device_id ext_clk_match[] = { struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = { [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", - 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_CON0, "fout_epll"), + EPLL_CON0, "fout_epll", NULL), [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 */ diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index dc6a700..21f5491 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -492,19 +492,19 @@ static __initdata struct of_device_id ext_clk_match[] = { struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = { [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_CON0, "fout_mpll"), + MPLL_CON0, "fout_mpll", NULL), [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_CON0), + GPLL_CON0, NULL), [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_CON0), + EPLL_CON0, NULL), [vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK, - VPLL_CON0), + VPLL_CON0, NULL), }; /* register exynox5250 clocks */ diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 3ea6b4f..86dfc64 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -729,27 +729,27 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = { [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, - MPLL_CON0), + MPLL_CON0, NULL), [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_CON0), + EPLL_CON0, NULL), [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_CON0), + IPLL_CON0, NULL), [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_CON0), + VPLL_CON0, NULL), [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_CON0), + BPLL_CON0, NULL), [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[] = { diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index f132353..b2088dd 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -18,6 +18,8 @@ struct samsung_clk_pll { void __iomem *lock_reg; void __iomem *con_reg; 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) @@ -350,7 +352,7 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list, struct clk *clk; struct clk_init_data init; struct samsung_pll_clock *list = clk_list; - int cnt; + int cnt, len; for (cnt = 0; cnt < nr_pll; cnt++, list++) { pll = kzalloc(sizeof(*pll), GFP_KERNEL); @@ -365,6 +367,21 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list, init.parent_names = &list->parent_name; init.num_parents = 1; + if (list->rate_table) { + /* find count of rates in rate_table */ + for (len = 0; list->rate_table[len].rate != 0; ) + len++; + + pll->rate_count = len; + pll->rate_table = kmemdup(list->rate_table, + list->rate_count * + sizeof(struct samsung_pll_rate_table), + GFP_KERNEL); + WARN(!pll->rate_table, + "%s: could not allocate rate table for %s\n", + __func__, list->name); + } + switch (list->type) { /* clk_ops for 35xx and 2550 are similar */ case pll_35xx: @@ -396,10 +413,11 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list, samsung_clk_add_lookup(clk, list->id); - if (list->alias) + if (list->alias) { if (clk_register_clkdev(clk, list->alias, list->dev_name)) pr_err("%s: failed to register lookup for %s", __func__, list->name); + } } } diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index 1536f27..95ae23d 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -19,6 +19,33 @@ enum samsung_pll_type { 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 { pll_4500, pll_4502, diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 51f60ca..3e6501c 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -280,10 +280,13 @@ struct samsung_pll_clock { const int con_offset; const int lock_offset; enum samsung_pll_type type; + const struct samsung_pll_rate_table *rate_table; + unsigned int rate_count; 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, \ .type = _typ, \ @@ -293,16 +296,17 @@ struct samsung_pll_clock { .flags = CLK_GET_RATE_NOCACHE, \ .con_offset = _con, \ .lock_offset = _lock, \ + .rate_table = _rtable, \ .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, \ - _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, \ - _lock, _con, _alias) + _lock, _con, _rtable, _alias) extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks, unsigned long *rdump, -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html