Last edited 3 weeks ago

SCMI device tree configuration

Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP21x lines, STM32MP23x lines, STM32MP25x lines

1. Article purpose[edit | edit source]

The purpose of this article is to explain how the System Control and Management Interface (SCMI) [1] resources are configured in OpenSTLinux (OP-TEE, U-Boot and Linux® kernel). The configuration is performed using the device tree mechanism.

SCMI services provided in STM32 MPU platforms are described in the SCMI overview article.

2. DT bindings documentation[edit | edit source]

The device tree binding documents for SCMI resources are stored either in the given applicable components listed below, or in the Linux kernel repository:

SCMI agent is only present in U-Boot and Linux® OS, while SCMI server is integrated in OP-TEE.

The SCMI agent DT node must reflect the services exposed by SCMI server embedded in OP-TEE.

From SCMI communication perspective, the agent and server for that platform use well defined ID numbers for each service, they are called domain IDs or domain_id in SCMI literature.

Warning white.png Warning
The domain ID used by agent and server to idetify each SCMI ressource must be identical. It is guaranteed in OpenSTlinux by using the same SCMI defines.

2.1. SCMI agent bindings[edit | edit source]

A SCMI agent, in U-Boot or Linux kernel is represented by a node named scmi in the firmware node of the device tree. Property compatible in the scmi node defines the SCMI transport used. Valid values for compatible property are listed in the SCMI DT bindings (Documentation/devicetree/bindings/firmware/arm,scmi.yaml ). Each SCMI protocol used is represented by a subnode of the scmi node and expose the framework associated for each protocol: clock, regulator, reset.


   firmware {
       scmi {
           compatible = "...";
           #address-cells = <1>;
           #size-cells = <0>;
           (...)
           protocol@11 {
               reg = <0x11>;
               #power-domain-cells
               (...)
           };
           protocol@13 {
               reg = <0x13>;
               #clock-cells
               (...)
           };
           protocol@14 {
               reg = <0x14>;
               #clock-cells
               (...)
           };
           (...)
           protocol@16 {
               reg = <0x16>;
               #reset-cells
               (...)
           };
           protocol@17 {
               reg = <0x17>;
               regulators {
                   (...)
               };
           };
           (...)
       };
   };

For example, the Arm® SCMI specification defines the SCMI power domain management protocol as identified with protocol ID 0x11. Device tree represents this SCMI protocol as a subnode named protocol@11 of the scmi node which is a power domain controller in the Linux® kernel (or "PM domain provider") with property #power-domain-cells; it exposes power domains to Linux® kernel drivers (Documentation/devicetree/bindings/power/power-domain.yaml ).

As shown in the source code snippet below, a device consuming the SCMI agent's power domain would refer to that power domain provider using the SCMI protocol node phandle, scmi_devpd1 here, and use the well defined SCMI power domain ID as phandle argument to identify the associated ressource :
e.g. with ID=2: power-domains = <&scmi_devpd1 2>;.
The below DTSI source code snippet is extracted from the SCMI DT bindings documentation Documentation/devicetree/bindings/firmware/arm,scmi.yaml .


   firmware {
       scmi {
           compatible = "arm,scmi-smc";
           shmem = <&cpu_scp_lpri0 &cpu_scp_lpri1>;
           arm,smc-id = <0xc3000001>;
           #address-cells = <1>;
           #size-cells = <0>;

           scmi_devpd1: protocol@11 {
               reg = <0x11>;
               #power-domain-cells = <1>;
           };
       };
   };


2.1.1. SCMI agent transport: channels and shared memory[edit | edit source]

When the platform uses a predefined area of sram compatible memory for exchanging SCMI messages between non-secure and secure worlds, the platform must set property shmem = <SOME_PHANDLE> in the scmi node, and possibly in the SCMI protocol subnodes, in case such procotol uses a specifc channel.

When using compatible="linaro,scmi-optee", SCMI communication can use OP-TEE dynamically allocated shared memory which is represented by the absence of property shmem in the related node.

The below example describes an OP-TEE SCMI firmware that exposes 2 channels. Channel 0 uses pre-defined sram shared memory and is used for SCMI base communication and for SCMI reset controls messaging (protocol 14). Channel 1 uses dynamically allocated OP-TEE shared memory and is used for a voltage regulator controller (protocol 17).

	scmi_sram: sram@2ffff000 {
		compatible = "mmio-sram";
		reg = <0x2ffff000 0x1000>;
		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0 0x2ffff000 0x1000>;

		scmi_shm: scmi_shm@0 {
			compatible = "arm,scmi-shmem";
			reg = <0 0x80>;
		};
	};

	firmware {
		scmi: scmi {
			compatible = "linaro,scmi-optee";
			linaro,optee-channel-id = <0>;
			shmem = <&scmi_shm>;
			#address-cells = <1>;
			#size-cells = <0>;
			scmi_clk: protocol@14 {
				reg = <0x14>;
				#clock-cells = <1>;
			};
			protocol@17 {
				reg = <0x17>;
				linaro,optee-channel-id = <1>;
				regulators {
					#address-cells = <1>;
					#size-cells = <0>;
					scmi_reg11: reg11@0 {
						reg = <0>;
						regulator-name = "reg11";
						regulator-min-microvolt = <1100000>;
					};
				};
			};
		};
	};

3. DT configuration (agent side)[edit | edit source]


This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device-tree file organization. STM32CubeMX can be used to generate the board device tree.

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

SoC level device tree data defines the SCMI node that represents SCMI communication means and SCMI protocols exposed by the SCMI server embedded in system secure world.

Info white.png Information

For STM32MP15x lines More info.png, ecosystem release ≥ v5.0.0 :
SCMI device tree node is implemented in DTSI file stm32mp15-scmi.dtsi included by board DTS files whereas prior ecosystem release v5.0.0 , the node was defined straight in the SoC DTSI file stm32mp151.dtsi.

The ecosystem release ≥ v5.0.0 embeds the SCMI OP-TEE transport as defined by compatible = "linaro,scmi-optee" the the scmi node. All SCMI message exchanges use a single communication channel, numbered 0, hence property linaro,optee-channel-id = <0> found in the scmi node. This communication channel uses OP-TEE shared memory for message exchange therefore there is no shmem property in the related scmi node.

SoC level device tree configuration data defines the SCMI protocols exposed by the SCMI server related to SoC resources. These are:

  • clock and reset controllers controlled by the SoC RCC subsystem and managed respectively through the SCMI clock protocol (protocol ID 0x14) and SCMI reset domain (protocol ID 0x16);
  • voltage regulators controller by SoC PWR subsystem and managed through the SCMI voltage domain protocol (protocol ID 0x17);
  • possibly CPU operating point exposed through the SCMI performance management protocol (protocol ID 0x13).

Description of how devices consume SCMI services is described in the below section DT_configuration_for_SCMI_resource_consumers.

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

Board level device tree configuration data defines the controls exposed by the SCMI server related to board specific configuration, as voltage regulators (exposed through the SCMI voltage domain protocol) for regulators controlled from the Power Management Integrated Circuit (PMIC).

Description of how device node binds to SCMI services is described in the below section DT configuration for SCMI resource consumers.

Remember that SCMI agent (Linux® kernel and U-Boot) device tree configuration data reflects the SCMI firmware services exposed by the SCMI server embedded in system secure world.

3.3. DT configuration examples[edit | edit source]

3.3.1. SCMI agent[edit | edit source]

The below illustration shows STM32MP13x lines More info.png SCMI device tree SoC level data using SCMI/OP-TEE transport over channel 0 using OP-TEE native shared memory and exposing clock, reset and voltage regulator controllers.

	firmware {
		scmi: scmi {
			compatible = "linaro,scmi-optee";
			linaro,optee-channel-id = <0>;
			#address-cells = <1>;
			#size-cells = <0>;
			scmi_clk: protocol@14 {
				reg = <0x14>;
				#clock-cells = <1>;
			};
			scmi_reset: protocol@16 {
				reg = <0x16>;
				#reset-cells = <1>;
			};
			protocol@17 {
				reg = <0x17>;
				linaro,optee-channel-id = <1>;
				regulators {
					#address-cells = <1>;
					#size-cells = <0>;
                                        scmi_reg11: voltd-reg11 {
                                                reg = <VOLTD_SCMI_REG11>;
                                                regulator-name = "reg11";
                                        };
                                        scmi_reg18: voltd-reg18 {
                                                reg = <VOLTD_SCMI_REG18>;
                                                regulator-name = "reg18";
                                        };
                                        scmi_usb33: voltd-usb33 {
                                                reg = <VOLTD_SCMI_USB33>;
                                                regulator-name = "usb33";
                                        };

				};
			};
		};
	};

3.3.2. DT configuration for SCMI resource consumers[edit | edit source]

All devices consuming SCMI resources refer to them using Device Tree phandle. For example, a device consuming clock and reset controllers refers to the phandle of the related SCMI clock protocol node scmi_clk or SCMI reset domain protocol node scmi_reset.

For example, the CPU references an SCMI clock:

	cpus {
		#address-cells = <1>;
		#size-cells = <0>;

		cpu0: cpu@0 {
			compatible = "arm,cortex-a7";
			device_type = "cpu";
			reg = <0>;
			clocks = <&scmi_clk CK_SCMI_MPU>;
			clock-names = "cpu";
			operating-points-v2 = <&cpu0_opp_table>;
			nvmem-cells = <&part_number_otp>;
			nvmem-cell-names = "part_number";
			#cooling-cells = <2>;
		};
	};


We can also point to examples for I2C4 bus that uses an SCMI clock and an SCMI reset controller ...

		i2c4: i2c@5c002000 {
			compatible = "st,stm32mp15-i2c";
			reg = <0x5c002000 0x400>;
			(...)
			clocks = <&scmi_clk CK_SCMI_I2C4>;
			resets = <&scmi_reset RST_SCMI_I2C4>;
			(...)
		};


... or the RTC device node.

		rtc: rtc@5c004000 {
			compatible = "st,stm32mp1-rtc";
			reg = <0x5c004000 0x400>;
			clocks = <&scmi_clk CK_SCMI_RTCAPB>,
				 <&scmi_clk CK_SCMI_RTC>;
			clock-names = "pclk", "rtc_ck";
			interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;
			(...)
		};


The IDs of the different resources are defined in the device tree bindings with SCMI define:

4. DT configuration (server side)[edit | edit source]

This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device-tree file organization. STM32CubeMX can be used to generate the board device tree.

The full SCMI configuration with a device-tree in OP-TEE is only available on STM32MP2 series.

4.1. DT configuration (STM32/SoC level)[edit | edit source]

SoC level device tree data defines the SCMI node that represents resources exposed with SCMI protocols by the SCMI server. The SCMI resources description is done with the helps of device-tree.

The server exposed resources to two different agents:

  • One agent for CortexA35 non secure context based on OP-TEE PTA to transport SCMI data: agent@1
  • One agent for CortexM33 non secure context based on a mailbox to transport SCMI data: agent@2

Each agent got a single channel and exposed resources can be different between agent.

The well known IDs of the different resources are indicated in unit-address of each SCMI element (in name with @unit-address and with reg=<unit-address>) and are defined in the device tree bindings file with SCMI defines:

Here it is an example extracted from core/arch/arm/dts/stm32mp251.dtsi :

scmi: scmi {
	compatible = "optee,scmi-server";
	#address-cells = <1>;
	#size-cells = <0>;

	/* Resources exposed to CortexA35 non secure agent */
	agent_a35_ns: agent@1 {
		reg = <1>; /* ID 0 is reserved */
		compatible = "linaro,scmi-optee"; /* Handle data transport with an OP-TEE PTA */
		scmi-channel-id = <0>; /* All resources are exposed on the same channel */
		#address-cells = <1>;
		#size-cells = <0>;
		
		/* Resources exposed with power domain protocol */
		scmi_pd: protocol@11 {
			reg = <0x11>;

			power-domains {
				#address-cells = <1>;
				#size-cells = <0>;

				pd_gpu: pd@0 {
					reg = <PD_SCMI_GPU>; /* Resource's SCMI identifier */
					clocks = <&rcc PLL3_CK>;
					voltd-supply = <&vddgpu>;
					domain-name = "gpu-pd"; /* Resource's SCMI name */
				};
			};
		};

		/* Resources exposed with clock protocol */
		scmi_clock: protocol@14 {
			reg = <0x14>;

			clocks {
				#address-cells = <1>;
				#size-cells = <0>;

				clock@0 {
					reg = <CK_SCMI_ICN_HS_MCU>;
					domain-name = "ck_icn_hs_mcu";
					clocks = <&rcc CK_ICN_HS_MCU>; /* OP-TEE clock exposed by SCMI */
					flags = <SCMI_CLOCK_DEFAULT_ENABLED>; /* Clock configuration, possible values: core/include/dt-bindings/scmi/scmi-clock.h  */
				};
				(...)
			};
		};

		/* Resources exposed with reset protocol */
		scmi_reset: protocol@16 {
			reg = <0x16>;

			resets {
				#address-cells = <1>;
				#size-cells = <0>;

				reset@0 {
					reg = <RST_SCMI_C1_R>;
					domain-name = "c1";
					resets = <&rcc C1_R>; /* OP-TEE reset exposed by SCMI */
				};

				(...)
			};
		};

		/* Resources exposed with regulator protocol */
		scmi_regulator: protocol@17 {
			reg = <0x17>;

			scmi_regu: regulators {
				#address-cells = <1>;
				#size-cells = <0>;

				voltd-vddio1 {
					reg = <VOLTD_SCMI_VDDIO1>;
					voltd-supply = <&vddio1>; /* OP-TEE regulator exposed by SCMI */
				};
				(...)
			};
		};
	};
	
	/* Resources exposed to CortexM33 non secure agent */
	agent_m33_ns: agent@2 {
		reg = <2>;
		compatible = "arm,scmi"; /* Handle data transport with a mailbox */
		scmi-channel-id = <0>;
		mbox-names = "scmi_cm33";
		mboxes = <&ipcc1 RIF_IPCC_CPU1_CHANNEL(16)>; /* Mailbox used between context */
		shmem = <&ipc_shmem>; /* Memory shared between context */
		#address-cells = <1>;
		#size-cells = <0>;

		scmi_clock_m33: protocol@14 {
			reg = <0x14>;

			clocks {
				#address-cells = <1>;
				#size-cells = <0>;

				clock@0 {
					reg = <CK_SCMI_ICN_HS_MCU>;
					domain-name = "ck_icn_hs_mcu";
					clocks = <&rcc CK_ICN_HS_MCU>;
					flags = <SCMI_CLOCK_DEFAULT_ENABLED>;
				};
				(...)
			};
		};

		scmi_reset_m33: protocol@16 {
			reg = <0x16>;

			resets {
				#address-cells = <1>;
				#size-cells = <0>;

				reset@0 {
					reg = <RST_SCMI_C1_R>;
					domain-name = "c1";
					resets = <&rcc C1_R>;
				};
				(...)
			};
		};

		scmi_regulator_m33: protocol@17 {
			reg = <0x17>;

			regulators {
				#address-cells = <1>;
				#size-cells = <0>;

				voltd-vdd33ucpd {
					reg = <VOLTD_SCMI_UCPD>;
					voltd-supply = <&vdd33ucpd>;
				};
			};
		};
	};
};

Power domain "PD_SCMI_GPU" is used to control the clock and the regulator of the GPU at the same time. So it requires a clock and a vold properties.

4.2. DT configuration (STM32/SoC level) for STM32MP1 series[edit | edit source]

For STM32MP1 series, the DT configuration is limited at regulator part, with compatible st,scmi-regulator-consumer, the clock and reset parts are defined in SCMI server server code source.

	scmi_regu: scmi-regu {
		compatible = "st,scmi-regulator-consumer";
		#address-cells = <1>;
		#size-cells = <0>;
		scmi-agent-id = <0>;
		scmi-channel-id = <0>;

		voltd-reg11 {
			reg = <VOLTD_SCMI_REG11>;
			voltd-supply = <&reg11>;
		};

		voltd-reg18 {
			reg = <VOLTD_SCMI_REG18>;
			voltd-supply = <&reg18>;
		};

		voltd-usb33 {
			reg = <VOLTD_SCMI_USB33>;
			voltd-supply = <&usb33>;
		};
	};
Info white.png Information
On STM32MP15x lines More info.png STMicroelectronics boards the I2C4 and STPMIC1 is assigned to Linux, so regulator are not exposed by SCMI server.

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

Protocols nodes can be surcharged to exposed resources not already declared at SoC level:

&scmi_regu {
	voltd-vddcore {
		reg = <VOLTD_SCMI_STPMIC2_BUCK2>;
		voltd-supply = <&vddcore>;
	};
	(...)
};

5. References[edit | edit source]

Refer to the following links for additional information:

  1. Arm System Control and Management Interface Platform Design Document (SCMI) specification:
    https://developer.arm.com/documentation/den0056