Re: [PATCH 4/5] clk: Add driver for Bitmain BM1880 SoC clock controller

2019-08-17 Thread Stephen Boyd
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

2019-08-16 Thread Manivannan Sadhasivam
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

2019-08-07 Thread Stephen Boyd
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

2019-07-05 Thread Manivannan Sadhasivam
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