Last edited 4 months ago

Pinctrl device tree configuration

Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP25x lines

1. Purpose[edit | edit source]

The purpose of this article is to explain how to configure the GPIO internal peripheral through the pin controller (pinctrl) framework, when this peripheral is assigned to Linux® OS (Cortex-A). The configuration is performed using the Device tree.

To better understand I/O management, it is recommended to read the Overview of GPIO pins article.

This article also provides an example explaining how to add a new pin in the device tree.

If the peripheral is assigned to another execution context, refer to How to assign an internal peripheral to an execution context article for guidelines on peripheral assignment and configuration.

2. DT bindings documentation[edit | edit source]

The Pinctrl device tree bindings are composed of:

  • generic DT bindings[1] used by the pinctrl framework.
  • vendor pinctrl DT bindings[2] used by the stm32-pinctrl driver: this binding document explains how to write device tree files for pinctrl.

3. DT configuration[edit | edit source]

3.1. DT configuration (STM32 level)[edit | edit source]

The pin controller node is composed of several parts:

3.1.1. STM32 pin controller information[edit | edit source]

The pin controller node is located in the SOC dtsi file

  • for STM32MP13x lines More info.png stm32mp131.dtsi[3]
  • for STM32MP15x lines More info.png stm32mp151.dtsi[4]
  • for STM32MP25x lines More info.png stm32mp251.dtsi[5]

For example:

pinctrl: pinctrl@50002000 {                 Comments
 	#address-cells = <1>;              
 	#size-cells = <1>;                 
 	ranges = <0 0x50002000 0xa400>;    -->Provides IP start address and memory map device size
 	interrupt-parent = <&exti>;        -->Provides interrupt parent controller (used when the GPIO is configured as an external interrupt)
 	st,syscfg = <&exti 0x60 0xff>;     -->Provides phandle for IRQ mux selection
 	pins-are-numbered;
	
        ...
};
Warning white.png Warning
This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.


3.1.2. GPIO bank information[edit | edit source]

The GPIO bank information nodes are located in the SOC dtsi file

  • for STM32MP13x lines More info.png stm32mp131.dtsi[3]
  • for STM32MP15x lines More info.png stm32mp151.dtsi[4]
  • for STM32MP25x lines More info.png stm32mp251.dtsi[5]

For example:

pinctrl: pinctrl@50002000 {                 Comments
 	...

	gpioa: gpio@50002000 {
		gpio-controller;           
		#gpio-cells = <2>;
		interrupt-controller;      -->Indicates that this GPIO bank can be used as interrupt controller
		#interrupt-cells = <2>;
		reg = <0x0 0x400>;         -->Provides offset in pinctrl addres map for the GPIO bank
		clocks = <&rcc GPIOA>;     -->phandle on GPIO bank clock
		st,bank-name = "GPIOA";
		status = "disabled";
	};

	gpiob: gpio@50003000 {
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
		reg = <0x1000 0x400>;
		clocks = <&rcc GPIOB>;
		st,bank-name = "GPIOB";
		status = "disabled";
	};

        ...
};

The GPIO bank definition may be completed by the pinctrl package dtsi files, as, for example for STM32MP15x lines More info.png stm32mp15xxaa-pinctrl.dtsi[6].

&pinctrl {
	st,package = <STM32MP_PKG_AA>;

	gpioa: gpio@50002000 {
		status = "okay";
		ngpios = <16>;
		gpio-ranges = <&pinctrl 0 0 16>;
	};

	gpiob: gpio@50003000 {
		status = "okay";
		ngpios = <16>;
		gpio-ranges = <&pinctrl 0 16 16>;
	};
Warning white.png Warning
This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.

3.1.3. Pin state definition[edit | edit source]

The pin states are defined in the pinctrl dtsi file

  • for STM32MP13x lines More info.png stm32mp13-pinctrl.dtsi [7]
  • for STM32MP15x lines More info.png stm32mp15-pinctrl.dtsi [8]
  • for STM32MP25x lines More info.png stm32mp25-pinctrl.dtsi [9]

For example:

&pinctrl {
        ...
         usart3_pins_a: usart3@0 {                                                   Comments
	        pins1 {
		        pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */      -->Pin muxing information: AF7 (alternate function 7) selected on PB10 pin
			         <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */      -->Pin muxing information: AF8 (alternate function 8) selected on PG8 pin
		        bias-disable;                                               -->Generic bindings corresponding to "no pull-up" and "no pull-down"
		        drive-push-pull;                                            -->Generic bindings to select pin driving information
		        slew-rate = <0>;                                            -->Generic bindings to select pin speed
	        };
	        pins2 {
		        pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
			         <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
		        bias-disable;
	        };
       };
       ...
};
- Refer to GPIO internal peripheral for more details on hardware pin configuration.

3.2. DT configuration (board level)[edit | edit source]

3.2.1. Pin state selection[edit | edit source]

As seen in Pin controller configuration (pin state definition part), all pin states are defined inside the pin controller node.

Each device that requires pins has to select the desired pin state phandle inside the board device tree file (see Device tree for more explanations about device tree file split).

The STM32MP1 devices feature a lot of possible pin combinations for a given internal peripheral. From one board to another, different sets of pins can consequently be used for an internal peripheral. Note that "_a", "_b" suffixes are used to identify pin muxing combinations in the device tree pinctrl file. The right suffixed combination must then be used in the device tree board file.

  • Example:
&usart3 {
        ...
	pinctrl-names = "default","sleep";
	pinctrl-0 = <&usart3_pins_a>;
	pinctrl-1 = <&usart3_sleep_pins_a>;
	...
};

3.2.2. GPIO bank secure information (OP-TEE device tree)[edit | edit source]

The secure aware GPIO banks (see peripheral runtime assignment tables) may contain some specific secure settings. A peripheral set as secure MUST use secure GPIOs.

The specific st,protreg binding defined in the OP-TEE device tree sets the security at boot time and prevents non secure peripherals from using pins.

  • For STM32MP1 series :
&gpiob {
	--> pins 1 and 6 are configured as secure
	st,protreg = <(TZPROT(1)|TZPROT(6))>;
};
  • For STM32MP2 series :
&gpioa {
	--> configure RIFSC for pin PA0 and PA1
	st,protreg = <
		RIFPROT(RIF_IOPORT_PIN(0), EMPTY_SEMWL, RIF_UNLOCK, RIF_NSEC, RIF_NPRIV, RIF_CID0, RIF_SEM_DIS, RIF_CFDIS)
		RIFPROT(RIF_IOPORT_PIN(1), EMPTY_SEMWL, RIF_UNLOCK, RIF_NSEC, RIF_NPRIV, RIF_CID0, RIF_SEM_DIS, RIF_CFDIS)
		[...]
	>;
};

See RIFSC device tree bindings RIFSC bindings for more information on RIFPROT macro.

Warning white.png Warning
If this property is not defined, all the GPIOs of the bank are set as non secure, so not compatible with a secure peripheral

3.3. DT configuration examples[edit | edit source]

3.3.1. How to add new pin states[edit | edit source]

To add new pin states and affect them to a foo_device, proceed as follows:

1. Find the pins you need:
In the example below, the foo_device needs to configure PC13, PG8 and PI2.
AF2 is selected as alternate function on PC13, and AF5 on PG8 and PI2.
Each pin requires an internal pull-up.
2. Write your pin state phandle in stm32mp15-pinctrl.dtsi.
 &pinctrl {
         ...
          foo_pins_a: foo@0 {
 	        pins {
 		        pinmux = <STM32_PINMUX('C', 13, AF2)>,
                                 <STM32_PINMUX('G', 8, AF5)>,
 			         <STM32_PINMUX('I', 2, AF5)>; 
 		        bias-pull-up;
 	        };
        };
        ...
 };
All the possible settings are described in GPIO internal peripheral.
3. Select the pin state phandle required for your device in the board file.
&foo {
        ...
	pinctrl-names = "default";
	pinctrl-0 = <&foo_pins_a>;
	...
};

4. How to configure GPIOs using STM32CubeMX[edit | edit source]

The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
The STM32CubeMX may not support all the properties described in the above DT bindings documentation paragraph. If so, the tool inserts user sections in the generated device tree. These sections can then be edited to add some properties and they are preserved from one generation to another. Refer to STM32CubeMX user manual for further information.

5. References[edit | edit source]

Please refer to the following links for additional information:

  1. Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt , Generic pinctrl device tree bindings
  2. Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml , STM32 pinctrl device tree bindings
  3. 3.0 3.1 stm32mp131.dtsi STM32MP13 SOC device tree file
  4. 4.0 4.1 stm32mp151.dtsi STM32MP15 SOC device tree file
  5. 5.0 5.1 stm32mp251.dtsi STM32MP25 SOC device tree file
  6. stm32mp15xxaa-pinctrl.dtsi STM32MP15 Pinctrl device tree file
  7. stm32mp13-pinctrl.dtsi STM32MP13 pinctrl device tree file
  8. stm32mp15-pinctrl.dtsi STM32MP15 pinctrl device tree file
  9. stm32mp25-pinctrl.dtsi STM32MP25 pinctrl device tree file