1.. _arm_scmi:
2
3ARM System Control and Management Interface
4###########################################
5
6Overview
7********
8
9What is SCMI?
10*************
11
12System Control and Management Interface (SCMI) is a specification developed by
13ARM, which describes a set of OS-agnostic software interfaces used to perform
14system management (e.g: clock control, pinctrl, etc...).
15
16
17Agent, platform, protocol and transport
18***************************************
19
20The SCMI specification defines **four** key terms, which will also be used throughout
21this documentation:
22
23	#. Agent
24		Entity that performs SCMI requests (e.g: gating a clock or configuring
25		a pin). In this context, Zephyr itself is an agent.
26	#. Platform
27		This refers to a set of hardware components that handle the requests from
28		agents and provide the necessary functionality. In some cases, the requests
29		are handled by a firmware, running on a core dedicated to performing system
30		management tasks.
31	#. Protocol
32		A protocol is a set of messages grouped by functionality. Intuitively, a message
33		can be thought of as a remote procedure call.
34
35		The SCMI specification defines ten standard protocols:
36
37		#. **Base** (0x10)
38		#. **Power domain management** (0x11)
39		#. **System power management** (0x12)
40		#. **Performance domain management** (0x13)
41		#. **Clock management** (0x14)
42		#. **Sensor management** (0x15)
43		#. **Reset domain management** (0x16)
44		#. **Voltage domain management** (0x17)
45		#. **Power capping and monitoring** (0x18)
46		#. **Pin Control** (0x19)
47
48		where each of these protocols is identified by an unique protocol ID
49		(listed between brackets).
50
51		Apart from the standard protocols, the SCMI specification reserves the
52		**0x80-0xFF** protocol ID range for vendor-specific protocols.
53
54
55	#. Transport
56		This describes how messages are exchanged between agents and the platform.
57		The communication itself happens through channels.
58
59.. note::
60	A system may have more than one agent.
61
62Channels
63********
64
65A **channel** is the medium through which agents and the platform exchange messages.
66The structure of a channel and the way it works is solely dependent on the transport.
67
68Each agent has its own distinct set of channels, meaning some channel A cannot be used
69by two different agents for example.
70
71Channels are **bidirectional** (exception: FastChannels), and, depending on which entity
72initiates the communication, can be one of **two** types:
73
74	#. A2P (agent to platform)
75		The agent is the initiator/requester. The messages passed through these
76		channels are known as **commands**.
77	#. P2A (platform to agent)
78		The platform is the initiator/requester.
79
80Messages
81********
82
83The SCMI specification defines **four** types of messages:
84
85	#. Synchronous
86		These are commands that block until the platform has completed the
87		requested work and are sent over A2P channels.
88	#. Asynchronous
89		For these commands, the platform schedules the requested work to
90		be performed at a later time. As such, they return almost immediately.
91		These commands are sent over A2P channels.
92	#. Delayed response
93		These messages indicate the completion of the work associated
94		with an asynchronous command. These are sent over P2A channels.
95
96	#. Notification
97		These messages are used to notify agents of events that take place on
98		the platform. These are sent over P2A channels.
99
100The Zephyr support for SCMI is based on the documentation provided by ARM:
101`DEN0056E <https://developer.arm.com/documentation/den0056/latest/>`_. For more details
102on the specification, the readers are encouraged to have a look at it.
103
104SCMI support in Zephyr
105**********************
106
107Shared memory and doorbell-based transport
108******************************************
109
110This form of transport uses shared memory for reading/writing messages
111and doorbells for signaling. The interaction with the shared
112memory area is performed using a driver (:file:`drivers/firmware/scmi/shmem.c`),
113which offers a set of functions for this exact purpose. Furthermore,
114signaling is performed using the Zephyr MBOX API (signaling mode only, no message passing).
115
116Interacting with the shared memory area and signaling are abstracted by the
117transport API, which is implemented by the shared memory and doorbell-based
118transport driver (:file:`drivers/firmware/scmi/mailbox.c`).
119
120The steps below exemplify how the communication between the Zephyr agent
121and the platform may happen using this transport:
122
123	#. Write message to the shared memory area.
124	#. Zephyr rings request doorbell. If in ``PRE_KERNEL_1`` or ``PRE_KERNEL_2`` phase start polling for reply, otherwise wait for reply doorbell ring.
125	#. Platform reads message from shared memory area, processes it, writes the reply back to the same area and rings the reply doorbell.
126	#. Zephyr reads reply from the shared memory area.
127
128In the context of this transport, a channel is comprised of a **single** shared
129memory area and one or more mailbox channels. This is because users may need/want
130to use different mailbox channels for the request/reply doorbells.
131
132
133Protocols
134*********
135
136Currently, Zephyr has support for the following standard protocols:
137
138	#. **Power domain management**
139	#. **Clock management**
140	#. **Pin Control**
141
142
143Power domain management
144***********************
145
146This protocol is intended for management of power states of power domains.
147This is done via a set of functions implementing various commands, for
148example, ``POWER_STATE_GET`` and ``POWER_STATE_SET``.
149
150.. note::
151	This driver is vendor-agnostic. As such, it may be used on any
152	system that uses SCMI for power domain management operations.
153
154Clock management protocol
155*************************
156
157This protocol is used to perform clock management operations. This is done
158via a driver (:file:`drivers/clock_control/clock_control_arm_scmi.c`), which
159implements the Zephyr clock control subsystem API. As such, from the user's
160perspective, using this driver is no different than using any other clock
161management driver.
162
163.. note::
164	This driver is vendor-agnostic. As such, it may be used on any
165	system that uses SCMI for clock management operations.
166
167Pin Control protocol
168********************
169
170This protocol is used to perform pin configuration operations. This is done
171via a set of functions implementing various commands. Currently, the only
172supported command is ``PINCTRL_SETTINGS_CONFIGURE``.
173
174.. note::
175	The support for this protocol **does not** include a definition for
176	the :code:`pinctrl_configure_pins` function. Each vendor should use
177	their own definition of :code:`pinctrl_configure_pins`, which should
178	call into the SCMI pin control protocol function implementing the
179	``PINCTRL_SETTINGS_CONFIGURE`` command.
180
181
182Enabling the SCMI support
183*************************
184
185To use the SCMI support, each vendor is required to add an ``scmi`` DT
186node (used for transport driver binding) and a ``protocol`` node under the ``scmi``
187node for each supported protocol.
188
189.. note::
190	Zephyr has no support for protocol discovery. As such, if users
191	add a DT node for a certain protocol it's assumed the platform
192	supports said protocol.
193
194The example below shows how a DT may be configured in order to use the
195SCMI support. It's assumed that the only protocol required is the clock
196management protocol.
197
198.. code-block:: devicetree
199
200	#include <mem.h>
201
202	#define MY_CLOCK_CONSUMER_CLK_ID 123
203
204	scmi_res0: memory@cafebabe {
205		/* mandatory to use shared memory driver */
206		compatible = "arm,scmi-shmem";
207		reg = <0xcafebabe DT_SIZE_K(1)>;
208	};
209
210	scmi {
211		/* compatible for shared memory and doorbell-based transport */
212		compatible = "arm,scmi";
213
214		/* one SCMI channel => A2P/transmit channel */
215		shmem = <&scmi_res0>;
216
217		/* two mailbox channels */
218		mboxes = <&my_mbox_ip 0>, <&my_mbox_ip 1>;
219		mbox-names = "tx", "tx_reply";
220
221		scmi_clk: protocol@14 {
222			compatible = "arm,scmi-clock";
223
224			/* matches the clock management protocol ID */
225			reg = <0x14>;
226
227			/* vendor-agnostic - always 1 */
228			#clock-cells = <1>;
229		};
230	};
231
232	my_mbox_ip: mailbox@deadbeef {
233		compatible = "vnd,mbox-ip";
234		reg = <0xdeadbeef DT_SIZE_K(1)>;
235		#mbox-cells = <1>;
236	};
237
238	my_clock_consumer_ip: serial@12345678 {
239		compatible = "vnd,consumer-ip";
240		reg = <0x12345678 DT_SIZE_K(1)>;
241		/* clock ID is vendor specific */
242		clocks = <&scmi_clk MY_CLOCK_CONSUMER_CLK_ID>;
243	};
244
245
246Finally, all that's left to do is enable :kconfig:option:`CONFIG_ARM_SCMI`.
247