[edk2-devel] [PATCH v2 16/28] Platform/NXP/LS1043aRdbPkg: Add Clock retrieval APIs

Leif Lindholm leif at nuviainc.com
Wed Apr 1 12:46:31 UTC 2020


On Fri, Mar 20, 2020 at 20:05:31 +0530, Pankaj Bansal wrote:
> From: Pankaj Bansal <pankaj.bansal at nxp.com>
> 
> The SOC takes primary clocking input from the external signal (a clock
> generator on board). The input (frequency) is multiplied using multiple
> phase locked loops (PLL) to create a variety of frequencies which can
> then be passed to a variety of internal logic, including cores and
> peripheral IP modules.
> 
> Therefore, move the clock retrieval APIs to Platform Lib.
> The Input clock is retrieved from board components in Platform Lib, and
> passed on to SOC Lib APIs to get the correct clock for an IP (after PLL
> multiplication).
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal at nxp.com>
> ---
>  .../Library/ArmPlatformLib/ArmPlatformLib.c   | 51 ++++++++++++++++++
>  Silicon/NXP/Include/Library/SocLib.h          | 44 +++++++++++++++
>  Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h | 53 +++++++++++++++++++
>  Silicon/NXP/LS1043A/Include/Soc.h             | 11 ++++
>  Silicon/NXP/Library/SocLib/Chassis2/Soc.c     | 52 ++++++++++++++++++
>  Silicon/NXP/Library/SocLib/LS1043aSocLib.inf  |  1 +
>  6 files changed, 212 insertions(+)
>  create mode 100644 Silicon/NXP/Include/Library/SocLib.h
>  create mode 100644 Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h
> 
> diff --git a/Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.c
> index 718c71bf02eb..7f5872a78cfc 100644
> --- a/Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.c
> +++ b/Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.c
> @@ -12,10 +12,60 @@
>  **/
>  
>  #include <Library/ArmPlatformLib.h>
> +#include <Library/SocLib.h>
>  #include <Ppi/ArmMpCoreInfo.h>
> +#include <Ppi/NxpPlatformGetClock.h>
>  
>  extern VOID SocInit (VOID);
>  
> +/**
> +  Get the clocks supplied by Platform(Board) to NXP Layerscape SOC IPs
> +
> +  @param[in]  ClockType  Variable of Type NXP_IP_CLOCK. Indicates which IP clock
> +                         is to be retrieved.
> +  @param[in]  ...        Variable argument list which is parsed based on
> +                         ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then
> +                         the second argument will be interpreted as controller
> +                         number.
> +                         if ClockType is NXP_CORE_CLOCK, then second argument
> +                         is interpreted as cluster number and third argument is
> +                         interpreted as core number (within the cluster)
> +
> +  @return                Actual Clock Frequency. Return value 0 should be
> +                         interpreted as clock not being provided to IP.
> +**/
> +UINT64
> +EFIAPI
> +NxpPlatformGetClock(
> +  IN  UINT32  ClockType,
> +  ...
> +  )
> +{
> +  UINT64      Clock;
> +  VA_LIST     Args;
> +
> +  Clock = 0;
> +
> +  VA_START (Args, ClockType);
> +
> +  switch (ClockType) {
> +  case NXP_SYSTEM_CLOCK:
> +    Clock = 100 * 1000 * 1000; // 100 MHz
> +    break;
> +  case NXP_I2C_CLOCK:
> +  case NXP_UART_CLOCK:
> +    Clock = NxpPlatformGetClock (NXP_SYSTEM_CLOCK);
> +    Clock = SocGetClock (Clock, ClockType, Args);
> +    break;
> +  default:
> +    break;
> +  }
> +
> +  VA_END (Args);
> +
> +  return Clock;
> +}
> +
>  /**
>    Return the current Boot Mode
>  
> @@ -69,6 +119,7 @@ PrePeiCoreGetMpCoreInfo (
>  }
>  
>  ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
> +NXP_PLATFORM_GET_CLOCK_PPI gPlatformGetClockPpi = { NxpPlatformGetClock };
>  
>  EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {
>    {
> diff --git a/Silicon/NXP/Include/Library/SocLib.h b/Silicon/NXP/Include/Library/SocLib.h
> new file mode 100644
> index 000000000000..749aa230dec5
> --- /dev/null
> +++ b/Silicon/NXP/Include/Library/SocLib.h
> @@ -0,0 +1,44 @@
> +/** @file
> +
> +  Copyright 2020 NXP
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef SOC_LIB_H__
> +#define SOC_LIB_H__
> +
> +#include <Uefi.h>
> +#include <Ppi/NxpPlatformGetClock.h>
> +
> +/**
> +  Return the input clock frequency to an IP Module.
> +  This function reads the RCW bits and calculates the  PLL multipler/divider
> +  values to be applied to various IP modules.
> +  If a module is disabled or doesn't exist on platform, then return zero.
> +
> +  @param[in]  BaseClock  Base clock to which PLL multipler/divider values is
> +                         to be applied.
> +  @param[in]  ClockType  Variable of Type NXP_IP_CLOCK. Indicates which IP clock
> +                         is to be retrieved.
> +  @param[in]  Args       Variable argument list which is parsed based on
> +                         ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then
> +                         the second argument will be interpreted as controller
> +                         number. e.g. if there are four i2c controllers in SOC,
> +                         then this value can be 0, 1, 2, 3
> +                         e.g. if ClockType is NXP_CORE_CLOCK, then second
> +                         argument is interpreted as cluster number and third
> +                         argument is interpreted as core number (within the
> +                         cluster)
> +
> +  @return                Actual Clock Frequency. Return value 0 should be
> +                         interpreted as clock not being provided to IP.
> +**/
> +UINT64
> +SocGetClock (
> +  IN  UINT64        BaseClock,
> +  IN  NXP_IP_CLOCK  ClockType,
> +  IN  VA_LIST       Args
> +  );
> +
> +#endif // SOC_LIB_H__
> diff --git a/Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h b/Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h
> new file mode 100644
> index 000000000000..6b553d36ce5b
> --- /dev/null
> +++ b/Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h
> @@ -0,0 +1,53 @@
> +/** @file
> +*
> +*  Copyright 2020 NXP
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#ifndef NXP_PLATFORM_PPI_H__
> +#define NXP_PLATFORM_PPI_H__
> +
> +#include <Uefi.h>
> +
> +typedef enum _NXP_IP_CLOCK {
> +  NXP_SYSTEM_CLOCK,
> +  NXP_CORE_CLOCK,
> +  NXP_UART_CLOCK,
> +  NXP_I2C_CLOCK

Will this enum be used by standalone drivers/applications?
If not, could the members be sorted alphabetically?

/
    Leif

> +} NXP_IP_CLOCK;
> +
> +/**
> +  Get the clocks supplied by Platform(Board) to NXP Layerscape SOC IPs
> +
> +  @param[in]  ClockType  Variable of Type NXP_IP_CLOCK. Indicates which IP clock
> +                         is to be retrieved.
> +  @param[in]  ...        Variable argument list which is parsed based on
> +                         ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then
> +                         the second argument will be interpreted as controller
> +                         number. e.g. if there are four i2c controllers in SOC,
> +                         then this value can be 0, 1, 2, 3
> +                         e.g. if ClockType is NXP_CORE_CLOCK, then second
> +                         argument is interpreted as cluster number and third
> +                         argument is interpreted as core number (within the
> +                         cluster)
> +
> +  @return                Actual Clock Frequency. Return value 0 should be
> +                         interpreted as clock not being provided to IP.
> +**/
> +typedef
> +UINT64
> +(EFIAPI * NXP_PLATFORM_GET_CLOCK)(
> +  IN NXP_IP_CLOCK ClockType,
> +  ...
> +  );
> +
> +typedef struct {
> +  NXP_PLATFORM_GET_CLOCK  PlatformGetClock;
> +} NXP_PLATFORM_GET_CLOCK_PPI;
> +
> +extern NXP_PLATFORM_GET_CLOCK_PPI gPlatformGetClockPpi;
> +
> +#endif // NXP_PLATFORM_PPI_H__
> +
> diff --git a/Silicon/NXP/LS1043A/Include/Soc.h b/Silicon/NXP/LS1043A/Include/Soc.h
> index 441871757d67..e62de570da8a 100644
> --- a/Silicon/NXP/LS1043A/Include/Soc.h
> +++ b/Silicon/NXP/LS1043A/Include/Soc.h
> @@ -8,6 +8,8 @@
>  #ifndef SOC_H__
>  #define SOC_H__
>  
> +#include <Chassis2/NxpSoc.h>
> +
>  /**
>    Soc Memory Map
>  **/
> @@ -41,4 +43,13 @@
>  #define LS1043A_I2C_SIZE             0x10000
>  #define LS1043A_I2C_NUM_CONTROLLERS  4
>  
> +#define LS1043A_DCFG_ADDRESS         CHASSIS2_DCFG_ADDRESS
> +
> +/**
> +  Reset Control Word (RCW) Bits
> +**/
> +#define SYS_PLL_RAT(x)  (((x) & 0x7c) >> 2) // Bits 2-6
> +
> +typedef CCSR_GUR LS1043A_DEVICE_CONFIG;
> +
>  #endif // SOC_H__
> diff --git a/Silicon/NXP/Library/SocLib/Chassis2/Soc.c b/Silicon/NXP/Library/SocLib/Chassis2/Soc.c
> index 98ca2e162f7b..480d8d18fb9f 100644
> --- a/Silicon/NXP/Library/SocLib/Chassis2/Soc.c
> +++ b/Silicon/NXP/Library/SocLib/Chassis2/Soc.c
> @@ -18,6 +18,8 @@
>  #include <Library/PcdLib.h>
>  #include <Library/PrintLib.h>
>  #include <Library/SerialPortLib.h>
> +#include <Library/SocLib.h>
> +#include <Soc.h>
>  
>  /**
>    Calculate the frequency of various controllers and
> @@ -50,6 +52,56 @@ GetSysInfo (
>                  CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
>  }
>  
> +/**
> +  Return the input clock frequency to an IP Module.
> +  This function reads the RCW bits and calculates the  PLL multipler/divider
> +  values to be applied to various IP modules.
> +  If a module is disabled or doesn't exist on platform, then return zero.
> +
> +  @param[in]  BaseClock  Base clock to which PLL multipler/divider values is
> +                         to be applied.
> +  @param[in]  ClockType  Variable of Type NXP_IP_CLOCK. Indicates which IP clock
> +                         is to be retrieved.
> +  @param[in]  Args       Variable argument list which is parsed based on
> +                         ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then
> +                         the second argument will be interpreted as controller
> +                         number. e.g. if there are four i2c controllers in SOC,
> +                         then this value can be 0, 1, 2, 3
> +                         e.g. if ClockType is NXP_CORE_CLOCK, then second
> +                         argument is interpreted as cluster number and third
> +                         argument is interpreted as core number (within the
> +                         cluster)
> +
> +  @return                Actual Clock Frequency. Return value 0 should be
> +                         interpreted as clock not being provided to IP.
> +**/
> +UINT64
> +SocGetClock (
> +  IN  UINT64        BaseClock,
> +  IN  NXP_IP_CLOCK  ClockType,
> +  IN  VA_LIST       Args
> +  )
> +{
> +  LS1043A_DEVICE_CONFIG  *Dcfg;
> +  UINT32                 RcwSr;
> +  UINT64                 ReturnValue;
> +
> +  ReturnValue = 0;
> +  Dcfg = (LS1043A_DEVICE_CONFIG  *)LS1043A_DCFG_ADDRESS;
> +
> +  switch (ClockType) {
> +  case NXP_UART_CLOCK:
> +  case NXP_I2C_CLOCK:
> +    RcwSr = GurRead ((UINTN)&Dcfg->RcwSr[0]);
> +    ReturnValue = BaseClock * SYS_PLL_RAT (RcwSr);
> +    break;
> +  default:
> +    break;
> +  }
> +
> +  return ReturnValue;
> +}
> +
>  /**
>    Function to initialize SoC specific constructs
>   **/
> diff --git a/Silicon/NXP/Library/SocLib/LS1043aSocLib.inf b/Silicon/NXP/Library/SocLib/LS1043aSocLib.inf
> index 99d89498e0e2..3d38a7e58b91 100644
> --- a/Silicon/NXP/Library/SocLib/LS1043aSocLib.inf
> +++ b/Silicon/NXP/Library/SocLib/LS1043aSocLib.inf
> @@ -17,6 +17,7 @@ [Packages]
>    ArmPkg/ArmPkg.dec
>    MdeModulePkg/MdeModulePkg.dec
>    MdePkg/MdePkg.dec
> +  Silicon/NXP/LS1043A/LS1043A.dec
>    Silicon/NXP/NxpQoriqLs.dec
>  
>  [LibraryClasses]
> -- 
> 2.17.1
> 

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#56845): https://edk2.groups.io/g/devel/message/56845
Mute This Topic: https://groups.io/mt/72077457/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list