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

Pankaj Bansal posted 28 patches 5 years, 10 months ago
There is a newer version of this series
[edk2-devel] [PATCH v2 16/28] Platform/NXP/LS1043aRdbPkg: Add Clock retrieval APIs
Posted by Pankaj Bansal 5 years, 10 months ago
From: Pankaj Bansal <pankaj.bansal@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@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
+} 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 (#56018): https://edk2.groups.io/g/devel/message/56018
Mute This Topic: https://groups.io/mt/72077457/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v2 16/28] Platform/NXP/LS1043aRdbPkg: Add Clock retrieval APIs
Posted by Leif Lindholm 5 years, 10 months ago
On Fri, Mar 20, 2020 at 20:05:31 +0530, Pankaj Bansal wrote:
> From: Pankaj Bansal <pankaj.bansal@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@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/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v2 16/28] Platform/NXP/LS1043aRdbPkg: Add Clock retrieval APIs
Posted by Pankaj Bansal 5 years, 10 months ago

> -----Original Message-----
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Wednesday, April 1, 2020 6:17 PM
> To: Pankaj Bansal (OSS) <pankaj.bansal@oss.nxp.com>
> Cc: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Michael D Kinney
> <michael.d.kinney@intel.com>; devel@edk2.groups.io; Varun Sethi
> <V.Sethi@nxp.com>; Samer El-Haj-Mahmoud <Samer.El-Haj-
> Mahmoud@arm.com>; Jon Nettleton <jon@solid-run.com>
> Subject: Re: [PATCH v2 16/28] Platform/NXP/LS1043aRdbPkg: Add Clock
> retrieval APIs
> 
> On Fri, Mar 20, 2020 at 20:05:31 +0530, Pankaj Bansal wrote:
> > From: Pankaj Bansal <pankaj.bansal@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@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?
> 

ok

> /
>     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 (#56976): https://edk2.groups.io/g/devel/message/56976
Mute This Topic: https://groups.io/mt/72077457/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-