Introduction
Pulse Width Modulation (PWM) is a commonly seen feature in embedded systems. It is a highly effective technique that utilizes the digital output of a microprocessor to control analog circuits, widely applied in various fields ranging from measurement and communication to power control and conversion. The Rockchip PWM supports three modes: Continuous mode, One-shot mode, and Capture mode, with 4 built-in channels.
Driver Files
The location of the driver file is: drivers/pwm/pwm-rockchip.c
For kernel versions 3.10 and 4.4 and above, the driver file name is the same. pwm-rockchip.c supports Continuous mode and One-shot mode, but there are some differences in the code. In kernel version 4.4 and above, pwm_config(), pwm_enable(), and pwm_disable() are wrapped in the pwm_apply_state() function. The benefit of this is that multiple PWM parameters can be changed at once, while the PWM driver in kernel 3.10 retains the original interface.
DTS Node Configuration
The DTS nodes for kernel version 3.10 and 4.4 and above have slight differences.
bl: backlight {
pwms = <&pwm 0 25000 PWM_POLARITY_INVERTED>;
pwm-names = “backlight”;
};
The main difference lies in the number of parameters configured. The kernel version 3.10 configures 2 parameters, while kernel version 4.4 and above can configure either 2 or 3 parameters. The number of parameters corresponds to the “pwm cells” in the PWM node. If the “pwm-cells” configuration is 3, then the optional polarity needs to be configured; if it is 2, polarity configuration is not required. For DTS configuration, refer to the documentation Documentation/devicetree/bindings/pwm/pwm.txt. The main parameters are explained as follows: Parameter 1 indicates the index (per-chip index of the PWM to request), which is generally 0, as each Rockchip PWM chip has only one. Parameter 2 indicates the time period of the PWM output waveform, in ns; for example, the configuration of 25000 below indicates that the desired PWM output period is 40K Hertz. Parameter 3 indicates polarity, which is an optional parameter; the configuration in the example below is for negative polarity.
PWM Process
The PWM driver process is generally the same across different kernel versions.
Using PWM
The usage of PWM in kernel and user space is described in Documentation/pwm.txt. Below, we will focus on the user space part. As stated in the pwm.txt document, PWM provides a user-space interface. Under the /sys/class/pwm/ node, after the PWM driver is successfully loaded, a pwmchip0 directory will be created in the /sys/class/pwm/ directory. Writing 0 to the export file opens PWM timer 0, which will create a pwm0 directory. Conversely, writing 0 to unexport will close the PWM timer, and the pwm0 directory will be deleted. This directory contains the following files:
enable: writing 1 enables PWM, writing 0 disables PWM;
polarity: there are two parameters to choose from, normal or inversed, indicating the output pin level inversion;
duty_cycle: in normal mode, it indicates the duration of high level within one cycle (unit: nanoseconds); in reversed mode, it indicates the duration of low level within one cycle (unit: nanoseconds);
period: indicates the period of the PWM wave (unit: nanoseconds);
oneshot_count: indicates the number of PWM waveforms in one-shot mode, the value cannot exceed 255;
Common Issues
Issues with PWM between U-Boot and kernel
If U-Boot uses PWM for voltage regulation, when it reaches the kernel stage, the PWM is still in working state. It is necessary to adjust the PWM clock count to match the current PWM state based on the current hardware status. Otherwise, there may be issues where the clock architecture detects an unused PWM clock, leading to its shutdown, causing PWM to fail to operate, resulting in problems such as system crashes due to insufficient PWM voltage regulation. The above patch has been corrected to ensure the PWM driver: drivers/pwm/pwm-rockchip.c is updated to the following commit points: 1. kernel-4.4: commit e6f2796ef5b660a70102c02d6c15f65ff8701d76 2. kernel-3.10: commit 5a3d9257d5e379391eb02457ccd70f28a8fb188b. Different clock sources used by U-Boot and kernel for PWM can also lead to switching issues, potentially causing changes in PWM duty cycle, resulting in problems such as system crashes due to insufficient PWM voltage regulation. Therefore, it is essential to keep the clock sources or frequencies consistent between U-Boot and kernel. Ensure that the GPLL frequency in U-Boot is consistent with that in the kernel, as the PWM clock is currently under GPLL. The GPLL frequency in U-Boot can be seen in the U-Boot boot log, while the kernel frequency can be checked by viewing the clock tree, using the command cat /sys/kernel/debug/clock/clock_tree | grep gpll. Inconsistencies in polarity and period configured in U-Boot and kernel can also lead to switching issues, potentially causing changes in PWM duty cycle, resulting in problems such as system crashes due to insufficient PWM voltage regulation. Therefore, it is essential to keep the polarity and period consistent between U-Boot and kernel.
PWM Regulator and PWM Pin Pull-Up/Pull-Down Configuration Issues
During reboot, many situations do not reset the registers inside the GRF, while the PWM controller will reset. This can change the default voltage of the PWM Regulator after reboot. Therefore, it is necessary to configure the PWM pin pull-up/pull-down in the kernel to be consistent with the default pull-up/pull-down settings and not configure it as none. This issue only needs to be modified when PWM is used for voltage regulation; it can be ignored for other functions. Confirm the default pull-up/pull-down of the PWM pin through the hardware schematic. For example, in the RK3399 excavator board, PWM2 is used for voltage regulation. In the schematic, find the PWM2 pin: GPIO1_C3/PWM2_d, where “d” indicates down as the default pull-down; if it is “u”, it indicates up as the default pull-up.