Thread (14 messages) flat view 14 messages, 4 authors, 2021-06-10

Re: [PATCH 0/6] pwm: sun4i: only wait 2 cycles prior to disabling

From: Emil Lenngren <hidden>
Date: 2021-05-31 20:03:40
Also in: linux-pwm, linux-sunxi

Den mån 31 maj 2021 kl 21:07 skrev Pascal Roeleven [off-list ref]:
On 2021-05-31 06:46, Roman Beranek wrote:
quoted
As Emil Lenngren has previously shown [1], actually only 1-2 cycles of
the prescaler-divided clock are necessary to pass before the PWM turns
off, not a full period.

To avoid having the PWM re-enabled from another thread while asleep,
ctrl_lock spinlock was converted to a mutex so that it can be released
only after the clock gate has finally been turned on.

[1] https://linux-sunxi.org/PWM_Controller_Register_Guide

Roman Beranek (6):
  pwm: sun4i: enable clk prior to getting its rate
  pwm: sun4i: disable EN bit prior to the delay
  pwm: sun4i: replace spinlock with a mutex
  pwm: sun4i: simplify calculation of the delay time
  pwm: sun4i: shorten the delay to 2 cycles
  pwm: sun4i: don't delay if the PWM is already off

 drivers/pwm/pwm-sun4i.c | 56 +++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 30 deletions(-)
Hi Roman,

Thanks for your attempt to fix this.

Unfortunately on my A10 device (Topwise A721), the controller still gets
stuck in an unrecoverable state after disabling and re-enabling the PWM
when it was already on (set in U-Boot), or when enabling it when it was
off. In this state, any changes to the period register (using devmem)
don't seem to have any effect. It seems to be stuck in the state it was
before disabling. The only thing which still works is enabling and
disabling.

I can't reproduce this behavior manually so I'm not sure what is causing
this.

Regarding the amount of cycles of sleep; Using a prescaler of 72000 the
PWM clock is 3 ms. Although timing tests using devmem seem unreliable
(too much overhead?), in U-Boot I need to 'sleep' for at least 7 ms
between the commands to make sure the output doesn't sometimes get stuck
in the enabled state. So in my case it seems to be at least 3 cycles. I
am not sure how reliable this method is. However even if I can get it
stuck in the enabled state using a shorter time, it doesn't cause the
behavior I mentioned before. I was always able to recover it manually.
Increasing the number of cycles to sleep therefore also doesn't solve my
problem. Until we can solve that I cannot confirm nor deny if 2 cycles
is enough.

Regards,
Pascal
You could look at the devmem source code, and in C write a script that
writes to pwm register to disable the pwm, insert a usleep, then
disable the gating. This can be done for various sleep values, then
retrying with same sleep value multiple times. Assuming the overhead
is low (you can check the overhead by checking the current timestamp
at the beginning and at the end of the program, take the diff and then
subtract the sleep time), you will get one range where it never works,
one range where it works sometimes, and one range where it always
works. The uncertain range's condition for succeeding will depend on
when in the cycle you run the code.
Assuming we believe 3 cycles are enough on A10 and prescaler is 72000,
the thresholds for these ranges are 0-6 ms, 6-9 ms and 9+ ms.

About "being stuck", I'm not sure exactly what you mean but it's
expected that writes to the period register won't be visible (if you
read it after a write) when the clock gating is disabled. Three full
cycles (with the gating is on) must take place before the change is
visible (i.e. need to wait four cycles to be sure). At least on >=A13.
I documented that here:
https://linux-sunxi.org/PWM_Controller_Register_Guide.

/Emil

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help