/** @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;

  do {
    MessageParams[0] = ClockId;
    MessageParams[1] = 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);

      RequiredArraySize = (*TotalRates) * 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 {
      // 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
                );
}
