All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime.ripard@free-electrons.com>
To: Priit Laes <plaes@plaes.org>
Cc: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>, Chen-Yu Tsai <wens@csie.org>,
	Russell King <linux@armlinux.org.uk>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com,
	Jonathan Liu <net147@gmail.com>
Subject: Re: [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>

[-- Attachment #1: Type: text/plain, Size: 3217 bytes --]

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: Priit Laes <plaes-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>
Cc: Michael Turquette
	<mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>,
	Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>,
	Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Jonathan Liu <net147-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: Re: [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-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 3149 bytes --]

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-q/aMd4JkU83YtjvyW6yDsg@public.gmane.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

WARNING: multiple messages have this Message-ID (diff)
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>

  parent reply	other threads:[~2017-07-05  7:43 UTC|newest]

Thread overview: 64+ 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 ` Priit Laes
2017-07-04 20:04 ` 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-04 20:04   ` Priit Laes
2017-07-04 20:04   ` Priit Laes
2017-07-05  4:06   ` Chen-Yu Tsai
2017-07-05  4:06     ` Chen-Yu Tsai
2017-07-05  4:06     ` Chen-Yu Tsai
2017-07-05  7:43   ` Maxime Ripard [this message]
2017-07-05  7:43     ` Maxime Ripard
2017-07-05  7:43     ` Maxime Ripard
2017-07-10  8:13   ` [linux-sunxi] " Olliver Schinagl
2017-07-10  8:13     ` Olliver Schinagl
2017-07-10  8:13     ` Olliver Schinagl
2017-07-04 20:04 ` [PATCH v5 2/6] clk: sunxi-ng: Add sun4i/sun7i CCU driver Priit Laes
2017-07-04 20:04   ` Priit Laes
2017-07-04 20:04   ` Priit Laes
2017-07-09 12:25   ` Jonathan Liu
2017-07-09 12:25     ` Jonathan Liu
2017-07-09 12:25     ` Jonathan Liu
2017-07-13 19:12     ` Priit Laes
2017-07-13 19:12       ` Priit Laes
2017-07-13 19:12       ` Priit Laes
2017-07-10  9:45   ` [linux-sunxi] " Olliver Schinagl
2017-07-10  9:45     ` Olliver Schinagl
2017-07-13 19:23     ` Priit Laes
2017-07-13 19:23       ` Priit Laes
2017-07-13 19:23       ` Priit Laes
2017-07-13 19:46       ` [linux-sunxi] " Olliver Schinagl
2017-07-13 19:46         ` Olliver Schinagl
2017-07-13 19:46         ` Olliver Schinagl
2017-07-14 13:48         ` [linux-sunxi] " Priit Laes
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-04 20:04   ` Priit Laes
2017-07-04 20:04   ` Priit Laes
2017-07-05  4:07   ` Chen-Yu Tsai
2017-07-05  4:07     ` Chen-Yu Tsai
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-04 20:04   ` Priit Laes
2017-07-04 20:04   ` Priit Laes
2017-07-05  4:07   ` Chen-Yu Tsai
2017-07-05  4:07     ` Chen-Yu Tsai
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-04 20:05   ` Priit Laes
2017-07-04 20:05   ` Priit Laes
2017-07-10 11:23   ` [linux-sunxi] " Olliver Schinagl
2017-07-10 11:23     ` Olliver Schinagl
2017-07-10 11:23     ` Olliver Schinagl
2017-07-10 11:55     ` Maxime Ripard
2017-07-10 11:55       ` Maxime Ripard
2017-07-10 11:55       ` Maxime Ripard
2017-07-10 12:24       ` [linux-sunxi] " Olliver Schinagl
2017-07-10 12:24         ` Olliver Schinagl
2017-07-10 12:24         ` Olliver Schinagl
2017-07-04 20:05 ` [PATCH v5 6/6] ARM: sun4i: " Priit Laes
2017-07-04 20:05   ` Priit Laes
2017-07-04 20:05   ` Priit Laes
2017-07-10 11:44   ` [linux-sunxi] " Olliver Schinagl
2017-07-10 11:44     ` Olliver Schinagl
2017-07-10 11:44     ` 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=devicetree@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=linux@armlinux.org.uk \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=net147@gmail.com \
    --cc=p.zabel@pengutronix.de \
    --cc=plaes@plaes.org \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    --cc=wens@csie.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.