From: Alex Elder <elder@riscstar.com>
To: Artur Weber <aweber.kernel@gmail.com>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>,
Florian Fainelli <florian.fainelli@broadcom.com>,
Ray Jui <rjui@broadcom.com>,
Scott Branden <sbranden@broadcom.com>,
Broadcom internal kernel review list
<bcm-kernel-feedback-list@broadcom.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>
Cc: Alex Elder <elder@kernel.org>,
Stanislav Jakubek <stano.jakubek@gmail.com>,
linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org,
~postmarketos/upstreaming@lists.sr.ht
Subject: Re: [PATCH RFC 3/5] clk: bcm281xx: implement prerequisite clocks
Date: Mon, 24 Feb 2025 10:20:16 -0600 [thread overview]
Message-ID: <d4aa25fb-2cc0-4b1a-a376-936e7e83233a@riscstar.com> (raw)
In-Reply-To: <20250216-kona-bus-clock-v1-3-e8779d77a6f2@gmail.com>
On 2/16/25 10:12 AM, Artur Weber wrote:
> From: Alex Elder <elder@kernel.org>
>
> Allow a clock to specify a "prerequisite" clock, identified by its
> name. The prerequisite clock must be prepared and enabled before a
> clock that depends on it is used. In order to simplify locking, we
> require a clock and its prerequisite to be associated with the same
> CCU. (We'll just trust--but not verify--that nobody defines a cycle
> of prerequisite clocks.)
>
> Rework the KONA_CLK() macro, and define a new KONA_CLK_PREREQ()
> variant that allows a prerequisite clock to be specified.
>
> Signed-off-by: Alex Elder <elder@linaro.org>
> --- Artur: rebase on v6.13, move prereq prepare/unprepare to main
> prepare/unprepare functions, use locking versions of clk_prepare
> and clk_enable since the non-locking versions are no longer
> public ---
> Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
I'm surprised there is no prepare function for the peripheral
clocks.
The prequisite clock should separate the prepare and the
enable functionality. Right now you have kona_clk_prepare()
doing both. Instead, a clock's prepare function should
prepare its prerequisite (if any). Then its enable function
should enable its parent.
Should all the users of peripheral clocks just also be required
to specify the bus clocks as well? I suppose that doesn't
encode the prerequisite property (bus comes before peripheral);
is that truly a requirement?
-Alex
> ---
> drivers/clk/bcm/clk-kona.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/bcm/clk-kona.h | 20 ++++++++++++---
> 2 files changed, 79 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
> index e92d57f3bbb147e72221802175a80502897d7504..21f925683d0da05ebc97f92236dfb207b1f9c741 100644
> --- a/drivers/clk/bcm/clk-kona.c
> +++ b/drivers/clk/bcm/clk-kona.c
> @@ -9,6 +9,7 @@
> #include <linux/delay.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> +#include <linux/clk.h>
> #include <linux/clk-provider.h>
>
> /*
> @@ -961,6 +962,63 @@ static int selector_write(struct ccu_data *ccu, struct bcm_clk_gate *gate,
> return ret;
> }
>
> +/*
> + * Common clock prepare/unprepare functions. These implement a "prerequisite"
> + * mechanism; the prerequisite clock is prepared and enabled before the main
> + * clock is prepared.
> + */
> +
> +static int kona_clk_prepare(struct clk_hw *hw)
> +{
> + struct kona_clk *bcm_clk = to_kona_clk(hw);
> + const char *clk_name = bcm_clk->init_data.name;
> + const char *prereq_name = bcm_clk->prereq.name;
> + struct clk *prereq_clk = bcm_clk->prereq.clk;
> + int ret;
> +
> + /* If there's no prerequisite clock, there's nothing to do */
> + if (!prereq_name)
> + return 0;
> +
> + /* Look up the prerequisite clock if we haven't already */
> + if (!prereq_clk) {
> + prereq_clk = __clk_lookup(prereq_name);
> + if (WARN_ON_ONCE(!prereq_clk))
> + return -ENOENT;
> + bcm_clk->prereq.clk = prereq_clk;
> + }
> +
> + ret = clk_prepare(prereq_clk);
> + if (ret) {
> + pr_err("%s: unable to prepare prereq clock %s for %s\n",
> + __func__, prereq_name, clk_name);
> + return ret;
> + }
> +
> + ret = clk_enable(prereq_clk);
> + if (ret) {
> + clk_unprepare(prereq_clk);
> + pr_err("%s: unable to enable prereq clock %s for %s\n",
> + __func__, prereq_name, clk_name);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void kona_clk_unprepare(struct clk_hw *hw)
> +{
> + struct kona_clk *bcm_clk = to_kona_clk(hw);
> + struct clk *prereq_clk = bcm_clk->prereq.clk;
> +
> + /* If there's no prerequisite clock, there's nothing to do */
> + if (!bcm_clk->prereq.name)
> + return;
> +
> + clk_disable(prereq_clk);
> + clk_unprepare(prereq_clk);
> +}
> +
> /* Peripheral clock operations */
>
> static int kona_peri_clk_enable(struct clk_hw *hw)
> @@ -1172,6 +1230,8 @@ static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> }
>
> struct clk_ops kona_peri_clk_ops = {
> + .prepare = kona_clk_prepare,
> + .unprepare = kona_clk_unprepare,
> .enable = kona_peri_clk_enable,
> .disable = kona_peri_clk_disable,
> .is_enabled = kona_peri_clk_is_enabled,
> @@ -1260,6 +1320,8 @@ static int kona_bus_clk_is_enabled(struct clk_hw *hw)
> }
>
> struct clk_ops kona_bus_clk_ops = {
> + .prepare = kona_clk_prepare,
> + .unprepare = kona_clk_unprepare,
> .enable = kona_bus_clk_enable,
> .disable = kona_bus_clk_disable,
> .is_enabled = kona_bus_clk_is_enabled,
> diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h
> index a5b3d8bdb54eaee9fad80c28796170207b817dfd..c32c621282ec6dd40fff3f7598ee8aa007fed524 100644
> --- a/drivers/clk/bcm/clk-kona.h
> +++ b/drivers/clk/bcm/clk-kona.h
> @@ -406,6 +406,10 @@ struct kona_clk {
> struct clk_init_data init_data; /* includes name of this clock */
> struct ccu_data *ccu; /* ccu this clock is associated with */
> enum bcm_clk_type type;
> + struct {
> + const char *name;
> + struct clk *clk;
> + } prereq;
> union {
> void *data;
> struct peri_clk_data *peri;
> @@ -416,16 +420,26 @@ struct kona_clk {
> container_of(_hw, struct kona_clk, hw)
>
> /* Initialization macro for an entry in a CCU's kona_clks[] array. */
> -#define KONA_CLK(_ccu_name, _clk_name, _type) \
> - { \
> +#define __KONA_CLK_COMMON(_ccu_name, _clk_name, _type) \
> .init_data = { \
> .name = #_clk_name, \
> .ops = &kona_ ## _type ## _clk_ops, \
> }, \
> .ccu = &_ccu_name ## _ccu_data, \
> .type = bcm_clk_ ## _type, \
> - .u.data = &_clk_name ## _data, \
> + .u.data = &_clk_name ## _data
> +
> +#define KONA_CLK(_ccu_name, _clk_name, _type) \
> + { \
> + __KONA_CLK_COMMON(_ccu_name, _clk_name, _type), \
> }
> +
> +#define KONA_CLK_PREREQ(_ccu_name, _clk_name, _type, _prereq) \
> + { \
> + .prereq.name = #_prereq, \
> + __KONA_CLK_COMMON(_ccu_name, _clk_name, _type), \
> + }
> +
> #define LAST_KONA_CLK { .type = bcm_clk_none }
>
> /*
>
next prev parent reply other threads:[~2025-02-24 16:20 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-16 16:12 [RFC PATCH 0/5] clk: bcm: kona: Add bus clock support and prerequisite clocks Artur Weber
2025-02-16 16:12 ` [PATCH RFC 1/5] dt-bindings: clock: brcm,kona-ccu: Add BCM21664 bus clocks Artur Weber
2025-02-21 20:20 ` Rob Herring (Arm)
2025-02-16 16:12 ` [PATCH RFC 2/5] clk: bcm: kona: Add support for " Artur Weber
2025-02-24 16:20 ` Alex Elder
2025-02-16 16:12 ` [PATCH RFC 3/5] clk: bcm281xx: implement prerequisite clocks Artur Weber
2025-02-24 16:20 ` Alex Elder [this message]
2025-02-25 18:48 ` Artur Weber
2025-02-25 19:35 ` Alex Elder
2025-02-16 16:12 ` [PATCH RFC 4/5] clk: bcm21664: Add matching bus clocks for peripheral clocks Artur Weber
2025-02-21 20:23 ` Rob Herring
2025-02-24 16:20 ` Alex Elder
2025-02-16 16:12 ` [PATCH RFC 5/5] ARM: dts: bcm2166x-common: " Artur Weber
2025-02-24 16:20 ` [RFC PATCH 0/5] clk: bcm: kona: Add bus clock support and prerequisite clocks Alex Elder
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=d4aa25fb-2cc0-4b1a-a376-936e7e83233a@riscstar.com \
--to=elder@riscstar.com \
--cc=aweber.kernel@gmail.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=elder@kernel.org \
--cc=florian.fainelli@broadcom.com \
--cc=krzk+dt@kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=rjui@broadcom.com \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
--cc=sbranden@broadcom.com \
--cc=stano.jakubek@gmail.com \
--cc=~postmarketos/upstreaming@lists.sr.ht \
/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