mbox series

[v5,00/12] Add clock driver for Actions S900 SoC

Message ID 20180317100952.28538-1-manivannan.sadhasivam@linaro.org
Headers show
Series Add clock driver for Actions S900 SoC | expand

Message

Manivannan Sadhasivam March 17, 2018, 10:09 a.m. UTC
This patchset adds clock support for Actions Semi OWL series
S900 SoC with relevant clock bindings and device tree info.

Driver has been validated on Bubblegum-96 board.

Thanks,
Mani

Changes in V5:

* Changed I2C clocks to fixed factor clocks
* Fixed minor issue in S900 PLL clock names
* Fixed S900 Kconfig
* Rebased on top of 4.16-rc5

Changes in V4:

* Moved to SPDX license tag for dt-bindings
* Fixed a warning in owl-common.h
* Rebased on top of 4.16-rc3

Changes in V3:

* Completely refactored the clock driver based on sunxi-ng
  clock structure
* Removed all owl_ prefixed functions for registering the
  clock driver and used the registration functions directly
* Moved to SPDX based license tag
* Removed module dependencies from the driver
* Made I2C clocks as simple gate clocks due to the lack of
  information about factor rates
* Added Ack from Rob for DT bindings
* Sourced CMU clock for UART5

Changes in V2: (https://lkml.org/lkml/2017/11/6/840)

* Changed the directory structure to actions/ and used owl- prefix
  for sources.
* Fixed MAINTAINERS and added Andreas as Designated Reviewer (R:).
* Introduced new Kconfig for S900 code part (CONFIG_CLK_OWL_S900).
* Changed the license from GPLv2 to GPLv2+.
* Moved fixed clock sources to DT
* Changed clock-controller node name to cmu in DT
* Added clocks property to cmu node in DT
* Changed compatible property value to "actions,s900-cmu"
* Fixed example UART controller node in documentation
* Fixed tab vs space issue

Changes in V1: (https://lkml.org/lkml/2017/10/31/808)

* Addressed last year's review comments from Stephen
* https://patchwork.kernel.org/patch/9254471/

Manivannan Sadhasivam (12):
  dt-bindings: clock: Add Actions S900 clock bindings
  arm64: dts: actions: Add S900 clock management unit nodes
  arm64: dts: actions: Source CMU clock for UART5
  clk: actions: Add common clock driver support
  clk: actions: Add gate clock support
  clk: actions: Add mux clock support
  clk: actions: Add divider clock support
  clk: actions: Add factor clock support
  clk: actions: Add fixed factor clock support
  clk: actions: Add composite clock support
  clk: actions: Add pll clock support
  clk: actions: Add S900 SoC clock support

 .../devicetree/bindings/clock/actions,s900-cmu.txt |  47 ++
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  |   8 +-
 arch/arm64/boot/dts/actions/s900.dtsi              |  20 +
 drivers/clk/Kconfig                                |   1 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/actions/Kconfig                        |  14 +
 drivers/clk/actions/Makefile                       |  13 +
 drivers/clk/actions/owl-common.c                   |  84 +++
 drivers/clk/actions/owl-common.h                   |  41 ++
 drivers/clk/actions/owl-composite.c                | 200 ++++++
 drivers/clk/actions/owl-composite.h                | 118 ++++
 drivers/clk/actions/owl-divider.c                  |  94 +++
 drivers/clk/actions/owl-divider.h                  |  75 +++
 drivers/clk/actions/owl-factor.c                   | 222 +++++++
 drivers/clk/actions/owl-factor.h                   |  83 +++
 drivers/clk/actions/owl-fixed-factor.c             |  81 +++
 drivers/clk/actions/owl-fixed-factor.h             |  62 ++
 drivers/clk/actions/owl-gate.c                     |  77 +++
 drivers/clk/actions/owl-gate.h                     |  73 +++
 drivers/clk/actions/owl-mux.c                      |  60 ++
 drivers/clk/actions/owl-mux.h                      |  61 ++
 drivers/clk/actions/owl-pll.c                      | 194 ++++++
 drivers/clk/actions/owl-pll.h                      |  92 +++
 drivers/clk/actions/owl-s900.c                     | 690 +++++++++++++++++++++
 drivers/clk/actions/owl-s900.h                     |  61 ++
 include/dt-bindings/clock/actions,s900-cmu.h       | 129 ++++
 26 files changed, 2594 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/actions,s900-cmu.txt
 create mode 100644 drivers/clk/actions/Kconfig
 create mode 100644 drivers/clk/actions/Makefile
 create mode 100644 drivers/clk/actions/owl-common.c
 create mode 100644 drivers/clk/actions/owl-common.h
 create mode 100644 drivers/clk/actions/owl-composite.c
 create mode 100644 drivers/clk/actions/owl-composite.h
 create mode 100644 drivers/clk/actions/owl-divider.c
 create mode 100644 drivers/clk/actions/owl-divider.h
 create mode 100644 drivers/clk/actions/owl-factor.c
 create mode 100644 drivers/clk/actions/owl-factor.h
 create mode 100644 drivers/clk/actions/owl-fixed-factor.c
 create mode 100644 drivers/clk/actions/owl-fixed-factor.h
 create mode 100644 drivers/clk/actions/owl-gate.c
 create mode 100644 drivers/clk/actions/owl-gate.h
 create mode 100644 drivers/clk/actions/owl-mux.c
 create mode 100644 drivers/clk/actions/owl-mux.h
 create mode 100644 drivers/clk/actions/owl-pll.c
 create mode 100644 drivers/clk/actions/owl-pll.h
 create mode 100644 drivers/clk/actions/owl-s900.c
 create mode 100644 drivers/clk/actions/owl-s900.h
 create mode 100644 include/dt-bindings/clock/actions,s900-cmu.h

-- 
2.14.1

Comments

Stephen Boyd March 20, 2018, 1:10 a.m. UTC | #1
Quoting Manivannan Sadhasivam (2018-03-17 03:09:49)
> Add support for Actions Semi fixed factor clock together with

> helper functions to be used in composite clock.

> 

> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

> ---

>  drivers/clk/actions/Makefile           |  1 +

>  drivers/clk/actions/owl-fixed-factor.c | 81 ++++++++++++++++++++++++++++++++++

>  drivers/clk/actions/owl-fixed-factor.h | 62 ++++++++++++++++++++++++++

>  3 files changed, 144 insertions(+)

>  create mode 100644 drivers/clk/actions/owl-fixed-factor.c

>  create mode 100644 drivers/clk/actions/owl-fixed-factor.h

> 

> diff --git a/drivers/clk/actions/Makefile b/drivers/clk/actions/Makefile

> index 994357fa560b..b618696ba54e 100644

> --- a/drivers/clk/actions/Makefile

> +++ b/drivers/clk/actions/Makefile

> @@ -5,3 +5,4 @@ clk-owl-y                       += owl-gate.o

>  clk-owl-y                      += owl-mux.o

>  clk-owl-y                      += owl-divider.o

>  clk-owl-y                      += owl-factor.o

> +clk-owl-y                      += owl-fixed-factor.o

> diff --git a/drivers/clk/actions/owl-fixed-factor.c b/drivers/clk/actions/owl-fixed-factor.c

> new file mode 100644

> index 000000000000..f1281565129c

> --- /dev/null

> +++ b/drivers/clk/actions/owl-fixed-factor.c

> @@ -0,0 +1,81 @@

> +// SPDX-License-Identifier: GPL-2.0+

> +//

> +// OWL fixed factor clock driver

> +//

> +// Copyright (c) 2014 Actions Semi Inc.

> +// Author: David Liu <liuwei@actions-semi.com>

> +//

> +// Copyright (c) 2018 Linaro Ltd.

> +// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

> +

> +#include <linux/clk-provider.h>

> +#include <linux/regmap.h>

> +#include <linux/slab.h>

> +

> +#include "owl-fixed-factor.h"

> +

> +long owl_fix_fact_helper_round_rate(struct owl_clk_common *common,

> +                               const struct owl_fix_fact_hw *fix_fact_hw,

> +                               unsigned long rate,

> +                               unsigned long *parent_rate)

> +{

> +       if (clk_hw_get_flags(&common->hw) & CLK_SET_RATE_PARENT) {

> +               unsigned long best_parent;

> +

> +               best_parent = (rate / fix_fact_hw->mul) * fix_fact_hw->div;

> +               *parent_rate = clk_hw_round_rate(clk_hw_get_parent(&common->hw),

> +                                                       best_parent);

> +       }

> +

> +       return (*parent_rate / fix_fact_hw->div) * fix_fact_hw->mul;

> +}

> +

> +static long owl_fix_fact_round_rate(struct clk_hw *hw, unsigned long rate,

> +                       unsigned long *parent_rate)

> +{

> +       struct owl_fix_fact *fix_fact = hw_to_owl_fix_fact(hw);

> +       struct owl_fix_fact_hw *fix_fact_hw = &fix_fact->fix_fact_hw;

> +

> +       return owl_fix_fact_helper_round_rate(&fix_fact->common, fix_fact_hw,

> +                                                       rate, parent_rate);

> +}

> +

> +unsigned long owl_fix_fact_helper_recalc_rate(struct owl_clk_common *common,

> +                       const struct owl_fix_fact_hw *fix_fact_hw,

> +                       unsigned long parent_rate)

> +{

> +       unsigned long long int rate;

> +

> +       rate = (unsigned long long int)parent_rate * fix_fact_hw->mul;

> +       do_div(rate, fix_fact_hw->div);

> +

> +       return (unsigned long)rate;


You can drop the cast.

> +}

> +

> +static unsigned long owl_fix_fact_recalc_rate(struct clk_hw *hw,

> +                       unsigned long parent_rate)

> +{

> +       struct owl_fix_fact *fix_fact = hw_to_owl_fix_fact(hw);

> +       struct owl_fix_fact_hw *fix_fact_hw = &fix_fact->fix_fact_hw;

> +

> +       return owl_fix_fact_helper_recalc_rate(&fix_fact->common, fix_fact_hw,

> +                                                       parent_rate);

> +}

> +

> +static int owl_fix_fact_set_rate(struct clk_hw *hw, unsigned long rate,

> +                              unsigned long parent_rate)

> +{

> +       /*

> +        * We must report success but we can do so unconditionally because

> +        * clk_fix_fact_round_rate returns values that ensure this call is a


What function is that?

> +        * nop.

> +        */

> +

> +       return 0;

> +}

> +

> +const struct clk_ops owl_fix_fact_ops = {

> +       .round_rate     = owl_fix_fact_round_rate,

> +       .recalc_rate    = owl_fix_fact_recalc_rate,

> +       .set_rate       = owl_fix_fact_set_rate,

> +};


Why can't you use the regular fixed factor clk code and ops?
Manivannan Sadhasivam March 20, 2018, 9:04 a.m. UTC | #2
Hi Stephen,

On Mon, Mar 19, 2018 at 06:10:03PM -0700, Stephen Boyd wrote:
> Quoting Manivannan Sadhasivam (2018-03-17 03:09:49)

> > Add support for Actions Semi fixed factor clock together with

> > helper functions to be used in composite clock.

> > 

> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

> > ---

> >  drivers/clk/actions/Makefile           |  1 +

> >  drivers/clk/actions/owl-fixed-factor.c | 81 ++++++++++++++++++++++++++++++++++

> >  drivers/clk/actions/owl-fixed-factor.h | 62 ++++++++++++++++++++++++++

> >  3 files changed, 144 insertions(+)

> >  create mode 100644 drivers/clk/actions/owl-fixed-factor.c

> >  create mode 100644 drivers/clk/actions/owl-fixed-factor.h

> > 

> > diff --git a/drivers/clk/actions/Makefile b/drivers/clk/actions/Makefile

> > index 994357fa560b..b618696ba54e 100644

> > --- a/drivers/clk/actions/Makefile

> > +++ b/drivers/clk/actions/Makefile

> > @@ -5,3 +5,4 @@ clk-owl-y                       += owl-gate.o

> >  clk-owl-y                      += owl-mux.o

> >  clk-owl-y                      += owl-divider.o

> >  clk-owl-y                      += owl-factor.o

> > +clk-owl-y                      += owl-fixed-factor.o

> > diff --git a/drivers/clk/actions/owl-fixed-factor.c b/drivers/clk/actions/owl-fixed-factor.c

> > new file mode 100644

> > index 000000000000..f1281565129c

> > --- /dev/null

> > +++ b/drivers/clk/actions/owl-fixed-factor.c

> > @@ -0,0 +1,81 @@

> > +// SPDX-License-Identifier: GPL-2.0+

> > +//

> > +// OWL fixed factor clock driver

> > +//

> > +// Copyright (c) 2014 Actions Semi Inc.

> > +// Author: David Liu <liuwei@actions-semi.com>

> > +//

> > +// Copyright (c) 2018 Linaro Ltd.

> > +// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

> > +

> > +#include <linux/clk-provider.h>

> > +#include <linux/regmap.h>

> > +#include <linux/slab.h>

> > +

> > +#include "owl-fixed-factor.h"

> > +

> > +long owl_fix_fact_helper_round_rate(struct owl_clk_common *common,

> > +                               const struct owl_fix_fact_hw *fix_fact_hw,

> > +                               unsigned long rate,

> > +                               unsigned long *parent_rate)

> > +{

> > +       if (clk_hw_get_flags(&common->hw) & CLK_SET_RATE_PARENT) {

> > +               unsigned long best_parent;

> > +

> > +               best_parent = (rate / fix_fact_hw->mul) * fix_fact_hw->div;

> > +               *parent_rate = clk_hw_round_rate(clk_hw_get_parent(&common->hw),

> > +                                                       best_parent);

> > +       }

> > +

> > +       return (*parent_rate / fix_fact_hw->div) * fix_fact_hw->mul;

> > +}

> > +

> > +static long owl_fix_fact_round_rate(struct clk_hw *hw, unsigned long rate,

> > +                       unsigned long *parent_rate)

> > +{

> > +       struct owl_fix_fact *fix_fact = hw_to_owl_fix_fact(hw);

> > +       struct owl_fix_fact_hw *fix_fact_hw = &fix_fact->fix_fact_hw;

> > +

> > +       return owl_fix_fact_helper_round_rate(&fix_fact->common, fix_fact_hw,

> > +                                                       rate, parent_rate);

> > +}

> > +

> > +unsigned long owl_fix_fact_helper_recalc_rate(struct owl_clk_common *common,

> > +                       const struct owl_fix_fact_hw *fix_fact_hw,

> > +                       unsigned long parent_rate)

> > +{

> > +       unsigned long long int rate;

> > +

> > +       rate = (unsigned long long int)parent_rate * fix_fact_hw->mul;

> > +       do_div(rate, fix_fact_hw->div);

> > +

> > +       return (unsigned long)rate;

> 

> You can drop the cast.

> 


Okay.

> > +}

> > +

> > +static unsigned long owl_fix_fact_recalc_rate(struct clk_hw *hw,

> > +                       unsigned long parent_rate)

> > +{

> > +       struct owl_fix_fact *fix_fact = hw_to_owl_fix_fact(hw);

> > +       struct owl_fix_fact_hw *fix_fact_hw = &fix_fact->fix_fact_hw;

> > +

> > +       return owl_fix_fact_helper_recalc_rate(&fix_fact->common, fix_fact_hw,

> > +                                                       parent_rate);

> > +}

> > +

> > +static int owl_fix_fact_set_rate(struct clk_hw *hw, unsigned long rate,

> > +                              unsigned long parent_rate)

> > +{

> > +       /*

> > +        * We must report success but we can do so unconditionally because

> > +        * clk_fix_fact_round_rate returns values that ensure this call is a

> 

> What function is that?

>


It should be owl_fix_fact_round_rate.

> > +        * nop.

> > +        */

> > +

> > +       return 0;

> > +}

> > +

> > +const struct clk_ops owl_fix_fact_ops = {

> > +       .round_rate     = owl_fix_fact_round_rate,

> > +       .recalc_rate    = owl_fix_fact_recalc_rate,

> > +       .set_rate       = owl_fix_fact_set_rate,

> > +};

> 

> Why can't you use the regular fixed factor clk code and ops?

>


That's going to be really messy. Since I'm having the clk_hw embedded inside
owl_clk_common and using it for registering all the clocks, using generic
fixed factor functions will be a different approach _only_ for this clock and
it won't look good I guess. Also, it may become complicated with composite
clocks.

If you still want to use the generic fixed factor code, I can do that in
next revision.

Your views?

Thanks,
Mani