[PATCH RFC 00/40] clk: port full Linux Common Clock Framework to U-Boot
Neil Armstrong
neil.armstrong at linaro.org
Fri Mar 20 18:55:05 CET 2026
On 3/20/26 17:52, Simon Glass wrote:
> 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.
>
Can't we allocate struct clk as udevices subdevices of clk drivers ?
Like alloc_clk() woult create a child udevice of dev and the lookup
functions would use the uclass functions and use dm for all the
allocation and lifetime of the clk.
This is what I did for the interconnect, and it works well. You
can easily create/attach/find/iterate/remove subdevices instead
of using custom alloc and lists.
Neil
> 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