summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-tegra.c
AgeCommit message (Collapse)AuthorFilesLines
2022-05-20pwm: tegra: Implement .apply() callbackUwe Kleine-König1-3/+27
To eventually get rid of all legacy drivers convert this driver to the modern world implementing .apply(). This just pushed a variant of pwm_apply_legacy() into the driver that was slightly simplified because the driver doesn't provide a .set_polarity() callback. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2022-05-20pwm: tegra: Optimize period calculationUwe Kleine-König1-5/+5
Dividing by the result of a division looses precision because the result is rounded twice. E.g. with clk_rate = 48000000 and period = 32760033 the following numbers result: rate = pc->clk_rate >> PWM_DUTY_WIDTH = 187500 hz = DIV_ROUND_CLOSEST_ULL(100ULL * NSEC_PER_SEC, period_ns) = 3052 rate = DIV_ROUND_CLOSEST_ULL(100ULL * rate, hz) = 6144 The exact result would be 6142.5061875 and (apart from rounding) this is found by using a single division. As a side effect is also a tad cheaper to calculate. Also using clk_rate >> PWM_DUTY_WIDTH looses precision. Consider for example clk_rate = 47999999 and period = 106667: mul_u64_u64_div_u64(pc->clk_rate >> PWM_DUTY_WIDTH, period_ns, NSEC_PER_SEC) = 19 mul_u64_u64_div_u64(pc->clk_rate, period_ns, NSEC_PER_SEC << PWM_DUTY_WIDTH) = 20 (The exact result is 20.000062083332033.) With this optimizations also switch from round-closest to round-down for the period calculation. Given that the calculations were non-optimal for quite some time now with variations in both directions which nobody reported as a problem, this is the opportunity to align the driver's behavior to the requirements of new drivers. This has several upsides: - Implementation is easier as there are no round-nearest variants of mul_u64_u64_div_u64(). - Requests for too small periods are now consistently refused. This was kind of arbitrary before, where period_ns < min_period_ns was refused, but in some cases min_period_ns isn't actually implementable and then values between min_period_ns and the actual minimum were rounded up to the actual minimum. Note that the duty_cycle calculation isn't using the usual round-down approach yet. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2022-02-02pwm: tegra: Rename variable pointing to driver private dataUwe Kleine-König1-30/+29
Status quo is that variables of type struct tegra_pwm_chip * are named "pwm", "chip" or "pc". The two formers are all not optimal because usually only struct pwm_device * variables are named "pwm" and "chip" is usually used for variabled of type struct pwm_chip *. So consistently use the same and non-conflicting name "pc". Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-12-16pwm: tegra: Add runtime PM and OPP supportDmitry Osipenko1-18/+64
The PWM on Tegra belongs to the core power domain and we're going to enable GENPD support for the core domain. Now PWM must be resumed using runtime PM API in order to initialize the PWM power state. The PWM clock rate must be changed using OPP API that will reconfigure the power domain performance state in accordance to the rate. Add runtime PM and OPP support to the PWM driver. Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
2021-06-30pwm: tegra: Assert reset only after the PWM was unregisteredUwe Kleine-König1-1/+3
The driver is supposed to stay functional until pwmchip_remove() returns. So the reset must be asserted only after that. pwmchip_remove() always returns 0, so the return code can be ignored which keeps the tegra_pwm_remove() a bit simpler. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-06-30pwm: tegra: Don't needlessly enable and disable the clock in .remove()Uwe Kleine-König1-6/+0
There is no reason to enable the PWM clock just to assert the reset control. (If the reset control depends on the clock this is a bug and probably it doesn't because in .probe() the reset is deasserted without the clock being enabled.) Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-06-30pwm: tegra: Don't modify HW state in .remove callbackUwe Kleine-König1-13/+0
A consumer is expected to disable a PWM before calling pwm_put(). And if they didn't there is hopefully a good reason (or the consumer needs fixing). Also if disabling an enabled PWM was the right thing to do, this should better be done in the framework instead of in each low level driver. So drop the hardware modification from the .remove() callback. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-06-30pwm: tegra: Drop an if block with an always false conditionUwe Kleine-König1-3/+0
tegra_pwm_remove() is only called after tegra_pwm_probe() successfully completed. In this case platform_set_drvdata() was called with a non-NULL value and so platform_get_drvdata(pdev) cannot return NULL. Returning an error code from a platform_driver's remove function is ignored anyway, so it's a good thing this exit path is gone. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-03-22pwm: Always allocate PWM chip base ID dynamicallyUwe Kleine-König1-1/+0
Since commit 5e5da1e9fbee ("pwm: ab8500: Explicitly allocate pwm chip base dynamically") all drivers use dynamic ID allocation explicitly. New drivers are supposed to do the same, so remove support for driver specified base IDs and drop all assignments in the low-level drivers. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-12-17pwm: tegra: Convert to devm_platform_ioremap_resource()Yangtao Li1-3/+1
Use devm_platform_ioremap_resource() to simplify code. Signed-off-by: Yangtao Li <tiny.windzz@gmail.com> Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-06-02pwm: tegra: Support dynamic clock frequency configurationSandipan Patra1-4/+76
Added support for dynamic clock freq configuration in PWM kernel driver. Earlier the PWM driver used to cache boot time clock rate by PWM clock parent during probe. Hence dynamically changing PWM frequency was not possible for all the possible ranges. With this change, dynamic calculation is enabled and it is able to set the requested period from sysfs knob provided the value is supported by clock source. Changes mainly have 2 parts: - Tegra186 and later chips [1] - Tegra210 and prior chips [2] For [1] - Changes implemented to set pwm period dynamically and also checks added to allow only if requested period(ns) is below or equals to higher range. For [2] - Only checks if the requested period(ns) is below or equals to higher range defined by max clock limit. The limitation in Tegra210 or prior chips are due to the reason of having only one PWM controller supporting multiple channels. But later chips have multiple PWM controller instances each having single channel support. Signed-off-by: Sandipan Patra <spatra@nvidia.com> Reviewed-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-03-30pwm: tegra: Add support for Tegra194Sandipan Patra1-0/+6
Tegra194 has multiple PWM controllers with each having only one output. Also the maxmimum frequency is higher than earlier SoCs. Add support for Tegra194 and specify the number of PWM outputs and maximum supported frequency using device tree match data. Signed-off-by: Sandipan Patra <spatra@nvidia.com> Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2019-05-21treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 1Thomas Gleixner1-14/+1
Based on 2 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not write to the free software foundation inc 51 franklin street fifth floor boston ma 02110 1301 usa this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option [no]_[pad]_[ctrl] any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not write to the free software foundation inc 51 franklin street fifth floor boston ma 02110 1301 usa extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 176 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Jilayne Lovejoy <opensource@jilayne.com> Reviewed-by: Steve Winslow <swinslow@gmail.com> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190519154040.652910950@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-09-26pwm: tegra: Remove gratuituous blank lineThierry Reding1-1/+0
It's common to follow a device tree ID table by the MODULE_DEVICE_TABLE immediately, without an extra blank line between. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-21pwm: tegra: Explicitly request exclusive reset controlPhilipp Zabel1-1/+1
Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Jonathan Hunter <jonathanh@nvidia.com> Cc: linux-pwm@vger.kernel.org Cc: linux-tegra@vger.kernel.org Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-06-13pwm: tegra: Set maximum pwm clock source per SoC tapeoutLaxman Dewangan1-1/+17
The PWM hardware IP is taped-out with different maximum frequency on different SoCs. From HW team: Before Tegra186, it is 48 MHz. In Tegra186, it is 102 MHz. Add support to limit the clock source frequency to the maximum IP supported frequency. Provide these values via SoC chipdata. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-13pwm: tegra: Read PWM clock source rate in driver initLaxman Dewangan1-1/+6
It is required to know the PWM clock source frequency to calculate the PWM period. In driver, the clock source frequency of the PWM does not get change and, hence, get the clock source frequency in driver init. Get this values later for period calculation from pwm_config(). This will help in avoiding the clock call for getting clock rate in the pwm_config() each time. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-13pwm: tegra: Avoid potential overflow for short periodsThierry Reding1-6/+4
For very short periods, the result of the division might overflow the unsigned long hz variable (on 32-bit architectures). Avoid that by making it an unsigned long long. While at it, also remove an unneeded local variable whose only purpose is to store a temporary computation. Acked-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-12pwm: tegra: Add support to configure pin state in suspends/resumeLaxman Dewangan1-0/+18
In some of NVIDIA Tegra's platform, PWM controller is used to control the PWM controlled regulators. PWM signal is connected to the VID pin of the regulator where duty cycle of PWM signal decide the voltage level of the regulator output. When system enters suspend, some PWM client/slave regulator devices require the PWM output to be tristated. Add support to configure the pin state via pinctrl frameworks in suspend and active state of the system. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-12pwm: tegra: Increase precision in PWM rate calculationLaxman Dewangan1-2/+5
The rate of the PWM calculated as follows: hz = NSEC_PER_SEC / period_ns; rate = (rate + (hz / 2)) / hz; This has the precision loss in lower PWM rate. Change this to have more precision as: hz = DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC * 100, period_ns); rate = DIV_ROUND_CLOSEST(rate * 100, hz) Example: 1. period_ns = 16672000, PWM clock rate is 200 KHz. Based on old formula hz = NSEC_PER_SEC / period_ns = 1000000000ul/16672000 = 59 (59.98) rate = (200K + 59/2)/59 = 3390 Based on new method: hz = 5998 rate = DIV_ROUND_CLOSE(200000*100, 5998) = 3334 If we measure the PWM signal rate, we will get more accurate period with rate value of 3334 instead of 3390. 2. period_ns = 16803898, PWM clock rate is 200 KHz. Based on old formula: hz = 59, rate = 3390 Based on new formula: hz = 5951, rate = 3360 The PWM signal rate of 3360 is more near to requested period than 3333. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-12pwm: tegra: Use DIV_ROUND_CLOSEST_ULL() instead of local implementationLaxman Dewangan1-2/+1
Use macro DIV_ROUND_CLOSEST_ULL() for 64-bit division to closest one instead of implementing the same locally. This increase readability. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Add support for Tegra186Laxman Dewangan1-3/+19
Tegra186 has multiple PWM controllers with only one output instead of one controller with four outputs in earlier SoC generations. Add support for Tegra186 and detect the number of PWM outputs using device tree match data. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Avoid overflow when calculating duty cycleHyong Bin Kim1-2/+3
duty_ns * (1 << PWM_DUTY_WIDTH) could overflow in integer calculation when the PWM rate is low. Hence do all calculation on unsigned long long to avoid overflow. Signed-off-by: Hyong Bin Kim <hyongbink@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Allow 100 % duty cycleVictor(Weiguo) Pan1-1/+1
To get 100 % duty cycle (always high), pulse width needs to be set to 256. Signed-off-by: Victor(Weiguo) Pan <wpan@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Add support for reset controlRohith Seelaboyina1-0/+20
Add reset control of the PWM controller to reset it before accessing the PWM register. Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Rename mmio_base to regsThierry Reding1-6/+6
The former is much longer to type and is ambiguous because the value stored in the field is not the (physical) base address of the memory- mapped I/O registers, but the virtual address of those registers as mapped through the MMU. Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Remove useless paddingThierry Reding1-4/+4
Use single spaces to separate data type from field names in structure definitions. Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11pwm: tegra: Drop NUM_PWM macroThierry Reding1-5/+3
This macro is used to initialize the ->npwm field of the PWM chip. Use a literal instead and make all other places rely on ->npwm. Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2015-07-20pwm: Add the pwm_is_enabled() helperBoris Brezillon1-3/+3
Some PWM drivers are testing the PWMF_ENABLED flag. Create a helper function to hide the logic behind enabled test. This will allow us to smoothly move from the current approach to an atomic PWM update approach. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2015-02-18pwm: tegra: Use NSEC_PER_SECThierry Reding1-1/+1
Instead of using the literal value for the number of nanoseconds per second, use the macro instead to increase readability. Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2014-10-20pwm: drop owner assignment from platform_driversWolfram Sang1-1/+0
A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2014-04-28pwm: tegra: Remove unnecessary OOM messagesJingoo Han1-3/+1
The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han <jg1.han@samsung.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2013-06-12pwm: Fill in missing .owner fieldsThierry Reding1-0/+1
Some drivers don't set the .owner fields of the struct device_driver or struct pwm_ops, which causes the module usage count to become wrong. Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2013-05-18drivers/pwm: don't check resource with devm_ioremap_resourceWolfram Sang1-5/+0
devm_ioremap_resource does sanity checks on the given resource. No need to duplicate this in the driver. Signed-off-by: Wolfram Sang <wsa@the-dreams.de> Acked-by: Stephen Warren <swarren@nvidia.com>
2013-04-23pwm: Constify OF match tablesThierry Reding1-1/+1
A few drivers already annotate this properly. Make the same change for all other OF supporting drivers. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
2013-02-26Merge tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwmLinus Torvalds1-3/+1
Pull PWM changes from Thierry Reding: "A new driver has been added to support the PWM mode of the timer counter blocks found on Atmel AT91 SoCs. The VT8500 driver now supports changing the PWM signal polarity and the TI drivers (EHRPWM and ECAP) gained suspend and resume functionality. User drivers can now query the core for whether access to a PWM device will sleep (if the PWM chip is on a slow bus such as I2C or SPI). The pwm-backlight driver now handles the backlight BL_CORE_FBBLANK state in addition to the FB layer's blanking states. To round things off, a few fixes and cleanups are also included" * tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwm: pwm: twl: Use to_twl() instead of container_of() pwm: tegra: assume CONFIG_OF pwm_backlight: Validate dft_brightness in main probe function pwm: Export pwm_{set,get}_chip_data() pwm: Make Kconfig entries more consistent pwm: Add can_sleep property to drivers pwm: Add pwm_can_sleep() as exported API to users pwm-backlight: handle BL_CORE_FBBLANK state pwm: pwm-tiecap: Low power sleep support pwm: pwm-tiehrpwm: Low power sleep support pwm: pwm-tiehrpwm: Update the clock handling of pwm-tiehrpwm driver pwm: vt8500: Add polarity support pwm: vt8500: Register write busy test performed incorrectly pwm: atmel: add Timer Counter Block PWM driver
2013-02-15pwm: tegra: assume CONFIG_OFStephen Warren1-3/+1
Tegra only supports, and always enables, device tree. Remove all ifdefs for DT support from the driver. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
2013-01-22pwm: Convert to devm_ioremap_resource()Thierry Reding1-3/+3
Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-28pwm: remove use of __devexitBill Pemberton1-1/+1
CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Acked-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-28pwm: remove use of __devexit_pBill Pemberton1-1/+1
CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Acked-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-17pwm: Remove a redundant error message when devm_request_and_ioremap failsAxel Lin1-3/+1
The implementation in devm_request_and_ioremap() already shows error message, so no need to show dev_err again if devm_request_and_ioremap() fails. Signed-off-by: Axel Lin <axel.lin@gmail.com> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Philip, Avinash <avinashphilip@ti.com> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
2012-07-23pwm: Convert pwm-tegra to use devm_clk_get()Axel Lin1-6/+2
Also return proper error in tegra_pwm_remove() if pwmchip_remove() fails. Signed-off-by: Axel Lin <axel.lin@gmail.com> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
2012-07-02pwm: tegra: Add device tree supportThierry Reding1-0/+11
Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation. Acked-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
2012-07-02pwm: Add NVIDIA Tegra SoC supportThierry Reding1-0/+254
This commit adds a generic PWM framework driver for the PWFM controller found on NVIDIA Tegra SoCs. The driver is based on code from the Chromium kernel tree and was originally written by Gary King (NVIDIA) and later modified by Simon Que (Chromium). Acked-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>