After going through the math and constraints checking to compute load
and match values, it is helpful to know what the resultant period and
duty cycle are.
Signed-off-by: David Rivshin <drivshin@allworx.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
When converting period and duty_cycle from nanoseconds to fclk cycles,
the error introduced by the integer division can be appreciable, especially
in the case of slow fclk or short period. Use DIV_ROUND_CLOSEST_ULL() so
that the error is kept to +/- 0.5 clock cycles.
Fixes: 6604c6556d ("pwm: Add PWM driver for OMAP using dual-mode timers")
Signed-off-by: David Rivshin <drivshin@allworx.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Add sanity checking to ensure that we do not program load or match values
that are out of range if a user requests period or duty_cycle values which
are not achievable. The match value cannot be less than the load value (but
can be equal), and neither can be 0xffffffff. This means that there must be
at least one fclk cycle between load and match, and another between match
and overflow.
Fixes: 6604c6556d ("pwm: Add PWM driver for OMAP using dual-mode timers")
Signed-off-by: David Rivshin <drivshin@allworx.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
[thierry.reding@gmail.com: minor coding style cleanups]
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Fix the calculation of load_value and match_value. Currently they
are slightly too low, which produces a noticeably wrong PWM rate with
sufficiently short periods (i.e. when 1/period approaches clk_rate/2).
Example:
clk_rate=32768Hz, period=122070ns, duty_cycle=61035ns (8192Hz/50% PWM)
Correct values: load = 0xfffffffc, match = 0xfffffffd
Current values: load = 0xfffffffa, match = 0xfffffffc
effective PWM: period=183105ns, duty_cycle=91553ns (5461Hz/50% PWM)
Fixes: 6604c6556d ("pwm: Add PWM driver for OMAP using dual-mode timers")
Signed-off-by: David Rivshin <drivshin@allworx.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Adam Ford <aford173@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The change fixes potential oops while accessing iomem on invalid address
if devm_ioremap_resource() fails due to some reason.
The devm_ioremap_resource() function returns ERR_PTR() and never returns
NULL, which makes useless a following check for NULL.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Fixes: 3a9f595702 ("pwm: Add Broadcom BCM7038 PWM controller support")
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
This is part of an ongoing process to migrate from ARCH_SHMOBILE to
ARCH_RENESAS the motivation for which being that RENESAS seems to be a
more appropriate name than SHMOBILE for the majority of Renesas ARM
based SoCs.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Commit d1cd214277 ("pwm: Set enable state properly on failed call to
enable") introduced a mutex that is needed to protect internal state of
PWM devices. Since that mutex is acquired in pwm_set_polarity() and in
pwm_enable() and might potentially block, all PWM devices effectively
become "might sleep".
It's rather pointless to keep the .can_sleep field around, but given
that there are external users let's postpone the removal for the next
release cycle.
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Adds support for using a OMAP dual-mode timer with PWM capability
as a Linux PWM device. The driver controls the timer by using the
dmtimer API.
Add a platform_data structure for each pwm-omap-dmtimer nodes containing
the dmtimers functions in order to get driver not rely on platform
specific functions.
Cc: Grant Erickson <marathon96@gmail.com>
Cc: NeilBrown <neilb@suse.de>
Cc: Joachim Eastwood <manabian@gmail.com>
Suggested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Tony Lindgren <tony@atomide.com>
[thierry.reding@gmail.com: coding style bikeshed, fix timer leak]
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Instead of silent acceptance of unsupported requested configuration
for PWM period and setting the boundary supported value, return
-ERANGE to a caller.
Duty period value equal to 0 or period is still accepted to allow
configuration by PWM sysfs interface, when it is set to 0 by default.
For reference this is a list of restrictions on period_ns == 1/freq:
| PWM parent clock | parent clock divisor | max freq | min freq |
+------------------+----------------------+----------+----------+
| HCLK == 13 MHz | 1 (min) | 50.7 KHz | 198.3 Hz |
| HCLK == 13 MHz | 15 (max) | 3.38 KHz | 13.22 Hz |
| RTC == 32.7 KHz | 1 (min) | 128 Hz | 0.5 Hz |
| RTC == 32.7 KHz | 15 (max) | 8.533 Hz | 0.033 Hz |
Note that PWM sysfs interface does not support setting of period more
than NSEC_PER_SEC / MAX_INT32 ~ 2 seconds, however this PWM controller
supports a period up to 30 seconds.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The change fixes a problem, if duty_ns is too small in comparison
to period_ns (as a valid corner case duty_ns is 0 ns), then due to
PWM_DUTY() macro applied on a value the result is overflowed over 8
bits, and instead of the highest bitfield duty cycle value 0xff the
invalid duty cycle bitfield value 0x00 is written.
For reference the LPC32xx spec defines PWMx_DUTY bitfield description
is this way and it seems to be correct:
[Low]/[High] = [PWM_DUTY]/[256-PWM_DUTY], where 0 < PWM_DUTY <= 255.
In addition according to my oscilloscope measurements LPC32xx PWM is
"tristate" in sense that it produces a wave with floating min/max
voltage levels for different duty cycle values, for corner cases:
PWM_DUTY == 0x01 => signal is in range from -1.05v to 0v
....
PWM_DUTY == 0x80 => signal is in range from -0.75v to +0.75v
....
PWM_DUTY == 0xff => signal is in range from 0v to +1.05v
PWM_DUTY == 0x00 => signal is around 0v, PWM is off
Due to this peculiarity on very long period ranges (less than 1KHz)
and odd pre-divider values PWM generated wave does not remind a
clock shape signal, but rather a heartbit shape signal with positive
and negative peaks, so I would recommend to use high-speed HCLK clock
as a PWM parent clock and avoid using RTC clock as a parent.
The change corrects PWM output in corner cases and prevents any
possible overflows in calculation of values for PWM_DUTY and
PWM_RELOADV bitfields, thus helper macro definitions may be removed.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
As a preparatory change for switching LPC32xx mach support to common
clock framework fix clk_enable/clk_disable calls without matching
clk_prepare/clk_unprepare.
The driver can not be used on a platform with common clock framework
until clk_prepare/clk_unprepare calls are added, otherwise clk_enable
calls will fail and a WARN is generated:
# echo 1 > /sys/bus/platform/drivers/lpc32xx-pwm/4005c000.pwm/pwm/pwmchip0/pwm0/enable
------------[ cut here ]------------
WARNING: CPU: 0 PID: 701 at drivers/clk/clk.c:727 clk_core_enable+0x2c/0xa4()
Modules linked in: sc16is7xx
CPU: 0 PID: 701 Comm: sh Tainted: G W 4.3.0-rc2+ #171
Hardware name: LPC32XX SoC (Flattened Device Tree)
Backtrace:
[<>] (dump_backtrace) from [<>] (show_stack+0x18/0x1c)
[<>] (show_stack) from [<>] (dump_stack+0x20/0x28)
[<>] (dump_stack) from [<>] (warn_slowpath_common+0x90/0xb8)
[<>] (warn_slowpath_common) from [<>] (warn_slowpath_null+0x24/0x2c)
[<>] (warn_slowpath_null) from [<>] (clk_core_enable+0x2c/0xa4)
[<>] (clk_core_enable) from [<>] (clk_enable+0x24/0x38)
[<>] (clk_enable) from [<>] (lpc32xx_pwm_enable+0x1c/0x40)
[<>] (lpc32xx_pwm_enable) from [<>] (pwm_enable+0x48/0x5c)
[<>] (pwm_enable) from [<>] (pwm_enable_store+0x5c/0x78)
[<>] (pwm_enable_store) from [<>] (dev_attr_store+0x20/0x2c)
[<>] (dev_attr_store) from [<>] (sysfs_kf_write+0x44/0x50)
[<>] (sysfs_kf_write) from [<>] (kernfs_fop_write+0x134/0x194)
[<>] (kernfs_fop_write) from [<>] (__vfs_write+0x34/0xdc)
[<>] (__vfs_write) from [<>] (vfs_write+0xb8/0x140)
[<>] (vfs_write) from [<>] (SyS_write+0x50/0x90)
[<>] (SyS_write) from [<>] (ret_fast_syscall+0x0/0x38)
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
LPC32xx SoC has two independent PWM controllers, they have different
clock parents, clock gates and even slightly different controls, and
each of these two PWM controllers has one output channel. Due to
almost similar controls arranged in a row it is incorrectly set that
there is one PWM controller with two channels, fix this problem, which
at the moment prevents separate configuration of different clock
parents and gates for both PWM controllers.
The change makes previous PWM device node description incompatible
with this update.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
A FTM PWM instance enables/disables three clocks: The bus clock, the
counter clock and the PWM clock. The bus clock gets enabled on
pwm_request, whereas the counter and PWM clocks will be enabled upon
pwm_enable.
The driver has three closesly related issues when enabling/disabling
clocks during suspend/resume:
- The three clocks are not treated differently in regards to the
individual PWM state enabled/requested. This can lead to clocks
getting disabled which have not been enabled in the first place
(a PWM channel which only has been requested going through
suspend/resume).
- When entering suspend, the current behavior relies on the
FTM_OUTMASK register: If a PWM output is unmasked, the driver
assumes the clocks are enabled. However, some PWM instances
have only 2 channels connected (e.g. Vybrid's FTM1). In that case,
the FTM_OUTMASK reads 0x3 if all channels are disabled, even if
the code wrote 0xff to it before. For those PWM instances, the
current approach to detect enabled PWM signals does not work.
- A third issue applies to the bus clock only, which can get enabled
multiple times (once for each PWM channel of a PWM chip). This is
fine, however when entering suspend mode, the clock only gets
disabled once.
This change introduces a different approach by relying on the enable
and prepared counters of the clock framework and using the frameworks
PWM signal states to address all three issues.
Clocks get disabled during suspend and back enabled on resume
regarding to the PWM channels individual state (requested/enabled).
Since we do not count the clock enables in the driver, this change no
longer clears the Status and Control registers Clock Source Selection
(FTM_SC[CLKS]). However, since we disable the selected clock anyway,
and we explicitly select the clock source on reenabling a PWM channel
this approach should not make a difference in practice.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Setting of PWM_SW_UPDATE is bit different in Intel Broxton compared to the
previous generation SoCs. Previously it was OK to set the bit many times
(from userspace via sysfs for example) before the PWM is actually enabled.
Starting from Intel Broxton it seems that we must set PWM_SW_UPDATE only
once before the PWM is enabled. Otherwise it is possible that the PWM does
not start properly.
Change the sequence of how PWM_SW_UPDATE is programmed so that we only set
it in pwm_lpss_config() when the PWM is already enabled. The initial
setting of PWM_SW_UPDATE will be done when PWM gets enabled. This should
make the driver work with the previous generation Intel SoCs and Broxton.
Add also small delay after the bit is set to let the hardware propagate it
properly.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
For Broxton PWM controller, base unit is defined as 8-bit integer
and 14-bit fraction, so need to update base unit setting to output
wave with right frequency.
Signed-off-by: Qipeng Zha <qipeng.zha@intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
It's possible that the PWM clock becomes an orphan. So better check the
result of clk_get_rate() in order to prevent a division by zero.
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Currently pwm-bcm2835 assumes a fixed clock rate and stores the
resulting scaler in the driver structure. But with the upcoming
PWM clock support for clk-bcm2835 the rate could change, so
calculate the scaler in the ->config() callback.
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The LPSS PWM driver calls pwm_lpss_disable() when the PWM device is
released (for example unexported from sysfs). This in turn calls
pm_runtime_put() which makes runtime PM count to be unbalanced if the
device has not been enabled at this point.
This is easy to reproduce:
# cd /sys/class/pwm/pwmchip0
# echo 0 > export
# echo 0 > unexport
The count is unbalanced and prevents the PWM device from being powered on
next time.
Fix this by removing ->free() callback. There are no resources to be
released anyway.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>