[PATCH RFC 00/40] clk: port full Linux Common Clock Framework to U-Boot
Simon Glass
sjg at chromium.org
Fri Mar 20 17:52:12 CET 2026
Hi Casey,
On Thu, 19 Mar 2026 at 14:56, Casey Connolly <casey.connolly at linaro.org> wrote:
>
> This RFC provides a proof of concept for using the full Linux CCF in
> U-Boot and consequently porting full Linux clock drivers with extremely
> minimal changes.
As a general question, what is the boot flow for the Qualcomm devices
you are are targeting, i.e. where does U-Boot come in the chain from
reset? Does it use xPL?
>
> == Overview ==
>
> This RFC is pretty long but can be separated into a few chunks. The
> first patches relate to Linux API compatibility and just contain small
> self contained changes, these can go upstream regardless of CCF.
>
> The next group of changes prepare for importing CCF from Linux, the
> standalone fixed clock drivers are moved to clk/basic, the existing
> U-Boot CCF drivers are moved to clk/uccf, and struct clk_ops is renamed
> to clk_ops_uboot.
>
> Additionally, clk_set_rate() is changed so that it returns a signed
> long, since it can return negative values. This is also done to align
> with CCF but it's a standalone improvement nonetheless.
Agreed.
>
> The next changes import CCF from Linux 6.19 and then adjust it to
> compile and work with U-Boot. These commits are split up mostly to
> try and reduce the size. Finally clk-uclass is adjusted for CCF, this
> definitely will need some additional passes to be a bit cleaner.
>
> With CCF done, sandbox clk-ccf driver gets a CCF_FULL port, the clk_ccf
> tests are adjusted to pass.
Minor point - perhaps CLK_LINUX ? CCF_FULL seems cryptic to me and
some would argue that the existing CLK_CCF is already full..
>
> Lastly, a PoC port of Qualcomms Linux clock drivers is done, this
> only has sm8650 clocks but they serve the desired purpose. The changes
> necessary to the Linux drivers are mostly to deal with U-Boots driver
> model, the actual platform specific clock drivers require essentially
> zero changes!
>
> === Feedback ===
>
> I'd like to get feedback on the overall architecture and ideas, feel
> free to point out any dead code or printf's I forgot about, but I'll for
> sure do a more detailed cleanup before the next revision.
>
> I would definitely like to input on how to deal with clk-uclass, since
> it's now supporting 3 different clock frameworks, but I'm now sure how
> best to separate the code out without duplicating code.
Perhaps a justification can be expressed in terms of code size / capabilities:
Small - can boot in xPL from limited SRAM, only simple clocks
Medium - smaller code size but still provides good access to clocks
Large - Linux compatible, full capability but lots of code
>
> In terms of overall architecture, CCF is a departure from the uclass
> model that U-Boot has stuck too for so long. If this is a success then
> I think it could make a lot of sense to make similar changes for power
> domains and resets. I think this change offers a lot of additional
> flexibility which has been sorely missed.
While those are separate, does this mean that there will be a
significant delta from Linux's clock drivers on Qualcomm, or will it
be minor?
>
> == Motivation ==
>
> There were quite a few motivating factors behind this effort which I
> think provide useful context for this series:
>
> 1. Existing UCLASS_CLK support in U-Boot (even with U-Boots minimal CCF)
> doesn't provide a fully cohesive API nor implement the necessary
> functionality to support complex modern platforms without a lot of
> additional effort.
>
> 2. While trying to enable display support on Qualcomm, it became clear
> that U-Boots clock framework was a severe limiting factor,
> particularly for more complicated setups like "bonded" dual-DSI.
It seems that 1 and 2 could be merged? The question here is how much
effort would someone want to put in. Providing an easy way to pull in
the Linux clock driver makes sense. Some people may wish to put in
effort to at least support the basic clocks for xPL, etc.
>
> 3. The current state of Qualcomm clock drivers in U-Boot is pretty poor,
> as the old very basic driver code is being expected to support more
> and more complicated usecases. Clock support is generally the most
> complicated part of bringing up any new Qualcomm platform, so being
> able to properly reuse Linux drivers with the familiar API greatly
> reduces the amount of friction when working on U-Boot support for
> complicated peripherals like the display.
>
> Consequently, My aim with this effort was primarily to provide API
> compatibility with Linux as much as possible, minimising the changes
> that have to be made to clock drivers to port them from Linux, and
> reducing the chance of introducing U-Boot specific bugs.
>
> === clk_ops/UCLASS_CLK ===
>
> CCF_FULL drivers should NOT use UCLASS_CLK, since CCF uses a totally
> independent clock API. If the clocks are provided by another device like
> a phy, they can simply be registered with the clk core the same way they
> are in Linux. Standalone clock drivers should use UCLASS_NOP.
Bypassing UCLASS_CLK entirely is a big departure. It means DM can't
track these clock devices properly - no uclass_find_device(), no
sequence numbers, no standard device iteration.
The suggestion to do the same for power domains and resets would
fragment driver model further.
How about having a single UCLASS_CLK_LINUX device?
>
> Clocks must all be registered during driver probe, the CCF will ensure
> that a given clock provider is probed (via a global ofnode -> device
> lookup) before checking the of_providers, thus making sure the clocks
> are registered so that the consumer can use them. There is currently no
> special handling for cyclical dependencies.
Driver model normally registers devices during a bind step, which
helps to remove the problem of cyclic dependencies. Is there any need
to wait until probe()? Also, can we statically declare it, to save
code size? Most of the definitions are static
The global ofnode -> device lookup to force probe ordering is
reinventing what DM already does with uclass probing. This feels like
it should integrate with DM rather than work around it.
>
> === struct clk ===
>
> It's definitely debatable if it makes sense to have 3 different structs
> for each clk (clk_hw, clk_core and clk). I do think clk_hw and clk_core
> are justified, since clk_hw is more tied to the hardware description and
> typically nested in a clk-specific descriptor while clk_core contains
> the internal runtime state of the clk which should remain private to
> CCF core.
Probably we should follow Linux, since we would start to lose the
benefit of your series if we merged two structs.
>
> It could make sense to merge clk and clk_core, but since struct clk is
> public in U-Boot, where it's an opaque pointer in Linux this would be
> a substantial effort. In Linux struct clk objects are allocated inside
> CCF, but in U-Boot they're allocated by the driver, this would need to
> be resolved before we investigate combining these structs.
>
> === Memory/perf overhead ===
>
> The memory and size overhead of CCF is undoubtably bigger than uCCF,
> although I suspect the difference is less than it might seem at
> first glance. In particular: clk_core is only ~50 bytes larger than
> struct udevice on ARM64, and an additional 120 bytes is saved for each
> U_BOOT_DRIVER used by uCCF.
>
> On the other hand, the CPU overhead is probably more significant,
> but not an unreasonable cost to ensure correctness and propagate rate
> changes across the clock tree.
We already struggle with slow pre-relocation performance, something I
have never really dug into.
>
> Just comparing the binary size of sandbox64_defconfig with uCCF vs
> CCF_FULL, CCF_FULL results in a 135k size increase in the binary. I
> haven't done any more detailed analysis here (still haven't got buildman
> to play nice...).
Sandbox may overestimate the size here, not sure. Ping on irc if you
need update with the buildman setup.
>
> === SPL ===
>
> This RFC doesn't have any SPL specific support, I think this role is
> better fulfilled by UCLASS_CLK.
>
> === U-Boot's old CCF port ===
>
> The original CCF port done for IMX platforms is vastly different in API,
> scope, and function to CCF_FULL, to differentiate I refer to it
> as "uCCF".
>
> I have kept support for this in and made it mutually exclusive with
> CCF_FULL. uCCF drivers have been moved to drivers/clk/uccf, with the new
> CCF port in drivers/clk/ccf.
>
> Included near the end of this series is a port of Sandbox's clk-ccf
> driver from uCCF over to CCF_FULL, this might be a useful reference for
> other drivers (although it's probably better to just adapt the Linux
> drivers).
>
> === Compat shim ===
>
> Lastly, this series includes a compat shim which allows UCLASS_CLK
> drivers to somewhat work with CCF, I would imagine this being useful
> if some generic peripheral device provides a clock for example, but in
> almost all cases I think it's better to implement a proper CCF clock
> device. Unless there is a particular usecase for this I would probably
> not include it in the next revision.
>
> == TODO/Outstanding issues ==
>
> * Clean up clk-uclass.c, does it make sense to somewhow split it in two?
> * Assess test coverage, have basic sandbox tests, would like to mostly
> use integration tests (i.e. diff the clk summary) once more platforms
> are supported.
> * pre-relocation support is currently missing, on Qualcomm at least I
> would prefer to completely skip FDT scanning pre-reloc, there is a
> patch in this series which does that. It is very non-trivial to try
> and handle clocks pre-reloc.
Does this mean that only serial is needed and the clock for it is
already set up by some pre-U-Boot phase?
Regards,
SImon
More information about the U-Boot
mailing list