From: John Watts <contact@jookia.org>
To: Aleksandr Shubin <privatesub2@gmail.com>
Cc: linux-kernel@vger.kernel.org,
"Brandon Cheo Fusi" <fusibrandon13@gmail.com>,
"Uwe Kleine-König" <ukleinek@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Chen-Yu Tsai" <wens@csie.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Philipp Zabel" <p.zabel@pengutronix.de>,
"Marc Kleine-Budde" <mkl@pengutronix.de>,
"Maksim Kiselev" <bigunclemax@gmail.com>,
linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-riscv@lists.infradead.org
Subject: Re: [PATCH v9 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
Date: Thu, 23 May 2024 13:16:47 +1000 [thread overview]
Message-ID: <Zk61H05-BTVUarFV@titan> (raw)
In-Reply-To: <20240520184227.120956-3-privatesub2@gmail.com>
Hi,
Here's a quick review based on the experience of me writing my own driver.
On Mon, May 20, 2024 at 09:42:20PM +0300, Aleksandr Shubin wrote:
> + act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> + ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> +
> + /*
> + * The duration of the active phase should not be longer
> + * than the duration of the period
> + */
> + if (act_cycle > ent_cycle)
> + act_cycle = ent_cycle;
> +
> + /*
> + * We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
> + * div_m <= 8. So the multiplication fits into an u64 without
> + * overflow.
> + */
> + tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> + tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);
Doesn't ent_cycle require a + 1 here?
Shouldn't act_cycle be > ent_cycle on 0% duty cycles?
> + /* if the neighbor channel is enable, check period only */
> + use_bus_clk = FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, clk_cfg) != 0;
> + val = mul_u64_u64_div_u64(state->period,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
It would be nice if it reclocked both channels.
> + /* calculate prescale_k, PWM entire cycle */
> + ent_cycle = val >> div_m;
> + prescale_k = DIV_ROUND_DOWN_ULL(ent_cycle, 65537);
> + if (prescale_k > SUN20I_PWM_CTL_PRESCAL_K_MAX)
> + prescale_k = SUN20I_PWM_CTL_PRESCAL_K_MAX;
> +
> + do_div(ent_cycle, prescale_k + 1);
> +
> + /* for N cycles, PPRx.PWM_ENTIRE_CYCLE = (N-1) */
> + reg_period = FIELD_PREP(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, ent_cycle - 1);
> +
> + /* set duty cycle */
> + val = mul_u64_u64_div_u64(state->duty_cycle,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
> + act_cycle = val >> div_m;
> + do_div(act_cycle, prescale_k + 1);
I'm not sure about this code. I don't quite get where the 65537 comes from or
what's really happening here.
To my understanding you either want to limit PWM_ENTIRE_CYCLE to 0xFFFE so and
scale PWM_ACTIVE_CYCLE from 0 to 65535 so it can be 0x0 at 100% duty cycles and
0xFFFF at 0% duty cycles, OR you want to scale it from 0 to 65536 and check if
the value is 65536, and if it is wrap it around to 0 and flip the polarity.
Thanks,
John.
WARNING: multiple messages have this Message-ID (diff)
From: John Watts <contact@jookia.org>
To: Aleksandr Shubin <privatesub2@gmail.com>
Cc: linux-kernel@vger.kernel.org,
"Brandon Cheo Fusi" <fusibrandon13@gmail.com>,
"Uwe Kleine-König" <ukleinek@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Chen-Yu Tsai" <wens@csie.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Philipp Zabel" <p.zabel@pengutronix.de>,
"Marc Kleine-Budde" <mkl@pengutronix.de>,
"Maksim Kiselev" <bigunclemax@gmail.com>,
linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-riscv@lists.infradead.org
Subject: Re: [PATCH v9 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
Date: Thu, 23 May 2024 13:16:47 +1000 [thread overview]
Message-ID: <Zk61H05-BTVUarFV@titan> (raw)
In-Reply-To: <20240520184227.120956-3-privatesub2@gmail.com>
Hi,
Here's a quick review based on the experience of me writing my own driver.
On Mon, May 20, 2024 at 09:42:20PM +0300, Aleksandr Shubin wrote:
> + act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> + ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> +
> + /*
> + * The duration of the active phase should not be longer
> + * than the duration of the period
> + */
> + if (act_cycle > ent_cycle)
> + act_cycle = ent_cycle;
> +
> + /*
> + * We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
> + * div_m <= 8. So the multiplication fits into an u64 without
> + * overflow.
> + */
> + tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> + tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);
Doesn't ent_cycle require a + 1 here?
Shouldn't act_cycle be > ent_cycle on 0% duty cycles?
> + /* if the neighbor channel is enable, check period only */
> + use_bus_clk = FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, clk_cfg) != 0;
> + val = mul_u64_u64_div_u64(state->period,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
It would be nice if it reclocked both channels.
> + /* calculate prescale_k, PWM entire cycle */
> + ent_cycle = val >> div_m;
> + prescale_k = DIV_ROUND_DOWN_ULL(ent_cycle, 65537);
> + if (prescale_k > SUN20I_PWM_CTL_PRESCAL_K_MAX)
> + prescale_k = SUN20I_PWM_CTL_PRESCAL_K_MAX;
> +
> + do_div(ent_cycle, prescale_k + 1);
> +
> + /* for N cycles, PPRx.PWM_ENTIRE_CYCLE = (N-1) */
> + reg_period = FIELD_PREP(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, ent_cycle - 1);
> +
> + /* set duty cycle */
> + val = mul_u64_u64_div_u64(state->duty_cycle,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
> + act_cycle = val >> div_m;
> + do_div(act_cycle, prescale_k + 1);
I'm not sure about this code. I don't quite get where the 65537 comes from or
what's really happening here.
To my understanding you either want to limit PWM_ENTIRE_CYCLE to 0xFFFE so and
scale PWM_ACTIVE_CYCLE from 0 to 65535 so it can be 0x0 at 100% duty cycles and
0xFFFF at 0% duty cycles, OR you want to scale it from 0 to 65536 and check if
the value is 65536, and if it is wrap it around to 0 and flip the polarity.
Thanks,
John.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: John Watts <contact@jookia.org>
To: Aleksandr Shubin <privatesub2@gmail.com>
Cc: linux-kernel@vger.kernel.org,
"Brandon Cheo Fusi" <fusibrandon13@gmail.com>,
"Uwe Kleine-König" <ukleinek@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Chen-Yu Tsai" <wens@csie.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Philipp Zabel" <p.zabel@pengutronix.de>,
"Marc Kleine-Budde" <mkl@pengutronix.de>,
"Maksim Kiselev" <bigunclemax@gmail.com>,
linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-riscv@lists.infradead.org
Subject: Re: [PATCH v9 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
Date: Thu, 23 May 2024 13:16:47 +1000 [thread overview]
Message-ID: <Zk61H05-BTVUarFV@titan> (raw)
In-Reply-To: <20240520184227.120956-3-privatesub2@gmail.com>
Hi,
Here's a quick review based on the experience of me writing my own driver.
On Mon, May 20, 2024 at 09:42:20PM +0300, Aleksandr Shubin wrote:
> + act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> + ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> +
> + /*
> + * The duration of the active phase should not be longer
> + * than the duration of the period
> + */
> + if (act_cycle > ent_cycle)
> + act_cycle = ent_cycle;
> +
> + /*
> + * We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
> + * div_m <= 8. So the multiplication fits into an u64 without
> + * overflow.
> + */
> + tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> + tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> + state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);
Doesn't ent_cycle require a + 1 here?
Shouldn't act_cycle be > ent_cycle on 0% duty cycles?
> + /* if the neighbor channel is enable, check period only */
> + use_bus_clk = FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, clk_cfg) != 0;
> + val = mul_u64_u64_div_u64(state->period,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
It would be nice if it reclocked both channels.
> + /* calculate prescale_k, PWM entire cycle */
> + ent_cycle = val >> div_m;
> + prescale_k = DIV_ROUND_DOWN_ULL(ent_cycle, 65537);
> + if (prescale_k > SUN20I_PWM_CTL_PRESCAL_K_MAX)
> + prescale_k = SUN20I_PWM_CTL_PRESCAL_K_MAX;
> +
> + do_div(ent_cycle, prescale_k + 1);
> +
> + /* for N cycles, PPRx.PWM_ENTIRE_CYCLE = (N-1) */
> + reg_period = FIELD_PREP(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, ent_cycle - 1);
> +
> + /* set duty cycle */
> + val = mul_u64_u64_div_u64(state->duty_cycle,
> + (use_bus_clk ? bus_rate : hosc_rate),
> + NSEC_PER_SEC);
> + act_cycle = val >> div_m;
> + do_div(act_cycle, prescale_k + 1);
I'm not sure about this code. I don't quite get where the 65537 comes from or
what's really happening here.
To my understanding you either want to limit PWM_ENTIRE_CYCLE to 0xFFFE so and
scale PWM_ACTIVE_CYCLE from 0 to 65535 so it can be 0x0 at 100% duty cycles and
0xFFFF at 0% duty cycles, OR you want to scale it from 0 to 65536 and check if
the value is 65536, and if it is wrap it around to 0 and flip the polarity.
Thanks,
John.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-05-23 3:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-20 18:42 [PATCH v9 0/3] Add support for Allwinner PWM on D1/T113s/R329 SoCs Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` [PATCH v9 1/3] dt-bindings: pwm: Add binding for Allwinner D1/T113-S3/R329 PWM controller Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` [PATCH v9 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-23 3:16 ` John Watts [this message]
2024-05-23 3:16 ` John Watts
2024-05-23 3:16 ` John Watts
2024-07-08 14:46 ` Uwe Kleine-König
2024-07-08 14:46 ` Uwe Kleine-König
2024-05-20 18:42 ` [PATCH v9 3/3] riscv: dts: allwinner: d1: Add pwm node Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-05-20 18:42 ` Aleksandr Shubin
2024-10-08 15:10 ` [PATCH v9 0/3] Add support for Allwinner PWM on D1/T113s/R329 SoCs Chris Morgan
2024-10-08 15:10 ` Chris Morgan
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=Zk61H05-BTVUarFV@titan \
--to=contact@jookia.org \
--cc=aou@eecs.berkeley.edu \
--cc=bigunclemax@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fusibrandon13@gmail.com \
--cc=jernej.skrabec@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=mkl@pengutronix.de \
--cc=p.zabel@pengutronix.de \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=privatesub2@gmail.com \
--cc=robh@kernel.org \
--cc=samuel@sholland.org \
--cc=ukleinek@kernel.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.