-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers: clock_control: Introduce revision 3 of CCM driver #59787
Changes from all commits
d0424aa
8bca890
cf5cd6a
018fe79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,4 +85,7 @@ | |
/* clocks = <&ccm IMX_CCM_UART4_CLK 0x6c 24>; */ | ||
pinctrl-0 = <&uart2_default>; | ||
pinctrl-names = "default"; | ||
assigned-clocks = <IMX93_CCM_LPUART2_ROOT>; | ||
assigned-clock-parents = <IMX93_CCM_OSC_24M>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like what we are trying to do here is encode a clock tree with these two properties. Rather than having a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean something like this?
I'm not sure setting the root clock sources through the DTS is the way to go. Parsing the DTS is already somewhat tricky due to all of the macro magic (e.g: Regarding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think we are trying to follow here the Linux implementation which is proved to work for a while. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I've taken a look at the Linux implementation, and I think I understand the goals here a bit better now. With that being said, Linux clearly has different clock drivers for each SOC (since the clock driver itself encodes the clock tree data, and as far as I can see Linux provides a generic framework to handle a lot of common functionalities with clocks: https://docs.kernel.org/driver-api/clk.html.) Given that, wouldn't we want this PR to have two components:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Additionally- just a general question about Linux clock setup- how does Linux handle a case where the initial clock frequency of the SOC should be produced via a PLL (something like 24MHz OSC -> PLL0 -> output clock)? Is the idea that the clock framework would call My concern with this approach in general is that for larger SOCs like the iMX RT series (or iMX itself), this approach makes sense for the ease of use. However, on smaller cores like the LPC parts I am concerned about the overhead of performing these clock calculations on boot There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It does.
Not sure how helpful I can be here since I'm not entirely familiar with how Linux initializes the clocks (also this approach isn't meant to be a 1:1 recreation of the Linux CCF, but rather a very simplified version that would still be powerful enough to serve our purposes). Not sure if this would help but the way I see things there's 3 possible approaches:
I tend to think option 1 (or even 3 maybe?) would be more plausible in Linux's case. As a side note, my current approach is based on number 2. Ideally, it should be based on 1 or 3.
Yeah this is indeed concerning. We could optimize the driver such that it initializes only clocks used by consumers, instead of initializing all of the clocks declared in the SoC layer's clock tree. Other than that, you could reduce the overhead by using a toned-down version of the clock tree and reducing the amount of configurations that need to be done through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This makes sense- thank you for the clarification
Of these, I actually prefer 2), since that would result in the lowest runtime overhead for the platform, and the least amount of definitions needed in code. The key thing I am worried about here is a need to implement
with something like this, the SOC initialization code could easily determine the PLL settings needed. If we used |
||
assigned-clock-rates = <24000000>; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Copyright 2023 NXP | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config CLOCK_CONTROL_MCUX_CCM_REV3 | ||
bool "MCUX CCM Rev3 driver" | ||
default y | ||
select NXP_HAL_DISABLE_IMPLICIT_CLOCKING | ||
depends on DT_HAS_NXP_IMX_CCM_REV3_ENABLED | ||
help | ||
Enable support for mcux ccm rev3 driver. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deviation from the
clocks = <xx>
standard property here concerns me. I think we should still be using theclocks
property for clock data, unless there is a good reason to deviate from the standard property nameused by other SOCsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with theclocks
property is that it doesn't offer enough flexibility. For instance, theassigned-clock-parents
property is optional (unless a node needs this property in which case it becomes mandatory). If we were to use theclocks
then it would be mandatory to specify a clock's parent as the number of elements in the resulting clocks array would have to be divisible by some value. Also, the drivers don't need to have access to all of the fields (e.g: the clock's frequency or the clock's parent). A handle to their clock is the only thing they need.Assuming the following example in which the
clocks
property has the following structure:clocks = <CLOCK_ID CLOCK_PARENT_ID CLOCK_RATE>,...
:The same thing could be achieved using the
assigned-clock*
properties as follows:In the first approach you might end up having a mixture of clocks the driver needs to actually use and clocks that are just used by the CCM driver to perform initialization. IMO, separating them is much cleaner. Also, in the case of SoCs such as i.MX93 configuring the root clock's rate will also configure the rate of the associated IP clock. As such,
CLOCK_IP1
would end up being pointlessly initialized.Of course, example 1 could be modified as follows (not sure this would actually work)
This would mean the CCM node would end up containing a bunch of clocks which would reduce the readability of the DTS (which is why I chose to add support for parsing distributed
assigned-clock*
properties)Also, some SoCs may not want to assign parents to clocks through the DTS. This would mean we'd end up with a bunch of
clocks
properties having the following value:clocks = <CLOCK_ID DUMMY_CLK_ID RATE>...
where
DUMMY_CLK_ID
is just a value ignored by the SoC layer.Considering all of this, I think using a combination of
clocks
andassigned-clock*
may be worth it. I'm not so sure about the disadvantages though. Is there a particular case in your mind for which things may become bad if we use bothclocks
and theassigned-clock*
properties?