[PATCH 4/5] clk: Add flag to prevent frequency changes when walking subtrees
Maxime Ripard
mripard at redhat.com
Tue Dec 17 04:47:53 PST 2024
On Thu, Nov 21, 2024 at 06:41:14PM +0100, Miquel Raynal wrote:
> There are mainly two ways to change a clock frequency.
There's much more than that :)
Off the top of my head, setting/clearing a min/max rate and changing the
parent might also result in a rate change.
And then, the firmware might get involved too.
> The active way requires calling ->set_rate() in order to ask "on
> purpose" for a frequency change. Otherwise, a clock can passively see
> its frequency being updated depending on upstream clock frequency
> changes. In most cases it is fine to just accept the new upstream
> frequency - which by definition will have an impact on downstream
> frequencies if we do not recalculate internal divisors. But there are
> cases where, upon an upstream frequency change, we would like to
> maintain a specific rate.
Why is clk_set_rate_exclusive not enough?
> As an example, on iMX8MP the video pipeline clocks are looking like this:
>
> video_pll1
> video_pll1_bypass
> video_pll1_out
> media_ldb
> media_ldb_root_clk
> media_disp2_pix
> media_disp2_pix_root_clk
> media_disp1_pix
> media_disp1_pix_root_clk
>
> media_ldb, media_disp2_pix and media_disp1_pix are simple divisors from
> which we might require 2 or 3 different rates, whereas video_pll1 is a
> very configurable PLL which can achieve almost any frequency. There are
> however relationships between them, typically the ldb clock must be 3.5
> or 7 times higher than the media_disp* clocks.
>
> Currently, if eg. media_disp2_pix is set to 71900000Hz, when media_ldb
> is (later) set to 503300000Hz, media_disp2_pix is updated to 503300000Hz
> as well, which clearly does not make sense. We want it to stay at
> 71900000Hz during the subtree walk.
>
> Achieving this is the purpose of the new clock flag:
> CLK_NO_RATE_CHANGE_DURING_PROPAGATION
>
> Please note, if the kernel was setting the ldb clock before a pixel
> clock, the result would be different, and this is also what this patch
> is trying to solve.
>
> Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> ---
> In all cases, the LDB must be aware of the device configuration, and ask
> for a clever frequency, we will never cope with slightly aware drivers
> when addressing this kind of subtle situation.
> ---
> drivers/clk/clk.c | 9 +++++++--
> include/linux/clk-provider.h | 2 ++
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index adfc5bfb93b5a65b6f58c52ca2c432d651f7dd7d..94d93470479e77769e63e97462b176261103b552 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1927,7 +1927,6 @@ long clk_get_accuracy(struct clk *clk)
> }
> EXPORT_SYMBOL_GPL(clk_get_accuracy);
>
> -__maybe_unused
> static unsigned long clk_determine(struct clk_core *core, unsigned long rate)
> {
> struct clk_rate_request req = {};
> @@ -2272,7 +2271,13 @@ static void clk_calc_subtree(struct clk_core *core)
> {
> struct clk_core *child;
>
> - core->new_rate = clk_recalc(core, core->parent->new_rate);
> + if (core->flags & CLK_NO_RATE_CHANGE_DURING_PROPAGATION) {
> + core->new_rate = clk_determine(core, core->rate);
> + if (!core->new_rate)
> + core->new_rate = clk_recalc(core, core->parent->new_rate);
> + } else {
> + core->new_rate = clk_recalc(core, core->parent->new_rate);
> + }
Sorry, it's not clear to me how it works. How will the parent clocks
will get notified to adjust their dividers in that scenario? Also, what
if they can't?
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241217/c51e5c39/attachment.sig>
More information about the linux-arm-kernel
mailing list