# Include/Guid/ArmMpCoreInfo.h\r
gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }\r
\r
+[Protocols.common]\r
+ ## Arm System Control and Management Interface(SCMI) Base protocol\r
+ ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h\r
+ gArmScmiBaseProtocolGuid = { 0xd7e5abe9, 0x33ab, 0x418e, { 0x9f, 0x91, 0x72, 0xda, 0xe2, 0xba, 0x8e, 0x2f } }\r
+\r
+ ## Arm System Control and Management Interface(SCMI) Clock management protocol\r
+ ## ArmPkg/Include/Protocol/ArmScmiClockProtocol.h\r
+ gArmScmiClockProtocolGuid = { 0x91ce67a8, 0xe0aa, 0x4012, { 0xb9, 0x9f, 0xb6, 0xfc, 0xf3, 0x4, 0x8e, 0xaa } }\r
+\r
+ ## Arm System Control and Management Interface(SCMI) Clock management protocol\r
+ ## ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h\r
+ gArmScmiPerformanceProtocolGuid = { 0x9b8ba84, 0x3dd3, 0x49a6, { 0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b, 0xad } }\r
+\r
[Ppis]\r
## Include/Ppi/ArmMpCoreInfo.h\r
gArmMpCoreInfoPpiGuid = { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} }\r
# ARM processor package.\r
#\r
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>\r
-# Copyright (c) 2011 - 2015, ARM Ltd. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>\r
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf\r
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf\r
\r
+ ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf\r
+\r
[LibraryClasses.common.PEIM]\r
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf\r
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf\r
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf\r
\r
+ ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf\r
+\r
[Components.AARCH64]\r
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_\r
+#define ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_\r
+\r
+// Return values of BASE_DISCOVER_LIST_PROTOCOLS command.\r
+typedef struct {\r
+ UINT32 NumProtocols;\r
+\r
+ // Array of four protocols in each element\r
+ // Total elements = 1 + (NumProtocols-1)/4\r
+\r
+ // NOTE: Since EDK2 does not allow flexible array member [] we declare\r
+ // here array of 1 element length. However below is used as a variable\r
+ // length array.\r
+ UINT8 Protocols[1];\r
+} BASE_DISCOVER_LIST;\r
+\r
+/** Initialize Base protocol and install protocol on a given handle.\r
+\r
+ @param[in] Handle Handle to install Base protocol.\r
+\r
+ @retval EFI_SUCCESS Base protocol interface installed\r
+ successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiBaseProtocolInit (\r
+ IN OUT EFI_HANDLE* Handle\r
+ );\r
+\r
+#endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_\r
+#define ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_\r
+\r
+#pragma pack(1)\r
+\r
+// Clock rate in two 32bit words.\r
+typedef struct {\r
+ UINT32 Low;\r
+ UINT32 High;\r
+} CLOCK_RATE_DWORD;\r
+\r
+// Format of the returned rate array. Linear or Non-linear,.RatesFlag Bit[12]\r
+#define RATE_FORMAT_SHIFT 12\r
+#define RATE_FORMAT_MASK 0x0001\r
+#define RATE_FORMAT(RatesFlags) ((RatesFlags >> RATE_FORMAT_SHIFT) \\r
+ & RATE_FORMAT_MASK)\r
+\r
+// Number of remaining rates after a call to the SCP, RatesFlag Bits[31:16]\r
+#define NUM_REMAIN_RATES_SHIFT 16\r
+#define NUM_REMAIN_RATES(RatesFlags) ((RatesFlags >> NUM_REMAIN_RATES_SHIFT))\r
+\r
+// Number of rates that are returned by a call.to the SCP, RatesFlag Bits[11:0]\r
+#define NUM_RATES_MASK 0x0FFF\r
+#define NUM_RATES(RatesFlags) (RatesFlags & NUM_RATES_MASK)\r
+\r
+// Return values for the CLOCK_DESCRIBER_RATE command.\r
+typedef struct {\r
+ UINT32 NumRatesFlags;\r
+\r
+ // NOTE: Since EDK2 does not allow flexible array member [] we declare\r
+ // here array of 1 element length. However below is used as a variable\r
+ // length array.\r
+ CLOCK_RATE_DWORD Rates[1];\r
+} CLOCK_DESCRIBE_RATES;\r
+\r
+#define CLOCK_SET_DEFAULT_FLAGS 0\r
+\r
+// Message parameters for CLOCK_RATE_SET command.\r
+typedef struct {\r
+ UINT32 Flags;\r
+ UINT32 ClockId;\r
+ CLOCK_RATE_DWORD Rate;\r
+} CLOCK_RATE_SET_ATTRIBUTES;\r
+\r
+// if ClockAttr Bit[0] is set then clock device is enabled.\r
+#define CLOCK_ENABLE_MASK 0x1\r
+#define CLOCK_ENABLED(ClockAttr) ((ClockAttr & CLOCK_ENABLE_MASK) == 1)\r
+\r
+typedef struct {\r
+ UINT32 Attributes;\r
+ UINT8 ClockName[SCMI_MAX_STR_LEN];\r
+} CLOCK_ATTRIBUTES;\r
+\r
+#pragma pack()\r
+\r
+/** Initialize clock management protocol and install protocol on a given handle.\r
+\r
+ @param[in] Handle Handle to install clock management protocol.\r
+\r
+ @retval EFI_SUCCESS Clock protocol interface installed successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiClockProtocolInit (\r
+ IN EFI_HANDLE *Handle\r
+ );\r
+\r
+#endif /* ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ */\r
--- /dev/null
+#/** @file\r
+#\r
+# Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# System Control and Management Interface V1.0\r
+# http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+# DEN0056A_System_Control_and_Management_Interface.pdf\r
+#**/\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010019\r
+ BASE_NAME = ArmScmiDxe\r
+ FILE_GUID = 9585984C-F027-45E9-AFDF-ADAA6DFAAAC7\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ ENTRY_POINT = ArmScmiDxeEntryPoint\r
+\r
+[Sources.common]\r
+ Scmi.c\r
+ ScmiBaseProtocol.c\r
+ ScmiClockProtocol.c\r
+ ScmiDxe.c\r
+ ScmiPerformanceProtocol.c\r
+\r
+[Packages]\r
+ ArmPkg/ArmPkg.dec\r
+ ArmPlatformPkg/ArmPlatformPkg.dec\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ ArmLib\r
+ ArmMtlLib\r
+ DebugLib\r
+ IoLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+\r
+[Protocols]\r
+ gArmScmiBaseProtocolGuid\r
+ gArmScmiClockProtocolGuid\r
+ gArmScmiPerformanceProtocolGuid\r
+\r
+[Depex]\r
+ TRUE\r
+\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_\r
+#define ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_\r
+\r
+#include <Protocol/ArmScmiPerformanceProtocol.h>\r
+\r
+// Number of performance levels returned by a call to the SCP, Lvls Bits[11:0]\r
+#define NUM_PERF_LEVELS_MASK 0x0FFF\r
+#define NUM_PERF_LEVELS(Lvls) (Lvls & NUM_PERF_LEVELS_MASK)\r
+\r
+// Number of performance levels remaining after a call to the SCP, Lvls Bits[31:16]\r
+#define NUM_REMAIN_PERF_LEVELS_SHIFT 16\r
+#define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> NUM_REMAIN_PERF_LEVELS_SHIFT)\r
+\r
+/** Return values for SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS command.\r
+ SCMI Spec ยง 4.5.2.5\r
+**/\r
+typedef struct {\r
+ UINT32 NumLevels;\r
+\r
+ // NOTE: Since EDK2 does not allow flexible array member [] we declare\r
+ // here array of 1 element length. However below is used as a variable\r
+ // length array.\r
+ SCMI_PERFORMANCE_LEVEL PerfLevel[1]; // Offset to array of performance levels\r
+} PERF_DESCRIBE_LEVELS;\r
+\r
+/** Initialize performance management protocol and install on a given Handle.\r
+\r
+ @param[in] Handle Handle to install performance management\r
+ protocol.\r
+\r
+ @retval EFI_SUCCESS Performance protocol installed successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiPerformanceProtocolInit (\r
+ IN EFI_HANDLE* Handle\r
+ );\r
+\r
+#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#include <Library/ArmMtlLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "ScmiPrivate.h"\r
+\r
+// SCMI Specification 1.0\r
+#define MAX_PROTOCOLS 6\r
+\r
+#define PROTOCOL_MASK 0xF\r
+\r
+// Arbitrary timeout value 20ms.\r
+#define RESPONSE_TIMEOUT 20000\r
+\r
+/** Return a pointer to the message payload.\r
+\r
+ @param[out] Payload Holds pointer to the message payload.\r
+\r
+ @retval EFI_SUCCESS Payload holds a valid message payload pointer.\r
+ @retval EFI_TIMEOUT Time out error if MTL channel is busy.\r
+ @retval EFI_UNSUPPORTED If MTL channel is unsupported.\r
+**/\r
+EFI_STATUS\r
+ScmiCommandGetPayload (\r
+ OUT UINT32** Payload\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ MTL_CHANNEL *Channel;\r
+\r
+ // Get handle to the Channel.\r
+ Status = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Payload will not be populated until channel is free.\r
+ Status = MtlWaitUntilChannelFree (Channel, RESPONSE_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Get the address of the payload.\r
+ *Payload = MtlGetChannelPayload (Channel);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Execute a SCMI command and receive a response.\r
+\r
+ This function uses a MTL channel to transfer message to SCP\r
+ and waits for a response.\r
+\r
+ @param[in] Command Pointer to the SCMI command (Protocol ID\r
+ and Message ID)\r
+\r
+ @param[in,out] PayloadLength SCMI command message length.\r
+\r
+ @param[out] OPTIONAL ReturnValues Pointer to SCMI response.\r
+\r
+ @retval OUT EFI_SUCCESS Command sent and message received successfully.\r
+ @retval OUT EFI_UNSUPPORTED Channel not supported.\r
+ @retval OUT EFI_TIMEOUT Timeout on the channel.\r
+ @retval OUT EFI_DEVICE_ERROR Channel not ready.\r
+ @retval OUT EFI_DEVICE_ERROR Message Header corrupted.\r
+ @retval OUT EFI_DEVICE_ERROR SCMI error.\r
+**/\r
+EFI_STATUS\r
+ScmiCommandExecute (\r
+ IN SCMI_COMMAND *Command,\r
+ IN OUT UINT32 *PayloadLength,\r
+ OUT UINT32 **ReturnValues OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SCMI_MESSAGE_RESPONSE *Response;\r
+ UINT32 MessageHeader;\r
+ UINT32 ResponseHeader;\r
+ MTL_CHANNEL *Channel;\r
+\r
+ ASSERT (PayloadLength != NULL);\r
+\r
+ Status = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Fill in message header.\r
+ MessageHeader = SCMI_MESSAGE_HEADER (\r
+ Command->MessageId,\r
+ SCMI_MESSAGE_TYPE_COMMAND,\r
+ Command->ProtocolId\r
+ );\r
+\r
+ // Send payload using MTL channel.\r
+ Status = MtlSendMessage (\r
+ Channel,\r
+ MessageHeader,\r
+ *PayloadLength\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Wait for the response on the channel.\r
+ Status = MtlReceiveMessage (Channel, &ResponseHeader, PayloadLength);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // SCMI must return MessageHeader unmodified.\r
+ if (MessageHeader != ResponseHeader) {\r
+ ASSERT (FALSE);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Response = (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload (Channel);\r
+\r
+ if (Response->Status != SCMI_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",\r
+ Command->ProtocolId,\r
+ Command->MessageId,\r
+ Response->Status\r
+ ));\r
+\r
+ ASSERT (FALSE);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (ReturnValues != NULL) {\r
+ *ReturnValues = Response->ReturnValues;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Internal common function useful for common protocol discovery messages.\r
+\r
+ @param[in] ProtocolId Protocol Id of the the protocol.\r
+ @param[in] MesaageId Message Id of the message.\r
+\r
+ @param[out] ReturnValues SCMI response return values.\r
+\r
+ @retval EFI_SUCCESS Success with valid return values.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ScmiProtocolDiscoveryCommon (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ IN SCMI_MESSAGE_ID MessageId,\r
+ OUT UINT32 **ReturnValues\r
+ )\r
+{\r
+ SCMI_COMMAND Command;\r
+ UINT32 PayloadLength = 0;\r
+\r
+ Command.ProtocolId = ProtocolId;\r
+ Command.MessageId = MessageId;\r
+\r
+ return ScmiCommandExecute (\r
+ &Command,\r
+ &PayloadLength,\r
+ ReturnValues\r
+ );\r
+}\r
+\r
+/** Return protocol version from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+ @param[out] Version Pointer to version of the protocol.\r
+\r
+ @retval EFI_SUCCESS Version holds a valid version received\r
+ from the SCP.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolVersion (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 *Version\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *ProtocolVersion;\r
+\r
+ Status = ScmiProtocolDiscoveryCommon (\r
+ ProtocolId,\r
+ SCMI_MESSAGE_ID_PROTOCOL_VERSION,\r
+ (UINT32**)&ProtocolVersion\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *Version = *ProtocolVersion;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return protocol attributes from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+ @param[out] ReturnValues Pointer to attributes of the protocol.\r
+\r
+ @retval EFI_SUCCESS ReturnValues points to protocol attributes.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolAttributes (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 **ReturnValues\r
+ )\r
+{\r
+ return ScmiProtocolDiscoveryCommon (\r
+ ProtocolId,\r
+ SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES,\r
+ ReturnValues\r
+ );\r
+}\r
+\r
+/** Return protocol message attributes from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+ @param[out] Attributes Pointer to attributes of the protocol.\r
+\r
+ @retval EFI_SUCCESS ReturnValues points to protocol message attributes.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolMessageAttributes (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 **ReturnValues\r
+ )\r
+{\r
+ return ScmiProtocolDiscoveryCommon (\r
+ ProtocolId,\r
+ SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES,\r
+ ReturnValues\r
+ );\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/ArmScmiBaseProtocol.h>\r
+\r
+#include "ArmScmiBaseProtocolPrivate.h"\r
+#include "ScmiPrivate.h"\r
+\r
+/** Return version of the Base protocol supported by SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI Base protocol.\r
+\r
+ @retval EFI_SUCCESS The version of the protocol is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseGetVersion (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ )\r
+{\r
+ return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_BASE, Version);\r
+}\r
+\r
+/** Return total number of SCMI protocols supported by the SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] TotalProtocols Total number of SCMI protocols supported.\r
+\r
+ @retval EFI_SUCCESS Total number of protocols supported are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseGetTotalProtocols (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *TotalProtocols\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *ReturnValues;\r
+\r
+ Status = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_BASE, &ReturnValues);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *TotalProtocols = SCMI_TOTAL_PROTOCOLS (ReturnValues[0]);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Common function which returns vendor details.\r
+\r
+ @param[in] MessageId SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR\r
+ OR\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR\r
+\r
+ @param[out] VendorIdentifier ASCII name of the vendor/subvendor.\r
+\r
+ @retval EFI_SUCCESS VendorIdentifier is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseDiscoverVendorDetails (\r
+ IN SCMI_MESSAGE_ID_BASE MessageId,\r
+ OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *ReturnValues;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 PayloadLength;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
+ Cmd.MessageId = MessageId;\r
+\r
+ PayloadLength = 0;\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ &ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ AsciiStrCpyS (\r
+ (CHAR8*)VendorIdentifier,\r
+ SCMI_MAX_STR_LEN,\r
+ (CONST CHAR8*)ReturnValues\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return vendor name.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] VendorIdentifier Null terminated ASCII string of up to\r
+ 16 bytes with a vendor name.\r
+\r
+ @retval EFI_SUCCESS VendorIdentifier is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseDiscoverVendor (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
+ )\r
+{\r
+ return BaseDiscoverVendorDetails (\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR,\r
+ VendorIdentifier\r
+ );\r
+}\r
+\r
+/** Return sub vendor name.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] VendorIdentifier Null terminated ASCII string of up to\r
+ 16 bytes with a sub vendor name.\r
+\r
+ @retval EFI_SUCCESS VendorIdentifier is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+BaseDiscoverSubVendor (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
+ )\r
+{\r
+ return BaseDiscoverVendorDetails (\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR,\r
+ VendorIdentifier\r
+ );\r
+}\r
+\r
+/** Return implementation version.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] ImplementationVersion Vendor specific implementation version.\r
+\r
+ @retval EFI_SUCCESS Implementation version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseDiscoverImplVersion (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *ImplementationVersion\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *ReturnValues;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 PayloadLength;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION;\r
+\r
+ PayloadLength = 0;\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ &ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *ImplementationVersion = ReturnValues[0];\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return list of protocols.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] ProtocolListSize Size of the ProtocolList.\r
+\r
+ @param[out] ProtocolList Protocol list.\r
+\r
+ @retval EFI_SUCCESS List of protocols is returned.\r
+ @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BaseDiscoverListProtocols (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ IN OUT UINT32 *ProtocolListSize,\r
+ OUT UINT8 *ProtocolList\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 TotalProtocols;\r
+ UINT32 *MessageParams;\r
+ BASE_DISCOVER_LIST *DiscoverList;\r
+ UINT32 Skip;\r
+ UINT32 Index;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 PayloadLength;\r
+ UINT32 RequiredSize;\r
+\r
+ Status = BaseGetTotalProtocols (This, &TotalProtocols);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ RequiredSize = sizeof (UINT8) * TotalProtocols;\r
+ if (*ProtocolListSize < RequiredSize) {\r
+ *ProtocolListSize = RequiredSize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS;\r
+\r
+ Skip = 0;\r
+\r
+ while (Skip < TotalProtocols) {\r
+\r
+ *MessageParams = Skip;\r
+\r
+ // Note PayloadLength is a IN/OUT parameter.\r
+ PayloadLength = sizeof (Skip);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&DiscoverList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ for (Index = 0; Index < DiscoverList->NumProtocols; Index++) {\r
+ ProtocolList[Skip++] = DiscoverList->Protocols[Index];\r
+ }\r
+ }\r
+\r
+ *ProtocolListSize = RequiredSize;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+// Instance of the SCMI Base protocol.\r
+STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {\r
+ BaseGetVersion,\r
+ BaseGetTotalProtocols,\r
+ BaseDiscoverVendor,\r
+ BaseDiscoverSubVendor,\r
+ BaseDiscoverImplVersion,\r
+ BaseDiscoverListProtocols\r
+};\r
+\r
+/** Initialize Base protocol and install protocol on a given handle.\r
+\r
+ @param[in] Handle Handle to install Base protocol.\r
+\r
+ @retval EFI_SUCCESS Base protocol interface installed\r
+ successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiBaseProtocolInit (\r
+ IN OUT EFI_HANDLE* Handle\r
+ )\r
+{\r
+ return gBS->InstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gArmScmiBaseProtocolGuid,\r
+ &BaseProtocol,\r
+ NULL\r
+ );\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/ArmScmiClockProtocol.h>\r
+\r
+#include "ArmScmiClockProtocolPrivate.h"\r
+#include "ScmiPrivate.h"\r
+\r
+/** Convert to 64 bit value from two 32 bit words.\r
+\r
+ @param[in] Low Lower 32 bits.\r
+ @param[in] High Higher 32 bits.\r
+\r
+ @retval UINT64 64 bit value.\r
+**/\r
+STATIC\r
+UINT64\r
+ConvertTo64Bit (\r
+ IN UINT32 Low,\r
+ IN UINT32 High\r
+ )\r
+{\r
+ return (Low | ((UINT64)High << 32));\r
+}\r
+\r
+/** Return version of the clock management protocol supported by SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI Clock management protocol.\r
+\r
+ @retval EFI_SUCCESS The version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockGetVersion (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ )\r
+{\r
+ return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_CLOCK, Version);\r
+}\r
+\r
+/** Return total number of clock devices supported by the clock management\r
+ protocol.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+\r
+ @param[out] TotalClocks Total number of clocks supported.\r
+\r
+ @retval EFI_SUCCESS Total number of clocks supported is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockGetTotalClocks (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ OUT UINT32 *TotalClocks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *ReturnValues;\r
+\r
+ Status = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_CLOCK, &ReturnValues);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *TotalClocks = SCMI_CLOCK_PROTOCOL_TOTAL_CLKS (ReturnValues[0]);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return attributes of a clock device.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Enabled If TRUE, the clock device is enabled.\r
+ @param[out] ClockAsciiName A NULL terminated ASCII string with the clock\r
+ name, of up to 16 bytes.\r
+\r
+ @retval EFI_SUCCESS Clock device attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockGetClockAttributes (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT BOOLEAN *Enabled,\r
+ OUT CHAR8 *ClockAsciiName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ UINT32 *MessageParams;\r
+ CLOCK_ATTRIBUTES *ClockAttributes;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 PayloadLength;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams = ClockId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES;\r
+\r
+ PayloadLength = sizeof (ClockId);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&ClockAttributes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ // TRUE if bit 0 of ClockAttributes->Attributes is set.\r
+ *Enabled = CLOCK_ENABLED (ClockAttributes->Attributes);\r
+\r
+ AsciiStrCpyS (\r
+ ClockAsciiName,\r
+ SCMI_MAX_STR_LEN,\r
+ (CONST CHAR8*)ClockAttributes->ClockName\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return list of rates supported by a given clock device.\r
+\r
+ @param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Format SCMI_CLOCK_RATE_FORMAT_DISCRETE: Clock device\r
+ supports range of clock rates which are non-linear.\r
+\r
+ SCMI_CLOCK_RATE_FORMAT_LINEAR: Clock device supports\r
+ range of linear clock rates from Min to Max in steps.\r
+\r
+ @param[out] TotalRates Total number of rates.\r
+\r
+ @param[in,out] RateArraySize Size of the RateArray.\r
+\r
+ @param[out] RateArray List of clock rates.\r
+\r
+ @retval EFI_SUCCESS List of clock rates is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval EFI_BUFFER_TOO_SMALL RateArraySize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockDescribeRates (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT SCMI_CLOCK_RATE_FORMAT *Format,\r
+ OUT UINT32 *TotalRates,\r
+ IN OUT UINT32 *RateArraySize,\r
+ OUT SCMI_CLOCK_RATE *RateArray\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 *MessageParams;\r
+ CLOCK_DESCRIBE_RATES *DescribeRates;\r
+ CLOCK_RATE_DWORD *Rate;\r
+\r
+ UINT32 RequiredArraySize = 0;\r
+ UINT32 RateIndex = 0;\r
+ UINT32 RateNo;\r
+ UINT32 RateOffset;\r
+\r
+ *TotalRates = 0;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES;\r
+\r
+ *MessageParams++ = ClockId;\r
+\r
+ do {\r
+\r
+ *MessageParams = RateIndex;\r
+\r
+ // Set Payload length, note PayloadLength is a IN/OUT parameter.\r
+ PayloadLength = sizeof (ClockId) + sizeof (RateIndex);\r
+\r
+ // Execute and wait for response on a SCMI channel.\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&DescribeRates\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (*TotalRates == 0) {\r
+ // In the first iteration we will get number of returned rates and number\r
+ // of remaining rates. With this information calculate required size\r
+ // for rate array. If provided RateArraySize is less, return an\r
+ // error.\r
+\r
+ *Format = RATE_FORMAT (DescribeRates->NumRatesFlags);\r
+\r
+ *TotalRates = NUM_RATES (DescribeRates->NumRatesFlags)\r
+ + NUM_REMAIN_RATES (DescribeRates->NumRatesFlags);\r
+\r
+ if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {\r
+ RequiredArraySize = (*TotalRates) * sizeof (UINT64);\r
+ } else {\r
+ // We need to return triplet of 64 bit value for each rate\r
+ RequiredArraySize = (*TotalRates) * 3 * sizeof (UINT64);\r
+ }\r
+\r
+ if (RequiredArraySize > (*RateArraySize)) {\r
+ *RateArraySize = RequiredArraySize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ }\r
+\r
+ RateOffset = 0;\r
+\r
+ if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {\r
+ for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {\r
+ Rate = &DescribeRates->Rates[RateOffset++];\r
+ // Non-linear discrete rates.\r
+ RateArray[RateIndex++].Rate = ConvertTo64Bit (Rate->Low, Rate->High);\r
+ }\r
+ } else {\r
+ for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {\r
+ // Linear clock rates from minimum to maximum in steps\r
+ // Minimum clock rate.\r
+ Rate = &DescribeRates->Rates[RateOffset++];\r
+ RateArray[RateIndex].Min = ConvertTo64Bit (Rate->Low, Rate->High);\r
+\r
+ Rate = &DescribeRates->Rates[RateOffset++];\r
+ // Maximum clock rate.\r
+ RateArray[RateIndex].Max = ConvertTo64Bit (Rate->Low, Rate->High);\r
+\r
+ Rate = &DescribeRates->Rates[RateOffset++];\r
+ // Step.\r
+ RateArray[RateIndex++].Step = ConvertTo64Bit (Rate->Low, Rate->High);\r
+ }\r
+ }\r
+ } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);\r
+\r
+ // Update RateArraySize with RequiredArraySize.\r
+ *RateArraySize = RequiredArraySize;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Get clock rate.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Rate Clock rate.\r
+\r
+ @retval EFI_SUCCESS Clock rate is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockRateGet (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT UINT64 *Rate\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ UINT32 *MessageParams;\r
+ CLOCK_RATE_DWORD *ClockRate;\r
+ SCMI_COMMAND Cmd;\r
+\r
+ UINT32 PayloadLength;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Fill arguments for clock protocol command.\r
+ *MessageParams = ClockId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_GET;\r
+\r
+ PayloadLength = sizeof (ClockId);\r
+\r
+ // Execute and wait for response on a SCMI channel.\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&ClockRate\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *Rate = ConvertTo64Bit (ClockRate->Low, ClockRate->High);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Set clock rate.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+ @param[in] Rate Clock rate.\r
+\r
+ @retval EFI_SUCCESS Clock rate set success.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ClockRateSet (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ IN UINT64 Rate\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CLOCK_RATE_SET_ATTRIBUTES *ClockRateSetAttributes;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 PayloadLength;\r
+\r
+ Status = ScmiCommandGetPayload ((UINT32**)&ClockRateSetAttributes);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Fill arguments for clock protocol command.\r
+ ClockRateSetAttributes->ClockId = ClockId;\r
+ ClockRateSetAttributes->Flags = CLOCK_SET_DEFAULT_FLAGS;\r
+ ClockRateSetAttributes->Rate.Low = (UINT32)Rate;\r
+ ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_SET;\r
+\r
+ PayloadLength = sizeof (CLOCK_RATE_SET_ATTRIBUTES);\r
+\r
+ // Execute and wait for response on a SCMI channel.\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+// Instance of the SCMI clock management protocol.\r
+STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {\r
+ ClockGetVersion,\r
+ ClockGetTotalClocks,\r
+ ClockGetClockAttributes,\r
+ ClockDescribeRates,\r
+ ClockRateGet,\r
+ ClockRateSet\r
+ };\r
+\r
+/** Initialize clock management protocol and install protocol on a given handle.\r
+\r
+ @param[in] Handle Handle to install clock management protocol.\r
+\r
+ @retval EFI_SUCCESS Clock protocol interface installed successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiClockProtocolInit (\r
+ IN EFI_HANDLE* Handle\r
+ )\r
+{\r
+ return gBS->InstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gArmScmiClockProtocolGuid,\r
+ &ScmiClockProtocol,\r
+ NULL\r
+ );\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/ArmScmiBaseProtocol.h>\r
+#include <Protocol/ArmScmiClockProtocol.h>\r
+#include <Protocol/ArmScmiPerformanceProtocol.h>\r
+\r
+#include "ArmScmiBaseProtocolPrivate.h"\r
+#include "ArmScmiClockProtocolPrivate.h"\r
+#include "ArmScmiPerformanceProtocolPrivate.h"\r
+#include "ScmiDxe.h"\r
+#include "ScmiPrivate.h"\r
+\r
+STATIC CONST SCMI_PROTOCOL_INIT_TABLE ProtocolInitFxns[MAX_PROTOCOLS] = {\r
+ { ScmiBaseProtocolInit },\r
+ { NULL },\r
+ { NULL },\r
+ { ScmiPerformanceProtocolInit },\r
+ { ScmiClockProtocolInit },\r
+ { NULL }\r
+};\r
+\r
+/** ARM SCMI driver entry point function.\r
+\r
+ This function installs the SCMI Base protocol and a list of other\r
+ protocols is queried using the Base protocol. If protocol is supported,\r
+ driver will call each protocol init function to install the protocol on\r
+ the ImageHandle.\r
+\r
+ @param[in] ImageHandle Handle to this EFI Image which will be used to\r
+ install Base, Clock and Performance protocols.\r
+ @param[in] SystemTable A pointer to boot time system table.\r
+\r
+ @retval EFI_SUCCESS Driver initalized successfully.\r
+ @retval EFI_UNSUPPORTED If SCMI base protocol version is not supported.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ArmScmiDxeEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SCMI_BASE_PROTOCOL *BaseProtocol;\r
+ UINT32 Version;\r
+ UINT32 Index;\r
+ UINT32 NumProtocols;\r
+ UINT32 ProtocolNo;\r
+ UINT8 SupportedList[MAX_PROTOCOLS];\r
+ UINT32 SupportedListSize = sizeof (SupportedList);\r
+\r
+ ProtocolNo = SCMI_PROTOCOL_ID_BASE & PROTOCOL_ID_MASK;\r
+\r
+ // Every SCMI implementation must implement the base protocol.\r
+ Status = ProtocolInitFxns[ProtocolNo].Init (&ImageHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gArmScmiBaseProtocolGuid,\r
+ NULL,\r
+ (VOID**)&BaseProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+\r
+ // Get SCMI Base protocol version.\r
+ Status = BaseProtocol->GetVersion (BaseProtocol, &Version);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+\r
+ if (Version != BASE_PROTOCOL_VERSION) {\r
+ ASSERT (FALSE);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ // Apart from Base protocol, SCMI may implement various other protocols,\r
+ // query total protocols implemented by the SCP firmware.\r
+ NumProtocols = 0;\r
+ Status = BaseProtocol->GetTotalProtocols (BaseProtocol, &NumProtocols);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (NumProtocols != 0);\r
+\r
+ // Get the list of protocols supported by SCP firmware on the platform.\r
+ Status = BaseProtocol->DiscoverListProtocols (\r
+ BaseProtocol,\r
+ &SupportedListSize,\r
+ SupportedList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+\r
+ // Install supported protocol on ImageHandle.\r
+ for (Index = 0; Index < NumProtocols; Index++) {\r
+ ProtocolNo = SupportedList[Index] & PROTOCOL_ID_MASK;\r
+ if (ProtocolInitFxns[ProtocolNo].Init != NULL) {\r
+ Status = ProtocolInitFxns[ProtocolNo].Init (&ImageHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ return Status;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+#ifndef SCMI_DXE_H_\r
+#define SCMI_DXE_H_\r
+\r
+#define MAX_PROTOCOLS 6\r
+#define PROTOCOL_ID_MASK 0xF\r
+#define MAX_VENDOR_LEN SCMI_MAX_STR_LEN\r
+\r
+/** Pointer to protocol initialization function.\r
+\r
+ @param[in] Handle A pointer to the EFI_HANDLE on which the protocol\r
+ interface is to be installed.\r
+\r
+ @retval EFI_SUCCESS Protocol interface installed successfully.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PROTOCOL_INIT_FXN)(\r
+ IN EFI_HANDLE *Handle\r
+ );\r
+\r
+typedef struct {\r
+ SCMI_PROTOCOL_INIT_FXN Init;\r
+} SCMI_PROTOCOL_INIT_TABLE;\r
+\r
+#endif /* SCMI_DXE_H_ */\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/ArmScmiPerformanceProtocol.h>\r
+\r
+#include "ArmScmiPerformanceProtocolPrivate.h"\r
+#include "ScmiPrivate.h"\r
+\r
+/** Return version of the performance management protocol supported by SCP.\r
+ firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI performance management\r
+ protocol.\r
+\r
+ @retval EFI_SUCCESS The version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PerformanceGetVersion (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ )\r
+{\r
+ return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_PERFORMANCE, Version);\r
+}\r
+\r
+/** Return protocol attributes of the performance management protocol.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+\r
+ @param[out] Attributes Protocol attributes.\r
+\r
+ @retval EFI_SUCCESS Protocol attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PerformanceGetAttributes (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32* ReturnValues;\r
+\r
+ Status = ScmiGetProtocolAttributes (\r
+ SCMI_PROTOCOL_ID_PERFORMANCE,\r
+ &ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (\r
+ Attributes,\r
+ ReturnValues,\r
+ sizeof (SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES)\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return performance domain attributes.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Attributes Performance domain attributes.\r
+\r
+ @retval EFI_SUCCESS Domain attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PerformanceDomainAttributes (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 *MessageParams;\r
+ UINT32 *ReturnValues;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams = DomainId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES;\r
+\r
+ PayloadLength = sizeof (DomainId);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ &ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (\r
+ DomainAttributes,\r
+ ReturnValues,\r
+ sizeof (SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES)\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Return list of performance domain levels of a given domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] NumLevels Total number of levels a domain can support.\r
+\r
+ @param[in,out] LevelArraySize Size of the performance level array.\r
+\r
+ @param[out] LevelArray Array of the performance levels.\r
+\r
+ @retval EFI_SUCCESS Domain levels are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval EFI_BUFFER_TOO_SMALL LevelArraySize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PerformanceDescribeLevels (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT UINT32 *NumLevels,\r
+ IN OUT UINT32 *LevelArraySize,\r
+ OUT SCMI_PERFORMANCE_LEVEL *LevelArray\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32* MessageParams;\r
+ UINT32 LevelIndex;\r
+ UINT32 RequiredSize;\r
+ UINT32 LevelNo;\r
+ UINT32 ReturnNumLevels;\r
+ UINT32 ReturnRemainNumLevels;\r
+\r
+ PERF_DESCRIBE_LEVELS *Levels;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ LevelIndex = 0;\r
+ RequiredSize = 0;\r
+\r
+ *MessageParams++ = DomainId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS;\r
+\r
+ do {\r
+\r
+ *MessageParams = LevelIndex;\r
+\r
+ // Note, PayloadLength is an IN/OUT parameter.\r
+ PayloadLength = sizeof (DomainId) + sizeof (LevelIndex);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&Levels\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ReturnNumLevels = NUM_PERF_LEVELS (Levels->NumLevels);\r
+ ReturnRemainNumLevels = NUM_REMAIN_PERF_LEVELS (Levels->NumLevels);\r
+\r
+ if (RequiredSize == 0) {\r
+ *NumLevels = ReturnNumLevels + ReturnRemainNumLevels;\r
+\r
+ RequiredSize = (*NumLevels) * sizeof (SCMI_PERFORMANCE_LEVEL);\r
+ if (RequiredSize > (*LevelArraySize)) {\r
+ // Update LevelArraySize with required size.\r
+ *LevelArraySize = RequiredSize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ }\r
+\r
+ for (LevelNo = 0; LevelNo < ReturnNumLevels; LevelNo++) {\r
+ CopyMem (\r
+ &LevelArray[LevelIndex++],\r
+ &Levels->PerfLevel[LevelNo],\r
+ sizeof (SCMI_PERFORMANCE_LEVEL)\r
+ );\r
+ }\r
+\r
+ } while (ReturnRemainNumLevels != 0);\r
+\r
+ *LevelArraySize = RequiredSize;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Set performance limits of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+ @param[in] Limit Performance limit to set.\r
+\r
+ @retval EFI_SUCCESS Performance limits set successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+PerformanceLimitsSet (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ IN SCMI_PERFORMANCE_LIMITS *Limits\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 *MessageParams;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams++ = DomainId;\r
+ *MessageParams++ = Limits->RangeMax;\r
+ *MessageParams = Limits->RangeMin;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET;\r
+\r
+ PayloadLength = sizeof (DomainId) + sizeof (SCMI_PERFORMANCE_LIMITS);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/** Get performance limits of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Limit Performance Limits of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance limits are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+PerformanceLimitsGet (\r
+ SCMI_PERFORMANCE_PROTOCOL *This,\r
+ UINT32 DomainId,\r
+ SCMI_PERFORMANCE_LIMITS *Limits\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 *MessageParams;\r
+\r
+ SCMI_PERFORMANCE_LIMITS *ReturnValues;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams = DomainId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET;\r
+\r
+ PayloadLength = sizeof (DomainId);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ (UINT32**)&ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Limits->RangeMax = ReturnValues->RangeMax;\r
+ Limits->RangeMin = ReturnValues->RangeMin;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Set performance level of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+ @param[in] Level Performance level of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance level set successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+PerformanceLevelSet (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ IN UINT32 Level\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 *MessageParams;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams++ = DomainId;\r
+ *MessageParams = Level;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET;\r
+\r
+ PayloadLength = sizeof (DomainId) + sizeof (Level);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/** Get performance level of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Level Performance level of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance level got successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+PerformanceLevelGet (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT UINT32 *Level\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PayloadLength;\r
+ SCMI_COMMAND Cmd;\r
+ UINT32 *ReturnValues;\r
+ UINT32 *MessageParams;\r
+\r
+ Status = ScmiCommandGetPayload (&MessageParams);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *MessageParams = DomainId;\r
+\r
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;\r
+ Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET;\r
+\r
+ PayloadLength = sizeof (DomainId);\r
+\r
+ Status = ScmiCommandExecute (\r
+ &Cmd,\r
+ &PayloadLength,\r
+ &ReturnValues\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *Level = *ReturnValues;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+// Instance of the SCMI performance management protocol.\r
+STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {\r
+ PerformanceGetVersion,\r
+ PerformanceGetAttributes,\r
+ PerformanceDomainAttributes,\r
+ PerformanceDescribeLevels,\r
+ PerformanceLimitsSet,\r
+ PerformanceLimitsGet,\r
+ PerformanceLevelSet,\r
+ PerformanceLevelGet\r
+};\r
+\r
+/** Initialize performance management protocol and install on a given Handle.\r
+\r
+ @param[in] Handle Handle to install performance management\r
+ protocol.\r
+\r
+ @retval EFI_SUCCESS Performance protocol installed successfully.\r
+**/\r
+EFI_STATUS\r
+ScmiPerformanceProtocolInit (\r
+ IN EFI_HANDLE* Handle\r
+ )\r
+{\r
+ return gBS->InstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gArmScmiPerformanceProtocolGuid,\r
+ &PerformanceProtocol,\r
+ NULL\r
+ );\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+#ifndef SCMI_PRIVATE_H_\r
+#define SCMI_PRIVATE_H_\r
+\r
+// SCMI protocol IDs.\r
+typedef enum {\r
+ SCMI_PROTOCOL_ID_BASE = 0x10,\r
+ SCMI_PROTOCOL_ID_POWER_DOMAIN = 0x11,\r
+ SCMI_PROTOCOL_ID_SYSTEM_POWER = 0x12,\r
+ SCMI_PROTOCOL_ID_PERFORMANCE = 0x13,\r
+ SCMI_PROTOCOL_ID_CLOCK = 0x14,\r
+ SCMI_PROTOCOL_ID_SENSOR = 0x15\r
+} SCMI_PROTOCOL_ID;\r
+\r
+// SCMI message types.\r
+typedef enum {\r
+ SCMI_MESSAGE_TYPE_COMMAND = 0,\r
+ SCMI_MESSAGE_TYPE_DELAYED_RESPONSE = 2, // Skipping 1 is deliberate.\r
+ SCMI_MESSAGE_TYPE_NOTIFICATION = 3\r
+} SCMI_MESSAGE_TYPE;\r
+\r
+// SCMI response error codes.\r
+typedef enum {\r
+ SCMI_SUCCESS = 0,\r
+ SCMI_NOT_SUPPORTED = -1,\r
+ SCMI_INVALID_PARAMETERS = -2,\r
+ SCMI_DENIED = -3,\r
+ SCMI_NOT_FOUND = -4,\r
+ SCMI_OUT_OF_RANGE = -5,\r
+ SCMI_BUSY = -6,\r
+ SCMI_COMMS_ERROR = -7,\r
+ SCMI_GENERIC_ERROR = -8,\r
+ SCMI_HARDWARE_ERROR = -9,\r
+ SCMI_PROTOCOL_ERROR = -10\r
+} SCMI_STATUS;\r
+\r
+// SCMI message IDs common to all protocols.\r
+typedef enum {\r
+ SCMI_MESSAGE_ID_PROTOCOL_VERSION = 0x0,\r
+ SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES = 0x1,\r
+ SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2\r
+} SCMI_MESSAGE_ID;\r
+\r
+// Not defined in SCMI specification but will help to identify a message.\r
+typedef struct {\r
+ SCMI_PROTOCOL_ID ProtocolId;\r
+ UINT32 MessageId;\r
+} SCMI_COMMAND;\r
+\r
+#pragma pack(1)\r
+\r
+// Response to a SCMI command.\r
+typedef struct {\r
+ INT32 Status;\r
+ UINT32 ReturnValues[];\r
+} SCMI_MESSAGE_RESPONSE;\r
+\r
+// Message header. MsgId[7:0], MsgType[9:8], ProtocolId[17:10]\r
+#define MESSAGE_TYPE_SHIFT 8\r
+#define PROTOCOL_ID_SHIFT 10\r
+#define SCMI_MESSAGE_HEADER(MsgId, MsgType, ProtocolId) ( \\r
+ MsgType << MESSAGE_TYPE_SHIFT | \\r
+ ProtocolId << PROTOCOL_ID_SHIFT | \\r
+ MsgId \\r
+ )\r
+// SCMI message header.\r
+typedef struct {\r
+ UINT32 MessageHeader;\r
+} SCMI_MESSAGE_HEADER;\r
+\r
+#pragma pack()\r
+\r
+/** Return a pointer to the message payload.\r
+\r
+ @param[out] Payload Holds pointer to the message payload.\r
+\r
+ @retval EFI_SUCCESS Payload holds a valid message payload pointer.\r
+ @retval EFI_TIMEOUT Time out error if MTL channel is busy.\r
+ @retval EFI_UNSUPPORTED If MTL channel is unsupported.\r
+**/\r
+EFI_STATUS\r
+ScmiCommandGetPayload (\r
+ OUT UINT32** Payload\r
+ );\r
+\r
+/** Execute a SCMI command and receive a response.\r
+\r
+ This function uses a MTL channel to transfer message to SCP\r
+ and waits for a response.\r
+\r
+ @param[in] Command Pointer to the SCMI command (Protocol ID\r
+ and Message ID)\r
+\r
+ @param[in,out] PayloadLength SCMI command message length.\r
+\r
+ @param[out] OPTIONAL ReturnValues Pointer to SCMI response.\r
+\r
+ @retval OUT EFI_SUCCESS Command sent and message received successfully.\r
+ @retval OUT EFI_UNSUPPORTED Channel not supported.\r
+ @retval OUT EFI_TIMEOUT Timeout on the channel.\r
+ @retval OUT EFI_DEVICE_ERROR Channel not ready.\r
+ @retval OUT EFI_DEVICE_ERROR Message Header corrupted.\r
+ @retval OUT EFI_DEVICE_ERROR SCMI error.\r
+**/\r
+EFI_STATUS\r
+ScmiCommandExecute (\r
+ IN SCMI_COMMAND *Command,\r
+ IN OUT UINT32 *PayloadLength,\r
+ OUT UINT32 **ReturnValues OPTIONAL\r
+ );\r
+\r
+/** Return protocol version from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+ @param[out] Version Pointer to version of the protocol.\r
+\r
+ @retval EFI_SUCCESS Version holds a valid version received\r
+ from the SCP.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolVersion (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 *Version\r
+ );\r
+\r
+/** Return protocol attributes from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+ @param[out] ReturnValues Pointer to attributes of the protocol.\r
+\r
+ @retval EFI_SUCCESS ReturnValues points to protocol attributes.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolAttributes (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 **ReturnValues\r
+ );\r
+\r
+/** Return protocol message attributes from SCP for a given protocol ID.\r
+\r
+ @param[in] Protocol ID Protocol ID.\r
+\r
+ @param[out] Attributes Pointer to attributes of the protocol.\r
+\r
+ @retval EFI_SUCCESS ReturnValues points to protocol message attributes.\r
+ @retval EFI_DEVICE_ERROR SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+EFI_STATUS\r
+ScmiGetProtocolMessageAttributes (\r
+ IN SCMI_PROTOCOL_ID ProtocolId,\r
+ OUT UINT32 **ReturnValues\r
+ );\r
+\r
+#endif /* SCMI_PRIVATE_H_ */\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_H_\r
+#define ARM_SCMI_H_\r
+\r
+/* As per SCMI specification, maximum allowed ASCII string length\r
+ for various return values/parameters of a SCMI message.\r
+*/\r
+#define SCMI_MAX_STR_LEN 16\r
+\r
+#endif /* ARM_SCMI_H_ */\r
+\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_BASE_PROTOCOL_H_\r
+#define ARM_SCMI_BASE_PROTOCOL_H_\r
+\r
+#include <Protocol/ArmScmi.h>\r
+\r
+#define BASE_PROTOCOL_VERSION 0x10000\r
+\r
+#define NUM_PROTOCOL_MASK 0xFFU\r
+#define NUM_AGENT_MASK 0xFFU\r
+\r
+#define NUM_AGENT_SHIFT 0x8\r
+\r
+/** Returns total number of protocols that are\r
+ implemented (excluding the Base protocol)\r
+*/\r
+#define SCMI_TOTAL_PROTOCOLS(Attr) (Attr & NUM_PROTOCOL_MASK)\r
+\r
+// Returns total number of agents in the system.\r
+#define SCMI_TOTAL_AGENTS(Attr) ((Attr >> NUM_AGENT_SHIFT) & NUM_AGENT_MASK)\r
+\r
+#define ARM_SCMI_BASE_PROTOCOL_GUID { \\r
+ 0xd7e5abe9, 0x33ab, 0x418e, {0x9f, 0x91, 0x72, 0xda, 0xe2, 0xba, 0x8e, 0x2f} \\r
+ }\r
+\r
+extern EFI_GUID gArmScmiBaseProtocolGuid;\r
+\r
+typedef struct _SCMI_BASE_PROTOCOL SCMI_BASE_PROTOCOL;\r
+\r
+/** Return version of the Base protocol supported by SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI Base protocol.\r
+\r
+ @retval EFI_SUCCESS The version of the protocol is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_GET_VERSION) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ );\r
+\r
+/** Return total number of SCMI protocols supported by the SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] TotalProtocols Total number of SCMI protocols supported.\r
+\r
+ @retval EFI_SUCCESS Total number of protocols supported are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_GET_TOTAL_PROTOCOLS) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *TotalProtocols\r
+ );\r
+\r
+/** Return vendor name.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] VendorIdentifier Null terminated ASCII string of up to\r
+ 16 bytes with a vendor name.\r
+\r
+ @retval EFI_SUCCESS VendorIdentifier is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_DISCOVER_VENDOR) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
+ );\r
+\r
+/** Return sub vendor name.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] VendorIdentifier Null terminated ASCII string of up to\r
+ 16 bytes with a vendor name.\r
+\r
+ @retval EFI_SUCCESS VendorIdentifier is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_DISCOVER_SUB_VENDOR) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
+ );\r
+\r
+/** Return implementation version.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] ImplementationVersion Vendor specific implementation version.\r
+\r
+ @retval EFI_SUCCESS Implementation version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ OUT UINT32 *ImplementationVersion\r
+ );\r
+\r
+/** Return list of protocols.\r
+\r
+ @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
+\r
+ @param[out] ProtocolListSize Size of the ProtocolList.\r
+\r
+ @param[out] ProtocolList Protocol list.\r
+\r
+ @retval EFI_SUCCESS List of protocols is returned.\r
+ @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_BASE_DISCOVER_LIST_PROTOCOLS) (\r
+ IN SCMI_BASE_PROTOCOL *This,\r
+ IN OUT UINT32 *ProtocolListSize,\r
+ OUT UINT8 *ProtocolList\r
+ );\r
+\r
+// Base protocol.\r
+typedef struct _SCMI_BASE_PROTOCOL {\r
+ SCMI_BASE_GET_VERSION GetVersion;\r
+ SCMI_BASE_GET_TOTAL_PROTOCOLS GetTotalProtocols;\r
+ SCMI_BASE_DISCOVER_VENDOR DiscoverVendor;\r
+ SCMI_BASE_DISCOVER_SUB_VENDOR DiscoverSubVendor;\r
+ SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION DiscoverImplementationVersion;\r
+ SCMI_BASE_DISCOVER_LIST_PROTOCOLS DiscoverListProtocols;\r
+} SCMI_BASE_PROTOCOL;\r
+\r
+// SCMI Message IDs for Base protocol.\r
+typedef enum {\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR = 0x3,\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR = 0x4,\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x5,\r
+ SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS = 0x6\r
+} SCMI_MESSAGE_ID_BASE;\r
+\r
+#endif /* ARM_SCMI_BASE_PROTOCOL_H_ */\r
+\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_CLOCK_PROTOCOL_H_\r
+#define ARM_SCMI_CLOCK_PROTOCOL_H_\r
+\r
+#include <Protocol/ArmScmi.h>\r
+\r
+#define ARM_SCMI_CLOCK_PROTOCOL_GUID { \\r
+ 0x91ce67a8, 0xe0aa, 0x4012, {0xb9, 0x9f, 0xb6, 0xfc, 0xf3, 0x4, 0x8e, 0xaa} \\r
+ }\r
+\r
+extern EFI_GUID gArmScmiClockProtocolGuid;\r
+\r
+// Message Type for clock management protocol.\r
+typedef enum {\r
+ SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES = 0x3,\r
+ SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES = 0x4,\r
+ SCMI_MESSAGE_ID_CLOCK_RATE_SET = 0x5,\r
+ SCMI_MESSAGE_ID_CLOCK_RATE_GET = 0x6,\r
+ SCMI_MESSAGE_ID_CLOCK_CONFIG_SET = 0x7\r
+} SCMI_MESSAGE_ID_CLOCK;\r
+\r
+typedef enum {\r
+ SCMI_CLOCK_RATE_FORMAT_DISCRETE, // Non-linear range.\r
+ SCMI_CLOCK_RATE_FORMAT_LINEAR // Linear range.\r
+} SCMI_CLOCK_RATE_FORMAT;\r
+\r
+// Clock management protocol version.\r
+#define SCMI_CLOCK_PROTOCOL_VERSION 0x10000\r
+\r
+#define SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_MASK 0xFFU\r
+#define SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_SHIFT 16\r
+#define SCMI_CLOCK_PROTOCOL_NUM_CLOCKS_MASK 0xFFFFU\r
+\r
+/** Total number of pending asynchronous clock rates changes\r
+ supported by the SCP, Attr Bits[23:16]\r
+*/\r
+#define SCMI_CLOCK_PROTOCOL_MAX_ASYNC_CLK_RATES(Attr) ( \\r
+ (Attr >> SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_SHIFT) && \\r
+ SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_MASK)\r
+\r
+// Total of clock devices supported by the SCP, Attr Bits[15:0]\r
+#define SCMI_CLOCK_PROTOCOL_TOTAL_CLKS(Attr) (Attr & SCMI_CLOCK_PROTOCOL_NUM_CLOCKS_MASK)\r
+\r
+#pragma pack(1)\r
+\r
+/* Depending on the format (linear/non-linear) supported by a clock device\r
+ either Rate or Min/Max/Step triplet is valid.\r
+*/\r
+typedef struct {\r
+ union {\r
+ UINT64 Min;\r
+ UINT64 Rate;\r
+ };\r
+ UINT64 Max;\r
+ UINT64 Step;\r
+} SCMI_CLOCK_RATE;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _SCMI_CLOCK_PROTOCOL SCMI_CLOCK_PROTOCOL;\r
+\r
+// Protocol Interface functions.\r
+\r
+/** Return version of the clock management protocol supported by SCP firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI Clock management protocol.\r
+\r
+ @retval EFI_SUCCESS The version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_GET_VERSION) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ );\r
+\r
+/** Return total number of clock devices supported by the clock management\r
+ protocol.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+\r
+ @param[out] TotalClocks Total number of clocks supported.\r
+\r
+ @retval EFI_SUCCESS Total number of clocks supported is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_GET_TOTAL_CLOCKS) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ OUT UINT32 *TotalClocks\r
+ );\r
+\r
+/** Return attributes of a clock device.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Enabled If TRUE, the clock device is enabled.\r
+ @param[out] ClockAsciiName A NULL terminated ASCII string with the clock\r
+ name, of up to 16 bytes.\r
+\r
+ @retval EFI_SUCCESS Clock device attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_GET_CLOCK_ATTRIBUTES) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT BOOLEAN *Enabled,\r
+ OUT CHAR8 *ClockAsciiName\r
+ );\r
+\r
+/** Return list of rates supported by a given clock device.\r
+\r
+ @param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Format SCMI_CLOCK_RATE_FORMAT_DISCRETE: Clock device\r
+ supports range of clock rates which are non-linear.\r
+\r
+ SCMI_CLOCK_RATE_FORMAT_LINEAR: Clock device supports\r
+ range of linear clock rates from Min to Max in steps.\r
+\r
+ @param[out] TotalRates Total number of rates.\r
+\r
+ @param[in,out] RateArraySize Size of the RateArray.\r
+\r
+ @param[out] RateArray List of clock rates.\r
+\r
+ @retval EFI_SUCCESS List of clock rates are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval EFI_BUFFER_TOO_SMALL RateArraySize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_DESCRIBE_RATES) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT SCMI_CLOCK_RATE_FORMAT *Format,\r
+ OUT UINT32 *TotalRates,\r
+ IN OUT UINT32 *RateArraySize,\r
+ OUT SCMI_CLOCK_RATE *RateArray\r
+ );\r
+\r
+/** Get clock rate.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+\r
+ @param[out] Rate Clock rate.\r
+\r
+ @retval EFI_SUCCESS Clock rate is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_RATE_GET) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ OUT UINT64 *Rate\r
+ );\r
+\r
+/** Set clock rate.\r
+\r
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.\r
+ @param[in] ClockId Identifier for the clock device.\r
+ @param[in] Rate Clock rate.\r
+\r
+ @retval EFI_SUCCESS Clock rate set success.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_CLOCK_RATE_SET) (\r
+ IN SCMI_CLOCK_PROTOCOL *This,\r
+ IN UINT32 ClockId,\r
+ IN UINT64 Rate\r
+ );\r
+\r
+typedef struct _SCMI_CLOCK_PROTOCOL {\r
+ SCMI_CLOCK_GET_VERSION GetVersion;\r
+ SCMI_CLOCK_GET_TOTAL_CLOCKS GetTotalClocks;\r
+ SCMI_CLOCK_GET_CLOCK_ATTRIBUTES GetClockAttributes;\r
+ SCMI_CLOCK_DESCRIBE_RATES DescribeRates;\r
+ SCMI_CLOCK_RATE_GET RateGet;\r
+ SCMI_CLOCK_RATE_SET RateSet;\r
+} SCMI_CLOCK_PROTOCOL;\r
+\r
+#endif /* ARM_SCMI_CLOCK_PROTOCOL_H_ */\r
+\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ System Control and Management Interface V1.0\r
+ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
+ DEN0056A_System_Control_and_Management_Interface.pdf\r
+**/\r
+\r
+#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_H_\r
+#define ARM_SCMI_PERFORMANCE_PROTOCOL_H_\r
+\r
+#include <Protocol/ArmScmi.h>\r
+\r
+#define PERFORMANCE_PROTOCOL_VERSION 0x10000\r
+\r
+#define ARM_SCMI_PERFORMANCE_PROTOCOL_GUID { \\r
+ 0x9b8ba84, 0x3dd3, 0x49a6, {0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b, 0xad} \\r
+ }\r
+\r
+extern EFI_GUID gArmScmiPerformanceProtocolGuid;\r
+\r
+typedef struct _SCMI_PERFORMANCE_PROTOCOL SCMI_PERFORMANCE_PROTOCOL;\r
+\r
+#pragma pack(1)\r
+\r
+#define POWER_IN_MW_SHIFT 16\r
+#define POWER_IN_MW_MASK 0x1\r
+#define NUM_PERF_DOMAINS_MASK 0xFFFF\r
+\r
+// Total number of performance domains, Attr Bits [15:0]\r
+#define SCMI_PERF_TOTAL_DOMAINS(Attr) (Attr & NUM_PERF_DOMAINS_MASK)\r
+\r
+// A flag to express power values in mW or platform specific way, Attr Bit [16]\r
+#define SCMI_PERF_POWER_IN_MW(Attr) ((Attr >> POWER_IN_MW_SHIFT) & \\r
+ POWER_IN_MW_MASK)\r
+\r
+// Performance protocol attributes return values.\r
+typedef struct {\r
+ UINT32 Attributes;\r
+ UINT64 StatisticsAddress;\r
+ UINT32 StatisticsLen;\r
+} SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES;\r
+\r
+#define SCMI_PERF_SUPPORT_LVL_CHANGE_NOTIFY(Attr) ((Attr >> 28) & 0x1)\r
+#define SCMI_PERF_SUPPORT_LIM_CHANGE_NOTIFY(Attr) ((Attr >> 29) & 0x1)\r
+#define SCMI_PERF_SUPPORT_SET_LVL(Attr) ((Attr >> 30) & 0x1)\r
+#define SCMI_PERF_SUPPORT_SET_LIM(Attr) ((Attr >> 31) & 0x1)\r
+#define SCMI_PERF_RATE_LIMIT(RateLimit) (RateLimit & 0xFFF)\r
+\r
+// Performance protocol domain attributes.\r
+typedef struct {\r
+ UINT32 Attributes;\r
+ UINT32 RateLimit;\r
+ UINT32 SustainedFreq;\r
+ UINT32 SustainedPerfLevel;\r
+ UINT8 Name[SCMI_MAX_STR_LEN];\r
+} SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES;\r
+\r
+// Worst case latency in microseconds, Bits[15:0]\r
+#define PERF_LATENCY_MASK 0xFFFF\r
+#define SCMI_PERFORMANCE_PROTOCOL_LATENCY(Latency) (Latency & PERF_LATENCY_MASK)\r
+\r
+// Performance protocol performance level.\r
+typedef struct {\r
+ UINT32 Level;\r
+ UINT32 PowerCost;\r
+ UINT32 Latency;\r
+} SCMI_PERFORMANCE_LEVEL;\r
+\r
+// Performance protocol performance limit.\r
+typedef struct {\r
+ UINT32 RangeMax;\r
+ UINT32 RangeMin;\r
+} SCMI_PERFORMANCE_LIMITS;\r
+\r
+#pragma pack()\r
+\r
+/** Return version of the performance management protocol supported by SCP.\r
+ firmware.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+\r
+ @param[out] Version Version of the supported SCMI performance management\r
+ protocol.\r
+\r
+ @retval EFI_SUCCESS The version is returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_GET_VERSION) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ OUT UINT32 *Version\r
+ );\r
+\r
+/** Return protocol attributes of the performance management protocol.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+\r
+ @param[out] Attributes Protocol attributes.\r
+\r
+ @retval EFI_SUCCESS Protocol attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_GET_ATTRIBUTES) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes\r
+\r
+ );\r
+\r
+/** Return performance domain attributes.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Attributes Performance domain attributes.\r
+\r
+ @retval EFI_SUCCESS Domain attributes are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_GET_DOMAIN_ATTRIBUTES) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes\r
+ );\r
+\r
+/** Return list of performance domain levels of a given domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] NumLevels Total number of levels a domain can support.\r
+\r
+ @param[in,out] LevelArraySize Size of the performance level array.\r
+\r
+ @param[out] LevelArray Array of the performance levels.\r
+\r
+ @retval EFI_SUCCESS Domain levels are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval EFI_BUFFER_TOO_SMALL LevelArraySize is too small for the result.\r
+ It has been updated to the size needed.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_DESCRIBE_LEVELS) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT UINT32 *NumLevels,\r
+ IN OUT UINT32 *LevelArraySize,\r
+ OUT SCMI_PERFORMANCE_LEVEL *LevelArray\r
+ );\r
+\r
+/** Set performance limits of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+ @param[in] Limit Performance limit to set.\r
+\r
+ @retval EFI_SUCCESS Performance limits set successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_LIMITS_SET) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ IN SCMI_PERFORMANCE_LIMITS *Limits\r
+ );\r
+\r
+/** Get performance limits of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Limit Performance Limits of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance limits are returned.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_LIMITS_GET) (\r
+ SCMI_PERFORMANCE_PROTOCOL *This,\r
+ UINT32 DomainId,\r
+ SCMI_PERFORMANCE_LIMITS *Limits\r
+ );\r
+\r
+/** Set performance level of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+ @param[in] Level Performance level of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance level set successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_LEVEL_SET) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ IN UINT32 Level\r
+ );\r
+\r
+/** Get performance level of a domain.\r
+\r
+ @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.\r
+ @param[in] DomainId Identifier for the performance domain.\r
+\r
+ @param[out] Level Performance level of the domain.\r
+\r
+ @retval EFI_SUCCESS Performance level got successfully.\r
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
+ @retval !(EFI_SUCCESS) Other errors.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *SCMI_PERFORMANCE_LEVEL_GET) (\r
+ IN SCMI_PERFORMANCE_PROTOCOL *This,\r
+ IN UINT32 DomainId,\r
+ OUT UINT32 *Level\r
+ );\r
+\r
+typedef struct _SCMI_PERFORMANCE_PROTOCOL {\r
+ SCMI_PERFORMANCE_GET_VERSION GetVersion;\r
+ SCMI_PERFORMANCE_GET_ATTRIBUTES GetProtocolAttributes;\r
+ SCMI_PERFORMANCE_GET_DOMAIN_ATTRIBUTES GetDomainAttributes;\r
+ SCMI_PERFORMANCE_DESCRIBE_LEVELS DescribeLevels;\r
+ SCMI_PERFORMANCE_LIMITS_SET LimitsSet;\r
+ SCMI_PERFORMANCE_LIMITS_GET LimitsGet;\r
+ SCMI_PERFORMANCE_LEVEL_SET LevelSet;\r
+ SCMI_PERFORMANCE_LEVEL_GET LevelGet;\r
+} SCMI_PERFORMANCE_PROTOCOL;\r
+\r
+typedef enum {\r
+ SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES = 0x3,\r
+ SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS = 0x4,\r
+ SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET = 0x5,\r
+ SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET = 0x6,\r
+ SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET = 0x7,\r
+ SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET = 0x8,\r
+} SCMI_MESSAGE_ID_PERFORMANCE;\r
+\r
+#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_H_ */\r
+\r