REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ArmPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			481 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			481 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   Copyright (c) 2017-2021, Arm Limited. All rights reserved.
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
|   System Control and Management Interface V1.0
 | |
|     http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
 | |
|     DEN0056A_System_Control_and_Management_Interface.pdf
 | |
| **/
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Protocol/ArmScmiClockProtocol.h>
 | |
| #include <Protocol/ArmScmiClock2Protocol.h>
 | |
| 
 | |
| #include "ArmScmiClockProtocolPrivate.h"
 | |
| #include "ScmiPrivate.h"
 | |
| 
 | |
| /** Convert to 64 bit value from two 32 bit words.
 | |
| 
 | |
|   @param[in] Low   Lower 32 bits.
 | |
|   @param[in] High  Higher 32 bits.
 | |
| 
 | |
|   @retval UINT64   64 bit value.
 | |
| **/
 | |
| STATIC
 | |
| UINT64
 | |
| ConvertTo64Bit (
 | |
|   IN UINT32  Low,
 | |
|   IN UINT32  High
 | |
|   )
 | |
| {
 | |
|   return (Low | ((UINT64)High << 32));
 | |
| }
 | |
| 
 | |
| /** Return version of the clock management protocol supported by SCP firmware.
 | |
| 
 | |
|   @param[in]  This     A Pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
| 
 | |
|   @param[out] Version  Version of the supported SCMI Clock management protocol.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The version is returned.
 | |
|   @retval EFI_DEVICE_ERROR  SCP returns an SCMI error.
 | |
|   @retval !(EFI_SUCCESS)    Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockGetVersion (
 | |
|   IN  SCMI_CLOCK_PROTOCOL  *This,
 | |
|   OUT UINT32               *Version
 | |
|   )
 | |
| {
 | |
|   return ScmiGetProtocolVersion (ScmiProtocolIdClock, Version);
 | |
| }
 | |
| 
 | |
| /** Return total number of clock devices supported by the clock management
 | |
|   protocol.
 | |
| 
 | |
|   @param[in]  This         A Pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
| 
 | |
|   @param[out] TotalClocks  Total number of clocks supported.
 | |
| 
 | |
|   @retval EFI_SUCCESS       Total number of clocks supported is returned.
 | |
|   @retval EFI_DEVICE_ERROR  SCP returns an SCMI error.
 | |
|   @retval !(EFI_SUCCESS)    Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockGetTotalClocks (
 | |
|   IN  SCMI_CLOCK_PROTOCOL  *This,
 | |
|   OUT UINT32               *TotalClocks
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT32      *ReturnValues;
 | |
| 
 | |
|   Status = ScmiGetProtocolAttributes (ScmiProtocolIdClock, &ReturnValues);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   *TotalClocks = SCMI_CLOCK_PROTOCOL_TOTAL_CLKS (ReturnValues[0]);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Return attributes of a clock device.
 | |
| 
 | |
|   @param[in]  This        A Pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
|   @param[in]  ClockId     Identifier for the clock device.
 | |
| 
 | |
|   @param[out] Enabled         If TRUE, the clock device is enabled.
 | |
|   @param[out] ClockAsciiName  A NULL terminated ASCII string with the clock
 | |
|                               name, of up to 16 bytes.
 | |
| 
 | |
|   @retval EFI_SUCCESS          Clock device attributes are returned.
 | |
|   @retval EFI_DEVICE_ERROR     SCP returns an SCMI error.
 | |
|   @retval !(EFI_SUCCESS)       Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockGetClockAttributes (
 | |
|   IN  SCMI_CLOCK_PROTOCOL  *This,
 | |
|   IN  UINT32               ClockId,
 | |
|   OUT BOOLEAN              *Enabled,
 | |
|   OUT CHAR8                *ClockAsciiName
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32            *MessageParams;
 | |
|   CLOCK_ATTRIBUTES  *ClockAttributes;
 | |
|   SCMI_COMMAND      Cmd;
 | |
|   UINT32            PayloadLength;
 | |
| 
 | |
|   Status = ScmiCommandGetPayload (&MessageParams);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   *MessageParams = ClockId;
 | |
| 
 | |
|   Cmd.ProtocolId = ScmiProtocolIdClock;
 | |
|   Cmd.MessageId  = ScmiMessageIdClockAttributes;
 | |
| 
 | |
|   PayloadLength = sizeof (ClockId);
 | |
| 
 | |
|   Status = ScmiCommandExecute (
 | |
|              &Cmd,
 | |
|              &PayloadLength,
 | |
|              (UINT32 **)&ClockAttributes
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // TRUE if bit 0 of ClockAttributes->Attributes is set.
 | |
|   *Enabled = CLOCK_ENABLED (ClockAttributes->Attributes);
 | |
| 
 | |
|   AsciiStrCpyS (
 | |
|     ClockAsciiName,
 | |
|     SCMI_MAX_STR_LEN,
 | |
|     (CONST CHAR8 *)ClockAttributes->ClockName
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Return list of rates supported by a given clock device.
 | |
| 
 | |
|   @param[in] This        A pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
|   @param[in] ClockId     Identifier for the clock device.
 | |
| 
 | |
|   @param[out] Format      ScmiClockRateFormatDiscrete: Clock device
 | |
|                           supports range of clock rates which are non-linear.
 | |
| 
 | |
|                           ScmiClockRateFormatLinear: Clock device supports
 | |
|                           range of linear clock rates from Min to Max in steps.
 | |
| 
 | |
|   @param[out] TotalRates  Total number of rates.
 | |
| 
 | |
|   @param[in,out] RateArraySize  Size of the RateArray.
 | |
| 
 | |
|   @param[out] RateArray   List of clock rates.
 | |
| 
 | |
|   @retval EFI_SUCCESS          List of clock rates is returned.
 | |
|   @retval EFI_DEVICE_ERROR     SCP returns an SCMI error.
 | |
|   @retval EFI_BUFFER_TOO_SMALL RateArraySize is too small for the result.
 | |
|                                It has been updated to the size needed.
 | |
|   @retval !(EFI_SUCCESS)       Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockDescribeRates (
 | |
|   IN     SCMI_CLOCK_PROTOCOL     *This,
 | |
|   IN     UINT32                  ClockId,
 | |
|   OUT    SCMI_CLOCK_RATE_FORMAT  *Format,
 | |
|   OUT    UINT32                  *TotalRates,
 | |
|   IN OUT UINT32                  *RateArraySize,
 | |
|   OUT    SCMI_CLOCK_RATE         *RateArray
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32                PayloadLength;
 | |
|   SCMI_COMMAND          Cmd;
 | |
|   UINT32                *MessageParams;
 | |
|   CLOCK_DESCRIBE_RATES  *DescribeRates;
 | |
|   CLOCK_RATE_DWORD      *Rate;
 | |
| 
 | |
|   UINT32  RequiredArraySize;
 | |
|   UINT32  RateIndex;
 | |
|   UINT32  RateNo;
 | |
|   UINT32  RateOffset;
 | |
| 
 | |
|   *TotalRates       = 0;
 | |
|   RequiredArraySize = 0;
 | |
|   RateIndex         = 0;
 | |
| 
 | |
|   Status = ScmiCommandGetPayload (&MessageParams);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Cmd.ProtocolId = ScmiProtocolIdClock;
 | |
|   Cmd.MessageId  = ScmiMessageIdClockDescribeRates;
 | |
| 
 | |
|   *MessageParams++ = ClockId;
 | |
| 
 | |
|   do {
 | |
|     *MessageParams = RateIndex;
 | |
| 
 | |
|     // Set Payload length, note PayloadLength is a IN/OUT parameter.
 | |
|     PayloadLength = sizeof (ClockId) + sizeof (RateIndex);
 | |
| 
 | |
|     // Execute and wait for response on a SCMI channel.
 | |
|     Status = ScmiCommandExecute (
 | |
|                &Cmd,
 | |
|                &PayloadLength,
 | |
|                (UINT32 **)&DescribeRates
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     if (*TotalRates == 0) {
 | |
|       // In the first iteration we will get number of returned rates and number
 | |
|       // of remaining rates. With this information calculate required size
 | |
|       // for rate array. If provided RateArraySize is less, return an
 | |
|       // error.
 | |
| 
 | |
|       *Format = RATE_FORMAT (DescribeRates->NumRatesFlags);
 | |
| 
 | |
|       *TotalRates = NUM_RATES (DescribeRates->NumRatesFlags)
 | |
|                     + NUM_REMAIN_RATES (DescribeRates->NumRatesFlags);
 | |
| 
 | |
|       if (*Format == ScmiClockRateFormatDiscrete) {
 | |
|         RequiredArraySize = (*TotalRates) * sizeof (UINT64);
 | |
|       } else {
 | |
|         // We need to return triplet of 64 bit value for each rate
 | |
|         RequiredArraySize = (*TotalRates) * 3 * sizeof (UINT64);
 | |
|       }
 | |
| 
 | |
|       if (RequiredArraySize > (*RateArraySize)) {
 | |
|         *RateArraySize = RequiredArraySize;
 | |
|         return EFI_BUFFER_TOO_SMALL;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     RateOffset = 0;
 | |
| 
 | |
|     if (*Format == ScmiClockRateFormatDiscrete) {
 | |
|       for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {
 | |
|         Rate = &DescribeRates->Rates[RateOffset++];
 | |
|         // Non-linear discrete rates.
 | |
|         RateArray[RateIndex++].DiscreteRate.Rate =
 | |
|           ConvertTo64Bit (Rate->Low, Rate->High);
 | |
|       }
 | |
|     } else {
 | |
|       for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {
 | |
|         // Linear clock rates from minimum to maximum in steps
 | |
|         // Minimum clock rate.
 | |
|         Rate                                    = &DescribeRates->Rates[RateOffset++];
 | |
|         RateArray[RateIndex].ContinuousRate.Min =
 | |
|           ConvertTo64Bit (Rate->Low, Rate->High);
 | |
| 
 | |
|         Rate = &DescribeRates->Rates[RateOffset++];
 | |
|         // Maximum clock rate.
 | |
|         RateArray[RateIndex].ContinuousRate.Max =
 | |
|           ConvertTo64Bit (Rate->Low, Rate->High);
 | |
| 
 | |
|         Rate = &DescribeRates->Rates[RateOffset++];
 | |
|         // Step.
 | |
|         RateArray[RateIndex++].ContinuousRate.Step =
 | |
|           ConvertTo64Bit (Rate->Low, Rate->High);
 | |
|       }
 | |
|     }
 | |
|   } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);
 | |
| 
 | |
|   // Update RateArraySize with RequiredArraySize.
 | |
|   *RateArraySize = RequiredArraySize;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Get clock rate.
 | |
| 
 | |
|   @param[in]  This        A Pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
|   @param[in]  ClockId     Identifier for the clock device.
 | |
| 
 | |
|   @param[out]  Rate       Clock rate.
 | |
| 
 | |
|   @retval EFI_SUCCESS          Clock rate is returned.
 | |
|   @retval EFI_DEVICE_ERROR     SCP returns an SCMI error.
 | |
|   @retval !(EFI_SUCCESS)       Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockRateGet (
 | |
|   IN  SCMI_CLOCK_PROTOCOL  *This,
 | |
|   IN  UINT32               ClockId,
 | |
|   OUT UINT64               *Rate
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32            *MessageParams;
 | |
|   CLOCK_RATE_DWORD  *ClockRate;
 | |
|   SCMI_COMMAND      Cmd;
 | |
| 
 | |
|   UINT32  PayloadLength;
 | |
| 
 | |
|   Status = ScmiCommandGetPayload (&MessageParams);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Fill arguments for clock protocol command.
 | |
|   *MessageParams = ClockId;
 | |
| 
 | |
|   Cmd.ProtocolId = ScmiProtocolIdClock;
 | |
|   Cmd.MessageId  = ScmiMessageIdClockRateGet;
 | |
| 
 | |
|   PayloadLength = sizeof (ClockId);
 | |
| 
 | |
|   // Execute and wait for response on a SCMI channel.
 | |
|   Status = ScmiCommandExecute (
 | |
|              &Cmd,
 | |
|              &PayloadLength,
 | |
|              (UINT32 **)&ClockRate
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   *Rate = ConvertTo64Bit (ClockRate->Low, ClockRate->High);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Set clock rate.
 | |
| 
 | |
|   @param[in]  This        A Pointer to SCMI_CLOCK_PROTOCOL Instance.
 | |
|   @param[in]  ClockId     Identifier for the clock device.
 | |
|   @param[in]  Rate        Clock rate.
 | |
| 
 | |
|   @retval EFI_SUCCESS          Clock rate set success.
 | |
|   @retval EFI_DEVICE_ERROR     SCP returns an SCMI error.
 | |
|   @retval !(EFI_SUCCESS)       Other errors.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| ClockRateSet (
 | |
|   IN SCMI_CLOCK_PROTOCOL  *This,
 | |
|   IN UINT32               ClockId,
 | |
|   IN UINT64               Rate
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                 Status;
 | |
|   CLOCK_RATE_SET_ATTRIBUTES  *ClockRateSetAttributes;
 | |
|   SCMI_COMMAND               Cmd;
 | |
|   UINT32                     PayloadLength;
 | |
| 
 | |
|   Status = ScmiCommandGetPayload ((UINT32 **)&ClockRateSetAttributes);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Fill arguments for clock protocol command.
 | |
|   ClockRateSetAttributes->ClockId   = ClockId;
 | |
|   ClockRateSetAttributes->Flags     = CLOCK_SET_DEFAULT_FLAGS;
 | |
|   ClockRateSetAttributes->Rate.Low  = (UINT32)Rate;
 | |
|   ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);
 | |
| 
 | |
|   Cmd.ProtocolId = ScmiProtocolIdClock;
 | |
|   Cmd.MessageId  = ScmiMessageIdClockRateSet;
 | |
| 
 | |
|   PayloadLength = sizeof (CLOCK_RATE_SET_ATTRIBUTES);
 | |
| 
 | |
|   // Execute and wait for response on a SCMI channel.
 | |
|   Status = ScmiCommandExecute (
 | |
|              &Cmd,
 | |
|              &PayloadLength,
 | |
|              NULL
 | |
|              );
 | |
| 
 | |
|   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 = ScmiProtocolIdClock;
 | |
|   Cmd.MessageId  = ScmiMessageIdClockConfigSet;
 | |
| 
 | |
|   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,
 | |
|   ClockGetTotalClocks,
 | |
|   ClockGetClockAttributes,
 | |
|   ClockDescribeRates,
 | |
|   ClockRateGet,
 | |
|   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.
 | |
| 
 | |
|   @retval EFI_SUCCESS            Clock protocol interface installed successfully.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ScmiClockProtocolInit (
 | |
|   IN EFI_HANDLE  *Handle
 | |
|   )
 | |
| {
 | |
|   return gBS->InstallMultipleProtocolInterfaces (
 | |
|                 Handle,
 | |
|                 &gArmScmiClockProtocolGuid,
 | |
|                 &ScmiClockProtocol,
 | |
|                 &gArmScmiClock2ProtocolGuid,
 | |
|                 &ScmiClock2Protocol,
 | |
|                 NULL
 | |
|                 );
 | |
| }
 |