Re: [PATCH v3 4/5] ARM: davinci: convert to common clock framework
From: David Lechner
Date: Tue Dec 19 2017 - 18:12:29 EST
On 12/19/2017 07:47 AM, Sekhar Nori wrote:
Hi David,
On Saturday 09 December 2017 07:45 AM, David Lechner wrote:
This converts the clocks in mach-davinci to the common clock framework.
Most of the patch just involves renaming struct clk to struct davinci_clk.
There is also a struct clk_hw added to provide the bridge between the
existing clock implementation and the common clock framework.
The clk_get_parent and clk_set_parent callbacks are dropped because all
clocks currently (effectivly) have a single parent, in which case the
common clock framework does not want you to implement these functions
yourself.
clk_unregister() is dropped because it is not used anywhere in
mach-davinci.
EXPORT_SYMBOL() is removed from functions not used outside of mach-davinci.
Fixed checkpatch.pl warning about bare use of unsigned in dump_clock().
Signed-off-by: David Lechner <david@xxxxxxxxxxxxxx>
The cleanups leading upto this patch look fine, but I am not sure about
this patch itself. Ideally, we should have moved to drivers/clk also.
And shared code with keystone too since the PSC and PLL implementations
of the two architectures are quite similar.
I could think of this as an intermediate step while we get there, but I
am afraid of the churn that would cause. For example, if we reuse
keystone driver, we will be using clk_psc and we can get rid of the
davinci_clk that this patch introduces.
So unless there is big roadblock to moving to drivers/clk, we should
probably do that in one shot.
Yes, this is intended as an intermediate step. My thinking was that it
would be better to do one thing at a time, so if something breaks, it
will be easier to find the problem than if we try to do everything at
once. But, you are right, there will be quite a few extra intermediate
steps required, for example, I have realized that in order to use the
davinci_clk concurrently with other clocks in the common clock
framework, at least the parent pointer and children linked list will
have to be removed, introducing another intermediate step.
While avoiding the davinci_clk step would be ideal, there is quite a bit
that needs to be done first before this will be possible. And the
downside I see to doing it this way is that no one will be able to test
any of the preparatory patches because they depend on the common clock
framework. We won't even be able to compile them until all the pieces
are in place and we can enable the common clock kernel configuration option.
Here is a list of some of the issues I know about so far preventing me
from doing everything at once at this point in time:
* Reentrancy of clk_enable() on non-SMP systems is broken in the common
clock framework [1][2], but this reentrancy is needed for the DA8xx USB
PHY PLL clock [3].
* drivers/remoteproc/da8xx_remoteproc.c calls
davinci_clk_reset_{assert,deassert}() in arch/arm/mach-davinci/clock.c.
This needs to be moved to the PSC driver in drivers/clk. The reset
framework in drivers/reset looks ideal for handling this, but it is
currently device tree only and it looks like we need it to work on
non-device tree boards. So, our options are: to move this hack to the
PSC driver in drivers/clk/ *or* to update the reset framework to work
with non-device tree boards *or* convert all of the mach-davinci boards
to device tree only.
* The device tree bindings for "ti,keystone,psc-clock" are not the best
and I am really not keen on reusing them. What makes sense to me would
be to define a device tree node that represents the entire PSC IP block
with child nodes for each clock output. Something like this:
power-controller@2350000 {
compatible = "ti,davinci-psc";
reg = <0x2350000 0xb00>;
...
clkhyperlink0: clkhyperlink0 {
#clock-cells = <0>;
clock-output-names = "hyperlink-0";
clocks = <&chipclk12>;
power-domain = <5>;
module-domain = <12>;
};
...
};
But the keystone bindings assign the entire PSC register space to each
clock individually (twice). And the really ugly part is that the module
domain and the power domain numbers of each PSC "clock" is embedded in
the register address. So, if you have reg = <0x02350030 0xb00>,
<0x02350014 0x400>; what this really means is that the clock driver will
iomap 0x02350000 (notice the 00 instead of the 30 and 14 at the end of
each register and that the base 0x02350000 is essentially listed twice
with two different sizes) and it means that this particular clock has a
module domain of 12 (0x30 / 4 = 12, 4 comes from the fact these are
32-bit registers) and a power domain of 5 (0x14 / 4 = 5). You can find
the numbers 12 and 5 easily in the SRM, but the numbers used in the
device tree bindings are pretty meaningless. Furthermore, the driver
itself stores the base address in a global variable which won't work for
DA8XX since it has two PSCs instead of one. So, for this case, I'm
really tempted to just write a new driver with better device tree
bindings rather than trying to fix up the keystone driver to make it
compatible with davinci and better device tree bindings while still
maintaining backwards compatibility with wacky device tree bindings.
* The keystone PLL driver and device tree bindings are in better shape,
but they cannot be used as-is with davinci family processors since the
registers are laid out differently. I have a work-in-progress patch for
this that I started quite a while back [4][5].
* All of the keystone clock drivers are currently device tree only, so
they will need to be modified *or* as mentioned above all mach-davinci
boards could be converted to device tree only.
[1]: https://patchwork.kernel.org/patch/10108437/
[2]: https://patchwork.kernel.org/patch/10115483/
[3]: https://patchwork.kernel.org/patch/9449741/
[4]:
https://github.com/dlech/ev3dev-kernel/commit/5e7bf2070aa03283b605d7b86864758d24f83aa8
[5]:
https://github.com/dlech/ev3dev-kernel/commit/1e34686ff57a673c8655eaedacec4d65d48f93b3
---
Also, a bit more background on my motivation here. Really, all I want is
to be able to use the "pwm-clock" device tree bindings to supply a clock
to a Bluetooth chip. But the driver for it requires the common clock
framework.
This is just a spare time project for me, which is why I have just done
the bare minimum to get CONFIG_COMMON_CLK enabled rather than trying to
fix all of the hard problems to do thing the "right way". As you have
seen above, there is still quite a bit of work remaining to be done,
especially when doing this just for fun. It is probably just wishful
thinking, but I kind of hoped that if I was able to get things this far,
maybe some other interested parties might be able to help with one of
the various pieces.
One way or another, I suppose I will get my Bluetooth clock eventually. :-)