Jetson TX2 Linux PWM Pulse Width Modulator
Introduction to Linux PWM Pulse Width Modulator for NVIDIA Jetson TX2
The following document has information about the Pulse Width Modulators available for the Jetson TX2 and how to control them.
There are eight PWMs available for the Jetson TX2:
Activating Jetson TX2 PWM
The Jetson TX2 pulse width modulators can be controlled at user space level using sysfs interface or at driver level using the PWM API.
Control PWM through sysfs
There are available 4 PWMs to be controlled at user space level. This interface allow the user to set the desired period and duty cycle and then activate or disable the PWM selected.
In /sys/class/pwm, you will find four directories corresponding to the first fourth PWMs available:
pwmchip0 --> GP_PWM1 pwmchip1 --> GP_PWM2 pwmchip2 --> GP_PWM3 pwmchip3 --> GP_PWM4 (Fan)
In order to set the configuration of one of the PWMs, you should export it first. Then, set the period, duty cycle and enable state as the following:
echo 0 > /sys/class/pwm/pwmchip0/export cd /sys/class/pwm/pwmchip0/pwm0 echo 20000 > period echo 10000 > duty_cycle echo 1 > enable
In the example above, the pulse activated (PWM1) has a frequency of 50 KHz (1/20us) and 50% of duty cycle (10000/20000 * 100).
Control Fan PWM (sysfs)
Jetson EVM only has pins exposed for the PWM signal that controls the fan, so in order to verify that the PWM is working correctly use the pin 4 on J15 Connector.
Disable Fan driver
As the PWM4 is already used by a driver that controls the fan, you should disable this driver in order to control the PWM manually.
Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-power-tree-p3489-1000-a00-00.dtsi
pwm-fan { + status = "disabled";  vdd-fan-supply = <&vdd_fan>;  };
Fix vdd_fan regulator state
The Fan controller has a GPIO that has to be set to low in order to allow the PWM activation, so you can modify the device-tree to set the initial value to low and keep this state to reduce complexity regarding PWM activation.
Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi
vdd_fan: regulator@13 { compatible = "regulator-fixed-sync"; reg = <13>; regulator-name = "vdd-fan"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio_i2c_0_74 4 0>; + enable-active-high; };
Note: You can also, disable this regulator and control manually vdd_fan GPIO (244) according to your needs.
Configure and Enable Fan PWM
Fan is controlled by GP_PWM4, so you in order to configure this PWM, you should apply the configuration to pwmchip3.
echo 0 > /sys/class/pwm/pwmchip3/export cd /sys/class/pwm/pwmchip3/pwm0 echo 20000 > period echo 10000 > duty_cycle echo 1 > enable
Verify PWM activation
Measure the PWM output on pin 4 of J15 Connector using an oscilloscope. You should see the pulse when you enable the PWM and you could measure frequency and duty cycle to validate this procedure.
Enable PWM using the API
A driver can configure and activate a PWM in a similar way to a the GPIOs are set. In order to do this, you should define the desired PWM in your corresponding driver node in your device-tree and implement the logic to parse and control this PWM in the driver.
Control Fan PWM (API)
In the following example, we are going to control the GP_PWM4 so, make sure you have the fan driver disabled and fix vdd_fan regulator to be in low state as explained in Control Fan PWM (sysfs)
Define the PWM in the Device-Tree
In the example below, the GP_PWM4 is defined in the AR1335 sensor node to start in low state and with a period of 45334 (~45 us).
ar1335_a@37 { compatible = "nvidia,ar1335"; reg = <0x37>; : #pwm-cells = <1>; pwms = <&tegra_pwm4 0 45334>; : };
Add API header
In the driver, add the following include:
#include <linux/pwm.h>
Get the PWM resource
In the driver, use the devm_pwm_get() function to pass to it the consumer device.
priv->pwm_dev = devm_pwm_get(&client->dev, NULL); if (IS_ERR(priv->pwm_dev)) { err = PTR_ERR(priv->pwm_dev); if (err != -EPROBE_DEFER) dev_err(&client->dev, "Unable to request PWM for fan\n"); return -EFAULT; } else { dev_info(&client->dev, "Got PWM for fan\n"); }
Configure PWM
Use pwm_config() method to set the duty cycle and period, in the example below the pulse is configured with a frequency of 60 Hz and 50% of duty cycle.
pwm_config(priv->pwm_dev, 8333333, 16666667);
Enable PWM
Once the PWM is configured, activate it like this:
pwm_enable(priv->pwm_dev);
Disable PWM
In order to disable PWM, use the following method:
pwm_diable(priv->pwm_dev);
Verify PWM
Using this methods you should be able to control the PWM and you can verify the output measuring pin 4 (J15 Connector).
Allow low PWM frequency configuration
For the latest Linux for Tegra (L4T-32), it's necessary to add extra device-tree configuration to allow lower frequency configuration for PWMs.
Example
For example the frequency range of operation for PWM3 is "400 Hz and below" as described in the TRM. However, with the default configuration this PWM can't be configured to use a frequency below ~50 Hz and it's necessary to specify the minimum frequency limit in the corresponding device-tree node.
The following change will allow to configure PWM3 to 30 Hz:
pwm@32a0000 { pwm-minimum-frequency-hz = <30>; /* required rate in Hz */ };
For direct inquiries, please refer to the contact information available on our Contact page. Alternatively, you may complete and submit the form provided at the same link. We will respond to your request at our earliest opportunity.
Links to RidgeRun Resources and RidgeRun Artificial Intelligence Solutions can be found in the footer below.