mbox series

[0/2] pwm: meson: fixes

Message ID 20241225105639.1787237-1-gnstark@salutedevices.com (mailing list archive)
Headers show
Series pwm: meson: fixes | expand

Message

George Stark Dec. 25, 2024, 10:56 a.m. UTC
The 1st patch from the series is only intended to drop several unneeded code lines
along with outdated comment. It's too simple to be sent alone.

The 2nd patch adjusts pwm frequency calculation. The patch depends on
not-yet-accepted series:
https://lore.kernel.org/linux-arm-kernel/20241119125318.3492261-1-gnstark@salutedevices.com/T/

Below I researched several cases this patch will affect.
One of the most frequent use of meson pwm in mainline dts files are:
1) wifi clock source and 2) cpu power regulation.

1) wifi clock source with period 32768Hz and 50% dutycycle is configured in DTS like this:
    pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
Here is the calculated and measured frequency output with and without the patch on
several boads/SoCs, where
${CLK_RATE} - pwm clock source
${COUNT_REG} - meson pwm regster with hi and lo values (e.g. PWMEF_PWM_E reg)

*** khadas vim1 ***
${CLK_RATE} -> 166666667
w/o the patch:
${COUNT_REG} -> 0x09EF09EF
oscilloscope measure: 32.7564Khz
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32756.8134827 Hz
with the patch:
${COUNT_REG} -> 0x09EE09EE
oscilloscope measure: 32.7693Khz
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32769.694652 Hz

*** khadas vim3 ***
${CLK_RATE} -> 666666656
w/o patch:
${COUNT_REG} -> 0x27BC27BD
oscilloscope measure: 32.7652Khz
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32764.8624367 Hz
with the patch:
${COUNT_REG} -> 0x27BB27BC
oscilloscope measure: 32.7684Khz
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32768.083362 Hz

*** meson a1 board ***
${CLK_RATE} -> 64000000
w/o patch:
${COUNT_REG} -> 0x03D003D1
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32736.57289 Hz
with the patch:
${COUNT_REG} -> 0x03CF03D0
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 32770.0972862 Hz

2) pwm power regulator. Power is regulated changing duty value with the constant period
*** meson a1 board ***
required: period 1500ns (667kHz), duty 70% for 0.8V
${CLK_RATE} -> 307200000
with the patch:
${COUNT_REG} -> 0x01410089
calculated period: ${CLK_RATE} / (${COUNT_REG}.lo + ${COUNT_REG}.hi + 2) = 667826.086957 Hz
calculated duty: (${COUNT_REG}.hi + 1) / (${COUNT_REG}.hi + ${COUNT_REG}.lo + 2) = 0.7
oscilloscope measure: 667.8Khz, 1498ns/1049ns, duty 70%
w/o the patch:
${COUNT_REG} -> 0x0142008A
calculated duty: (${COUNT_REG}.hi + 1) / (${COUNT_REG}.hi + ${COUNT_REG}.lo + 2) = 0.69
oscilloscope measure: 664.9Khz, 1504ns/1051ns, duty 69%

*******************
**** ATTENTION ****
*******************
There's a potential problem related to meson_pwm_get_state's change.
When pwm-regulator is initialized before the kernel is loaded and incomplete
voltage-table is used (meson a1 board vendor kernel)

voltage table fragment from kernel dts:
  compatible = "pwm-regulator";
  voltage-table =
  ...
  <800000 70>,
  <790000 73>,
  <780000 76>,
  ...

pwm regulator is initialized in bootloader bl2/bl3.x
${CLK_RATE} -> 24000000
${COUNT_REG} -> 0x00190009
oscilloscope measure: 666.67Khz, 1500ns/1083ns, duty 72%

pwm_get_state w/o the patch returns:
pwm period: (${COUNT_REG}.hi + ${COUNT_REG}.lo) / ${CLK_RATE} = 1416 ns
pwm duty: ${COUNT_REG}.hi / ${CLK_RATE} = 1041 ns
duty: 1041 / 1416 = 73%
Value 73% is found in the voltage table and everything is ok

pwm_get_state with the patch returns:
pwm period: (${COUNT_REG}.hi + ${COUNT_REG}.lo + 2) / ${CLK_RATE} = 1500 ns
pwm duty: (${COUNT_REG}.hi + 1) / ${CLK_RATE} = 1083 ns
duty: 1083 / 1500 = 72%

72% is not found in the voltage table.
In that case pwm-regulator driver on its own sets the minimum voltage from the table.
If this is the cpu power regulator then cpu may hang due to voltage is lowered
w/o prior proper frequency lowering. In that situation voltage-table should be
adjusted to have intermediate values.

Just before sending the letter I've found the only mainline board that may be
broken by this patch:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
I can patch meson-s4-s805x2-aq222.dts' voltage table or propose patch to pwm-regulator
to change the way pwm-regulator deals with out-of-table pwm values.

George Stark (2):
  pwm: meson: Simplify meson_pwm_cnt_to_ns()
  pwm: meson: Fix computing counter register

 drivers/pwm/pwm-meson.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

--
2.25.1