* [U-Boot] [PATCH V3 2/4] clk: prograte clk enable/disable to parent
2019-08-21 13:35 [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Peng Fan
@ 2019-08-21 13:35 ` Peng Fan
2019-08-21 13:35 ` [U-Boot] [PATCH V3 3/4] clk: support clk tree dump Peng Fan
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2019-08-21 13:35 UTC (permalink / raw)
To: u-boot
On i.MX8MM, thinking such as clk path
OSC->PLL->PLL GATE->CCM ROOT->CCGR GATE->Device
Only enabling CCGR GATE is not enough, we also need to enable PLL GATE
to make sure the clk path work. So when enabling CCGR GATE,
we could prograte to enabling PLL GATE to make life easier.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
V3:
None
V2:
Improve commit log
Check enable_count when enable/disable to avoid touch hardware
following Linux
drivers/clk/clk-uclass.c | 77 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 71 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index c66b6f3c4e..64c181f4ad 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -449,13 +449,45 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
int clk_enable(struct clk *clk)
{
const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ struct clk *clkp = NULL;
+ int ret;
debug("%s(clk=%p)\n", __func__, clk);
- if (!ops->enable)
- return -ENOSYS;
+ if (CONFIG_IS_ENABLED(CLK_CCF)) {
+ /* Take id 0 as a non-valid clk, such as dummy */
+ if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
+ if (clkp->enable_count) {
+ clkp->enable_count++;
+ return 0;
+ }
+ if (clkp->dev->parent &&
+ device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
+ if (ret) {
+ printf("Enable %s failed\n",
+ clkp->dev->parent->name);
+ return ret;
+ }
+ }
+ }
- return ops->enable(clk);
+ if (ops->enable) {
+ ret = ops->enable(clk);
+ if (ret) {
+ printf("Enable %s failed\n", clk->dev->name);
+ return ret;
+ }
+ }
+ if (clkp)
+ clkp->enable_count++;
+ } else {
+ if (!ops->enable)
+ return -ENOSYS;
+ return ops->enable(clk);
+ }
+
+ return 0;
}
int clk_enable_bulk(struct clk_bulk *bulk)
@@ -474,13 +506,46 @@ int clk_enable_bulk(struct clk_bulk *bulk)
int clk_disable(struct clk *clk)
{
const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ struct clk *clkp = NULL;
+ int ret;
debug("%s(clk=%p)\n", __func__, clk);
- if (!ops->disable)
- return -ENOSYS;
+ if (CONFIG_IS_ENABLED(CLK_CCF)) {
+ if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
+ if (clkp->enable_count == 0) {
+ printf("clk %s already disabled\n",
+ clkp->dev->name);
+ return 0;
+ }
- return ops->disable(clk);
+ if (--clkp->enable_count > 0)
+ return 0;
+ }
+
+ if (ops->disable) {
+ ret = ops->disable(clk);
+ if (ret)
+ return ret;
+ }
+
+ if (clkp && clkp->dev->parent &&
+ device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
+ if (ret) {
+ printf("Disable %s failed\n",
+ clkp->dev->parent->name);
+ return ret;
+ }
+ }
+ } else {
+ if (!ops->disable)
+ return -ENOSYS;
+
+ return ops->disable(clk);
+ }
+
+ return 0;
}
int clk_disable_bulk(struct clk_bulk *bulk)
--
2.16.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 3/4] clk: support clk tree dump
2019-08-21 13:35 [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Peng Fan
2019-08-21 13:35 ` [U-Boot] [PATCH V3 2/4] clk: prograte clk enable/disable to parent Peng Fan
@ 2019-08-21 13:35 ` Peng Fan
2019-08-23 21:48 ` Simon Glass
2019-08-21 13:35 ` [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code Peng Fan
2019-08-23 21:48 ` [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Simon Glass
3 siblings, 1 reply; 9+ messages in thread
From: Peng Fan @ 2019-08-21 13:35 UTC (permalink / raw)
To: u-boot
The previous code only dump the clk list. This patch is
to support clk tree dump, and also dump the enable_cnt.
The code used in patch is similar to dm_dump_all, but
the code here only filter out the UCLASS_CLK devices.
On i.MX8MM, Partial output:
u-boot=> clk dump
Rate Usecnt Name
------------------------------------------
24000000 0 |-- clock-osc-24m
24000000 0 | |-- dram_pll_ref_sel
750000000 0 | | `-- dram_pll
750000000 0 | | `-- dram_pll_bypass
750000000 0 | | `-- dram_pll_out
24000000 0 | |-- arm_pll_ref_sel
1200000000 0 | | `-- arm_pll
1200000000 0 | | `-- arm_pll_bypass
1200000000 0 | | `-- arm_pll_out
1200000000 0 | | `-- arm_a53_src
1200000000 0 | | `-- arm_a53_cg
1200000000 0 | | `-- arm_a53_div
24000000 4 | |-- sys_pll1_ref_sel
800000000 4 | | `-- sys_pll1
800000000 4 | | `-- sys_pll1_bypass
800000000 4 | | `-- sys_pll1_out
40000000 0 | | |-- sys_pll1_40m
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
V3:
Fix build break for some platforms
V2:
Improve commit log
cmd/clk.c | 79 +++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 30 deletions(-)
diff --git a/cmd/clk.c b/cmd/clk.c
index 5402c87de7..74ad868500 100644
--- a/cmd/clk.c
+++ b/cmd/clk.c
@@ -7,51 +7,70 @@
#include <clk.h>
#if defined(CONFIG_DM) && defined(CONFIG_CLK)
#include <dm.h>
+#include <dm/device.h>
+#include <dm/root.h>
#include <dm/device-internal.h>
+#include <linux/clk-provider.h>
#endif
-int __weak soc_clk_dump(void)
-{
#if defined(CONFIG_DM) && defined(CONFIG_CLK)
- struct udevice *dev;
- struct uclass *uc;
- struct clk clk;
- int ret;
- ulong rate;
-
- /* Device addresses start at 1 */
- ret = uclass_get(UCLASS_CLK, &uc);
- if (ret)
- return ret;
-
- uclass_foreach_dev(dev, uc) {
- memset(&clk, 0, sizeof(clk));
- ret = device_probe(dev);
- if (ret)
- goto noclk;
+static void show_clks(struct udevice *dev, int depth, int last_flag)
+{
+ int i, is_last;
+ struct udevice *child;
+ struct clk *clkp;
+ u32 rate;
+
+ clkp = dev_get_clk_ptr(dev);
+ if (device_get_uclass_id(dev) == UCLASS_CLK && clkp) {
+ rate = clk_get_rate(clkp);
+
+ printf(" %-12u %8d ", rate, clkp->enable_count);
+
+ for (i = depth; i >= 0; i--) {
+ is_last = (last_flag >> i) & 1;
+ if (i) {
+ if (is_last)
+ printf(" ");
+ else
+ printf("| ");
+ } else {
+ if (is_last)
+ printf("`-- ");
+ else
+ printf("|-- ");
+ }
+ }
- ret = clk_request(dev, &clk);
- if (ret)
- goto noclk;
+ printf("%s\n", dev->name);
+ }
- rate = clk_get_rate(&clk);
- clk_free(&clk);
+ list_for_each_entry(child, &dev->child_head, sibling_node) {
+ is_last = list_is_last(&child->sibling_node, &dev->child_head);
+ show_clks(child, depth + 1, (last_flag << 1) | is_last);
+ }
+}
- if (rate == -ENODEV)
- goto noclk;
+int __weak soc_clk_dump(void)
+{
+ struct udevice *root;
- printf("%-30.30s : %lu Hz\n", dev->name, rate);
- continue;
- noclk:
- printf("%-30.30s : ? Hz\n", dev->name);
+ root = dm_root();
+ if (root) {
+ printf(" Rate Usecnt Name\n");
+ printf("------------------------------------------\n");
+ show_clks(root, -1, 0);
}
return 0;
+}
#else
+int __weak soc_clk_dump(void)
+{
puts("Not implemented\n");
return 1;
-#endif
}
+#endif
static int do_clk_dump(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
--
2.16.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 3/4] clk: support clk tree dump
2019-08-21 13:35 ` [U-Boot] [PATCH V3 3/4] clk: support clk tree dump Peng Fan
@ 2019-08-23 21:48 ` Simon Glass
2019-08-26 1:08 ` Peng Fan
0 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2019-08-23 21:48 UTC (permalink / raw)
To: u-boot
Hi Peng,
On Wed, 21 Aug 2019 at 07:35, Peng Fan <peng.fan@nxp.com> wrote:
>
> The previous code only dump the clk list. This patch is
> to support clk tree dump, and also dump the enable_cnt.
>
> The code used in patch is similar to dm_dump_all, but
> the code here only filter out the UCLASS_CLK devices.
>
> On i.MX8MM, Partial output:
> u-boot=> clk dump
> Rate Usecnt Name
> ------------------------------------------
> 24000000 0 |-- clock-osc-24m
> 24000000 0 | |-- dram_pll_ref_sel
> 750000000 0 | | `-- dram_pll
> 750000000 0 | | `-- dram_pll_bypass
> 750000000 0 | | `-- dram_pll_out
> 24000000 0 | |-- arm_pll_ref_sel
> 1200000000 0 | | `-- arm_pll
> 1200000000 0 | | `-- arm_pll_bypass
> 1200000000 0 | | `-- arm_pll_out
> 1200000000 0 | | `-- arm_a53_src
> 1200000000 0 | | `-- arm_a53_cg
> 1200000000 0 | | `-- arm_a53_div
> 24000000 4 | |-- sys_pll1_ref_sel
> 800000000 4 | | `-- sys_pll1
> 800000000 4 | | `-- sys_pll1_bypass
> 800000000 4 | | `-- sys_pll1_out
> 40000000 0 | | |-- sys_pll1_40m
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>
> V3:
> Fix build break for some platforms
> V2:
> Improve commit log
>
> cmd/clk.c | 79 +++++++++++++++++++++++++++++++++++++++------------------------
> 1 file changed, 49 insertions(+), 30 deletions(-)
Can we get a sandbox test for this?
Regards,
Simon
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 3/4] clk: support clk tree dump
2019-08-23 21:48 ` Simon Glass
@ 2019-08-26 1:08 ` Peng Fan
0 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2019-08-26 1:08 UTC (permalink / raw)
To: u-boot
> Subject: Re: [PATCH V3 3/4] clk: support clk tree dump
>
> Hi Peng,
>
> On Wed, 21 Aug 2019 at 07:35, Peng Fan <peng.fan@nxp.com> wrote:
> >
> > The previous code only dump the clk list. This patch is to support clk
> > tree dump, and also dump the enable_cnt.
> >
> > The code used in patch is similar to dm_dump_all, but the code here
> > only filter out the UCLASS_CLK devices.
> >
> > On i.MX8MM, Partial output:
> > u-boot=> clk dump
> > Rate Usecnt Name
> > ------------------------------------------
> > 24000000 0 |-- clock-osc-24m
> > 24000000 0 | |-- dram_pll_ref_sel
> > 750000000 0 | | `-- dram_pll
> > 750000000 0 | | `-- dram_pll_bypass
> > 750000000 0 | | `-- dram_pll_out
> > 24000000 0 | |-- arm_pll_ref_sel
> > 1200000000 0 | | `-- arm_pll
> > 1200000000 0 | | `-- arm_pll_bypass
> > 1200000000 0 | | `-- arm_pll_out
> > 1200000000 0 | | `--
> arm_a53_src
> > 1200000000 0 | | `--
> arm_a53_cg
> > 1200000000 0 | |
> `-- arm_a53_div
> > 24000000 4 | |-- sys_pll1_ref_sel
> > 800000000 4 | | `-- sys_pll1
> > 800000000 4 | | `-- sys_pll1_bypass
> > 800000000 4 | | `-- sys_pll1_out
> > 40000000 0 | | |--
> sys_pll1_40m
> >
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
> >
> > V3:
> > Fix build break for some platforms
> > V2:
> > Improve commit log
> >
> > cmd/clk.c | 79
> > +++++++++++++++++++++++++++++++++++++++------------------------
> > 1 file changed, 49 insertions(+), 30 deletions(-)
>
> Can we get a sandbox test for this?
Let me try to add one.
Thanks,
Peng.
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code
2019-08-21 13:35 [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Peng Fan
2019-08-21 13:35 ` [U-Boot] [PATCH V3 2/4] clk: prograte clk enable/disable to parent Peng Fan
2019-08-21 13:35 ` [U-Boot] [PATCH V3 3/4] clk: support clk tree dump Peng Fan
@ 2019-08-21 13:35 ` Peng Fan
2019-08-23 21:49 ` Simon Glass
2019-08-23 21:48 ` [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Simon Glass
3 siblings, 1 reply; 9+ messages in thread
From: Peng Fan @ 2019-08-21 13:35 UTC (permalink / raw)
To: u-boot
Since we added clk enable_count and prograte clk child enabling
operation to clk parent, so add a new function sandbox_clk_enable_count
to get enable_count for test usage.
And add test code to get the enable_count after we enable/disable
the device clk.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
V3:
Fix build for sandbox
V2:
New Patch
drivers/clk/clk_sandbox_ccf.c | 15 +++++++++++++++
include/sandbox-clk.h | 3 +++
test/dm/clk_ccf.c | 28 ++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git a/drivers/clk/clk_sandbox_ccf.c b/drivers/clk/clk_sandbox_ccf.c
index e126f18d8e..9fa27229e1 100644
--- a/drivers/clk/clk_sandbox_ccf.c
+++ b/drivers/clk/clk_sandbox_ccf.c
@@ -25,6 +25,18 @@ struct clk_pllv3 {
u32 div_shift;
};
+int sandbox_clk_enable_count(struct clk *clk)
+{
+ struct clk *clkp = NULL;
+ int ret;
+
+ ret = clk_get_by_id(clk->id, &clkp);
+ if (ret)
+ return 0;
+
+ return clkp->enable_count;
+}
+
static ulong clk_pllv3_get_rate(struct clk *clk)
{
unsigned long parent_rate = clk_get_parent_rate(clk);
@@ -254,6 +266,9 @@ static int sandbox_clk_ccf_probe(struct udevice *dev)
sandbox_clk_composite("i2c", i2c_sels, ARRAY_SIZE(i2c_sels),
®, 0));
+ clk_dm(SANDBOX_CLK_I2C_ROOT,
+ sandbox_clk_gate2("i2c_root", "i2c", base + 0x7c, 0));
+
return 0;
}
diff --git a/include/sandbox-clk.h b/include/sandbox-clk.h
index f449de1364..296cddfbb0 100644
--- a/include/sandbox-clk.h
+++ b/include/sandbox-clk.h
@@ -20,6 +20,7 @@ enum {
SANDBOX_CLK_USDHC1_SEL,
SANDBOX_CLK_USDHC2_SEL,
SANDBOX_CLK_I2C,
+ SANDBOX_CLK_I2C_ROOT,
};
enum sandbox_pllv3_type {
@@ -74,4 +75,6 @@ static inline struct clk *sandbox_clk_mux(const char *name, void __iomem *reg,
width, 0);
}
+int sandbox_clk_enable_count(struct clk *clk);
+
#endif /* __SANDBOX_CLK_H__ */
diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c
index bbc4b500e8..ae3a4d8a76 100644
--- a/test/dm/clk_ccf.c
+++ b/test/dm/clk_ccf.c
@@ -64,6 +64,34 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
rate = clk_get_rate(clk);
ut_asserteq(rate, 60000000);
+#if CONFIG_IS_ENABLED(CLK_CCF)
+ /* Test clk tree enable/disable */
+ ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk);
+ ut_assertok(ret);
+ ut_asserteq_str("i2c_root", clk->dev->name);
+
+ ret = clk_enable(clk);
+ ut_assertok(ret);
+
+ ret = sandbox_clk_enable_count(clk);
+ ut_asserteq(ret, 1);
+
+ ret = clk_get_by_id(SANDBOX_CLK_I2C, &pclk);
+ ut_assertok(ret);
+
+ ret = sandbox_clk_enable_count(pclk);
+ ut_asserteq(ret, 1);
+
+ ret = clk_disable(clk);
+ ut_assertok(ret);
+
+ ret = sandbox_clk_enable_count(clk);
+ ut_asserteq(ret, 0);
+
+ ret = sandbox_clk_enable_count(pclk);
+ ut_asserteq(ret, 0);
+#endif
+
return 1;
}
--
2.16.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code
2019-08-21 13:35 ` [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code Peng Fan
@ 2019-08-23 21:49 ` Simon Glass
0 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2019-08-23 21:49 UTC (permalink / raw)
To: u-boot
On Wed, 21 Aug 2019 at 07:35, Peng Fan <peng.fan@nxp.com> wrote:
>
> Since we added clk enable_count and prograte clk child enabling
> operation to clk parent, so add a new function sandbox_clk_enable_count
> to get enable_count for test usage.
>
> And add test code to get the enable_count after we enable/disable
> the device clk.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>
> V3:
> Fix build for sandbox
> V2:
> New Patch
>
> drivers/clk/clk_sandbox_ccf.c | 15 +++++++++++++++
> include/sandbox-clk.h | 3 +++
> test/dm/clk_ccf.c | 28 ++++++++++++++++++++++++++++
> 3 files changed, 46 insertions(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 1/4] clk: introduce enable_count
2019-08-21 13:35 [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Peng Fan
` (2 preceding siblings ...)
2019-08-21 13:35 ` [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code Peng Fan
@ 2019-08-23 21:48 ` Simon Glass
2019-08-26 1:08 ` Peng Fan
3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2019-08-23 21:48 UTC (permalink / raw)
To: u-boot
Hi Peng,
On Wed, 21 Aug 2019 at 07:35, Peng Fan <peng.fan@nxp.com> wrote:
>
> As what Linux Kernel 5.3.0 provides when enable/disable clk,
> there is an enable_count in clk_core_disable/enable. Introduce
> enable_count to track the clk enable/disable count when
> clk_enable/disable for CCF. And Initialize enable_count to 0 when
> register the clk.
>
> And clk tree dump with enable_count will be supported, it will
> be easy for us to check the clk status with enable_count
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>
> V3:
> None
> CI: https://travis-ci.org/MrVan/u-boot/builds/574753709
> V2:
> Improve commit log
> Rename enable_cnt to enable_count following Linux Kernel
>
> drivers/clk/clk.c | 1 +
> drivers/clk/clk_fixed_rate.c | 1 +
> include/clk.h | 1 +
> 3 files changed, 3 insertions(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
Do you think it would be worth making this a u8 to save space?
Or perhaps this feature could be optional?
Regards,
Simon
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH V3 1/4] clk: introduce enable_count
2019-08-23 21:48 ` [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Simon Glass
@ 2019-08-26 1:08 ` Peng Fan
0 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2019-08-26 1:08 UTC (permalink / raw)
To: u-boot
Hi Simon,
> Subject: Re: [PATCH V3 1/4] clk: introduce enable_count
>
> Hi Peng,
>
> On Wed, 21 Aug 2019 at 07:35, Peng Fan <peng.fan@nxp.com> wrote:
> >
> > As what Linux Kernel 5.3.0 provides when enable/disable clk, there is
> > an enable_count in clk_core_disable/enable. Introduce enable_count to
> > track the clk enable/disable count when clk_enable/disable for CCF.
> > And Initialize enable_count to 0 when register the clk.
> >
> > And clk tree dump with enable_count will be supported, it will be easy
> > for us to check the clk status with enable_count
> >
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
> >
> > V3:
> > None
> > CI:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftrav
> >
> is-ci.org%2FMrVan%2Fu-boot%2Fbuilds%2F574753709&data=02%7C01
> %7Cpen
> >
> g.fan%40nxp.com%7C626abf64d2f8431f2bcc08d72813bbb2%7C686ea1d3bc
> 2b4c6fa
> >
> 92cd99c5c301635%7C0%7C0%7C637021937522749993&sdata=PQs59S
> 1gAK8P%2B
> > HGOfXKweJlVHqKGJDZ11jM%2F45%2BCz7E%3D&reserved=0
> > V2:
> > Improve commit log
> > Rename enable_cnt to enable_count following Linux Kernel
> >
> > drivers/clk/clk.c | 1 +
> > drivers/clk/clk_fixed_rate.c | 1 +
> > include/clk.h | 1 +
> > 3 files changed, 3 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Do you think it would be worth making this a u8 to save space?
The structured is not marked __packed, so u8 would not save space.
>
> Or perhaps this feature could be optional?
I'll try.
Thanks,
Peng.
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 9+ messages in thread