linux/drivers/pwm
Clark Wang a25351e4c7 pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle
Implement workaround for ERR051198
(https://www.nxp.com/docs/en/errata/IMX8MN_0N14Y.pdf)

PWM output may not function correctly if the FIFO is empty when a new SAR
value is programmed.

Description:
  When the PWM FIFO is empty, a new value programmed to the PWM Sample
  register (PWM_PWMSAR) will be directly applied even if the current timer
  period has not expired. If the new SAMPLE value programmed in the
  PWM_PWMSAR register is less than the previous value, and the PWM counter
  register (PWM_PWMCNR) that contains the current COUNT value is greater
  than the new programmed SAMPLE value, the current period will not flip
  the level. This may result in an output pulse with a duty cycle of 100%.

Workaround:
  Program the current SAMPLE value in the PWM_PWMSAR register before
  updating the new duty cycle to the SAMPLE value in the PWM_PWMSAR
  register. This will ensure that the new SAMPLE value is modified during
  a non-empty FIFO, and can be successfully updated after the period
  expires.

Write the old SAR value before updating the new duty cycle to SAR. This
avoids writing the new value into an empty FIFO.

This only resolves the issue when the PWM period is longer than 2us
(or <500kHz) because write register is not quick enough when PWM period is
very short.

Reproduce steps:
  cd /sys/class/pwm/pwmchip1/pwm0
  echo 2000000000 > period     # It is easy to observe by using long period
  echo 1000000000 > duty_cycle
  echo 1 > enable
  echo       8000 > duty_cycle # One full high pulse will be seen by scope

Fixes: 166091b189 ("[ARM] MXC: add pwm driver for i.MX SoCs")
Reviewed-by: Jun Li <jun.li@nxp.com>
Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20241008194123.1943141-1-Frank.Li@nxp.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
2024-10-25 11:42:36 +02:00
..
core.c pwm: Reorder symbols in core.c 2024-09-28 15:13:56 +02:00
Kconfig pwm: adp5585: Add Analog Devices ADP5585 support 2024-08-01 14:09:28 +01:00
Makefile pwm: adp5585: Add Analog Devices ADP5585 support 2024-08-01 14:09:28 +01:00
pwm-ab8500.c pwm: ab8500: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:19 +01:00
pwm-adp5585.c pwm: adp5585: Set OSC_EN bit to 1 when PWM state is enabled 2024-09-16 15:24:58 +02:00
pwm-apple.c pwm: apple: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:19 +01:00
pwm-atmel-hlcdc.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-atmel-tcb.c pwm: atmel-tcb: Use min() macro 2024-10-25 11:33:34 +02:00
pwm-atmel.c pwm: atmel: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:19 +01:00
pwm-axi-pwmgen.c pwm: axi-pwmgen: Enable FORCE_ALIGN by default 2024-10-25 11:42:36 +02:00
pwm-bcm2835.c pwm: bcm2835: Drop open coded variant of devm_clk_rate_exclusive_get() 2024-04-30 18:57:08 +02:00
pwm-bcm-iproc.c pwm: bcm-iproc: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:20 +01:00
pwm-bcm-kona.c pwm: bcm-kona: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:20 +01:00
pwm-berlin.c pwm: berlin: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:20 +01:00
pwm-brcmstb.c pwm: brcmstb: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:20 +01:00
pwm-clk.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-clps711x.c pwm: clps711x: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:21 +01:00
pwm-crc.c pwm: crc: Make use of devm_pwmchip_alloc() function 2024-02-15 12:59:21 +01:00
pwm-cros-ec.c pwm: cros-ec: Simplify device tree xlation 2024-07-10 17:52:47 +02:00
pwm-dwc-core.c pwm: dwc: allow suspend/resume for 16 channels 2024-04-15 17:28:13 +02:00
pwm-dwc.c pwm: dwc: allow suspend/resume for 16 channels 2024-04-15 17:28:13 +02:00
pwm-dwc.h pwm: dwc: allow suspend/resume for 16 channels 2024-04-15 17:28:13 +02:00
pwm-ep93xx.c pwm: ep93xx: drop legacy pinctrl 2024-09-12 14:33:11 +00:00
pwm-fsl-ftm.c pwm: fsl-ftm: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:09 +01:00
pwm-gpio.c pwm: Add GPIO PWM driver 2024-07-10 17:52:47 +02:00
pwm-hibvt.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-img.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-imx1.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-imx27.c pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle 2024-10-25 11:42:36 +02:00
pwm-imx-tpm.c pwm: imx-tpm: Use correct MODULO value for EPWM mode 2024-10-25 11:29:17 +02:00
pwm-intel-lgm.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-iqs620a.c pwm: iqs620a: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:10 +01:00
pwm-jz4740.c pwm: jz4740: Another few conversions to regmap_{set,clear}_bits() 2024-07-10 17:52:46 +02:00
pwm-keembay.c pwm: keembay: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:10 +01:00
pwm-lp3943.c pwm: lp3943: Fix an incorrect type in lp3943_pwm_parse_dt() 2024-09-16 15:23:36 +02:00
pwm-lpc18xx-sct.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-lpc32xx.c pwm: lpc32xx: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:11 +01:00
pwm-lpss-pci.c pwm: lpss: drop redundant runtime PM handles 2024-07-10 17:53:51 +02:00
pwm-lpss-platform.c pwm: lpss: use devm_pm_runtime_enable() helper 2024-07-10 17:53:51 +02:00
pwm-lpss.c pwm: lpss-*: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:11 +01:00
pwm-lpss.h pwm: lpss-*: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:11 +01:00
pwm-mediatek.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-meson.c pwm: meson: Add support for Amlogic S4 PWM 2024-07-10 17:52:47 +02:00
pwm-microchip-core.c pwm: microchip-core: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:12 +01:00
pwm-mtk-disp.c pwm: mtk-disp: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:12 +01:00
pwm-mxs.c pwm: mxs: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:12 +01:00
pwm-ntxec.c pwm: ntxec: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:12 +01:00
pwm-omap-dmtimer.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-pca9685.c pwm: pca9685: Drop explicit initialization of struct i2c_device_id::driver_data to 0 2024-05-10 07:30:27 +02:00
pwm-pxa.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-raspberrypi-poe.c pwm: raspberrypi-poe: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:13 +01:00
pwm-rcar.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-renesas-tpu.c pwm: renesas-tpu: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:13 +01:00
pwm-rockchip.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-rz-mtu3.c pwm: rz-mtu3: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:14 +01:00
pwm-samsung.c of: remove internal arguments from of_property_for_each_u32() 2024-07-25 06:53:47 -05:00
pwm-sifive.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-sl28cpld.c pwm: sl28cpld: Make use of devm_pwmchip_alloc() function 2024-02-19 11:04:15 +01:00
pwm-spear.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-sprd.c pwm: sprd: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:10 +01:00
pwm-sti.c pwm: sti: Prefer local variable over pointer dereference 2024-04-26 21:29:17 +02:00
pwm-stm32-lp.c pwm: stm32-lp: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:25 +01:00
pwm-stm32.c pwm: stm32: Fix error checking for a regmap_read() call 2024-10-04 19:03:12 +02:00
pwm-stmpe.c pwm: stmpe: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:25 +01:00
pwm-sun4i.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-sunplus.c pwm: sunplus: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:25 +01:00
pwm-tegra.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-tiecap.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-tiehrpwm.c pwm: Switch back to struct platform_driver::remove() 2024-09-16 15:24:59 +02:00
pwm-twl-led.c pwm: twl-led: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:27 +01:00
pwm-twl.c pwm: twl: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:27 +01:00
pwm-visconti.c pwm: add missing MODULE_DESCRIPTION() macros 2024-07-10 17:52:46 +02:00
pwm-vt8500.c pwm: vt8500: Make use of devm_pwmchip_alloc() function 2024-02-22 14:39:27 +01:00
pwm-xilinx.c pwm: xilinx: Simplify using devm_ functions 2024-07-10 17:53:52 +02:00