xref: /rk3399_ARM-atf/docs/design_documents/psci_osi_mode.rst (revision e706d7ff268a6a5cf3ff000ea7c3867e39047eca)
1*e706d7ffSWing LiPSCI OS-initiated mode
2*e706d7ffSWing Li======================
3*e706d7ffSWing Li
4*e706d7ffSWing Li:Author: Maulik Shah & Wing Li
5*e706d7ffSWing Li:Organization: Qualcomm Innovation Center, Inc. & Google LLC
6*e706d7ffSWing Li:Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
7*e706d7ffSWing Li:Status: RFC
8*e706d7ffSWing Li
9*e706d7ffSWing Li.. contents:: Table of Contents
10*e706d7ffSWing Li
11*e706d7ffSWing LiIntroduction
12*e706d7ffSWing Li------------
13*e706d7ffSWing Li
14*e706d7ffSWing LiPower state coordination
15*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^
16*e706d7ffSWing Li
17*e706d7ffSWing LiA power domain topology is a logical hierarchy of power domains in a system that
18*e706d7ffSWing Liarises from the physical dependencies between power domains.
19*e706d7ffSWing Li
20*e706d7ffSWing LiLocal power states describe power states for an individual node, and composite
21*e706d7ffSWing Lipower states describe the combined power states for an individual node and its
22*e706d7ffSWing Liparent node(s).
23*e706d7ffSWing Li
24*e706d7ffSWing LiEntry into low-power states for a topology node above the core level requires
25*e706d7ffSWing Licoordinating its children nodes. For example, in a system with a power domain
26*e706d7ffSWing Lithat encompasses a shared cache, and a separate power domain for each core that
27*e706d7ffSWing Liuses the shared cache, the core power domains must be powered down before the
28*e706d7ffSWing Lishared cache power domain can be powered down.
29*e706d7ffSWing Li
30*e706d7ffSWing LiPSCI supports two modes of power state coordination: platform-coordinated and
31*e706d7ffSWing LiOS-initiated.
32*e706d7ffSWing Li
33*e706d7ffSWing LiPlatform-coordinated
34*e706d7ffSWing Li~~~~~~~~~~~~~~~~~~~~
35*e706d7ffSWing Li
36*e706d7ffSWing LiPlatform-coordinated mode is the default mode of power state coordination, and
37*e706d7ffSWing Liis currently the only supported mode in TF-A.
38*e706d7ffSWing Li
39*e706d7ffSWing LiIn platform-coordinated mode, the platform is responsible for coordinating power
40*e706d7ffSWing Listates, and chooses the deepest power state for a topology node that can be
41*e706d7ffSWing Litolerated by its children.
42*e706d7ffSWing Li
43*e706d7ffSWing LiOS-initiated
44*e706d7ffSWing Li~~~~~~~~~~~~
45*e706d7ffSWing Li
46*e706d7ffSWing LiOS-initiated mode is optional.
47*e706d7ffSWing Li
48*e706d7ffSWing LiIn OS-initiated mode, the calling OS is responsible for coordinating power
49*e706d7ffSWing Listates, and may request for a topology node to enter a low-power state when
50*e706d7ffSWing Liits last child enters the low-power state.
51*e706d7ffSWing Li
52*e706d7ffSWing LiMotivation
53*e706d7ffSWing Li----------
54*e706d7ffSWing Li
55*e706d7ffSWing LiThere are two reasons why OS-initiated mode might be a more suitable option than
56*e706d7ffSWing Liplatform-coordinated mode for a platform.
57*e706d7ffSWing Li
58*e706d7ffSWing LiScalability
59*e706d7ffSWing Li^^^^^^^^^^^
60*e706d7ffSWing Li
61*e706d7ffSWing LiIn platform-coordinated mode, each core independently selects their own local
62*e706d7ffSWing Lipower states, and doesn't account for composite power states that are shared
63*e706d7ffSWing Libetween cores.
64*e706d7ffSWing Li
65*e706d7ffSWing LiIn OS-initiated mode, the OS has knowledge of the next wakeup event for each
66*e706d7ffSWing Licore, and can have more precise control over the entry, exit, and wakeup
67*e706d7ffSWing Lilatencies when deciding if a composite power state (e.g. for a cluster) is
68*e706d7ffSWing Liappropriate. This is especially important for multi-cluster SMP systems and
69*e706d7ffSWing Liheterogeneous systems like big.LITTLE, where different processor types can have
70*e706d7ffSWing Lidifferent power efficiencies.
71*e706d7ffSWing Li
72*e706d7ffSWing LiSimplicity
73*e706d7ffSWing Li^^^^^^^^^^
74*e706d7ffSWing Li
75*e706d7ffSWing LiIn platform-coordinated mode, the OS doesn't have visibility when the last core
76*e706d7ffSWing Liat a power level enters a low-power state. If the OS wants to perform last man
77*e706d7ffSWing Liactivity (e.g. powering off a shared resource when it is no longer needed), it
78*e706d7ffSWing Liwould have to communicate with an API side channel to know when it can do so.
79*e706d7ffSWing LiThis could result in a design smell where the platform is using
80*e706d7ffSWing Liplatform-coordinated mode when it should be using OS-initiated mode instead.
81*e706d7ffSWing Li
82*e706d7ffSWing LiIn OS-initiated mode, the OS can perform last man activity if it selects a
83*e706d7ffSWing Licomposite power state when the last core enters a low-power state. This
84*e706d7ffSWing Lieliminates the need for a side channel, and uses the well documented API between
85*e706d7ffSWing Lithe OS and the platform.
86*e706d7ffSWing Li
87*e706d7ffSWing LiCurrent vendor implementations and workarounds
88*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89*e706d7ffSWing Li
90*e706d7ffSWing Li* STMicroelectronics
91*e706d7ffSWing Li
92*e706d7ffSWing Li  * For their ARM32 platforms, they're using OS-initiated mode implemented in
93*e706d7ffSWing Li    OP-TEE.
94*e706d7ffSWing Li  * For their future ARM64 platforms, they are interested in using OS-initiated
95*e706d7ffSWing Li    mode in TF-A.
96*e706d7ffSWing Li
97*e706d7ffSWing Li* Qualcomm
98*e706d7ffSWing Li
99*e706d7ffSWing Li  * For their mobile platforms, they're using OS-initiated mode implemented in
100*e706d7ffSWing Li    their own custom secure monitor firmware.
101*e706d7ffSWing Li  * For their Chrome OS platforms, they're using platform-coordinated mode in
102*e706d7ffSWing Li    TF-A with custom driver logic to perform last man activity.
103*e706d7ffSWing Li
104*e706d7ffSWing Li* Google
105*e706d7ffSWing Li
106*e706d7ffSWing Li  * They're using platform-coordinated mode in TF-A with custom driver logic to
107*e706d7ffSWing Li    perform last man activity.
108*e706d7ffSWing Li
109*e706d7ffSWing LiBoth Qualcomm and Google would like to be able to use OS-initiated mode in TF-A
110*e706d7ffSWing Liin order to simplify custom driver logic.
111*e706d7ffSWing Li
112*e706d7ffSWing LiRequirements
113*e706d7ffSWing Li------------
114*e706d7ffSWing Li
115*e706d7ffSWing LiPSCI_FEATURES
116*e706d7ffSWing Li^^^^^^^^^^^^^
117*e706d7ffSWing Li
118*e706d7ffSWing LiPSCI_FEATURES is for checking whether or not a PSCI function is implemented and
119*e706d7ffSWing Liwhat its properties are.
120*e706d7ffSWing Li
121*e706d7ffSWing Li.. c:macro:: PSCI_FEATURES
122*e706d7ffSWing Li
123*e706d7ffSWing Li   :param func_id: 0x8400_000A.
124*e706d7ffSWing Li   :param psci_func_id: the function ID of a PSCI function.
125*e706d7ffSWing Li   :retval NOT_SUPPORTED: if the function is not implemented.
126*e706d7ffSWing Li   :retval feature flags associated with the function: if the function is
127*e706d7ffSWing Li       implemented.
128*e706d7ffSWing Li
129*e706d7ffSWing LiCPU_SUSPEND feature flags
130*e706d7ffSWing Li~~~~~~~~~~~~~~~~~~~~~~~~~
131*e706d7ffSWing Li
132*e706d7ffSWing Li* Reserved, bits[31:2]
133*e706d7ffSWing Li* Power state parameter format, bit[1]
134*e706d7ffSWing Li
135*e706d7ffSWing Li  * A value of 0 indicates the original format is used.
136*e706d7ffSWing Li  * A value of 1 indicates the extended format is used.
137*e706d7ffSWing Li
138*e706d7ffSWing Li* OS-initiated mode, bit[0]
139*e706d7ffSWing Li
140*e706d7ffSWing Li  * A value of 0 indicates OS-initiated mode is not supported.
141*e706d7ffSWing Li  * A value of 1 indicates OS-initiated mode is supported.
142*e706d7ffSWing Li
143*e706d7ffSWing LiSee sections 5.1.14 and 5.15 of the PSCI spec (DEN0022D.b) for more details.
144*e706d7ffSWing Li
145*e706d7ffSWing LiPSCI_SET_SUSPEND_MODE
146*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^
147*e706d7ffSWing Li
148*e706d7ffSWing LiPSCI_SET_SUSPEND_MODE is for switching between the two different modes of power
149*e706d7ffSWing Listate coordination.
150*e706d7ffSWing Li
151*e706d7ffSWing Li.. c:macro:: PSCI_SET_SUSPEND_MODE
152*e706d7ffSWing Li
153*e706d7ffSWing Li   :param func_id: 0x8400_000F.
154*e706d7ffSWing Li   :param mode: 0 indicates platform-coordinated mode, 1 indicates OS-initiated
155*e706d7ffSWing Li       mode.
156*e706d7ffSWing Li   :retval SUCCESS: if the request is successful.
157*e706d7ffSWing Li   :retval NOT_SUPPORTED: if OS-initiated mode is not supported.
158*e706d7ffSWing Li   :retval INVALID_PARAMETERS: if the requested mode is not a valid value (0 or
159*e706d7ffSWing Li       1).
160*e706d7ffSWing Li   :retval DENIED: if the cores are not in the correct state.
161*e706d7ffSWing Li
162*e706d7ffSWing LiSwitching from platform-coordinated to OS-initiated is only allowed if the
163*e706d7ffSWing Lifollowing conditions are met:
164*e706d7ffSWing Li
165*e706d7ffSWing Li* All cores are in one of the following states:
166*e706d7ffSWing Li
167*e706d7ffSWing Li  * Running.
168*e706d7ffSWing Li  * Off, through a call to CPU_OFF or not yet booted.
169*e706d7ffSWing Li  * Suspended, through a call to CPU_DEFAULT_SUSPEND.
170*e706d7ffSWing Li
171*e706d7ffSWing Li* None of the cores has called CPU_SUSPEND since the last change of mode or
172*e706d7ffSWing Li  boot.
173*e706d7ffSWing Li
174*e706d7ffSWing LiSwitching from OS-initiated to platform-coordinated is only allowed if all cores
175*e706d7ffSWing Liother than the calling core are off, either through a call to CPU_OFF or not yet
176*e706d7ffSWing Libooted.
177*e706d7ffSWing Li
178*e706d7ffSWing LiIf these conditions are not met, the PSCI implementation must return DENIED.
179*e706d7ffSWing Li
180*e706d7ffSWing LiSee sections 5.1.19 and 5.20 of the PSCI spec (DEN0022D.b) for more details.
181*e706d7ffSWing Li
182*e706d7ffSWing LiCPU_SUSPEND
183*e706d7ffSWing Li^^^^^^^^^^^
184*e706d7ffSWing Li
185*e706d7ffSWing LiCPU_SUSPEND is for moving a topology node into a low-power state.
186*e706d7ffSWing Li
187*e706d7ffSWing Li.. c:macro:: CPU_SUSPEND
188*e706d7ffSWing Li
189*e706d7ffSWing Li   :param func_id: 0xC400_0001.
190*e706d7ffSWing Li   :param power_state: the requested low-power state to enter.
191*e706d7ffSWing Li   :param entry_point_address: the address at which the core must resume
192*e706d7ffSWing Li       execution following wakeup from a powerdown state.
193*e706d7ffSWing Li   :param context_id: this field specifies a pointer to the saved context that
194*e706d7ffSWing Li       must be restored on a core following wakeup from a powerdown state.
195*e706d7ffSWing Li   :retval SUCCESS: if the request is successful.
196*e706d7ffSWing Li   :retval INVALID_PARAMETERS: in OS-initiated mode, this error is returned when
197*e706d7ffSWing Li       a low-power state is requested for a topology node above the core level,
198*e706d7ffSWing Li       and at least one of the node's children is in a local low-power state
199*e706d7ffSWing Li       that is incompatible with the request.
200*e706d7ffSWing Li   :retval INVALID_ADDRESS: if the entry_point_address argument is invalid.
201*e706d7ffSWing Li   :retval DENIED: only in OS-initiated mode; this error is returned when a
202*e706d7ffSWing Li       low-power state is requested for a topology node above the core level,
203*e706d7ffSWing Li       and at least one of the node's children is running, i.e. not in a
204*e706d7ffSWing Li       low-power state.
205*e706d7ffSWing Li
206*e706d7ffSWing LiIn platform-coordinated mode, the PSCI implementation coordinates requests from
207*e706d7ffSWing Liall cores to determine the deepest power state to enter.
208*e706d7ffSWing Li
209*e706d7ffSWing LiIn OS-initiated mode, the calling OS is making an explicit request for a
210*e706d7ffSWing Lispecific power state, as opposed to expressing a vote. The PSCI implementation
211*e706d7ffSWing Limust comply with the request, unless the request is not consistent with the
212*e706d7ffSWing Liimplementation's view of the system's state, in which case, the implementation
213*e706d7ffSWing Limust return INVALID_PARAMETERS or DENIED.
214*e706d7ffSWing Li
215*e706d7ffSWing LiSee sections 5.1.2 and 5.4 of the PSCI spec (DEN0022D.b) for more details.
216*e706d7ffSWing Li
217*e706d7ffSWing LiPower state formats
218*e706d7ffSWing Li~~~~~~~~~~~~~~~~~~~
219*e706d7ffSWing Li
220*e706d7ffSWing LiOriginal format
221*e706d7ffSWing Li
222*e706d7ffSWing Li* Power Level, bits[25:24]
223*e706d7ffSWing Li
224*e706d7ffSWing Li  * The requested level in the power domain topology to enter a low-power
225*e706d7ffSWing Li    state.
226*e706d7ffSWing Li
227*e706d7ffSWing Li* State Type, bit[16]
228*e706d7ffSWing Li
229*e706d7ffSWing Li  * A value of 0 indicates a standby or retention state.
230*e706d7ffSWing Li  * A value of 1 indicates a powerdown state.
231*e706d7ffSWing Li
232*e706d7ffSWing Li* State ID, bits[15:0]
233*e706d7ffSWing Li
234*e706d7ffSWing Li  * Field to specify the requested composite power state.
235*e706d7ffSWing Li  * The state ID encodings must uniquely describe every possible composite
236*e706d7ffSWing Li    power state.
237*e706d7ffSWing Li  * In OS-initiated mode, the state ID encoding must allow expressing the
238*e706d7ffSWing Li    power level at which the calling core is the last to enter a powerdown
239*e706d7ffSWing Li    state.
240*e706d7ffSWing Li
241*e706d7ffSWing LiExtended format
242*e706d7ffSWing Li
243*e706d7ffSWing Li* State Type, bit[30]
244*e706d7ffSWing Li* State ID, bits[27:0]
245*e706d7ffSWing Li
246*e706d7ffSWing LiRaces in OS-initiated mode
247*e706d7ffSWing Li~~~~~~~~~~~~~~~~~~~~~~~~~~
248*e706d7ffSWing Li
249*e706d7ffSWing LiIn OS-initiated mode, there are race windows where the OS's view and
250*e706d7ffSWing Liimplementation's view of the system's state differ. It is possible for the OS to
251*e706d7ffSWing Limake requests that are invalid given the implementation's view of the system's
252*e706d7ffSWing Listate. For example, the OS might request a powerdown state for a node from one
253*e706d7ffSWing Licore, while at the same time, the implementation observes that another core in
254*e706d7ffSWing Lithat node is powering up.
255*e706d7ffSWing Li
256*e706d7ffSWing LiTo address potential race conditions in power state requests:
257*e706d7ffSWing Li
258*e706d7ffSWing Li* The calling OS must specify in each CPU_SUSPEND request the deepest power
259*e706d7ffSWing Li  level for which it sees the calling core as the last running core (last man).
260*e706d7ffSWing Li  This is required even if the OS doesn't want the node at that power level to
261*e706d7ffSWing Li  enter a low-power state.
262*e706d7ffSWing Li* The implementation must validate that the requested power states in the
263*e706d7ffSWing Li  CPU_SUSPEND request are consistent with the system's state, and that the
264*e706d7ffSWing Li  calling core is the last core running at the requested power level, or deny
265*e706d7ffSWing Li  the request otherwise.
266*e706d7ffSWing Li
267*e706d7ffSWing LiSee sections 4.2.3.2, 6.2, and 6.3 of the PSCI spec (DEN0022D.b) for more
268*e706d7ffSWing Lidetails.
269*e706d7ffSWing Li
270*e706d7ffSWing LiCaveats
271*e706d7ffSWing Li-------
272*e706d7ffSWing Li
273*e706d7ffSWing LiCPU_OFF
274*e706d7ffSWing Li^^^^^^^
275*e706d7ffSWing Li
276*e706d7ffSWing LiCPU_OFF is always platform-coordinated, regardless of whether the power state
277*e706d7ffSWing Licoordination mode for suspend is platform-coordinated or OS-initiated. If all
278*e706d7ffSWing Licores in a topology node call CPU_OFF, the last core will power down the node.
279*e706d7ffSWing Li
280*e706d7ffSWing LiIn OS-initiated mode, if a subset of the cores in a topology node has called
281*e706d7ffSWing LiCPU_OFF, the last running core may call CPU_SUSPEND to request a powerdown state
282*e706d7ffSWing Liat or above that node's power level.
283*e706d7ffSWing Li
284*e706d7ffSWing LiSee section 5.5.2 of the PSCI spec (DEN0022D.b) for more details.
285*e706d7ffSWing Li
286*e706d7ffSWing LiImplementation
287*e706d7ffSWing Li--------------
288*e706d7ffSWing Li
289*e706d7ffSWing LiCurrent implementation of platform-coordinated mode
290*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
291*e706d7ffSWing Li
292*e706d7ffSWing LiPlatform-coordinated is currently the only supported power state coordination
293*e706d7ffSWing Limode in TF-A.
294*e706d7ffSWing Li
295*e706d7ffSWing LiThe functions of interest in the ``psci_cpu_suspend`` call stack are as follows:
296*e706d7ffSWing Li
297*e706d7ffSWing Li* ``psci_validate_power_state``
298*e706d7ffSWing Li
299*e706d7ffSWing Li  * This function calls a platform specific ``validate_power_state`` handler,
300*e706d7ffSWing Li    which takes the ``power_state`` parameter, and updates the ``state_info``
301*e706d7ffSWing Li    object with the requested states for each power level.
302*e706d7ffSWing Li
303*e706d7ffSWing Li* ``psci_find_target_suspend_lvl``
304*e706d7ffSWing Li
305*e706d7ffSWing Li  * This function takes the ``state_info`` object containing the requested power
306*e706d7ffSWing Li    states for each power level, and returns the deepest power level that was
307*e706d7ffSWing Li    requested to enter a low power state, i.e. the target power level.
308*e706d7ffSWing Li
309*e706d7ffSWing Li* ``psci_do_state_coordination``
310*e706d7ffSWing Li
311*e706d7ffSWing Li  * This function takes the target power level and the ``state_info`` object
312*e706d7ffSWing Li    containing the requested power states for each power level, and updates the
313*e706d7ffSWing Li    ``state_info`` object with the coordinated target power state for each
314*e706d7ffSWing Li    level.
315*e706d7ffSWing Li
316*e706d7ffSWing Li* ``pwr_domain_suspend``
317*e706d7ffSWing Li
318*e706d7ffSWing Li  * This is a platform specific handler that takes the ``state_info`` object
319*e706d7ffSWing Li    containing the target power states for each power level, and transitions
320*e706d7ffSWing Li    each power level to the specified power state.
321*e706d7ffSWing Li
322*e706d7ffSWing LiProposed implementation of OS-initiated mode
323*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
324*e706d7ffSWing Li
325*e706d7ffSWing LiTo add support for OS-initiated mode, the following changes are proposed:
326*e706d7ffSWing Li
327*e706d7ffSWing Li* Add a boolean build option ``PSCI_OS_INIT_MODE`` for a platform to enable
328*e706d7ffSWing Li  optional support for PSCI OS-initiated mode. This build option defaults to 0.
329*e706d7ffSWing Li
330*e706d7ffSWing Li.. note::
331*e706d7ffSWing Li
332*e706d7ffSWing Li   If ``PSCI_OS_INIT_MODE=0``, the following changes will not be compiled into
333*e706d7ffSWing Li   the build.
334*e706d7ffSWing Li
335*e706d7ffSWing Li* Update ``psci_features`` to return 1 in bit[0] to indicate support for
336*e706d7ffSWing Li  OS-initiated mode for CPU_SUSPEND.
337*e706d7ffSWing Li* Define a ``suspend_mode`` enum: ``PLAT_COORD`` and ``OS_INIT``.
338*e706d7ffSWing Li* Define a ``psci_suspend_mode`` global variable with a default value of
339*e706d7ffSWing Li  ``PLAT_COORD``.
340*e706d7ffSWing Li* Implement a new function handler ``psci_set_suspend_mode`` for
341*e706d7ffSWing Li  PSCI_SET_SUSPEND_MODE.
342*e706d7ffSWing Li* Since ``psci_validate_power_state`` calls a platform specific
343*e706d7ffSWing Li  ``validate_power_state`` handler, the platform implementation should populate
344*e706d7ffSWing Li  the ``state_info`` object based on the state ID from the given ``power_state``
345*e706d7ffSWing Li  parameter.
346*e706d7ffSWing Li* ``psci_find_target_suspend_lvl`` remains unchanged.
347*e706d7ffSWing Li* Implement a new function ``psci_validate_state_coordination`` that ensures the
348*e706d7ffSWing Li  request satisfies the following conditions, and denies any requests
349*e706d7ffSWing Li  that don't:
350*e706d7ffSWing Li
351*e706d7ffSWing Li  * The requested power states for each power level are consistent with the
352*e706d7ffSWing Li    system's state
353*e706d7ffSWing Li  * The calling core is the last core running at the requested power level
354*e706d7ffSWing Li
355*e706d7ffSWing Li  This function differs from ``psci_do_state_coordination`` in that:
356*e706d7ffSWing Li
357*e706d7ffSWing Li  * The ``psci_req_local_pwr_states`` map is not modified if the request were to
358*e706d7ffSWing Li    be denied
359*e706d7ffSWing Li  * The ``state_info`` argument is never modified since it contains the power
360*e706d7ffSWing Li    states requested by the calling OS
361*e706d7ffSWing Li
362*e706d7ffSWing Li* Update ``psci_cpu_suspend_start`` to do the following:
363*e706d7ffSWing Li
364*e706d7ffSWing Li  * If ``PSCI_SUSPEND_MODE`` is ``PLAT_COORD``, call
365*e706d7ffSWing Li    ``psci_do_state_coordination``.
366*e706d7ffSWing Li  * If ``PSCI_SUSPEND_MODE`` is ``OS_INIT``, call
367*e706d7ffSWing Li    ``psci_validate_state_coordination``. If validation fails, propagate the
368*e706d7ffSWing Li    error up the call stack.
369*e706d7ffSWing Li
370*e706d7ffSWing Li* Update the return type of the platform specific ``pwr_domain_suspend``
371*e706d7ffSWing Li  handler from ``void`` to ``int``, to allow the platform to optionally perform
372*e706d7ffSWing Li  validations based on hardware states.
373*e706d7ffSWing Li
374*e706d7ffSWing Li.. image:: ../resources/diagrams/psci-osi-mode.png
375*e706d7ffSWing Li
376*e706d7ffSWing LiTesting
377*e706d7ffSWing Li-------
378*e706d7ffSWing Li
379*e706d7ffSWing LiThe proposed patches can be found at
380*e706d7ffSWing Lihttps://review.trustedfirmware.org/q/topic:psci-osi.
381*e706d7ffSWing Li
382*e706d7ffSWing LiTesting on FVP and Google platforms
383*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
384*e706d7ffSWing Li
385*e706d7ffSWing LiThe proposed patches add a new CPU Suspend in OSI mode test suite to TF-A Tests.
386*e706d7ffSWing LiThis has been enabled and verified on the FVP_Base_RevC-2xAEMvA platform and
387*e706d7ffSWing LiGoogle platforms, and excluded from all other platforms via the build option
388*e706d7ffSWing Li``PLAT_TESTS_SKIP_LIST``.
389*e706d7ffSWing Li
390*e706d7ffSWing LiTesting on STM32MP15
391*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^
392*e706d7ffSWing Li
393*e706d7ffSWing LiThe proposed patches have been tested and verified on the STM32MP15 platform,
394*e706d7ffSWing Liwhich has a single cluster with 2 CPUs, by Gabriel Fernandez
395*e706d7ffSWing Li<gabriel.fernandez@st.com> from STMicroelectronics with this device tree
396*e706d7ffSWing Liconfiguration:
397*e706d7ffSWing Li
398*e706d7ffSWing Li.. code-block:: devicetree
399*e706d7ffSWing Li
400*e706d7ffSWing Li   cpus {
401*e706d7ffSWing Li           #address-cells = <1>;
402*e706d7ffSWing Li           #size-cells = <0>;
403*e706d7ffSWing Li
404*e706d7ffSWing Li           cpu0: cpu@0 {
405*e706d7ffSWing Li                   device_type = "cpu";
406*e706d7ffSWing Li                   compatible = "arm,cortex-a7";
407*e706d7ffSWing Li                   reg = <0>;
408*e706d7ffSWing Li                   enable-method = "psci";
409*e706d7ffSWing Li                   power-domains = <&CPU_PD0>;
410*e706d7ffSWing Li                   power-domain-names = "psci";
411*e706d7ffSWing Li           };
412*e706d7ffSWing Li           cpu1: cpu@1 {
413*e706d7ffSWing Li                   device_type = "cpu";
414*e706d7ffSWing Li                   compatible = "arm,cortex-a7";
415*e706d7ffSWing Li                   reg = <1>;
416*e706d7ffSWing Li                   enable-method = "psci";
417*e706d7ffSWing Li                   power-domains = <&CPU_PD1>;
418*e706d7ffSWing Li                   power-domain-names = "psci";
419*e706d7ffSWing Li           };
420*e706d7ffSWing Li
421*e706d7ffSWing Li           idle-states {
422*e706d7ffSWing Li                   cpu_retention: cpu-retention {
423*e706d7ffSWing Li                           compatible = "arm,idle-state";
424*e706d7ffSWing Li                           arm,psci-suspend-param = <0x00000001>;
425*e706d7ffSWing Li                           entry-latency-us = <130>;
426*e706d7ffSWing Li                           exit-latency-us = <620>;
427*e706d7ffSWing Li                           min-residency-us = <700>;
428*e706d7ffSWing Li                           local-timer-stop;
429*e706d7ffSWing Li                   };
430*e706d7ffSWing Li           };
431*e706d7ffSWing Li
432*e706d7ffSWing Li           domain-idle-states {
433*e706d7ffSWing Li                   CLUSTER_STOP: core-power-domain {
434*e706d7ffSWing Li                           compatible = "domain-idle-state";
435*e706d7ffSWing Li                           arm,psci-suspend-param = <0x01000001>;
436*e706d7ffSWing Li                           entry-latency-us = <230>;
437*e706d7ffSWing Li                           exit-latency-us = <720>;
438*e706d7ffSWing Li                           min-residency-us = <2000>;
439*e706d7ffSWing Li                           local-timer-stop;
440*e706d7ffSWing Li                   };
441*e706d7ffSWing Li           };
442*e706d7ffSWing Li   };
443*e706d7ffSWing Li
444*e706d7ffSWing Li   psci {
445*e706d7ffSWing Li           compatible = "arm,psci-1.0";
446*e706d7ffSWing Li           method = "smc";
447*e706d7ffSWing Li
448*e706d7ffSWing Li           CPU_PD0: power-domain-cpu0 {
449*e706d7ffSWing Li                   #power-domain-cells = <0>;
450*e706d7ffSWing Li                   power-domains = <&pd_core>;
451*e706d7ffSWing Li                   domain-idle-states = <&cpu_retention>;
452*e706d7ffSWing Li           };
453*e706d7ffSWing Li
454*e706d7ffSWing Li           CPU_PD1: power-domain-cpu1 {
455*e706d7ffSWing Li                   #power-domain-cells = <0>;
456*e706d7ffSWing Li                   power-domains = <&pd_core>;
457*e706d7ffSWing Li                   domain-idle-states = <&cpu_retention>;
458*e706d7ffSWing Li           };
459*e706d7ffSWing Li
460*e706d7ffSWing Li           pd_core: power-domain-cluster {
461*e706d7ffSWing Li                   #power-domain-cells = <0>;
462*e706d7ffSWing Li                   domain-idle-states = <&CLUSTER_STOP>;
463*e706d7ffSWing Li           };
464*e706d7ffSWing Li   };
465*e706d7ffSWing Li
466*e706d7ffSWing LiTesting on Qualcomm SC7280
467*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^
468*e706d7ffSWing Li
469*e706d7ffSWing LiThe proposed patches have been tested and verified on the SC7280 platform by
470*e706d7ffSWing LiMaulik Shah <quic_mkshah@quicinc.com> from Qualcomm with this device tree
471*e706d7ffSWing Liconfiguration:
472*e706d7ffSWing Li
473*e706d7ffSWing Li.. code-block:: devicetree
474*e706d7ffSWing Li
475*e706d7ffSWing Li   cpus {
476*e706d7ffSWing Li           #address-cells = <2>;
477*e706d7ffSWing Li           #size-cells = <0>;
478*e706d7ffSWing Li
479*e706d7ffSWing Li           CPU0: cpu@0 {
480*e706d7ffSWing Li                   device_type = "cpu";
481*e706d7ffSWing Li                   compatible = "arm,kryo";
482*e706d7ffSWing Li                   reg = <0x0 0x0>;
483*e706d7ffSWing Li                   enable-method = "psci";
484*e706d7ffSWing Li                   power-domains = <&CPU_PD0>;
485*e706d7ffSWing Li                   power-domain-names = "psci";
486*e706d7ffSWing Li           };
487*e706d7ffSWing Li
488*e706d7ffSWing Li           CPU1: cpu@100 {
489*e706d7ffSWing Li                   device_type = "cpu";
490*e706d7ffSWing Li                   compatible = "arm,kryo";
491*e706d7ffSWing Li                   reg = <0x0 0x100>;
492*e706d7ffSWing Li                   enable-method = "psci";
493*e706d7ffSWing Li                   power-domains = <&CPU_PD1>;
494*e706d7ffSWing Li                   power-domain-names = "psci";
495*e706d7ffSWing Li           };
496*e706d7ffSWing Li
497*e706d7ffSWing Li           CPU2: cpu@200 {
498*e706d7ffSWing Li                   device_type = "cpu";
499*e706d7ffSWing Li                   compatible = "arm,kryo";
500*e706d7ffSWing Li                   reg = <0x0 0x200>;
501*e706d7ffSWing Li                   enable-method = "psci";
502*e706d7ffSWing Li                   power-domains = <&CPU_PD2>;
503*e706d7ffSWing Li                   power-domain-names = "psci";
504*e706d7ffSWing Li           };
505*e706d7ffSWing Li
506*e706d7ffSWing Li           CPU3: cpu@300 {
507*e706d7ffSWing Li                   device_type = "cpu";
508*e706d7ffSWing Li                   compatible = "arm,kryo";
509*e706d7ffSWing Li                   reg = <0x0 0x300>;
510*e706d7ffSWing Li                   enable-method = "psci";
511*e706d7ffSWing Li                   power-domains = <&CPU_PD3>;
512*e706d7ffSWing Li                   power-domain-names = "psci";
513*e706d7ffSWing Li           }
514*e706d7ffSWing Li
515*e706d7ffSWing Li           CPU4: cpu@400 {
516*e706d7ffSWing Li                   device_type = "cpu";
517*e706d7ffSWing Li                   compatible = "arm,kryo";
518*e706d7ffSWing Li                   reg = <0x0 0x400>;
519*e706d7ffSWing Li                   enable-method = "psci";
520*e706d7ffSWing Li                   power-domains = <&CPU_PD4>;
521*e706d7ffSWing Li                   power-domain-names = "psci";
522*e706d7ffSWing Li           };
523*e706d7ffSWing Li
524*e706d7ffSWing Li           CPU5: cpu@500 {
525*e706d7ffSWing Li                   device_type = "cpu";
526*e706d7ffSWing Li                   compatible = "arm,kryo";
527*e706d7ffSWing Li                   reg = <0x0 0x500>;
528*e706d7ffSWing Li                   enable-method = "psci";
529*e706d7ffSWing Li                   power-domains = <&CPU_PD5>;
530*e706d7ffSWing Li                   power-domain-names = "psci";
531*e706d7ffSWing Li           };
532*e706d7ffSWing Li
533*e706d7ffSWing Li           CPU6: cpu@600 {
534*e706d7ffSWing Li                   device_type = "cpu";
535*e706d7ffSWing Li                   compatible = "arm,kryo";
536*e706d7ffSWing Li                   reg = <0x0 0x600>;
537*e706d7ffSWing Li                   enable-method = "psci";
538*e706d7ffSWing Li                   power-domains = <&CPU_PD6>;
539*e706d7ffSWing Li                   power-domain-names = "psci";
540*e706d7ffSWing Li           };
541*e706d7ffSWing Li
542*e706d7ffSWing Li           CPU7: cpu@700 {
543*e706d7ffSWing Li                   device_type = "cpu";
544*e706d7ffSWing Li                   compatible = "arm,kryo";
545*e706d7ffSWing Li                   reg = <0x0 0x700>;
546*e706d7ffSWing Li                   enable-method = "psci";
547*e706d7ffSWing Li                   power-domains = <&CPU_PD7>;
548*e706d7ffSWing Li                   power-domain-names = "psci";
549*e706d7ffSWing Li           };
550*e706d7ffSWing Li
551*e706d7ffSWing Li           idle-states {
552*e706d7ffSWing Li                   entry-method = "psci";
553*e706d7ffSWing Li
554*e706d7ffSWing Li                   LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
555*e706d7ffSWing Li                           compatible = "arm,idle-state";
556*e706d7ffSWing Li                           idle-state-name = "little-power-down";
557*e706d7ffSWing Li                           arm,psci-suspend-param = <0x40000003>;
558*e706d7ffSWing Li                           entry-latency-us = <549>;
559*e706d7ffSWing Li                           exit-latency-us = <901>;
560*e706d7ffSWing Li                           min-residency-us = <1774>;
561*e706d7ffSWing Li                           local-timer-stop;
562*e706d7ffSWing Li                   };
563*e706d7ffSWing Li
564*e706d7ffSWing Li                   LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 {
565*e706d7ffSWing Li                           compatible = "arm,idle-state";
566*e706d7ffSWing Li                           idle-state-name = "little-rail-power-down";
567*e706d7ffSWing Li                           arm,psci-suspend-param = <0x40000004>;
568*e706d7ffSWing Li                           entry-latency-us = <702>;
569*e706d7ffSWing Li                           exit-latency-us = <915>;
570*e706d7ffSWing Li                           min-residency-us = <4001>;
571*e706d7ffSWing Li                           local-timer-stop;
572*e706d7ffSWing Li                   };
573*e706d7ffSWing Li
574*e706d7ffSWing Li                   BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
575*e706d7ffSWing Li                           compatible = "arm,idle-state";
576*e706d7ffSWing Li                           idle-state-name = "big-power-down";
577*e706d7ffSWing Li                           arm,psci-suspend-param = <0x40000003>;
578*e706d7ffSWing Li                           entry-latency-us = <523>;
579*e706d7ffSWing Li                           exit-latency-us = <1244>;
580*e706d7ffSWing Li                           min-residency-us = <2207>;
581*e706d7ffSWing Li                           local-timer-stop;
582*e706d7ffSWing Li                   };
583*e706d7ffSWing Li
584*e706d7ffSWing Li                   BIG_CPU_SLEEP_1: cpu-sleep-1-1 {
585*e706d7ffSWing Li                           compatible = "arm,idle-state";
586*e706d7ffSWing Li                           idle-state-name = "big-rail-power-down";
587*e706d7ffSWing Li                           arm,psci-suspend-param = <0x40000004>;
588*e706d7ffSWing Li                           entry-latency-us = <526>;
589*e706d7ffSWing Li                           exit-latency-us = <1854>;
590*e706d7ffSWing Li                           min-residency-us = <5555>;
591*e706d7ffSWing Li                           local-timer-stop;
592*e706d7ffSWing Li                   };
593*e706d7ffSWing Li           };
594*e706d7ffSWing Li
595*e706d7ffSWing Li           domain-idle-states {
596*e706d7ffSWing Li                   CLUSTER_SLEEP_0: cluster-sleep-0 {
597*e706d7ffSWing Li                           compatible = "arm,idle-state";
598*e706d7ffSWing Li                           idle-state-name = "cluster-power-down";
599*e706d7ffSWing Li                           arm,psci-suspend-param = <0x40003444>;
600*e706d7ffSWing Li                           entry-latency-us = <3263>;
601*e706d7ffSWing Li                           exit-latency-us = <6562>;
602*e706d7ffSWing Li                           min-residency-us = <9926>;
603*e706d7ffSWing Li                           local-timer-stop;
604*e706d7ffSWing Li                   };
605*e706d7ffSWing Li           };
606*e706d7ffSWing Li   };
607*e706d7ffSWing Li
608*e706d7ffSWing Li   psci {
609*e706d7ffSWing Li           compatible = "arm,psci-1.0";
610*e706d7ffSWing Li           method = "smc";
611*e706d7ffSWing Li
612*e706d7ffSWing Li           CPU_PD0: cpu0 {
613*e706d7ffSWing Li                   #power-domain-cells = <0>;
614*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
615*e706d7ffSWing Li                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
616*e706d7ffSWing Li           };
617*e706d7ffSWing Li
618*e706d7ffSWing Li           CPU_PD1: cpu1 {
619*e706d7ffSWing Li                   #power-domain-cells = <0>;
620*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
621*e706d7ffSWing Li                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
622*e706d7ffSWing Li           };
623*e706d7ffSWing Li
624*e706d7ffSWing Li           CPU_PD2: cpu2 {
625*e706d7ffSWing Li                   #power-domain-cells = <0>;
626*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
627*e706d7ffSWing Li                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
628*e706d7ffSWing Li           };
629*e706d7ffSWing Li
630*e706d7ffSWing Li           CPU_PD3: cpu3 {
631*e706d7ffSWing Li                   #power-domain-cells = <0>;
632*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
633*e706d7ffSWing Li                   domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
634*e706d7ffSWing Li           };
635*e706d7ffSWing Li
636*e706d7ffSWing Li           CPU_PD4: cpu4 {
637*e706d7ffSWing Li                   #power-domain-cells = <0>;
638*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
639*e706d7ffSWing Li                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
640*e706d7ffSWing Li           };
641*e706d7ffSWing Li
642*e706d7ffSWing Li           CPU_PD5: cpu5 {
643*e706d7ffSWing Li                   #power-domain-cells = <0>;
644*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
645*e706d7ffSWing Li                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
646*e706d7ffSWing Li           };
647*e706d7ffSWing Li
648*e706d7ffSWing Li           CPU_PD6: cpu6 {
649*e706d7ffSWing Li                   #power-domain-cells = <0>;
650*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
651*e706d7ffSWing Li                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
652*e706d7ffSWing Li           };
653*e706d7ffSWing Li
654*e706d7ffSWing Li           CPU_PD7: cpu7 {
655*e706d7ffSWing Li                   #power-domain-cells = <0>;
656*e706d7ffSWing Li                   power-domains = <&CLUSTER_PD>;
657*e706d7ffSWing Li                   domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
658*e706d7ffSWing Li           };
659*e706d7ffSWing Li
660*e706d7ffSWing Li           CLUSTER_PD: cpu-cluster0 {
661*e706d7ffSWing Li                   #power-domain-cells = <0>;
662*e706d7ffSWing Li                   domain-idle-states = <&CLUSTER_SLEEP_0>;
663*e706d7ffSWing Li           };
664*e706d7ffSWing Li   };
665*e706d7ffSWing Li
666*e706d7ffSWing LiComparisons on Qualcomm SC7280
667*e706d7ffSWing Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
668*e706d7ffSWing Li
669*e706d7ffSWing LiCPUIdle states
670*e706d7ffSWing Li~~~~~~~~~~~~~~
671*e706d7ffSWing Li
672*e706d7ffSWing Li* 8 CPUs, 1 L3 cache
673*e706d7ffSWing Li* Platform-coordinated mode
674*e706d7ffSWing Li
675*e706d7ffSWing Li  * CPUIdle states
676*e706d7ffSWing Li
677*e706d7ffSWing Li    * State0 - WFI
678*e706d7ffSWing Li    * State1 - Core collapse
679*e706d7ffSWing Li    * State2 - Rail collapse
680*e706d7ffSWing Li    * State3 - L3 cache off and system resources voted off
681*e706d7ffSWing Li
682*e706d7ffSWing Li* OS-initiated mode
683*e706d7ffSWing Li
684*e706d7ffSWing Li  * CPUIdle states
685*e706d7ffSWing Li
686*e706d7ffSWing Li    * State0 - WFI
687*e706d7ffSWing Li    * State1 - Core collapse
688*e706d7ffSWing Li    * State2 - Rail collapse
689*e706d7ffSWing Li
690*e706d7ffSWing Li  * Cluster domain idle state
691*e706d7ffSWing Li
692*e706d7ffSWing Li    * State3 - L3 cache off and system resources voted off
693*e706d7ffSWing Li
694*e706d7ffSWing Li.. image:: ../resources/diagrams/psci-flattened-vs-hierarchical-idle-states.png
695*e706d7ffSWing Li
696*e706d7ffSWing LiResults
697*e706d7ffSWing Li~~~~~~~
698*e706d7ffSWing Li
699*e706d7ffSWing Li* The following stats have been captured with fixed CPU frequencies from the use
700*e706d7ffSWing Li  case of 10 seconds of device idle with the display turned on and Wi-Fi and
701*e706d7ffSWing Li  modem turned off.
702*e706d7ffSWing Li* Count refers to the number of times a CPU or cluster entered power collapse.
703*e706d7ffSWing Li* Residency refers to the time in seconds a CPU or cluster stayed in power
704*e706d7ffSWing Li  collapse.
705*e706d7ffSWing Li* The results are an average of 3 iterations of actual counts and residencies.
706*e706d7ffSWing Li
707*e706d7ffSWing Li.. image:: ../resources/diagrams/psci-pc-mode-vs-osi-mode.png
708*e706d7ffSWing Li
709*e706d7ffSWing LiOS-initiated mode was able to scale better than platform-coordinated mode for
710*e706d7ffSWing Limultiple CPUs. The count and residency results for state3 (i.e. a cluster domain
711*e706d7ffSWing Liidle state) in OS-initiated mode for multiple CPUs were much closer to the
712*e706d7ffSWing Liresults for a single CPU than in platform-coordinated mode.
713*e706d7ffSWing Li
714*e706d7ffSWing Li--------------
715*e706d7ffSWing Li
716*e706d7ffSWing Li*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
717