linux/drivers/pwm
Thomas Hebb 4de445cb43 pwm: berlin: Don't use broken prescaler values
The Berlin PWM driver is currently broken on at least BG2CD. The
symptoms manifest as a very non-linear and erratic mapping from the duty
cycle configured in software to the duty cycle produced by hardware.

The cause of the bug is software's configuration of the prescaler, and
in particular its usage of the six prescaler values between the minimum
value of 1 and the maximum value of 4096. As it turns out, these six
values do not actually slow down the PWM clock; rather, they emulate
slowing down the clock by internally multiplying the value of TCNT.

This would be a fine trick, if not for the fact that the internal,
scaled TCNT value has no extra bits beyond the 16 already exposed to
software in the register. What this means is that, for a prescaler of 4,
the software must ensure that the top two bits of TCNT are not set,
because hardware will chop them off; for a prescaler of 8, the top three
bits must not be set, and so forth. Software does not currently ensure
this, resulting in a TCNT several orders of magnitude lower than
intended any time one of those six prescalers are selected.

Because hardware chops off the high bits in its internal shift, the
middle six prescalers don't actually allow *anything* that the first
doesn't. In fact, they are strictly worse than the first, since the
internal shift of TCNT prevents software from setting the low bits,
decreasing the resolution, without providing any extra high bits.

By skipping the useless prescalers entirely, this patch both fixes the
driver's behavior and increases its performance (since, when the 4096
prescaler is selected, it now does only a single shift rather than the
seven successive divisions it did before).

Tested on BG2CD.

Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2018-07-09 18:57:03 +02:00
..
core.c pwm: Silently error out on EPROBE_DEFER 2017-07-06 08:29:16 +02:00
Kconfig pwm: stm32: Enforce dependency on CONFIG_MFD_STM32_TIMERS 2018-06-06 10:04:00 +02:00
Makefile pwm: remove pwm-bfin driver 2018-03-26 15:57:08 +02:00
pwm-ab8500.c pwm: drop owner assignment from platform_drivers 2014-10-20 16:21:28 +02:00
pwm-atmel-hlcdc.c pwm: atmel-hlcdc: Implement the suspend/resume hooks 2017-04-06 17:45:02 +02:00
pwm-atmel-tcb.c pwm: simplify getting .drvdata 2018-04-30 10:40:57 +02:00
pwm-atmel.c pwm: atmel: Enable PWM on sama5d2 2017-04-06 17:45:03 +02:00
pwm-bcm2835.c pwm: bcm2835: Support for polarity setting via DT 2017-08-21 07:27:58 +02:00
pwm-bcm-iproc.c pwm: Add support for Broadcom iProc PWM controller 2016-07-11 12:49:25 +02:00
pwm-bcm-kona.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-berlin.c pwm: berlin: Don't use broken prescaler values 2018-07-09 18:57:03 +02:00
pwm-brcmstb.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-clps711x.c pwm: clps711x: Changing the compatibility string to match with the smallest supported chip 2016-07-06 17:38:17 +02:00
pwm-crc.c pwm: Use pwm_get/set_xxx() helpers where appropriate 2016-05-17 14:44:59 +02:00
pwm-cros-ec.c pwm: cros-ec: Fix transposed param settings 2017-07-06 17:16:37 +02:00
pwm-ep93xx.c pwm: Add the pwm_is_enabled() helper 2015-07-20 09:46:06 +02:00
pwm-fsl-ftm.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-hibvt.c pwm: hibvt: Explicitly request exclusive reset control 2017-08-21 08:52:40 +02:00
pwm-img.c pwm: img: Add runtime PM 2017-11-15 10:38:37 +01:00
pwm-imx.c pwm: imx: Let PWM be active during suspend 2018-03-28 00:17:36 +02:00
pwm-jz4740.c pwm: jz4740: Add support for devicetree 2018-03-28 00:23:56 +02:00
pwm-lp3943.c treewide: devm_kzalloc() -> devm_kcalloc() 2018-06-12 16:19:22 -07:00
pwm-lpc18xx-sct.c pwm: lpc-18xx: use pwm_set_chip_data 2016-09-08 10:55:05 +02:00
pwm-lpc32xx.c pwm: lpc32xx: Set PWM_PIN_LEVEL bit to default value 2016-07-11 12:49:29 +02:00
pwm-lpss-pci.c pwm: lpss: Set enable-bit before waiting for update-bit to go low 2017-04-06 14:48:14 +02:00
pwm-lpss-platform.c pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume 2018-06-06 10:00:39 +02:00
pwm-lpss.c pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume 2018-06-06 10:00:39 +02:00
pwm-lpss.h pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume 2018-06-06 10:00:39 +02:00
pwm-mediatek.c pwm: mediatek: Improve precision in rate calculation 2018-03-28 00:32:25 +02:00
pwm-meson.c pwm: meson: Fix allocation of PWM channel array 2018-04-30 10:32:30 +02:00
pwm-mtk-disp.c pwm: Add MediaTek MT2701 display PWM driver support 2016-09-06 10:48:53 +02:00
pwm-mxs.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-omap-dmtimer.c pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops 2018-02-22 10:54:24 -08:00
pwm-pca9685.c pwm: pca9685: clarify pca9685_set_sleep_mode() interface. 2017-07-25 13:41:59 +02:00
pwm-puv3.c pwm: puv3: Delete an error message for a failed memory allocation 2018-03-27 23:27:05 +02:00
pwm-pxa.c pwm: constify pwm_ops structures 2017-01-19 00:38:17 +01:00
pwm-rcar.c pwm: simplify getting .drvdata 2018-04-30 10:40:57 +02:00
pwm-renesas-tpu.c pwm: renesas-tpu: Remove support for SH7372 2017-08-18 17:27:14 +02:00
pwm-rockchip.c pwm: rockchip: Add rk3328 support 2017-08-18 17:44:34 +02:00
pwm-samsung.c pwm: pwm-samsung: fix suspend/resume support 2017-08-21 10:39:12 +02:00
pwm-spear.c pwm: drop owner assignment from platform_drivers 2014-10-20 16:21:28 +02:00
pwm-sti.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-stm32-lp.c pwm: stm32: LPTimer: Use 3 cells ->of_xlate() 2018-03-28 00:54:56 +02:00
pwm-stm32.c pwm: Changes for v4.18-rc1 2018-06-14 16:25:43 +09:00
pwm-stmpe.c pwm: stmpe: Fix wrong register offset for hwpwm=2 case 2017-12-05 09:33:05 +01:00
pwm-sun4i.c pwm: sun4i: Simplify controller mapping 2018-03-28 01:12:12 +02:00
pwm-tegra.c pwm: tegra: Explicitly request exclusive reset control 2017-08-21 08:53:07 +02:00
pwm-tiecap.c pwm: tiecap: Set driver data before runtime PM enable 2017-08-21 08:31:37 +02:00
pwm-tiehrpwm.c pwm: tiehrpwm: Set driver data before runtime PM enable 2017-08-21 08:42:56 +02:00
pwm-tipwmss.c pwm: pwm-tipwmss: Remove all runtime PM gets/puts 2016-09-06 10:48:54 +02:00
pwm-twl-led.c mfd: twl: Move header file out of I2C realm 2017-09-04 14:41:02 +01:00
pwm-twl.c mfd: twl: Move header file out of I2C realm 2017-09-04 14:41:02 +01:00
pwm-vt8500.c pwm: vt8500: Undo preparation of a clock source. 2017-07-25 13:43:28 +02:00
pwm-zx.c pwm: Add ZTE ZX PWM device driver 2017-08-21 08:11:24 +02:00
sysfs.c pwm: sysfs: Use put_device() instead of kfree() 2018-03-28 01:18:53 +02:00