From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 1/6] clk: sunxi-ng: div: Add support for fixed post-divider
Date: Wed, 5 Jul 2017 09:43:10 +0200 [thread overview]
Message-ID: <20170705074310.b6ycyf27htv5gkxm@flea> (raw)
In-Reply-To: <805048a548031cafc890e6ea06ee773bdfb199d0.1499197129.git-series.plaes@plaes.org>
On Tue, Jul 04, 2017 at 11:04:56PM +0300, Priit Laes wrote:
> SATA clock on sun4i/sun7i is of type (parent) / M / 6 where
> 6 is fixed post-divider.
>
> Signed-off-by: Priit Laes <plaes@plaes.org>
> ---
> drivers/clk/sunxi-ng/ccu_div.c | 18 ++++++++++++++++--
> drivers/clk/sunxi-ng/ccu_div.h | 3 ++-
> 2 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
> index c0e5c10..054b12a 100644
> --- a/drivers/clk/sunxi-ng/ccu_div.c
> +++ b/drivers/clk/sunxi-ng/ccu_div.c
> @@ -21,6 +21,9 @@ static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
> {
> struct ccu_div *cd = data;
>
> + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
> + rate /= cd->fixed_post_div;
> +
> return divider_round_rate_parent(&cd->common.hw, parent,
> rate, parent_rate,
> cd->div.table, cd->div.width,
This doesn't work.
The rate formula is
rate = parent / div / 6
Which is equivalent to
div = rate * 6 / parent
You should be multiplying the rate, not dividing it (or dividing the
parent, but then you'll also need to multiply it back after the call
to divider_round_rate_parent).
Consider this, some driver wants to set a rate of 100MHz on this
clock. The parent is 1.2GHz, and you have your postdiv of 6.
The divider we want to compute is 2, obviously.
You're doing here:
rate / 6 = parent / div
Which means that you'll end up trying to find the divider between
1.2GHz and 16.6666MHz, which is going to be 72.
> @@ -62,8 +65,13 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
> parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
> parent_rate);
>
> - return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
> - cd->div.flags);
> + val = divider_recalc_rate(hw, parent_rate, val, cd->div.table,
> + cd->div.flags);
> +
> + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
> + val /= cd->fixed_post_div;
> +
> + return val;
> }
>
> static int ccu_div_determine_rate(struct clk_hw *hw,
> @@ -71,6 +79,9 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
> {
> struct ccu_div *cd = hw_to_ccu_div(hw);
>
> + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
> + req->rate *= cd->fixed_post_div;
> +
I guess this is why you never really saw the issue. Combined with your
division in ccu_div_round_rate, it produces the exact rate you were
given as an argument.
> return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
> req, ccu_div_round_rate, cd);
> }
> @@ -89,6 +100,9 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
> val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
> cd->div.flags);
>
> + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
> + val /= cd->fixed_post_div;
> +
If you multiply the rate before calling divider_get_val, you won't
have to do the division of the divider, with all the rounding
weirdness it might create.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170705/4fbf8943/attachment.sig>
next prev parent reply other threads:[~2017-07-05 7:43 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-04 20:04 [PATCH v5 0/6] ARM: sunxi: Convert sun4i/sun7i series SoCs to sunxi-ng CCU Priit Laes
2017-07-04 20:04 ` [PATCH v5 1/6] clk: sunxi-ng: div: Add support for fixed post-divider Priit Laes
2017-07-05 4:06 ` Chen-Yu Tsai
2017-07-05 7:43 ` Maxime Ripard [this message]
2017-07-10 8:13 ` [linux-sunxi] " Olliver Schinagl
2017-07-04 20:04 ` [PATCH v5 2/6] clk: sunxi-ng: Add sun4i/sun7i CCU driver Priit Laes
2017-07-09 12:25 ` Jonathan Liu
2017-07-13 19:12 ` Priit Laes
2017-07-10 9:45 ` [linux-sunxi] " Olliver Schinagl
2017-07-13 19:23 ` Priit Laes
2017-07-13 19:46 ` Olliver Schinagl
2017-07-14 13:48 ` Priit Laes
2017-07-04 20:04 ` [PATCH v5 3/6] dt-bindings: List devicetree binding for the CCU of Allwinner A20 Priit Laes
2017-07-05 4:07 ` Chen-Yu Tsai
2017-07-04 20:04 ` [PATCH v5 4/6] dt-bindings: List devicetree binding for the CCU of Allwinner A10 Priit Laes
2017-07-05 4:07 ` Chen-Yu Tsai
2017-07-04 20:05 ` [PATCH v5 5/6] ARM: sun7i: Convert to CCU Priit Laes
2017-07-10 11:23 ` [linux-sunxi] " Olliver Schinagl
2017-07-10 11:55 ` Maxime Ripard
2017-07-10 12:24 ` Olliver Schinagl
2017-07-04 20:05 ` [PATCH v5 6/6] ARM: sun4i: " Priit Laes
2017-07-10 11:44 ` [linux-sunxi] " Olliver Schinagl
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=20170705074310.b6ycyf27htv5gkxm@flea \
--to=maxime.ripard@free-electrons.com \
--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