git: 9df53d07e6bc - main - clk: add call for nodes to get the programmed/decided frequency passed back
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 26 Dec 2021 18:27:15 UTC
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=9df53d07e6bce5d38fca860367da546f6a420a90 commit 9df53d07e6bce5d38fca860367da546f6a420a90 Author: Adrian Chadd <adrian@FreeBSD.org> AuthorDate: 2021-12-14 18:01:08 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2021-12-26 12:18:53 +0000 clk: add call for nodes to get the programmed/decided frequency passed back Summary: The existing call can only really be used for a node wishing to configure its parent, but as we don't pass in a pointer to the freq, we can't set it to what it would be for a DRY_RUN pass. So for clock nodes that wish to try setting parent frequencies to see which would be the best for its own target frequency, we really do need a way to call in and pass in a flag /and/ a pointer to freq so it can be updated for us as the clock tree is recursed through. Reviewers: manu Approved by: manu Subscribers: imp Differential Revision: https://reviews.freebsd.org/D33445 --- sys/dev/extres/clk/clk.c | 35 +++++++++++++++++++++++++++++------ sys/dev/extres/clk/clk.h | 2 ++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/sys/dev/extres/clk/clk.c b/sys/dev/extres/clk/clk.c index f4284fcd59ba..2be233c465a9 100644 --- a/sys/dev/extres/clk/clk.c +++ b/sys/dev/extres/clk/clk.c @@ -965,8 +965,8 @@ clknode_get_freq(struct clknode *clknode, uint64_t *freq) return (0); } -int -clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, +static int +_clknode_set_freq(struct clknode *clknode, uint64_t *freq, int flags, int enablecnt) { int rv, done; @@ -976,7 +976,7 @@ clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, CLK_TOPO_XASSERT(); /* Check for no change */ - if (clknode->freq == freq) + if (clknode->freq == *freq) return (0); parent_freq = 0; @@ -1003,7 +1003,7 @@ clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, } /* Set frequency for this clock. */ - rv = CLKNODE_SET_FREQ(clknode, parent_freq, &freq, flags, &done); + rv = CLKNODE_SET_FREQ(clknode, parent_freq, freq, flags, &done); if (rv != 0) { printf("Cannot set frequency for clk: %s, error: %d\n", clknode->name, rv); @@ -1015,7 +1015,7 @@ clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, if (done) { /* Success - invalidate frequency cache for all children. */ if ((flags & CLK_SET_DRYRUN) == 0) { - clknode->freq = freq; + clknode->freq = *freq; /* Clock might have reparent during set_freq */ if (clknode->parent_cnt > 0) { rv = clknode_get_freq(clknode->parent, @@ -1028,7 +1028,8 @@ clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, } } else if (clknode->parent != NULL) { /* Nothing changed, pass request to parent. */ - rv = clknode_set_freq(clknode->parent, freq, flags, enablecnt); + rv = _clknode_set_freq(clknode->parent, freq, flags, + enablecnt); } else { /* End of chain without action. */ printf("Cannot set frequency for clk: %s, end of chain\n", @@ -1039,6 +1040,28 @@ clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, return (rv); } +int +clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, + int enablecnt) +{ + + return (_clknode_set_freq(clknode, &freq, flags, enablecnt)); +} + +int +clknode_try_freq(struct clknode *clknode, uint64_t freq, int flags, + int enablecnt, uint64_t *out_freq) +{ + int rv; + + rv = _clknode_set_freq(clknode, &freq, flags | CLK_SET_DRYRUN, + enablecnt); + if (out_freq != NULL) + *out_freq = freq; + + return (rv); +} + int clknode_enable(struct clknode *clknode) { diff --git a/sys/dev/extres/clk/clk.h b/sys/dev/extres/clk/clk.h index 3ddf8fc574de..5daf3c0731ee 100644 --- a/sys/dev/extres/clk/clk.h +++ b/sys/dev/extres/clk/clk.h @@ -115,6 +115,8 @@ struct clknode *clknode_find_by_id(struct clkdom *clkdom, intptr_t id); int clknode_get_freq(struct clknode *clknode, uint64_t *freq); int clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, int enablecnt); +int clknode_try_freq(struct clknode *clknode, uint64_t freq, int flags, + int enablecnt, uint64_t *out_freq); int clknode_enable(struct clknode *clknode); int clknode_disable(struct clknode *clknode); int clknode_stop(struct clknode *clknode, int depth);