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@xxxxxxxxxxx> > --- > 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
Attachment:
signature.asc
Description: PGP signature