From: Conor Dooley <conor.dooley@microchip.com>
To: Chen Wang <unicorn_wang@outlook.com>
Cc: Conor Dooley <conor@kernel.org>, Chen Wang <unicornxw@gmail.com>,
<aou@eecs.berkeley.edu>, <chao.wei@sophgo.com>,
<krzysztof.kozlowski+dt@linaro.org>, <mturquette@baylibre.com>,
<palmer@dabbelt.com>, <paul.walmsley@sifive.com>,
<richardcochran@gmail.com>, <robh+dt@kernel.org>,
<sboyd@kernel.org>, <devicetree@vger.kernel.org>,
<linux-clk@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-riscv@lists.infradead.org>, <haijiao.liu@sophgo.com>,
<xiaoguang.xing@sophgo.com>, <guoren@kernel.org>,
<jszhang@kernel.org>, <inochiama@outlook.com>,
<samuel.holland@sifive.com>
Subject: Re: [PATCH v6 3/4] clk: sophgo: Add SG2042 clock generator driver
Date: Tue, 12 Dec 2023 08:37:39 +0000 [thread overview]
Message-ID: <20231212-unnerving-rule-1052a5b7253e@wendy> (raw)
In-Reply-To: <MA0P287MB0332A937E4DF0044594B19CCFE8EA@MA0P287MB0332.INDP287.PROD.OUTLOOK.COM>
[-- Attachment #1: Type: text/plain, Size: 4290 bytes --]
On Tue, Dec 12, 2023 at 10:22:28AM +0800, Chen Wang wrote:
> On 2023/12/9 0:47, Conor Dooley wrote:
> > On Fri, Dec 08, 2023 at 09:14:32AM +0800, Chen Wang wrote:
> > > +#define ENCODE_PLL_CTRL(fbdiv, p1, p2, refdiv) \
> > > + (((fbdiv & 0xfff) << 16) | ((p2 & 0x7) << 12) | ((p1 & 0x7) << 8) | (refdiv & 0x3f))
> > IMO this should be a function not a macro.
> Would like to listen why it should be a function instead of a macro? Any
> experiences you can share with me?
Readability. A function, which could be inlined allows you to break this
up and make it easier to read.
> > > +/*
> > > + * Based on input rate/prate/fbdiv/refdiv, look up the postdiv1_2 table
> > > + * to get the closest postdiiv combination.
> > > + * @rate: FOUTPOSTDIV
> > > + * @prate: parent rate, i.e. FREF
> > > + * @fbdiv: FBDIV
> > > + * @refdiv: REFDIV
> > > + * @postdiv1: POSTDIV1, output
> > > + * @postdiv2: POSTDIV2, output
> > > + * See TRM:
> > > + * FOUTPOSTDIV = FREF * FBDIV / REFDIV / (POSTDIV1 * POSTDIV2)
> > > + * So we get following formula to get POSTDIV1 and POSTDIV2:
> > > + * POSTDIV = (prate/REFDIV) x FBDIV/rate
> > > + * above POSTDIV = POSTDIV1*POSTDIV2
> > > + */
> > > +static int __sg2042_pll_get_postdiv_1_2(
> > > + unsigned long rate,
> > > + unsigned long prate,
> > > + unsigned int fbdiv,
> > > + unsigned int refdiv,
> > > + unsigned int *postdiv1,
> > > + unsigned int *postdiv2)
> > This is not the coding style btw.
> Agree, will fix this.
> > > +{
> > > + int index = 0;
> > > + int ret = 0;
> > > + u64 tmp0;
> > > +
> > > + /* prate/REFDIV and result save to tmp0 */
> > > + tmp0 = prate;
> > > + do_div(tmp0, refdiv);
> > > +
> > > + /* ((prate/REFDIV) x FBDIV) and result save to tmp0 */
> > > + tmp0 *= fbdiv;
> > > +
> > > + /* ((prate/REFDIV) x FBDIV)/rate and result save to tmp0 */
> > > + do_div(tmp0, rate);
> > > +
> > > + /* tmp0 is POSTDIV1*POSTDIV2, now we calculate div1 and div2 value */
> > > + if (tmp0 <= 7) {
> > > + /* (div1 * div2) <= 7, no need to use array search */
> > > + *postdiv1 = tmp0;
> > > + *postdiv2 = 1;
> > > + } else {
> > > + /* (div1 * div2) > 7, use array search */
> > > + for (index = 0; index < ARRAY_SIZE(postdiv1_2); index++) {
> > > + if (tmp0 > postdiv1_2[index][POSTDIV_RESULT_INDEX]) {
> > > + continue;
> > > + } else {
> > > + /* found it */
> > > + break;
> > > + }
> > > + }
> > > + if (index < ARRAY_SIZE(postdiv1_2)) {
> > > + *postdiv1 = postdiv1_2[index][1];
> > > + *postdiv2 = postdiv1_2[index][0];
> > > + } else {
> > > + pr_debug("%s can not find in postdiv array!\n", __func__);
> > > + ret = -EINVAL;
> > > + }
> > > + }
> > > +
> > > + return ret;
> > > +}
> > Reading this function it makes me wonder if (and I am far from the best
> > person to comment, someone like Stephen is vastly more qualified) you
> > should model this as several "stages", each implemented by the
> > "standard" clocks - like clk_divider etc. The code here is quite
> > complicated IMO as it seems to be trying to implement several stages of
> > division in one go.
>
> The objective of __sg2042_pll_get_postdiv_1_2() is straightforward: based on
> the formula defined by the TRM, with input rate/prate/fbdiv/refdiv, we can
> get the possiblle combination of POSTDIV1 and POSTDIV2 by looking up the
> table of postdiv1_2. We will later use it to setup the clock register.
>
> Though the codes looks a bit complicated, but accually it is calculate with
> the formula : POSTDIV = (prate/REFDIV) x FBDIV/rate, I just separate it into
> several steps to make it easy to understand, I have listed the formula in
> the comment on top of the function.
I understand what you are doing, I did something similar myself
previously. My suggestion/question was about using the "standard" types
of clock that the core provides to represent as many of the clocks in
this driver as is feasible.
> > There's quite a lot in the driver and I will admit that I have not read
> > it all my any means (I skimmed from here onwards), but in general my
> > advice would be to try and reuse the generic code as much as possible.
> Agree, I will double check and try to optimize the code in next revision.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Conor Dooley <conor.dooley@microchip.com>
To: Chen Wang <unicorn_wang@outlook.com>
Cc: Conor Dooley <conor@kernel.org>, Chen Wang <unicornxw@gmail.com>,
<aou@eecs.berkeley.edu>, <chao.wei@sophgo.com>,
<krzysztof.kozlowski+dt@linaro.org>, <mturquette@baylibre.com>,
<palmer@dabbelt.com>, <paul.walmsley@sifive.com>,
<richardcochran@gmail.com>, <robh+dt@kernel.org>,
<sboyd@kernel.org>, <devicetree@vger.kernel.org>,
<linux-clk@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-riscv@lists.infradead.org>, <haijiao.liu@sophgo.com>,
<xiaoguang.xing@sophgo.com>, <guoren@kernel.org>,
<jszhang@kernel.org>, <inochiama@outlook.com>,
<samuel.holland@sifive.com>
Subject: Re: [PATCH v6 3/4] clk: sophgo: Add SG2042 clock generator driver
Date: Tue, 12 Dec 2023 08:37:39 +0000 [thread overview]
Message-ID: <20231212-unnerving-rule-1052a5b7253e@wendy> (raw)
In-Reply-To: <MA0P287MB0332A937E4DF0044594B19CCFE8EA@MA0P287MB0332.INDP287.PROD.OUTLOOK.COM>
[-- Attachment #1.1: Type: text/plain, Size: 4290 bytes --]
On Tue, Dec 12, 2023 at 10:22:28AM +0800, Chen Wang wrote:
> On 2023/12/9 0:47, Conor Dooley wrote:
> > On Fri, Dec 08, 2023 at 09:14:32AM +0800, Chen Wang wrote:
> > > +#define ENCODE_PLL_CTRL(fbdiv, p1, p2, refdiv) \
> > > + (((fbdiv & 0xfff) << 16) | ((p2 & 0x7) << 12) | ((p1 & 0x7) << 8) | (refdiv & 0x3f))
> > IMO this should be a function not a macro.
> Would like to listen why it should be a function instead of a macro? Any
> experiences you can share with me?
Readability. A function, which could be inlined allows you to break this
up and make it easier to read.
> > > +/*
> > > + * Based on input rate/prate/fbdiv/refdiv, look up the postdiv1_2 table
> > > + * to get the closest postdiiv combination.
> > > + * @rate: FOUTPOSTDIV
> > > + * @prate: parent rate, i.e. FREF
> > > + * @fbdiv: FBDIV
> > > + * @refdiv: REFDIV
> > > + * @postdiv1: POSTDIV1, output
> > > + * @postdiv2: POSTDIV2, output
> > > + * See TRM:
> > > + * FOUTPOSTDIV = FREF * FBDIV / REFDIV / (POSTDIV1 * POSTDIV2)
> > > + * So we get following formula to get POSTDIV1 and POSTDIV2:
> > > + * POSTDIV = (prate/REFDIV) x FBDIV/rate
> > > + * above POSTDIV = POSTDIV1*POSTDIV2
> > > + */
> > > +static int __sg2042_pll_get_postdiv_1_2(
> > > + unsigned long rate,
> > > + unsigned long prate,
> > > + unsigned int fbdiv,
> > > + unsigned int refdiv,
> > > + unsigned int *postdiv1,
> > > + unsigned int *postdiv2)
> > This is not the coding style btw.
> Agree, will fix this.
> > > +{
> > > + int index = 0;
> > > + int ret = 0;
> > > + u64 tmp0;
> > > +
> > > + /* prate/REFDIV and result save to tmp0 */
> > > + tmp0 = prate;
> > > + do_div(tmp0, refdiv);
> > > +
> > > + /* ((prate/REFDIV) x FBDIV) and result save to tmp0 */
> > > + tmp0 *= fbdiv;
> > > +
> > > + /* ((prate/REFDIV) x FBDIV)/rate and result save to tmp0 */
> > > + do_div(tmp0, rate);
> > > +
> > > + /* tmp0 is POSTDIV1*POSTDIV2, now we calculate div1 and div2 value */
> > > + if (tmp0 <= 7) {
> > > + /* (div1 * div2) <= 7, no need to use array search */
> > > + *postdiv1 = tmp0;
> > > + *postdiv2 = 1;
> > > + } else {
> > > + /* (div1 * div2) > 7, use array search */
> > > + for (index = 0; index < ARRAY_SIZE(postdiv1_2); index++) {
> > > + if (tmp0 > postdiv1_2[index][POSTDIV_RESULT_INDEX]) {
> > > + continue;
> > > + } else {
> > > + /* found it */
> > > + break;
> > > + }
> > > + }
> > > + if (index < ARRAY_SIZE(postdiv1_2)) {
> > > + *postdiv1 = postdiv1_2[index][1];
> > > + *postdiv2 = postdiv1_2[index][0];
> > > + } else {
> > > + pr_debug("%s can not find in postdiv array!\n", __func__);
> > > + ret = -EINVAL;
> > > + }
> > > + }
> > > +
> > > + return ret;
> > > +}
> > Reading this function it makes me wonder if (and I am far from the best
> > person to comment, someone like Stephen is vastly more qualified) you
> > should model this as several "stages", each implemented by the
> > "standard" clocks - like clk_divider etc. The code here is quite
> > complicated IMO as it seems to be trying to implement several stages of
> > division in one go.
>
> The objective of __sg2042_pll_get_postdiv_1_2() is straightforward: based on
> the formula defined by the TRM, with input rate/prate/fbdiv/refdiv, we can
> get the possiblle combination of POSTDIV1 and POSTDIV2 by looking up the
> table of postdiv1_2. We will later use it to setup the clock register.
>
> Though the codes looks a bit complicated, but accually it is calculate with
> the formula : POSTDIV = (prate/REFDIV) x FBDIV/rate, I just separate it into
> several steps to make it easy to understand, I have listed the formula in
> the comment on top of the function.
I understand what you are doing, I did something similar myself
previously. My suggestion/question was about using the "standard" types
of clock that the core provides to represent as many of the clocks in
this driver as is feasible.
> > There's quite a lot in the driver and I will admit that I have not read
> > it all my any means (I skimmed from here onwards), but in general my
> > advice would be to try and reuse the generic code as much as possible.
> Agree, I will double check and try to optimize the code in next revision.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2023-12-12 8:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-08 1:13 [PATCH v6 0/4] riscv: sophgo: add clock support for sg2042 Chen Wang
2023-12-08 1:13 ` Chen Wang
2023-12-08 1:13 ` [PATCH v6 1/4] dt-bindings: soc: sophgo: Add Sophgo system control module Chen Wang
2023-12-08 1:13 ` Chen Wang
2023-12-08 1:14 ` [PATCH v6 2/4] dt-bindings: clock: sophgo: support SG2042 Chen Wang
2023-12-08 1:14 ` Chen Wang
2023-12-08 16:26 ` Conor Dooley
2023-12-08 16:26 ` Conor Dooley
2023-12-08 1:14 ` [PATCH v6 3/4] clk: sophgo: Add SG2042 clock generator driver Chen Wang
2023-12-08 1:14 ` Chen Wang
2023-12-08 16:47 ` Conor Dooley
2023-12-08 16:47 ` Conor Dooley
2023-12-12 2:22 ` Chen Wang
2023-12-12 2:22 ` Chen Wang
2023-12-12 8:37 ` Conor Dooley [this message]
2023-12-12 8:37 ` Conor Dooley
2023-12-14 0:15 ` Stephen Boyd
2023-12-14 0:15 ` Stephen Boyd
2023-12-18 9:01 ` Chen Wang
2023-12-18 9:01 ` Chen Wang
2023-12-09 6:22 ` Dan Carpenter
2023-12-09 6:22 ` Dan Carpenter
2023-12-12 0:05 ` Chen Wang
2023-12-12 0:05 ` Chen Wang
2023-12-08 1:15 ` [PATCH v6 4/4] riscv: dts: add clock generator for Sophgo SG2042 SoC Chen Wang
2023-12-08 1:15 ` Chen Wang
2023-12-08 10:11 ` [PATCH v6 0/4] riscv: sophgo: add clock support for sg2042 Chen Wang
2023-12-08 10:11 ` Chen Wang
2023-12-08 10:30 ` Conor Dooley
2023-12-08 10:30 ` Conor Dooley
2023-12-08 11:57 ` Chen Wang
2023-12-08 11:57 ` Chen Wang
-- strict thread matches above, loose matches on Subject: below --
2023-12-08 11:45 [PATCH v6 3/4] clk: sophgo: Add SG2042 clock generator driver kernel test robot
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=20231212-unnerving-rule-1052a5b7253e@wendy \
--to=conor.dooley@microchip.com \
--cc=aou@eecs.berkeley.edu \
--cc=chao.wei@sophgo.com \
--cc=conor@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=guoren@kernel.org \
--cc=haijiao.liu@sophgo.com \
--cc=inochiama@outlook.com \
--cc=jszhang@kernel.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mturquette@baylibre.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=richardcochran@gmail.com \
--cc=robh+dt@kernel.org \
--cc=samuel.holland@sifive.com \
--cc=sboyd@kernel.org \
--cc=unicorn_wang@outlook.com \
--cc=unicornxw@gmail.com \
--cc=xiaoguang.xing@sophgo.com \
/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.