From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4.2 01/13] clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
Date: Tue, 01 Jul 2014 11:30:47 +0200 [thread overview]
Message-ID: <2161459.ftBWKNzjEe@diego> (raw)
In-Reply-To: <CAG374jAeMKm-6D3Ai2Bzayr=jUJYMgtTuAdi6PjbCr4JUpo-zg@mail.gmail.com>
From: Boris BREZILLON <b.brezillon@overkiz.com>
In case the rate_hw does not implement determine_rate, but only round_rate
we fallback to best_parent selection if mux_hw is present and support
reparenting.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
This also fixes a rate calculation problem when using the standard div and
mux ops, as in this case currently only the mux->determine_rate is used
in the composite rate calculation.
So when for example the composite clock has two parents at 600 and 800MHz,
the requested rate is 75MHz, which the divider could provide, without this
change the rate would be set 600MHz ignoring the divider completely.
This may be way out of spec for the component.
[fixed the output to actually return a rate instead of the diff]
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
changes since v4.1:
- forgot the From override, Boris is the original author
changes since v4:
- address comments from Gabriel Fernandez
- use abs()
- init best_rate
drivers/clk/clk-composite.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 57a078e..9548bfc 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -64,11 +64,56 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk_hw *rate_hw = composite->rate_hw;
struct clk_hw *mux_hw = composite->mux_hw;
+ struct clk *parent;
+ unsigned long parent_rate;
+ long tmp_rate, best_rate = 0;
+ unsigned long rate_diff;
+ unsigned long best_rate_diff = ULONG_MAX;
+ int i;
if (rate_hw && rate_ops && rate_ops->determine_rate) {
rate_hw->clk = hw->clk;
return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
best_parent_p);
+ } else if (rate_hw && rate_ops && rate_ops->round_rate &&
+ mux_hw && mux_ops && mux_ops->set_parent) {
+ *best_parent_p = NULL;
+
+ if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+ *best_parent_p = clk_get_parent(mux_hw->clk);
+ *best_parent_rate = __clk_get_rate(*best_parent_p);
+
+ return rate_ops->round_rate(rate_hw, rate,
+ best_parent_rate);
+ }
+
+ for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+ parent = clk_get_parent_by_index(mux_hw->clk, i);
+ if (!parent)
+ continue;
+
+ parent_rate = __clk_get_rate(parent);
+
+ tmp_rate = rate_ops->round_rate(rate_hw, rate,
+ &parent_rate);
+ if (tmp_rate < 0)
+ continue;
+
+ rate_diff = abs(rate - tmp_rate);
+
+ if (!rate_diff || !*best_parent_p
+ || best_rate_diff > rate_diff) {
+ *best_parent_p = parent;
+ *best_parent_rate = parent_rate;
+ best_rate_diff = rate_diff;
+ best_rate = tmp_rate;
+ }
+
+ if (!rate_diff)
+ return rate;
+ }
+
+ return best_rate;
} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
mux_hw->clk = hw->clk;
return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -196,7 +241,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->rate_hw = rate_hw;
composite->rate_ops = rate_ops;
clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
- if (rate_ops->determine_rate)
+ if (rate_ops->determine_rate ||
+ (rate_ops->round_rate && clk_composite_ops->set_parent))
clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
--
1.9.0
next prev parent reply other threads:[~2014-07-01 9:30 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-22 20:41 [PATCH v4 00/13] Clock support for rk3066,rk3188 and rk3288 Heiko Stübner
2014-06-22 20:43 ` [PATCH v4 01/13] clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent Heiko Stübner
2014-06-25 7:57 ` Gabriel Fernandez
2014-06-30 22:00 ` [PATCH v4.1 " Heiko Stübner
2014-07-01 9:30 ` Heiko Stübner [this message]
2014-06-22 20:43 ` [PATCH v4 02/13] clk: composite: allow read-only clocks Heiko Stübner
2014-07-01 20:46 ` Mike Turquette
2014-06-22 20:44 ` [PATCH v4 03/13] clk: rockchip: add basic infrastructure for clock branches Heiko Stübner
2014-07-01 18:45 ` Mike Turquette
2014-06-22 20:44 ` [PATCH v4 04/13] clk: rockchip: add clock type for pll clocks and pll used on rk3066 Heiko Stübner
2014-06-22 20:45 ` [PATCH v4 05/13] clk: rockchip: add reset controller Heiko Stübner
2014-06-22 20:46 ` [PATCH v4 06/13] dt-bindings: add documentation for rk3188 clock and reset unit Heiko Stübner
2014-06-22 20:47 ` [PATCH v4 07/13] clk: rockchip: add clock driver for rk3188 and rk3066 clocks Heiko Stübner
2014-06-22 20:47 ` [PATCH v4 08/13] ARM: rockchip: Select ARCH_HAS_RESET_CONTROLLER Heiko Stübner
2014-06-22 20:48 ` [PATCH v4 09/13] ARM: dts: rockchip: add cru nodes and update device clocks to use it Heiko Stübner
2014-06-22 20:48 ` [PATCH v4 10/13] ARM: dts: rockchip: move oscillator input clock into main dtsi Heiko Stübner
2014-06-22 20:49 ` [PATCH v4 11/13] arm: dts: rockchip: remove obsolete clock gate definitions Heiko Stübner
2014-06-22 20:49 ` [PATCH v4 12/13] clk: rockchip: add clock controller for rk3288 Heiko Stübner
2014-06-22 20:50 ` [PATCH v4 13/13] dt-bindings: add documentation for rk3288 cru Heiko Stübner
2014-06-29 17:41 ` [PATCH v4 00/13] Clock support for rk3066,rk3188 and rk3288 Max Schwarz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2161459.ftBWKNzjEe@diego \
--to=heiko@sntech.de \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).