meson8b clock driver rewrite/cleanup
Subsystems (6)
cover meson8b clock driver rewrite/cleanup
This series came about while writing the clock driver for the AmLogic GXBB clock controller. GXBB shares much of the same clock controller IP as the Meson8b clock controller and the source for the drivers is very similar. However, I wanted the GXBB driver to actually be a real platform_driver, and not an early initcall, which led to the same changes in the Meson8b driver. From there a lot of other changes came about.
This series improves documentation, refactors statically initialized data, removes unnecessary registration functions and converts the meson8b clock controller code into a proper platform_driver. It also changes up the Kconfig bits to prepare for the gxbb clock controller. The diffstat is -190, which is nice as well.
As a consequence of the shift to platform_driver, all of clocks are registered at module_init time. If any are needed very early during boot then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is necessary.
Additionally this series makes use of some of the nice clk_hw helper introduced by Stephen, especially clk_hw_onecell_data.
Michael Turquette (10):
clk: meson8b: rectify reg offsets with datasheet
clk: meson8b: clean up fixed rate clocks
clk: meson8b: clean up pll clocks
clk: meson8b: clean up fixed factor clocks
clk: meson8b: clean up cpu clocks
clk: meson8b: remove mali clk
clk: meson8b: clean up composite clocks
clk: meson8b: convert to platform_driver
arm: meson: explicitly select clk drivers
clk: meson: only build selected platforms
arch/arm/mach-meson/Kconfig | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/meson/Kconfig | 12 + drivers/clk/meson/Makefile | 4 +- drivers/clk/meson/clk-cpu.c | 73 +----- drivers/clk/meson/clk-pll.c | 72 +---- drivers/clk/meson/clkc.c | 249 ------------------ drivers/clk/meson/clkc.h | 150 ++--------- drivers/clk/meson/meson8b-clkc.c | 436 +++++++++++++++++++++++++------ include/dt-bindings/clock/meson8b-clkc.h | 4 +- 11 files changed, 408 insertions(+), 598 deletions(-) create mode 100644 drivers/clk/meson/Kconfig delete mode 100644 drivers/clk/meson/clkc.c
Signature · 1 line
2.1.4
PATCH 1/10 clk: meson8b: rectify reg offsets with datasheet
The register offsets in the data sheet are confusing. Document them more thoroughly.
--- drivers/clk/meson/meson8b-clkc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/clk/meson/meson8b-clkc.c +12 -3
@@ -24,10 +24,19 @@#include "clkc.h" +/* +* Clock controller register offsets +* +* Register offsets from the HardKernel[0] data sheet are listed in comment +* blocks below. Those offsets must be multiplied by 4 before adding them to +* the base address to get the right value +* +* [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf +*/ #define MESON8B_REG_CTL0_ADDR 0x0000 -#define MESON8B_REG_SYS_CPU_CNTL1 0x015c -#define MESON8B_REG_HHI_MPEG 0x0174 -#define MESON8B_REG_MALI 0x01b0 +#define MESON8B_REG_SYS_CPU_CNTL1 0x015c/* 0x57 offset in data sheet */ +#define MESON8B_REG_HHI_MPEG 0x0174/* 0x5d offset in data sheet */ +#define MESON8B_REG_MALI 0x01b0/* 0x6c offset in data sheet */ #define MESON8B_REG_PLL_FIXED 0x0280#define MESON8B_REG_PLL_SYS 0x0300#define MESON8B_REG_PLL_VID 0x0320
Signature · 1 line
2.1.4
PATCH 2/10 clk: meson8b: clean up fixed rate clocks
In reply to Michael TurquetteRemove the fixed_rate registration function and helpers from clkc.[ch]. Replace unnecessary configuration struct with static initialization of the desired clock type.
While we're here, begin the transition to a proper platform_driver and call of_clk_add_hw_provider with a shiny new struct clk_hw_onecell_data.
--- drivers/clk/meson/clkc.c | 34 -------------------- drivers/clk/meson/clkc.h | 26 --------------- drivers/clk/meson/meson8b-clkc.c | 69 +++++++++++++++++++++++++++++++--------- 3 files changed, 54 insertions(+), 75 deletions(-)
drivers/clk/meson/clkc.c +0 -34
@@ -167,36 +167,6 @@ meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,return clk; } -static struct clk *__init -meson_clk_register_fixed_rate (const struct clk_conf *clk_conf, -void __iomem *clk_base) -{ -struct clk *clk; -const struct fixed_rate_conf *fixed_rate_conf; -const struct parm *r; -unsigned long rate; -u32 reg; - - fixed_rate_conf = &clk_conf->conf.fixed_rate; - rate = fixed_rate_conf->rate; - -if (!rate) { - r = &fixed_rate_conf->rate_parm; - reg =readl (clk_base + clk_conf->reg_off + r->reg_off); - rate =PARM_GET (r->width, r->shift, reg); - } - - rate *=1000000 ; - - clk =clk_register_fixed_rate (NULL , - clk_conf->clk_name, - clk_conf->num_parents - ? clk_conf->clks_parent[0 ] :NULL , - clk_conf->flags, rate); - -return clk; -} -void __init meson_clk_register_clks (const struct clk_conf *clk_confs,unsigned int nr_confs,void __iomem *clk_base)
@@ -208,10 +178,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,const struct clk_conf *clk_conf = &clk_confs[i];switch (clk_conf->clk_type) { -case CLK_FIXED_RATE : - clk =meson_clk_register_fixed_rate (clk_conf, - clk_base); -break ;case CLK_FIXED_FACTOR : clk =meson_clk_register_fixed_factor (clk_conf, clk_base);
drivers/clk/meson/clkc.h +0 -26
@@ -69,11 +69,6 @@ struct fixed_fact_conf {struct parm mult_parm; }; -struct fixed_rate_conf { -unsigned long rate; -struct parm rate_parm; -}; -struct composite_conf {struct parm mux_parm;struct parm div_parm;
@@ -89,7 +84,6 @@ struct composite_conf {enum clk_type {CLK_FIXED_FACTOR , -CLK_FIXED_RATE ,CLK_COMPOSITE ,CLK_CPU ,CLK_PLL ,
@@ -105,32 +99,12 @@ struct clk_conf {unsigned long flags;union {struct fixed_fact_conf fixed_fact; -struct fixed_rate_conf fixed_rate;const struct composite_conf *composite;struct pll_conf *pll;const struct clk_div_table *div_table; } conf; }; -#define FIXED_RATE_P (_ro, _ci, _cn, _f, _c) \ - { \ - .reg_off = (_ro), \ - .clk_type = CLK_FIXED_RATE, \ - .clk_id = (_ci), \ - .clk_name = (_cn), \ - .flags = (_f), \ - .conf.fixed_rate.rate_parm = _c, \ - } \ - -#define FIXED_RATE (_ci, _cn, _f, _r) \ - { \ - .clk_type = CLK_FIXED_RATE, \ - .clk_id = (_ci), \ - .clk_name = (_cn), \ - .flags = (_f), \ - .conf.fixed_rate.rate = (_r), \ - } \ -#define PLL (_ro, _ci, _cn, _cp, _f, _c) \ { \ .reg_off = (_ro), \
drivers/clk/meson/meson8b-clkc.c +54 -15
104 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 3/10 clk: meson8b: clean up pll clocks
In reply to Michael TurquetteRemove the pll registration function and helpers. Replace unnecessary configuration struct with static initialization of the desired clock type.
--- drivers/clk/meson/clk-pll.c | 72 ++++-------------------- drivers/clk/meson/clkc.c | 6 +- drivers/clk/meson/clkc.h | 52 +++++++++--------- drivers/clk/meson/meson8b-clkc.c | 115 ++++++++++++++++++++++++++++++++------- 4 files changed, 131 insertions(+), 114 deletions(-)
drivers/clk/meson/clk-pll.c +11 -61
@@ -44,13 +44,6 @@#define MESON_PLL_RESET BIT(29)#define MESON_PLL_LOCK BIT(31) -struct meson_clk_pll { -struct clk_hw hw; -void __iomem *base; -struct pll_conf *conf; -unsigned int rate_count; -spinlock_t *lock; -};#define to_meson_clk_pll (_hw) container_of(_hw, struct meson_clk_pll, hw) static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
@@ -63,15 +56,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,u16 n, m, od;u32 reg; - p = &pll->conf->n; + p = &pll->n; reg =readl (pll->base + p->reg_off); n =PARM_GET (p->width, p->shift, reg); - p = &pll->conf->m; + p = &pll->m; reg =readl (pll->base + p->reg_off); m =PARM_GET (p->width, p->shift, reg); - p = &pll->conf->od; + p = &pll->od; reg =readl (pll->base + p->reg_off); od =PARM_GET (p->width, p->shift, reg);
@@ -84,7 +77,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) {struct meson_clk_pll *pll =to_meson_clk_pll (hw); -const struct pll_rate_table *rate_table = pll->conf->rate_table; +const struct pll_rate_table *rate_table = pll->rate_table;int i;for (i =0 ; i < pll->rate_count; i++) {
@@ -99,7 +92,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,static const struct pll_rate_table *meson_clk_get_pll_settings (struct meson_clk_pll *pll,unsigned long rate) { -const struct pll_rate_table *rate_table = pll->conf->rate_table; +const struct pll_rate_table *rate_table = pll->rate_table;int i;for (i =0 ; i < pll->rate_count; i++) {
@@ -145,24 +138,24 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,return -EINVAL ;/* PLL reset */ - p = &pll->conf->n; + p = &pll->n; reg =readl (pll->base + p->reg_off);writel (reg |MESON_PLL_RESET , pll->base + p->reg_off); reg =PARM_SET (p->width, p->shift, reg, rate_set->n);writel (reg, pll->base + p->reg_off); - p = &pll->conf->m; + p = &pll->m; reg =readl (pll->base + p->reg_off); reg =PARM_SET (p->width, p->shift, reg, rate_set->m);writel (reg, pll->base + p->reg_off); - p = &pll->conf->od; + p = &pll->od; reg =readl (pll->base + p->reg_off); reg =PARM_SET (p->width, p->shift, reg, rate_set->od);writel (reg, pll->base + p->reg_off); - p = &pll->conf->n; + p = &pll->n; ret =meson_clk_pll_wait_lock (pll, p);if (ret) { pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
@@ -173,55 +166,12 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,return ret; } -static const struct clk_ops meson_clk_pll_ops = { +const struct clk_ops meson_clk_pll_ops = { .recalc_rate = meson_clk_pll_recalc_rate, .round_rate = meson_clk_pll_round_rate, .set_rate = meson_clk_pll_set_rate, }; -static const struct clk_ops meson_clk_pll_ro_ops = { +const struct clk_ops meson_clk_pll_ro_ops = { .recalc_rate = meson_clk_pll_recalc_rate, }; - -struct clk *meson_clk_register_pll (const struct clk_conf *clk_conf, -void __iomem *reg_base, -spinlock_t *lock) -{ -struct clk *clk; -struct meson_clk_pll *clk_pll; -struct clk_init_data init; - - clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); -if (!clk_pll) -return ERR_PTR (-ENOMEM ); - - clk_pll->base = reg_base + clk_conf->reg_off; - clk_pll->lock = lock; - clk_pll->conf = clk_conf->conf.pll; - - init.name = clk_conf->clk_name; - init.flags = clk_conf->flags |CLK_GET_RATE_NOCACHE ; - - init.parent_names = &clk_conf->clks_parent[0 ]; - init.num_parents =1 ; - init.ops = &meson_clk_pll_ro_ops; - -/* If no rate_table is specified we assume the PLL is read-only */ -if (clk_pll->conf->rate_table) { -int len; - -for (len =0 ; clk_pll->conf->rate_table[len].rate !=0 ; ) - len++; - - clk_pll->rate_count = len; - init.ops = &meson_clk_pll_ops; - } - - clk_pll->hw.init = &init; - - clk =clk_register (NULL , &clk_pll->hw); -if (IS_ERR (clk)) -kfree (clk_pll); - -return clk; -}
drivers/clk/meson/clkc.c +1 -5
@@ -21,7 +21,7 @@#include "clkc.h" -static DEFINE_SPINLOCK (clk_lock); +DEFINE_SPINLOCK (clk_lock);static struct clk **clks;static struct clk_onecell_data clk_data;
@@ -190,10 +190,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, clk =meson_clk_register_cpu (clk_conf, clk_base, &clk_lock);break ; -case CLK_PLL : - clk =meson_clk_register_pll (clk_conf, clk_base, - &clk_lock); -break ;default : clk =NULL ; }
drivers/clk/meson/clkc.h +25 -27
87 lines not on this page · raw message
drivers/clk/meson/meson8b-clkc.c +94 -21
153 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 4/10 clk: meson8b: clean up fixed factor clocks
In reply to Michael TurquetteRemove the fixed factor registration function and helpers. Replace unnecessary configuration struct with static initialization of the desired clock type.
--- drivers/clk/meson/clkc.c | 46 ---------------------------- drivers/clk/meson/clkc.h | 19 ------------ drivers/clk/meson/meson8b-clkc.c | 66 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 71 deletions(-)
drivers/clk/meson/clkc.c +0 -46
@@ -125,48 +125,6 @@ error:return clk; } -static struct clk *__init -meson_clk_register_fixed_factor (const struct clk_conf *clk_conf, -void __iomem *clk_base) -{ -struct clk *clk; -const struct fixed_fact_conf *fixed_fact_conf; -const struct parm *p; -unsigned int mult, div; -u32 reg; - - fixed_fact_conf = &clk_conf->conf.fixed_fact; - - mult = clk_conf->conf.fixed_fact.mult; - div = clk_conf->conf.fixed_fact.div; - -if (!mult) { - mult =1 ; - p = &fixed_fact_conf->mult_parm; -if (MESON_PARM_APPLICABLE (p)) { - reg =readl (clk_base + clk_conf->reg_off + p->reg_off); - mult =PARM_GET (p->width, p->shift, reg); - } - } - -if (!div) { - div =1 ; - p = &fixed_fact_conf->div_parm; -if (MESON_PARM_APPLICABLE (p)) { - reg =readl (clk_base + clk_conf->reg_off + p->reg_off); - mult =PARM_GET (p->width, p->shift, reg); - } - } - - clk =clk_register_fixed_factor (NULL , - clk_conf->clk_name, - clk_conf->clks_parent[0 ], - clk_conf->flags, - mult, div); - -return clk; -} -void __init meson_clk_register_clks (const struct clk_conf *clk_confs,unsigned int nr_confs,void __iomem *clk_base)
@@ -178,10 +136,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,const struct clk_conf *clk_conf = &clk_confs[i];switch (clk_conf->clk_type) { -case CLK_FIXED_FACTOR : - clk =meson_clk_register_fixed_factor (clk_conf, - clk_base); -break ;case CLK_COMPOSITE : clk =meson_clk_register_composite (clk_conf, clk_base);
drivers/clk/meson/clkc.h +0 -19
@@ -69,13 +69,6 @@ struct meson_clk_pll {#define to_meson_clk_pll (_hw) container_of(_hw, struct meson_clk_pll, hw) -struct fixed_fact_conf { -unsigned int div; -unsigned int mult; -struct parm div_parm; -struct parm mult_parm; -}; -struct composite_conf {struct parm mux_parm;struct parm div_parm;
@@ -90,7 +83,6 @@ struct composite_conf {#define PNAME (x) static const char *x[]enum clk_type { -CLK_FIXED_FACTOR ,CLK_COMPOSITE ,CLK_CPU , };
@@ -104,22 +96,11 @@ struct clk_conf {int num_parents;unsigned long flags;union { -struct fixed_fact_conf fixed_fact;const struct composite_conf *composite;const struct clk_div_table *div_table; } conf; }; -#define FIXED_FACTOR_DIV (_ci, _cn, _cp, _f, _d) \ - { \ - .clk_type = CLK_FIXED_FACTOR, \ - .clk_id = (_ci), \ - .clk_name = (_cn), \ - .clks_parent = (_cp), \ - .num_parents = ARRAY_SIZE(_cp), \ - .conf.fixed_fact.div = (_d), \ - } \ -#define CPU (_ro, _ci, _cn, _cp, _dt) \ { \ .reg_off = (_ro), \
drivers/clk/meson/meson8b-clkc.c +60 -6
85 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 5/10 clk: meson8b: clean up cpu clocks
In reply to Michael TurquetteRemove the cpu clock registration function and helpers. Replace unnecessary configuration struct with static initialization of the desired clock type.
Ninja rename a5_clk to cpu_clk to better align with cpufreq convention.
--- drivers/clk/meson/clk-cpu.c | 73 +++------------------------------------- drivers/clk/meson/clkc.c | 4 --- drivers/clk/meson/clkc.h | 25 ++++++-------- drivers/clk/meson/meson8b-clkc.c | 47 ++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 90 deletions(-)
drivers/clk/meson/clk-cpu.c +4 -69
@@ -51,13 +51,6 @@#include "clkc.h" -struct meson_clk_cpu { -struct notifier_block clk_nb; -const struct clk_div_table *div_table; -struct clk_hw hw; -void __iomem *base; -u16 reg_off; -};#define to_meson_clk_cpu_hw (_hw) container_of(_hw, struct meson_clk_cpu, hw)#define to_meson_clk_cpu_nb (_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
@@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,return parent_rate / div; } +/* FIXME MUX1 & MUX2 should be struct clk_hw objects */ static int meson_clk_cpu_pre_rate_change (struct meson_clk_cpu *clk_cpu,struct clk_notifier_data *ndata) {
@@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,return 0 ; } +/* FIXME MUX1 & MUX2 should be struct clk_hw objects */ static int meson_clk_cpu_post_rate_change (struct meson_clk_cpu *clk_cpu,struct clk_notifier_data *ndata) {
@@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,* PLL clock is to be changed. We use the xtal input as temporary parent * while the PLL frequency is stabilized. */ -static int meson_clk_cpu_notifier_cb (struct notifier_block *nb, +int meson_clk_cpu_notifier_cb (struct notifier_block *nb,unsigned long event,void *data) {struct clk_notifier_data *ndata = data;
@@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,return notifier_from_errno (ret); } -static const struct clk_ops meson_clk_cpu_ops = { +const struct clk_ops meson_clk_cpu_ops = { .recalc_rate = meson_clk_cpu_recalc_rate, .round_rate = meson_clk_cpu_round_rate, .set_rate = meson_clk_cpu_set_rate, }; - -struct clk *meson_clk_register_cpu (const struct clk_conf *clk_conf, -void __iomem *reg_base, -spinlock_t *lock) -{ -struct clk *clk; -struct clk *pclk; -struct meson_clk_cpu *clk_cpu; -struct clk_init_data init; -int ret; - - clk_cpu =kzalloc (sizeof (*clk_cpu),GFP_KERNEL ); -if (!clk_cpu) -return ERR_PTR (-ENOMEM ); - - clk_cpu->base = reg_base; - clk_cpu->reg_off = clk_conf->reg_off; - clk_cpu->div_table = clk_conf->conf.div_table; - clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb; - - init.name = clk_conf->clk_name; - init.ops = &meson_clk_cpu_ops; - init.flags = clk_conf->flags |CLK_GET_RATE_NOCACHE ; - init.flags |=CLK_SET_RATE_PARENT ; - init.parent_names = clk_conf->clks_parent; - init.num_parents =1 ; - - clk_cpu->hw.init = &init; - - pclk =__clk_lookup (clk_conf->clks_parent[0 ]); -if (!pclk) { -pr_err ("%s: could not lookup parent clock %s\n" , - __func__, clk_conf->clks_parent[0 ]); - ret = -EINVAL ; - goto free_clk; - } - - ret =clk_notifier_register (pclk, &clk_cpu->clk_nb); -if (ret) { -pr_err ("%s: failed to register clock notifier for %s\n" , - __func__, clk_conf->clk_name); - goto free_clk; - } - - clk =clk_register (NULL , &clk_cpu->hw); -if (IS_ERR (clk)) { - ret =PTR_ERR (clk); - goto unregister_clk_nb; - } - -return clk; - -unregister_clk_nb: -clk_notifier_unregister (pclk, &clk_cpu->clk_nb); -free_clk: -kfree (clk_cpu); - -return ERR_PTR (ret); -} -
drivers/clk/meson/clkc.c +0 -4
@@ -140,10 +140,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, clk =meson_clk_register_composite (clk_conf, clk_base);break ; -case CLK_CPU : - clk =meson_clk_register_cpu (clk_conf, clk_base, - &clk_lock); -break ;default : clk =NULL ; }
drivers/clk/meson/clkc.h +11 -14
@@ -69,6 +69,14 @@ struct meson_clk_pll {#define to_meson_clk_pll (_hw) container_of(_hw, struct meson_clk_pll, hw) +struct meson_clk_cpu { +struct clk_hw hw; +void __iomem *base; +u16 reg_off; +struct notifier_block clk_nb; +const struct clk_div_table *div_table; +}; +struct composite_conf {struct parm mux_parm;struct parm div_parm;
@@ -84,7 +92,6 @@ struct composite_conf {enum clk_type {CLK_COMPOSITE , -CLK_CPU , };struct clk_conf {
@@ -101,17 +108,6 @@ struct clk_conf { } conf; }; -#define CPU (_ro, _ci, _cn, _cp, _dt) \ - { \ - .reg_off = (_ro), \ - .clk_type = CLK_CPU, \ - .clk_id = (_ci), \ - .clk_name = (_cn), \ - .clks_parent = (_cp), \ - .num_parents = ARRAY_SIZE(_cp), \ - .conf.div_table = (_dt), \ - } \ -#define COMPOSITE (_ro, _ci, _cn, _cp, _f, _c) \ { \ .reg_off = (_ro), \
@@ -127,8 +123,8 @@ struct clk_conf {struct clk **meson_clk_init (struct device_node *np,unsigned long nr_clks);void meson_clk_register_clks (const struct clk_conf *clk_confs,unsigned int nr_confs,void __iomem *clk_base); -struct clk *meson_clk_register_cpu (const struct clk_conf *clk_conf, -void __iomem *reg_base,spinlock_t *lock); +int meson_clk_cpu_notifier_cb (struct notifier_block *nb,unsigned long event, +void *data);/* shared data */ extern spinlock_t clk_lock;
@@ -136,5 +132,6 @@ extern spinlock_t clk_lock;/* clk_ops */ extern const struct clk_ops meson_clk_pll_ro_ops;extern const struct clk_ops meson_clk_pll_ops; +extern const struct clk_ops meson_clk_cpu_ops;#endif /* __CLKC_H */
drivers/clk/meson/meson8b-clkc.c +44 -3
96 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 6/10 clk: meson8b: remove mali clk
In reply to Michael TurquetteThis clock is undocumented and always orphaned. Get rid of it until we have more complete clock tree documentation.
--- drivers/clk/meson/meson8b-clkc.c | 22 ---------------------- 1 file changed, 22 deletions(-)
drivers/clk/meson/meson8b-clkc.c +0 -22
@@ -112,11 +112,8 @@ static const struct clk_div_table cpu_div_table[] = { };PNAME (p_clk81) = {"fclk_div3" ,"fclk_div4" ,"fclk_div5" }; -PNAME (p_mali) = {"fclk_div3" ,"fclk_div4" ,"fclk_div5" , -"fclk_div7" ,"zero" };static u32 mux_table_clk81[] = {6 ,5 ,7 }; -static u32 mux_table_mali[] = {6 ,5 ,7 ,4 ,0 };static const struct composite_conf clk81_conf__initconst = { .mux_table = mux_table_clk81,
@@ -126,13 +123,6 @@ static const struct composite_conf clk81_conf __initconst = { .gate_parm = PARM(0x00, 7, 1), }; -static const struct composite_conf mali_conf__initconst = { - .mux_table = mux_table_mali, - .mux_parm =PARM (0x00 ,9 ,3 ), - .div_parm =PARM (0x00 ,0 ,7 ), - .gate_parm =PARM (0x00 ,8 ,1 ), -}; -static struct clk_fixed_rate meson8b_xtal = { .fixed_rate =24000000 , .hw.init = &(struct clk_init_data ){
@@ -142,15 +132,6 @@ static struct clk_fixed_rate meson8b_xtal = { }, }; -static struct clk_fixed_rate meson8b_zero = { - .fixed_rate =0 , - .hw.init = &(struct clk_init_data ){ - .name ="zero" , - .num_parents =0 , - .ops = &clk_fixed_rate_ops, - }, -}; -static struct meson_clk_pll meson8b_fixed_pll = { .m = { .reg_off =MESON8B_REG_PLL_FIXED ,
@@ -301,8 +282,6 @@ static struct meson_clk_cpu meson8b_cpu_clk = {static const struct clk_conf meson8b_clk_confs[]__initconst = {COMPOSITE (MESON8B_REG_HHI_MPEG ,CLKID_CLK81 ,"clk81" , p_clk81,CLK_SET_RATE_NO_REPARENT |CLK_IGNORE_UNUSED , &clk81_conf), -COMPOSITE (MESON8B_REG_MALI ,CLKID_MALI ,"mali" , p_mali, -CLK_IGNORE_UNUSED , &mali_conf), };/*
@@ -315,7 +294,6 @@ static const struct clk_conf meson8b_clk_confs[] __initconst = {static struct clk_hw_onecell_data meson8b_hw_onecell_data = { .hws = { [CLKID_XTAL ] = &meson8b_xtal.hw, - [CLKID_ZERO ] = &meson8b_zero.hw, [CLKID_PLL_FIXED ] = &meson8b_fixed_pll.hw, [CLKID_PLL_VID ] = &meson8b_vid_pll.hw, [CLKID_PLL_SYS ] = &meson8b_sys_pll.hw,
Signature · 1 line
2.1.4
PATCH 7/10 clk: meson8b: clean up composite clocks
In reply to Michael TurquetteRemove the composite clock registration function and helpers. Replace unnecessary configuration struct with static initialization of the desired clock type.
To preserve git bisect this patch also flips the switch and starts using of_clk_add_hw_provider instead of the deprecated meson_clk_register_clks method. As a byproduct clk.c can be deleted.
--- drivers/clk/meson/Makefile | 2 +- drivers/clk/meson/clkc.c | 161 ------------------------------- drivers/clk/meson/clkc.h | 56 ----------- drivers/clk/meson/meson8b-clkc.c | 93 ++++++++++++------ include/dt-bindings/clock/meson8b-clkc.h | 4 +- 5 files changed, 69 insertions(+), 247 deletions(-) delete mode 100644 drivers/clk/meson/clkc.c
drivers/clk/meson/Makefile +1 -1
@@ -2,5 +2,5 @@ # Makefile for Meson specific clk # -obj-y += clkc.o clk-pll.o clk-cpu.o +obj-y += clk-pll.o clk-cpu.o obj-y += meson8b-clkc.o
drivers/clk/meson/clkc.c deleted +0 -161
161 lines not on this page · raw message
drivers/clk/meson/clkc.h +0 -56
71 lines not on this page · raw message
drivers/clk/meson/meson8b-clkc.c +65 -28
143 lines not on this page · raw message
include/dt-bindings/clock/meson8b-clkc.h +3 -1
@@ -19,7 +19,9 @@#define CLKID_MALI 11#define CLKID_CPUCLK 12#define CLKID_ZERO 13 +#define CLKID_MPEG_SEL 14 +#define CLKID_MPEG_DIV 15 -#define CLK_NR_CLKS (CLKID_ZERO + 1) +#define CLK_NR_CLKS (CLKID_MPEG_DIV + 1)#endif /* __MESON8B_CLKC_H */
Signature · 1 line
2.1.4
PATCH 8/10 clk: meson8b: convert to platform_driver
In reply to Michael TurquetteThis patch creates a proper platform_driver for the meson8b clock controller. Use of CLK_OF_DECLARE is removed, and can be added back in later if very early registration of some clocks is required.
--- drivers/clk/meson/meson8b-clkc.c | 67 +++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 18 deletions(-)
drivers/clk/meson/meson8b-clkc.c +49 -18
@@ -2,6 +2,9 @@* Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione <[email protected]> * +* Copyright (c) 2016 BayLibre, Inc. +* Michael Turquette <[email protected]> +* * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation.
@@ -17,11 +20,10 @@#include <linux/clk.h> #include <linux/clk-provider.h> -#include <linux/kernel.h> -#include <linux/of.h> #include <linux/of_address.h> -#include <linux/slab.h> #include <dt-bindings/clock/meson8b-clkc.h> +#include <linux/platform_device.h> +#include <linux/module.h> #include "clkc.h"
@@ -350,18 +352,19 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = { &meson8b_sys_pll, }; -static void __init meson8b_clkc_init (struct device_node *np) +static int meson8b_clkc_probe (struct platform_device *pdev) {void __iomem *clk_base;int ret, clkid, i;struct clk_hw *parent_hw;struct clk *parent_clk; +struct device *dev = &pdev->dev;/* Generic clocks and PLLs */ - clk_base =of_iomap (np,1 ); + clk_base =of_iomap (dev->of_node,1 );if (!clk_base) {pr_err ("%s: Unable to map clk base\n" , __func__); -return ; +return -ENXIO ; }/* Populate base address for PLLs */
@@ -386,9 +389,9 @@ static void __init meson8b_clkc_init(struct device_node *np)continue ;/* FIXME convert to devm_clk_register */ - ret =clk_hw_register (NULL , meson8b_hw_onecell_data.hws[clkid]); + ret =devm_clk_hw_register (dev, meson8b_hw_onecell_data.hws[clkid]);if (ret) - goto unregister; + goto iounmap; }/*
@@ -411,17 +414,45 @@ static void __init meson8b_clkc_init(struct device_node *np)if (ret) {pr_err ("%s: failed to register clock notifier for cpu_clk\n" , __func__); - goto unregister_clk_nb; + goto iounmap; } -of_clk_add_hw_provider (np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data); -return ; +return of_clk_add_hw_provider (dev->of_node, of_clk_hw_onecell_get, + &meson8b_hw_onecell_data); -/* FIXME remove after converting to platform_driver/devm_clk_register */ -unregister_clk_nb: -clk_notifier_unregister (parent_clk, &meson8b_a5_clk.clk_nb); -unregister: -for (clkid =CLK_NR_CLKS -1 ; clkid >=0 ; clkid--) -clk_hw_unregister (meson8b_hw_onecell_data.hws[clkid]); +iounmap: +iounmap (clk_base); +return ret; } -CLK_OF_DECLARE (meson8b_clock,"amlogic,meson8b-clkc" , meson8b_clkc_init); + +static const struct of_device_id meson8b_clkc_match_table[] = { + { .compatible ="amlogic,meson8b-clkc" }, + { } +}; +MODULE_DEVICE_TABLE (of, meson8b_match_table); + +static struct platform_driver meson8b_driver = { + .probe = meson8b_clkc_probe, + .driver = { + .name ="meson8b-clkc" , + .of_match_table = meson8b_clkc_match_table, + }, +}; + +static int __init meson8b_clkc_init (void ) +{ +return platform_driver_register (&meson8b_driver); +} +module_init (meson8b_clkc_init); + +static void __exit meson8b_clkc_exit(void) +{ +platform_driver_unregister (&meson8b_driver); +} +module_exit (meson8b_clkc_exit); + +MODULE_DESCRIPTION ("AmLogic S805 / Meson8b Clock Controller Driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:meson8b-clkc" ); +MODULE_AUTHOR ("Michael Turquette <[email protected]>" ); +MODULE_AUTHOR ("Carlo Caione <[email protected]>" );
Signature · 1 line
2.1.4
PATCH 9/10 arm: meson: explicitly select clk drivers
In reply to Michael TurquetteThe AmLogic clock controller code is used by both arm and arm64 architectures. Explicitly select the core code for all Meson (32-bit arm) builds, and also select the Meson8b driver when that machine is built.
--- arch/arm/mach-meson/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/mach-meson/Kconfig +3 -0
@@ -7,6 +7,8 @@ menuconfig ARCH_MESON select CACHE_L2X0 select PINCTRL select PINCTRL_MESON + select COMMON_CLK + select COMMON_CLK_AMLOGIC if ARCH_MESON
@@ -24,5 +26,6 @@ config MACH_MESON8B bool "Amlogic Meson8b SoCs support" default ARCH_MESON select MESON6_TIMER + select COMMON_CLK_MESON8B endif
Signature · 1 line
2.1.4
PATCH 10/10 clk: meson: only build selected platforms
In reply to Michael TurquetteBreak the AmLogic clock code up so that only the necessary parts are compiled and linked. The core code is selected by both arm and arm64 builds with COMMON_CLK_AMLOGIC. The individual drivers have their own config options as well.
--- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/meson/Kconfig | 12 ++++++++++++ drivers/clk/meson/Makefile | 4 ++-- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 drivers/clk/meson/Kconfig
drivers/clk/Kconfig +1 -0
@@ -208,6 +208,7 @@ config COMMON_CLK_OXNAS source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" +source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig"
drivers/clk/Makefile +1 -1
@@ -65,7 +65,7 @@ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/ endif obj-y += mvebu/ -obj-$(CONFIG_ARCH_MESON) += meson/ +obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_NXP) += nxp/
drivers/clk/meson/Kconfig new file +12 -0
@@ -0,0 +1,12 @@ +config COMMON_CLK_AMLOGIC + bool + depends on OF + depends on ARCH_MESON || COMPILE_TEST + +config COMMON_CLK_MESON8B + bool + depends on COMMON_CLK_AMLOGIC + help + Support for the clock controller on AmLogic S805 devices, aka + meson8b. Say Y if you want peripherals and CPU frequency scaling to + work.
drivers/clk/meson/Makefile +2 -2
@@ -2,5 +2,5 @@ # Makefile for Meson specific clk # -obj-y += clk-pll.o clk-cpu.o -obj-y += meson8b-clkc.o +obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o +obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o
Signature · 1 line
2.1.4
Kevin Hilman
maintainercover meson8b clock driver rewrite/cleanup
In reply to Michael TurquetteQuoted 14 lines · Michael Turquette
This series came about while writing the clock driver for the AmLogic GXBB clock controller. GXBB shares much of the same clock controller IP as the Meson8b clock controller and the source for the drivers is very similar. However, I wanted the GXBB driver to actually be a real
platform_driver, and not an early initcall, which led to the same changes in the Meson8b driver. From there a lot of other changes came about.This series improves documentation, refactors statically initialized data, removes unnecessary registration functions and converts the meson8b clock controller code into a proper
platform_driver. It also changes up theKconfigbits to prepare for the gxbb clock controller. The diffstat is -190, which is nice as well.
Quoted 7 lines
As a consequence of the shift to
platform_driver, all of clocks are registered atmodule_inittime. If any are needed very early during boot then theOF_CLK_DECLAREstuff can be added back in, but I doubt it is necessary.Additionally this series makes use of some of the nice
clk_hwhelper introduced by Stephen, especiallyclk_hw_onecell_data.
Not sure if it qualifies as much of a clock test, but I at least boot tested this on meson8b-odroidc1 and nothing exploded, and the clk_summary looks sane:
/ # cat /debug/clk/clk_summary
clock enable_cnt prepare_cnt rate accuracy phase
----------------------------------------------------------------------------------------
xtal 0 0 24000000 0 0
sys_pll 0 0 1200000000 0 0
cpu_clk 0 0 1200000000 0 0
vid_pll 0 0 732000000 0 0
fixed_pll 0 0 2550000000 0 0
fclk_div7 0 0 364285714 0 0
fclk_div5 0 0 510000000 0 0
fclk_div4 0 0 637500000 0 0
mpeg_clk_sel 0 0 637500000 0 0
mpeg_clk_div 0 0 159375000 0 0
clk81 0 0 159375000 0 0
fclk_div3 0 0 850000000 0 0
fclk_div2 0 0 1275000000 0 0Kevin
cover meson8b clock driver rewrite/cleanup
Quoting Kevin Hilman (2016-06-14 12:12:50)
Quoted 31 lines
Quoted 14 lines · Michael Turquette
This series came about while writing the clock driver for the AmLogic GXBB clock controller. GXBB shares much of the same clock controller IP as the Meson8b clock controller and the source for the drivers is very similar. However, I wanted the GXBB driver to actually be a real
platform_driver, and not an early initcall, which led to the same changes in the Meson8b driver. From there a lot of other changes came about.This series improves documentation, refactors statically initialized data, removes unnecessary registration functions and converts the meson8b clock controller code into a proper
platform_driver. It also changes up theKconfigbits to prepare for the gxbb clock controller. The diffstat is -190, which is nice as well.Quoted 7 lines
As a consequence of the shift to
platform_driver, all of clocks are registered atmodule_inittime. If any are needed very early during boot then theOF_CLK_DECLAREstuff can be added back in, but I doubt it is necessary.Additionally this series makes use of some of the nice
clk_hwhelper introduced by Stephen, especiallyclk_hw_onecell_data.Not sure if it qualifies as much of a clock test, but I at least boot tested this on meson8b-odroidc1 and nothing exploded, and the
clk_summarylooks sane:/ # cat /debug/clk/clk_summary
clockenable_cntprepare_cntrate accuracy phase
----------------------------------------------------------------------------------------
Quoted 13 lines
xtal 0 0 24000000 0 0
sys_pll 0 0 1200000000 0 0
cpu_clk 0 0 1200000000 0 0
vid_pll 0 0 732000000 0 0
fixed_pll 0 0 2550000000 0 0
fclk_div7 0 0 364285714 0 0
fclk_div5 0 0 510000000 0 0
fclk_div4 0 0 637500000 0 0
mpeg_clk_sel 0 0 637500000 0 0
mpeg_clk_div 0 0 159375000 0 0
clk81 0 0 159375000 0 0
fclk_div3 0 0 850000000 0 0
fclk_div2 0 0 1275000000 0 0Thanks Kevin. I'll take that as a Tested-by.
Regards,
Mike
Quoted 2 lines
Kevin
Michael Turquette
Appliedcover meson8b clock driver rewrite/cleanup
In reply to Michael TurquetteQuoting Michael Turquette (2016-06-09 17:27:37)
Quoted 7 lines
This series came about while writing the clock driver for the AmLogic GXBB clock controller. GXBB shares much of the same clock controller IP as the Meson8b clock controller and the source for the drivers is very similar. However, I wanted the GXBB driver to actually be a real
platform_driver, and not an early initcall, which led to the same changes in the Meson8b driver. From there a lot of other changes came about.
Applied to clk-next.
Regards,
Mike
Quoted 45 lines
This series improves documentation, refactors statically initialized data, removes unnecessary registration functions and converts the meson8b clock controller code into a proper
platform_driver. It also changes up theKconfigbits to prepare for the gxbb clock controller. The diffstat is -190, which is nice as well.As a consequence of the shift to
platform_driver, all of clocks are registered atmodule_inittime. If any are needed very early during boot then theOF_CLK_DECLAREstuff can be added back in, but I doubt it is necessary.Additionally this series makes use of some of the nice
clk_hwhelper introduced by Stephen, especiallyclk_hw_onecell_data.Michael Turquette (10):
clk: meson8b: rectify reg offsets with datasheet
clk: meson8b: clean up fixed rate clocks
clk: meson8b: clean up pll clocks
clk: meson8b: clean up fixed factor clocks
clk: meson8b: clean up cpu clocks
clk: meson8b: remove mali clk
clk: meson8b: clean up composite clocks
clk: meson8b: convert toplatform_driver
arm: meson: explicitly select clk drivers
clk: meson: only build selected platformsarch/arm/mach-meson/Kconfig | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/meson/Kconfig | 12 + drivers/clk/meson/Makefile | 4 +- drivers/clk/meson/clk-cpu.c | 73 +----- drivers/clk/meson/clk-pll.c | 72 +---- drivers/clk/meson/clkc.c | 249 ------------------ drivers/clk/meson/clkc.h | 150 ++--------- drivers/clk/meson/meson8b-clkc.c | 436 +++++++++++++++++++++++++------ include/dt-bindings/clock/meson8b-clkc.h | 4 +- 11 files changed, 408 insertions(+), 598 deletions(-) create mode 100644 drivers/clk/meson/Kconfig delete mode 100644 drivers/clk/meson/clkc.cSignature · 1 line
2.1.4