diff options
author | Jeff Brasen <jbrasen@nvidia.com> | 2018-12-13 16:48:44 -0700 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2018-12-21 18:30:46 +0100 |
commit | 559a07d84e5af3db09ae91844e4cb924b8f60668 (patch) | |
tree | d139bf97c59218fffd07553167c43bf2e19a0208 /ArmPkg/Drivers | |
parent | 9bba10eb4336ac517f9d4c6665f075c3928478cd (diff) | |
download | edk2-559a07d84e5af3db09ae91844e4cb924b8f60668.zip edk2-559a07d84e5af3db09ae91844e4cb924b8f60668.tar.gz edk2-559a07d84e5af3db09ae91844e4cb924b8f60668.tar.bz2 |
ArmPkg/ArmScmiDxe: Add clock enable function
Add function to allow enabling and disabling of the clock using the SCMI
interface. Add gArmScmiClock2ProtocolGuid to distinguish platforms that
support new API from those that just have the older protocol.
SCMI_CLOCK2_PROTOCOL also adds a version parameter to allow for future
changes. It is placed after the functions that are present in the
existing protocol to allow SCMI_CLOCK2_PROTOCOL to be cast to
SCMI_CLOCK_PROTOCOL so that only a single implementation of those
function are needed.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Diffstat (limited to 'ArmPkg/Drivers')
-rw-r--r-- | ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h | 7 | ||||
-rw-r--r-- | ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf | 1 | ||||
-rw-r--r-- | ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c | 62 |
3 files changed, 70 insertions, 0 deletions
diff --git a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h index 0d1ec6f..c135bac 100644 --- a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h +++ b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h @@ -59,6 +59,13 @@ typedef struct { CLOCK_RATE_DWORD Rate;
} CLOCK_RATE_SET_ATTRIBUTES;
+
+// Message parameters for CLOCK_CONFIG_SET command.
+typedef struct {
+ UINT32 ClockId;
+ UINT32 Attributes;
+} CLOCK_CONFIG_SET_ATTRIBUTES;
+
// if ClockAttr Bit[0] is set then clock device is enabled.
#define CLOCK_ENABLE_MASK 0x1
#define CLOCK_ENABLED(ClockAttr) ((ClockAttr & CLOCK_ENABLE_MASK) == 1)
diff --git a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf index 05ce9c0..9b29b9f 100644 --- a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf +++ b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf @@ -46,6 +46,7 @@ [Protocols]
gArmScmiBaseProtocolGuid
gArmScmiClockProtocolGuid
+ gArmScmiClock2ProtocolGuid
gArmScmiPerformanceProtocolGuid
[Depex]
diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c b/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c index 64d2afa..c7f27a3 100644 --- a/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c @@ -19,6 +19,7 @@ #include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/ArmScmiClockProtocol.h>
+#include <Protocol/ArmScmiClock2Protocol.h>
#include "ArmScmiClockProtocolPrivate.h"
#include "ScmiPrivate.h"
@@ -388,6 +389,53 @@ ClockRateSet ( return Status;
}
+/** Enable/Disable specified clock.
+
+ @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance.
+ @param[in] ClockId Identifier for the clock device.
+ @param[in] Enable TRUE to enable, FALSE to disable.
+
+ @retval EFI_SUCCESS Clock enable/disable successful.
+ @retval EFI_DEVICE_ERROR SCP returns an SCMI error.
+ @retval !(EFI_SUCCESS) Other errors.
+**/
+STATIC
+EFI_STATUS
+ClockEnable (
+ IN SCMI_CLOCK2_PROTOCOL *This,
+ IN UINT32 ClockId,
+ IN BOOLEAN Enable
+ )
+{
+ EFI_STATUS Status;
+ CLOCK_CONFIG_SET_ATTRIBUTES *ClockConfigSetAttributes;
+ SCMI_COMMAND Cmd;
+ UINT32 PayloadLength;
+
+ Status = ScmiCommandGetPayload ((UINT32**)&ClockConfigSetAttributes);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Fill arguments for clock protocol command.
+ ClockConfigSetAttributes->ClockId = ClockId;
+ ClockConfigSetAttributes->Attributes = Enable ? BIT0 : 0;
+
+ Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
+ Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_CONFIG_SET;
+
+ PayloadLength = sizeof (CLOCK_CONFIG_SET_ATTRIBUTES);
+
+ // Execute and wait for response on a SCMI channel.
+ Status = ScmiCommandExecute (
+ &Cmd,
+ &PayloadLength,
+ NULL
+ );
+
+ return Status;
+}
+
// Instance of the SCMI clock management protocol.
STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {
ClockGetVersion,
@@ -398,6 +446,18 @@ STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = { ClockRateSet
};
+// Instance of the SCMI clock management protocol.
+STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
+ (SCMI_CLOCK2_GET_VERSION)ClockGetVersion,
+ (SCMI_CLOCK2_GET_TOTAL_CLOCKS)ClockGetTotalClocks,
+ (SCMI_CLOCK2_GET_CLOCK_ATTRIBUTES)ClockGetClockAttributes,
+ (SCMI_CLOCK2_DESCRIBE_RATES)ClockDescribeRates,
+ (SCMI_CLOCK2_RATE_GET)ClockRateGet,
+ (SCMI_CLOCK2_RATE_SET)ClockRateSet,
+ SCMI_CLOCK2_PROTOCOL_VERSION,
+ ClockEnable
+ };
+
/** Initialize clock management protocol and install protocol on a given handle.
@param[in] Handle Handle to install clock management protocol.
@@ -413,6 +473,8 @@ ScmiClockProtocolInit ( Handle,
&gArmScmiClockProtocolGuid,
&ScmiClockProtocol,
+ &gArmScmiClock2ProtocolGuid,
+ &ScmiClock2Protocol,
NULL
);
}
|