Last edited one month ago

TIM OpenSTLinux drivers

(Redirected from TIM Linux driver)
Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP21x lines, STM32MP23x lines, STM32MP25x lines

1. Article purpose[edit | edit source]

This article introduces the TIM Linux® and U-Boot drivers for the TIM internal peripheral[1]:

  • Which TIM features are supported by the drivers
  • How to configure, use and debug the drivers
  • What are the structures of the drivers, and where the source code can be found.

2. Short description[edit | edit source]

The TIM internal peripheral is supported in Linux® and U-Boot software components through dedicated drivers. Refer to the TIM internal peripheral to understand how a particular TIM instance is actually supported, depending on STM32 MPU device and execution context (here U-Boot or Linux context).

2.1. U-Boot driver[edit | edit source]

Since ecosystem release ≥ v6.1.0 More info.png , the TIM internal peripheral can be used in U-Boot for PWM.
The U-Boot driver is based on the pwm-uclass. This uclass offers an API[2] which can be used to implement PWM client applications.
Similarly to the Linux® driver, the TIM U-Boot driver is based on a parent/child driver model:

  • TIM multi-function parent driver:
    - handles registers and clock resources,
    - detects the TIM counter resolution, e.g. 16 or 32 bits,
    - is based on the NOP uclass.
  • TIM PWM child driver:
    - detects the number of TIM channels,
    - handles PWM output channels,
    - is based on the PWM uclass.

2.2. Linux kernel driver[edit | edit source]

The TIM[1] Linux driver (kernel space) is based on the PWM, IIO and counter frameworks. It provides several functionalities:

MFD driver:

  • handles registers, clock and DMA[3] resources
  • detects the TIM counter resolution, e.g. 16 or 32 bits.

PWM driver:

  • detects the number of TIM channels.
  • handles PWM output channels.
  • handles PWM capture channels (input) Deprecated. Note that the PWM capture relies on DMA, which is handled by the MFD core.

IIO driver:

  • handles hardware trigger sources (synchronously with PWM) for other internal peripherals such as ADC[4], DAC[5], DFSDM[6].

Counter driver:

  • handles the quadrature encoder interface[7].
  • counts on internal clock.
  • capture counter value with timestamps, upon external input signal edge.
Warning white.png Warning
It is recommended to use the counter subsystem with TIM counter driver for the capture feature. It is supported both on STM32MP1 series and on STM32MP2 series.

It now super-seeds the PWM framework input capture feature (supported only on STM32MP1 series).

2.3. Handover between U-Boot and Linux kernel PWM drivers[edit | edit source]

A typical use case for a PWM channel is to control a display panel backlight. In such a case, it can be useful to enforce a smooth transition at boot time in between U-Boot and the Linux kernel:

  • U-Boot first configures the desired panel brightness, for the splash-screen,
  • Then during Linux boot, the TIM PWM driver maintains the same configuration: It checks the enabled PWM channels at probe time to preserve their configuration, such as period and duty cycle. It may tuned later, as described in "How to modify the panel backlight".

3. Configuration[edit | edit source]

3.1. U-Boot configuration[edit | edit source]

The U-Boot PWM driver can be activated in the U-Boot configuration using the U-Boot menuconfig tool.
Enable the following configurations:

  • CONFIG_MFD_STM32_TIMERS
  • CONFIG_DM_PWM
  • CONFIG_PWM_STM32
-> ARM architecture
    [*] STM32 multifonction timer support
-> Device Drivers
    [*] Enable support for pulse-width modulation devices (PWM)
    [*] Enable support for STM32 PWM

In addition, in order to control a display panel backlight, enable the following configurations:

  • CONFIG_BACKLIGHT_PWM
-> Device Drivers
  -> Graphics support
    -> Enable driver model support for LCD/video
      [*]   Generic PWM based Backlight Driver

U-boot also implements pwm[8] command line tool. To activate it, enable the following configuration:

  • CONFIG_CMD_PWM
-> Command line interface
  -> Device access commands
    [*] pwm

3.2. Kernel configuration[edit | edit source]

Activate the TIM[1] Linux driver in the kernel configuration using the Linux Menuconfig tool: Menuconfig or how to configure kernel.

Enable the following configurations (and their dependencies):

  • CONFIG_MFD_STM32_TIMERS
  • CONFIG_PWM_STM32
  • CONFIG_IIO_STM32_TIMER_TRIGGER
  • CONFIG_STM32_TIMER_CNT
Device Drivers  --->
  -> Multifunction device drivers  --->
     <*> Support for STM32 Timers
  -> Pulse-width modulation (PWM) support  --->
     <*> STMicroelectronics STM32 PWM
  -> Industrial I/O support  --->
     -> Triggers - standalone  --->
        <*> STM32 timer trigger
  -> Counter support  --->
     <*> STM32 Timer encoder counter driver

3.3. Device tree[edit | edit source]

Refer to the TIM device tree configuration article when configuring the TIM Linux kernel driver.

4. How to use[edit | edit source]

4.1. U-Boot driver[edit | edit source]

The pwm[8] command line tool can be used to control a TIM PWM channel:

pwm
pwm - control pwm channels

Usage:
pwm invert <pwm_dev_num> <channel> <polarity> - invert polarity
pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM
pwm enable <pwm_dev_num> <channel> - enable PWM output
pwm disable <pwm_dev_num> <channel> - disable PWM output
Note: All input values are in decimal

For example on STM32MP135F-DK Discovery kit More info green.png, the TIM1 channel 3 can be used in PWM mode to control the panel backlight brightness:

pwm config 0 2 1000000 100000  # Sets period to 1 ms, period to 0.1 ms (10%)
pwm config 0 2 1000000 500000  # Sets period to 1 ms, period to 0.5 ms (50%)
pwm config 0 2 1000000 1000000 # Sets period to 1 ms, period to   1 ms (100%)

4.2. Linux kernel driver[edit | edit source]

How to use PWM with sysfs interface

How to set up a TIM or LPTIM trigger using the sysfs interface

How to use the quadrature encoder with the sysfs interface

How to capture a signal with the counter subsystem

How to modify the panel backlight

5. How to trace and debug[edit | edit source]

5.1. In U-Boot[edit | edit source]

Refer to U-Boot - How to debug for details about debug means in U-Boot.

In order to check the PWM driver in U-Boot is correctly probed, the dm tree command can be used:

# Example on STM32MP135F-DK Discovery kit More info green.png
dm tree
 Class     Index  Probed  Driver                Name
-----------------------------------------------------------
 ...
 nop           0  [ + ]   stm32_timers          |   |-- timer@44000000
 pwm           0  [ + ]   stm32_pwm             |   |   `-- pwm
 ...
 backlight     0  [ + ]   pwm_backlight         |-- panel-backlight

When the driver has been correctly probed, e.g. the TIM clock has been enabled, the registers may be dumped by using:

md 0x44000000
44000000: 00000081 00000000 00000000 00000000  ................
44000010: 0003001f 00000000 00000000 00000068  ............h...
44000020: 00000f00 00006164 00000003 0000cc00  ....da..........
44000030: 00000000 00000000 00000000 0000cc01  ................
...

On a running PWM, the TIM CNT register (at offset 0x24) is continuously counting. It can be seen by using:

md 0x44000024 1
44000024: 00005fa0                             ._..
md 0x44000024 1
44000024: 0000b21b                             ....

5.2. In Linux kernel[edit | edit source]

The TIM[1] Linux driver can access the timer registers through REGMAP.

It comes with debugfs[9] entries, which allow dumping registers:

cd /sys/kernel/debug/regmap
ls
40004000.timer  44000000.timer

cd 44000000.timer
cat registers
000: 00000081
004: 00000000
008: 00000000
00c: 00000000
...

It also comes with tracepoints[10]:

cd /sys/kernel/debug/tracing
cat available_events | grep regmap
...
regmap:regmap_reg_read
regmap:regmap_reg_write

6. Source code location[edit | edit source]

6.1. U-Boot[edit | edit source]

The TIM U-Boot driver source code is composed of:

6.2. Linux kernel[edit | edit source]

The TIM Linux driver source code is composed of:

7. References[edit | edit source]