Re: [PATCH 4/5] clk: Add driver for Bitmain BM1880 SoC clock controller
Quoting Manivannan Sadhasivam (2019-08-16 20:55:57) > Hi Stephen, > > On Wed, Aug 07, 2019 at 10:15:59PM -0700, Stephen Boyd wrote: > > Quoting Manivannan Sadhasivam (2019-07-05 08:14:39) > > > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig > > > index fc1e0cf44995..ffc61ed85ade 100644 > > > --- a/drivers/clk/Kconfig > > > +++ b/drivers/clk/Kconfig > > > @@ -304,6 +304,12 @@ config COMMON_CLK_FIXED_MMIO > > > help > > > Support for Memory Mapped IO Fixed clocks > > > > > > +config COMMON_CLK_BM1880 > > > + bool "Clock driver for Bitmain BM1880 SoC" > > > + depends on ARCH_BITMAIN || COMPILE_TEST > > > + help > > > + This driver supports the clocks on Bitmain BM1880 SoC. > > > > Can you add this config somewhere else besides the end? Preferably > > close to alphabetically in this file. > > > > Okay. I got confused by the fact that Makefile is sorted but not the > Kconfig. Ok. I'll make a reminder to sort the Kconfig after -rc1 next time. > > > > + > > > source "drivers/clk/actions/Kconfig" > > > source "drivers/clk/analogbits/Kconfig" > > > source "drivers/clk/bcm/Kconfig" > > > diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c > > > new file mode 100644 > > > index ..26cdb75bb936 > > > --- /dev/null > > > +++ b/drivers/clk/clk-bm1880.c [] > > > + > > > +struct clk *bm1880_clk_register_pll(const struct bm1880_pll_clock > > > *pll_clk, > > > + void __iomem *sys_base) > > > +{ > > > + struct bm1880_pll_hw_clock *pll_hw; > > > + struct clk_init_data init; > > > + struct clk_hw *hw; > > > + int err; > > > + > > > + pll_hw = kzalloc(sizeof(*pll_hw), GFP_KERNEL); > > > + if (!pll_hw) > > > + return ERR_PTR(-ENOMEM); > > > + > > > + init.name = pll_clk->name; > > > + init.ops = &bm1880_pll_ops; > > > + init.flags = pll_clk->flags; > > > + init.parent_names = &pll_clk->parent; > > > > Can you use the new way of specifying parents instead of using strings > > for everything? > > > > Sure, will do it for clocks which doesn't use helper APIs. > > > > + init.num_parents = 1; > > > + > > > + pll_hw->hw.init = &init; > > > + pll_hw->pll.reg = pll_clk->reg; > > > + pll_hw->base = sys_base; > > > + > > > + hw = &pll_hw->hw; > > > + err = clk_hw_register(NULL, hw); > > > + > > > + if (err) { > > > + kfree(pll_hw); > > > + return ERR_PTR(err); > > > + } > > > + > > > + return hw->clk; > > > > Can this return the clk_hw pointer instead? > > > > What is the benefit? I see that only hw:init is going to be NULL in future. Eventually we will remove ->clk from struct clk_hw and then this will break. It also clearly makes this driver a clk provider driver and not a clk consumer. > So, I'll keep it as it is. Please no! > > > + > > > bm1880_clk_unregister_pll(data->clk_data.clks[clks[i].id]); > > > + > > > + return PTR_ERR(clk); > > > +} > > > + > > > +int bm1880_clk_register_mux(const struct bm1880_mux_clock *clks, > > > + int num_clks, struct bm1880_clock_data *data) > > > +{ > > > + struct clk *clk; > > > + void __iomem *sys_base = data->sys_base; > > > + int i; > > > + > > > + for (i = 0; i < num_clks; i++) { > > > + clk = clk_register_mux(NULL, clks[i].name, > > > > Can you use the clk_hw based APIs for generic type clks? > > > > IMO using helper APIs greatly reduce code size and makes the driver > look more clean. So I prefer to use the helpers wherever applicable. > When you plan to deprecate those, I'll switch over to plain clk_hw APIs. We have clk_hw_register_mux(). Please use it. The clk based registration APIs are deprecated. > > > + kfree(clk_data); > > > +} > > > + > > > +CLK_OF_DECLARE_DRIVER(bm1880_clk, "bitmain,bm1880-clk", bm1880_clk_init); > > > > Is there a reason why it can't be a platform driver? > > > > Hmm, I looked into the majority of drivers which live under `driver/clk/`. > Most of them are using CLK_OF_DECLARE_DRIVER, so I thought that only drivers > which have a separate directory are preferred by the maintainers to use > platform driver way. > > Anyway, I can switch over to platform driver and that's what I prefer. > Yes please use a platform driver unless it doesn't work for some reason. Even then, use a platform driver and CLK_OF_DECLARE_DRIVER() in conjunction to register the early clks from the OF_DECLARED section and then adopt the rest to the proper device driver later on. This way we gain the benefits of driver core.
Re: [PATCH 4/5] clk: Add driver for Bitmain BM1880 SoC clock controller
Hi Stephen, On Wed, Aug 07, 2019 at 10:15:59PM -0700, Stephen Boyd wrote: > Quoting Manivannan Sadhasivam (2019-07-05 08:14:39) > > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig > > index fc1e0cf44995..ffc61ed85ade 100644 > > --- a/drivers/clk/Kconfig > > +++ b/drivers/clk/Kconfig > > @@ -304,6 +304,12 @@ config COMMON_CLK_FIXED_MMIO > > help > > Support for Memory Mapped IO Fixed clocks > > > > +config COMMON_CLK_BM1880 > > + bool "Clock driver for Bitmain BM1880 SoC" > > + depends on ARCH_BITMAIN || COMPILE_TEST > > + help > > + This driver supports the clocks on Bitmain BM1880 SoC. > > Can you add this config somewhere else besides the end? Preferably > close to alphabetically in this file. > Okay. I got confused by the fact that Makefile is sorted but not the Kconfig. > > + > > source "drivers/clk/actions/Kconfig" > > source "drivers/clk/analogbits/Kconfig" > > source "drivers/clk/bcm/Kconfig" > > diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c > > new file mode 100644 > > index ..26cdb75bb936 > > --- /dev/null > > +++ b/drivers/clk/clk-bm1880.c > > @@ -0,0 +1,947 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Bitmain BM1880 SoC clock driver > > + * > > + * Copyright (c) 2019 Linaro Ltd. > > + * Author: Manivannan Sadhasivam > > + */ > > + > > +#include > > +#include > > +#include > > Should probably add kernel.h for at least container_of() > okay. > > + > > +#include > > + > > +#define BM1880_CLK_MPLL_CTL0x00 > > +#define BM1880_CLK_SPLL_CTL0x04 > > +#define BM1880_CLK_FPLL_CTL0x08 > > +#define BM1880_CLK_DDRPLL_CTL 0x0c > > + > > +#define BM1880_CLK_ENABLE0 0x00 > > +#define BM1880_CLK_ENABLE1 0x04 > > +#define BM1880_CLK_SELECT 0x20 > > +#define BM1880_CLK_DIV00x40 > > +#define BM1880_CLK_DIV10x44 > > +#define BM1880_CLK_DIV20x48 > > +#define BM1880_CLK_DIV30x4c > > +#define BM1880_CLK_DIV40x50 > > +#define BM1880_CLK_DIV50x54 > > +#define BM1880_CLK_DIV60x58 > > +#define BM1880_CLK_DIV70x5c > > +#define BM1880_CLK_DIV80x60 > > +#define BM1880_CLK_DIV90x64 > > +#define BM1880_CLK_DIV10 0x68 > > +#define BM1880_CLK_DIV11 0x6c > > +#define BM1880_CLK_DIV12 0x70 > > +#define BM1880_CLK_DIV13 0x74 > > +#define BM1880_CLK_DIV14 0x78 > > +#define BM1880_CLK_DIV15 0x7c > > +#define BM1880_CLK_DIV16 0x80 > > +#define BM1880_CLK_DIV17 0x84 > > +#define BM1880_CLK_DIV18 0x88 > > +#define BM1880_CLK_DIV19 0x8c > > +#define BM1880_CLK_DIV20 0x90 > > +#define BM1880_CLK_DIV21 0x94 > > +#define BM1880_CLK_DIV22 0x98 > > +#define BM1880_CLK_DIV23 0x9c > > +#define BM1880_CLK_DIV24 0xa0 > > +#define BM1880_CLK_DIV25 0xa4 > > +#define BM1880_CLK_DIV26 0xa8 > > +#define BM1880_CLK_DIV27 0xac > > +#define BM1880_CLK_DIV28 0xb0 > > + > > +#define to_bm1880_pll_clk(_hw) container_of(_hw, struct > > bm1880_pll_hw_clock, hw) > > +#define to_bm1880_div_clk(_hw) container_of(_hw, struct > > bm1880_div_hw_clock, hw) > > + > > +static DEFINE_SPINLOCK(bm1880_clk_lock); > > + > > +struct bm1880_clock_data { > > + void __iomem *pll_base; > > + void __iomem *sys_base; > > + struct clk_onecell_data clk_data; > > +}; > > + > > +struct bm1880_gate_clock { > > + unsigned intid; > > + const char *name; > > + const char *parent; > > + u32 gate_reg; > > + s8 gate_shift; > > + unsigned long flags; > > +}; > > + > > +struct bm1880_mux_clock { > > + unsigned intid; > > + const char *name; > > + const char * const * parents; > > + s8 num_parents; > > + u32 reg; > > + s8 shift; > > + unsigned long flags; > > +}; > > + > > +struct bm1880_div_clock { > > + unsigned intid; > > + const char *name; > > + const char *parent; > > + u32 reg; > > + u8 shift; > > + u8 width; > > + u32 initval; > > + struct clk_div_table *table; > > + unsigned long flags; > > +}; > > + > > +struct bm1880_div_hw_clock { > > + struct bm1880_div_clock div; > > + void __iomem *base; > > + spinlock_t *lock; > > + struct clk_hw hw; > > +}; > > + > > +struct bm1880_composite_clock { > > + unsigned intid; > > + const char *name; > > + const char *parent; > > + const char * const * parents; > > + unsigned intnum_parents; > > + unsigned long flags; > > + > > + u32 gate_reg; > > + u32 mux_reg; > > + u32 div_reg; > > + > > +
Re: [PATCH 4/5] clk: Add driver for Bitmain BM1880 SoC clock controller
Quoting Manivannan Sadhasivam (2019-07-05 08:14:39) > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig > index fc1e0cf44995..ffc61ed85ade 100644 > --- a/drivers/clk/Kconfig > +++ b/drivers/clk/Kconfig > @@ -304,6 +304,12 @@ config COMMON_CLK_FIXED_MMIO > help > Support for Memory Mapped IO Fixed clocks > > +config COMMON_CLK_BM1880 > + bool "Clock driver for Bitmain BM1880 SoC" > + depends on ARCH_BITMAIN || COMPILE_TEST > + help > + This driver supports the clocks on Bitmain BM1880 SoC. Can you add this config somewhere else besides the end? Preferably close to alphabetically in this file. > + > source "drivers/clk/actions/Kconfig" > source "drivers/clk/analogbits/Kconfig" > source "drivers/clk/bcm/Kconfig" > diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c > new file mode 100644 > index ..26cdb75bb936 > --- /dev/null > +++ b/drivers/clk/clk-bm1880.c > @@ -0,0 +1,947 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Bitmain BM1880 SoC clock driver > + * > + * Copyright (c) 2019 Linaro Ltd. > + * Author: Manivannan Sadhasivam > + */ > + > +#include > +#include > +#include Should probably add kernel.h for at least container_of() > + > +#include > + > +#define BM1880_CLK_MPLL_CTL0x00 > +#define BM1880_CLK_SPLL_CTL0x04 > +#define BM1880_CLK_FPLL_CTL0x08 > +#define BM1880_CLK_DDRPLL_CTL 0x0c > + > +#define BM1880_CLK_ENABLE0 0x00 > +#define BM1880_CLK_ENABLE1 0x04 > +#define BM1880_CLK_SELECT 0x20 > +#define BM1880_CLK_DIV00x40 > +#define BM1880_CLK_DIV10x44 > +#define BM1880_CLK_DIV20x48 > +#define BM1880_CLK_DIV30x4c > +#define BM1880_CLK_DIV40x50 > +#define BM1880_CLK_DIV50x54 > +#define BM1880_CLK_DIV60x58 > +#define BM1880_CLK_DIV70x5c > +#define BM1880_CLK_DIV80x60 > +#define BM1880_CLK_DIV90x64 > +#define BM1880_CLK_DIV10 0x68 > +#define BM1880_CLK_DIV11 0x6c > +#define BM1880_CLK_DIV12 0x70 > +#define BM1880_CLK_DIV13 0x74 > +#define BM1880_CLK_DIV14 0x78 > +#define BM1880_CLK_DIV15 0x7c > +#define BM1880_CLK_DIV16 0x80 > +#define BM1880_CLK_DIV17 0x84 > +#define BM1880_CLK_DIV18 0x88 > +#define BM1880_CLK_DIV19 0x8c > +#define BM1880_CLK_DIV20 0x90 > +#define BM1880_CLK_DIV21 0x94 > +#define BM1880_CLK_DIV22 0x98 > +#define BM1880_CLK_DIV23 0x9c > +#define BM1880_CLK_DIV24 0xa0 > +#define BM1880_CLK_DIV25 0xa4 > +#define BM1880_CLK_DIV26 0xa8 > +#define BM1880_CLK_DIV27 0xac > +#define BM1880_CLK_DIV28 0xb0 > + > +#define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, > hw) > +#define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, > hw) > + > +static DEFINE_SPINLOCK(bm1880_clk_lock); > + > +struct bm1880_clock_data { > + void __iomem *pll_base; > + void __iomem *sys_base; > + struct clk_onecell_data clk_data; > +}; > + > +struct bm1880_gate_clock { > + unsigned intid; > + const char *name; > + const char *parent; > + u32 gate_reg; > + s8 gate_shift; > + unsigned long flags; > +}; > + > +struct bm1880_mux_clock { > + unsigned intid; > + const char *name; > + const char * const * parents; > + s8 num_parents; > + u32 reg; > + s8 shift; > + unsigned long flags; > +}; > + > +struct bm1880_div_clock { > + unsigned intid; > + const char *name; > + const char *parent; > + u32 reg; > + u8 shift; > + u8 width; > + u32 initval; > + struct clk_div_table *table; > + unsigned long flags; > +}; > + > +struct bm1880_div_hw_clock { > + struct bm1880_div_clock div; > + void __iomem *base; > + spinlock_t *lock; > + struct clk_hw hw; > +}; > + > +struct bm1880_composite_clock { > + unsigned intid; > + const char *name; > + const char *parent; > + const char * const * parents; > + unsigned intnum_parents; > + unsigned long flags; > + > + u32 gate_reg; > + u32 mux_reg; > + u32 div_reg; > + > + s8 gate_shift; > + s8 mux_shift; > + s8 div_shift; > + s8 div_width; > + s16 div_initval; > + struct clk_div_table *table; > +}; > + > +struct bm1880_pll_clock { > + unsigned intid; > + const char *name; > + const char *parent; > + u32 reg; > + unsigned long flags; > +}; > + > +struct bm1880_pll_hw_cloc
[PATCH 4/5] clk: Add driver for Bitmain BM1880 SoC clock controller
Add common clock driver for Bitmain BM1880 SoC clock controller. Signed-off-by: Manivannan Sadhasivam --- drivers/clk/Kconfig | 6 + drivers/clk/Makefile | 1 + drivers/clk/clk-bm1880.c | 947 +++ 3 files changed, 954 insertions(+) create mode 100644 drivers/clk/clk-bm1880.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index fc1e0cf44995..ffc61ed85ade 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -304,6 +304,12 @@ config COMMON_CLK_FIXED_MMIO help Support for Memory Mapped IO Fixed clocks +config COMMON_CLK_BM1880 + bool "Clock driver for Bitmain BM1880 SoC" + depends on ARCH_BITMAIN || COMPILE_TEST + help + This driver supports the clocks on Bitmain BM1880 SoC. + source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" source "drivers/clk/bcm/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 9ef4305d55e0..66c44b84a6f2 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MACH_ASM9260)+= clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)+= clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o +obj-$(CONFIG_COMMON_CLK_BM1880)+= clk-bm1880.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_CLPS711X)+= clk-clps711x.o diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c new file mode 100644 index ..26cdb75bb936 --- /dev/null +++ b/drivers/clk/clk-bm1880.c @@ -0,0 +1,947 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bitmain BM1880 SoC clock driver + * + * Copyright (c) 2019 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include + +#include + +#define BM1880_CLK_MPLL_CTL0x00 +#define BM1880_CLK_SPLL_CTL0x04 +#define BM1880_CLK_FPLL_CTL0x08 +#define BM1880_CLK_DDRPLL_CTL 0x0c + +#define BM1880_CLK_ENABLE0 0x00 +#define BM1880_CLK_ENABLE1 0x04 +#define BM1880_CLK_SELECT 0x20 +#define BM1880_CLK_DIV00x40 +#define BM1880_CLK_DIV10x44 +#define BM1880_CLK_DIV20x48 +#define BM1880_CLK_DIV30x4c +#define BM1880_CLK_DIV40x50 +#define BM1880_CLK_DIV50x54 +#define BM1880_CLK_DIV60x58 +#define BM1880_CLK_DIV70x5c +#define BM1880_CLK_DIV80x60 +#define BM1880_CLK_DIV90x64 +#define BM1880_CLK_DIV10 0x68 +#define BM1880_CLK_DIV11 0x6c +#define BM1880_CLK_DIV12 0x70 +#define BM1880_CLK_DIV13 0x74 +#define BM1880_CLK_DIV14 0x78 +#define BM1880_CLK_DIV15 0x7c +#define BM1880_CLK_DIV16 0x80 +#define BM1880_CLK_DIV17 0x84 +#define BM1880_CLK_DIV18 0x88 +#define BM1880_CLK_DIV19 0x8c +#define BM1880_CLK_DIV20 0x90 +#define BM1880_CLK_DIV21 0x94 +#define BM1880_CLK_DIV22 0x98 +#define BM1880_CLK_DIV23 0x9c +#define BM1880_CLK_DIV24 0xa0 +#define BM1880_CLK_DIV25 0xa4 +#define BM1880_CLK_DIV26 0xa8 +#define BM1880_CLK_DIV27 0xac +#define BM1880_CLK_DIV28 0xb0 + +#define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, hw) +#define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, hw) + +static DEFINE_SPINLOCK(bm1880_clk_lock); + +struct bm1880_clock_data { + void __iomem *pll_base; + void __iomem *sys_base; + struct clk_onecell_data clk_data; +}; + +struct bm1880_gate_clock { + unsigned intid; + const char *name; + const char *parent; + u32 gate_reg; + s8 gate_shift; + unsigned long flags; +}; + +struct bm1880_mux_clock { + unsigned intid; + const char *name; + const char * const * parents; + s8 num_parents; + u32 reg; + s8 shift; + unsigned long flags; +}; + +struct bm1880_div_clock { + unsigned intid; + const char *name; + const char *parent; + u32 reg; + u8 shift; + u8 width; + u32 initval; + struct clk_div_table *table; + unsigned long flags; +}; + +struct bm1880_div_hw_clock { + struct bm1880_div_clock div; + void __iomem *base; + spinlock_t *lock; + struct clk_hw hw; +}; + +struct bm1880_composite_clock { + unsigned intid; + const char *name; + const char *parent; + const char * const * parents; + unsigned intnum_parents; + unsigned long flags; + + u32 gate_reg; + u32 mux_reg; + u32 div_reg