SCMI device tree configuration

Revision as of 16:00, 20 January 2023 by Registered User (Rephrased and simplified the description.)



1. Article purpose[edit source]

The purpose of this article is to explain how the SCMI resources configuration are defined in U-Boot bootloader and Linux® kernel.

The configuration is performed using the device tree mechanism[1].

2. DT bindings documentation[edit source]

The SCMI services device tree bindings are defined in the Linux kernel source tree, in Arm SCMI DT bindings[2] documentation.

An SCMI agent, in U-Boot or Linux kernel is represented by a node name scmi in the device tree. Each SCMI protocol used is reprsented by a subnode of the scmi node. They subnodes represent the devices referenced by consumer nodes in the device tree.

For example the Device tree represents the SCMI power domain management protocol as (protocol ID Ox11) as power domain controller (PM domain provider in Device tree litterature). This power domain controller is a subnode named protocol@11 of the scmi node. Each power domain exposed on that protocol is idetified by well known ID number. A device consuming that power domain would refer to the SCMI power domain node phandle and use the SCMI power domain ID as phandle argument, e.g. power-domains = <&scmi_pd 2>;. The below source code is extracted from SCMI Device tree documentation.

    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>;
            };

        };
    };

3. DT configuration[edit source]

When the STM32MP1 platform is to operate with an SCMI server in secure OP-TEE world, it needs to be described in Linux kernel and U-Boot bootloader device tree source files.

The SCMI devices are described by a node named scmi. When using known piece of sram compatible shared memory for SCMI messages transfer, the platform must also represent "arm,scmi-shmem" compatible nodes to describe the shared memory.

When OP-TEE SCMI server exposes clocks and reset controllers the Linux or U-Boot need to access, their device tree image shall integrate a node named scmi in the firmware node. This node shall include a subnode named protocol@14 that is a clock controller (#clock-cells) and a subnode named protocol@16 that is a reset controller (reset-cells).

	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";
			#address-cells = <1>;
			#size-cells = <0>;
			linaro,optee-channel-id = <0>;
			shmem = <&scmi_shm>;

			scmi_clk: protocol@14 {
				reg = <0x14>;
				#clock-cells = <1>;
			};

			scmi_reset: protocol@16 {
				reg = <0x16>;
				#reset-cells = <1>;
			};
		};
	};

All devices using SCMI clocks and reset controllers refer to the phandle of the related SCMI clock contoller node scmi_clk and SCMI reset controller 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 point also examples for I2C4 bus node or RTC node:

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

		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>;
			status = "disabled";
		};

4. References[edit source]

Please refer to the following links for additional information: