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