public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Lukasz Majewski <lukma@denx.de>
To: u-boot@lists.denx.de
Subject: [PATCH v3 01/12] clk: Always use the supplied struct clk
Date: Thu, 6 Feb 2020 22:21:52 +0100	[thread overview]
Message-ID: <20200206222152.168a8fec@jawa> (raw)
In-Reply-To: <51a36d85-3b9c-1173-ca6a-8c44fc5b5cc1@gmail.com>

Hi Sean,

> CCF clocks should always use the struct clock passed to their methods
> for extracting the driver-specific clock information struct.
> Previously, many functions would use the clk->dev->priv if the device
> was bound. This could cause problems with composite clocks. The
> individual clocks in a composite clock did not have the ->dev field
> filled in. This was fine, because the device-specific clock
> information would be used. However, since there was no ->dev, there
> was no way to get the parent clock. This caused the recalc_rate
> method of the CCF divider clock to fail. One option would be to use
> the clk->priv field to get the composite clock and from there get the
> appropriate parent device. However, this would tie the implementation
> to the composite clock. In general, different devices should not rely
> on the contents of ->priv from another device.
> 
> The simple solution to this problem is to just always use the
> supplied struct clock. The composite clock now fills in the ->dev
> pointer of its child clocks. This allows child clocks to make calls
> like clk_get_parent() without issue.
> 
> imx avoided the above problem by using a custom get_rate function
> with composite clocks.
> 
> Signed-off-by: Sean Anderson <seanga2@gmail.com>

Thank you Sean for your CCF enhancement and updating the ccf.txt
documentation entry.

Acked-by: Lukasz Majewski <lukma@denx.de>

I don't mind if RISC-V SoC maintainer pulls the whole series (including
CCF patches).

> ---
>   Changes for v3:
>   - Documented new assumptions in the CCF
>   - Wrapped docs to 80 columns
> 
>  doc/imx/clk/ccf.txt            | 63
> +++++++++++++++++----------------- drivers/clk/clk-composite.c    |
> 8 +++++ drivers/clk/clk-divider.c      |  6 ++--
>  drivers/clk/clk-fixed-factor.c |  3 +-
>  drivers/clk/clk-gate.c         |  6 ++--
>  drivers/clk/clk-mux.c          | 12 +++----
>  drivers/clk/imx/clk-gate2.c    |  4 +--
>  7 files changed, 51 insertions(+), 51 deletions(-)
> 
> diff --git a/doc/imx/clk/ccf.txt b/doc/imx/clk/ccf.txt
> index 36b60dc438..e40ac360e8 100644
> --- a/doc/imx/clk/ccf.txt
> +++ b/doc/imx/clk/ccf.txt
> @@ -1,42 +1,37 @@
>  Introduction:
>  =============
>  
> -This documentation entry describes the Common Clock Framework [CCF]
> -port from Linux kernel (v5.1.12) to U-Boot.
> +This documentation entry describes the Common Clock Framework [CCF]
> port from +Linux kernel (v5.1.12) to U-Boot.
>  
> -This code is supposed to bring CCF to IMX based devices (imx6q, imx7
> -imx8). Moreover, it also provides some common clock code, which would
> -allow easy porting of CCF Linux code to other platforms.
> +This code is supposed to bring CCF to IMX based devices (imx6q, imx7
> imx8). +Moreover, it also provides some common clock code, which
> would allow easy +porting of CCF Linux code to other platforms.
>  
>  Design decisions:
>  =================
>  
> -* U-Boot's driver model [DM] for clk differs from Linux CCF. The most
> -  notably difference is the lack of support for hierarchical clocks
> and
> -  "clock as a manager driver" (single clock DTS node acts as a
> starting
> -  point for all other clocks).
> +* U-Boot's driver model [DM] for clk differs from Linux CCF. The
> most notably
> +  difference is the lack of support for hierarchical clocks and
> "clock as a
> +  manager driver" (single clock DTS node acts as a starting point
> for all other
> +  clocks).
>  
> -* The clk_get_rate() caches the previously read data if
> CLK_GET_RATE_NOCACHE
> -  is not set (no need for recursive access).
> +* The clk_get_rate() caches the previously read data if
> CLK_GET_RATE_NOCACHE is
> +  not set (no need for recursive access).
>  
> -* On purpose the "manager" clk driver (clk-imx6q.c) is not using
> large
> -  table to store pointers to clocks - e.g.
> clk[IMX6QDL_CLK_USDHC2_SEL] = ....
> -  Instead we use udevice's linked list for the same class
> (UCLASS_CLK). +* On purpose the "manager" clk driver (clk-imx6q.c) is
> not using large table to
> +  store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = ....
> Instead we
> +  use udevice's linked list for the same class (UCLASS_CLK).
>  
>    Rationale:
>    ----------
> -    When porting the code as is from Linux, one would need ~1KiB of
> RAM to
> -    store it. This is way too much if we do plan to use this driver
> in SPL.
> +    When porting the code as is from Linux, one would need ~1KiB of
> RAM to store
> +    it. This is way too much if we do plan to use this driver in SPL.
>  
>  * The "central" structure of this patch series is struct udevice and
> its uclass_priv field contains the struct clk pointer (to the
> originally created one).
>  
> -* Up till now U-Boot's driver model (DM) CLK operates on udevice
> (main
> -  access to clock is by udevice ops)
> -  In the CCF the access to struct clk (embodying pointer to *dev) is
> -  possible via dev_get_clk_ptr() (it is a wrapper on
> dev_get_uclass_priv()). -
>  * To keep things simple the struct udevice's uclass_priv pointer is
> used to store back pointer to corresponding struct clk. However, it
> is possible to modify clk-uclass.c file and add there struct
> uc_clk_priv, which would have @@ -45,13 +40,17 @@ Design decisions:
>    setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv))
> the uclass_priv stores the pointer to struct clk.
>  
> +* Non-CCF clocks do not have a pointer to a clock in clk->dev->priv.
> In the case
> +  of composite clocks, clk->dev->priv may not match clk. Drivers
> should always
> +  use the struct clk which is passed to them, and not clk->dev->priv.
> +
>  * It is advised to add common clock code (like already added rate
> and flags) to the struct clk, which is a top level description of the
> clock. 
>  * U-Boot's driver model already provides the facility to
> automatically allocate
> -  (via private_alloc_size) device private data (accessible via
> dev->priv).
> -  It may look appealing to use this feature to allocate private
> structures for
> -  CCF clk devices e.g. divider (struct clk_divider *divider) for
> IMX6Q clock.
> +  (via private_alloc_size) device private data (accessible via
> dev->priv). It
> +  may look appealing to use this feature to allocate private
> structures for CCF
> +  clk devices e.g. divider (struct clk_divider *divider) for IMX6Q
> clock. 
>    The above feature had not been used for following reasons:
>    - The original CCF Linux kernel driver is the "manager" for clocks
> - it @@ -64,21 +63,23 @@ Design decisions:
>  
>  * I've added the clk_get_parent(), which reads parent's
> dev->uclass_priv to provide parent's struct clk pointer. This seems
> the easiest way to get
> -  child/parent relationship for struct clk in U-Boot's udevice based
> clocks.
> +  child/parent relationship for struct clk in U-Boot's udevice based
> clocks.  In
> +  the future arbitrary parents may be supported by adding a
> get_parent function
> +  to clk_ops.
>  
>  * Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in
> 'struct clk'. Clock IP block agnostic flags from 'struct clk_core'
> (e.g. NOCACHE) have been
> -  moved from this struct one level up to 'struct clk'.
> +  moved from this struct one level up to 'struct clk'. Many flags are
> +  unimplemented at the moment.
>  
>  * For tests the new ./test/dm/clk_ccf.c and
> ./drivers/clk/clk_sandbox_ccf.c files have been introduced. The
> latter setups the CCF clock structure for
> -  sandbox by reusing, if possible, generic clock primitives - like
> divier
> -  and mux. The former file provides code to tests this setup.
> +  sandbox by reusing, if possible, generic clock primitives - like
> divier and
> +  mux. The former file provides code to tests this setup.
>  
>    For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been
> introduced.
> -  All new primitives added for new architectures must have
> corresponding test
> -  in the two aforementioned files.
> -
> +  All new primitives added for new architectures must have
> corresponding test in
> +  the two aforementioned files.
>  
>  Testing (sandbox):
>  ==================
> diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
> index a5626c33d1..d0f273d47f 100644
> --- a/drivers/clk/clk-composite.c
> +++ b/drivers/clk/clk-composite.c
> @@ -145,6 +145,14 @@ struct clk *clk_register_composite(struct device
> *dev, const char *name, goto err;
>  	}
>  
> +	if (composite->mux)
> +		composite->mux->dev = clk->dev;
> +	if (composite->rate)
> +		composite->rate->dev = clk->dev;
> +	if (composite->gate)
> +		composite->gate->dev = clk->dev;
> +
> +
>  	return clk;
>  
>  err:
> diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
> index 822e09b084..bfa05f24a3 100644
> --- a/drivers/clk/clk-divider.c
> +++ b/drivers/clk/clk-divider.c
> @@ -70,8 +70,7 @@ unsigned long divider_recalc_rate(struct clk *hw,
> unsigned long parent_rate, 
>  static ulong clk_divider_recalc_rate(struct clk *clk)
>  {
> -	struct clk_divider *divider =
> to_clk_divider(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_divider *divider = to_clk_divider(clk);
>  	unsigned long parent_rate = clk_get_parent_rate(clk);
>  	unsigned int val;
>  
> @@ -150,8 +149,7 @@ int divider_get_val(unsigned long rate, unsigned
> long parent_rate, 
>  static ulong clk_divider_set_rate(struct clk *clk, unsigned long
> rate) {
> -	struct clk_divider *divider =
> to_clk_divider(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_divider *divider = to_clk_divider(clk);
>  	unsigned long parent_rate = clk_get_parent_rate(clk);
>  	int value;
>  	u32 val;
> diff --git a/drivers/clk/clk-fixed-factor.c
> b/drivers/clk/clk-fixed-factor.c index 711b0588bc..d2401cf440 100644
> --- a/drivers/clk/clk-fixed-factor.c
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -18,8 +18,7 @@
>  
>  static ulong clk_factor_recalc_rate(struct clk *clk)
>  {
> -	struct clk_fixed_factor *fix =
> -		to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
> +	struct clk_fixed_factor *fix = to_clk_fixed_factor(clk);
>  	unsigned long parent_rate = clk_get_parent_rate(clk);
>  	unsigned long long int rate;
>  
> diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
> index 70b8794554..b2933bc24a 100644
> --- a/drivers/clk/clk-gate.c
> +++ b/drivers/clk/clk-gate.c
> @@ -43,8 +43,7 @@
>   */
>  static void clk_gate_endisable(struct clk *clk, int enable)
>  {
> -	struct clk_gate *gate = to_clk_gate(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_gate *gate = to_clk_gate(clk);
>  	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
>  	u32 reg;
>  
> @@ -86,8 +85,7 @@ static int clk_gate_disable(struct clk *clk)
>  
>  int clk_gate_is_enabled(struct clk *clk)
>  {
> -	struct clk_gate *gate = to_clk_gate(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_gate *gate = to_clk_gate(clk);
>  	u32 reg;
>  
>  #if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
> diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
> index 5acc0b8cbd..67b4afef28 100644
> --- a/drivers/clk/clk-mux.c
> +++ b/drivers/clk/clk-mux.c
> @@ -35,8 +35,7 @@
>  int clk_mux_val_to_index(struct clk *clk, u32 *table, unsigned int
> flags, unsigned int val)
>  {
> -	struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_mux *mux = to_clk_mux(clk);
>  	int num_parents = mux->num_parents;
>  
>  	if (table) {
> @@ -79,8 +78,7 @@ unsigned int clk_mux_index_to_val(u32 *table,
> unsigned int flags, u8 index) 
>  u8 clk_mux_get_parent(struct clk *clk)
>  {
> -	struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_mux *mux = to_clk_mux(clk);
>  	u32 val;
>  
>  #if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
> @@ -97,8 +95,7 @@ u8 clk_mux_get_parent(struct clk *clk)
>  static int clk_fetch_parent_index(struct clk *clk,
>  				  struct clk *parent)
>  {
> -	struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_mux *mux = to_clk_mux(clk);
>  
>  	int i;
>  
> @@ -115,8 +112,7 @@ static int clk_fetch_parent_index(struct clk *clk,
>  
>  static int clk_mux_set_parent(struct clk *clk, struct clk *parent)
>  {
> -	struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ?
> -			dev_get_clk_ptr(clk->dev) : clk);
> +	struct clk_mux *mux = to_clk_mux(clk);
>  	int index;
>  	u32 val;
>  	u32 reg;
> diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
> index 1b9db6e791..e32c0cb53e 100644
> --- a/drivers/clk/imx/clk-gate2.c
> +++ b/drivers/clk/imx/clk-gate2.c
> @@ -37,7 +37,7 @@ struct clk_gate2 {
>  
>  static int clk_gate2_enable(struct clk *clk)
>  {
> -	struct clk_gate2 *gate =
> to_clk_gate2(dev_get_clk_ptr(clk->dev));
> +	struct clk_gate2 *gate = to_clk_gate2(clk);
>  	u32 reg;
>  
>  	reg = readl(gate->reg);
> @@ -50,7 +50,7 @@ static int clk_gate2_enable(struct clk *clk)
>  
>  static int clk_gate2_disable(struct clk *clk)
>  {
> -	struct clk_gate2 *gate =
> to_clk_gate2(dev_get_clk_ptr(clk->dev));
> +	struct clk_gate2 *gate = to_clk_gate2(clk);
>  	u32 reg;
>  
>  	reg = readl(gate->reg);




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20200206/d62c0e29/attachment.sig>

  reply	other threads:[~2020-02-06 21:21 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-02 19:56 [PATCH v3 00/12] riscv: Add Sipeed Maix support Sean Anderson
2020-02-02 19:58 ` [PATCH v3 01/12] clk: Always use the supplied struct clk Sean Anderson
2020-02-06 21:21   ` Lukasz Majewski [this message]
     [not found]     ` <752D002CFF5D0F4FA35C0100F1D73F3FA46D30F5@ATCPCS16.andestech.com>
2020-02-12  1:23       ` Rick Chen
2020-02-02 19:58 ` [PATCH v3 02/12] clk: Check that ops of composite clock components, exist before calling Sean Anderson
2020-02-06 21:41   ` Lukasz Majewski
2020-02-02 19:59 ` [PATCH v3 03/12] clk: Unconditionally recursively en-/dis-able clocks Sean Anderson
2020-02-06 21:45   ` Lukasz Majewski
2020-02-02 20:01 ` [PATCH v3 04/12] reset: Add generic reset driver Sean Anderson
2020-02-03  0:04   ` Simon Glass
2020-02-03 23:14     ` Sean Anderson
2020-02-04 11:06   ` Bin Meng
2020-02-04 14:14     ` Sean Anderson
2020-02-02 20:02 ` [PATCH v3 05/12] dm: Add support for simple-pm-bus Sean Anderson
2020-02-03  0:04   ` Simon Glass
2020-02-03 23:15     ` Sean Anderson
2020-02-05  0:16       ` Simon Glass
2020-02-04 11:13   ` Bin Meng
2020-02-02 20:04 ` [PATCH v3 06/12] riscv: Add headers for asm/global_data.h Sean Anderson
2020-02-04 11:17   ` Bin Meng
2020-02-02 20:05 ` [PATCH v3 07/12] riscv: Add option to support RISC-V privileged spec 1.9.1 Sean Anderson
2020-02-04 11:21   ` Bin Meng
2020-02-04 14:19     ` Sean Anderson
2020-02-04 14:38       ` Bin Meng
2020-02-04 14:48         ` Sean Anderson
2020-02-04 16:04           ` Bin Meng
2020-02-04 16:07             ` Sean Anderson
2020-02-02 20:06 ` [PATCH v3 08/12] riscv: Allow use of reset drivers Sean Anderson
2020-02-04 11:22   ` Bin Meng
2020-02-02 20:07 ` [PATCH v3 09/12] riscv: Add K210 pll support Sean Anderson
2020-02-02 20:07 ` [PATCH v3 10/12] riscv: Add K210 clock support Sean Anderson
2020-02-06 21:51   ` Lukasz Majewski
2020-02-02 20:10 ` [PATCH v3 11/12] riscv: Add device tree for K210 Sean Anderson
2020-02-04 11:32   ` Bin Meng
2020-02-04 14:23     ` Sean Anderson
2020-02-04 14:40       ` Bin Meng
2020-02-02 20:10 ` [PATCH v3 12/12] riscv: Add initial Sipeed Maix support Sean Anderson
2020-02-04 11:38   ` Bin Meng
2020-02-04 14:26     ` Sean Anderson
2020-02-04 14:42       ` Bin Meng
2020-02-04 14:49         ` Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200206222152.168a8fec@jawa \
    --to=lukma@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox