2019-05-19 16:51:31 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-12-21 10:47:07 +04:00
/*
* drivers / pwm / pwm - tegra . c
*
* Tegra pulse - width - modulation controller driver
*
2020-06-01 08:20:36 +03:00
* Copyright ( c ) 2010 - 2020 , NVIDIA Corporation .
2011-12-21 10:47:07 +04:00
* Based on arch / arm / plat - mxc / pwm . c by Sascha Hauer < s . hauer @ pengutronix . de >
2020-06-01 08:20:36 +03:00
*
* Overview of Tegra Pulse Width Modulator Register :
* 1. 13 - bit : Frequency division ( SCALE )
* 2. 8 - bit : Pulse division ( DUTY )
* 3. 1 - bit : Enable bit
*
* The PWM clock frequency is divided by 256 before subdividing it based
* on the programmable frequency division value to generate the required
* frequency for PWM output . The maximum output frequency that can be
* achieved is ( max rate of source clock ) / 256.
* e . g . if source clock rate is 408 MHz , maximum output frequency can be :
* 408 MHz / 256 = 1.6 MHz .
* This 1.6 MHz frequency can further be divided using SCALE value in PWM .
*
* PWM pulse width : 8 bits are usable [ 23 : 16 ] for varying pulse width .
* To achieve 100 % duty cycle , program Bit [ 24 ] of this register to
* 1 ’ b1 . In which case the other bits [ 23 : 16 ] are set to don ' t care .
*
* Limitations :
* - When PWM is disabled , the output is driven to inactive .
* - It does not allow the current PWM period to complete and
* stops abruptly .
*
* - If the register is reconfigured while PWM is running ,
* it does not complete the currently running period .
*
* - If the user input duty is beyond acceptible limits ,
* - EINVAL is returned .
2011-12-21 10:47:07 +04:00
*/
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/io.h>
# include <linux/module.h>
# include <linux/of.h>
2016-06-22 14:47:23 +03:00
# include <linux/of_device.h>
2021-12-01 02:23:28 +03:00
# include <linux/pm_opp.h>
2011-12-21 10:47:07 +04:00
# include <linux/pwm.h>
# include <linux/platform_device.h>
2017-04-07 12:34:02 +03:00
# include <linux/pinctrl/consumer.h>
2021-12-01 02:23:28 +03:00
# include <linux/pm_runtime.h>
2011-12-21 10:47:07 +04:00
# include <linux/slab.h>
2016-06-22 14:47:19 +03:00
# include <linux/reset.h>
2011-12-21 10:47:07 +04:00
2021-12-01 02:23:28 +03:00
# include <soc/tegra/common.h>
2011-12-21 10:47:07 +04:00
# define PWM_ENABLE (1 << 31)
# define PWM_DUTY_WIDTH 8
# define PWM_DUTY_SHIFT 16
# define PWM_SCALE_WIDTH 13
# define PWM_SCALE_SHIFT 0
2016-06-22 14:47:23 +03:00
struct tegra_pwm_soc {
unsigned int num_channels ;
2017-05-02 17:05:37 +03:00
/* Maximum IP frequency for given SoCs */
unsigned long max_frequency ;
2016-06-22 14:47:23 +03:00
} ;
2011-12-21 10:47:07 +04:00
struct tegra_pwm_chip {
2016-07-11 12:26:52 +03:00
struct pwm_chip chip ;
struct device * dev ;
2011-12-21 10:47:07 +04:00
2016-07-11 12:26:52 +03:00
struct clk * clk ;
2016-06-22 14:47:19 +03:00
struct reset_control * rst ;
2011-12-21 10:47:07 +04:00
2017-04-13 17:10:27 +03:00
unsigned long clk_rate ;
2020-06-01 08:20:36 +03:00
unsigned long min_period_ns ;
2017-04-13 17:10:27 +03:00
2016-07-11 12:27:29 +03:00
void __iomem * regs ;
2016-06-22 14:47:23 +03:00
const struct tegra_pwm_soc * soc ;
2011-12-21 10:47:07 +04:00
} ;
static inline struct tegra_pwm_chip * to_tegra_pwm_chip ( struct pwm_chip * chip )
{
return container_of ( chip , struct tegra_pwm_chip , chip ) ;
}
2021-11-23 12:29:36 +03:00
static inline u32 pwm_readl ( struct tegra_pwm_chip * pc , unsigned int offset )
2011-12-21 10:47:07 +04:00
{
2021-11-23 12:29:36 +03:00
return readl ( pc - > regs + ( offset < < 4 ) ) ;
2011-12-21 10:47:07 +04:00
}
2021-11-23 12:29:36 +03:00
static inline void pwm_writel ( struct tegra_pwm_chip * pc , unsigned int offset , u32 value )
2011-12-21 10:47:07 +04:00
{
2021-11-23 12:29:36 +03:00
writel ( value , pc - > regs + ( offset < < 4 ) ) ;
2011-12-21 10:47:07 +04:00
}
static int tegra_pwm_config ( struct pwm_chip * chip , struct pwm_device * pwm ,
int duty_ns , int period_ns )
{
struct tegra_pwm_chip * pc = to_tegra_pwm_chip ( chip ) ;
2022-04-25 16:22:44 +03:00
unsigned long long c = duty_ns ;
2020-06-01 08:20:36 +03:00
unsigned long rate , required_clk_rate ;
2011-12-21 10:47:07 +04:00
u32 val = 0 ;
int err ;
/*
* Convert from duty_ns / period_ns to a fixed number of duty ticks
* per ( 1 < < PWM_DUTY_WIDTH ) cycles and make sure to round to the
* nearest integer during division .
*/
2016-06-22 14:47:21 +03:00
c * = ( 1 < < PWM_DUTY_WIDTH ) ;
2017-04-07 12:33:59 +03:00
c = DIV_ROUND_CLOSEST_ULL ( c , period_ns ) ;
2011-12-21 10:47:07 +04:00
val = ( u32 ) c < < PWM_DUTY_SHIFT ;
2020-06-01 08:20:36 +03:00
/*
* min period = max clock limit > > PWM_DUTY_WIDTH
*/
if ( period_ns < pc - > min_period_ns )
return - EINVAL ;
2011-12-21 10:47:07 +04:00
/*
* Compute the prescaler value for which ( 1 < < PWM_DUTY_WIDTH )
* cycles at the PWM clock rate will take period_ns nanoseconds .
2020-06-01 08:20:36 +03:00
*
* num_channels : If single instance of PWM controller has multiple
* channels ( e . g . Tegra210 or older ) then it is not possible to
* configure separate clock rates to each of the channels , in such
* case the value stored during probe will be referred .
*
* If every PWM controller instance has one channel respectively , i . e .
* nums_channels = = 1 then only the clock rate can be modified
* dynamically ( e . g . Tegra186 or Tegra194 ) .
2011-12-21 10:47:07 +04:00
*/
2020-06-01 08:20:36 +03:00
if ( pc - > soc - > num_channels = = 1 ) {
/*
* Rate is multiplied with 2 ^ PWM_DUTY_WIDTH so that it matches
* with the maximum possible rate that the controller can
* provide . Any further lower value can be derived by setting
* PFM bits [ 0 : 12 ] .
*
* required_clk_rate is a reference rate for source clock and
* it is derived based on user requested period . By setting the
* source clock rate as required_clk_rate , PWM controller will
* be able to configure the requested period .
*/
2022-11-10 14:45:48 +03:00
required_clk_rate = DIV_ROUND_UP_ULL ( ( u64 ) NSEC_PER_SEC < < PWM_DUTY_WIDTH ,
2022-10-28 15:33:55 +03:00
period_ns ) ;
2020-06-01 08:20:36 +03:00
2022-10-28 15:33:56 +03:00
if ( required_clk_rate > clk_round_rate ( pc - > clk , required_clk_rate ) )
/*
* required_clk_rate is a lower bound for the input
* rate ; for lower rates there is no value for PWM_SCALE
* that yields a period less than or equal to the
* requested period . Hence , for lower rates , double the
* required_clk_rate to get a clock rate that can meet
* the requested period .
*/
required_clk_rate * = 2 ;
2021-12-01 02:23:28 +03:00
err = dev_pm_opp_set_rate ( pc - > dev , required_clk_rate ) ;
2020-06-01 08:20:36 +03:00
if ( err < 0 )
return - EINVAL ;
/* Store the new rate for further references */
pc - > clk_rate = clk_get_rate ( pc - > clk ) ;
}
2017-04-07 12:34:00 +03:00
/* Consider precision in PWM_SCALE_WIDTH rate calculation */
2022-04-25 16:22:44 +03:00
rate = mul_u64_u64_div_u64 ( pc - > clk_rate , period_ns ,
( u64 ) NSEC_PER_SEC < < PWM_DUTY_WIDTH ) ;
2011-12-21 10:47:07 +04:00
/*
* Since the actual PWM divider is the register ' s frequency divider
2020-06-01 08:20:36 +03:00
* field plus 1 , we need to decrement to get the correct value to
2011-12-21 10:47:07 +04:00
* write to the register .
*/
if ( rate > 0 )
rate - - ;
2022-04-25 16:22:44 +03:00
else
return - EINVAL ;
2011-12-21 10:47:07 +04:00
/*
* Make sure that the rate will fit in the register ' s frequency
* divider field .
*/
if ( rate > > PWM_SCALE_WIDTH )
return - EINVAL ;
val | = rate < < PWM_SCALE_SHIFT ;
/*
* If the PWM channel is disabled , make sure to turn on the clock
* before writing the register . Otherwise , keep it enabled .
*/
2015-07-01 11:21:47 +03:00
if ( ! pwm_is_enabled ( pwm ) ) {
2021-12-01 02:23:28 +03:00
err = pm_runtime_resume_and_get ( pc - > dev ) ;
if ( err )
2011-12-21 10:47:07 +04:00
return err ;
} else
val | = PWM_ENABLE ;
pwm_writel ( pc , pwm - > hwpwm , val ) ;
/*
* If the PWM is not enabled , turn the clock off again to save power .
*/
2015-07-01 11:21:47 +03:00
if ( ! pwm_is_enabled ( pwm ) )
2021-12-01 02:23:28 +03:00
pm_runtime_put ( pc - > dev ) ;
2011-12-21 10:47:07 +04:00
return 0 ;
}
static int tegra_pwm_enable ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct tegra_pwm_chip * pc = to_tegra_pwm_chip ( chip ) ;
int rc = 0 ;
u32 val ;
2021-12-01 02:23:28 +03:00
rc = pm_runtime_resume_and_get ( pc - > dev ) ;
if ( rc )
2011-12-21 10:47:07 +04:00
return rc ;
val = pwm_readl ( pc , pwm - > hwpwm ) ;
val | = PWM_ENABLE ;
pwm_writel ( pc , pwm - > hwpwm , val ) ;
return 0 ;
}
static void tegra_pwm_disable ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct tegra_pwm_chip * pc = to_tegra_pwm_chip ( chip ) ;
u32 val ;
val = pwm_readl ( pc , pwm - > hwpwm ) ;
val & = ~ PWM_ENABLE ;
pwm_writel ( pc , pwm - > hwpwm , val ) ;
2021-12-01 02:23:28 +03:00
pm_runtime_put_sync ( pc - > dev ) ;
2011-12-21 10:47:07 +04:00
}
2022-05-06 19:48:06 +03:00
static int tegra_pwm_apply ( struct pwm_chip * chip , struct pwm_device * pwm ,
const struct pwm_state * state )
{
int err ;
bool enabled = pwm - > state . enabled ;
if ( state - > polarity ! = PWM_POLARITY_NORMAL )
return - EINVAL ;
if ( ! state - > enabled ) {
if ( enabled )
tegra_pwm_disable ( chip , pwm ) ;
return 0 ;
}
err = tegra_pwm_config ( pwm - > chip , pwm , state - > duty_cycle , state - > period ) ;
if ( err )
return err ;
if ( ! enabled )
err = tegra_pwm_enable ( chip , pwm ) ;
return err ;
}
2011-12-21 10:47:07 +04:00
static const struct pwm_ops tegra_pwm_ops = {
2022-05-06 19:48:06 +03:00
. apply = tegra_pwm_apply ,
2011-12-21 10:47:07 +04:00
. owner = THIS_MODULE ,
} ;
static int tegra_pwm_probe ( struct platform_device * pdev )
{
2021-11-23 12:29:36 +03:00
struct tegra_pwm_chip * pc ;
2011-12-21 10:47:07 +04:00
int ret ;
2021-11-23 12:29:36 +03:00
pc = devm_kzalloc ( & pdev - > dev , sizeof ( * pc ) , GFP_KERNEL ) ;
if ( ! pc )
2011-12-21 10:47:07 +04:00
return - ENOMEM ;
2021-11-23 12:29:36 +03:00
pc - > soc = of_device_get_match_data ( & pdev - > dev ) ;
pc - > dev = & pdev - > dev ;
2011-12-21 10:47:07 +04:00
2021-11-23 12:29:36 +03:00
pc - > regs = devm_platform_ioremap_resource ( pdev , 0 ) ;
if ( IS_ERR ( pc - > regs ) )
return PTR_ERR ( pc - > regs ) ;
2011-12-21 10:47:07 +04:00
2021-11-23 12:29:36 +03:00
platform_set_drvdata ( pdev , pc ) ;
2011-12-21 10:47:07 +04:00
2021-11-23 12:29:36 +03:00
pc - > clk = devm_clk_get ( & pdev - > dev , NULL ) ;
if ( IS_ERR ( pc - > clk ) )
return PTR_ERR ( pc - > clk ) ;
2011-12-21 10:47:07 +04:00
2021-12-01 02:23:28 +03:00
ret = devm_tegra_core_dev_init_opp_table_common ( & pdev - > dev ) ;
if ( ret )
return ret ;
pm_runtime_enable ( & pdev - > dev ) ;
ret = pm_runtime_resume_and_get ( & pdev - > dev ) ;
if ( ret )
return ret ;
2017-05-02 17:05:37 +03:00
/* Set maximum frequency of the IP */
2021-11-23 12:29:36 +03:00
ret = dev_pm_opp_set_rate ( pc - > dev , pc - > soc - > max_frequency ) ;
2017-05-02 17:05:37 +03:00
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Failed to set max frequency: %d \n " , ret ) ;
2021-12-01 02:23:28 +03:00
goto put_pm ;
2017-05-02 17:05:37 +03:00
}
/*
* The requested and configured frequency may differ due to
* clock register resolutions . Get the configured frequency
* so that PWM period can be calculated more accurately .
*/
2021-11-23 12:29:36 +03:00
pc - > clk_rate = clk_get_rate ( pc - > clk ) ;
2017-04-13 17:10:27 +03:00
2020-06-01 08:20:36 +03:00
/* Set minimum limit of PWM period for the IP */
2021-11-23 12:29:36 +03:00
pc - > min_period_ns =
( NSEC_PER_SEC / ( pc - > soc - > max_frequency > > PWM_DUTY_WIDTH ) ) + 1 ;
2020-06-01 08:20:36 +03:00
2021-11-23 12:29:36 +03:00
pc - > rst = devm_reset_control_get_exclusive ( & pdev - > dev , " pwm " ) ;
if ( IS_ERR ( pc - > rst ) ) {
ret = PTR_ERR ( pc - > rst ) ;
2016-06-22 14:47:19 +03:00
dev_err ( & pdev - > dev , " Reset control is not found: %d \n " , ret ) ;
2021-12-01 02:23:28 +03:00
goto put_pm ;
2016-06-22 14:47:19 +03:00
}
2021-11-23 12:29:36 +03:00
reset_control_deassert ( pc - > rst ) ;
2016-06-22 14:47:19 +03:00
2021-11-23 12:29:36 +03:00
pc - > chip . dev = & pdev - > dev ;
pc - > chip . ops = & tegra_pwm_ops ;
pc - > chip . npwm = pc - > soc - > num_channels ;
2011-12-21 10:47:07 +04:00
2021-11-23 12:29:36 +03:00
ret = pwmchip_add ( & pc - > chip ) ;
2011-12-21 10:47:07 +04:00
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " pwmchip_add() failed: %d \n " , ret ) ;
2021-11-23 12:29:36 +03:00
reset_control_assert ( pc - > rst ) ;
2021-12-01 02:23:28 +03:00
goto put_pm ;
2011-12-21 10:47:07 +04:00
}
2021-12-01 02:23:28 +03:00
pm_runtime_put ( & pdev - > dev ) ;
2011-12-21 10:47:07 +04:00
return 0 ;
2021-12-01 02:23:28 +03:00
put_pm :
pm_runtime_put_sync_suspend ( & pdev - > dev ) ;
pm_runtime_force_suspend ( & pdev - > dev ) ;
return ret ;
2011-12-21 10:47:07 +04:00
}
2023-03-03 21:54:41 +03:00
static void tegra_pwm_remove ( struct platform_device * pdev )
2011-12-21 10:47:07 +04:00
{
struct tegra_pwm_chip * pc = platform_get_drvdata ( pdev ) ;
2016-06-22 14:47:19 +03:00
2021-06-17 12:51:43 +03:00
pwmchip_remove ( & pc - > chip ) ;
2016-06-22 14:47:19 +03:00
reset_control_assert ( pc - > rst ) ;
2021-12-01 02:23:28 +03:00
pm_runtime_force_suspend ( & pdev - > dev ) ;
2011-12-21 10:47:07 +04:00
}
2021-12-01 02:23:28 +03:00
static int __maybe_unused tegra_pwm_runtime_suspend ( struct device * dev )
2017-04-07 12:34:02 +03:00
{
2021-12-01 02:23:28 +03:00
struct tegra_pwm_chip * pc = dev_get_drvdata ( dev ) ;
int err ;
clk_disable_unprepare ( pc - > clk ) ;
err = pinctrl_pm_select_sleep_state ( dev ) ;
if ( err ) {
clk_prepare_enable ( pc - > clk ) ;
return err ;
}
return 0 ;
2017-04-07 12:34:02 +03:00
}
2021-12-01 02:23:28 +03:00
static int __maybe_unused tegra_pwm_runtime_resume ( struct device * dev )
2017-04-07 12:34:02 +03:00
{
2021-12-01 02:23:28 +03:00
struct tegra_pwm_chip * pc = dev_get_drvdata ( dev ) ;
int err ;
err = pinctrl_pm_select_default_state ( dev ) ;
if ( err )
return err ;
err = clk_prepare_enable ( pc - > clk ) ;
if ( err ) {
pinctrl_pm_select_sleep_state ( dev ) ;
return err ;
}
return 0 ;
2017-04-07 12:34:02 +03:00
}
2016-06-22 14:47:23 +03:00
static const struct tegra_pwm_soc tegra20_pwm_soc = {
. num_channels = 4 ,
2017-05-02 17:05:37 +03:00
. max_frequency = 48000000UL ,
2016-06-22 14:47:23 +03:00
} ;
static const struct tegra_pwm_soc tegra186_pwm_soc = {
. num_channels = 1 ,
2017-05-02 17:05:37 +03:00
. max_frequency = 102000000UL ,
2016-06-22 14:47:23 +03:00
} ;
2020-03-05 14:27:33 +03:00
static const struct tegra_pwm_soc tegra194_pwm_soc = {
. num_channels = 1 ,
. max_frequency = 408000000UL ,
} ;
2013-04-18 12:04:14 +04:00
static const struct of_device_id tegra_pwm_of_match [ ] = {
2016-06-22 14:47:23 +03:00
{ . compatible = " nvidia,tegra20-pwm " , . data = & tegra20_pwm_soc } ,
{ . compatible = " nvidia,tegra186-pwm " , . data = & tegra186_pwm_soc } ,
2020-03-05 14:27:33 +03:00
{ . compatible = " nvidia,tegra194-pwm " , . data = & tegra194_pwm_soc } ,
2011-12-21 11:04:13 +04:00
{ }
} ;
MODULE_DEVICE_TABLE ( of , tegra_pwm_of_match ) ;
2017-04-07 12:34:02 +03:00
static const struct dev_pm_ops tegra_pwm_pm_ops = {
2021-12-01 02:23:28 +03:00
SET_RUNTIME_PM_OPS ( tegra_pwm_runtime_suspend , tegra_pwm_runtime_resume ,
NULL )
SET_SYSTEM_SLEEP_PM_OPS ( pm_runtime_force_suspend ,
pm_runtime_force_resume )
2017-04-07 12:34:02 +03:00
} ;
2011-12-21 10:47:07 +04:00
static struct platform_driver tegra_pwm_driver = {
. driver = {
. name = " tegra-pwm " ,
2013-02-16 02:02:22 +04:00
. of_match_table = tegra_pwm_of_match ,
2017-04-07 12:34:02 +03:00
. pm = & tegra_pwm_pm_ops ,
2011-12-21 10:47:07 +04:00
} ,
. probe = tegra_pwm_probe ,
2023-03-03 21:54:41 +03:00
. remove_new = tegra_pwm_remove ,
2011-12-21 10:47:07 +04:00
} ;
module_platform_driver ( tegra_pwm_driver ) ;
MODULE_LICENSE ( " GPL " ) ;
2020-06-01 08:20:36 +03:00
MODULE_AUTHOR ( " Sandipan Patra <spatra@nvidia.com> " ) ;
MODULE_DESCRIPTION ( " Tegra PWM controller driver " ) ;
2011-12-21 10:47:07 +04:00
MODULE_ALIAS ( " platform:tegra-pwm " ) ;