From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by mx.groups.io with SMTP id smtpd.web11.2951.1587633551019263698 for ; Thu, 23 Apr 2020 02:19:11 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=fZDRmRWi; spf=pass (domain: nuviainc.com, ip: 209.85.221.67, mailfrom: leif@nuviainc.com) Received: by mail-wr1-f67.google.com with SMTP id d15so4346722wrx.3 for ; Thu, 23 Apr 2020 02:19:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=ZsKagpToPURFKVjTAaBqAF76jJEzDxyc537B1BIrrkM=; b=fZDRmRWiw8NXu+F55WNpa4ABBsTGKqcnt8Hbp/Ywmyt5DJJvbiK6G6nB+rHzK1yqzg hebdzoXstKEBgt3pCc1CnAS0m+d7/acql+2EDi7HXmUyKeZ1N5LEHfzDo+ABOLSWRMda NyOjxg3N7v50Ovz+BiwTJC9O2S9yshW2L11pwp90mrvEwWnOBI/1t6b+gzpCxoRfvqAv rKijiIDONz1IpgIKKEvoRuf1RJvD67DY+oiWQJnYSWEdC54BrMG6t7u7Dxz39+t0P4Zz 8AtYy3pfYVsopuz5zloynnSCks76vOa+LlUWBl5JV5XhmmpRV1qwNox/MKUa54LzpxVr RbFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ZsKagpToPURFKVjTAaBqAF76jJEzDxyc537B1BIrrkM=; b=T5Eu3V1R0XbOuKbhvjFzivYXP/d4AlQ4vqaP4ywIzCrEecxpk4j5tHuEjFhHPazLsr SRLsUKYdizK1A3NoMK7EymLVyyaXXULVKtcaz1EMKsGZQ1ELbwsp6ZKRmp2vvQlGv5Fc pPH6DG5IUwgNgySY8zK1mViSEvq5EjBedrZdpGadl8PbeptOWzfwSPp3kEq3sj2D//iz 9/gbW3inbWktGDhsUP4RD68KBvjjPZF2I72s8uElmfnUIr6FM8f/n8C8v+ua6N2Lv9wx 8+RESmMUwSZpEGFQIrAZUNk7Qkf/o1JXTJ2QRFQLw3BnPmTUoc4y1mwTko8Z/1r8lzGU l1Uw== X-Gm-Message-State: AGi0PuYW63fGVwP32kDPY7dqBsEerND5KH9tnfPbX23Il5mWvik30WDB 9fW0N8Hw2h9+BaNlnQwjm4LJzg== X-Google-Smtp-Source: APiQypJky9GEOuRoClsO/+DGS+ELpRcoqq0l7Nh0jtLFDB5Ftg8sZfaqbO4CIPxvZaf6DzqskuVACg== X-Received: by 2002:adf:9564:: with SMTP id 91mr3953687wrs.246.1587633549433; Thu, 23 Apr 2020 02:19:09 -0700 (PDT) Return-Path: Received: from vanye ([2001:470:1f09:12f0:b26e:bfff:fea9:f1b8]) by smtp.gmail.com with ESMTPSA id g15sm2771646wrp.96.2020.04.23.02.19.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Apr 2020 02:19:08 -0700 (PDT) Date: Thu, 23 Apr 2020 10:19:06 +0100 From: "Leif Lindholm" To: Pankaj Bansal Cc: Meenakshi Aggarwal , Michael D Kinney , devel@edk2.groups.io, Varun Sethi , Samer El-Haj-Mahmoud , Jon Nettleton , Ard Biesheuvel Subject: Re: [PATCH edk2-platforms v3 13/24] Platform/NXP/LS1043aRdbPkg: Add Clock retrieval APIs Message-ID: <20200423091906.GS14075@vanye> References: <20200415121342.9246-1-pankaj.bansal@oss.nxp.com> <20200415121342.9246-14-pankaj.bansal@oss.nxp.com> MIME-Version: 1.0 In-Reply-To: <20200415121342.9246-14-pankaj.bansal@oss.nxp.com> User-Agent: Mutt/1.10.1 (2018-07-13) Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Apr 15, 2020 at 17:43:31 +0530, Pankaj Bansal wrote: > From: Pankaj Bansal > > 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 Reviewed-by: Leif Lindholm > --- > > Notes: > - sorted NXP_IP_CLOCK enum alphabetically > > Silicon/NXP/Library/SocLib/LS1043aSocLib.inf | 1 + > Silicon/NXP/Include/Library/SocLib.h | 44 ++++++++++++++++ > Silicon/NXP/Include/Ppi/NxpPlatformGetClock.h | 53 ++++++++++++++++++++ > Silicon/NXP/LS1043A/Include/Soc.h | 11 ++++ > Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.c | 51 +++++++++++++++++++ > Silicon/NXP/Library/SocLib/Chassis2/Soc.c | 52 +++++++++++++++++++ > 6 files changed, 212 insertions(+) > > 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 @@ > ArmPkg/ArmPkg.dec > MdeModulePkg/MdeModulePkg.dec > MdePkg/MdePkg.dec > + Silicon/NXP/LS1043A/LS1043A.dec > Silicon/NXP/NxpQoriqLs.dec > > [LibraryClasses] > 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 > +#include > + > +/** > + 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..bc086bc5b337 > --- /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 > + > +typedef enum _NXP_IP_CLOCK { > + NXP_CORE_CLOCK, > + NXP_I2C_CLOCK, > + NXP_SYSTEM_CLOCK, > + NXP_UART_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 > + > /** > 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/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 > +#include > #include > +#include > > 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/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 > #include > #include > +#include > +#include > > /** > 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 > **/ > -- > 2.17.1 >