linux/drivers/pwm
Clark Wang 1649f1224b pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle
[ Upstream commit a25351e4c7 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2024-12-14 19:53:22 +01:00
..
core.c pwm: Fix out-of-bounds access in of_pwm_single_xlate() 2024-01-25 15:27:42 -08:00
Kconfig pwm: Add clock based PWM output driver 2022-07-29 13:41:18 +02:00
Makefile pwm: Add clock based PWM output driver 2022-07-29 13:41:18 +02:00
pwm-ab8500.c pwm: ab8500: Fix error code in probe() 2023-07-19 16:21:59 +02:00
pwm-atmel-hlcdc.c pwm: atmel-hlcdc: Fix clock imbalance related to suspend support 2024-03-26 18:20:33 -04:00
pwm-atmel-tcb.c pwm: atmel-tcb: Fix race condition and convert to guards 2024-08-03 08:48:55 +02:00
pwm-atmel.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-bcm-iproc.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-bcm-kona.c treewide: Replace GPLv2 boilerplate/reference with SPDX - gpl-2.0_30.RULE (part 2) 2022-06-10 14:51:35 +02:00
pwm-bcm2835.c pwm: Simplify all drivers with explicit of_pwm_n_cells = 3 2021-05-25 18:19:15 +02:00
pwm-berlin.c pwm: berlin: Ensure configuring period and duty_cycle isn't wrongly skipped 2021-07-08 16:09:17 +02:00
pwm-brcmstb.c pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume 2023-11-20 11:52:15 +01:00
pwm-clk.c pwm: Add clock based PWM output driver 2022-07-29 13:41:18 +02:00
pwm-clps711x.c pwm: clps71xx: Implement .apply() callback 2022-04-22 18:52:30 +02:00
pwm-crc.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-cros-ec.c pwm: cros-ec: Explicitly set .polarity in .get_state() 2023-04-13 16:55:18 +02:00
pwm-dwc.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-ep93xx.c pwm: ep93xx: Simplify using devm_pwmchip_add() 2021-09-02 21:38:41 +02:00
pwm-fsl-ftm.c pwm: fsl-ftm: Simplify using devm_pwmchip_add() 2021-09-02 21:38:41 +02:00
pwm-hibvt.c pwm: hibvt: Explicitly set .polarity in .get_state() 2023-04-13 16:55:18 +02:00
pwm-img.c pwm: img: fix pwm clock lookup 2024-04-03 15:19:45 +02:00
pwm-imx-tpm.c pwm: imx-tpm: Use correct MODULO value for EPWM mode 2024-11-14 13:15:14 +01:00
pwm-imx1.c pwm: imx1: Implement .apply callback 2022-02-02 17:05:19 +01:00
pwm-imx27.c pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle 2024-12-14 19:53:22 +01:00
pwm-intel-lgm.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-iqs620a.c pwm: iqs620a: Explicitly set .polarity in .get_state() 2023-04-13 16:55:19 +02:00
pwm-jz4740.c pwm: jz4740: Don't use dev_err_probe() in .request() 2024-01-25 15:27:42 -08:00
pwm-keembay.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-lp3943.c pwm: lp3943: Implement .apply() callback 2022-04-22 18:43:09 +02:00
pwm-lpc18xx-sct.c pwm: lpc18xx: Fix period handling 2022-07-29 13:41:18 +02:00
pwm-lpc32xx.c pwm: lpc32xx: Remove handling of PWM channels 2023-09-19 12:28:00 +02:00
pwm-lpss-pci.c pwm: lpss: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros 2022-09-28 16:18:57 +02:00
pwm-lpss-platform.c pwm: lpss: Use device_get_match_data() to get device data 2022-09-28 16:18:11 +02:00
pwm-lpss.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-lpss.h pwm: lpss: Add a comment to the bypass field 2022-09-28 16:21:46 +02:00
pwm-mediatek.c pwm: mediatek: always use bus clock for PWM on MT7622 2022-12-31 13:32:51 +01:00
pwm-meson.c pwm: meson: fix handling of period/duty if greater than UINT_MAX 2023-07-23 13:49:46 +02:00
pwm-mtk-disp.c pwm: mtk_disp: Fix the disable flow of disp_pwm 2023-07-19 16:21:59 +02:00
pwm-mxs.c pwm: mxs: Simplify using devm_pwmchip_add() 2021-09-02 21:38:45 +02:00
pwm-ntxec.c pwm: ntxec: Simplify using devm_pwmchip_add() 2021-09-02 21:38:46 +02:00
pwm-omap-dmtimer.c pwm: omap-dmtimer: Don't check the return code of pwmchip_remove() 2021-09-02 21:38:52 +02:00
pwm-pca9685.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-pxa.c pwm: pxa: Implement .apply() callback 2022-02-02 18:03:05 +01:00
pwm-raspberrypi-poe.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-rcar.c pwm: rcar: Simplify multiplication/shift logic 2022-02-24 15:14:56 +01:00
pwm-renesas-tpu.c pwm: renesas-tpu: Improve precision of period and duty_cycle calculation 2022-05-20 16:18:40 +02:00
pwm-rockchip.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-samsung.c pwm: samsung: Implement .apply() callback 2022-05-20 15:59:34 +02:00
pwm-sifive.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-sl28cpld.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-spear.c pwm: spear: Ensure configuring period and duty_cycle isn't wrongly skipped 2021-07-08 16:08:38 +02:00
pwm-sprd.c pwm: sprd: Explicitly set .polarity in .get_state() 2023-04-13 16:55:19 +02:00
pwm-sti.c pwm: sti: Simplify probe function using devm functions 2024-06-12 11:03:14 +02:00
pwm-stm32-lp.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-stm32.c pwm: stm32: Always do lazy disabling 2024-08-03 08:48:55 +02:00
pwm-stmpe.c pwm: stmpe: Implement .apply() callback 2022-05-20 16:28:35 +02:00
pwm-sun4i.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-sunplus.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-tegra.c pwm: tegra: Fix 32 bit build 2022-12-31 13:33:12 +01:00
pwm-tiecap.c pwm: tiecap: Simplify using devm_pwmchip_add() 2021-09-02 21:38:48 +02:00
pwm-tiehrpwm.c pwm: tiehrpwm: Implement .apply() callback 2022-02-24 13:52:59 +01:00
pwm-twl-led.c pwm: twl-led: Document some limitations and link to the reference manual 2022-07-29 13:41:18 +02:00
pwm-twl.c pwm: twl: Implement .apply() callback 2021-11-17 17:12:42 +01:00
pwm-visconti.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
pwm-vt8500.c pwm: vt8500: Rename variable pointing to driver private data 2022-02-24 14:35:20 +01:00
pwm-xilinx.c pwm: Make .get_state() callback return an error code 2023-04-13 16:55:18 +02:00
sysfs.c pwm: sysfs: Do not apply state to already disabled PWMs 2023-07-19 16:21:59 +02:00