linux/drivers/pwm
Clark Wang 0d9cee68a3 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-09 10:31:54 +01:00
..
core.c pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() 2024-06-12 11:12:24 +02:00
Kconfig mfd: rz-mtu3: Link time dependencies 2023-08-18 21:48:04 +01:00
Makefile pwm: Add Renesas RZ/G2L MTU3a PWM driver 2023-06-23 15:46:29 +02:00
pwm-ab8500.c pwm: ab8500: Fix error code in probe() 2023-06-23 15:43:49 +02:00
pwm-apple.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-atmel-hlcdc.c pwm: atmel-hlcdc: Fix clock imbalance related to suspend support 2024-03-26 18:19:26 -04:00
pwm-atmel-tcb.c pwm: atmel-tcb: Fix race condition and convert to guards 2024-08-03 08:53:23 +02:00
pwm-atmel.c pwm: atmel: Simplify using devm functions 2023-07-28 10:15:44 +02:00
pwm-bcm-iproc.c pwm: bcm-iproc: Convert to platform remove callback returning void 2023-03-30 16:26:24 +02:00
pwm-bcm-kona.c pwm: bcm-kona: Consistently name pwm_chip variables "chip" 2023-07-21 20:23:31 +02:00
pwm-bcm2835.c pwm: bcm2835: Convert to platform remove callback returning void 2023-03-30 16:26:25 +02:00
pwm-berlin.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-brcmstb.c pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume 2023-11-20 11:59:34 +01:00
pwm-clk.c pwm: clk: Use the devm_clk_get_prepared() helper function 2023-06-23 15:34:33 +02:00
pwm-clps711x.c pwm: clps71xx: Implement .apply() callback 2022-04-22 18:52:30 +02:00
pwm-crc.c pwm: crc: Consistently name pwm_chip variables "chip" 2023-07-21 20:23:31 +02:00
pwm-cros-ec.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-dwc.c pwm: dwc: Use devm_pwmchip_add() 2023-02-20 12:26:35 +01:00
pwm-ep93xx.c pwm: ep93xx: Simplify using devm_pwmchip_add() 2021-09-02 21:38:41 +02:00
pwm-fsl-ftm.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-hibvt.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-img.c pwm: img: fix pwm clock lookup 2024-04-03 15:28:52 +02:00
pwm-imx-tpm.c pwm: imx-tpm: Use correct MODULO value for EPWM mode 2024-11-14 13:19:35 +01:00
pwm-imx1.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-imx27.c pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle 2024-12-09 10:31:54 +01:00
pwm-intel-lgm.c pwm: Make .get_state() callback return an error code 2022-12-06 12:46:22 +01:00
pwm-iqs620a.c pwm: iqs620a: Explicitly set .polarity in .get_state() 2023-03-23 14:44:41 +01:00
pwm-jz4740.c pwm: jz4740: Don't use dev_err_probe() in .request() 2024-01-25 15:35:46 -08:00
pwm-keembay.c pwm: Make .get_state() callback return an error code 2022-12-06 12:46:22 +01:00
pwm-lp3943.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-lpc18xx-sct.c pwm: lpc18xx-sct: Simplify using devm_clk_get_enabled() 2023-07-28 09:38:04 +02:00
pwm-lpc32xx.c pwm: lpc32xx: Remove handling of PWM channels 2023-08-22 10:14:16 +02:00
pwm-lpss-pci.c pwm: lpss: Rename pwm_lpss_probe() --> devm_pwm_lpss_probe() 2022-11-22 16:36:27 +02:00
pwm-lpss-platform.c pwm: lpss-platform: Convert to platform remove callback returning void 2023-03-30 16:26:32 +02:00
pwm-lpss.c pwm: Changes for v6.2-rc1 2022-12-21 09:41:28 -08:00
pwm-lpss.h pwm: lpss: Allow other drivers to enable PWM LPSS 2022-11-22 16:36:27 +02:00
pwm-mediatek.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-meson.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-microchip-core.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-mtk-disp.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +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: Use device_set_of_node_from_dev() 2023-07-28 09:39:02 +02:00
pwm-omap-dmtimer.c pwm: omap-dmtimer: Convert to platform remove callback returning void 2023-03-30 16:26:33 +02:00
pwm-pca9685.c pwm: pca9685: Switch i2c driver back to use .probe() 2023-06-23 15:44:00 +02:00
pwm-pxa.c pwm: pxa: Don't reimplement of_device_get_match_data() 2023-07-28 09:38:18 +02:00
pwm-raspberrypi-poe.c pwm: Make .get_state() callback return an error code 2022-12-06 12:46:22 +01:00
pwm-rcar.c pwm: rcar: Drop of_match_ptr for ID table 2023-04-06 15:41:24 +02: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: rockchip: Consistently name pwm_chip variables "chip" 2023-07-21 20:23:31 +02:00
pwm-rz-mtu3.c pwm: rz-mtu3: Fix build warning 'num_channel_ios' not described 2023-07-28 09:24:43 +02:00
pwm-samsung.c pwm: samsung: Convert to platform remove callback returning void 2023-03-30 16:26:34 +02:00
pwm-sifive.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-sl28cpld.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-spear.c pwm: spear: Convert to platform remove callback returning void 2023-03-30 16:26:35 +02:00
pwm-sprd.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-sti.c pwm: sti: Simplify probe function using devm functions 2024-06-12 11:11:46 +02:00
pwm-stm32-lp.c pwm: stm32-lp: Drop of_match_ptr for ID table 2023-04-06 15:42:22 +02:00
pwm-stm32.c pwm: stm32: Always do lazy disabling 2024-08-03 08:53:22 +02:00
pwm-stmpe.c pwm: stmpe: Handle errors when disabling the signal 2023-07-28 09:49:18 +02:00
pwm-sun4i.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-sunplus.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-tegra.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-tiecap.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-tiehrpwm.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-twl-led.c pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() 2024-06-12 11:12:24 +02:00
pwm-twl.c pwm: twl: Implement .apply() callback 2021-11-17 17:12:42 +01:00
pwm-visconti.c pwm: Explicitly include correct DT includes 2023-07-24 13:28:05 +02:00
pwm-vt8500.c pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() 2024-06-12 11:12:24 +02:00
pwm-xilinx.c pwm: xilinx: Convert to platform remove callback returning void 2023-03-30 16:26:40 +02:00
sysfs.c pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() 2024-06-12 11:12:24 +02:00