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>
This commit is contained in:
Jeff Brasen
2018-12-13 16:48:44 -07:00
committed by Ard Biesheuvel
parent 9bba10eb43
commit 559a07d84e
5 changed files with 268 additions and 0 deletions

View File

@@ -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
);
}