From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: chasel.chiu@intel.com) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by groups.io with SMTP; Fri, 16 Aug 2019 18:16:56 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 18:16:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="179835082" Received: from pgsmsx114.gar.corp.intel.com ([10.108.55.203]) by orsmga003.jf.intel.com with ESMTP; 16 Aug 2019 18:16:50 -0700 Received: from pgsmsx110.gar.corp.intel.com (10.221.44.111) by pgsmsx114.gar.corp.intel.com (10.108.55.203) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sat, 17 Aug 2019 09:14:31 +0800 Received: from pgsmsx111.gar.corp.intel.com ([169.254.2.22]) by PGSMSX110.gar.corp.intel.com ([169.254.13.32]) with mapi id 14.03.0439.000; Sat, 17 Aug 2019 09:14:30 +0800 From: "Chiu, Chasel" To: "Kubacki, Michael A" , "devel@edk2.groups.io" CC: "Chaganty, Rangasai V" , "Desimone, Nathaniel L" , "Gao, Liming" , "Kinney, Michael D" , "Sinha, Ankit" Subject: Re: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances Thread-Topic: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances Thread-Index: AQHVVJEcikaWUpT/d0WrjiDCmMM4zab+iQnA Date: Sat, 17 Aug 2019 01:14:30 +0000 Message-ID: <3C3EFB470A303B4AB093197B6777CCEC5046239E@PGSMSX111.gar.corp.intel.com> References: <20190817001603.30632-1-michael.a.kubacki@intel.com> <20190817001603.30632-24-michael.a.kubacki@intel.com> In-Reply-To: <20190817001603.30632-24-michael.a.kubacki@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNmE4Yzc1YzgtMzJkNC00YWFiLTkyOTMtYWQ0ZDcwMGFlMjk4IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiNTNCVmppcXg0UHh6QlhXb0liYmxBdFNYVnpjV1ZGbXRHcTVNS0FnR3hqS0t1WkZGMUdhRGsxcktyWmIxUlRrMCJ9 x-ctpclassification: CTP_NT x-originating-ip: [172.30.20.206] MIME-Version: 1.0 Return-Path: chasel.chiu@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Chasel Chiu > -----Original Message----- > From: Kubacki, Michael A > Sent: Saturday, August 17, 2019 8:16 AM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V ; Chiu, Chasel > ; Desimone, Nathaniel L > ; Gao, Liming ; > Kinney, Michael D ; Sinha, Ankit > > Subject: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add P= EI > private library instances >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2082 >=20 > Adds PCH PEI private library class instances. These library instances > may be compatible with other boot phases as indicated by the library type= . >=20 > * PeiDxeSmmGpioPrivateLibCnl > * PeiDxeSmmPchDmiLib > * PeiDxeSmmPchDmiWithS3Lib > * PeiDxeSmmPchInitCommonLib > * PeiDxeSmmPchPciExpressHelpersLib > * PeiDxeSmmPchPsfPrivateLibCnl > * PeiDxeSmmPmcPrivateLibCnl > * PeiDxeSmmPmcPrivateLibWithS3 > * PeiGpioHelpersLib > * PeiGpioNameBufferLib > * PeiPmcPrivateLibCnl >=20 > Cc: Sai Chaganty > Cc: Chasel Chiu > Cc: Nate DeSimone > Cc: Liming Gao > Cc: Michael D Kinney > Cc: Ankit Sinha > Signed-off-by: Michael Kubacki > --- >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/PeiDxeSmmGpioPrivateLibCnl.inf | 45 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PeiDxeSmmPchDmiLib.inf | 40 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PeiDxeSmmPchDmiWithS3Lib.inf | 40 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCo > mmonLib/PeiDxeSmmPchInitCommonLib.inf | 34 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExp= r > essHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPri= v > ateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf | 41 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PeiDxeSmmPmcPrivateLibCnl.inf | 48 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PeiDxeSmmPmcPrivateLibWithS3.inf | 39 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PeiPmcPrivateLibCnl.inf | 40 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/= Pei > GpioHelpersLib.inf | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferL= i > b/PeiGpioNameBufferLib.inf | 35 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioNativePrivateLibInternal.h | 477 ++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmi14.h | 70 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmi15.h | 113 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExp= r > essHelpersLib/PchPciExpressHelpersLibrary.h | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPri= v > ateLib/PchPsfPrivateLibInternal.h | 490 ++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PmcPrivateLibInternal.h | 47 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioNamesCnl.c | 166 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioNativePrivateLib.c | 1304 +++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioNativePrivateLibCnl.c | 2275 +++++++++++++++= +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioPrivateLib.c | 752 ++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriva= t > eLib/GpioPrivateLibCnl.c | 225 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmi14.c | 67 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmi15.c | 113 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmiLib.c | 569 +++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib > /PchDmiWithS3Lib.c | 79 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCo > mmonLib/PchInitCommon.c | 221 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExp= r > essHelpersLib/PchPciExpressHelpersLibrary.c | 2407 > ++++++++++++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPri= v > ateLib/PchPsfPrivateLib.c | 542 +++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPri= v > ateLib/PchPsfPrivateLibCnl.c | 338 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PeiPmcPrivateLib.c | 92 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PmcPrivateLib.c | 1033 +++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PmcPrivateLibClient.c | 73 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PmcPrivateLibCnl.c | 360 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat > eLib/PmcPrivateLibWithS3.c | 194 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/= Pei > GpioHelpersLib.c | 356 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferL= i > b/GpioNameBufferPei.c | 68 + > 37 files changed, 12919 insertions(+) >=20 > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/PeiDxeSmmGpioPrivateLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/PeiDxeSmmGpioPrivateLibCnl.inf > new file mode 100644 > index 0000000000..318b54a99c > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/PeiDxeSmmGpioPrivateLibCnl.inf > @@ -0,0 +1,45 @@ > +## @file > +# Component description file for the PeiDxeSmmGpioPrivateLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmGpioPrivateLibCnl > +FILE_GUID =3D E078A734-BEA0-47CF-A476-3742316D01FC > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D GpioPrivateLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# > + > + > +[LibraryClasses] > + BaseLib > + IoLib > + DebugLib > + PmcLib > + PchInfoLib > + GpioLib > + GpioNameBufferLib > + SataLib > + > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > + GpioPrivateLib.c > + GpioNativePrivateLib.c > + GpioPrivateLibCnl.c > + GpioNativePrivateLibCnl.c > + GpioNamesCnl.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiLib.inf > new file mode 100644 > index 0000000000..b36fc15901 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiLib.inf > @@ -0,0 +1,40 @@ > +## @file > +# Component description file for the PeiDxeSmmPchDmiLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchDmiLib > +FILE_GUID =3D 067DC1C4-2668-4F06-9921-307514B66B34 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchDmiLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[LibraryClasses] > + BaseLib > + IoLib > + DebugLib > + PchInfoLib > + PchPcrLib > + > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > + PchDmiLib.c > + PchDmi14.c > + PchDmi15.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiWithS3Lib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiWithS3Lib.inf > new file mode 100644 > index 0000000000..1eda7cdba8 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PeiDxeSmmPchDmiWithS3Lib.inf > @@ -0,0 +1,40 @@ > +## @file > +# Component description file for the PeiDxeSmmPchDmiWithS3Lib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchDmiWithS3Lib > +FILE_GUID =3D 32CCA047-6AF0-46FF-83DA-32BA62484075 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchDmiWithS3Lib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[LibraryClasses] > + BaseLib > + IoLib > + DebugLib > + PchPcrLib > + PchInfoLib > + S3BootScriptLib > + PchDmiLib > + > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > + PchDmiWithS3Lib.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PeiDxeSmmPchInitCommonLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PeiDxeSmmPchInitCommonLib.inf > new file mode 100644 > index 0000000000..d81c428a1c > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PeiDxeSmmPchInitCommonLib.inf > @@ -0,0 +1,34 @@ > +## @file > +# Component description file for the PchInitCommonLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D PeiDxeSmmPchInitCommonLib > + FILE_GUID =3D E9C4FE04-8A79-43FA-B3E0-603359C31B4= 3 > + MODULE_TYPE =3D BASE > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D PchInitCommonLib > + > +[Sources] > + PchInitCommon.c > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > +[LibraryClasses] > + IoLib > + DebugLib > + PciSegmentLib > + PchCycleDecodingLib > + PchPcieRpLib > + PchSbiAccessLib > + PchInfoLib > + SataLib > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf > new file mode 100644 > index 0000000000..16b1c019b8 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf > @@ -0,0 +1,42 @@ > +## @file > +# Component description file for the PeiDxeSmmPchPciExpressHelpersLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchPciExpressHelpersLib > +FILE_GUID =3D 07E3F76D-6D26-419d-9053-58696A15B519 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchPciExpressHelpersLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# > + > + > + > +[LibraryClasses] > +IoLib > +DebugLib > +PchPcieRpLib > +PchPcrLib > +PchInfoLib > +GpioLib > +TimerLib > +PchInitCommonLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchPciExpressHelpersLibrary.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf > new file mode 100644 > index 0000000000..0ed9f30dcc > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf > @@ -0,0 +1,41 @@ > +## @file > +# PEI/DXE/SMM PCH PSF Private Lib for Cannon Lake PCH > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchPsfPrivateLibCnl > +FILE_GUID =3D 7A6C18CA-0353-433E-885D-DD68BFAD38BE > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchPsfPrivateLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[LibraryClasses] > + BaseLib > + IoLib > + DebugLib > + PciSegmentLib > + PchInfoLib > + PchPcrLib > + SataLib > + SaPlatformLib > + > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > + PchPsfPrivateLib.c > + PchPsfPrivateLibCnl.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibCnl.inf > new file mode 100644 > index 0000000000..adb154dd14 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibCnl.inf > @@ -0,0 +1,48 @@ > +## @file > +# PEI/DXE/SMM PCH PMC Private Lib for Cannon Lake PCH. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPmcPrivateLibCnl > +FILE_GUID =3D A1CB52AD-4FAB-4214-94A0-323E3BE4E934 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PmcPrivateLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +TimerLib > +PciSegmentLib > +PchInfoLib > +PchPcrLib > +PmcLib > +PchPsfPrivateLib > +PchDmiLib > +SataLib > +BaseMemoryLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Pcd] > +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress > + > + > +[Sources] > +PmcPrivateLib.c > +PmcPrivateLibClient.c > +PmcPrivateLibCnl.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf > new file mode 100644 > index 0000000000..cd1380dc43 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf > @@ -0,0 +1,39 @@ > +## @file > +# PEI/DXE/SMM PCH private PMC Lib. > +# This part of PMC lib includes S3BootScript support > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPmcPrivateLibWithS3 > +FILE_GUID =3D 5890CA5A-1955-4A02-A09C-01E4150606CC > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PmcPrivateLibWithS3 > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > +PmcLib > +PcdLib > +S3BootScriptLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PmcPrivateLibWithS3.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLibCnl.inf > new file mode 100644 > index 0000000000..ab3645c61d > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLibCnl.inf > @@ -0,0 +1,40 @@ > +## @file > +# PEI PCH PMC Private Lib for Cannon Lake PCH. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiPmcPrivateLibCnl > +FILE_GUID =3D 1DD4EA23-12F2-4F05-93AF-535476106D8C > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D PeiPmcPrivateLib > + > + > +[LibraryClasses] > +BaseLib > +BaseMemoryLib > +IoLib > +DebugLib > +PeiServicesLib > +PciSegmentLib > +ConfigBlockLib > +PchInfoLib > +PchPcrLib > +PmcLib > +PmcPrivateLib > +PchEspiLib > +GpioPrivateLib > +PeiItssLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > +[Sources] > +PeiPmcPrivateLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.inf > new file mode 100644 > index 0000000000..b6f786d80b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.inf > @@ -0,0 +1,42 @@ > +## @file > +# Component description file for the PeiGpioHelpersLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiGpioHelpersLib > +FILE_GUID =3D 1838E1E7-3CC4-4A74-90D9-B421EF2A579F > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D GpioHelpersLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +HobLib > +GpioLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PeiGpioHelpersLib.c > + > + > +[Guids] > +gGpioLibUnlockHobGuid > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/PeiGpioNameBufferLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/PeiGpioNameBufferLib.inf > new file mode 100644 > index 0000000000..3619a2e6a7 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/PeiGpioNameBufferLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# Component description file for the PeiGpioMemLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiGpioNameBufferLib > +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662CDAB863F2 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D GpioNameBufferLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 > +# > + > +[LibraryClasses] > +HobLib > +BaseLib > +IoLib > +DebugLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > +[Sources] > +GpioNameBufferPei.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibInternal.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibInternal.h > new file mode 100644 > index 0000000000..e081027c40 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibInternal.h > @@ -0,0 +1,477 @@ > +/** @file > + Header file for GPIO Private Lib Internal functions. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ > +#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ > + > +#include > + > +#define GPIO_PAD_NONE 0 > + > +/** > + This function provides SerialIo I2C controller pins > + > + @param[in] SerialIoI2cControllerNumber I2C controller > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoI2cPins ( > + IN UINT32 SerialIoI2cControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides SerialIo UART controller pins > + > + @param[in] SerialIoUartControllerNumber UART controller > + @param[in] HardwareFlowControl Hardware Flow control > + @param[in] PinMuxing UART controller pin muxing > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoUartPins ( > + IN UINT32 SerialIoUartControllerNumber, > + IN BOOLEAN HardwareFlowControl, > + IN UINT32 PinMuxing, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides SerialIo SPI controller pins > + > + @param[in] SerialIoSpiControllerNumber SPI controller > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoSpiPins ( > + IN UINT32 SerialIoSpiControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides ISH GP pin data > + > + @param[in] IshGpPinNumber ISH GP pin number > + > + @param[out] NativePin ISH GP pin > +**/ > +VOID > +GpioGetIshGpPin ( > + IN UINT32 IshGpPinNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ); > + > +/** > + This function provides ISH UART controller pins > + > + @param[in] IshUartControllerNumber ISH UART controller > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetIshUartPins ( > + IN UINT32 IshUartControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides ISH I2C controller pins > + > + @param[in] IshI2cControllerNumber ISH I2C controller > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetIshI2cPins ( > + IN UINT32 IshI2cControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides ISH SPI controller pins > + > + @param[in] IshSpiControllerNumber SPI controller > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetIshSpiPins ( > + IN UINT32 IshSpiControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides SCS SD CARD controller pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetScsSdCardPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides SCS SD CARD detect pin > + > + @retval GpioPin SD CARD Detect pin > +**/ > +GPIO_PAD > +GpioGetScsSdCardDetectPin ( > + VOID > + ); > + > +/** > + This function provides SCS eMMC controller pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetScsEmmcPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides HD Audio Link pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetHdAudioLinkPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides DMIC interface pins > + > + @param[in] DmicNumber DMIC interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaDmicPins ( > + IN UINT32 DmicNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides SSP/I2S interface pins > + > + @param[in] SspInterfaceNumber SSP/I2S interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaSspPins ( > + IN UINT32 SspInterfaceNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides SNDW interface pins > + > + @param[in] SndwInterfaceNumber SNDWx interface number > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaSndwPins ( > + IN UINT32 SndwInterfaceNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides SMBUS interface pins > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetSmbusPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides SATA DevSlp pin data > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + @param[out] NativePin SATA DevSlp pin > +**/ > +VOID > +GpioGetSataDevSlpPin ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ); > + > +/** > + This function provides PCIe CLKREQ pin data > + > + @param[in] ClkreqIndex CLKREQ# number > + @param[out] NativePin Native pin data > +**/ > +VOID > +GpioGetPcieClkReqPin ( > + IN UINT32 ClkreqIndex, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ); > + > +/** > + This function provides eDP pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetEdpPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides DDPx interface pins > + > + @param[in] DdpInterface DDPx interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetDdpPins ( > + IN GPIO_DDP DdpInterface, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi BT UART pins > + > + @param[in] ConnectionType CNVi BT UART connection type > + @param[out] VCnviBtUartPad Table with vCNV_BT_UARTx pads > + @param[out] VCnviBtUartPadMode vCNV_BT_UARTx pad mode > + @param[out] VUartForCnviBtPad Table with vUART0 pads > + @param[out] VUartForCnviBtPadMode vUART0 pad mode > +**/ > +VOID > +GpioGetCnviBtUartPins ( > + IN VGPIO_CNVI_BT_UART_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviBtUartPad, > + OUT GPIO_PAD_MODE *VCnviBtUartPadMode, > + OUT GPIO_PAD **VUartForCnviBtPad, > + OUT GPIO_PAD_MODE *VUartForCnviBtPadMode > + ); > + > +/** > + This function provides CNVi BT UART external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviBtUartExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi BT I2S pins > + > + @param[in] ConnectionType CNVi BT I2S connection type > + @param[out] VCnviBtI2sPad Table with vCNV_BT_I2Sx pads > + @param[out] VCnviBtI2sPadMode vCNV_BT_I2Sx pad mode > + @param[out] VSspForCnviBtPad Table with vSSP2 pads > + @param[out] VSspForCnviBtPadMode vSSP2 pad mode > +**/ > +VOID > +GpioGetCnviBtI2sPins ( > + IN VGPIO_CNVI_BT_I2S_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviBtI2sPad, > + OUT GPIO_PAD_MODE *VCnviBtI2sPadMode, > + OUT GPIO_PAD **VSspForCnviBtPad, > + OUT GPIO_PAD_MODE *VSspForCnviBtPadMode > + ); > + > +/** > + This function provides CNVi BT I2S external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviBtI2sExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi MFUART1 pins > + > + @param[in] ConnectionType CNVi MFUART1 connection type > + @param[out] VCnviBtI2sPad Table with vCNV_MFUART1x pads > + @param[out] VCnviBtI2sPadMode vCNV_MFUART1x pad mode > + @param[out] VSspForCnviBtPad Table with vISH_UART0 pads > + @param[out] VSspForCnviBtPadMode vISH_UART0 pad mode > +**/ > +VOID > +GpioGetCnviMfUart1Pins ( > + IN VGPIO_CNVI_MF_UART1_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviMfUart1Pad, > + OUT GPIO_PAD_MODE *VCnviMfUart1PadMode, > + OUT GPIO_PAD **VUartForCnviMfUart1Pad, > + OUT GPIO_PAD_MODE *VUartForCnviMfUart1PadMode > + ); > + > +/** > + This function provides CNVi MFUART1 external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviMfUart1ExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi Bluetooth Enable pad > + > + @retval GpioPad CNVi Bluetooth Enable pad > +**/ > +GPIO_PAD > +GpioGetCnviBtEnablePin ( > + VOID > + ); > + > +/** > + This function provides CNVi BRI RGI GPIO pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnvBriRgiPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi MFUART2 external pins > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnvMfUart2ExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ); > + > +/** > + This function provides CNVi BT interface select pin > + > + @retval GpioPad GPIO pad for CNVi BT interface select > +**/ > +GPIO_PAD > +GpioGetCnviBtIfSelectPin ( > + VOID > + ); > + > +/** > + This function provides CNVi BT Charging pin > + > + @retval GpioPad GPIO pad for CNVi BT Charging select > +**/ > +GPIO_PAD > +GpioGetCnviBtChargingPin ( > + VOID > + ); > + > +/** > + This function provides CNVi A4WP pin > + > + @param[out] GpioNativePad GPIO native pad for CNVi A4WP > +**/ > +VOID > +GpioGetCnviA4WpPin ( > + OUT GPIO_PAD_NATIVE_FUNCTION *GpioNativePad > + ); > + > +/** > + This function provides CNVi BT host wake int pin > + > + @retval GpioPad GPIO pad BT host wake int > +**/ > +GPIO_PAD > +GpioGetCnviBtHostWakeIntPin ( > + VOID > + ); > + > +/** > + This function provides IMGCLKOUT pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetImgClkOutPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ); > + > +/** > + This function provides PWRBTN pin > + > + @retval GpioPad PWRTBTN pin > +**/ > +GPIO_PAD > +GpioGetPwrBtnPin ( > + VOID > + ); > + > +/** > + This procedure enables debounce feature on a selected pad configured i= n > input mode > + Debounce time can be specified in microseconds. GPIO HW supports only > certain values > + according to below formula: > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock perio= d). > + RTC clock with f =3D 32 KHz is used for glitch filter. > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us). > + Supported DebounceTime values are following: > + DebounceTime =3D 0 -> Debounce feature disabled > + DebounceTime > 0 && < 250us -> Not supported > + DebounceTime =3D 250us - 1024000us -> Supported range (DebounceTime = =3D > 250us * 2^n) > + For values not supported by GPIO HW, function will round down > + to closest supported > + > + @param[in] GpioPad GPIO pad > + @param[in, out] DebounceTime Debounce Time in microseconds > + If Debounce Time =3D 0, Debouncer feat= ure will be > disabled > + Function will set DebounceTime argumen= t to > rounded supported value > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad or unsupported > DebounceDuration value > + @retval EFI_UNSUPPORTED GpioPad is not owned by host > +**/ > +EFI_STATUS > +GpioSetDebounceTimer ( > + IN GPIO_PAD GpioPad, > + IN OUT UINT32 *DebounceTime > + ); > + > +/** > + This function provides LPC pin > + > + @retval GpioPad LPC pin > +**/ > +GPIO_PAD > +GpioGetLpcPin ( > + VOID > + ); > + > +#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.h > new file mode 100644 > index 0000000000..1d50c04b0f > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.h > @@ -0,0 +1,70 @@ > +/** @file > + Internal header file for PCH DMI library for SIP14 > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef __PCH_DMI_14_H__ > +#define __PCH_DMI_14_H__ > + > +#include > +#include > + > +/** > + This function checks if DMI SIP14 Secured Register Lock (SRL) is set > + > + @retval SRL state > +**/ > +BOOLEAN > +IsPchDmi14Locked ( > + VOID > + ); > + > +/** > + Enable PCIe Relaxed Order for DMI SIP14 > +**/ > +VOID > +PchDmi14EnablePcieRelaxedOrder ( > + VOID > + ); > + > +/** > + This function will switch SAI value to be driven to IOSF Primary Fabri= c > + for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI. > + To be used when PCH is paired with CFL CPU. > +**/ > +VOID > +PchDmi14EnablePostBootSai ( > + VOID > + ); > + > +/** > + Secure Register Lock data > + > + @param[out] SrlRegOffset Register offset holding Secure Register= Lock > setting > + @param[out] SrlRegMask Mask for Secure Register Lock setting > +**/ > +VOID > +PchDmi14SrlRegData ( > + OUT UINT16 *SrlRegOffset, > + OUT UINT32 *SrlRegMask > + ); > + > +/** > + Get PCH DMI SIP14 Virtual Channel Control and Status registers > + > + @param[in] Vc The virtual channel number for progra= ming > + @param[out] DmiVcCtlAddress DMI Virtual Channel Control register > address > + @param[out] DmiVcStsAddress DMI Virtual Channel Status register > address > +**/ > +VOID > +PchDmi14VcRegs ( > + IN PCH_DMI_VC_TYPE Vc, > + OUT UINT16 *DmiVcCtlAddress, > + OUT UINT16 *DmiVcStsAddress > + ); > + > + > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.h > new file mode 100644 > index 0000000000..744a96fe14 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.h > @@ -0,0 +1,113 @@ > +/** @file > + Internal header file for PCH DMI library for SIP15 > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef __PCH_DMI_15_H__ > +#define __PCH_DMI_15_H__ > + > +#include > +#include > + > +/** > + This function checks if DMI SIP15 Secured Register Lock (SRL) is set > + > + @retval SRL state > +**/ > +BOOLEAN > +IsPchDmi15Locked ( > + VOID > + ); > + > +/** > + Set DMI thermal throttling to recommended configuration. > + It's intended only for P-DMI SIP15. > +**/ > +VOID > +PchDmi15SetRecommendedThermalThrottling ( > + VOID > + ); > + > +/** > + Set DMI thermal throttling to custom configuration. > + This function will configure Thermal Sensor 0/1/2/3 TargetWidth and se= t > + DMI Thermal Sensor Autonomous Width Enable. > + It's intended only for P-DMI SIP15. > + > + @param[in] DmiThermalThrottling DMI Thermal Throttling structur= e. > +**/ > +VOID > +PchDmi15SetCustomThermalThrottling ( > + IN DMI_THERMAL_THROTTLING DmiThermalThrottling > + ); > + > +/** > + Enable PCIe Relaxed Order for DMI SIP15 > +**/ > +VOID > +PchDmi15EnablePcieRelaxedOrder ( > + VOID > + ); > + > +/** > + This function will switch SAI value to be driven to IOSF Primary Fabri= c > + for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI. > + To be used when PCH is paired with CFL CPU. > +**/ > +VOID > +PchDmi15EnablePostBootSai ( > + VOID > + ); > + > +/** > + This function will do necessary configuration after platform > + should have switched to POSTBOOT_SAI. It needs to be called even if > + POSTBOOT_SAI was not set. > +**/ > +VOID > +PchDmi15ConfigAfterPostBootSai ( > + VOID > + ); > + > +/** > + Secure Register Lock data > + > + @param[out] SrlRegOffset Register offset holding Secure Register= Lock > setting > + @param[out] SrlRegMask Mask for Secure Register Lock setting > +**/ > +VOID > +PchDmi15SrlRegData ( > + OUT UINT16 *SrlRegOffset, > + OUT UINT32 *SrlRegMask > + ); > + > +/** > + Get PCH DMI SIP15 Virtual Channel Control and Status registers > + > + @param[in] Vc The virtual channel number for progra= ming > + @param[out] DmiVcCtlAddress DMI Virtual Channel Control register > address > + @param[out] DmiVcStsAddress DMI Virtual Channel Status register > address > +**/ > +VOID > +PchDmi15VcRegs ( > + IN PCH_DMI_VC_TYPE Vc, > + OUT UINT16 *DmiVcCtlAddress, > + OUT UINT16 *DmiVcStsAddress > + ); > + > +/** > + The function sets the Target Link Speed to GEN 3 in P-DMI SIP15. > + > + @param[in] TargetLinkSpeed Target Link Speed > + 2: GEN2 > + 3: GEN3 > +**/ > +VOID > +PchDmi15SetTargetLinkSpeed ( > + IN UINT8 TargetLinkSpeed > + ); > + > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.h > new file mode 100644 > index 0000000000..b14f24b18f > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.h > @@ -0,0 +1,42 @@ > +/** @file > + Header file for PCH Pci Express helps library implementation. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_ > +#define _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define LTR_VALUE_MASK (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 += BIT7 > + BIT8 + BIT9) > +#define LTR_SCALE_MASK (BIT10 + BIT11 + BIT12) > + > +#define CONFIG_WRITE_LOOP_COUNT 100000 > + > +// > +// LTR related macros > +// > +#define LTR_LATENCY_VALUE(x) ((x) & LTR_VALUE_MASK) > +#define LTR_SCALE_VALUE(x) (((x) & LTR_SCALE_MASK) >> 10) > +#define LTR_LATENCY_NS(x) (LTR_LATENCY_VALUE(x) * (1 << (5 = * > LTR_SCALE_VALUE(x)))) > + > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibInternal.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibInternal.h > new file mode 100644 > index 0000000000..f633df0411 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibInternal.h > @@ -0,0 +1,490 @@ > +/** @file > + This file contains internal header for PSF lib usage > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PCH_PSF_PRIVATE_LIB_INTERNAL_H_ > +#define _PCH_PSF_PRIVATE_LIB_INTERNAL_H_ > + > +#include > +#include > + > +#define PSF_PORT_NULL ((PSF_PORT){0,0}) > +#define PSF_IS_PORT_NULL(PsfPort) ((PsfPort.PsfPid =3D=3D 0) && > (PsfPort.RegBase =3D=3D 0)) > + > +/** > + Disable bridge (e.g. PCIe Root Port) at PSF level > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfDisableBridge ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Disable bridge (e.g. PCIe Root Port) at PSF level in RS3 > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfRs3DisableBridge ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Check if bridge (e.g. PCIe Root Port) is enabled at PSF level > + > + @param[in] PsfPort PSF PORT data structure > + > + @retval TRUE Bridge behind PSF Port is enabled > + FALSE Bridge behind PSF Port is disabled > +**/ > +BOOLEAN > +PsfIsBridgeEnabled ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Disable device IOSpace at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfDisableDeviceIoSpace ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Enable device IOSpace at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfEnableDeviceIoSpace ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Disable device Memory Space at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfDisableDeviceMemSpace ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Enable device Memory Space at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfEnableDeviceMemSpace ( > + IN PSF_PORT PsfPort > + ); > + > +/** > + Set device BARx address at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > + @param[in] BarNum BAR Number (0:BAR0, 1:BAR1, ...) > + @param[in] BarValue 32bit BAR value > +**/ > +VOID > +PsfSetDeviceBarValue ( > + IN PSF_PORT PsfPort, > + IN UINT8 BarNum, > + IN UINT32 BarValue > + ); > + > +/** > + Return PSF_PORT for TraceHub device > + > + @retval PsfPort PSF PORT structure for TraceHub device > +**/ > +PSF_PORT > +PsfTraceHubPort ( > + VOID > + ); > + > +/** > + This procedure will return PSF_PORT for TraceHub ACPI device > + > + @retval PsfPort PSF PORT structure for TraceHub ACPI device > +**/ > +PSF_PORT > +PsfTraceHubAcpiDevPort ( > + VOID > + ); > + > +/** > + Return PSF_PORT for HECI device > + > + @param[in] HeciDevice HECIx Device (HECI1-4) > + > + @retval PsfPort PSF PORT structure for HECI device > +**/ > +PSF_PORT > +PsfHeciPort ( > + IN UINT8 HeciDevice > + ); > + > +/** > + This procedure will return PSF_PORT for SOL device > + > + @retval PsfPort PSF PORT structure for SOL device > +**/ > +PSF_PORT > +PsfSolPort ( > + VOID > + ); > + > +/** > + Return PSF_PORT for ISH device > + > + @retval PsfPort PSF PORT structure for ISH device > +**/ > +PSF_PORT > +PsfIshPort ( > + VOID > + ); > + > +/** > + Return PSF_PORT for CNVi device > + > + @retval PsfPort PSF PORT structure for CNVi device > +**/ > +PSF_PORT > +PsfCnviPort ( > + VOID > + ); > + > +/** > + Return PSF_PORT for PMC device > + > + @retval PsfPort PSF PORT structure for PMC device > +**/ > +PSF_PORT > +PsfPmcPort ( > + VOID > + ); > + > +/** > + Return second level PSF_PORT to which PCIE Root Port device is connect= ed > (directly) > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe > +**/ > +PSF_PORT > +PsfPcieSecondLevelPort ( > + IN UINT32 RpIndex > + ); > + > +/** > + Return PSF_PORT at root PSF level to which PCIe Root Port device is > connected > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe > + > +**/ > +PSF_PORT > +PsfRootPciePort ( > + IN UINT32 RpIndex > + ); > + > +/** > + Return RS3 PSF_PORT at root PSF level to which PCIe Root Port device i= s > connected > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe > +**/ > +PSF_PORT > +PsfRootRs3PciePort ( > + IN UINT32 RpIndex > + ); > + > +/** > + Check if PCIe Root Port is enabled > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval TRUE PCIe Root Port is enabled > + FALSE PCIe Root Port is disabled > +**/ > +BOOLEAN > +PsfIsPcieRootPortEnabled ( > + IN UINT32 RpIndex > + ); > + > +// > +// Type of enpoint connected to PSF port. > +// PsfNullPort is used for ports which do not exist > +// > +typedef enum { > + PsfNullPort, > + PsfToPsfPort, > + PsfPcieCtrlPort > +} PSF_TOPO_PORT_TYPE; > + > +// > +// Structure for storing information on location in PSF topology > +// Every PSF node is identified by PsfID and PsfPortId > +// > +typedef struct { > + UINT8 PsfId; > + UINT8 PortId; > +} PSF_TOPO_PORT; > + > +#define PSF_TOPO_PORT_NULL ((PSF_TOPO_PORT){0, 0}) > +#define PSF_IS_TOPO_PORT_NULL(PsfTopoPort) (((PsfTopoPort).PsfId =3D=3D = 0) > && ((PsfTopoPort).PortId =3D=3D 0)) > + > +// > +// This is optional field containing PSF port specific data > +// > +typedef union { > + UINT32 PcieCtrlIndex; > +} PSF_TOPO_PORT_DATA; > + > +// > +// Structure representing PSF port in PSF topology > +// If port is of PsfToPsfPort type Child will point to the first > +// port of sub PSF segment. > +// > +typedef struct PSF_TOPOLOGY { > + PSF_TOPO_PORT PsfPort; > + PSF_TOPO_PORT_TYPE PortType; > + CONST struct PSF_TOPOLOGY *Child; > + PSF_TOPO_PORT_DATA PortData; > +} PSF_TOPOLOGY; > + > +// > +// Tag for identifying last element of PSF_TOPOLOGY type array > +// > +#define PSF_TOPOLOGY_END {{0, 0}, PsfNullPort, NULL} > + > +/** > + Get PSF Pcie Tree topology > + > + @param[in] PsfTopology PSF Port from PSF PCIe tree topology > + > + @retval PsfTopology PSF PCIe tree topology > +**/ > +CONST PSF_TOPOLOGY* > +PsfGetRootPciePsfTopology ( > + VOID > + ); > + > +// > +// Structure for storing data on PCIe controller to PSF assignment and > GrantCount register offsets > +// > +typedef struct { > + PCH_SBI_PID PsfPid; > + UINT16 DevGntCnt0Base; > + UINT16 TargetGntCntPg1Tgt0Base; > +} PSF_GRANT_COUNT_REG; > + > +/** > + Grant count regs data for PSF that is directly connected to PCIe Root = Ports > + > + @param[in] Controller PCIe Root Port Controller index (0 based) > + @param[out] GrantCountReg Structure with PSF Grant Count register dat= a > +**/ > +VOID > +PsfPcieGrantCountBaseReg ( > + IN UINT8 Controller, > + OUT PSF_GRANT_COUNT_REG *GrantCountReg > + ); > + > +/** > + Get Grant Count number (Device Grant Count and Target Grant Count) > + for PSF that is directly connected to PCIe Root Ports > + > + @param[in] Controller PCIe Root Port Controller index > + @param[in] Channel PCIe Root Port Channel index > + @param[out] DgcrNo Device Grant Count number > + @param[out] PgTgtNo Target Grant Count number > +**/ > +VOID > +PsfPcieGrantCountNumber ( > + IN UINT8 Controller, > + IN UINT8 Channel, > + OUT UINT8 *DgcrNo, > + OUT UINT8 *PgTgtNo > + ); > + > +/** > + Grant count regs data for a given PSF-to-PSF port. > + > + @param[in] PsfTopoPort PSF-to-PSF port > + > + @param[out] GrantCountReg Structure with PSF Grant Count register > data > +**/ > +VOID > +PsfSegmentGrantCountBaseReg ( > + IN PSF_TOPO_PORT PsfTopoPort, > + OUT PSF_GRANT_COUNT_REG *GrantCountReg > + ); > + > +/** > + Grant Count number (Device Grant Count and Target Grant Count) for a > given PSF-to-PSF port. > + > + @param[in] PsfTopoPort PSF-to-PSF port > + @param[out] DgcrNo Device Grant Count number > + @param[out] PgTgtNo Target Grant Count number > +**/ > +VOID > +PsfSegmentGrantCountNumber ( > + IN PSF_TOPO_PORT PsfTopoPort, > + OUT UINT8 *DgcrNo, > + OUT UINT8 *PgTgtNo > + ); > + > +// > +// Do not override PSF Grant Count value and leave HW default setting > +// > +#define DEFAULT_PCIE_GRANT_COUNT 0xFF > + > +typedef struct { > + UINT32 Id; > + PCH_SBI_PID SbPid; > +} PSF_SEGMENT; > + > +/** > + Get list of supported PSF segments. > + > + @param[out] PsfTable Array of supported PSF segments > + @param[out] PsfTableLength Length of PsfTable > +**/ > +VOID > +PsfSegments ( > + OUT PSF_SEGMENT **PsfTable, > + OUT UINT32 *PsfTableLength > + ); > + > +/** > + Get PSF SideBand Port ID from PSF ID (1 - PSF1, 2 - PSF2, ...) > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + > + @retval PSF SideBand Port ID > +**/ > +PCH_SBI_PID > +PsfSbPortId ( > + UINT32 PsfId > + ); > + > +/** > + Get EOI register data for given PSF ID > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + @param[out] EoiTargetBase EOI Target register > + @param[out] EoiControlBase EOI Control register > + > + @retval MaxTargets Number of supported targets > + > +**/ > +UINT8 > +PsfEoiRegData ( > + UINT32 PsfId, > + UINT16 *EoiTargetBase, > + UINT16 *EoiControlBase > + ); > + > +/** > + Get MCTP register data for given PSF ID > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + @param[out] MctpTargetBase MCTP Target register > + @param[out] MctpControlBase MCTP Control register > + > + @retval MaxTargets Number of supported targets > + > +**/ > +UINT8 > +PsfMctpRegData ( > + UINT32 PsfId, > + UINT16 *MctpTargetBase, > + UINT16 *MctpControlBase > + ); > + > +/** > + P2SB PSF port Destination ID (psf_id:port_group_id:port_id:channel_id) > + > + @retval P2SB Destination ID > +**/ > +PSF_PORT_DEST_ID > +PsfP2sbDestinationId ( > + VOID > + ); > + > +/** > + DMI PSF port Destination ID (psf_id:port_group_id:port_id:channel_id) > + > + @retval DMI Destination ID > +**/ > +PSF_PORT_DEST_ID > +PsfDmiDestinationId ( > + VOID > + ); > + > +/** > + Check if MCTP is supported > + > + @retval TRUE MCTP is supported > + FALSE MCTP is not supported > +**/ > +BOOLEAN > +PsfIsMctpSupported ( > + VOID > + ); > + > +/** > + Return the PSF (Root level) Function Config PSF_PORT for PCIe Root Por= t > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe Function Config > +**/ > +PSF_PORT > +PsfRootPcieFunctionConfigPort ( > + IN UINT32 RpIndex > + ); > + > +/** > + Return the PSF (Root level) RS3 Function Config PSF_PORT for PCIe Root= Port > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe Function Config > +**/ > +PSF_PORT > +PsfRootRs3PcieFunctionConfigPort ( > + IN UINT32 RpIndex > + ); > + > +/** > + Return the PSF Function Config Second Level PSF_PORT for PCIe Root Por= t > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval PsfPort PSF PORT structure for PCIe Function Config > +**/ > +PSF_PORT > +PsfPcieFunctionConfigSecondLevelPort ( > + IN UINT32 RpIndex > + ); > + > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibInternal.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibInternal.h > new file mode 100644 > index 0000000000..c08d1cf10d > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibInternal.h > @@ -0,0 +1,47 @@ > +/** @file > + Internal header file for PMC Private library > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PMC_PRIVATE_LIB_INTERNAL_H_ > +#define _PMC_PRIVATE_LIB_INTERNAL_H_ > + > +/** > + Check if MODPHY SUS PG is supported > + > + @retval Status of MODPHY SUS PG support > +**/ > +BOOLEAN > +PmcIsModPhySusPgSupported ( > + VOID > + ); > + > +/** > + This function is part of PMC init and configures which clock wake sign= als > should > + set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent > up to the CPU/PCH > +**/ > +VOID > +PmcInitClockWakeEnable ( > + VOID > + ); > + > +/** > + This function configures PWRMBASE + 0x1E00 register > +**/ > +VOID > +PmcConfigureRegPwrm1E00 ( > + VOID > + ); > + > +/** > + This function configures Misc PM_SYNC events settings > +**/ > +VOID > +PmcConfigurePmSyncEventsSettings ( > + VOID > + ); > + > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNamesCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNamesCnl.c > new file mode 100644 > index 0000000000..5a4876bfeb > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNamesCnl.c > @@ -0,0 +1,166 @@ > +/** @file > + This file contains GPIO name library implementation > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +STATIC CONST CHAR8* mGpioGppaNames[] =3D { > + "ESPI_CLK_LOOPBK" > +}; > + > +STATIC CONST CHAR8* mGpioGppbNames[] =3D { > + "GSPI0_CLK_LOOPBK", > + "GSPI1_CLK_LOOPBK" > +}; > + > +STATIC CONST CHAR8* mGpioGpdNames[] =3D { > + "SLP_LANB", > + "SLP_SUSB", > + "SLP_WAKEB", > + "SLP_DRAM_RESETB" > +}; > + > +STATIC CONST CHAR8* mGpioGppiNames[] =3D { > + "SYS_PWROK", > + "SYS_RESETB", > + "MLK_RSTB" > +}; > + > +STATIC CONST CHAR8* mGpioSpiNames[] =3D { > + "SPI0_IO_2", > + "SPI0_IO_3", > + "SPI0_MOSI_IO_0", > + "SPI0_MOSI_IO_1", > + "SPI0_TPM_CSB", > + "SPI0_FLASH_0_CSB", > + "SPI0_FLASH_1_CSB", > + "SPI0_CLK", > + "SPI0_CLK_LOOPBK" > +}; > + > +STATIC CONST CHAR8* mGpioAzaNames[] =3D { > + "HDA_BCLK", > + "HDA_RSTB", > + "HDA_SYNC", > + "HDA_SDO", > + "HDA_SDI_0", > + "HDA_SDI_1", > + "SSP1_SFRM", > + "SSP1_TXD" > +}; > + > +STATIC CONST CHAR8* mGpioJtagNames[] =3D { > + "JTAG_TDO", > + "JTAGX", > + "PRDYB", > + "PREQB", > + "CPU_TRSTB", > + "JTAG_TDI", > + "JTAG_TMS", > + "JTAG_TCK", > + "ITP_PMODE" > +}; > + > +STATIC CONST CHAR8* mGpioHvmosNames[] =3D { > + "HVMOS_L_BKLTEN", > + "HVMOS_L_BKLCTL", > + "HVMOS_L_VDDEN", > + "HVMOS_SYS_PWROK", > + "HVMOS_SYS_RESETB", > + "HVMOS_MLK_RSTB" > +}; > + > +STATIC CONST CHAR8* mGpioCpuNames[] =3D { > + "HDACPU_SDI", > + "HDACPU_SDO", > + "HDACPU_SCLK", > + "PM_SYNC", > + "PECI", > + "CPUPWRGD", > + "THRMTRIPB", > + "PLTRST_CPUB", > + "PM_DOWN", > + "TRIGGER_IN", > + "TRIGGER_OUT" > +}; > + > +STATIC CONST GPIO_GROUP_NAME_INFO mPchLpGroupDescriptors[] =3D { > + GPIO_GROUP_NAME("GPP_A", GPIO_CNL_LP_ESPI_CLK_LOOPBK, > mGpioGppaNames), > + GPIO_GROUP_NAME("GPP_B", GPIO_CNL_LP_GSPI0_CLK_LOOPBK, > mGpioGppbNames), > + GPIO_GROUP_NAME_BASIC("GPP_C"), > + GPIO_GROUP_NAME_BASIC("GPP_D"), > + GPIO_GROUP_NAME_BASIC("GPP_E"), > + GPIO_GROUP_NAME_BASIC("GPP_F"), > + GPIO_GROUP_NAME_BASIC("GPP_G"), > + GPIO_GROUP_NAME_BASIC("GPP_H"), > + GPIO_GROUP_NAME("GPD", GPIO_CNL_LP_SLP_LANB, mGpioGpdNames), > + GPIO_GROUP_NAME_BASIC("VGPIO"), > + GPIO_GROUP_NAME("SPI", GPIO_CNL_LP_SPI0_IO_2, mGpioSpiNames), > + GPIO_GROUP_NAME("AZA", GPIO_CNL_LP_HDA_BCLK, mGpioAzaNames), > + GPIO_GROUP_NAME("CPU", GPIO_CNL_LP_HDACPU_SDI, > mGpioCpuNames), > + GPIO_GROUP_NAME("JTAG", GPIO_CNL_LP_JTAG_TDO, mGpioJtagNames), > + GPIO_GROUP_NAME("HVMOS", GPIO_CNL_LP_HVMOS_L_BKLTEN, > mGpioHvmosNames) > +}; > + > +STATIC CONST GPIO_GROUP_NAME_INFO mPchHGroupDescriptors[] =3D { > + GPIO_GROUP_NAME("GPP_A", GPIO_CNL_H_ESPI_CLK_LOOPBK, > mGpioGppaNames), > + GPIO_GROUP_NAME("GPP_B", GPIO_CNL_H_GSPI0_CLK_LOOPBK, > mGpioGppbNames), > + GPIO_GROUP_NAME_BASIC("GPP_C"), > + GPIO_GROUP_NAME_BASIC("GPP_D"), > + GPIO_GROUP_NAME_BASIC("GPP_E"), > + GPIO_GROUP_NAME_BASIC("GPP_F"), > + GPIO_GROUP_NAME_BASIC("GPP_G"), > + GPIO_GROUP_NAME_BASIC("GPP_H"), > + GPIO_GROUP_NAME("GPP_I", GPIO_CNL_H_SYS_PWROK, > mGpioGppiNames), > + GPIO_GROUP_NAME_BASIC("GPP_J"), > + GPIO_GROUP_NAME_BASIC("GPP_K"), > + GPIO_GROUP_NAME("GPD", GPIO_CNL_H_SLP_LANB, mGpioGpdNames), > + GPIO_GROUP_NAME_BASIC("VGPIO"), > + GPIO_GROUP_NAME("SPI", GPIO_CNL_H_SPI0_IO_2, mGpioSpiNames), > + GPIO_GROUP_NAME("AZA", GPIO_CNL_H_HDA_BCLK, mGpioAzaNames), > + GPIO_GROUP_NAME("CPU", GPIO_CNL_H_HDACPU_SDI, > mGpioCpuNames), > + GPIO_GROUP_NAME("JTAG", GPIO_CNL_H_JTAG_TDO, mGpioJtagNames), > +}; > + > +/** > + Returns GPIO_GROUP_NAME_INFO corresponding to the given GpioPad > + > + @param[in] GroupIndex Group index > + > + @retval GPIO_GROUP_NAME_INFO* Pointer to the > GPIO_GROUP_NAME_INFO > + @reval NULL If no group descriptor was found > +**/ > +CONST > +GPIO_GROUP_NAME_INFO* > +GpioGetGroupNameInfo ( > + IN UINT32 GroupIndex > + ) > +{ > + if (IsPchLp ()) { > + if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) { > + return &mPchLpGroupDescriptors[GroupIndex]; > + } else { > + ASSERT (FALSE); > + return NULL; > + } > + } else { > + if (GroupIndex < ARRAY_SIZE (mPchHGroupDescriptors)) { > + return &mPchHGroupDescriptors[GroupIndex]; > + } else { > + ASSERT (FALSE); > + return NULL; > + } > + } > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLib.c > new file mode 100644 > index 0000000000..affecf9ec0 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLib.c > @@ -0,0 +1,1304 @@ > +/** @file > + This file contains routines for GPIO native and chipset specific purpo= se > + used by Reference Code only. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "GpioNativePrivateLibInternal.h" > +#include > +#include > +#include > + > +/** > + This function sets SerialIo I2C controller pins into native mode > + > + @param[in] SerialIoI2cControllerNumber I2C controller > + @param[in] GpioTermination GPIO termination type > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSerialIoI2c ( > + IN UINT32 SerialIoI2cControllerNumber, > + IN GPIO_ELECTRICAL_CONFIG GpioTermination > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD_NATIVE_FUNCTION *I2cGpio; > + GPIO_CONFIG GpioConfig; > + > + GpioGetSerialIoI2cPins ( > + SerialIoI2cControllerNumber, > + &I2cGpio > + ); > + > + if (I2cGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG)); > + GpioConfig.ElectricalConfig =3D GpioTermination; > + > + for (Index =3D 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index= ++) > { > + GpioConfig.PadMode =3D I2cGpio[Index].Mode; > + > + Status =3D GpioSetPadConfig(I2cGpio[Index].Pad, &GpioConfig); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets SerialIo UART controller pins into native mode > + > + @param[in] SerialIoUartControllerNumber UART controller > + @param[in] HardwareFlowControl Hardware Flow control > + @param[in] PinMuxing UART controller pin muxing > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSerialIoUart ( > + IN UINT32 SerialIoUartControllerNumber, > + IN BOOLEAN HardwareFlowControl, > + IN UINT32 PinMuxing > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + UINT32 PinsUsed; > + GPIO_PAD_NATIVE_FUNCTION *UartGpio; > + > + GpioGetSerialIoUartPins ( > + SerialIoUartControllerNumber, > + HardwareFlowControl, > + PinMuxing, > + &UartGpio, > + &PinsUsed > + ); > + > + if (UartGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PinsUsed; Index++) { > + Status =3D GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode= ); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + GpioSetInputInversion (UartGpio[Index].Pad, 0); > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets SerialIo SPI controller pins into native mode > + > + @param[in] SerialIoSpiControllerNumber SPI controller > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSerialIoSpi ( > + IN UINT32 SerialIoSpiControllerNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SpiGpio; > + UINT32 NumOfSpiPins; > + > + GpioGetSerialIoSpiPins ( > + SerialIoSpiControllerNumber, > + &SpiGpio, > + &NumOfSpiPins > + ); > + > + if (SpiGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < NumOfSpiPins; Index++) { > + Status =3D GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + GpioSetInputInversion (SpiGpio[Index].Pad, 0); > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets ISH I2C controller pins into native mode > + > + @param[in] IshI2cControllerNumber I2C controller > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableIshI2c ( > + IN UINT32 IshI2cControllerNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *I2cGpio; > + > + GpioGetIshI2cPins ( > + IshI2cControllerNumber, > + &I2cGpio > + ); > + > + if (I2cGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_ISH_PINS_PER_I2C_CONTROLLER; Index++) { > + Status =3D GpioSetPadMode (I2cGpio[Index].Pad, I2cGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets ISH UART controller pins into native mode > + > + @param[in] IshUartControllerNumber UART controller > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableIshUart ( > + IN UINT32 IshUartControllerNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *UartGpio; > + > + GpioGetIshUartPins ( > + IshUartControllerNumber, > + &UartGpio > + ); > + > + if (UartGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_ISH_PINS_PER_UART_CONTROLLER; Index++) { > + Status =3D GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode= ); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets ISH SPI controller pins into native mode > + > + @param[in] IshSpiControllerNumber SPI controller > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableIshSpi ( > + IN UINT32 IshSpiControllerNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SpiGpio; > + UINT32 NumOfSpiPins; > + > + GpioGetIshSpiPins ( > + IshSpiControllerNumber, > + &SpiGpio, > + &NumOfSpiPins > + ); > + > + if (SpiGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < NumOfSpiPins; Index++) { > + Status =3D GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets ISH GP pin into native mode > + > + @param[in] IshGpPinNumber ISH GP pin number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableIshGpPin ( > + IN UINT32 IshGpPinNumber > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD_NATIVE_FUNCTION IshGp; > + > + GpioGetIshGpPin ( > + IshGpPinNumber, > + &IshGp > + ); > + > + Status =3D GpioSetPadMode (IshGp.Pad, IshGp.Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function sets SCS SD card controller pins into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableScsSdCard ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SdCardGpio; > + UINT32 NumOfSdCardPins; > + GPIO_CONFIG PwrEnConfig; > + > + GpioGetScsSdCardPins ( > + &SdCardGpio, > + &NumOfSdCardPins > + ); > + > + if (SdCardGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // We need to leave the PWREN# > + // GPIO pad unlocked since it is controlled at runtime > + // by ACPI code. It is a work around for our SD card > + // controller not respecting PWREN# invertion settings > + // during D3. Since this pad will be in GPIO mode when > + // SD controller is in D3 we need to set correct pad config. > + // > + GpioUnlockPadCfg (SdCardGpio[0].Pad); > + GpioGetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig); > + PwrEnConfig.PadMode =3D SdCardGpio[0].Mode; > + PwrEnConfig.Direction =3D GpioDirOut; > + PwrEnConfig.HostSoftPadOwn =3D GpioHostOwnAcpi; > + PwrEnConfig.InterruptConfig =3D GpioIntDis; > + PwrEnConfig.PowerConfig =3D GpioHostDeepReset; > + PwrEnConfig.LockConfig =3D GpioPadUnlock; > + GpioSetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig); > + > + for (Index =3D 1; Index < NumOfSdCardPins; Index++) { > + Status =3D GpioSetPadMode (SdCardGpio[Index].Pad, > SdCardGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // SD Card Pins GPP_G0 - G4 require Native Termination > + // Index in mPch[Lp/H]ScsSdCardGpio (depends on > mPch[Lp/H]ScsSdCardGpio internal organization): > + // GPP_G0 =3D 1 > + // GPP_G4 =3D 5 > + // > + if (Index >=3D 1 && Index <=3D 5) { > + Status =3D GpioSetPadElectricalConfig (SdCardGpio[Index].Pad, > GpioTermNative); > + ASSERT_EFI_ERROR (Status); > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function enables SCS Sd Card controller card detect pin > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableScsSdCardDetect ( > + VOID > + ) > +{ > + GPIO_CONFIG PadConfig; > + GPIO_PAD GpioPad; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + /// > + /// vSD3_CD_B line is driven by GPPC_G_5_SD3_CDB > + /// and is used for interrupt for card detect event. > + /// GPPC_G_5_SD3_CDB cannot be used for interrupt because this pin > + /// is in native mode. > + /// > + GpioPad =3D GpioGetScsSdCardDetectPin (); > + PadConfig.PadMode =3D GpioPadModeGpio; > + PadConfig.Direction =3D GpioDirIn; > + PadConfig.HostSoftPadOwn =3D GpioHostOwnGpio; > + PadConfig.InterruptConfig =3D GpioIntBothEdge; > + PadConfig.PowerConfig =3D GpioHostDeepReset; > + > + // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver > mode. > + GpioUnlockPadCfg (GpioPad); > + > + return GpioSetPadConfig (GpioPad, &PadConfig); > +} > + > +/** > + This function sets SCS eMMC controller pins into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableScsEmmc ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *EmmcGpio; > + UINT32 NumOfEmmcPins; > + > + GpioGetScsEmmcPins ( > + &EmmcGpio, > + &NumOfEmmcPins > + ); > + > + if (EmmcGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < NumOfEmmcPins; Index++) { > + Status =3D GpioSetPadMode (EmmcGpio[Index].Pad, > EmmcGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets HDA Link pins into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableHdaLink ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *HdaLinkGpio; > + UINT32 NumOfHdaLinkPins; > + > + GpioGetHdAudioLinkPins ( > + &HdaLinkGpio, > + &NumOfHdaLinkPins > + ); > + > + if (HdaLinkGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < NumOfHdaLinkPins; Index++) { > + Status =3D GpioSetPadMode (HdaLinkGpio[Index].Pad, > HdaLinkGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets HDA DMIC pins into native mode > + > + @param[in] DmicNumber DMIC number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableHdaDmic ( > + IN UINT32 DmicNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *DmicGpio; > + > + GpioGetHdaDmicPins ( > + DmicNumber, > + &DmicGpio > + ); > + > + if (DmicGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (DmicGpio[Index].Pad, > DmicGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets HDA SSP interface pins into native mode > + > + @param[in] SspInterfaceNumber SSPx interface number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableHdaSsp ( > + IN UINT32 SspInterfaceNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SspGpio; > + > + GpioGetHdaSspPins ( > + SspInterfaceNumber, > + &SspGpio > + ); > + > + if (SspGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_HDA_SSP_NUMBER_OF_PINS; Index++) { > + Status =3D GpioSetPadMode (SspGpio[Index].Pad, SspGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function sets HDA SoundWire interface pins into native mode > + > + @param[in] SndwInterfaceNumber SNDWx interface number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableHdaSndw ( > + IN UINT32 SndwInterfaceNumber > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SndwGpio; > + > + GpioGetHdaSndwPins ( > + SndwInterfaceNumber, > + &SndwGpio > + ); > + > + if (SndwGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (SndwGpio[Index].Pad, > SndwGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function sets SMBUS controller pins into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSmbus ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *SmbusGpio; > + > + GpioGetSmbusPins (&SmbusGpio); > + > + if (SmbusGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_SMBUS_NUMBER_OF_PINS; Index++) { > + Status =3D GpioSetPadMode (SmbusGpio[Index].Pad, > SmbusGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function sets SATA DevSlp pins into native mode > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSataDevSlpPin ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION DevSlpGpio; > + > + GpioGetSataDevSlpPin ( > + SataCtrlIndex, > + SataPort, > + &DevSlpGpio > + ); > + > + GpioSetPadResetConfig (DevSlpGpio.Pad, GpioResumeReset); > + > + return GpioSetPadMode (DevSlpGpio.Pad, DevSlpGpio.Mode); > +} > + > +/** > + This function checks if SataDevSlp pin is in native mode > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port > + @param[out] DevSlpPad DevSlpPad > + This is an optional parameter and may = be NULL. > + > + @retval TRUE DevSlp is in native mode > + FALSE DevSlp is not in native mode > +**/ > +BOOLEAN > +GpioIsSataDevSlpPinEnabled ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort, > + OUT GPIO_PAD *DevSlpPad OPTIONAL > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION DevSlpNativePad; > + GPIO_PAD_MODE GpioMode; > + EFI_STATUS Status; > + > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + GpioGetSataDevSlpPin ( > + SataCtrlIndex, > + SataPort, > + &DevSlpNativePad > + ); > + > + Status =3D GpioGetPadMode (DevSlpNativePad.Pad, &GpioMode); > + > + if (EFI_ERROR (Status) || (GpioMode !=3D DevSlpNativePad.Mode)) { > + if (DevSlpPad !=3D NULL) { > + *DevSlpPad =3D GPIO_PAD_NONE; > + } > + return FALSE; > + } else { > + if (DevSlpPad !=3D NULL) { > + *DevSlpPad =3D DevSlpNativePad.Pad; > + } > + return TRUE; > + } > +} > + > +/** > + This function sets SATAGPx pin into native mode > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSataGpPin ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION SataGpGpio; > + > + GpioGetSataGpPin ( > + SataCtrlIndex, > + SataPort, > + &SataGpGpio > + ); > + > + DEBUG_CODE_BEGIN (); > + GPIO_PAD_MODE PadMode; > + GpioGetPadMode (SataGpGpio.Pad, &PadMode); > + if (PadMode =3D=3D GpioPadModeNative1) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Cannot enable SATAGP%d, %a > already used for SATAXPCIE_%d\n", > + SataPort, > + GpioName (SataGpGpio.Pad), > + SataPort)); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + DEBUG_CODE_END (); > + > + return GpioSetPadMode (SataGpGpio.Pad, SataGpGpio.Mode); > +} > + > +/** > + Returns a pad for given CLKREQ# index. > + > + @param[in] ClkreqIndex CLKREQ# number > + > + @return CLKREQ# pad. > +**/ > +GPIO_PAD > +GpioGetClkreqPad ( > + IN UINT32 ClkreqIndex > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION ClkReqGpio; > + > + GpioGetPcieClkReqPin ( > + ClkreqIndex, > + &ClkReqGpio > + ); > + > + return ClkReqGpio.Pad; > +} > + > +/** > + Enables CLKREQ# pad in native mode. > + > + @param[in] ClkreqIndex CLKREQ# number > + > + @return none > +**/ > +VOID > +GpioEnableClkreq ( > + IN UINT32 ClkreqIndex > + ) > +{ > + GPIO_CONFIG PadConfig; > + GPIO_PAD_NATIVE_FUNCTION ClkReqGpio; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + GpioGetPcieClkReqPin ( > + ClkreqIndex, > + &ClkReqGpio > + ); > + > + PadConfig.PadMode =3D ClkReqGpio.Mode; > + PadConfig.Direction =3D GpioDirNone; > + PadConfig.PowerConfig =3D GpioHostDeepReset; > + DEBUG ((DEBUG_INFO, "Enabling CLKREQ%d\n", ClkreqIndex)); > + GpioSetPadConfig (ClkReqGpio.Pad, &PadConfig); > +} > + > + > +/** > + This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mod= e > for eDP Panel > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableEdpPins ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD_NATIVE_FUNCTION *EdpPins; > + UINT32 EdpPinsNumber; > + > + GpioGetEdpPins ( > + &EdpPins, > + &EdpPinsNumber > + ); > + > + if (EdpPins =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Configure HPD, VDD and BKLT Pins for eDP panel > + // > + for (Index =3D 0; Index < EdpPinsNumber; Index++) { > + Status =3D GpioSetPadMode (EdpPins[Index].Pad, EdpPins[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function sets DDP pins into native mode > + > + @param[in] DdpInterface DDPx interface > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableDpInterface ( > + IN GPIO_DDP DdpInterface > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *DdpGpio; > + > + GpioGetDdpPins ( > + DdpInterface, > + &DdpGpio > + ); > + > + if (DdpGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_DDP_NUMBER_OF_PINS; Index++) { > + Status =3D GpioSetPadMode (DdpGpio[Index].Pad, DdpGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function configures GPIO connection between CNVi and CRF > + @param[in] None > + > + @retval Status > +**/ > +EFI_STATUS > +GpioConfigureCnviCrfConnection ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD_NATIVE_FUNCTION *CnviBriRgiExternalPad; > + > + GpioGetCnvBriRgiPins (&CnviBriRgiExternalPad); > + > + if (CnviBriRgiExternalPad =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Configure CNVi BRI and RGI buses for high speed communication with = CRF > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS; > Index++) { > + Status =3D GpioSetPadMode (CnviBriRgiExternalPad[Index].Pad, > CnviBriRgiExternalPad[Index].Mode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function configures virtual GPIO connection for CNVi Bluetooth UA= RT > + > + @param[in] ConnectionType > + > + @retval Status > +**/ > +EFI_STATUS > +GpioConfigureCnviBtUartConnection ( > + IN VGPIO_CNVI_BT_UART_CONNECTION_TYPE ConnectionType > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD *VCnviBtUartPad; > + GPIO_PAD_MODE VCnviBtUartPadMode; > + GPIO_PAD *VUartForCnviBtPad; > + GPIO_PAD_MODE VUartForCnviBtPadMode; > + GPIO_PAD_NATIVE_FUNCTION *CnviBtUartExternalPad; > + > + GpioGetCnviBtUartPins ( > + ConnectionType, > + &VCnviBtUartPad, > + &VCnviBtUartPadMode, > + &VUartForCnviBtPad, > + &VUartForCnviBtPadMode > + ); > + > + if ((VCnviBtUartPad =3D=3D NULL) || > + (VUartForCnviBtPad =3D=3D NULL)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Configure CNVi Bluetooth UART for certain connection > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (VCnviBtUartPad[Index], > VCnviBtUartPadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable virtual connection for UART for Bluetooth > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (VUartForCnviBtPad[Index], > VUartForCnviBtPadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable CNVi BT UART on external pads > + // > + if (ConnectionType =3D=3D GpioCnviBtUartToExternalPads) { > + > + GpioGetCnviBtUartExternalPins (&CnviBtUartExternalPad); > + > + if (CnviBtUartExternalPad =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++= ) > { > + Status =3D GpioSetPadMode (CnviBtUartExternalPad[Index].Pad, > CnviBtUartExternalPad[Index].Mode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function configures virtual GPIO connection for CNVi Bluetooth I2= S > + > + @param[in] ConnectionType > + > + @retval Status > +**/ > +EFI_STATUS > +GpioConfigureCnviBtI2sConnection ( > + IN VGPIO_CNVI_BT_I2S_CONNECTION_TYPE ConnectionType > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD *VCnviBtI2sPad; > + GPIO_PAD_MODE VCnviBtI2sPadMode; > + GPIO_PAD *VSspForCnviBtPad; > + GPIO_PAD_MODE VSspForCnviBtPadMode; > + GPIO_PAD_NATIVE_FUNCTION *CnviBtI2sExternalPad; > + > + GpioGetCnviBtI2sPins ( > + ConnectionType, > + &VCnviBtI2sPad, > + &VCnviBtI2sPadMode, > + &VSspForCnviBtPad, > + &VSspForCnviBtPadMode > + ); > + > + if ((VCnviBtI2sPad =3D=3D NULL) || > + (VSspForCnviBtPad =3D=3D NULL)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Configure CNVi Bluetooth I2S for certain connection > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) { > + Status =3D GpioSetPadMode (VCnviBtI2sPad[Index], VCnviBtI2sPadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable virtual connection for SSP for Bluetooth > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) { > + Status =3D GpioSetPadMode (VSspForCnviBtPad[Index], > VSspForCnviBtPadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable CNV BT I2S on external pads > + // > + if (ConnectionType =3D=3D (VGPIO_CNVI_BT_I2S_CONNECTION_TYPE) > GpioCnviBtI2sToExternalPads) { > + > + GpioGetCnviBtI2sExternalPins (&CnviBtI2sExternalPad); > + > + if (CnviBtI2sExternalPad =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++)= { > + Status =3D GpioSetPadMode (CnviBtI2sExternalPad[Index].Pad, > CnviBtI2sExternalPad[Index].Mode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This function configures virtual GPIO connection for CNVi MFUART1 > + > + @param[in] ConnectionType > + > + @retval Status > +**/ > +EFI_STATUS > +GpioConfigureCnviMfUart1Connection ( > + IN VGPIO_CNVI_MF_UART1_CONNECTION_TYPE ConnectionType > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + GPIO_PAD *VCnviMfUart1Pad; > + GPIO_PAD_MODE VCnviMfUart1PadMode; > + GPIO_PAD *VUartForCnviMfUart1Pad; > + GPIO_PAD_MODE VUartForCnviMfUart1PadMode; > + GPIO_PAD_NATIVE_FUNCTION *CnviMfUart1ExternalPad; > + > + GpioGetCnviMfUart1Pins ( > + ConnectionType, > + &VCnviMfUart1Pad, > + &VCnviMfUart1PadMode, > + &VUartForCnviMfUart1Pad, > + &VUartForCnviMfUart1PadMode > + ); > + > + if ((VCnviMfUart1Pad =3D=3D NULL) || > + (VUartForCnviMfUart1Pad =3D=3D NULL)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Configure CNVi MFUART1 for certain connection > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (VCnviMfUart1Pad[Index], > VCnviMfUart1PadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable virtual connection for MFUART1 > + // > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) > { > + Status =3D GpioSetPadMode (VUartForCnviMfUart1Pad[Index], > VUartForCnviMfUart1PadMode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Enable CNV MFUART1 on external pads > + // > + if (ConnectionType =3D=3D GpioCnviMfUart1ToExternalPads) { > + > + GpioGetCnviMfUart1ExternalPins (&CnviMfUart1ExternalPad); > + > + if (CnviMfUart1ExternalPad =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++= ) > { > + Status =3D GpioSetPadMode (CnviMfUart1ExternalPad[Index].Pad, > CnviMfUart1ExternalPad[Index].Mode); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return EFI_UNSUPPORTED; > + } > + } > + } > + return EFI_SUCCESS; > +} > + > + > +/** > + This function sets CNVi Bluetooth Enable value > + > + @param[in] Value CNVi BT enable value > + 0: Disable, 1: Enable > + @retval Status > +**/ > +EFI_STATUS > +GpioSetCnviBtEnState ( > + IN UINT32 Value > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD CnviBtEnPad; > + GPIO_CONFIG PadConfig; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + PadConfig.PadMode =3D GpioPadModeGpio; > + PadConfig.HostSoftPadOwn =3D GpioHostOwnGpio; > + PadConfig.Direction =3D GpioDirOut; > + if (Value =3D=3D 1) { > + PadConfig.OutputState =3D GpioOutHigh; > + } else { > + PadConfig.OutputState =3D GpioOutLow; > + } > + CnviBtEnPad =3D GpioGetCnviBtEnablePin (); > + > + // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver > mode and it is GPO > + GpioUnlockPadCfg (CnviBtEnPad); > + GpioUnlockPadCfgTx (CnviBtEnPad); > + Status =3D GpioSetPadConfig (CnviBtEnPad, &PadConfig); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > +/** > + This function sets CNVi Bluetooth main host interface > + > + @param[in] BtInterface CNVi BT Interface Select value > + GpioCnviBtIfUart: UART, GpioCnviBtIfUs= b: USB > + @retval Status > +**/ > +EFI_STATUS > +GpioSetCnviBtInterface ( > + IN VGPIO_CNVI_BT_INTERFACE BtInterface > + ) > +{ > + EFI_STATUS Status; > + GPIO_CONFIG PadConfig; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + PadConfig.PadMode =3D GpioPadModeGpio; > + PadConfig.Direction =3D GpioDirOut; > + if (BtInterface =3D=3D GpioCnviBtIfUsb) { > + PadConfig.OutputState =3D GpioOutHigh; > + } else { > + PadConfig.OutputState =3D GpioOutLow; > + } > + > + Status =3D GpioSetPadConfig (GpioGetCnviBtIfSelectPin (), &PadConfig); > + ASSERT_EFI_ERROR (Status); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function sets CNVi Bluetooth Wireless Charging support > + > + @param[in] BtWirelessCharging CNVi BT Wireless Charging support > + 0: Normal BT operation (no Wireless Ch= arging > support) > + 1: Enable BT Wireless Charging > + @retval Status > +**/ > +EFI_STATUS > +GpioSetCnviBtWirelessCharging ( > + IN UINT32 BtWirelessCharging > + ) > +{ > + EFI_STATUS Status; > + GPIO_CONFIG CnviBtChargingPadConfig; > + GPIO_PAD_NATIVE_FUNCTION A4WpPad; > + > + ZeroMem (&CnviBtChargingPadConfig, sizeof (CnviBtChargingPadConfig)); > + > + CnviBtChargingPadConfig.PadMode =3D GpioPadModeGpio; > + CnviBtChargingPadConfig.Direction =3D GpioDirOut; > + > + if (BtWirelessCharging =3D=3D 1) { > + CnviBtChargingPadConfig.OutputState =3D GpioOutHigh; > + > + GpioGetCnviA4WpPin (&A4WpPad); > + > + Status =3D GpioSetPadMode (A4WpPad.Pad, A4WpPad.Mode); > + ASSERT_EFI_ERROR (Status); > + > + } else { > + CnviBtChargingPadConfig.OutputState =3D GpioOutLow; > + } > + > + Status =3D GpioSetPadConfig (GpioGetCnviBtChargingPin (), > &CnviBtChargingPadConfig); > + ASSERT_EFI_ERROR (Status); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function enables and configures CNVi Bluetooth Host wake-up > interrupt > + > + @param[in] None > + > + @retval Status > +**/ > +EFI_STATUS > +GpioConfigureCnviBtHostWakeInt ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD CnviBtHostWakeIntPad; > + GPIO_CONFIG PadConfig; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + PadConfig.PadMode =3D GpioPadModeGpio; > + PadConfig.Direction =3D GpioDirIn; > + PadConfig.HostSoftPadOwn =3D GpioHostOwnGpio; > + PadConfig.InterruptConfig =3D GpioIntEdge; > + PadConfig.PowerConfig =3D GpioHostDeepReset; > + CnviBtHostWakeIntPad =3D GpioGetCnviBtHostWakeIntPin (); > + > + // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver > mode. > + GpioUnlockPadCfg (CnviBtHostWakeIntPad); > + Status =3D GpioSetPadConfig (CnviBtHostWakeIntPad, &PadConfig); > + ASSERT_EFI_ERROR (Status); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function enables IMGU CLKOUT native pin > + > + @param[in] None > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableImguClkOut ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + GPIO_PAD_NATIVE_FUNCTION *ImguClkOutGpio; > + UINT32 NoOfNativePins; > + > + GpioGetImgClkOutPins ( > + &ImguClkOutGpio, > + &NoOfNativePins > + ); > + > + if (ImguClkOutGpio =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0; Index < NoOfNativePins; Index++) { > + Status =3D GpioSetPadMode (ImguClkOutGpio[Index].Pad, > ImguClkOutGpio[Index].Mode); > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + Power button debounce configuration > + Debounce time can be specified in microseconds. Only certain values > according > + to below formula are supported: > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock perio= d). > + RTC clock with f =3D 32 KHz is used for glitch filter. > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us). > + Supported DebounceTime values are following: > + DebounceTime =3D 0 -> Debounce feature disabled > + DebounceTime > 0 && < 250us -> Not supported > + DebounceTime =3D 250us - 1024000us -> Supported range (DebounceTime = =3D > 250us * 2^n) > + For values not supported by HW, they will be rounded down to closest > supported one > + > + @param[in] DebounceTime Debounce Time in microseconds > + If Debounce Time =3D 0, Debouncer feature w= ill be > disabled > + Function will set DebounceTime argument to = rounded > supported value > +**/ > +VOID > +GpioSetPwrBtnDebounceTimer ( > + IN UINT32 DebounceTime > + ) > +{ > + GpioSetDebounceTimer (GpioGetPwrBtnPin (), &DebounceTime); > +} > + > +/** > + Configure LPC GPIO > +**/ > +VOID > +LpcConfigureGpio ( > + VOID > + ) > +{ > + GPIO_PAD GpioPad; > + GpioPad =3D GpioGetLpcPin(); > + > + if (GpioPad =3D=3D 0) { > + return; > + } else { > + GpioSetPadElectricalConfig (GpioPad, GpioTermWpu20K); > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibCnl.c > new file mode 100644 > index 0000000000..4cff00c27b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioNativePrivateLibCnl.c > @@ -0,0 +1,2275 @@ > +/** @file > + This file contains specific GPIO information > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "GpioNativePrivateLibInternal.h" > + > +// > +// I2C controller pins > +// I2C[controller number][pin: SDA/SCL] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=3D > +{ > + {{GPIO_CNL_LP_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C17, > GpioPadModeNative1}}, > + {{GPIO_CNL_LP_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C19, > GpioPadModeNative1}}, > + {{GPIO_CNL_LP_GPP_H4, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H5 , > GpioPadModeNative1}}, > + {{GPIO_CNL_LP_GPP_H6, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H7 , > GpioPadModeNative1}}, > + {{GPIO_CNL_LP_GPP_H8, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H9 , > GpioPadModeNative1}}, > + {{GPIO_CNL_LP_GPP_H10, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H11, > GpioPadModeNative1}} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=3D > +{ > + {{GPIO_CNL_H_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C17, > GpioPadModeNative1}}, // I2C0 > + {{GPIO_CNL_H_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C19, > GpioPadModeNative1}}, // I2C1 > + {{GPIO_CNL_H_GPP_D13, GpioPadModeNative3}, {GPIO_CNL_H_GPP_D14, > GpioPadModeNative3}}, // I2C2 > + {{GPIO_CNL_H_GPP_D4, GpioPadModeNative2}, {GPIO_CNL_H_GPP_D23, > GpioPadModeNative2}} // I2C3 > +}; > + > + > +/** > + This function provides SerialIo I2C controller pins > + > + @param[in] SerialIoI2cControllerNumber I2C controller > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoI2cPins ( > + IN UINT32 SerialIoI2cControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchLpI2cGpio)) { > + *NativePinsTable =3D mPchLpI2cGpio[SerialIoI2cControllerNumber]; > + return; > + } > + } else { > + if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchHI2cGpio)) { > + *NativePinsTable =3D mPchHI2cGpio[SerialIoI2cControllerNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > +// > +// UART controller pins > +// UART[controller number][pin: RXD/TXD/RTSB/CTSB] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=3D > +{ > + { // UART0 > + {GPIO_CNL_LP_GPP_C8, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C9, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C10, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C11, GpioPadModeNative1} > + }, > + { // UART1 > + {GPIO_CNL_LP_GPP_C12, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C13, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C14, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C15, GpioPadModeNative1} > + }, > + { // UART2 > + {GPIO_CNL_LP_GPP_C20, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C21, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C22, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_C23, GpioPadModeNative1}, > + }, > + { // UART0 (2nd pin set) > + {GPIO_CNL_LP_GPP_F5, GpioPadModeNative2}, > + {GPIO_CNL_LP_GPP_F6, GpioPadModeNative2}, > + {GPIO_CNL_LP_GPP_F4, GpioPadModeNative2}, > + {GPIO_CNL_LP_GPP_F7, GpioPadModeNative2} > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=3D > +{ > + { // UART0 > + {GPIO_CNL_H_GPP_C8, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C9, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C10, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C11, GpioPadModeNative1} > + }, > + { // UART1 > + {GPIO_CNL_H_GPP_C12, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C13, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C14, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C15, GpioPadModeNative1} > + }, > + { // UART2 > + {GPIO_CNL_H_GPP_C20, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C21, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C22, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_C23, GpioPadModeNative1} > + }, > + { // UART0 (2nd pin set) > + {GPIO_CNL_H_GPP_J5, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_J6, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_J4, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_J7, GpioPadModeNative2} > + } > +}; > + > +/** > + This function provides SerialIo UART controller pins > + > + @param[in] SerialIoUartControllerNumber UART controller > + @param[in] HardwareFlowControl Hardware Flow control > + @param[in] PinMuxing UART controller pin muxing > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoUartPins ( > + IN UINT32 SerialIoUartControllerNumber, > + IN BOOLEAN HardwareFlowControl, > + IN UINT32 PinMuxing, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + UINTN UartGpioIndex; > + > + UartGpioIndex =3D SerialIoUartControllerNumber; > + > + if ((SerialIoUartControllerNumber =3D=3D 0) && (PinMuxing =3D=3D 1)) { > + // Last record is for UART0 second pin set > + if (IsPchLp ()) { > + UartGpioIndex =3D ARRAY_SIZE (mPchLpUartGpio) - 1; > + } else { > + UartGpioIndex =3D ARRAY_SIZE (mPchHUartGpio) - 1; > + } > + } > + > + if (HardwareFlowControl) { > + *NoOfNativePins =3D PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER; > + } else { > + *NoOfNativePins =3D > PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL; > + } > + > + if (IsPchLp ()) { > + if (UartGpioIndex < ARRAY_SIZE (mPchLpUartGpio)) { > + *NativePinsTable =3D mPchLpUartGpio[UartGpioIndex]; > + return; > + } > + } else { > + if (UartGpioIndex < ARRAY_SIZE (mPchHUartGpio)) { > + *NativePinsTable =3D mPchHUartGpio[UartGpioIndex]; > + return; > + } > + } > + > + *NativePinsTable =3D NULL; > + *NoOfNativePins =3D 0; > + ASSERT (FALSE); > +} > + > +// > +// SPI controller pins > +// SPI[controller number][pin: CSB/CLK/MISO/MOSI] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=3D > +{ > + { // SPI0 > + {GPIO_CNL_LP_GPP_B15, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B16, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B17, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B18, GpioPadModeNative1} > + }, > + { // SPI1 > + {GPIO_CNL_LP_GPP_B19, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B20, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B21, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B22, GpioPadModeNative1} > + }, > + { // SPI2 > + {GPIO_CNL_LP_GPP_D9, GpioPadModeNative3}, > + {GPIO_CNL_LP_GPP_D10, GpioPadModeNative3}, > + {GPIO_CNL_LP_GPP_D11, GpioPadModeNative3}, > + {GPIO_CNL_LP_GPP_D12, GpioPadModeNative3} > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=3D > +{ > + { // SPI0 > + {GPIO_CNL_H_GPP_B15, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B16, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B17, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B18, GpioPadModeNative1} > + }, > + { // SPI1 > + {GPIO_CNL_H_GPP_B19, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B20, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B21, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B22, GpioPadModeNative1} > + }, > + { // SPI2 > + {GPIO_CNL_H_GPP_D9, GpioPadModeNative3}, > + {GPIO_CNL_H_GPP_D10, GpioPadModeNative3}, > + {GPIO_CNL_H_GPP_D11, GpioPadModeNative3}, > + {GPIO_CNL_H_GPP_D12, GpioPadModeNative3} > + } > +}; > + > +/** > + This function provides SerialIo SPI controller pins > + > + @param[in] SerialIoSpiControllerNumber SPI controller > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetSerialIoSpiPins ( > + IN UINT32 SerialIoSpiControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchLpSpiGpio)) { > + *NativePinsTable =3D mPchLpSpiGpio[SerialIoSpiControllerNumber]; > + *NoOfNativePins =3D ARRAY_SIZE > (mPchLpSpiGpio[SerialIoSpiControllerNumber]); > + return; > + } > + } else { > + if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchHSpiGpio)) { > + *NativePinsTable =3D mPchHSpiGpio[SerialIoSpiControllerNumber]; > + *NoOfNativePins =3D ARRAY_SIZE > (mPchHSpiGpio[SerialIoSpiControllerNumber]); > + return; > + } > + } > + *NativePinsTable =3D NULL; > + *NoOfNativePins =3D 0; > + ASSERT (FALSE); > +} > + > +// > +// ISH GP pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpIshGPGpio[] =3D > +{ > + {GPIO_CNL_LP_GPP_A18, GpioPadModeNative1},// ISH_GP_0 > + {GPIO_CNL_LP_GPP_A19, GpioPadModeNative1},// ISH_GP_1 > + {GPIO_CNL_LP_GPP_A20, GpioPadModeNative1},// ISH_GP_2 > + {GPIO_CNL_LP_GPP_A21, GpioPadModeNative1},// ISH_GP_3 > + {GPIO_CNL_LP_GPP_A22, GpioPadModeNative1},// ISH_GP_4 > + {GPIO_CNL_LP_GPP_A23, GpioPadModeNative1},// ISH_GP_5 > + {GPIO_CNL_LP_GPP_A12, GpioPadModeNative2},// ISH_GP_6 > + {GPIO_CNL_LP_GPP_A17, GpioPadModeNative2} // ISH_GP_7 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHIshGPGpio[] =3D > +{ > + {GPIO_CNL_H_GPP_A18, GpioPadModeNative1},// ISH_GP_0 > + {GPIO_CNL_H_GPP_A19, GpioPadModeNative1},// ISH_GP_1 > + {GPIO_CNL_H_GPP_A20, GpioPadModeNative1},// ISH_GP_2 > + {GPIO_CNL_H_GPP_A21, GpioPadModeNative1},// ISH_GP_3 > + {GPIO_CNL_H_GPP_A22, GpioPadModeNative1},// ISH_GP_4 > + {GPIO_CNL_H_GPP_A23, GpioPadModeNative1},// ISH_GP_5 > + {GPIO_CNL_H_GPP_A12, GpioPadModeNative2},// ISH_GP_6 > + {GPIO_CNL_H_GPP_A17, GpioPadModeNative2} // ISH_GP_7 > +}; > + > +/** > + This function provides ISH GP pin data > + > + @param[in] IshGpPinNumber ISH GP pin number > + @param[out] NativePin ISH GP pin > +**/ > +VOID > +GpioGetIshGpPin ( > + IN UINT32 IshGpPinNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ) > +{ > + if (IsPchLp ()) { > + if (IshGpPinNumber < ARRAY_SIZE (mPchLpIshGPGpio)) { > + *NativePin =3D mPchLpIshGPGpio[IshGpPinNumber]; > + return; > + } > + } else { > + if (IshGpPinNumber < ARRAY_SIZE (mPchHIshGPGpio)) { > + *NativePin =3D mPchHIshGPGpio[IshGpPinNumber]; > + return; > + } > + } > + *NativePin =3D (GPIO_PAD_NATIVE_FUNCTION){0}; > + ASSERT (FALSE); > +} > + > +// > +// ISH UART controller pins > +// ISH UART[controller number][pin: RXD/TXD/RTSB/CTSB] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =3D > +{ > + { // UART0 > + {GPIO_CNL_LP_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD > + {GPIO_CNL_LP_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD > + {GPIO_CNL_LP_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS > + {GPIO_CNL_LP_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS > + }, > + { // UART1 > + {GPIO_CNL_LP_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD > + {GPIO_CNL_LP_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD > + {GPIO_CNL_LP_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTSB > + {GPIO_CNL_LP_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTSB > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =3D > +{ > + { // UART0 > + {GPIO_CNL_H_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD > + {GPIO_CNL_H_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD > + {GPIO_CNL_H_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS > + {GPIO_CNL_H_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS > + }, > + { // UART1 > + {GPIO_CNL_H_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD > + {GPIO_CNL_H_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD > + {GPIO_CNL_H_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTS > + {GPIO_CNL_H_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTS > + } > +}; > + > +/** > + This function provides ISH UART controller pins > + > + @param[in] IshUartControllerNumber ISH UART controller > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetIshUartPins ( > + IN UINT32 IshUartControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (IshUartControllerNumber < ARRAY_SIZE (mPchLpIshUartGpio)) { > + *NativePinsTable =3D mPchLpIshUartGpio[IshUartControllerNumber]; > + return; > + } > + } else { > + if (IshUartControllerNumber < ARRAY_SIZE (mPchHIshUartGpio)) { > + *NativePinsTable =3D mPchHIshUartGpio[IshUartControllerNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// ISH I2C controller pins > +// ISH I2C[controller number][pin: SDA/SCL] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =3D > +{ > + { // I2C0 > + {GPIO_CNL_LP_GPP_D5, GpioPadModeNative1},// ISH_I2C0_SDA > + {GPIO_CNL_LP_GPP_D6, GpioPadModeNative1} // ISH_I2C0_SCL > + }, > + { // I2C1 > + {GPIO_CNL_LP_GPP_D7, GpioPadModeNative1},// ISH_I2C1_SDA > + {GPIO_CNL_LP_GPP_D8, GpioPadModeNative1} // ISH_I2C1_SCL > + }, > + { // I2C2 > + {GPIO_CNL_LP_GPP_H10, GpioPadModeNative2},// ISH_I2C2_SDA > + {GPIO_CNL_LP_GPP_H11, GpioPadModeNative2} // ISH_I2C2_SCL > + }, > + { // I2C3 > + {GPIO_CNL_LP_GPP_H4, GpioPadModeNative2},// ISH_I2C3_SDA > + {GPIO_CNL_LP_GPP_H5, GpioPadModeNative2} // ISH_I2C3_SCL > + }, > + { // I2C4 > + {GPIO_CNL_LP_GPP_H6, GpioPadModeNative2},// ISH_I2C4_SDA > + {GPIO_CNL_LP_GPP_H7, GpioPadModeNative2} // ISH_I2C4_SCL > + }, > + { // I2C5 > + {GPIO_CNL_LP_GPP_H8, GpioPadModeNative2},// ISH_I2C5_SDA > + {GPIO_CNL_LP_GPP_H9, GpioPadModeNative2} // ISH_I2C5_SCL > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =3D > +{ > + { // I2C0 > + {GPIO_CNL_H_GPP_H19, GpioPadModeNative1},// ISH_I2C0_SDA > + {GPIO_CNL_H_GPP_H20, GpioPadModeNative1} // ISH_I2C0_SCL > + }, > + { // I2C1 > + {GPIO_CNL_H_GPP_H21, GpioPadModeNative1},// ISH_I2C1_SDA > + {GPIO_CNL_H_GPP_H22, GpioPadModeNative1} // ISH_I2C1_SCL > + }, > + { // I2C2 > + {GPIO_CNL_H_GPP_D4, GpioPadModeNative1},// ISH_I2C2_SDA > + {GPIO_CNL_H_GPP_D23, GpioPadModeNative1} // ISH_I2C2_SCL > + } > +}; > + > +/** > + This function provides ISH I2C controller pins > + > + @param[in] IshI2cControllerNumber ISH I2C controller > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetIshI2cPins ( > + IN UINT32 IshI2cControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (IshI2cControllerNumber < ARRAY_SIZE (mPchLpIshI2cGpio)) { > + *NativePinsTable =3D mPchLpIshI2cGpio[IshI2cControllerNumber]; > + return; > + } > + } else { > + if (IshI2cControllerNumber < ARRAY_SIZE (mPchHIshI2cGpio)) { > + *NativePinsTable =3D mPchHIshI2cGpio[IshI2cControllerNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// ISH SPI controller pins > +// ISH SPI[pin: CSB/CLK/MISO/MOSI] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =3D > +{ > + {GPIO_CNL_LP_GPP_D9, GpioPadModeNative1},// ISH_SPI_CSB > + {GPIO_CNL_LP_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK > + {GPIO_CNL_LP_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO > + {GPIO_CNL_LP_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =3D > +{ > + {GPIO_CNL_H_GPP_D9, GpioPadModeNative1},// ISH_SPI_CSB > + {GPIO_CNL_H_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK > + {GPIO_CNL_H_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO > + {GPIO_CNL_H_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI > +}; > + > +/** > + This function provides ISH SPI controller pins > + > + @param[in] IshSpiControllerNumber SPI controller > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetIshSpiPins ( > + IN UINT32 IshSpiControllerNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + if (IshSpiControllerNumber < ARRAY_SIZE (mPchLpIshSpiGpio)) { > + *NativePinsTable =3D mPchLpIshSpiGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpIshSpiGpio); > + return; > + } > + } else { > + if (IshSpiControllerNumber < ARRAY_SIZE (mPchHIshSpiGpio)) { > + *NativePinsTable =3D mPchHIshSpiGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchHIshSpiGpio); > + return; > + } > + } > + > + *NoOfNativePins =3D 0; > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// GPIO pins for SD controller > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpScsSdCardGpio[9] =3D > +{ > + {GPIO_CNL_LP_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B > + {GPIO_CNL_LP_GPP_G0, GpioPadModeNative1},// SD_CMD > + {GPIO_CNL_LP_GPP_G1, GpioPadModeNative1},// SD_DATA_0 > + {GPIO_CNL_LP_GPP_G2, GpioPadModeNative1},// SD_DATA_1 > + {GPIO_CNL_LP_GPP_G3, GpioPadModeNative1},// SD_DATA_2 > + {GPIO_CNL_LP_GPP_G4, GpioPadModeNative1},// SD_DATA_3 > + {GPIO_CNL_LP_GPP_G5, GpioPadModeNative1},// SD_CDB > + {GPIO_CNL_LP_GPP_G6, GpioPadModeNative1},// SD_CLK > + {GPIO_CNL_LP_GPP_G7, GpioPadModeNative1} // SD_WP > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHScsSdCardGpio[9] =3D > +{ > + {GPIO_CNL_H_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B > + {GPIO_CNL_H_GPP_G0, GpioPadModeNative1},// SD_CMD > + {GPIO_CNL_H_GPP_G1, GpioPadModeNative1},// SD_DATA_0 > + {GPIO_CNL_H_GPP_G2, GpioPadModeNative1},// SD_DATA_1 > + {GPIO_CNL_H_GPP_G3, GpioPadModeNative1},// SD_DATA_2 > + {GPIO_CNL_H_GPP_G4, GpioPadModeNative1},// SD_DATA_3 > + {GPIO_CNL_H_GPP_G5, GpioPadModeNative1},// SD_CDB > + {GPIO_CNL_H_GPP_G6, GpioPadModeNative1},// SD_CLK > + {GPIO_CNL_H_GPP_G7, GpioPadModeNative1} // SD_WP > +}; > + > +/** > + This function provides SCS SD CARD controller pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetScsSdCardPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpScsSdCardGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpScsSdCardGpio); > + } else { > + *NativePinsTable =3D mPchHScsSdCardGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchHScsSdCardGpio); > + } > +} > + > +/** > + This function provides SCS SD CARD detect pin > + > + @retval GpioPin SD CARD Detect pin > +**/ > +GPIO_PAD > +GpioGetScsSdCardDetectPin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_VGPIO39; > + } else { > + return GPIO_CNL_H_VGPIO6; > + } > +} > + > +// > +// GPIO pins for eMMC controller > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpScsEmmcGpio[12] =3D > +{ > + {GPIO_CNL_LP_GPP_F11, GpioPadModeNative1},// EMMC_CMD > + {GPIO_CNL_LP_GPP_F12, GpioPadModeNative1},// EMMC_DATA_0 > + {GPIO_CNL_LP_GPP_F13, GpioPadModeNative1},// EMMC_DATA_1 > + {GPIO_CNL_LP_GPP_F14, GpioPadModeNative1},// EMMC_DATA_2 > + {GPIO_CNL_LP_GPP_F15, GpioPadModeNative1},// EMMC_DATA_3 > + {GPIO_CNL_LP_GPP_F16, GpioPadModeNative1},// EMMC_DATA_4 > + {GPIO_CNL_LP_GPP_F17, GpioPadModeNative1},// EMMC_DATA_5 > + {GPIO_CNL_LP_GPP_F18, GpioPadModeNative1},// EMMC_DATA_6 > + {GPIO_CNL_LP_GPP_F19, GpioPadModeNative1},// EMMC_DATA_7 > + {GPIO_CNL_LP_GPP_F20, GpioPadModeNative1},// EMMC_RCLK > + {GPIO_CNL_LP_GPP_F21, GpioPadModeNative1},// EMMC_CLK > + {GPIO_CNL_LP_GPP_F22, GpioPadModeNative1} // EMMC_RESETB > +}; > + > +/** > + This function provides SCS eMMC controller pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetScsEmmcPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpScsEmmcGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpScsEmmcGpio); > + } else { > + ASSERT (FALSE); > + return; > + } > +} > + > +// > +// GPIO pins for HD Audio Link [pin: BCLK/RSTB/SYNC/SDO/SDIx] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_HDA_BCLK, GpioPadModeNative1},// HDA_BCLK > + {GPIO_CNL_LP_HDA_RSTB, GpioPadModeNative1},// HDA_RSTB > + {GPIO_CNL_LP_HDA_SYNC, GpioPadModeNative1},// HDA_SYNC > + {GPIO_CNL_LP_HDA_SDO, GpioPadModeNative1},// HDA_SDO > + {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0 > + {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_HDA_BCLK, GpioPadModeNative1},// HDA_BCLK > + {GPIO_CNL_H_HDA_RSTB, GpioPadModeNative1},// HDA_RSTB > + {GPIO_CNL_H_HDA_SYNC, GpioPadModeNative1},// HDA_SYNC > + {GPIO_CNL_H_HDA_SDO, GpioPadModeNative1},// HDA_SDO > + {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0 > + {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1 > +}; > + > +/** > + This function provides HD Audio Link pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetHdAudioLinkPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpHdaLinkGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpHdaLinkGpio); > + } else { > + *NativePinsTable =3D mPchHHdaLinkGpio; > + *NoOfNativePins =3D ARRAY_SIZE (mPchHHdaLinkGpio); > + } > +} > + > +// > +// GPIO pins for HD Audio DMIC [DMIC number][pin: CLK/DATA] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =3D > +{ > + { // DMIC0 > + {GPIO_CNL_LP_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0 > + {GPIO_CNL_LP_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0 > + }, > + { // DMIC1 > + {GPIO_CNL_LP_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1 > + {GPIO_CNL_LP_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1 > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =3D > +{ > + { // DMIC0 > + {GPIO_CNL_H_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0 > + {GPIO_CNL_H_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0 > + }, > + { // DMIC1 > + {GPIO_CNL_H_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1 > + {GPIO_CNL_H_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1 > + } > +}; > + > +/** > + This function provides DMIC interface pins > + > + @param[in] DmicNumber DMIC interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaDmicPins ( > + IN UINT32 DmicNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (DmicNumber < ARRAY_SIZE (mPchLpHdaDmicGpio)) { > + *NativePinsTable =3D mPchLpHdaDmicGpio[DmicNumber]; > + return; > + } > + } else { > + if (DmicNumber < ARRAY_SIZE (mPchHHdaDmicGpio)) { > + *NativePinsTable =3D mPchHHdaDmicGpio[DmicNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// GPIO pins for HD Audio SSPx/I2Sx interface [SSP number][pin: > SCLK/SFRM/TXD/RXD] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =3D > +{ > + { // SSP0/I2S0 > + {GPIO_CNL_LP_HDA_BCLK, GpioPadModeNative2},// SSP0_SCLK > + {GPIO_CNL_LP_HDA_SYNC, GpioPadModeNative2},// SSP0_SFRM > + {GPIO_CNL_LP_HDA_SDO, GpioPadModeNative2},// SSP0_TXD > + {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD > + }, > + { // SSP1/I2S1 > + {GPIO_CNL_LP_HDA_RSTB, GpioPadModeNative2},// SSP1_SCLK > + {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM > + {GPIO_CNL_LP_SSP1_TXD, GpioPadModeNative1},// SSP1_TXD > + {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD > + }, > + { // SSP2/I2S2 > + {GPIO_CNL_LP_GPP_H0, GpioPadModeNative1},// SSP2_SCLK > + {GPIO_CNL_LP_GPP_H1, GpioPadModeNative1},// SSP2_SFRM > + {GPIO_CNL_LP_GPP_H2, GpioPadModeNative1},// SSP2_TXD > + {GPIO_CNL_LP_GPP_H3, GpioPadModeNative1} // SSP2_RXD > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =3D > +{ > + { // SSP0/I2S0 > + {GPIO_CNL_H_HDA_BCLK, GpioPadModeNative2},// SSP0_SCLK > + {GPIO_CNL_H_HDA_SYNC, GpioPadModeNative2},// SSP0_SFRM > + {GPIO_CNL_H_HDA_SDO, GpioPadModeNative2},// SSP0_TXD > + {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD > + }, > + { // SSP1/I2S1 > + {GPIO_CNL_H_HDA_RSTB, GpioPadModeNative2},// SSP1_SCLK > + {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM > + {GPIO_CNL_H_SSP1_TXD, GpioPadModeNative1},// SSP1_TXD > + {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD > + }, > + { // SSP2/I2S2 > + {GPIO_CNL_H_GPP_D5, GpioPadModeNative1}, // SSP2_SFRM > + {GPIO_CNL_H_GPP_D6, GpioPadModeNative1}, // SSP2_TXD > + {GPIO_CNL_H_GPP_D7, GpioPadModeNative1}, // SSP2_RXD > + {GPIO_CNL_H_GPP_D8, GpioPadModeNative1} // SSP2_SCLK > + } > +}; > + > +/** > + This function provides SSP/I2S interface pins > + > + @param[in] SspInterfaceNumber SSP/I2S interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaSspPins ( > + IN UINT32 SspInterfaceNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (SspInterfaceNumber < ARRAY_SIZE (mPchLpHdaSspInterfaceGpio)) { > + *NativePinsTable =3D mPchLpHdaSspInterfaceGpio[SspInterfaceNumber]= ; > + return; > + } > + } else { > + if (SspInterfaceNumber < ARRAY_SIZE (mPchHHdaSspInterfaceGpio)) { > + *NativePinsTable =3D mPchHHdaSspInterfaceGpio[SspInterfaceNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// GPIO Pin for HD Audio SSP_MCLK/I2S_MCLK > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpHdaSspMasterClockGpio =3D {GPIO_CNL_LP_GPP_D23, > GpioPadModeNative1}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHHdaSspMasterClockGpio =3D {GPIO_CNL_H_GPP_B11, > GpioPadModeNative1}; > + > +/** > + This function sets HDA SSP Master Clock into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableHdaSspMasterClock ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GpioSetPadMode (mPchLpHdaSspMasterClockGpio.Pad, > mPchLpHdaSspMasterClockGpio.Mode); > + } else { > + return GpioSetPadMode (mPchHHdaSspMasterClockGpio.Pad, > mPchHHdaSspMasterClockGpio.Mode); > + } > +} > + > +// > +// GPIO pins for HD Audio SoundWire interface [SNDW number][pin: > CLK/DATA] > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =3D > +{ > + { // SNDW1 > + {GPIO_CNL_LP_HDA_RSTB, GpioPadModeNative3},// SNDW1_CLK > + {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA > + }, > + { // SNDW2 > + {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK > + {GPIO_CNL_LP_SSP1_TXD, GpioPadModeNative2} // SNDW2_DATA > + }, > + { // SNDW3 > + {GPIO_CNL_LP_GPP_D17, GpioPadModeNative2},// SNDW3_CLK > + {GPIO_CNL_LP_GPP_D18, GpioPadModeNative2} // SNDW3_DATA > + }, > + { // SNDW4 > + {GPIO_CNL_LP_GPP_D19, GpioPadModeNative2},// SNDW4_CLK > + {GPIO_CNL_LP_GPP_D20, GpioPadModeNative2} // SNDW4_DATA > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =3D > +{ > + { // SNDW1 > + {GPIO_CNL_H_HDA_RSTB, GpioPadModeNative3},// SNDW1_CLK > + {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA > + }, > + { // SNDW2 > + {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK > + {GPIO_CNL_H_SSP1_TXD, GpioPadModeNative2} // SNDW2_DATA > + }, > + { // SNDW3 > + {GPIO_CNL_H_GPP_D17, GpioPadModeNative2},// SNDW3_CLK > + {GPIO_CNL_H_GPP_D18, GpioPadModeNative2} // SNDW3_DATA > + }, > + { // SNDW4 > + {GPIO_CNL_H_GPP_D19, GpioPadModeNative2},// SNDW4_CLK > + {GPIO_CNL_H_GPP_D20, GpioPadModeNative2} // SNDW4_DATA > + } > +}; > + > +/** > + This function provides SNDW interface pins > + > + @param[in] SndwInterfaceNumber SNDWx interface number > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetHdaSndwPins ( > + IN UINT32 SndwInterfaceNumber, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + if (SndwInterfaceNumber < ARRAY_SIZE (mPchLpHdaSndwGpio)) { > + *NativePinsTable =3D mPchLpHdaSndwGpio[SndwInterfaceNumber]; > + return; > + } > + } else { > + if (SndwInterfaceNumber < ARRAY_SIZE (mPchHHdaSndwGpio)) { > + *NativePinsTable =3D mPchHHdaSndwGpio[SndwInterfaceNumber]; > + return; > + } > + } > + *NativePinsTable =3D NULL; > + ASSERT (FALSE); > +} > + > +// > +// GPIO pins for SMBUS > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_C0, GpioPadModeNative1},// SMB_CLK > + {GPIO_CNL_LP_GPP_C1, GpioPadModeNative1} // SMB_DATA > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_C0, GpioPadModeNative1}, // SMB_CLK > + {GPIO_CNL_H_GPP_C1, GpioPadModeNative1} // SMB_DATA > +}; > + > +/** > + This function provides SMBUS interface pins > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetSmbusPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpSmbusGpio; > + } else { > + *NativePinsTable =3D mPchHSmbusGpio; > + } > +} > + > +// > +// SMBUS Alert pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSmbusAlertGpio =3D {GPIO_CNL_LP_GPP_C2, GpioPadModeNative1}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSmbusAlertGpio =3D {GPIO_CNL_H_GPP_C2, GpioPadModeNative1}; > + > +/** > + This function sets SMBUS ALERT pin into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSmbusAlert ( > + VOID > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION SmbusAlertGpio; > + > + if (IsPchLp ()) { > + SmbusAlertGpio =3D mPchLpSmbusAlertGpio; > + } else { > + SmbusAlertGpio =3D mPchHSmbusAlertGpio; > + } > + > + return GpioSetPadMode (SmbusAlertGpio.Pad, SmbusAlertGpio.Mode); > +} > + > +// > +// SATADevSlpPin to GPIO pin mapping > +// SATA_DEVSLP_x -> GPIO pin y > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSataDevSlpPinToGpioMap[] =3D > +{ > + {GPIO_CNL_LP_GPP_E4, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_E5, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_E6, GpioPadModeNative1} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSataDevSlpPinToGpioMap[] =3D > +{ > + {GPIO_CNL_H_GPP_E4, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F8, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F9, GpioPadModeNative1} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata1DevSlpPinToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 1 > + {GPIO_CNL_H_GPP_E4, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F7, GpioPadModeNative1} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata2DevSlpPinToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 2 > + {GPIO_CNL_H_GPP_E4, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F7, GpioPadModeNative1} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata3DevSlpPinToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 3 > + {GPIO_CNL_H_GPP_E4, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_E6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_F7, GpioPadModeNative1} > +}; > + > +/** > + This function provides SATA DevSlp pin data > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + @param[out] NativePin SATA DevSlp pin > +**/ > +VOID > +GpioGetSataDevSlpPin ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ) > +{ > + if (IsCdfPch ()) { > + if (SataCtrlIndex =3D=3D SATA_1_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata1DevSlpPinToGpioMap)) { > + *NativePin =3D mCdfPchSata1DevSlpPinToGpioMap[SataPort]; > + return; > + } > + } else if (SataCtrlIndex =3D=3D SATA_2_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata2DevSlpPinToGpioMap)) { > + *NativePin =3D mCdfPchSata2DevSlpPinToGpioMap[SataPort]; > + return; > + } > + } else if (SataCtrlIndex =3D=3D SATA_3_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata3DevSlpPinToGpioMap)) { > + *NativePin =3D mCdfPchSata3DevSlpPinToGpioMap[SataPort]; > + return; > + } > + } > + } else { > + if (IsPchLp ()) { > + if (SataPort < ARRAY_SIZE (mPchLpSataDevSlpPinToGpioMap)) { > + *NativePin =3D mPchLpSataDevSlpPinToGpioMap[SataPort]; > + return; > + } > + } else { > + if (SataPort < ARRAY_SIZE (mPchHSataDevSlpPinToGpioMap)) { > + *NativePin =3D mPchHSataDevSlpPinToGpioMap[SataPort]; > + return; > + } > + } > + } > + *NativePin =3D (GPIO_PAD_NATIVE_FUNCTION){0}; > + ASSERT (FALSE); > +} > + > +// > +// SATA reset port to GPIO pin mapping > +// SATAGP_x -> GPIO pin y > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSataGpToGpioMap[] =3D > +{ > + {GPIO_CNL_LP_GPP_E0, GpioPadModeNative2}, > + {GPIO_CNL_LP_GPP_E1, GpioPadModeNative2}, > + {GPIO_CNL_LP_GPP_E2, GpioPadModeNative2} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSataGpToGpioMap[] =3D > +{ > + {GPIO_CNL_H_GPP_E0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E2, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F3, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F4, GpioPadModeNative2} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata1GpToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 1 > + {GPIO_CNL_H_GPP_E0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E2, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F2, GpioPadModeNative2} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata2GpToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 2 > + {GPIO_CNL_H_GPP_E0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E2, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F2, GpioPadModeNative2} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mCdfPchSata3GpToGpioMap[] =3D > +{ > +/// @todo SERVER- update for SATA 3 > + {GPIO_CNL_H_GPP_E0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_E2, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F0, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F1, GpioPadModeNative2}, > + {GPIO_CNL_H_GPP_F2, GpioPadModeNative2} > +}; > + > +/** > + This function provides SATA GP pin data > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + @param[out] NativePin SATA GP pin > +**/ > +VOID > +GpioGetSataGpPin ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ) > +{ > + if (IsCdfPch ()) { > + if (SataCtrlIndex =3D=3D SATA_1_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata1GpToGpioMap)) { > + *NativePin =3D mCdfPchSata1GpToGpioMap[SataPort]; > + return; > + } > + } else if (SataCtrlIndex =3D=3D SATA_2_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata2GpToGpioMap)) { > + *NativePin =3D mCdfPchSata2GpToGpioMap[SataPort]; > + return; > + } > + } else if (SataCtrlIndex =3D=3D SATA_3_CONTROLLER_INDEX) { > + if (SataPort < ARRAY_SIZE (mCdfPchSata3GpToGpioMap)) { > + *NativePin =3D mCdfPchSata3GpToGpioMap[SataPort]; > + return; > + } > + } > + } else { > + if (IsPchLp ()) { > + if (SataPort < ARRAY_SIZE (mPchLpSataGpToGpioMap)) { > + *NativePin =3D mPchLpSataGpToGpioMap[SataPort]; > + return; > + } > + } else { > + if (SataPort < ARRAY_SIZE (mPchHSataGpToGpioMap)) { > + *NativePin =3D mPchHSataGpToGpioMap[SataPort]; > + return; > + } > + } > + } > + *NativePin =3D (GPIO_PAD_NATIVE_FUNCTION){0}; > + ASSERT (FALSE); > +} > + > +// > +// SATA LED pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpSataLedGpio =3D {GPIO_CNL_LP_GPP_E8, GpioPadModeNative1}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHSataLedGpio =3D {GPIO_CNL_H_GPP_E8, GpioPadModeNative1}; > + > +/** > + This function sets SATA LED pin into native mode. SATA LED indicates > + SATA controller activity > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableSataLed ( > + VOID > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION SataLedGpio; > + > + if (IsPchLp ()) { > + SataLedGpio =3D mPchLpSataLedGpio; > + } else { > + SataLedGpio =3D mPchHSataLedGpio; > + } > + > + return GpioSetPadMode (SataLedGpio.Pad, SataLedGpio.Mode); > +} > + > +// > +// USB2 OC pins > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpUsbOcGpioPins[] =3D > +{ > + {GPIO_CNL_LP_GPP_E9, GpioPadModeNative1},// USB_OC_0 > + {GPIO_CNL_LP_GPP_E10, GpioPadModeNative1},// USB_OC_1 > + {GPIO_CNL_LP_GPP_E11, GpioPadModeNative1},// USB_OC_2 > + {GPIO_CNL_LP_GPP_E12, GpioPadModeNative1} // USB_OC_3 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHUsbOcGpioPins[] =3D > +{ > + {GPIO_CNL_H_GPP_E9, GpioPadModeNative1},// USB_OC_0 > + {GPIO_CNL_H_GPP_E10, GpioPadModeNative1},// USB_OC_1 > + {GPIO_CNL_H_GPP_E11, GpioPadModeNative1},// USB_OC_2 > + {GPIO_CNL_H_GPP_E12, GpioPadModeNative1},// USB_OC_3 > + {GPIO_CNL_H_GPP_F15, GpioPadModeNative1},// USB_OC_4 > + {GPIO_CNL_H_GPP_F16, GpioPadModeNative1},// USB_OC_5 > + {GPIO_CNL_H_GPP_F17, GpioPadModeNative1},// USB_OC_6 > + {GPIO_CNL_H_GPP_F18, GpioPadModeNative1} // USB_OC_7 > +}; > + > +/** > + This function enables USB OverCurrent pins by setting > + USB2 OCB pins into native mode > + > + @param[in] OcPinNumber USB OC pin number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableUsbOverCurrent ( > + IN UINTN OcPinNumber > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION OcGpio; > + > + if (IsPchLp ()) { > + if (OcPinNumber >=3D ARRAY_SIZE (mPchLpUsbOcGpioPins)) { > + ASSERT(FALSE); > + return EFI_UNSUPPORTED; > + } > + OcGpio =3D mPchLpUsbOcGpioPins[OcPinNumber]; > + } else { > + if (OcPinNumber >=3D ARRAY_SIZE (mPchHUsbOcGpioPins)) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + OcGpio =3D mPchHUsbOcGpioPins[OcPinNumber]; > + } > + > + return GpioSetPadMode (OcGpio.Pad, OcGpio.Mode); > +} > + > +// > +// GPIO pin for PCIE SCRCLKREQB > +// SCRCLKREQB_x -> GPIO pin y > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpPcieSrcClkReqbPinToGpioMap[] =3D > +{ > + {GPIO_CNL_LP_GPP_B5, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B6, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B7, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B8, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B9, GpioPadModeNative1}, > + {GPIO_CNL_LP_GPP_B10, GpioPadModeNative1} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHPcieSrcClkReqbPinToGpioMap[] =3D > +{ > + {GPIO_CNL_H_GPP_B5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B7, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B8, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B9, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_B10, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H0, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H1, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H2, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H3, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H4, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H5, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H6, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H7, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H8, GpioPadModeNative1}, > + {GPIO_CNL_H_GPP_H9, GpioPadModeNative1} > +}; > + > +/** > + This function provides PCIe CLKREQ pin data > + > + @param[in] ClkreqIndex CLKREQ# number > + @param[out] NativePin Native pin data > +**/ > +VOID > +GpioGetPcieClkReqPin ( > + IN UINT32 ClkreqIndex, > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin > + ) > +{ > + if (IsPchLp ()) { > + if (ClkreqIndex < ARRAY_SIZE (mPchLpPcieSrcClkReqbPinToGpioMap)) { > + *NativePin =3D mPchLpPcieSrcClkReqbPinToGpioMap[ClkreqIndex]; > + return; > + } > + } else { > + if (ClkreqIndex < ARRAY_SIZE (mPchHPcieSrcClkReqbPinToGpioMap)) { > + *NativePin =3D mPchHPcieSrcClkReqbPinToGpioMap[ClkreqIndex]; > + return; > + } > + } > + *NativePin =3D (GPIO_PAD_NATIVE_FUNCTION){0}; > + ASSERT (FALSE); > +} > + > +// > +// PCHHOTB pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpPchHotbPin =3D {GPIO_CNL_LP_GPP_B23, GpioPadModeNative2}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHPchHotbPin =3D {GPIO_CNL_H_GPP_B23, GpioPadModeNative2}; > + > +/** > + This function sets PCHHOT pin into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnablePchHot ( > + VOID > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION PchHotbPin; > + > + if (IsPchLp ()) { > + PchHotbPin =3D mPchLpPchHotbPin; > + } else { > + PchHotbPin =3D mPchHPchHotbPin; > + } > + > + return GpioSetPadMode (PchHotbPin.Pad, PchHotbPin.Mode); > +} > + > +// > +// VRALERTB pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpVrAlertbPin =3D {GPIO_CNL_LP_GPP_B2, GpioPadModeNative1}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHVrAlertbPin =3D {GPIO_CNL_H_GPP_B2, GpioPadModeNative1}; > + > +// > +// CPU_C10_GATE pin > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCpuC10GatePin =3D {GPIO_CNL_LP_GPP_H18, GpioPadModeNative1}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCpuC10GatePin =3D {GPIO_CNL_H_GPP_J1, GpioPadModeNative2}; > + > +/** > + This function sets VRALERTB pin into native mode > + > + @param[in] none > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableVrAlert ( > + VOID > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION VrAlertGpio; > + > + if (IsPchLp ()) { > + VrAlertGpio =3D mPchLpVrAlertbPin; > + } else { > + VrAlertGpio =3D mPchHVrAlertbPin; > + } > + > + return GpioSetPadMode (VrAlertGpio.Pad, VrAlertGpio.Mode); > +} > + > +/** > +This function sets CPU C10 Gate pins into native mode > + > +@retval Status > +**/ > +EFI_STATUS > +GpioEnableCpuC10GatePin ( > + VOID > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION CpuC10GateGpio; > + > + if (IsPchLp ()) { > + CpuC10GateGpio =3D mPchLpCpuC10GatePin; > + } else { > + CpuC10GateGpio =3D mPchHCpuC10GatePin; > + } > + > + return GpioSetPadMode (CpuC10GateGpio.Pad, CpuC10GateGpio.Mode); > +} > + > +// > +// CPU GP pins > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_E3, GpioPadModeNative1}, // CPU_GP_0 > + {GPIO_CNL_LP_GPP_E7, GpioPadModeNative1}, // CPU_GP_1 > + {GPIO_CNL_LP_GPP_B3, GpioPadModeNative1}, // CPU_GP_2 > + {GPIO_CNL_LP_GPP_B4, GpioPadModeNative1}, // CPU_GP_3 > +}; > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_E3, GpioPadModeNative1}, // CPU_GP_0 > + {GPIO_CNL_H_GPP_E7, GpioPadModeNative1}, // CPU_GP_1 > + {GPIO_CNL_H_GPP_B3, GpioPadModeNative1}, // CPU_GP_2 > + {GPIO_CNL_H_GPP_B4, GpioPadModeNative1}, // CPU_GP_3 > +}; > + > +/** > + This function sets CPU GP pins into native mode > + > + @param[in] CpuGpPinNum CPU GP pin number > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableCpuGpPin ( > + IN UINT32 CpuGpPinNum > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION CpuGpPin; > + > + if (IsPchLp ()) { > + if (CpuGpPinNum >=3D ARRAY_SIZE (mPchLpCpuGpPinMap)) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + CpuGpPin =3D mPchLpCpuGpPinMap[CpuGpPinNum]; > + } else { > + if (CpuGpPinNum >=3D ARRAY_SIZE (mPchHCpuGpPinMap)) { > + ASSERT(FALSE); > + return EFI_UNSUPPORTED; > + } > + CpuGpPin =3D mPchHCpuGpPinMap[CpuGpPinNum]; > + } > + > + return GpioSetPadMode (CpuGpPin.Pad, CpuGpPin.Mode); > +} > + > +// > +// DDSP_HPD pins > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpDdspHpdPins[] =3D > +{ > + {GPIO_CNL_LP_GPP_E13, GpioPadModeNative1},// DDSP_HPD_0 > + {GPIO_CNL_LP_GPP_E14, GpioPadModeNative1},// DDSP_HPD_1 > + {GPIO_CNL_LP_GPP_E15, GpioPadModeNative1},// DDSP_HPD_2 > + {GPIO_CNL_LP_GPP_E16, GpioPadModeNative1} // DDSP_HPD_3 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHDdspHpdPins[] =3D > +{ > + {GPIO_CNL_H_GPP_I0, GpioPadModeNative1},// DDSP_HPD_0 > + {GPIO_CNL_H_GPP_I1, GpioPadModeNative1},// DDSP_HPD_1 > + {GPIO_CNL_H_GPP_I2, GpioPadModeNative1},// DDSP_HPD_2 > + {GPIO_CNL_H_GPP_I3, GpioPadModeNative1} // DDSP_HPD_3 > +}; > + > +/** > + This function sets DDSP_HPDx pin into native mode > + > + @param[in] DdspHpdPin DDSP_HPDx pin > + > + @retval Status > +**/ > +EFI_STATUS > +GpioEnableDpHotPlugDetect ( > + IN GPIO_DDSP_HPD DdspHpdPin > + ) > +{ > + GPIO_PAD_NATIVE_FUNCTION DdspHpdGpio; > + UINT32 DdspHpdPinIndex; > + > + if (DdspHpdPin > GpioDdspHpd3) { > + return EFI_UNSUPPORTED; > + } > + > + DdspHpdPinIndex =3D DdspHpdPin - GpioDdspHpd0; > + > + if (IsPchLp ()) { > + if (DdspHpdPinIndex >=3D ARRAY_SIZE (mPchLpDdspHpdPins)) { > + goto Error; > + } > + DdspHpdGpio =3D mPchLpDdspHpdPins[DdspHpdPinIndex]; > + } else { > + if (DdspHpdPinIndex >=3D ARRAY_SIZE (mPchHDdspHpdPins)) { > + goto Error; > + } > + DdspHpdGpio =3D mPchHDdspHpdPins[DdspHpdPinIndex]; > + } > + > + return GpioSetPadMode (DdspHpdGpio.Pad, DdspHpdGpio.Mode); > +Error: > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > +} > + > +// > +// EDP HPD, VDD and BKLT pins > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_E17, GpioPadModeNative1},// EDP_HPD > + {GPIO_CNL_LP_HVMOS_L_VDDEN, GpioPadModeNative1},// VDDEN > + {GPIO_CNL_LP_HVMOS_L_BKLTEN, GpioPadModeNative1},// BKLTEN > + {GPIO_CNL_LP_HVMOS_L_BKLTCTL, GpioPadModeNative1} // BKLTCTL > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_I4, GpioPadModeNative1},// EDP_HPD > + {GPIO_CNL_H_GPP_F19, GpioPadModeNative1},// VDDEN > + {GPIO_CNL_H_GPP_F20, GpioPadModeNative1},// BKLTEN > + {GPIO_CNL_H_GPP_F21, GpioPadModeNative1} // BKLTCTL > +}; > + > +/** > + This function provides eDP pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetEdpPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpEdpPins; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpEdpPins); > + } else { > + *NativePinsTable =3D mPchHEdpPins; > + *NoOfNativePins =3D ARRAY_SIZE (mPchHEdpPins); > + } > +} > + > +// > +// DDPB/C/D/F CTRLCLK and CTRLDATA pins > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_G > PIO_DDP_NUMBER_OF_PINS] =3D > +{ > + {// DDPB > + {GPIO_CNL_LP_GPP_E18, GpioPadModeNative1},// DDPB_CTRLCLK > + {GPIO_CNL_LP_GPP_E19, GpioPadModeNative1} // DDPB_CTRLDATA > + }, > + {// DDPC > + {GPIO_CNL_LP_GPP_E20, GpioPadModeNative1},// DDPC_CTRLCLK > + {GPIO_CNL_LP_GPP_E21, GpioPadModeNative1} // DDPC_CTRLDATA > + }, > + {// DDPD > + {GPIO_CNL_LP_GPP_E22, GpioPadModeNative1},// DDPD_CTRLCLK > + {GPIO_CNL_LP_GPP_E23, GpioPadModeNative1} // DDPD_CTRLDATA > + }, > + {// DDPF > + {GPIO_CNL_LP_GPP_H16, GpioPadModeNative1},// DDPF_CTRLCLK > + {GPIO_CNL_LP_GPP_H17, GpioPadModeNative1} // DDPF_CTRLDATA > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GP > IO_DDP_NUMBER_OF_PINS] =3D > +{ > + {// DDPB > + {GPIO_CNL_H_GPP_I5, GpioPadModeNative1}, // DDPB_CTRLCLK > + {GPIO_CNL_H_GPP_I6, GpioPadModeNative1}, // DDPB_CTRLDATA > + }, > + {// DDPC > + {GPIO_CNL_H_GPP_I7, GpioPadModeNative1}, // DDPC_CTRLCLK > + {GPIO_CNL_H_GPP_I8, GpioPadModeNative1}, // DDPC_CTRLDATA > + }, > + {// DDPD > + {GPIO_CNL_H_GPP_I9, GpioPadModeNative1}, // DDPD_CTRLCLK > + {GPIO_CNL_H_GPP_I10, GpioPadModeNative1}, // DDPD_CTRLDATA > + }, > + {// DDPF > + {GPIO_CNL_H_GPP_F22, GpioPadModeNative1}, // DDPF_CTRLCLK > + {GPIO_CNL_H_GPP_F23, GpioPadModeNative1}, // DDPF_CTRLDATA > + } > +}; > + > +/** > + This function provides DDPx interface pins > + > + @param[in] DdpInterface DDPx interface > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetDdpPins ( > + IN GPIO_DDP DdpInterface, > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + UINT32 DdpInterfaceIndex; > + > + switch (DdpInterface) { > + case GpioDdpB: > + case GpioDdpC: > + case GpioDdpD: > + DdpInterfaceIndex =3D DdpInterface - GpioDdpB; > + break; > + case GpioDdpF: > + DdpInterfaceIndex =3D 3; > + break; > + default: > + goto Error; > + } > + > + if (IsPchLp ()) { > + if (DdpInterfaceIndex < ARRAY_SIZE (mPchLpDdpInterfacePins)) { > + *NativePinsTable =3D mPchLpDdpInterfacePins[DdpInterfaceIndex]; > + return; > + } > + } else { > + if (DdpInterfaceIndex < ARRAY_SIZE (mPchHDdpInterfacePins)) { > + *NativePinsTable =3D mPchHDdpInterfacePins[DdpInterfaceIndex]; > + return; > + } > + } > +Error: > + *NativePinsTable =3D NULL; > + ASSERT(FALSE); > +} > + > +/** > + This function enables CNVi RF Reset pin > +**/ > +VOID > +GpioEnableCnviRfResetPin ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD GpioPad; > + GPIO_PAD_MODE PadMode; > + > + if (IsPchLp ()) { > + GpioPad =3D GPIO_CNL_LP_GPP_H1; > + PadMode =3D GpioPadModeNative3; > + } else { > + GpioPad =3D GPIO_CNL_H_GPP_D5; > + PadMode =3D GpioPadModeNative3; > + } > + > + Status =3D GpioSetPadMode (GpioPad, PadMode); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function enables CNVi MODEM CLKREQ pin > +**/ > +VOID > +GpioEnableCnviModemClkReqPin ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD GpioPad; > + GPIO_PAD_MODE PadMode; > + > + if (IsPchLp ()) { > + GpioPad =3D GPIO_CNL_LP_GPP_H2; > + PadMode =3D GpioPadModeNative3; > + } else { > + GpioPad =3D GPIO_CNL_H_GPP_D6; > + PadMode =3D GpioPadModeNative3; > + } > + > + Status =3D GpioSetPadMode (GpioPad, PadMode); > + ASSERT_EFI_ERROR (Status); > +} > + > + > +/** > + This function provides CNVi BT interface select pin > + > + @retval GpioPad GPIO pad for CNVi BT interface select > +**/ > +GPIO_PAD > +GpioGetCnviBtIfSelectPin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_VGPIO5; > + } else { > + return GPIO_CNL_H_VGPIO7; > + } > +} > + > +/** > + This function provides CNVi BT Charging pin > + > + @retval GpioPad GPIO pad for CNVi BT Charging select > +**/ > +GPIO_PAD > +GpioGetCnviBtChargingPin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_VGPIO3; > + } else { > + return GPIO_CNL_H_VGPIO3; > + } > +} > + > +/** > + This function provides CNVi A4WP pin > + > + @param[out] GpioNativePad GPIO native pad for CNVi A4WP > +**/ > +VOID > +GpioGetCnviA4WpPin ( > + OUT GPIO_PAD_NATIVE_FUNCTION *GpioNativePad > + ) > +{ > + GpioNativePad->Mode =3D GpioPadModeNative1; > + if (IsPchLp ()) { > + GpioNativePad->Pad =3D GPIO_CNL_LP_GPP_F23; > + } else { > + GpioNativePad->Pad =3D GPIO_CNL_H_GPP_J11; > + } > +} > + > +/** > + This function provides CNVi BT host wake int pin > + > + @retval GpioPad GPIO pad BT host wake int > +**/ > +GPIO_PAD > +GpioGetCnviBtHostWakeIntPin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_VGPIO4; > + } else { > + return GPIO_CNL_H_VGPIO4; > + } > +} > + > +// > +// CNVi Bluetooth UART pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_LP_VGPIO6, // vCNV_BT_UART_TXD > + GPIO_CNL_LP_VGPIO7, // vCNV_BT_UART_RXD > + GPIO_CNL_LP_VGPIO8, // vCNV_BT_UART_CTS_B > + GPIO_CNL_LP_VGPIO9 // vCNV_BT_UART_RTS_B > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_H_VGPIO8, // vCNV_BT_UART_TXD > + GPIO_CNL_H_VGPIO9, // vCNV_BT_UART_RXD > + GPIO_CNL_H_VGPIO10,// vCNV_BT_UART_CTS_B > + GPIO_CNL_H_VGPIO11 // vCNV_BT_UART_RTS_B > +}; > + > +// > +// vUART for Bluetooth > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] > =3D > +{ > + GPIO_CNL_LP_VGPIO18, // vUART0_TXD > + GPIO_CNL_LP_VGPIO19, // vUART0_RXD > + GPIO_CNL_LP_VGPIO20, // vUART0_CTS_B > + GPIO_CNL_LP_VGPIO21 // vUART0_RTS_B > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_H_VGPIO20, // vUART0_TXD > + GPIO_CNL_H_VGPIO21, // vUART0_RXD > + GPIO_CNL_H_VGPIO22, // vUART0_CTS_B > + GPIO_CNL_H_VGPIO23 // vUART0_RTS_B > +}; > + > +/** > + This function provides CNVi BT UART pins > + > + @param[in] ConnectionType CNVi BT UART connection type > + @param[out] VCnviBtUartPad Table with vCNV_BT_UARTx pads > + @param[out] VCnviBtUartPadMode vCNV_BT_UARTx pad mode > + @param[out] VUartForCnviBtPad Table with vUART0 pads > + @param[out] VUartForCnviBtPadMode vUART0 pad mode > +**/ > +VOID > +GpioGetCnviBtUartPins ( > + IN VGPIO_CNVI_BT_UART_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviBtUartPad, > + OUT GPIO_PAD_MODE *VCnviBtUartPadMode, > + OUT GPIO_PAD **VUartForCnviBtPad, > + OUT GPIO_PAD_MODE *VUartForCnviBtPadMode > + ) > +{ > + if (IsPchLp ()) { > + *VCnviBtUartPad =3D mPchLpVCnviBtUartGpioPad; > + *VUartForCnviBtPad =3D mPchLpVUartForCnviBtGpioPad; > + } else { > + *VCnviBtUartPad =3D mPchHVCnviBtUartGpioPad; > + *VUartForCnviBtPad =3D mPchHVUartForCnviBtGpioPad; > + } > + > + switch (ConnectionType) { > + case GpioCnviBtUartToSerialIoUart0: > + *VCnviBtUartPadMode =3D GpioPadModeNative1; > + *VUartForCnviBtPadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviBtUartToIshUart0: > + *VCnviBtUartPadMode =3D GpioPadModeNative2; > + *VUartForCnviBtPadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviBtUartNotConnected: > + case GpioCnviBtUartToExternalPads: > + *VCnviBtUartPadMode =3D GpioPadModeGpio; > + *VUartForCnviBtPadMode =3D GpioPadModeGpio; > + break; > + default: > + ASSERT (FALSE); > + return; > + } > +} > + > +// > +// CNVi Bluetooth UART external pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] > =3D > +{ > + {GPIO_CNL_LP_GPP_C8, GpioPadModeNative2}, // CNV_BT_UART_0_RXD > + {GPIO_CNL_LP_GPP_C9, GpioPadModeNative2}, // CNV_BT_UART_0_TXD > + {GPIO_CNL_LP_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS > + {GPIO_CNL_LP_GPP_C11, GpioPadModeNative2} // CNV_BT_UART_0_CTS > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_C8, GpioPadModeNative2}, // CNV_BT_UART_0_RXD > + {GPIO_CNL_H_GPP_C9, GpioPadModeNative2}, // CNV_BT_UART_0_TXD > + {GPIO_CNL_H_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS > + {GPIO_CNL_H_GPP_C11, GpioPadModeNative2} // CNV_BT_UART_0_CTS > +}; > + > +/** > + This function provides CNVi BT UART external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviBtUartExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpCnviBtUartExternalPads; > + } else { > + *NativePinsTable =3D mPchHCnviBtUartExternalPads; > + } > +} > + > +// > +// CNVi Bluetooth I2S pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_LP_VGPIO30, // vCNV_BT_I2S_BCLK > + GPIO_CNL_LP_VGPIO31, // vCNV_BT_I2S_WS_SYNC > + GPIO_CNL_LP_VGPIO32, // vCNV_BT_I2S_SDO > + GPIO_CNL_LP_VGPIO33 // vCNV_BT_I2S_SDI > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_H_VGPIO32, // vCNV_BT_I2S_BCLK > + GPIO_CNL_H_VGPIO33, // vCNV_BT_I2S_WS_SYNC > + GPIO_CNL_H_VGPIO34, // vCNV_BT_I2S_SDO > + GPIO_CNL_H_VGPIO35 // vCNV_BT_I2S_SDI > +}; > + > +// > +// vSSP for Bluetooth > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_LP_VGPIO34, // vSSP2_SCLK > + GPIO_CNL_LP_VGPIO35, // vSSP2_SFRM > + GPIO_CNL_LP_VGPIO36, // vSSP2_TXD > + GPIO_CNL_LP_VGPIO37 // vSSP2_RXD > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_H_VGPIO36, // vSSP2_SCLK > + GPIO_CNL_H_VGPIO37, // vSSP2_SFRM > + GPIO_CNL_H_VGPIO38, // vSSP2_TXD > + GPIO_CNL_H_VGPIO39 // vSSP2_RXD > +}; > + > +/** > + This function provides CNVi BT I2S pins > + > + @param[in] ConnectionType CNVi BT I2S connection type > + @param[out] VCnviBtI2sPad Table with vCNV_BT_I2Sx pads > + @param[out] VCnviBtI2sPadMode vCNV_BT_I2Sx pad mode > + @param[out] VSspForCnviBtPad Table with vSSP2 pads > + @param[out] VSspForCnviBtPadMode vSSP2 pad mode > +**/ > +VOID > +GpioGetCnviBtI2sPins ( > + IN VGPIO_CNVI_BT_I2S_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviBtI2sPad, > + OUT GPIO_PAD_MODE *VCnviBtI2sPadMode, > + OUT GPIO_PAD **VSspForCnviBtPad, > + OUT GPIO_PAD_MODE *VSspForCnviBtPadMode > + ) > +{ > + if (IsPchLp ()) { > + *VCnviBtI2sPad =3D mPchLpVCnviBtI2sGpioPad; > + *VSspForCnviBtPad =3D mPchLpVSspForCnviBtGpioPad; > + } else { > + *VCnviBtI2sPad =3D mPchHVCnviBtI2sGpioPad; > + *VSspForCnviBtPad =3D mPchHVSspForCnviBtGpioPad; > + } > + > + switch (ConnectionType) { > + case GpioCnviBtI2sToSsp0: > + *VCnviBtI2sPadMode =3D GpioPadModeNative1; > + *VSspForCnviBtPadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviBtI2sToSsp1: > + *VCnviBtI2sPadMode =3D GpioPadModeNative2; > + *VSspForCnviBtPadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviBtI2sToSsp2: > + *VCnviBtI2sPadMode =3D GpioPadModeNative3; > + *VSspForCnviBtPadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviBtI2sNotConnected: > + case GpioCnviBtI2sToExternalPads: > + *VCnviBtI2sPadMode =3D GpioPadModeGpio; > + *VSspForCnviBtPadMode =3D GpioPadModeGpio; > + break; > + default: > + ASSERT (FALSE); > + return; > + } > +} > + > +// > +// CNVi Bluetooth I2S external pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_H0, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC > + {GPIO_CNL_LP_GPP_H1, GpioPadModeNative2}, // CNV_BT_I2S_BCLK > + {GPIO_CNL_LP_GPP_H2, GpioPadModeNative2}, // CNV_BT_I2S_SDI > + {GPIO_CNL_LP_GPP_H3, GpioPadModeNative2} // CNV_BT_I2S_SDO > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_D8, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC > + {GPIO_CNL_H_GPP_D5, GpioPadModeNative2}, // CNV_BT_I2S_BCLK > + {GPIO_CNL_H_GPP_D6, GpioPadModeNative2}, // CNV_BT_I2S_SDI > + {GPIO_CNL_H_GPP_D7, GpioPadModeNative2} // CNV_BT_I2S_SDO > +}; > + > +/** > + This function provides CNVi BT I2S external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviBtI2sExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpCnviBtI2sExternalPads; > + } else { > + *NativePinsTable =3D mPchHCnviBtI2sExternalPads; > + } > +} > + > +// > +// CNVi MFUART1 pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_LP_VGPIO10, // vCNV_MFUART1_TXD > + GPIO_CNL_LP_VGPIO11, // vCNV_MFUART1_RXD > + GPIO_CNL_LP_VGPIO12, // vCNV_MFUART1_CTS_B > + GPIO_CNL_LP_VGPIO13 // vCNV_MFUART1_RTS_B > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =3D > +{ > + GPIO_CNL_H_VGPIO12, // vCNV_MFUART1_TXD > + GPIO_CNL_H_VGPIO13, // vCNV_MFUART1_RXD > + GPIO_CNL_H_VGPIO14, // vCNV_MFUART1_CTS_B > + GPIO_CNL_H_VGPIO15 // vCNV_MFUART1_RTS_B > +}; > + > +// > +// vUART for MFUART1 > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchLpVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_ > PINS] =3D > +{ > + GPIO_CNL_LP_VGPIO22, // vISH_UART0_TXD > + GPIO_CNL_LP_VGPIO23, // vISH_UART0_RXD > + GPIO_CNL_LP_VGPIO24, // vISH_UART0_CTS_B > + GPIO_CNL_LP_VGPIO25 // vISH_UART0_RTS_B > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD > mPchHVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_ > PINS] =3D > +{ > + GPIO_CNL_H_VGPIO24, // vISH_UART0_TXD > + GPIO_CNL_H_VGPIO25, // vISH_UART0_RXD > + GPIO_CNL_H_VGPIO26, // vISH_UART0_CTS_B > + GPIO_CNL_H_VGPIO27 // vISH_UART0_RTS_B > +}; > + > +/** > + This function provides CNVi MFUART1 pins > + > + @param[in] ConnectionType CNVi MFUART1 connection type > + @param[out] VCnviBtI2sPad Table with vCNV_MFUART1x pads > + @param[out] VCnviBtI2sPadMode vCNV_MFUART1x pad mode > + @param[out] VSspForCnviBtPad Table with vISH_UART0 pads > + @param[out] VSspForCnviBtPadMode vISH_UART0 pad mode > +**/ > +VOID > +GpioGetCnviMfUart1Pins ( > + IN VGPIO_CNVI_MF_UART1_CONNECTION_TYPE ConnectionType, > + OUT GPIO_PAD **VCnviMfUart1Pad, > + OUT GPIO_PAD_MODE *VCnviMfUart1PadMode, > + OUT GPIO_PAD **VUartForCnviMfUart1Pad, > + OUT GPIO_PAD_MODE *VUartForCnviMfUart1PadMode > + ) > +{ > + if (IsPchLp ()) { > + *VCnviMfUart1Pad =3D mPchLpVCnviMfUart1GpioPad; > + *VUartForCnviMfUart1Pad =3D mPchLpVUartForCnviMfUart1GpioPad; > + } else { > + *VCnviMfUart1Pad =3D mPchHVCnviMfUart1GpioPad; > + *VUartForCnviMfUart1Pad =3D mPchHVUartForCnviMfUart1GpioPad; > + } > + > + switch (ConnectionType) { > + case GpioCnviMfUart1ToSerialIoUart2: > + *VCnviMfUart1PadMode =3D GpioPadModeNative2; > + *VUartForCnviMfUart1PadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviMfUart1ToIshUart0: > + *VCnviMfUart1PadMode =3D GpioPadModeNative1; > + *VUartForCnviMfUart1PadMode =3D GpioPadModeNative1; > + break; > + case GpioCnviMfUart1NotConnected: > + case GpioCnviMfUart1ToExternalPads: > + *VCnviMfUart1PadMode =3D GpioPadModeGpio; > + *VUartForCnviMfUart1PadMode =3D GpioPadModeGpio; > + break; > + default: > + ASSERT (FALSE); > + return; > + } > +} > + > +// > +// CNVi MFUART1 external pads > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] > =3D > +{ > + {GPIO_CNL_LP_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD > + {GPIO_CNL_LP_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD > + {GPIO_CNL_LP_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS > + {GPIO_CNL_LP_GPP_C15, GpioPadModeNative3} // CNV_MFUART1_CTS > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] > =3D > +{ > + {GPIO_CNL_H_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD > + {GPIO_CNL_H_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD > + {GPIO_CNL_H_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS > + {GPIO_CNL_H_GPP_C15, GpioPadModeNative3} // CNV_MFUART1_CTS > +}; > + > +/** > + This function provides CNVi MFUART1 external pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnviMfUart1ExternalPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpCnviMfUart1ExternalPads; > + } else { > + *NativePinsTable =3D mPchHCnviMfUart1ExternalPads; > + } > +} > + > +/** > + This function provides CNVi Bluetooth Enable pad > + > + @retval GpioPad CNVi Bluetooth Enable pad > +**/ > +GPIO_PAD > +GpioGetCnviBtEnablePin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_VGPIO0; > + } else { > + return GPIO_CNL_H_VGPIO0; > + } > +} > + > +// > +// CNVi BRI (Bluetooth Radio Interface) and RGI (Radio Generic Interface= ) > buses from Pulsar to CRF (Companion RF) > +// > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_F4, GpioPadModeNative1}, // CNV_BRI_DT > + {GPIO_CNL_LP_GPP_F5, GpioPadModeNative1}, // CNV_BRI_RSP > + {GPIO_CNL_LP_GPP_F6, GpioPadModeNative1}, // CNV_RGI_DT > + {GPIO_CNL_LP_GPP_F7, GpioPadModeNative1} // CNV_RGI_RSP > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_J4, GpioPadModeNative1}, // CNV_BRI_DT > + {GPIO_CNL_H_GPP_J5, GpioPadModeNative1}, // CNV_BRI_RSP > + {GPIO_CNL_H_GPP_J6, GpioPadModeNative1}, // CNV_RGI_DT > + {GPIO_CNL_H_GPP_J7, GpioPadModeNative1} // CNV_RGI_RSP > +}; > + > +/** > + This function provides CNVi BRI RGI GPIO pads > + > + @param[out] NativePinsTable Table with pins > +**/ > +VOID > +GpioGetCnvBriRgiPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpCnviBriRgiGpioPad; > + } else { > + *NativePinsTable =3D mPchHCnviBriRgiGpioPad; > + } > +} > + > + > +/** > + This function sets CNVi WiFi mode > + > + @param[in] Value CNVi WiFi Mode value > + GpioCnviWiFiAuto: WiFi is automaticall= y > enabled/disabled by WiFi core > + GpioCnviWiFiEnabled: WiFi is enabled r= egardless of > WiFi core decision > + @retval Status > +**/ > +EFI_STATUS > +GpioSetCnviWifiMode ( > + IN VGPIO_CNVI_WIFI_MODE WiFiMode > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD CnviWifiModePad; > + GPIO_CONFIG PadConfig; > + > + ZeroMem (&PadConfig, sizeof (PadConfig)); > + > + PadConfig.PadMode =3D GpioPadModeGpio; > + PadConfig.Direction =3D GpioDirOut; > + if (WiFiMode =3D=3D GpioCnviWiFiEnabled) { > + PadConfig.OutputState =3D GpioOutHigh; > + } else { > + PadConfig.OutputState =3D GpioOutLow; > + } > + > + if (IsPchLp ()) { > + CnviWifiModePad =3D GPIO_CNL_LP_VGPIO2; > + } else { > + CnviWifiModePad =3D GPIO_CNL_H_VGPIO2; > + } > + > + Status =3D GpioSetPadConfig (CnviWifiModePad, &PadConfig); > + ASSERT_EFI_ERROR (Status); > + > + return EFI_SUCCESS; > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchLpImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_LP_GPP_D4, GpioPadModeNative1}, // IMGCLKOUT_0 > + {GPIO_CNL_LP_GPP_H20, GpioPadModeNative1}, // IMGCLKOUT_1 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION > mPchHImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =3D > +{ > + {GPIO_CNL_H_GPP_K22, GpioPadModeNative1}, // IMGCLKOUT_0 > + {GPIO_CNL_H_GPP_K23, GpioPadModeNative1}, // IMGCLKOUT_1 > +}; > + > +/** > + This function provides IMGCLKOUT pins > + > + @param[out] NativePinsTable Table with pins > + @param[out] NoOfNativePins Number of pins > +**/ > +VOID > +GpioGetImgClkOutPins ( > + OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable, > + OUT UINT32 *NoOfNativePins > + ) > +{ > + if (IsPchLp ()) { > + *NativePinsTable =3D mPchLpImguClkOutGpioPad; > + *NoOfNativePins =3D ARRAY_SIZE (mPchLpImguClkOutGpioPad); > + } else { > + *NativePinsTable =3D mPchHImguClkOutGpioPad; > + *NoOfNativePins =3D ARRAY_SIZE (mPchHImguClkOutGpioPad); > + } > +} > + > +/** > + This function provides PWRBTN pin > + > + @retval GpioPad PWRTBTN pin > +**/ > +GPIO_PAD > +GpioGetPwrBtnPin ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_GPD3; > + } else { > + return GPIO_CNL_H_GPD3; > + } > +} > + > +/** > + This function provides LPC pin > + > + @retval GpioPad LPC pin > +**/ > +GPIO_PAD > +GpioGetLpcPin ( > + VOID > + ) > +{ > + if (PchGetLpcDid () =3D=3D V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU) { > + return GPIO_CNL_H_GPP_A8; > + } else { > + return 0; > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLib.c > new file mode 100644 > index 0000000000..2cf11c6da2 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLib.c > @@ -0,0 +1,752 @@ > +/** @file > + This file contains GPIO routines for RC usage > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "GpioNativePrivateLibInternal.h" > + > +/** > + This procedure is used to check if GpioPad is valid for certain chipse= t > + > + @param[in] GpioPad GPIO pad > + > + @retval TRUE This pin is valid on this chipset > + FALSE Incorrect pin > +**/ > +BOOLEAN > +GpioIsCorrectPadForThisChipset ( > + IN GPIO_PAD GpioPad > + ) > +{ > + return ((GPIO_GET_CHIPSET_ID (GpioPad) =3D=3D GpioGetThisChipsetId ())= && > + (GpioGetGroupIndexFromGpioPad (GpioPad) < > GpioGetNumberOfGroups ())); > +} > + > +/** > + This procedure will get value of selected gpio register > + > + @param[in] Group GPIO group number > + @param[in] Offset GPIO register offset > + @param[out] RegVal Value of gpio register > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetReg ( > + IN GPIO_GROUP Group, > + IN UINT32 Offset, > + OUT UINT32 *RegVal > + ) > +{ > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + // > + // Check if group argument exceeds GPIO GROUP INFO array > + // > + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + *RegVal =3D MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, Offset)); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will set value of selected gpio register > + > + @param[in] Group GPIO group number > + @param[in] Offset GPIO register offset > + @param[in] RegVal Value of gpio register > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioSetReg ( > + IN GPIO_GROUP Group, > + IN UINT32 Offset, > + IN UINT32 RegVal > + ) > +{ > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + // > + // Check if group argument exceeds GPIO GROUP INFO array > + // > + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + MmioWrite32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, Offset), RegVal); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used by PchSmiDispatcher and will return information > + needed to register GPI SMI. > + > + @param[in] Index GPI SMI number > + @param[out] GpioPin GPIO pin > + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi > Registers > + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN > register > + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetPadAndSmiRegs ( > + IN UINT32 Index, > + OUT GPIO_PAD *GpioPin, > + OUT UINT8 *GpiSmiBitOffset, > + OUT UINT32 *GpiHostSwOwnRegAddress, > + OUT UINT32 *GpiSmiStsRegAddress > + ) > +{ > + UINT32 GroupIndex; > + UINT32 PadNumber; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + GPIO_GROUP GpioGroup; > + UINT32 GpioGroupInfoLength; > + UINT32 SmiStsRegOffset; > + UINT32 HostSwOwnRegOffset; > + GPIO_PAD_OWN PadOwnVal; > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + PadNumber =3D 0; > + GroupIndex =3D 0; > + for (GroupIndex =3D 0; GroupIndex < GpioGroupInfoLength; GroupIndex++)= { > + PadNumber =3D Index; > + if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) { > + // > + // Found group and pad number > + // > + break; > + } > + Index =3D Index - GpioGroupInfo[GroupIndex].PadPerGroup; > + } > + > + // > + // Check if legal pad number > + // > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup){ > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check if selected group has GPI SMI Enable and Status registers > + // > + if (GpioGroupInfo[GroupIndex].SmiEnOffset =3D=3D > NO_REGISTER_FOR_PROPERTY) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioGroup =3D GpioGetGroupFromGroupIndex (GroupIndex); > + *GpioPin =3D GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, > PadNumber); > + > + DEBUG_CODE_BEGIN (); > + // > + // Check if selected GPIO Pad is not owned by CSME/ISH/IE > + // > + GpioGetPadOwnership (*GpioPin, &PadOwnVal); > + if (PadOwnVal !=3D GpioPadOwnHost) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a not owned by host!\n", > GpioName (*GpioPin))); > + return EFI_INVALID_PARAMETER; > + } > + DEBUG_CODE_END (); > + > + *GpiSmiBitOffset =3D (UINT8)(PadNumber % 32); > + > + HostSwOwnRegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset + > (PadNumber / 32) * 0x4; > + *GpiHostSwOwnRegAddress =3D PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, HostSwOwnRegOffset); > + > + SmiStsRegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumbe= r > / 32) * 0x4; > + *GpiSmiStsRegAddress =3D PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, SmiStsRegOffset); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will set GPIO Driver IRQ number > + > + @param[in] Irq Irq number > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid IRQ number > +**/ > +EFI_STATUS > +GpioSetIrq ( > + IN UINT8 Irq > + ) > +{ > + UINT32 Data32And; > + UINT32 Data32Or; > + PCH_SBI_PID *GpioComSbiIds; > + UINT32 NoOfGpioComs; > + UINT32 GpioComIndex; > + > + Data32And =3D (UINT32)~(B_GPIO_PCR_MISCCFG_IRQ_ROUTE); > + Data32Or =3D (UINT32)Irq << N_GPIO_PCR_MISCCFG_IRQ_ROUTE; > + > + NoOfGpioComs =3D GpioGetComSbiPortIds (&GpioComSbiIds); > + > + // > + // Program MISCCFG register for each community > + // > + for (GpioComIndex =3D 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) > { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], > R_GPIO_PCR_MISCCFG), > + Data32And, > + Data32Or > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will return Port ID of GPIO Community from GpioPad > + > + @param[in] GpioPad GpioPad > + > + @retval GpioCommunityPortId Port ID of GPIO Community > +**/ > +UINT8 > +GpioGetGpioCommunityPortIdFromGpioPad ( > + IN GPIO_PAD GpioPad > + ) > +{ > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + return GpioGroupInfo[GroupIndex].Community; > +} > + > +/** > + This procedure will return PadCfg address from GpioPad > + > + @param[in] GpioPad GpioPad > + > + @retval GpioPadCfgAddress PadCfg Address of GpioPad > +**/ > +UINT32 > +GpioGetGpioPadCfgAddressFromGpioPad ( > + IN GPIO_PAD GpioPad > + ) > +{ > + UINT32 PadCfgRegAddress; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + // > + // Create Pad Configuration register offset > + // > + PadCfgRegAddress =3D GpioGroupInfo[GroupIndex].PadCfgOffset + > S_GPIO_PCR_PADCFG * PadNumber; > + > + return PadCfgRegAddress; > +} > + > + > +/** > + This procedure will check if GpioPad is owned by host. > + > + @param[in] GpioPad GPIO pad > + > + @retval TRUE GPIO pad is owned by host > + @retval FALSE GPIO pad is not owned by host and should not = be > used with GPIO lib API > +**/ > +BOOLEAN > +GpioIsPadHostOwned ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_PAD_OWN PadOwnVal; > + > + // > + // Check if selected GPIO Pad is not owned by CSME/ISH > + // If GPIO is not owned by Host all access to PadCfg will be dropped > + // > + GpioGetPadOwnership (GpioPad, &PadOwnVal); > + if (PadOwnVal !=3D GpioPadOwnHost) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a is not owned by host!\n", > GpioName (GpioPad))); > + return FALSE; > + } > + > + return TRUE; > +} > + > +/** > + This procedure will check if GpioPad argument is valid. > + Function will check below conditions: > + - GpioPad represents a pad for current PCH > + - GpioPad belongs to valid GpioGroup > + - GPIO PadNumber is not greater than number of pads for this group > + > + @param[in] GpioPad GPIO pad > + > + @retval TRUE GPIO pad is valid and can be used with GPIO l= ib API > + @retval FALSE GPIO pad is invalid and cannot be used with G= PIO lib > API > +**/ > +BOOLEAN > +GpioIsPadValid ( > + IN GPIO_PAD GpioPad > + ) > +{ > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 PadNumber; > + > + if (!GpioIsCorrectPadForThisChipset (GpioPad)) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used > on this chipset!\n", GpioPad)); > + goto Error; > + } > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + // > + // Check if legal pin number > + // > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + if (PadNumber >=3D GpioGroupInfo[GpioGetGroupIndexFromGpioPad > (GpioPad)].PadPerGroup) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible > range for this group\n", PadNumber)); > + goto Error; > + } > + > + return TRUE; > +Error: > + ASSERT (FALSE); > + return FALSE; > +} > + > +/** > + This procedure will read GPIO Pad Configuration register > + > + @param[in] GpioPad GPIO pad > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 > + > + @retval PadCfgRegValue PADCFG_DWx value > +**/ > +UINT32 > +GpioReadPadCfgReg ( > + IN GPIO_PAD GpioPad, > + IN UINT8 DwReg > + ) > +{ > + UINT32 PadCfgReg; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + // > + // Create Pad Configuration register offset > + // > + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + > S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg; > + > + return MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, PadCfgReg)); > +} > + > +/** > + This procedure will write or read GPIO Pad Configuration register > + > + @param[in] GpioPad GPIO pad > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 > + @param[in] PadCfgAndMask Mask to be AND'ed with PADCFG reg > value > + @param[in] PadCfgOrMask Mask to be OR'ed with PADCFG reg value > + > + @retval none > +**/ > +VOID > +GpioWritePadCfgReg ( > + IN GPIO_PAD GpioPad, > + IN UINT8 DwReg, > + IN UINT32 PadCfgAndMask, > + IN UINT32 PadCfgOrMask > + ) > +{ > + UINT32 PadCfgReg; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + UINT32 PadCfgLock; > + UINT32 PadCfgLockTx; > + > + PadCfgLock =3D 0; > + PadCfgLockTx =3D 0; > + > + // > + // Check if Pad Configuration (except output state) is to be changed. > + // If AND and OR masks will indicate that configuration fields (other = than > output control) > + // are to be modified it means that there is a need to perform an unlo= ck (if > set) > + // > + if ((~PadCfgAndMask | PadCfgOrMask) & (UINT32)~B_GPIO_PCR_TX_STATE) > { > + GpioGetPadCfgLock (GpioPad, &PadCfgLock); > + if (PadCfgLock) { > + GpioUnlockPadCfg (GpioPad); > + } > + } > + > + // > + // Check if Pad Output state is to be changed > + // If AND and OR masks will indicate that output control > + // is to be modified it means that there is a need to perform an unloc= k (if set) > + // > + if ((~PadCfgAndMask | PadCfgOrMask) & B_GPIO_PCR_TX_STATE) { > + GpioGetPadCfgLockTx (GpioPad, &PadCfgLockTx); > + if (PadCfgLockTx) { > + GpioUnlockPadCfgTx (GpioPad); > + } > + } > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + // > + // Create Pad Configuration register offset > + // > + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + > S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg; > + > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > PadCfgReg), > + PadCfgAndMask, > + PadCfgOrMask > + ); > + > + if (PadCfgLock) { > + GpioLockPadCfg (GpioPad); > + } > + if (PadCfgLockTx) { > + GpioLockPadCfgTx (GpioPad); > + } > +} > + > +/** > + This procedure will set GPIO mode > + > + @param[in] GpioPad GPIO pad > + @param[out] PadModeValue GPIO pad mode value > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioSetPadMode ( > + IN GPIO_PAD GpioPad, > + IN GPIO_PAD_MODE PadModeValue > + ) > +{ > + UINT32 PadCfgOrMask; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (PadModeValue !=3D (GPIO_PAD_MODE)GpioHardwareDefault) { > + > + PadCfgOrMask =3D (((PadModeValue & B_GPIO_PAD_MODE_MASK) >> > (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE); > + > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~B_GPIO_PCR_PAD_MODE, > + PadCfgOrMask > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO mode > + > + @param[in] GpioPad GPIO pad > + @param[out] PadModeValue GPIO pad mode value > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetPadMode ( > + IN GPIO_PAD GpioPad, > + OUT GPIO_PAD_MODE *PadModeValue > + ) > +{ > + UINT32 PadCfgRegValue; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgRegValue =3D GpioReadPadCfgReg (GpioPad, 0); > + > + *PadModeValue =3D (GPIO_PAD_MODE)(((PadCfgRegValue & > B_GPIO_PCR_PAD_MODE) >> (N_GPIO_PCR_PAD_MODE - > (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPIO_PAD_MODE_BIT_POS)); > + > + return EFI_SUCCESS; > +} > + > +/** > + The function performs GPIO Power Management programming. > +**/ > +VOID > +GpioConfigurePm ( > + VOID > + ) > +{ > + UINT32 Data32Or; > + UINT32 Data32And; > + PCH_SBI_PID *GpioComSbiIds; > + UINT32 NoOfGpioComs; > + UINT32 GpioComIndex; > + > + Data32And =3D (UINT32)~0, > + // > + // Enable MISCCFG.GPSIDEDPCGEn, MISCCFG.GPRCOMPCDLCGEn, > MISCCFG.GPRTCDLCGEn, > + // MISCCFG.GPDLCGEn and MISCCFG.GPDPCGEn for GPIO communities > + // > + Data32Or =3D (B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN | > + B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN | > + B_GPIO_PCR_MISCCFG_GPRTCDLCGEN | > + B_GPIO_PCR_MISCCFG_GPDLCGEN | > + B_GPIO_PCR_MISCCFG_GPDPCGEN); > + > + NoOfGpioComs =3D GpioGetComSbiPortIds (&GpioComSbiIds); > + > + // > + // Configure Clock Gating in each community > + // > + for (GpioComIndex =3D 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) > { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], > R_GPIO_PCR_MISCCFG), > + Data32And, > + Data32Or > + ); > + } > +} > + > +/** > + This procedure is used to unlock all GPIO pads. > + This function can only be called when platform is still in HOSTIA_BOOT= _SAI. > +**/ > +VOID > +GpioUnlockAllPads ( > + VOID > + ) > +{ > + UINT32 DwNum; > + UINT32 GroupIndex; > + UINT32 NumberOfGroups; > + GPIO_GROUP Group; > + UINT32 LockValue; > + EFI_STATUS Status; > + > + NumberOfGroups =3D GpioGetNumberOfGroups (); > + > + for (GroupIndex =3D 0; GroupIndex < NumberOfGroups; GroupIndex++) { > + Group =3D GpioGetGroupFromGroupIndex (GroupIndex); > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)); DwNum++) { > + > + GpioGetPadCfgLockForGroupDw (Group, DwNum, &LockValue); > + > + if (LockValue) { > + Status =3D GpioUnlockPadCfgForGroupDw (Group, DwNum, ~0u); > + ASSERT_EFI_ERROR (Status); > + } > + > + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &LockValue); > + > + if (LockValue) { > + Status =3D GpioUnlockPadCfgTxForGroupDw (Group, DwNum, ~0u); > + ASSERT_EFI_ERROR (Status); > + } > + } > + } > +} > + > +/** > + Generates GPIO name from GpioPad > + This function returns pointer to the static buffer > + > + @param[in] GpioPad GpioPad > + > + @retval CHAR8* Pointer to the gpio name string > +**/ > +CHAR8* > +GpioName ( > + IN GPIO_PAD GpioPad > + ) > +{ > + return GpioGetPadName (GpioPad, GpioGetStaticNameBuffer (), > GPIO_NAME_LENGTH_MAX); > +} > + > + > +// > +// For GPIO debounce feature glitch filter clock is used > +// which is driven by RTC clock with f =3D 32kHz (T =3D 31.25us) > +// > +#define GPIO_DEB_CLK_PERIOD_IN_NS 31250 > + > +/** > + This procedure enables debounce feature on a selected pad configured i= n > input mode > + Debounce time can be specified in microseconds. GPIO HW supports only > certain values > + according to below formula: > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock perio= d). > + RTC clock with f =3D 32 KHz is used for glitch filter. > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us). > + Supported DebounceTime values are following: > + DebounceTime =3D 0 -> Debounce feature disabled > + DebounceTime > 0 && < 250us -> Not supported > + DebounceTime =3D 250us - 1024000us -> Supported range (DebounceTime = =3D > 250us * 2^n) > + For values not supported by GPIO HW, function will round down > + to closest supported > + > + @param[in] GpioPad GPIO pad > + @param[in, out] DebounceTime Debounce Time in microseconds > + If Debounce Time =3D 0, Debouncer feat= ure will be > disabled > + Function will set DebounceTime argumen= t to > rounded supported value > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad or unsupported > DebounceDuration value > + @retval EFI_UNSUPPORTED GpioPad is not owned by host > +**/ > +EFI_STATUS > +GpioSetDebounceTimer ( > + IN GPIO_PAD GpioPad, > + IN OUT UINT32 *DebounceTime > + ) > +{ > + UINT32 DebounceEnable; > + UINT32 DebounceValue; > + UINT32 InRangeDebounceTime; > + UINT32 SupportedDebounceTime; > + UINT32 Temp; > + BOOLEAN SupportedValue; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (*DebounceTime > 1024000) { > + InRangeDebounceTime =3D 1024000; > + SupportedValue =3D FALSE; > + } else if ((*DebounceTime < 250) && (*DebounceTime > 0)) { > + InRangeDebounceTime =3D 0; > + SupportedValue =3D FALSE; > + } else { > + InRangeDebounceTime =3D *DebounceTime; > + SupportedValue =3D TRUE; > + } > + > + // > + // DebounceValue =3D log2 (InRangeDebounceTime * f_deb_clk) > + // > + DebounceValue =3D 0; > + Temp =3D InRangeDebounceTime * 1000 / GPIO_DEB_CLK_PERIOD_IN_NS; > + > + // > + // Check if any rounding occurred > + // > + if (InRangeDebounceTime !=3D (Temp * GPIO_DEB_CLK_PERIOD_IN_NS / 1000)= ) > { > + SupportedValue =3D FALSE; > + } > + > + // > + // Check if value is power of 2 > + // > + if ((Temp !=3D 0) && ((Temp & (Temp - 1)) !=3D 0)) { > + SupportedValue =3D FALSE; > + } > + > + // > + // DebounceValue =3D log2 (Temp) > + // > + while (Temp > 1) { > + Temp >>=3D 1; > + DebounceValue++; > + } > + > + if (DebounceValue > 0) { > + DebounceEnable =3D B_GPIO_PCR_DEBEN; > + SupportedDebounceTime =3D (1 << DebounceValue) * > GPIO_DEB_CLK_PERIOD_IN_NS / 1000; > + } else { > + DebounceEnable =3D 0; > + SupportedDebounceTime =3D 0; > + } > + > + GpioWritePadCfgReg ( > + GpioPad, > + 2, > + (UINT32)~(B_GPIO_PCR_DEBOUNCE | B_GPIO_PCR_DEBEN), > + (DebounceValue << N_GPIO_PCR_DEBOUNCE) | DebounceEnable > + ); > + > + if (!SupportedValue) { > + DEBUG ((DEBUG_WARN, "GPIO WARNING: %a %dus debounce time > rounded down to %dus\n", > + GpioName (GpioPad), > + *DebounceTime, > + SupportedDebounceTime)); > + } > + > + *DebounceTime =3D SupportedDebounceTime; > + > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLibCnl.c > new file mode 100644 > index 0000000000..a6d260f4ad > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPri= v > ateLib/GpioPrivateLibCnl.c > @@ -0,0 +1,225 @@ > +/** @file > + This file contains specific GPIO information > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO > mPchLpGpioGroupInfo[] =3D { > + {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_A_PAD_MAX}, //CNL PCH-LP GPP_A > + {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_B_PAD_MAX}, //CNL PCH-LP GPP_B > + {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_C_PAD_MAX}, //CNL PCH-LP GPP_C > + {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_D_PAD_MAX}, //CNL PCH-LP GPP_D > + {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_E_PAD_MAX}, //CNL PCH-LP GPP_E > + {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_F_PAD_MAX}, //CNL PCH-LP GPP_F > + {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_G_PAD_MAX}, //CNL PCH-LP GPP_G > + {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPP_H_PAD_MAX}, //CNL PCH-LP GPP_H > + {PID_GPIOCOM2, R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_GPD_PAD_MAX}, //CNL PCH-LP GPD > + {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_VGPIO_PAD_MAX}, //CNL PCH-LP vGPIO > + {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_SPI_PAD_MAX}, //CNL PCH-LP SPI > + {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_AZA_PAD_MAX}, //CNL PCH-LP AZA > + {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_CPU_PAD_MAX}, //CNL PCH-LP CPU > + {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_JTAG_PAD_MAX}, //CNL PCH-LP JTAG > + {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX, > R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET, > CNL_PCH_LP_GPIO_HVMOS_PAD_MAX} //CNL PCH-LP HVMOS > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO > mPchHGpioGroupInfo[] =3D { > + {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_A_PAD_MAX}, //CNL PCH-H GPP_A > + {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_B_PAD_MAX}, //CNL PCH-H GPP_B > + {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_C_PAD_MAX}, //CNL PCH-H GPP_C > + {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_D_PAD_MAX}, //CNL PCH-H GPP_D > + {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_E_PAD_MAX}, //CNL PCH-H GPP_E > + {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_F_PAD_MAX}, //CNL PCH-H GPP_F > + {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_G_PAD_MAX}, //CNL PCH-H GPP_G > + {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_H_PAD_MAX}, //CNL PCH-H GPP_H > + {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN, > R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_I_PAD_MAX}, //CNL PCH-H GPP_I > + {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_J_PAD_MAX}, //CNL PCH-H GPP_J > + {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPP_K_PAD_MAX}, //CNL PCH-H GPP_K > + {PID_GPIOCOM2, R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET, > CNL_PCH_H_GPIO_GPD_PAD_MAX}, //CNL PCH-H GPD > + {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN, > R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS, > R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE, > R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS, > R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET, > CNL_PCH_H_GPIO_VGPIO_PAD_MAX}, //CNL PCH-H vGPIO > + {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET, > CNL_PCH_H_GPIO_SPI_PAD_MAX}, //CNL PCH-H SPI > + {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET, > CNL_PCH_H_GPIO_AZA_PAD_MAX}, //CNL PCH-H AZA > + {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET, > CNL_PCH_H_GPIO_CPU_PAD_MAX}, //CNL PCH-H CPU > + {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN, > R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK, > R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX, > R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET, > CNL_PCH_H_GPIO_JTAG_PAD_MAX} //CNL PCH-H JTAG > +}; > + > +/** > + This procedure will retrieve address and length of GPIO info table > + > + @param[out] GpioGroupInfoTableLength Length of GPIO group table > + > + @retval Pointer to GPIO group table > + > +**/ > +CONST GPIO_GROUP_INFO* > +GpioGetGroupInfoTable ( > + OUT UINT32 *GpioGroupInfoTableLength > + ) > +{ > + if (IsPchLp ()) { > + *GpioGroupInfoTableLength =3D ARRAY_SIZE (mPchLpGpioGroupInfo); > + return mPchLpGpioGroupInfo; > + } else { > + *GpioGroupInfoTableLength =3D ARRAY_SIZE (mPchHGpioGroupInfo); > + return mPchHGpioGroupInfo; > + } > +} > + > +/** > + Get GPIO Chipset ID specific to PCH generation and series > +**/ > +UINT32 > +GpioGetThisChipsetId ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_CNL_LP_CHIPSET_ID; > + } else { > + return GPIO_CNL_H_CHIPSET_ID; > + } > +} > + > +/** > + This internal procedure will check if group is within DeepSleepWell. > + > + @param[in] Group GPIO Group > + > + @retval GroupWell TRUE: This is DSW Group > + FALSE: This is not DSW Group > +**/ > +BOOLEAN > +GpioIsDswGroup ( > + IN GPIO_GROUP Group > + ) > +{ > + if ((Group =3D=3D GPIO_CNL_LP_GROUP_GPD) || (Group =3D=3D > GPIO_CNL_H_GROUP_GPD)) { > + return TRUE; > + } else { > + return FALSE; > + } > +} > + > +/** > + This procedure will perform special handling of GPP_A_12. > + > + @param[in] None > + > + @retval None > +**/ > +VOID > +GpioA12SpecialHandling ( > + VOID > + ) > +{ > + GPIO_PAD_OWN PadOwnVal; > + GPIO_PAD GpioPad; > + > + // > + // PCH BWG 16.6. GPP_A_12 Special Handling > + // > + if (IsPchLp ()) { > + GpioPad =3D GPIO_CNL_LP_GPP_A12; > + } else { > + GpioPad =3D GPIO_CNL_H_GPP_A12; > + } > + GpioGetPadOwnership (GpioPad, &PadOwnVal); > + > + // > + // If the pad is host-own, BIOS has to always lock this pad after bein= g > initialized > + // > + if (PadOwnVal =3D=3D GpioPadOwnHost) { > + // > + // Set PadCfgLock for GPP_A_12 > + // > + GpioLockPadCfg (GpioPad); > + } > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED PCH_SBI_PID mGpioComSbiIds[] =3D > +{ > + PID_GPIOCOM0, PID_GPIOCOM1, PID_GPIOCOM2, PID_GPIOCOM3, > PID_GPIOCOM4 > +}; > + > +/** > + This function provides GPIO Community PortIDs > + > + @param[out] NativePinsTable Table with GPIO COMMx SBI > PortIDs > + > + @retval Number of communities > +**/ > +UINT32 > +GpioGetComSbiPortIds ( > + OUT PCH_SBI_PID **GpioComSbiIds > + ) > +{ > + *GpioComSbiIds =3D mGpioComSbiIds; > + return ARRAY_SIZE (mGpioComSbiIds); > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING > mPchLpGpioGroupToGpeMapping[] =3D { > + {GPIO_CNL_LP_GROUP_GPP_A, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A}, > + {GPIO_CNL_LP_GROUP_GPP_B, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B}, > + {GPIO_CNL_LP_GROUP_GPP_C, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C}, > + {GPIO_CNL_LP_GROUP_GPP_D, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D}, > + {GPIO_CNL_LP_GROUP_GPP_E, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E}, > + {GPIO_CNL_LP_GROUP_GPP_F, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F}, > + {GPIO_CNL_LP_GROUP_GPP_G, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G}, > + {GPIO_CNL_LP_GROUP_GPP_H, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H}, > + {GPIO_CNL_LP_GROUP_GPD, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD}, > + {GPIO_CNL_LP_GROUP_VGPIO , 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO}, > + {GPIO_CNL_LP_GROUP_SPI, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI}, > + {GPIO_CNL_LP_GROUP_AZA, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA}, > + {GPIO_CNL_LP_GROUP_JTAG, 0, > V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG, > V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING > mPchHGpioGroupToGpeMapping[] =3D { > + {GPIO_CNL_H_GROUP_GPP_A, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A}, > + {GPIO_CNL_H_GROUP_GPP_B, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B}, > + {GPIO_CNL_H_GROUP_GPP_C, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C}, > + {GPIO_CNL_H_GROUP_GPP_D, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D}, > + {GPIO_CNL_H_GROUP_GPP_E, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E}, > + {GPIO_CNL_H_GROUP_GPP_F, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F}, > + {GPIO_CNL_H_GROUP_GPP_G, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G}, > + {GPIO_CNL_H_GROUP_GPP_H, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H}, > + {GPIO_CNL_H_GROUP_GPP_I, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I}, > + {GPIO_CNL_H_GROUP_GPP_J, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J}, > + {GPIO_CNL_H_GROUP_GPP_K, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K}, > + {GPIO_CNL_H_GROUP_GPD, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD}, > + {GPIO_CNL_H_GROUP_VGPIO, 0, > V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO, > V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO} > +}; > + > +/** > + Get information for GPIO Group required to program GPIO and PMC for > desired 1-Tier GPE mapping > + > + @param[out] GpioGroupToGpeMapping Table with GPIO Group to > GPE mapping > + @param[out] GpioGroupToGpeMappingLength GPIO Group to GPE > mapping table length > +**/ > +VOID > +GpioGetGroupToGpeMapping ( > + OUT GPIO_GROUP_TO_GPE_MAPPING **GpioGroupToGpeMapping, > + OUT UINT32 *GpioGroupToGpeMappingLength > + ) > +{ > + if (IsPchLp ()) { > + *GpioGroupToGpeMapping =3D mPchLpGpioGroupToGpeMapping; > + *GpioGroupToGpeMappingLength =3D ARRAY_SIZE > (mPchLpGpioGroupToGpeMapping); > + } else { > + *GpioGroupToGpeMapping =3D mPchHGpioGroupToGpeMapping; > + *GpioGroupToGpeMappingLength =3D ARRAY_SIZE > (mPchHGpioGroupToGpeMapping); > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.c > new file mode 100644 > index 0000000000..2f9b6a7e6f > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi14.c > @@ -0,0 +1,67 @@ > +/** @file > + This file contains functions for PCH DMI SIP14 > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + This function checks if DMI SIP14 Secured Register Lock (SRL) is set > + > + @retval SRL state > +**/ > +BOOLEAN > +IsPchDmi14Locked ( > + VOID > + ) > +{ > + return ((PchPcrRead32 (PID_DMI, R_PCH_DMI14_PCR_DMIC) & > B_PCH_DMI14_PCR_DMIC_SRL) !=3D 0); > +} > + > +/** > + Enable PCIe Relaxed Order for DMI SIP14 > +**/ > +VOID > +PchDmi14EnablePcieRelaxedOrder ( > + VOID > + ) > +{ > + // > + // Enable Forced Relaxed Ordering to always allow downstream > completions to pass posted writes. > + // Set Completion Relaxed Ordering Attribute Override Value > + // and Completion Relaxed Ordering Attribute Override Enable > + // > + PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI14_PCR_2314, ~0u, (BIT31 | > BIT7)); > +} > + > +/** > + Secure Register Lock data > + > + @param[out] SrlRegOffset Register offset holding Secure Register= Lock > setting > + @param[out] SrlRegMask Mask for Secure Register Lock setting > +**/ > +VOID > +PchDmi14SrlRegData ( > + OUT UINT16 *SrlRegOffset, > + OUT UINT32 *SrlRegMask > + ) > +{ > + *SrlRegMask =3D B_PCH_DMI14_PCR_DMIC_SRL; > + *SrlRegOffset =3D R_PCH_DMI14_PCR_DMIC; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.c > new file mode 100644 > index 0000000000..c711b3de39 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmi15.c > @@ -0,0 +1,113 @@ > +/** @file > + This file contains functions for PCH DMI SIP15 > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + This function checks if DMI SIP15 Secured Register Lock (SRL) is set > + > + @retval SRL state > +**/ > +BOOLEAN > +IsPchDmi15Locked ( > + VOID > + ) > +{ > + return ((PchPcrRead32 (PID_DMI, R_PCH_DMI15_PCR_MPC) & > B_PCH_DMI15_PCR_MPC_SRL) !=3D 0); > +} > + > +/** > + Set DMI thermal throttling to recommended configuration. > + It's intended only for P-DMI SIP15. > +**/ > +VOID > +PchDmi15SetRecommendedThermalThrottling ( > + VOID > + ) > +{ > + UINT32 Data32And; > + UINT32 Data32Or; > + /// > + /// DMI recommended Thermal Sensor Target Width > + /// is the HW default configuration: > + /// - Thermal Sensor 3 Target Width: 0 (x1) > + /// - Thermal Sensor 2 Target Width: 1 (x2) > + /// - Thermal Sensor 1 Target Width: 2 (x4) > + /// - Thermal Sensor 0 Target Width: 3 (x8) > + /// Enable Thermal Sensor Autonomous Width > + /// > + Data32And =3D (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | > B_PCH_DMI15_PCR_UPHWAWC_TS2TW | > + B_PCH_DMI15_PCR_UPHWAWC_TS1TW | > B_PCH_DMI15_PCR_UPHWAWC_TS0TW); > + Data32Or =3D (0 << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) | > + (1 << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) | > + (2 << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) | > + (3 << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) | > + B_PCH_DMI15_PCR_UPHWAWC_TSAWEN; > + > + PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, > Data32And, Data32Or); > +} > + > +/** > + Set DMI thermal throttling to custom configuration. > + This function will configure Thermal Sensor 0/1/2/3 TargetWidth and se= t > + DMI Thermal Sensor Autonomous Width Enable. > + It's intended only for P-DMI SIP15. > + > + @param[in] DmiThermalThrottling DMI Thermal Throttling structur= e. > +**/ > +VOID > +PchDmi15SetCustomThermalThrottling ( > + IN DMI_THERMAL_THROTTLING DmiThermalThrottling > + ) > +{ > + UINT32 Data32And; > + UINT32 Data32Or; > + > + /// > + /// DMI Throttling action > + /// > + Data32And =3D (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | > B_PCH_DMI15_PCR_UPHWAWC_TS2TW | > + B_PCH_DMI15_PCR_UPHWAWC_TS1TW | > B_PCH_DMI15_PCR_UPHWAWC_TS0TW); > + Data32Or =3D (DmiThermalThrottling.ThermalSensor3TargetWidth << > N_PCH_DMI15_PCR_UPHWAWC_TS3TW) | > + (DmiThermalThrottling.ThermalSensor2TargetWidth << > N_PCH_DMI15_PCR_UPHWAWC_TS2TW) | > + (DmiThermalThrottling.ThermalSensor1TargetWidth << > N_PCH_DMI15_PCR_UPHWAWC_TS1TW) | > + (DmiThermalThrottling.ThermalSensor0TargetWidth << > N_PCH_DMI15_PCR_UPHWAWC_TS0TW) | > + B_PCH_DMI15_PCR_UPHWAWC_TSAWEN; > + > + PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, > Data32And, Data32Or); > +} > + > + > +/** > + Secure Register Lock data > + > + @param[out] SrlRegOffset Register offset holding Secure Register= Lock > setting > + @param[out] SrlRegMask Mask for Secure Register Lock setting > +**/ > +VOID > +PchDmi15SrlRegData ( > + OUT UINT16 *SrlRegOffset, > + OUT UINT32 *SrlRegMask > + ) > +{ > + *SrlRegMask =3D B_PCH_DMI15_PCR_MPC_SRL; > + *SrlRegOffset =3D R_PCH_DMI15_PCR_MPC; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiLib.c > new file mode 100644 > index 0000000000..f1b2867659 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiLib.c > @@ -0,0 +1,569 @@ > +/** @file > + PCH DMI library. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PchDmi14.h" > +#include "PchDmi15.h" > + > +/** > + This function checks if DMI Secured Register Lock (SRL) is set > + > + @retval SRL state > +**/ > +BOOLEAN > +IsPchDmiLocked ( > + VOID > + ) > +{ > + if (IsPchWithPdmi ()) { > + return IsPchDmi15Locked (); > + } else { > + return IsPchDmi14Locked (); > + } > +} > + > +/** > + Backward DMI library API compatibility > + ACPI base address programming is done in PSF > + > + @param[in] Address Address for ACPI base. > + > + @retval EFI_UNSUPPORTED NOT supported programming. > +**/ > +EFI_STATUS > +PchDmiSetAcpiBase ( > + IN UINT16 Address > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Backward DMI library API compatibility > + PWRMBASE is a standard BAR and doesn't require > + additional DMI base decoding programming > + > + @param[in] Address Address for PWRM base. > + > + @retval EFI_UNSUPPORTED NOT supported programming. > +**/ > +EFI_STATUS > +PchDmiSetPwrmBase ( > + IN UINT32 Address > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Set PCH TCO base address decoding in DMI > + > + @param[in] Address Address for TCO base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetTcoBase ( > + IN UINT16 Address > + ) > +{ > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [SMBUS PCI > offset 50h[15:5], 1]. > + // > + PchPcrWrite16 ( > + PID_DMI, R_PCH_DMI_PCR_TCOBASE, > + (Address | BIT1) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Get PCH TCO base address. > + > + @retval Address Address of TCO base address. > +**/ > +UINT16 > +PchDmiGetTcoBase ( > + VOID > + ) > +{ > + // > + // Read "TCO Base Address" PCR[DMI] + 2778h[15:5] > + // > + return (PchPcrRead16 (PID_DMI, R_PCH_DMI_PCR_TCOBASE) & > B_PCH_DMI_PCR_TCOBASE_TCOBA); > +} > + > +/** > + Set PCH LPC/eSPI generic IO range decoding in DMI > + > + @param[in] Address Address for generic IO range bas= e > address. > + @param[in] Length Length of generic IO range. > + @param[in] RangeIndex Index of choosen range > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetLpcGenIoRange ( > + IN UINT32 Address, > + IN UINT32 Length, > + IN UINT32 RangeIndex > + ) > +{ > + UINT32 Data32; > + // > + // This cycle decoding is only allowed to set when DMIC.SRL is 0. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + Data32 =3D (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA)= ; > + Data32 |=3D (UINT32) Address; > + Data32 |=3D B_LPC_CFG_GENX_DEC_EN; > + // > + // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the sam= e > value programmed in LPC/eSPI PCI Offset 84h~93h. > + // > + PchPcrWrite32 ( > + PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4), > + Data32 > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH eSPI eSPI CS1# generic IO range decoding in DMI > + > + @param[in] Address Address for generic IO range bas= e > address. > + @param[in] Length Length of generic IO range. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetEspiCs1GenIoRange ( > + IN UINT32 Address, > + IN UINT32 Length > + ) > +{ > + UINT32 Data32; > + // > + // This cycle decoding is only allowed to set when DMIC.SRL is 0. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + Data32 =3D (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA)= ; > + Data32 |=3D (UINT32) Address; > + Data32 |=3D B_LPC_CFG_GENX_DEC_EN; > + // > + // Program eSPI Generic IO Range #, PCR[DMI] + 27BCh to the same value > programmed in eSPI PCI Offset A4h. > + // > + PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, Data32); > + > + return EFI_SUCCESS; > +} > + > +/** > + Clear PCH LPC/eSPI generic IO range decoding in DMI > + > + @param[in] RangeIndex Index of chosen range > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiClearLpcGenIoRange ( > + IN UINTN RangeIndex > + ) > +{ > + // > + // This cycle decoding is only allowed to set when DMIC.SRL is 0. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the sam= e > value programmed in LPC/eSPI PCI Offset 84h~93h. > + // > + PchPcrWrite32 ( > + PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4), > + 0 > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Clear PCH eSPI CS1# generic IO range decoding in DMI > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiClearEspiCs1GenIoRange ( > + VOID > + ) > +{ > + // > + // This cycle decoding is only allowed to set when DMIC.SRL is 0. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + // > + // Program LPC Generic IO Range #, PCR[DMI] + 27BCh to the same value > programmed in eSPI PCI Offset A4h. > + // > + PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, 0); > + > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH LPC/eSPI memory range decoding in DMI > + > + @param[in] Address Address for memory base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetLpcMemRange ( > + IN UINT32 Address > + ) > +{ > + if (IsPchDmiLocked ()) { > + DEBUG ((DEBUG_ERROR, "PchDmiSetLpcMemRange Error. DMI is > locked.\n")); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // Program LPC Memory Range, PCR[DMI] + 2740h to the same value > programmed in LPC/eSPI PCI Offset 98h. > + // > + PchPcrWrite32 ( > + PID_DMI, R_PCH_DMI_PCR_LPCGMR, > + (Address | B_LPC_CFG_LGMR_LMRD_EN) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH eSPI CS1# memory range decoding in DMI > + > + @param[in] Address Address for memory base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetEspiCs1MemRange ( > + IN UINT32 Address > + ) > +{ > + if (IsPchDmiLocked ()) { > + DEBUG ((DEBUG_ERROR, "PchLpcMemRange2Set Error. DMI is locked.\n")); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // Program LPC Memory Range, PCR[DMI] + 27C0h to the same value > programmed in eSPI PCI Offset A8h. > + // > + PchPcrWrite32 ( > + PID_DMI, R_PCH_DMI_PCR_SEGMR, > + (Address | B_LPC_CFG_LGMR_LMRD_EN) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Check if Boot BIOS Strap is set for SPI. > + > + @retval TRUE Boot BIOS Strap set for SPI > + @retval FALSE Boot BIOS Strap set for LPC/eSPI > +**/ > +BOOLEAN > +PchDmiIsBootBiosStrapSetForSpi ( > + VOID > + ) > +{ > + // > + // Check General Control and Status (GCS) [10] > + // '0': SPI > + // '1': LPC/eSPI > + // > + return ((PchPcrRead32 (PID_DMI, R_PCH_DMI_PCR_GCS) & > B_PCH_DMI_PCR_BBS) !=3D B_PCH_DMI_PCR_BBS); > +} > + > +/** > + Set PCH BIOS range decoding in DMI > + Please check EDS for detail of BiosDecodeEnable bit definition. > + bit 15: F8-FF Enable > + bit 14: F0-F8 Enable > + bit 13: E8-EF Enable > + bit 12: E0-E8 Enable > + bit 11: D8-DF Enable > + bit 10: D0-D7 Enable > + bit 9: C8-CF Enable > + bit 8: C0-C7 Enable > + bit 7: Legacy F Segment Enable > + bit 6: Legacy E Segment Enable > + bit 5: Reserved > + bit 4: Reserved > + bit 3: 70-7F Enable > + bit 2: 60-6F Enable > + bit 1: 50-5F Enable > + bit 0: 40-4F Enable > + > + @param[in] BiosDecodeEnable Bios decode enable setting. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetBiosDecodeEnable ( > + IN UINT16 BiosDecodeEnable > + ) > +{ > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // program LPC BIOS Decode Enable, PCR[DMI] + 2744h to the same value > programmed in LPC or SPI Offset D8h. > + // > + PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCBDE, BiosDecodeEnable); > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH LPC/eSPI IO decode ranges in DMI > + Please check EDS for detail of LPC/eSPI IO decode ranges bit definitio= n. > + Bit 12: FDD range > + Bit 9:8: LPT range > + Bit 6:4: ComB range > + Bit 2:0: ComA range > + > + @param[in] LpcIoDecodeRanges LPC/eSPI IO decode ranges bit > settings. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetLpcIoDecodeRanges ( > + IN UINT16 LpcIoDecodeRanges > + ) > +{ > + // > + // This cycle decoding is only allowed to set when DMI is not locked. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // program LPC I/O Decode Ranges, PCR[DMI] + 2770h[15:0] to the same > value programmed in LPC/eSPI PCI offset 80h. > + // > + PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCIOD, LpcIoDecodeRanges); > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH LPC/eSPI IO enable decoding in DMI > + > + @param[in] LpcIoEnableDecoding LPC/eSPI IO enable decoding bit > settings. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchDmiSetLpcIoEnable ( > + IN UINT16 LpcIoEnableDecoding > + ) > +{ > + // > + // This cycle decoding is only allowed to set when DMI is not locked. > + // > + if (IsPchDmiLocked ()) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // program LPC I/O Decode Ranges, PCR[DMI] + 2774h[15:0] to the same > value programmed in LPC/eSPI PCI offset 82h. > + // > + PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCIOE, LpcIoEnableDecoding); > + return EFI_SUCCESS; > +} > + > + > +/** > + Set PCH IO port 80h cycle decoding to PCIE root port in DMI > + > + @param[in] RpNumber PCIE root port physical number. > + > + @retval EFI_SUCCESS Successfully completed. > +**/ > +EFI_STATUS > +PchDmiSetIoPort80Decode ( > + IN UINTN RpNumber > + ) > +{ > + UINT16 DmiRpDestinationId; > + PSF_PORT_DEST_ID PsfRpDestinationId; > + > + if (IsPchDmiLocked ()) { > + DEBUG ((DEBUG_ERROR, "PchIoPort80DecodeSet Error. DMI is > locked.\n")); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + /// > + /// IO port 80h is typically used by decoder/LED hardware for debug > purposes. > + /// By default PCH will forward IO port 80h cycles to LPC bus. The Res= erved > Page Route (RPR) bit > + /// of General Control and Status register, located at PCR[DMI] + 274C= h[11] , > allows software to > + /// re-direct IO port 80h cycles to PCIe bus so that a target (for exa= mple, a > debug card) on > + /// PCIe bus can receive and claim these cycles. > + /// The "RPR Destination ID", PCR[DMI] + 274Ch[31:16] need to be set > accordingly to point > + /// to the root port that decode this range. Reading from Port 80h may= not > return valid values > + /// if the POST-card itself do not shadow the writes. Unlike LPC, PCIe= does > not shadow the Port 80 writes. > + /// > + PsfRpDestinationId =3D PsfPcieDestinationId ((UINT32)RpNumber); > + > + DmiRpDestinationId =3D (UINT16)((0x2 << 12) | > + (PsfRpDestinationId.Fields.PsfId << 8) | > + (PsfRpDestinationId.Fields.PortGroupId <= < 7) | > + (PsfRpDestinationId.Fields.PortId << 3) = | > + PsfRpDestinationId.Fields.ChannelId); > + > + // > + // Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest I= D of > RP. > + // > + PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_GCS + 2, DmiRpDestinationId); > + // > + // Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'. > + // Use byte write on GCS+1 and leave the BILD bit which is RWO. > + // > + PchPcrAndThenOr8 (PID_DMI, R_PCH_DMI_PCR_GCS + 1, 0xFF, > (B_PCH_DMI_PCR_RPR >> 8)); > + > + return EFI_SUCCESS; > +} > + > +/** > + Set DMI thermal throttling to recommended configuration. > + It's intended only for P-DMI. > +**/ > +VOID > +PchDmiSetRecommendedThermalThrottling ( > + VOID > + ) > +{ > + if (IsPchWithPdmi ()) { > + PchDmi15SetRecommendedThermalThrottling (); > + } > +} > + > +/** > + Set DMI thermal throttling to custom configuration. > + This function will configure Thermal Sensor 0/1/2/3 TargetWidth and se= t > + DMI Thermal Sensor Autonomous Width Enable. > + It's intended only for P-DMI. > + > + @param[in] DmiThermalThrottling DMI Thermal Throttling structur= e. > +**/ > +VOID > +PchDmiSetCustomThermalThrottling ( > + IN DMI_THERMAL_THROTTLING DmiThermalThrottling > + ) > +{ > + if (IsPchWithPdmi ()) { > + PchDmi15SetCustomThermalThrottling (DmiThermalThrottling); > + } > +} > + > +/** > + Determines where to send the reserved page registers > + Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Po= rt > + with the destination ID specified in GCS.RPRDID using DMI source decod= e. > +**/ > +VOID > +PchDmiSetReservedPageRegToPcieRootPort ( > + VOID > + ) > +{ > + PchPcrAndThenOr8 ( > + PID_DMI, R_PCH_DMI_PCR_GCS + 1, > + (UINT8) ~0, > + (UINT8) (B_PCH_DMI_PCR_RPR >> 8) > + ); > +} > + > +/** > + Determines where to send the reserved page registers > + DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cy= cles > hitting these ranges will > + end up in P2SB which will then forward the cycle to LPC or eSPI throug= h IOSF > Sideband. > +**/ > +VOID > +PchDmiSetReservedPageRegToLpc ( > + VOID > + ) > +{ > + PchPcrAndThenOr8 ( > + PID_DMI, R_PCH_DMI_PCR_GCS + 1, > + (UINT8) (~(B_PCH_DMI_PCR_RPR >> 8)), > + 0 > + ); > +} > + > +/** > + uCode Patch Region Enable (UPRE). Enables memory access targeting the > uCode patch region (0xFEF00000 to 0xFEFFFFFF) > + to be forwarded to SPI Flash. This can only be set if the boot flash i= s on SPI. > +**/ > +VOID > +PchDmiEnableUCodePatchRegion ( > + VOID > + ) > +{ > + /// > + /// Setup "uCode Patch Region Enable", PCR [DMI] + 2748h[0] to '0b' > + /// > + PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_UCPR, (UINT32) > ~B_PCH_DMI_PCR_UCPR_UPRE, 0); > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiWithS3Lib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiWithS3Lib.c > new file mode 100644 > index 0000000000..9778c9a252 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL > ib/PchDmiWithS3Lib.c > @@ -0,0 +1,79 @@ > +/** @file > + PCH DMI library with S3 boot script support. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PchDmi14.h" > +#include "PchDmi15.h" > + > +/** > + Configure PCH DMI Lock > +**/ > +VOID > +PchDmiSetLockWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 Data32Or; > + UINT32 Data32And; > + UINT16 Address; > + > + Data32And =3D 0xFFFFFFFF; > + if (IsPchWithPdmi ()) { > + PchDmi15SrlRegData (&Address, &Data32Or); > + } else { > + PchDmi14SrlRegData (&Address, &Data32Or); > + } > + > + PchPcrAndThenOr32 ( > + PID_DMI, Address, > + Data32And, > + Data32Or > + ); > + PCH_PCR_BOOT_SCRIPT_READ_WRITE ( > + S3BootScriptWidthUint32, > + PID_DMI, Address, > + &Data32Or, > + &Data32And > + ); > +} > + > +/** > + Set BIOS interface Lock-Down > +**/ > +VOID > +PchDmiSetBiosLockDownWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 Data32Or; > + UINT32 Data32And; > + > + // > + // Set BIOS Lock-Down (BILD) > + // When set, prevents GCS.BBS from being changed > + // > + Data32And =3D 0xFFFFFFFF; > + Data32Or =3D B_PCH_DMI_PCR_BILD; > + PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_GCS, Data32And, > Data32Or); > + PCH_PCR_BOOT_SCRIPT_READ_WRITE ( > + S3BootScriptWidthUint32, > + PID_DMI, R_PCH_DMI_PCR_GCS, > + &Data32Or, > + &Data32And > + ); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PchInitCommon.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PchInitCommon.c > new file mode 100644 > index 0000000000..14bd51ec43 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInit= C > ommonLib/PchInitCommon.c > @@ -0,0 +1,221 @@ > +/** @file > + Pch common library for PCH INIT PEI/DXE/SMM modules > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +extern CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[]; > +extern CONST UINT32 mPchPcieControllerInfoSize; > + > +#define PORT_PLS_TIMEOUT 100 ///< 100 * 10 us =3D 1ms timeout for USB= 3 > PortSC PLS polling > + > +/** > + This function returns PID according to PCIe controller index > + > + @param[in] ControllerIndex PCIe controller index > + > + @retval PCH_SBI_PID Returns PID for SBI Access > +**/ > +PCH_SBI_PID > +PchGetPcieControllerSbiPid ( > + IN UINT32 ControllerIndex > + ) > +{ > + ASSERT (ControllerIndex < mPchPcieControllerInfoSize); > + return mPchPcieControllerInfo[ControllerIndex].Pid; > +} > + > +/** > + This function returns PID according to Root Port Number > + > + @param[in] RpIndex Root Port Index (0-based) > + > + @retval PCH_SBI_PID Returns PID for SBI Access > +**/ > +PCH_SBI_PID > +GetRpSbiPid ( > + IN UINTN RpIndex > + ) > +{ > + return PchGetPcieControllerSbiPid ((UINT32) (RpIndex / > PCH_PCIE_CONTROLLER_PORTS)); > +} > + > +/** > + Calculate root port device number based on physical port index. > + > + @param[in] RpIndex Root port index (0-based). > + > + @retval Root port device number. > +**/ > +UINT32 > +PchGetPcieRpDevice ( > + IN UINT32 RpIndex > + ) > +{ > + UINTN ControllerIndex; > + ControllerIndex =3D RpIndex / PCH_PCIE_CONTROLLER_PORTS; > + ASSERT (ControllerIndex < mPchPcieControllerInfoSize); > + return mPchPcieControllerInfo[ControllerIndex].DevNum; > +} > + > +/** > + This function reads Pci Config register via SBI Access > + > + @param[in] RpIndex Root Port Index (0-based) > + @param[in] Offset Offset of Config register > + @param[out] *Data32 Value of Config register > + > + @retval EFI_SUCCESS SBI Read successful. > +**/ > +EFI_STATUS > +PchSbiRpPciRead32 ( > + IN UINT32 RpIndex, > + IN UINT32 Offset, > + OUT UINT32 *Data32 > + ) > +{ > + EFI_STATUS Status; > + UINT32 RpDevice; > + UINT8 Response; > + UINT16 Fid; > + > + RpDevice =3D PchGetPcieRpDevice (RpIndex); > + Fid =3D (UINT16) ((RpDevice << 3) | (RpIndex % 4 )); > + Status =3D PchSbiExecutionEx ( > + GetRpSbiPid (RpIndex), > + Offset, > + PciConfigRead, > + FALSE, > + 0xF, > + 0, > + Fid, > + Data32, > + &Response > + ); > + if (Status !=3D EFI_SUCCESS) { > + DEBUG((DEBUG_ERROR,"Sideband Read Failed of RpIndex %d Offset 0x%x. > Device =3D %d Fid =3D 0x%x\n",RpIndex, Offset, RpDevice, Fid)); > + ASSERT (FALSE); > + } > + return Status; > +} > + > +/** > + This function And then Or Pci Config register via SBI Access > + > + @param[in] RpIndex Root Port Index (0-based) > + @param[in] Offset Offset of Config register > + @param[in] Data32And Value of Config register to be And-ed > + @param[in] Data32AOr Value of Config register to be Or-ed > + > + @retval EFI_SUCCESS SBI Read and Write successful. > +**/ > +EFI_STATUS > +PchSbiRpPciAndThenOr32 ( > + IN UINT32 RpIndex, > + IN UINT32 Offset, > + IN UINT32 Data32And, > + IN UINT32 Data32Or > + ) > +{ > + EFI_STATUS Status; > + UINT32 RpDevice; > + UINT32 Data32; > + UINT8 Response; > + UINT16 Fid; > + > + RpDevice =3D PchGetPcieRpDevice (RpIndex); > + Status =3D PchSbiRpPciRead32 (RpIndex, Offset, &Data32); > + if (Status =3D=3D EFI_SUCCESS) { > + Data32 &=3D Data32And; > + Data32 |=3D Data32Or; > + Fid =3D (UINT16) ((RpDevice << 3) | (RpIndex % 4 )); > + Status =3D PchSbiExecutionEx ( > + GetRpSbiPid (RpIndex), > + Offset, > + PciConfigWrite, > + FALSE, > + 0xF, > + 0, > + Fid, > + &Data32, > + &Response > + ); > + if (Status !=3D EFI_SUCCESS) { > + DEBUG((DEBUG_ERROR,"Sideband Write Failed of RpIndex %d Offset > 0x%x. Device =3D %d Fid =3D 0x%x\n",RpIndex, Offset, RpDevice, Fid)); > + ASSERT (FALSE); > + } > + } else { > + ASSERT (FALSE); > + } > + return Status; > +} > + > +/** > + Print registers value > + > + @param[in] PrintMmioBase Mmio base address > + @param[in] PrintSize Number of registers > + @param[in] OffsetFromBase Offset from mmio base address > + > + @retval None > +**/ > +VOID > +PrintRegisters ( > + IN UINTN PrintMmioBase, > + IN UINT32 PrintSize, > + IN UINT32 OffsetFromBase > + ) > +{ > + UINT32 Offset; > + DEBUG ((DEBUG_VERBOSE, " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C = 0D > 0E 0F")); > + for (Offset =3D 0; Offset < PrintSize; Offset++) { > + if ((Offset % 16) =3D=3D 0) { > + DEBUG ((DEBUG_VERBOSE, "\n %04X: ", (Offset + OffsetFromBase) & > 0xFFF0)); > + } > + DEBUG ((DEBUG_VERBOSE, "%02X ", MmioRead8 (PrintMmioBase + > Offset))); > + } > + DEBUG ((DEBUG_VERBOSE, "\n")); > +} > + > +/** > + Print registers value > + > + @param[in] PrintPciSegmentBase Pci segment base address > + @param[in] PrintSize Number of registers > + @param[in] OffsetFromBase Offset from mmio base address > + > + @retval None > +**/ > +VOID > +PrintPciRegisters ( > + IN UINT64 PrintPciSegmentBase, > + IN UINT32 PrintSize, > + IN UINT32 OffsetFromBase > + ) > +{ > + UINT32 Offset; > + DEBUG ((DEBUG_VERBOSE, " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C = 0D > 0E 0F")); > + for (Offset =3D 0; Offset < PrintSize; Offset++) { > + if ((Offset % 16) =3D=3D 0) { > + DEBUG ((DEBUG_VERBOSE, "\n %04X: ", (Offset + OffsetFromBase) & > 0xFFF0)); > + } > + DEBUG ((DEBUG_VERBOSE, "%02X ", PciSegmentRead8 > (PrintPciSegmentBase + Offset))); > + } > + DEBUG ((DEBUG_VERBOSE, "\n")); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.c > new file mode 100644 > index 0000000000..dcb43285b7 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciE= x > pressHelpersLib/PchPciExpressHelpersLibrary.c > @@ -0,0 +1,2407 @@ > +/** @file > + This file contains routines that support PCI Express initialization > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PchPciExpressHelpersLibrary.h" > +#include > + > +#define ASPM_L1_NO_LIMIT 0xFF > +#define ASPM_L0s_NO_LIMIT 0x7 > + > +#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds > +// > +// This structure conveniently keeps segment:bus:device:function > coordinates of a PCIe device > +// in a single variable. PcieCap is offset to PCI Express capabilities. = Having it > cached together > +// with coordinates is an optimization feature, because code in this fil= e uses > it a lot > +// > +typedef struct { > + UINT32 Seg : 8; > + UINT32 Bus : 8; > + UINT32 Dev : 5; > + UINT32 Func : 3; > + UINT32 PcieCap : 8; > +} SBDF; > + > +typedef struct { > + UINT32 MaxSnoopLatencyValue : 10; > + UINT32 MaxSnoopLatencyScale : 3; > + UINT32 MaxSnoopLatencyRequirement : 1; > + UINT32 MaxNoSnoopLatencyValue : 10; > + UINT32 MaxNoSnoopLatencyScale : 3; > + UINT32 MaxNoSnoopLatencyRequirement : 1; > + UINT32 ForceOverride : 1; > +} LTR_OVERRIDE; > + > +typedef struct { > + UINT32 MaxSnoopLatencyValue : 10; > + UINT32 MaxSnoopLatencyScale : 3; > + UINT32 MaxNoSnoopLatencyValue : 10; > + UINT32 MaxNoSnoopLatencyScale : 3; > +} LTR_LIMIT; > + > +#define MSLV_BIT_OFFSET 0 > +#define MSLS_BIT_OFFSET 10 > +#define MNSLV_BIT_OFFSET 13 > +#define MNSLS_BIT_OFFSET 23 > + > + > +typedef struct { > + UINT32 Size; > + const PCH_PCIE_DEVICE_OVERRIDE* Table; > +} OVERRIDE_TABLE; > + > +typedef enum { > + DevTypePci, > + DevTypePcieEndpoint, > + DevTypePcieUpstream, > + DevTypePcieDownstream, > + DevTypeMax > +} PCI_DEV_TYPE; > + > +// > +// This structure keeps in one place all data relevant to enabling L0s a= nd L1. > +// L0s latencies are encoded in the same way as in hardware registers. T= he > only operation > +// that will be performed on them is comparison > +// L1 latencies are decoded to microseconds, because they will be used i= n > subtractions and additions > +// > +typedef struct { > + UINT32 L0sSupported : 1; > + UINT32 L1Supported : 1; > + UINT32 L0sAcceptableLatency : 3; // encoded as in hardware register > + UINT32 L1AcceptableLatencyUs : 8; // decoded to microseconds > + UINT32 LinkL0sExitLatency : 3; // encoded as in hardware register > + UINT32 LinkL1ExitLatencyUs : 8; // decoded to microseconds > +} ASPM_CAPS; > + > +typedef struct { > + UINT32 AspmL11 : 1; > + UINT32 AspmL12 : 1; > + UINT32 PmL11 : 1; > + UINT32 PmL12 : 1; > + UINT32 Cmrt : 8; // Common Mode Restore Time > + UINT32 TpoScale : 2; // T power_on scale > + UINT32 TpoValue : 6; // T power_on value > +} L1SS_CAPS; > + > +#define MAX_SBDF_TABLE_SIZE 50 //arbitrary table size; big enough to > accomodate even full length TBT chain. > + > +typedef struct { > + UINT32 Count; > + SBDF Entry [MAX_SBDF_TABLE_SIZE]; > +} SBDF_TABLE; > + > +/** > + Converts device's segment:bus:device:function coordinates to flat addr= ess > + > + @param[in] Sbdf device's segment:bus:device:function coordinates > + @retval address of device's PCI cfg space > +**/ > +STATIC > +UINT64 > +SbdfToBase ( > + SBDF Sbdf > + ) > +{ > + return PCI_SEGMENT_LIB_ADDRESS (Sbdf.Seg, Sbdf.Bus, Sbdf.Dev, Sbdf.Fun= c, > 0); > +} > + > +/** > + Get PCIe port number for enabled port. > + @param[in] RpBase Root Port pci segment base address > + @retval Root Port number (1 based) > +**/ > +UINT32 > +PciePortNum ( > + IN UINT64 RpBase > + ) > +{ > + return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) >> > N_PCH_PCIE_CFG_LCAP_PN; > +} > + > +/** > + Get PCIe root port index > + @param[in] RpBase Root Port pci segment base address > + @retval Root Port index (0 based) > +**/ > +UINT32 > +PciePortIndex ( > + IN UINT64 RpBase > + ) > +{ > + return PciePortNum (RpBase) - 1; > +} > + > +/** > + Translate PCIe Port/Lane pair to 0-based PCIe lane number. > + > + @param[in] RpIndex Root Port index > + @param[in] RpLane Root Port Lane (0-3) > + > + @retval PCIe lane number (0-based) > +**/ > +UINT32 > +PchPciePhysicalLane ( > + UINT32 RpIndex, > + UINT32 RpLane > + ) > +{ > + UINT32 ControllerIndex; > + UINT32 ControllerLane; > + > + ASSERT (RpIndex < GetPchMaxPciePortNum ()); > + ASSERT (((RpIndex % 4) + RpLane) < 4); > + > + ControllerIndex =3D (RpIndex / 4); > + ControllerLane =3D (RpIndex % 4) + RpLane; > + if (IsPcieLaneReversalEnabled (RpIndex)) { > + ControllerLane =3D 3 - ControllerLane; > + } > + return (ControllerIndex * 4) + ControllerLane; > +} > + > +/** > + Checks if lane reversal is enabled on a given root port > + > + @param[in] RpIndex Root port index (0-based) > + > + @retval TRUE if lane reversal is enbabled, FALSE otherwise > +**/ > +BOOLEAN > +IsPcieLaneReversalEnabled ( > + IN UINT32 RpIndex > + ) > +{ > + UINT32 Data32; > + PchSbiRpPciRead32 (PchGetPcieFirstPortIndex (RpIndex), > R_PCH_PCIE_CFG_PCIEDBG, &Data32); > + return !! (Data32 & B_PCH_PCIE_CFG_PCIEDBG_LR); > +} > + > +/** > + Calculates the index of the first port on the same controller. > + > + @param[in] RpIndex Root Port Number (0-based) > + > + @retval Index of the first port on the first controller. > +**/ > +UINT32 > +PchGetPcieFirstPortIndex ( > + IN UINT32 RpIndex > + ) > +{ > + UINT32 ControllerIndex; > + > + ControllerIndex =3D RpIndex / PCH_PCIE_CONTROLLER_PORTS; > + return ControllerIndex * PCH_PCIE_CONTROLLER_PORTS; > +} > + > +/* > + Returns Tpower_on capability of device > + > + @param[in] DeviceBase device's PCI segment base address > + @param[in] L1ssCapOffset offset to L1substates capability in device= 's > extended config space > + > + @retval structure containing Tpoweron scale and va= lue > +*/ > +T_POWER_ON > +GetTpoCapability ( > + UINT64 DeviceBase, > + UINT32 L1ssCapOffset > + ) > +{ > + T_POWER_ON Tpo; > + UINT32 L1ssCapabilities; > + > + L1ssCapabilities =3D PciSegmentRead32 (DeviceBase + L1ssCapOffset + > R_PCIE_EX_L1SCAP_OFFSET); > + Tpo.Scale =3D (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTPOS) >> > N_PCIE_EX_L1SCAP_PTPOS; > + Tpo.Value =3D (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTV) >> > N_PCIE_EX_L1SCAP_PTV; > + return Tpo; > +} > + > +/* > + Converts Tpower_on from value:scale notation to microseconds > + > + @param[in] TpoScale T power on scale > + @param[in] TpoValue T power on value > + > + @retval number of microseconds > +*/ > +UINT32 > +TpoToUs ( > + UINT32 TpoScale, > + UINT32 TpoValue > + ) > +{ > + static const UINT8 TpoScaleMultiplier[] =3D {2, 10, 100}; > + > + ASSERT (TpoScale < TpoScaleMax); > + if (TpoScale >=3D TpoScaleMax) { > + return 0; > + } > + return (TpoScaleMultiplier[TpoScale] * TpoValue); > +} > + > +/** > + Finds the Offset to a given Capabilities ID > + Each capability has an ID and a pointer to next Capability, so they fo= rm a > linked list. > + This function walks the list of Capabilities present in device's pci c= fg. If > requested capability > + can be found, its offset is returned. > + If the capability can't be found or if device doesn't exist, function = returns 0 > + CAPID list: > + 0x01 =3D PCI Power Management Interface > + 0x04 =3D Slot Identification > + 0x05 =3D MSI Capability > + 0x10 =3D PCI Express Capability > + > + @param[in] DeviceBase device's base address > + @param[in] CapId CAPID to search for > + > + @retval 0 CAPID not found (this includes situati= on where > device doesn't exit) > + @retval Other CAPID found, Offset of desired CAPID > +**/ > +UINT8 > +PcieBaseFindCapId ( > + IN UINT64 DeviceBase, > + IN UINT8 CapId > + ) > +{ > + UINT8 CapHeaderOffset; > + UINT8 CapHeaderId; > + UINT16 Data16; > + // > + // We do not explicitly check if device exists to save time and avoid > unnecessary PCI access > + // If the device doesn't exist, check for CapHeaderId !=3D 0xFF will f= ail and > function will return offset 0 > + // > + if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & > EFI_PCI_STATUS_CAPABILITY) =3D=3D 0x00) { > + /// > + /// Function has no capability pointer > + /// > + return 0; > + } else { > + /// > + /// Check the header layout to determine the Offset of Capabilities = Pointer > Register > + /// > + if ((PciSegmentRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & > HEADER_LAYOUT_CODE) =3D=3D (HEADER_TYPE_CARDBUS_BRIDGE)) { > + /// > + /// If CardBus bridge, start at Offset 0x14 > + /// > + CapHeaderOffset =3D EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR; > + } else { > + /// > + /// Otherwise, start at Offset 0x34 > + /// > + CapHeaderOffset =3D PCI_CAPBILITY_POINTER_OFFSET; > + } > + /// > + /// Get Capability Header, A pointer value of 00h is used to indicat= e the last > capability in the list. > + /// > + CapHeaderId =3D 0; > + CapHeaderOffset =3D PciSegmentRead8 (DeviceBase + CapHeaderOffset) & > ((UINT8) ~(BIT0 | BIT1)); > + while (CapHeaderOffset !=3D 0 && CapHeaderId !=3D 0xFF) { > + Data16 =3D PciSegmentRead16 (DeviceBase + CapHeaderOffset); > + CapHeaderId =3D (UINT8)(Data16 & 0xFF); > + if (CapHeaderId =3D=3D CapId) { > + if (CapHeaderOffset > PCI_MAXLAT_OFFSET) { > + /// > + /// Return valid capability offset > + /// > + DEBUG ((DEBUG_INFO,"CapId %x,%x->%02x\n", > ((UINT32)(DeviceBase&0xFFFFF000)>>12), CapId, CapHeaderOffset)); > + return CapHeaderOffset; > + } else { > + ASSERT ((FALSE)); > + return 0; > + } > + } > + /// > + /// Each capability must be DWORD aligned. > + /// The bottom two bits of all pointers (including the initial poi= nter at 34h) > are reserved > + /// and must be implemented as 00b although software must mask the= m > to allow for future uses of these bits. > + /// > + CapHeaderOffset =3D (UINT8)(Data16 >> 8); > + } > + return 0; > + } > +} > + > +/** > + Find the Offset to a given Capabilities ID > + CAPID list: > + 0x01 =3D PCI Power Management Interface > + 0x04 =3D Slot Identification > + 0x05 =3D MSI Capability > + 0x10 =3D PCI Express Capability > + > + @param[in] Segment Pci Segment Number > + @param[in] Bus Pci Bus Number > + @param[in] Device Pci Device Number > + @param[in] Function Pci Function Number > + @param[in] CapId CAPID to search for > + > + @retval 0 CAPID not found > + @retval Other CAPID found, Offset of desired CAPID > +**/ > +UINT8 > +PcieFindCapId ( > + IN UINT8 Segment, > + IN UINT8 Bus, > + IN UINT8 Device, > + IN UINT8 Function, > + IN UINT8 CapId > + ) > +{ > + UINT64 DeviceBase; > + > + DEBUG ((DEBUG_INFO,"PcieFindCapId () SBDF %0x: %0x: %0x :%0x, CapId = =3D > %0x \n", Segment, Bus, Device, Function, CapId)); > + DeviceBase =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function= , > 0); > + return PcieBaseFindCapId (DeviceBase, CapId); > +} > + > +/** > + Search and return the offset of desired Pci Express Capability ID > + CAPID list: > + 0x0001 =3D Advanced Error Reporting Capability > + 0x0002 =3D Virtual Channel Capability > + 0x0003 =3D Device Serial Number Capability > + 0x0004 =3D Power Budgeting Capability > + > + @param[in] DeviceBase device base address > + @param[in] CapId Extended CAPID to search for > + > + @retval 0 CAPID not found, this includes situati= on where > device doesn't exist > + @retval Other CAPID found, Offset of desired CAPID > +**/ > +UINT16 > +PcieBaseFindExtendedCapId ( > + IN UINT64 DeviceBase, > + IN UINT16 CapId > + ) > +{ > + UINT16 CapHeaderOffset; > + UINT16 CapHeaderId; > + /// > + /// Start to search at Offset 0x100 > + /// Get Capability Header, A pointer value of 00h is used to indicate = the last > capability in the list. > + /// > + CapHeaderId =3D 0; > + CapHeaderOffset =3D R_PCH_PCIE_CFG_EXCAP_OFFSET; > + while (CapHeaderOffset !=3D 0 && CapHeaderId !=3D MAX_UINT16) { > + CapHeaderId =3D PciSegmentRead16 (DeviceBase + CapHeaderOffset); > + if (CapHeaderId =3D=3D CapId) { > + return CapHeaderOffset; > + } > + /// > + /// Each capability must be DWORD aligned. > + /// The bottom two bits of all pointers are reserved and must be > implemented as 00b > + /// although software must mask them to allow for future uses of the= se > bits. > + /// > + CapHeaderOffset =3D (PciSegmentRead16 (DeviceBase + CapHeaderOffset = + > 2) >> 4) & ((UINT16) ~(BIT0 | BIT1)); > + } > + > + return 0; > +} > + > +/** > + Search and return the offset of desired Pci Express Capability ID > + CAPID list: > + 0x0001 =3D Advanced Error Reporting Capability > + 0x0002 =3D Virtual Channel Capability > + 0x0003 =3D Device Serial Number Capability > + 0x0004 =3D Power Budgeting Capability > + > + @param[in] Segment Pci Segment Number > + @param[in] Bus Pci Bus Number > + @param[in] Device Pci Device Number > + @param[in] Function Pci Function Number > + @param[in] CapId Extended CAPID to search for > + > + @retval 0 CAPID not found, this includes situati= on where > device doesn't exist > + @retval Other CAPID found, Offset of desired CAPID > +**/ > +UINT16 > +PcieFindExtendedCapId ( > + IN UINT8 Segment, > + IN UINT8 Bus, > + IN UINT8 Device, > + IN UINT8 Function, > + IN UINT16 CapId > + ) > +{ > + UINT64 DeviceBase; > + > + DeviceBase =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function= , > 0); > + return PcieBaseFindExtendedCapId (DeviceBase, CapId); > +} > + > +/** > + This function checks whether PHY lane power gating is enabled on the p= ort. > + > + @param[in] RpBase Root Port base address > + > + @retval TRUE PHY power gating is enabled > + @retval FALSE PHY power gating disabled > +**/ > +STATIC > +BOOLEAN > +PcieIsPhyLanePgEnabled ( > + IN UINT64 RpBase > + ) > +{ > + UINT32 Data32; > + Data32 =3D PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL); > + return (Data32 & B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE) !=3D 0; > +} > + > +/** > + Get current PCIe link speed. > + > + @param[in] RpBase Root Port base address > + @retval Link speed > +**/ > +UINT32 > +GetLinkSpeed ( > + UINT64 RpBase > + ) > +{ > + return PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) & > B_PCIE_LSTS_CLS; > +} > + > +/** > + Get max PCIe link speed supported by the root port. > + > + @param[in] RpBase Root Port base address > + @retval Max link speed > +**/ > +UINT32 > +GetMaxLinkSpeed ( > + UINT64 RpBase > + ) > +{ > + return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) & > B_PCIE_LCAP_MLS; > +} > + > +/** > + Get max payload size supported by device. > + > + @param[in] Sbdf device's segment:bus:device:function coordinates > + @retval Max payload size, encoded in the same way as in register (0= =3D128b, > 1=3D256b, etc) > +**/ > +STATIC > +UINT8 > +GetMps ( > + SBDF Sbdf > + ) > +{ > + return (PciSegmentRead16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + > R_PCIE_DCAP_OFFSET) & B_PCIE_DCAP_MPS); > +} > + > +/** > + Sets Maximum Payload Size to be used by device > + > + @param[in] Sbdf device's segment:bus:device:function coordinates > + @param[in] Mps Max payload size, encoded in the same way as in > register (0=3D128b, 1=3D256b, etc) > +**/ > +STATIC > +VOID > +SetMps ( > + SBDF Sbdf, > + UINT8 Mps > + ) > +{ > + PciSegmentAndThenOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + > R_PCIE_DCTL_OFFSET, (UINT16) ~B_PCIE_DCTL_MPS, Mps << > N_PCIE_DCTL_MPS); > +} > + > +/** > + Checks if given PCI device is capable of Latency Tolerance Reporting > + > + @param[in] Sbdf device's segment:bus:device:function > coordinates > + > + @retval TRUE if yes > +**/ > +STATIC > +BOOLEAN > +IsLtrCapable ( > + SBDF Sbdf > + ) > +{ > + if (Sbdf.PcieCap =3D=3D 0) { > + return FALSE; > + } > + return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + > R_PCIE_DCAP2_OFFSET) & B_PCIE_DCAP2_LTRMS); > +} > + > +/** > + Enables LTR feature in given device > + > + @param[in] Sbdf device's segment:bus:device:function > coordinates > +**/ > +STATIC > +VOID > +EnableLtr ( > + SBDF Sbdf > + ) > +{ > + if (Sbdf.PcieCap =3D=3D 0) { > + return; > + } > + PciSegmentOr32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCTL2_OFFSET= , > B_PCIE_DCTL2_LTREN); > +} > + > +/** > + Checks if PCI device at given address exists > + > + @param[in] Base device's base address > + > + @retval TRUE if exists > +**/ > +BOOLEAN > +IsDevicePresent ( > + UINT64 Base > + ) > +{ > + if (PciSegmentRead16 (Base) =3D=3D 0xFFFF) { > + return FALSE; > + } > + return TRUE; > +} > + > +/** > + Returns information about type of device. > + > + @param[out] Sbdf device's segment:bus:device:function > coordinates > + @retval one of: not a PCIe device (legacy PCI), PCIe endpoint, PCI= e > upstream port or PCIe downstream port (including rootport) > +**/ > +STATIC > +PCI_DEV_TYPE > +GetDeviceType ( > + SBDF Sbdf > + ) > +{ > + UINT8 DeviceType; > + > + if (Sbdf.PcieCap =3D=3D 0) { > + return DevTypePci; > + } > + DeviceType =3D (UINT8) ((PciSegmentRead16 (SbdfToBase (Sbdf) + > Sbdf.PcieCap + R_PCIE_XCAP_OFFSET) & B_PCIE_XCAP_DT) >> > N_PCIE_XCAP_DT); > + if (DeviceType =3D=3D PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) { > + return DevTypePcieUpstream; > + } else if (DeviceType =3D=3D PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT || > DeviceType =3D=3D PCIE_DEVICE_PORT_TYPE_ROOT_PORT) { > + return DevTypePcieDownstream; > + } else { > + return DevTypePcieEndpoint; > + } > +} > + > +/** > + Initializes Dev:Func numbers for use in FindNextPcieChild or > FindNextLegalSbdf functions. > + > + @param[out] Sbdf device's segment:bus:device:function > coordinates > +**/ > +STATIC > +VOID > +InitChildFinder ( > + OUT SBDF *Sbdf > + ) > +{ > + // > + // Initialize Dev/Func to maximum values, so that when FindNextLegalSb= df > () > + // is called on those input parameters, it will return 1st legal addre= ss (Dev 0 > Func 0). > + // > + Sbdf->Dev =3D PCI_MAX_DEVICE; > + Sbdf->Func =3D PCI_MAX_FUNC; > +} > + > +/** > + Checks the device is a bridge and has non-zero secondary bus number > assigned. > + If so, it returns TRUE and initializes ChildSbdf with such values that > + allow searching for devices on the secondary bus. > + ChildSbdf will be mangled even if this function returns FALSE. > + > + Legal bus assignment is assumed. This function doesn't check subordina= te > bus numbers of > + the the device it was called on or any bridges between it and root com= plex > + > + @param[in] Sbdf device's segment:bus:device:function coordinate= s > + @param[out] ChildSbdf SBDF initialized in such way that calling > FindNextPcieChild( ) on it will find all children devices > + > + @retval TRUE if device is a bridge and has a bus behind it; FALSE othe= rwise > +**/ > +STATIC > +BOOLEAN > +HasChildBus ( > + SBDF Sbdf, > + SBDF *ChildSbdf > + ) > +{ > + UINT32 Data32; > + UINT64 Base; > + UINT8 SecondaryBus; > + > + ChildSbdf->Seg =3D Sbdf.Seg; > + InitChildFinder (ChildSbdf); > + > + Base =3D SbdfToBase (Sbdf); > + > + if (PciSegmentRead8 (Base + R_PCI_BCC_OFFSET) !=3D PCI_CLASS_BRIDGE) { > + DEBUG ((DEBUG_INFO, "HasChildBus%02:%02:%02: no\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + return FALSE; > + } > + Data32 =3D PciSegmentRead32 (Base + > PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET); > + SecondaryBus =3D (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SCBN) >> 8); > + ChildSbdf->Bus =3D SecondaryBus; > + if (SecondaryBus =3D=3D 0) { > + DEBUG ((DEBUG_INFO, "HasChildBus%02x:%02x:%02x: no\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + return FALSE; > + } else { > + DEBUG ((DEBUG_INFO, "HasChildBus%02x:%02x:%02x: yes, %x\n", > Sbdf.Bus, Sbdf.Dev, Sbdf.Func, SecondaryBus)); > + return TRUE; > + } > +} > + > +/** > + Checks if device is a multifunction device > + Besides comparing Multifunction bit (BIT7) it checks if contents of > HEADER_TYPE register > + make sense (header !=3D 0xFF) to prevent false positives when called o= n > devices which do not exist > + > + @param[in] Base device's base address > + > + @retval TRUE if multifunction; FALSE otherwise > +**/ > +BOOLEAN > +IsMultifunctionDevice ( > + UINT64 Base > + ) > +{ > + UINT8 HeaderType; > + HeaderType =3D PciSegmentRead8(Base + PCI_HEADER_TYPE_OFFSET); > + if ((HeaderType =3D=3D 0xFF) || ((HeaderType & > HEADER_TYPE_MULTI_FUNCTION) =3D=3D 0)) { > + return FALSE; > + } > + return TRUE; > +} > + > +/** > + Returns combination of two LTR override values > + The resulting LTR override separately chooses stricter limits for snoo= p and > nosnoop > + > + @param[in] LtrA LTR override values to be combined > + @param[in] LtrB LTR override values to be combined > + > + @retval LTR override value > +**/ > +STATIC > +LTR_OVERRIDE > +CombineLtr ( > + LTR_OVERRIDE LtrA, > + LTR_OVERRIDE LtrB > + ) > +{ > + UINT64 DecodedLatencyA; > + UINT64 DecodedLatencyB; > + LTR_OVERRIDE Result; > + static UINT32 ScaleEncoding [8] =3D {1, 32, 1024, 32768, 1048576, 3355= 4432, 0, > 0}; > + > + DecodedLatencyA =3D ScaleEncoding[LtrA.MaxSnoopLatencyScale] * > LtrA.MaxSnoopLatencyValue; > + DecodedLatencyB =3D ScaleEncoding[LtrB.MaxSnoopLatencyScale] * > LtrB.MaxSnoopLatencyValue; > + if ((!LtrB.MaxSnoopLatencyRequirement) || ((DecodedLatencyA < > DecodedLatencyB) && LtrA.MaxSnoopLatencyRequirement)) { > + Result.MaxSnoopLatencyValue =3D LtrA.MaxSnoopLatencyValue; > + Result.MaxSnoopLatencyScale =3D LtrA.MaxSnoopLatencyScale; > + Result.MaxSnoopLatencyRequirement =3D > LtrA.MaxSnoopLatencyRequirement; > + } else { > + Result.MaxSnoopLatencyValue =3D LtrB.MaxSnoopLatencyValue; > + Result.MaxSnoopLatencyScale =3D LtrB.MaxSnoopLatencyScale; > + Result.MaxSnoopLatencyRequirement =3D > LtrB.MaxSnoopLatencyRequirement; > + } > + DecodedLatencyA =3D ScaleEncoding[LtrA.MaxNoSnoopLatencyScale] * > LtrA.MaxNoSnoopLatencyValue; > + DecodedLatencyB =3D ScaleEncoding[LtrB.MaxNoSnoopLatencyScale] * > LtrB.MaxNoSnoopLatencyValue; > + if ((!LtrB.MaxNoSnoopLatencyRequirement) || ((DecodedLatencyA < > DecodedLatencyB) && LtrA.MaxNoSnoopLatencyRequirement)) { > + Result.MaxNoSnoopLatencyValue =3D LtrA.MaxNoSnoopLatencyValue; > + Result.MaxNoSnoopLatencyScale =3D LtrA.MaxNoSnoopLatencyScale; > + Result.MaxNoSnoopLatencyRequirement =3D > LtrA.MaxNoSnoopLatencyRequirement; > + } else { > + Result.MaxNoSnoopLatencyValue =3D LtrB.MaxNoSnoopLatencyValue; > + Result.MaxNoSnoopLatencyScale =3D LtrB.MaxNoSnoopLatencyScale; > + Result.MaxNoSnoopLatencyRequirement =3D > LtrB.MaxNoSnoopLatencyRequirement; > + } > + Result.ForceOverride =3D FALSE; > + if (LtrA.ForceOverride || LtrB.ForceOverride) { > + Result.ForceOverride =3D TRUE; > + } > + DEBUG ((DEBUG_INFO, "CombineLtr: A(V%d S%d E%d : V%d S%d E%d, > F%d)\n", > + LtrA.MaxSnoopLatencyValue, LtrA.MaxSnoopLatencyScale, > LtrA.MaxSnoopLatencyRequirement, > + LtrA.MaxNoSnoopLatencyValue, LtrA.MaxNoSnoopLatencyScale, > LtrA.MaxNoSnoopLatencyRequirement, > + LtrA.ForceOverride > + )); > + DEBUG ((DEBUG_INFO, " : B(V%d S%d E%d : V%d S%d E%d, F%d)\n", > + LtrB.MaxSnoopLatencyValue, LtrB.MaxSnoopLatencyScale, > LtrB.MaxSnoopLatencyRequirement, > + LtrB.MaxNoSnoopLatencyValue, LtrB.MaxNoSnoopLatencyScale, > LtrB.MaxNoSnoopLatencyRequirement, > + LtrB.ForceOverride > + )); > + DEBUG ((DEBUG_INFO, " : R(V%d S%d E%d : V%d S%d E%d, F%d)\n", > + Result.MaxSnoopLatencyValue, Result.MaxSnoopLatencyScale, > Result.MaxSnoopLatencyRequirement, > + Result.MaxNoSnoopLatencyValue, Result.MaxNoSnoopLatencyScale, > Result.MaxNoSnoopLatencyRequirement, > + Result.ForceOverride > + )); > + return Result; > +} > + > +/** > + Returns LTR override value for given device > + The value is extracted from Device Override table. If the device is no= t found, > + the returned value will have Requirement bits clear > + > + @param[in] Base device's base address > + @param[in] Override device override table > + > + @retval LTR override value > +**/ > +STATIC > +LTR_OVERRIDE > +GetOverrideLtr ( > + UINT64 Base, > + OVERRIDE_TABLE *Override > + ) > +{ > + UINT16 DevId; > + UINT16 VenId; > + UINT16 RevId; > + UINT32 Index; > + LTR_OVERRIDE ReturnValue =3D {0}; > + > + VenId =3D PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET); > + DevId =3D PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET); > + RevId =3D PciSegmentRead16 (Base + PCI_REVISION_ID_OFFSET); > + > + for (Index =3D 0; Index < Override->Size; Index++) { > + if (((Override->Table[Index].OverrideConfig & PchPcieLtrOverride) = =3D=3D > PchPcieLtrOverride) && > + (Override->Table[Index].VendorId =3D=3D VenId) && > + ((Override->Table[Index].DeviceId =3D=3D DevId) || > (Override->Table[Index].DeviceId =3D=3D 0xFFFF)) && > + ((Override->Table[Index].RevId =3D=3D RevId) || > (Override->Table[Index].RevId =3D=3D 0xFF))) { > + if (Override->Table[Index].SnoopLatency & 0x8000) { > + ReturnValue.MaxSnoopLatencyRequirement =3D 1; > + ReturnValue.MaxSnoopLatencyValue =3D > Override->Table[Index].SnoopLatency & 0x3FF; > + ReturnValue.MaxSnoopLatencyScale =3D > (Override->Table[Index].SnoopLatency & 0x1C00) >> 10; > + } > + if (Override->Table[Index].NonSnoopLatency & 0x8000) { > + ReturnValue.MaxNoSnoopLatencyRequirement =3D 1; > + ReturnValue.MaxNoSnoopLatencyValue =3D > Override->Table[Index].NonSnoopLatency & 0x3FF; > + ReturnValue.MaxNoSnoopLatencyScale =3D > (Override->Table[Index].NonSnoopLatency & 0x1C00) >> 10; > + } > + ReturnValue.ForceOverride =3D Override->Table[Index].ForceLtrOverr= ide; > + break; > + } > + } > + return ReturnValue; > +} > + > +/** > + Sets LTR limit in a device. > + > + @param[in] Base device's base address > + @param[in] Ltr LTR limit > +**/ > +STATIC > +VOID > +SetLtrLimit ( > + UINT64 Base, > + LTR_LIMIT Ltr > + ) > +{ > + UINT16 LtrCapOffset; > + UINT16 Data16; > + > + LtrCapOffset =3D PcieBaseFindExtendedCapId (Base, > R_PCH_PCIE_LTRECH_CID); > + if (LtrCapOffset =3D=3D 0) { > + return; > + } > + Data16 =3D (UINT16)((Ltr.MaxSnoopLatencyValue << > N_PCH_PCIE_LTRECH_MSLR_VALUE) | (Ltr.MaxSnoopLatencyScale << > N_PCH_PCIE_LTRECH_MSLR_SCALE)); > + PciSegmentWrite16(Base + LtrCapOffset + > R_PCH_PCIE_LTRECH_MSLR_OFFSET, Data16); > + > + Data16 =3D (UINT16)((Ltr.MaxNoSnoopLatencyValue << > N_PCH_PCIE_LTRECH_MNSLR_VALUE) | (Ltr.MaxNoSnoopLatencyScale << > N_PCH_PCIE_LTRECH_MNSLR_SCALE)); > + PciSegmentWrite16(Base + LtrCapOffset + > R_PCH_PCIE_LTRECH_MNSLR_OFFSET, Data16); > +} > + > +/** > + Checks if device at given address exists and is a PCI Express device. > + PCI express devices are distinguished from PCI by having Capability ID= 0x10 > + If the device is PCI express then its SDBF structure gets updated with= pointer > to > + the PCIe Capability. This is an optimization feature. It greatly decre= ases the > number > + of bus accesses, since most features configured by this library depend= on > registers > + whose location is relative to PCIe capability. > + > + @param[in,out] Sbdf on entry, segment:bus:device:function coordinate= s > + on exit, PcieCap offset is updated > + @retval TRUE when PCIe device exists; FALSE if it's not = PCIe or > there's no device at all > +**/ > +STATIC > +BOOLEAN > +IsPcieDevice ( > + SBDF *Sbdf > + ) > +{ > + UINT8 PcieCapOffset; > + UINT64 Base; > + > + Base =3D SbdfToBase (*Sbdf); > + > + if (PciSegmentRead16 (Base) =3D=3D 0xFFFF) { > + return FALSE; > + } > + > + > + PcieCapOffset =3D PcieBaseFindCapId (Base, EFI_PCI_CAPABILITY_ID_PCIEX= P); > + if (PcieCapOffset =3D=3D 0) { > + DEBUG ((DEBUG_INFO, "IsPcieDevice %02x:%02x:%02x - legacy\n", > Sbdf->Bus, Sbdf->Dev, Sbdf->Func)); > + return FALSE; > + } else { > + Sbdf->PcieCap =3D PcieCapOffset; > + DEBUG ((DEBUG_INFO, "IsPcieDevice %02x:%02x:%02x - yes\n", Sbdf->Bus= , > Sbdf->Dev, Sbdf->Func)); > + return TRUE; > + } > +} > + > +/** > + Returns TRUE and Dev:Func numbers where a PCIe device could legally be > located, or FALSE if there > + no such coordinates left. > + > + Segment and Bus fields of SBDF structure are input only and determine > which bus will be scanned. > + This function should be called in a while() loop. It replaces the less= efficient > method of > + using nested FOR loops that iterate over all device and function numbe= rs. It > is optimized for > + the amount of bus access. If function0 doesn't exist or doesn't have > Multifunction bit set, > + then higher function numbers are skipped. If parent of this bus is a > downstream port, then > + Device numbers 1-31 get skipped too (there can be only Dev0 behind > downstream ports) > + If device/function number =3D=3D 0x1F/0x7, this function returns first= possible > address, that is 0:0 > + Any other device number means Dev:Func contain address of last found > child device > + and this function should search for next one > + > + @param[in] ParentDevType type of bridge who's partent of this bus > + @param[in,out] Sbdf On entry: location returned previously f= rom > this function > + Dev:Func value of 1F:07 means = search should > start from the beginning > + On exit: if legal Dev:Func combination = was found, > that Dev:Func is returned > + otherwise, Dev:Func are initia= lized to 1F:07 for > convenience > + @retval TRUE when next legal Dev:Func address was found; FALSE otherwi= se > +**/ > +STATIC > +BOOLEAN > +FindNextLegalSbdf ( > + IN PCI_DEV_TYPE ParentDevType, > + IN OUT SBDF *Sbdf > + ) > +{ > + UINT8 MaxDev; > + UINT64 Func0Base; > + > + if (ParentDevType =3D=3D DevTypePcieEndpoint) { > + return FALSE; > + } > + if (ParentDevType =3D=3D DevTypePcieUpstream) { > + MaxDev =3D PCI_MAX_DEVICE; > + } else { > + MaxDev =3D 0; > + } > + Func0Base =3D PCI_SEGMENT_LIB_ADDRESS (Sbdf->Seg, Sbdf->Bus, Sbdf->Dev= , > 0, 0); > + if ((Sbdf->Dev =3D=3D PCI_MAX_DEVICE) && Sbdf->Func =3D=3D PCI_MAX_FUN= C) { > + Sbdf->Dev =3D 0; > + Sbdf->Func =3D 0; > + return TRUE; > + } else if ((Sbdf->Func =3D=3D PCI_MAX_FUNC) || (Sbdf->Func =3D=3D 0 > && !IsMultifunctionDevice (Func0Base))) { > + // > + // if it's the last function of a device, then return Func0 of new dev= ice or > FALSE in case there are no more devices > + // > + if (Sbdf->Dev =3D=3D MaxDev) { > + InitChildFinder (Sbdf); > + return FALSE; > + } > + (Sbdf->Dev)++; > + Sbdf->Func =3D 0; > + return TRUE; > + } else { > + (Sbdf->Func)++; > + return TRUE; > + } > +} > + > +/** > + Finds next PCIe (not legacy PCI) device behind given device > + If device/function number =3D=3D 0x1F/0x7, this function searches for = children > from scratch > + Any other device number means Dev:Func contain address of last found > child device > + and this function should search for next one > + > + @param[in] ParentDevType type of bridge who's partent of this bus > + @param[in,out] Sbdf On entry: location returned previously f= rom > this function > + Dev:Func value of 0x1F:0x07 me= ans search > should start from the beginning > + On exit: if PCIe device was found, its = SBDF > coordinates are returned > + otherwise, Dev:Func are initia= lized to > 0x1F:0x07 for convenience > + @retval TRUE when next PCIe device was found; FALSE otherwise > +**/ > +STATIC > +BOOLEAN > +FindNextPcieChild ( > + IN PCI_DEV_TYPE ParentDevType, > + IN OUT SBDF *Sbdf > + ) > +{ > + while ( FindNextLegalSbdf (ParentDevType, Sbdf)) { > + if (IsPcieDevice (Sbdf)) { > + return TRUE; > + } > + } > + return FALSE; > +} > + > +/** > + Checks device's Slot Clock Configuration > + > + @param[in] Base device's base address > + > + @retval TRUE when device uses slot clock, FALSE otherwise > +**/ > +BOOLEAN > +GetScc ( > + UINT64 Base, > + UINT8 PcieCapOffset > + ) > +{ > + return !!(PciSegmentRead16 (Base + PcieCapOffset + R_PCIE_LSTS_OFFSET) > & B_PCIE_LSTS_SCC); > +} > + > +/** > + Sets Common Clock Configuration bit for given device. > + > + @param[in] Base device's base address > +**/ > +VOID > +EnableCcc ( > + UINT64 Base, > + UINT8 PcieCapOffset > + ) > +{ > + PciSegmentOr8 (Base + PcieCapOffset + R_PCIE_LCTL_OFFSET, > B_PCIE_LCTL_CCC); > +} > + > +/** > + Retrains link behind given device. > + It only makes sense to call it for downstream ports. If called for ups= tream > port nothing will happen. > + If WaitUntilDone is TRUE function will wait until link retrain had fin= ished, > otherwise it will return immediately. > + Link must finish retrain before software can access the device on the = other > side. If it's not going to access it > + then considerable time can be saved by not waiting here. > + > + @param[in] Sbdf Device's Segment:Bus:Device:Function > coordinates > + @param[in] WaitUntilDone when TRUE, function waits until link has > retrained > +**/ > +VOID > +RetrainLink ( > + UINT64 Base, > + UINT8 PcieCapOffset, > + BOOLEAN WaitUntilDone > + ) > +{ > + UINT16 LinkTraining; > + UINT32 TimeoutUs; > + > + TimeoutUs =3D LINK_RETRAIN_WAIT_TIME; > + // > + // Before triggering link retrain make sure it's not already retrainin= g. > Otherwise > + // settings recently entered in LCTL register might go unnoticed > + // > + do { > + LinkTraining =3D (PciSegmentRead16 (Base + PcieCapOffset + > R_PCIE_LSTS_OFFSET) & B_PCIE_LSTS_LT); > + TimeoutUs--; > + } while (LinkTraining && (TimeoutUs !=3D 0)); > + > + PciSegmentOr8 (Base + PcieCapOffset + R_PCIE_LCTL_OFFSET, > B_PCIE_LCTL_RL); > + > + TimeoutUs =3D LINK_RETRAIN_WAIT_TIME; > + if (WaitUntilDone) { > + do { > + LinkTraining =3D (PciSegmentRead16 (Base + PcieCapOffset + > R_PCIE_LSTS_OFFSET) & B_PCIE_LSTS_LT); > + TimeoutUs--; > + } while (LinkTraining && (TimeoutUs !=3D 0)); > + } > +} > + > +/** > + Checks if given device supports Clock Power Management > + > + @param[in] Sbdf segment:bus:device:function coordinates of a devic= e > + > + @retval TRUE when device supports it, FALSE otherwise > +**/ > +STATIC > +BOOLEAN > +IsCpmSupported ( > + SBDF Sbdf > + ) > +{ > + return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + > R_PCIE_LCAP_OFFSET) & B_PCIE_LCAP_CPM); > +} > + > +/** > + Sets Enable Clock Power Management bit for given device > + > + @param[in] Base device's base address > +**/ > +STATIC > +VOID > +EnableCpm ( > + SBDF Sbdf > + ) > +{ > + PciSegmentOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_LCTL_OFFSET, > B_PCIE_LCTL_ECPM); > +} > + > +/** > + Checks if given device is an IoAPIC > + > + @param[in] Base device's base address > + > + @retval TRUE if it's an IoAPIC > +**/ > +BOOLEAN > +IsIoApicDevice ( > + UINT64 Base > + ) > +{ > + UINT8 BaseClassCode; > + UINT8 SubClassCode; > + UINT8 ProgInterface; > + > + BaseClassCode =3D PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET + 2); > + SubClassCode =3D PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET + 1); > + ProgInterface =3D PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET); > + if ((BaseClassCode =3D=3D PCI_CLASS_SYSTEM_PERIPHERAL) && > + (SubClassCode =3D=3D PCI_SUBCLASS_PIC) && > + ((ProgInterface =3D=3D PCI_IF_APIC_CONTROLLER) || > + (ProgInterface =3D=3D PCI_IF_APIC_CONTROLLER2))) { > + return TRUE; > + } > + return FALSE; > +} > + > +/** > + There are some devices which support L1 substates, but due to silicon = bugs > the corresponding register > + cannot be found by scanning PCIe capabilities. This function checks li= st of > such devices and if one > + is found, returns its L1ss capability register offset > + > + @param[in] Base base address of device > + @param[in] Override table of devices that need override > + @retval offset to L1ss capability register > +**/ > +UINT16 > +GetOverrideL1ssCapsOffset ( > + UINT64 Base, > + OVERRIDE_TABLE *Override > + ) > +{ > + UINT16 DeviceId; > + UINT16 VendorId; > + UINT8 Revision; > + UINT32 Index; > + > + VendorId =3D PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET); > + DeviceId =3D PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET); > + Revision =3D PciSegmentRead8 (Base + PCI_REVISION_ID_OFFSET); > + > + for (Index =3D 0; Index < Override->Size; Index++) { > + if (((Override->Table[Index].OverrideConfig & PchPcieL1SubstatesOver= ride) > =3D=3D PchPcieL1SubstatesOverride) && > + (Override->Table[Index].VendorId =3D=3D VendorId) && > + (Override->Table[Index].DeviceId =3D=3D DeviceId) && > + (Override->Table[Index].RevId =3D=3D Revision || > Override->Table[Index].RevId =3D=3D 0xFF)) { > + return Override->Table[Index].L1SubstatesCapOffset; > + } > + } > + return 0; > +} > + > +/** > + There are some devices whose implementation of L1 substates is partial= ly > broken. This function checks > + list of such devices and if one is found, overrides their L1ss-related > capabilities > + > + @param[in] Base base address of device > + @param[in] Override table of devices that need override > + @param[in,out] L1ss on entry, capabilities read from register; o= n exit, > capabilities modified according ot override table > +**/ > +STATIC > +VOID > +OverrideL1ssCaps ( > + UINT64 Base, > + OVERRIDE_TABLE *Override, > + L1SS_CAPS *L1ss > + ) > +{ > + UINT16 DeviceId; > + UINT16 VendorId; > + UINT8 Revision; > + UINT32 Index; > + > + VendorId =3D PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET); > + DeviceId =3D PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET); > + Revision =3D PciSegmentRead8 (Base + PCI_REVISION_ID_OFFSET); > + > + for (Index =3D 0; Index < Override->Size; Index++) { > + if (((Override->Table[Index].OverrideConfig & PchPcieL1SubstatesOver= ride) > =3D=3D PchPcieL1SubstatesOverride) && > + (Override->Table[Index].VendorId =3D=3D VendorId) && > + (Override->Table[Index].DeviceId =3D=3D DeviceId) && > + (Override->Table[Index].RevId =3D=3D Revision || > Override->Table[Index].RevId =3D=3D 0xFF)) { > + L1ss->PmL12 &=3D !!(Override->Table[Index].L1SubstatesCapMask & > B_PCIE_EX_L1SCAP_PPL12S); > + L1ss->PmL11 &=3D !!(Override->Table[Index].L1SubstatesCapMask & > B_PCIE_EX_L1SCAP_PPL11S); > + L1ss->AspmL12 &=3D !!(Override->Table[Index].L1SubstatesCapMask & > B_PCIE_EX_L1SCAP_AL12S); > + L1ss->AspmL11 &=3D !!(Override->Table[Index].L1SubstatesCapMask & > B_PCIE_EX_L1SCAP_AL1SS); > + if (Override->Table[Index].L1sTpowerOnValue !=3D 0) { > + L1ss->Cmrt =3D Override->Table[Index].L1sCommonModeRestoreTime; > + L1ss->TpoScale =3D Override->Table[Index].L1sTpowerOnScale; > + L1ss->TpoValue =3D Override->Table[Index].L1sTpowerOnValue; > + } > + return; > + } > + } > +} > + > +/** > + Returns L1 sub states capabilities of a device > + > + @param[in] Base base address of a device > + > + @retval L1SS_CAPS structure filled with device's capabilities > +**/ > +STATIC > +L1SS_CAPS > +GetL1ssCaps ( > + UINT64 Base, > + OVERRIDE_TABLE *Override > + ) > +{ > + L1SS_CAPS Capabilities =3D {0}; > + UINT16 PcieCapOffset; > + UINT32 CapsRegister; > + > + PcieCapOffset =3D GetOverrideL1ssCapsOffset (Base, Override); > + if (PcieCapOffset =3D=3D 0) { > + PcieCapOffset =3D PcieBaseFindExtendedCapId (Base, V_PCIE_EX_L1S_CID= ); > + } > + if (PcieCapOffset =3D=3D 0) { > + return Capabilities; > + } > + CapsRegister =3D PciSegmentRead32 (Base + PcieCapOffset + > R_PCIE_EX_L1SCAP_OFFSET); > + if (CapsRegister & B_PCIE_EX_L1SCAP_L1PSS) { > + Capabilities.PmL11 =3D !!(CapsRegister & B_PCIE_EX_L1SCAP_PPL11S); > + Capabilities.PmL12 =3D !!(CapsRegister & B_PCIE_EX_L1SCAP_PPL12S); > + Capabilities.AspmL12 =3D !!(CapsRegister & B_PCIE_EX_L1SCAP_AL12S); > + Capabilities.AspmL11 =3D !!(CapsRegister & B_PCIE_EX_L1SCAP_AL1SS); > + Capabilities.Cmrt =3D (CapsRegister & B_PCIE_EX_L1SCAP_CMRT) >> > N_PCIE_EX_L1SCAP_CMRT; > + Capabilities.TpoValue =3D (CapsRegister & B_PCIE_EX_L1SCAP_PTV) >> > N_PCIE_EX_L1SCAP_PTV; > + Capabilities.TpoScale =3D (CapsRegister & B_PCIE_EX_L1SCAP_PTPOS) >> > N_PCIE_EX_L1SCAP_PTPOS; > + } > + OverrideL1ssCaps (Base, Override, &Capabilities); > + return Capabilities; > +} > + > +/** > + Returns combination of two sets of L1 substate capabilities > + Given feature is supported by the link only if both sides support it > + Time parameters for link (Cmrt and Tpo) depend on the bigger value > between two sides > + > + @param[in] L1ssA L1 substate capabilities of first device > + @param[in] L1ssB L1 substate capabilities of second device > + > + @retval Link's L1 substate capabilities > +**/ > +STATIC > +L1SS_CAPS > +CombineL1ss ( > + L1SS_CAPS L1ssA, > + L1SS_CAPS L1ssB > + ) > +{ > + L1SS_CAPS Combined; > + > + Combined.PmL12 =3D L1ssA.PmL12 && L1ssB.PmL12; > + Combined.PmL11 =3D L1ssA.PmL11 && L1ssB.PmL11; > + Combined.AspmL12 =3D L1ssA.AspmL12 && L1ssB.AspmL12; > + Combined.AspmL11 =3D L1ssA.AspmL11 && L1ssB.AspmL11; > + Combined.Cmrt =3D MAX (L1ssA.Cmrt, L1ssB.Cmrt); > + if (TpoToUs (L1ssA.TpoScale, L1ssA.TpoValue) > TpoToUs (L1ssB.TpoScale= , > L1ssB.TpoValue)) { > + Combined.TpoScale =3D L1ssA.TpoScale; > + Combined.TpoValue =3D L1ssA.TpoValue; > + } else { > + Combined.TpoScale =3D L1ssB.TpoScale; > + Combined.TpoValue =3D L1ssB.TpoValue; > + } > + return Combined; > +} > + > +/** > + Configures L1 substate feature in a device > + > + @param[in] Sbdf segment:bus:device:function coordinates of a devic= e > + @param[in] L1ss configuration to be programmed > + @param[in] Override table of devices that require special handling > +**/ > +STATIC > +VOID > +SetL1ss ( > + SBDF Sbdf, > + L1SS_CAPS L1ss, > + OVERRIDE_TABLE *Override > + ) > +{ > + UINT16 PcieCapOffset; > + UINT32 Ctrl1Register; > + UINT32 Ctrl2Register; > + UINT64 Base; > + > + Base =3D SbdfToBase(Sbdf); > + Ctrl1Register =3D 0; > + Ctrl2Register =3D 0; > + > + PcieCapOffset =3D GetOverrideL1ssCapsOffset (Base, Override); > + if (PcieCapOffset =3D=3D 0) { > + PcieCapOffset =3D PcieBaseFindExtendedCapId (Base, V_PCIE_EX_L1S_CID= ); > + } > + if (PcieCapOffset =3D=3D 0) { > + return; > + } > + Ctrl1Register |=3D (L1ss.PmL12 ? B_PCIE_EX_L1SCAP_PPL12S : 0); > + Ctrl1Register |=3D (L1ss.PmL11 ? B_PCIE_EX_L1SCAP_PPL11S : 0); > + Ctrl1Register |=3D (L1ss.AspmL12 ? B_PCIE_EX_L1SCAP_AL12S : 0); > + Ctrl1Register |=3D (L1ss.AspmL11 ? B_PCIE_EX_L1SCAP_AL1SS : 0); > + if (GetDeviceType (Sbdf) =3D=3D DevTypePcieDownstream) { > + Ctrl1Register |=3D (L1ss.Cmrt << N_PCIE_EX_L1SCAP_CMRT); > + } > + /// > + /// Set L1.2 LTR threshold to 80us (value =3D 0x50, scale =3D 0x2 =3D= 1024ns), in > accordance to BWG > + /// BUG BUG BUG It shouldn't be hardcoded, it should consider Tpower= on, > otherwise we risk situation where > + /// BUG BUG BUG threshold is lower than Tpo, and every L1 entry turn= s > into L1.2 entry with no possibility > + /// BUG BUG BUG to exit before LTR elapses, because exit can take no= less > than Tpo > + /// > + Ctrl1Register |=3D (0x50 << N_PCIE_EX_L1SCTL1_L12LTRTLV); > + Ctrl1Register |=3D (2 << N_PCIE_EX_L1SCTL1_L12LTRTLSV); > + > + Ctrl2Register |=3D (L1ss.TpoScale); > + Ctrl2Register |=3D (L1ss.TpoValue << N_PCIE_EX_L1SCTL2_POWT); > + > + PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL1_OFFSET, 0)= ; > + PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL2_OFFSET, > Ctrl2Register); > + PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL1_OFFSET, > Ctrl1Register); > +} > + > +/** > + Converts L1 latency from enumerated register value to microseconds > + > + @param[in] L1Latency latency value retrieved from register; see PC= IE > specification for encoding > + @retval L1 latency converted to microseconds > +**/ > +UINT32 > +L1LatencyToUs ( > + UINT32 L1Latency > + ) > +{ > + if (L1Latency < 7) { > + return 1 * (BIT0 << L1Latency); > + } else { > + return ASPM_L1_NO_LIMIT; > + } > +} > + > +/** > + Modifies L1 latency by provided value > + > + @param[in] Aspm Structure that contains ASPM capabilities of a lin= k, > including L1 acceptable latency > + @param[in] Value Value, in microseconds, to be added to L1 acceptab= le > latency. Can be negative. > + @retval Aspm structure with modified L1 acceptable latency > +**/ > +STATIC > +ASPM_CAPS > +PatchL1AcceptableLatency ( > + ASPM_CAPS Aspm, > + INT8 Value > + ) > +{ > + if (Aspm.L1AcceptableLatencyUs !=3D ASPM_L1_NO_LIMIT) { > + if (Value > 0) { > + Aspm.L1AcceptableLatencyUs +=3D Value; > + } else { > + if (Aspm.L1AcceptableLatencyUs > (UINT32)(-1*Value)) { > + Aspm.L1AcceptableLatencyUs =3D Aspm.L1AcceptableLatencyUs + Valu= e; > + } else { > + Aspm.L1AcceptableLatencyUs =3D 0; > + } > + } > + } > + return Aspm; > +} > + > +/** > + Reads ASPM capabilities of a device > + > + @param[in] Sbdf segment:bus:device:function coordinates of a device > + > +@retval structure containing device's ASPM capabilities > +**/ > +STATIC > +ASPM_CAPS > +GetAspmCaps ( > + SBDF Sbdf > + ) > +{ > + > + UINT32 LinkCapRegister; > + UINT32 DevCapRegister; > + UINT64 Base; > + ASPM_CAPS Aspm =3D {0}; > + > + Base =3D SbdfToBase (Sbdf); > + > + LinkCapRegister =3D PciSegmentRead32 (Base + Sbdf.PcieCap + > R_PCIE_LCAP_OFFSET); > + DevCapRegister =3D PciSegmentRead32 (Base + Sbdf.PcieCap + > R_PCIE_DCAP_OFFSET); > + > + /// > + /// Check endpoint for pre-1.1 devices based on the Role based Error > Reporting Capability bit. Don't report L0s support for old devices > + /// > + if (DevCapRegister & B_PCIE_DCAP_RBER) { > + Aspm.L0sSupported =3D !!(LinkCapRegister & B_PCIE_LCAP_APMS_L0S); > + } > + Aspm.L1Supported =3D !!(LinkCapRegister & B_PCIE_LCAP_APMS_L1); > + > + Aspm.LinkL0sExitLatency =3D (LinkCapRegister & B_PCIE_LCAP_EL0) >> > N_PCIE_LCAP_EL0; > + Aspm.LinkL1ExitLatencyUs =3D L1LatencyToUs( (LinkCapRegister & > B_PCIE_LCAP_EL1) >> N_PCIE_LCAP_EL1); > + > + if (GetDeviceType (Sbdf) =3D=3D DevTypePcieEndpoint) { > + Aspm.L0sAcceptableLatency =3D (DevCapRegister & B_PCIE_DCAP_E0AL) >> > N_PCIE_DCAP_E0AL; > + Aspm.L1AcceptableLatencyUs =3D L1LatencyToUs( (DevCapRegister & > B_PCIE_DCAP_E1AL) >> N_PCIE_DCAP_E1AL); > + DEBUG ((DEBUG_INFO, "GetAspmCaps %02x:%02x:%02x L0s%c %d:%d > L1%c %d:%d\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, > + > Aspm.L0sSupported?'+':'-', Aspm.LinkL0sExitLatency, > Aspm.L0sAcceptableLatency, > + > Aspm.L1Supported?'+':'-', Aspm.LinkL1ExitLatencyUs, > Aspm.L1AcceptableLatencyUs)); > + } else { > + Aspm.L0sAcceptableLatency =3D ASPM_L0s_NO_LIMIT; > + Aspm.L1AcceptableLatencyUs =3D ASPM_L1_NO_LIMIT; > + DEBUG ((DEBUG_INFO, "GetAspmCaps %02x:%02x:%02x L0s%c %d:x L1%c > %d:x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, > + > Aspm.L0sSupported?'+':'-', Aspm.LinkL0sExitLatency, > + > Aspm.L1Supported?'+':'-', Aspm.LinkL1ExitLatencyUs)); > + } > + return Aspm; > +} > + > +/** > + Get ASPM L0s and L1 override of given device. > + > + @param[in] Sbdf Segment,Bus,Device,Function address of > currently visited PCIe device > + @param[in,out] MyAspm Current device's ASPM capabilities > structure > + @param[in] Override Pch Pcie devices OverrideTable > +**/ > +STATIC > +VOID > +GetOverrideAspm ( > + SBDF Sbdf, > + ASPM_CAPS *MyAspm, > + OVERRIDE_TABLE *Override > + ) > +{ > + UINT16 DeviceId; > + UINT16 VendorId; > + UINT8 Revision; > + UINT32 Index; > + UINT64 Base; > + > + Base =3D SbdfToBase (Sbdf); > + > + VendorId =3D PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET); > + DeviceId =3D PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET); > + Revision =3D PciSegmentRead8 (Base + PCI_REVISION_ID_OFFSET); > + > + for (Index =3D 0; Index < Override->Size; Index++) { > + if (((Override->Table[Index].OverrideConfig & PchPcieL1L2Override) = =3D=3D > PchPcieL1L2Override) && > + (Override->Table[Index].VendorId =3D=3D VendorId) && > + (Override->Table[Index].DeviceId =3D=3D DeviceId) && > + (Override->Table[Index].RevId =3D=3D Revision || > Override->Table[Index].RevId =3D=3D 0xFF)) { > + DEBUG ((DEBUG_INFO, "GetOverrideAspm %02x:%02x:%02x, original > L0sSupported =3D 0x%x, L1Supported =3D 0x%x\n", > + Sbdf.Bus, Sbdf.Dev, Sbdf.Func, MyAspm->L0sSupported, > MyAspm->L1Supported)); > + if (MyAspm->L0sSupported) { > + // > + // If L0s is supported in capability, apply platform override. > + // > + MyAspm->L0sSupported =3D Override->Table[Index].EndPointAspm & > BIT0; > + } > + if (MyAspm->L1Supported) { > + // > + // If L1 is supported in capability, apply platform override. > + // > + MyAspm->L1Supported =3D (Override->Table[Index].EndPointAspm & > BIT1) >> 1; > + } > + DEBUG ((DEBUG_INFO, "GetOverrideAspm %02x:%02x:%02x, override > L0sSupported =3D 0x%x, L1Supported =3D 0x%x\n", > + Sbdf.Bus, Sbdf.Dev, Sbdf.Func, MyAspm->L0sSupported, > MyAspm->L1Supported)); > + } > + } > +} > + > +/** > + Combines ASPM capabilities of two devices on both ends of a link to > determine link's ASPM capabilities > + > + @param[in] AspmA, AspmB ASPM capabilities of two devices > + > +@retval ASPM_CAPS structure containing combined ASPM capabilities > +**/ > +STATIC > +ASPM_CAPS > +CombineAspm ( > + ASPM_CAPS AspmA, > + ASPM_CAPS AspmB, > + BOOLEAN DownstreamPort > + ) > +{ > + ASPM_CAPS Combined; > + > + if (DownstreamPort) { > + // > + // When combining ASPM in downstream ports, combination must reflect > state of link just below > + // and consider all acceptable latencies of all endpoints anywhere d= own > below that port > + // > + Combined.L0sSupported =3D AspmA.L0sSupported & AspmB.L0sSupported; > + Combined.L1Supported =3D AspmA.L1Supported & AspmB.L1Supported; > + Combined.LinkL0sExitLatency =3D MAX (AspmA.LinkL0sExitLatency, > AspmB.LinkL0sExitLatency); > + Combined.LinkL1ExitLatencyUs =3D MAX (AspmA.LinkL1ExitLatencyUs, > AspmB.LinkL1ExitLatencyUs); > + Combined.L0sAcceptableLatency =3D MIN (AspmA.L0sAcceptableLatency, > AspmB.L0sAcceptableLatency); > + Combined.L1AcceptableLatencyUs =3D MIN (AspmA.L1AcceptableLatencyUs, > AspmB.L1AcceptableLatencyUs); > + } else { > + // > + // When combining ASPM in switch upstream ports, > + // Supported and ExitLatency must only reflect capabilities of upstr= eam > port itself > + // But acceptable latencies must consider all endpoints anywhere bel= ow > + // > + Combined.L0sSupported =3D AspmA.L0sSupported; > + Combined.L1Supported =3D AspmA.L1Supported; > + Combined.LinkL0sExitLatency =3D AspmA.LinkL0sExitLatency; > + Combined.LinkL1ExitLatencyUs =3D AspmA.LinkL1ExitLatencyUs; > + Combined.L0sAcceptableLatency =3D MIN (AspmA.L0sAcceptableLatency, > AspmB.L0sAcceptableLatency); > + Combined.L1AcceptableLatencyUs =3D MIN (AspmA.L1AcceptableLatencyUs, > AspmB.L1AcceptableLatencyUs); > + } > + DEBUG ((DEBUG_INFO, "CombineAspm %x:%x -> %x\n", > AspmA.L1AcceptableLatencyUs, AspmB.L1AcceptableLatencyUs, > Combined.L1AcceptableLatencyUs)); > + return Combined; > +} > + > +/** > + Checks if L1 can be enabled on given link, according to ASPM parameter= s of > that link > + > + @param[in] Aspm set of parameters describing this link and > endpoint devices below it > + @retval TRUE if L1 can be enabled > +**/ > +STATIC > +BOOLEAN > +IsL1Allowed ( > + ASPM_CAPS Aspm > + ) > +{ > + return (Aspm.L1Supported && (Aspm.L1AcceptableLatencyUs >=3D > Aspm.LinkL1ExitLatencyUs)); > +} > + > +/** > + Checks if L0s can be enabled on given link, according to ASPM paramete= rs of > that link > + > + @param[in] Aspm set of parameters describing this link and > endpoint devices below it > + @retval TRUE if L0s can be enabled > +**/ > +STATIC > +BOOLEAN > +IsL0sAllowed ( > + ASPM_CAPS Aspm > + ) > +{ > + return (Aspm.L0sSupported && (Aspm.L0sAcceptableLatency >=3D > Aspm.LinkL0sExitLatency)); > +} > + > +/** > + Enables L0s and L1 for given port, if possible. > + L0s/L1 can be enabled if it's supported on both sides of a link and if= link's > latency doesn't exceed > + acceptable latency of any endpoint below this link > + > + @param[in] Base device's base address > + @param[in] Aspm set of parameters describing this link and > endpoint devices below it > +**/ > +STATIC > +VOID > +SetAspm ( > + SBDF Sbdf, > + ASPM_CAPS Aspm > + ) > +{ > + UINT16 DataOr; > + > + DataOr =3D 0; > + if (IsL0sAllowed (Aspm)) { > + DataOr |=3D V_PCIE_LCTL_ASPM_L0S; > + } > + if (IsL1Allowed (Aspm)) { > + DataOr |=3D V_PCIE_LCTL_ASPM_L1; > + } > + DEBUG ((DEBUG_INFO, "SetAspm on %02x:%02x:%02x to %d\n", > Sbdf.Bus,Sbdf.Dev,Sbdf.Func, DataOr)); > + PciSegmentAndThenOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + > R_PCIE_LCTL_OFFSET, (UINT16)~B_PCIE_LCTL_ASPM, DataOr); > +} > + > +/** > + Adds device entry to a list of devices. > + > + @param[in,out] Table array of devices > + @param[in] Sbdf segment:bus:device:function coordinates of dev= ice > to be added to table > +**/ > +STATIC > +VOID > +AddToDeviceTable ( > + SBDF_TABLE *Table, > + SBDF Sbdf > + ) > +{ > + if (Table->Count < MAX_SBDF_TABLE_SIZE) { > + Table->Entry[Table->Count++] =3D Sbdf; > + } else { > + ASSERT (FALSE); > + } > +} > + > +/** > + Remove device entry from a list and clear its bus assignment > + > + @param[in,out] Table array of devices > +**/ > +STATIC > +VOID > +ClearBusFromTable ( > + SBDF_TABLE *Table > + ) > +{ > + while (Table->Count > 0) { > + PciSegmentWrite32 (SbdfToBase (Table->Entry[Table->Count - 1]) + > PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0); > + Table->Count--; > + } > +} > + > +/** > + Attempts to assign secondary and subordinate bus numbers to uninitiali= zed > bridges in PCIe tree > + If the device is a bridge and already has bus numbers assigned, they w= on't > be changed > + Otherwise new bus number will be assigned below this bridge. > + This function can be called from SMM, where BIOS must not modify bus > numbers to prevent > + conflict with OS enumerator. To prevent this, this function returns li= st of > bridges whose > + bus numbers were changed. All devices from that list must have buses > cleared afterwards. > + > + @param[in] Sbdf segment:bus:device:function coordinates= of > device to be added to table > + @param[in] MinBus minimum Bus number that can be assigned > below this port > + @param[in] MaxBus maximum Bus number that can be assigned > below this port > + @param[in] BridgeCleanupList list of bridges where bus numbers were > modified > + > + @retval maximum bus number assigned anywhere below this device > +**/ > +STATIC > +UINT8 > +RecursiveBusAssignment ( > + SBDF Sbdf, > + UINT8 MinBus, > + UINT8 MaxBus, > + SBDF_TABLE *BridgeCleanupList > + ) > +{ > + UINT64 Base; > + SBDF ChildSbdf; > + PCI_DEV_TYPE DevType; > + UINT32 Data32; > + UINT8 BelowBus; > + UINT8 SecondaryBus; > + UINT8 SubordinateBus; > + > + ChildSbdf.Seg =3D Sbdf.Seg; > + InitChildFinder (&ChildSbdf); > + Base =3D SbdfToBase (Sbdf); > + > + // > + // On way down: > + // assign secondary bus, then increase it by one before stepping dow= n; > temporarily assign max subordinate bus > + // On way up: > + // fix subordinate bus assignment to equal max bus number assigned > anywhere below; return that number > + // > + DevType =3D GetDeviceType (Sbdf); > + if ((Sbdf.Bus >=3D MaxBus) || (DevType =3D=3D DevTypePcieEndpoint) || = (DevType > =3D=3D DevTypePci)) { > + return (UINT8) Sbdf.Bus; > + } else { > + Data32 =3D PciSegmentRead32 (Base + > PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET); > + SecondaryBus =3D (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SCBN) >> 8); > + SubordinateBus =3D (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SBBN) >> 16); > + if (SecondaryBus !=3D 0) { > + ChildSbdf.Bus =3D SecondaryBus; > + MinBus =3D SecondaryBus + 1; > + DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentP %x:%x:%x -> > %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, MinBus, > SubordinateBus)); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + BelowBus =3D RecursiveBusAssignment (ChildSbdf, MinBus, > SubordinateBus, BridgeCleanupList); > + MinBus =3D BelowBus + 1; > + } > + return SubordinateBus; > + } else { > + Data32 =3D Sbdf.Bus + (MinBus << 8) + (MaxBus << 16); > + PciSegmentWrite32(Base + > PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Data32); > + AddToDeviceTable (BridgeCleanupList, Sbdf); > + DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentE %x:%x:%x -> > %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, MinBus, MaxBus)); > + BelowBus =3D MinBus; > + ChildSbdf.Bus =3D MinBus; > + MinBus++; > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + BelowBus =3D RecursiveBusAssignment (ChildSbdf, MinBus, MaxBus, > BridgeCleanupList); > + MinBus =3D BelowBus + 1; > + } > + Data32 &=3D ~B_PCI_BRIDGE_BNUM_SBBN; > + Data32 |=3D (BelowBus << 16); > + PciSegmentWrite32 (Base + > PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Data32); > + DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentL %x:%x:%x -> > %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, (Data32&0xFF00)>>8= , > BelowBus)); > + return BelowBus; > + } > + } > +} > + > +/** > + Enables L0s and/or L1 for PCIE links in the hierarchy below > + L0s/L1 can be enabled when both sides of a link support it and link la= tency > is smaller than acceptable latency > + ASPM of a given link is independend from any other link (except 1ms L1 > adjustment, read below), so it's possible to > + have a hierarchy when RP link has no ASPM but links below do. > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] Depth How many links there are bet= ween > this port and root complex > + @param[in] Override Pch Pcie devices OverrideTab= le > + > + @retval structure that describes acceptable latencies of all endpoints= below > plus ASPM parameters of last link > +**/ > +STATIC > +ASPM_CAPS > +RecursiveAspmConfiguration ( > + SBDF Sbdf, > + UINT8 Depth, > + OVERRIDE_TABLE *Override > + ) > +{ > + SBDF ChildSbdf; > + ASPM_CAPS MyAspm; > + ASPM_CAPS ChildAspm; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveAspmConfiguration %x:%x:%x\n", > Sbdf.Bus, Sbdf.Dev, Sbdf.Func)); > + > + // > + // On way down: > + // pass number of links traversed; increase it per upstream port vis= ited > (not endpoint) > + // On way up: > + // EndPoint: read Acceptable Latencies; subtract Depth From > L1AcceptableLat to account for "1us per switch additional delay" > + // Downstreamport: AND L0s/L1 caps; calculate LinkLatency; enable L0= s/L1 > if supported and if acceptable latency is bigger than link latency; > + // if L1 not enabled, add back 1us to Acceptable Latency to cancel= earlier > Depth subtraction > + // UpstreamPort: calculate minimum of below Acceptable Latencies; > return that, with upper link's Latency and L0s/L1 support > + // > + DevType =3D GetDeviceType(Sbdf); > + if (DevType =3D=3D DevTypePcieUpstream) { > + Depth++; > + } > + MyAspm =3D GetAspmCaps (Sbdf); > + // > + // Get ASPM L0s and L1 override > + // > + GetOverrideAspm (Sbdf, &MyAspm, Override); > + if (DevType =3D=3D DevTypePcieEndpoint) { > + // > + // Every switch between endpoint and CPU introduces 1us additional > latency on L1 exit. This is reflected by > + // subtracting 1us per switch from endpoint's acceptable L1 latency. > + // In case L1 doesn't get enabled in one of switches, that 1us will = be added > back. > + // This calculation is not precise. It ignores that some switches' a= dded > delay may be shadowed by > + // other links' exit latency. But it guarantees that acceptable late= ncy won't > be exceeded and is simple > + // enough to perform in a single iteration without backtracking. > + // > + return PatchL1AcceptableLatency (MyAspm, (-1 * Depth)); > + } > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + ChildAspm =3D RecursiveAspmConfiguration (ChildSbdf, Depth, Overri= de); > + MyAspm =3D CombineAspm (MyAspm, ChildAspm, (DevType =3D=3D > DevTypePcieDownstream)); > + } > + if (DevType =3D=3D DevTypePcieDownstream) { > + SetAspm (Sbdf, MyAspm); > + // > + // ASPM config must be consistent across all functions of a device= . That's > why there's while loop. > + // > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + SetAspm (ChildSbdf, MyAspm); > + } > + if (!IsL1Allowed (MyAspm)) { > + MyAspm =3D PatchL1AcceptableLatency (MyAspm, 1); > + } > + } > + } > + return MyAspm; > +} > + > +/** > + Enables L1 substates for PCIE links in the hierarchy below > + L1.1 / L1.2 can be enabled if both sides of a link support it. > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + > + @retval structure that describes L1ss capabilities of the device > +**/ > +STATIC > +L1SS_CAPS > +RecursiveL1ssConfiguration ( > + SBDF Sbdf, > + OVERRIDE_TABLE *Override > + ) > +{ > + UINT64 Base; > + SBDF ChildSbdf; > + L1SS_CAPS CombinedCaps; > + L1SS_CAPS ChildCaps; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveL1ssConfiguration %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + Base =3D SbdfToBase (Sbdf); > + // > + // On way down: > + // do nothing > + // On way up: > + // In downstream ports, combine L1ss capabilities of that port and d= evice > behind it, then enable L1.1 and/or L1.2 if possible > + // Return L1ss capabilities > + // > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + ChildCaps =3D RecursiveL1ssConfiguration (ChildSbdf, Override); > + if (DevType =3D=3D DevTypePcieDownstream && ChildSbdf.Func =3D=3D = 0) { > + CombinedCaps =3D CombineL1ss (GetL1ssCaps (Base, Override), > ChildCaps); > + SetL1ss (Sbdf, CombinedCaps, Override); > + SetL1ss (ChildSbdf, CombinedCaps, Override); > + } > + } > + } > + return GetL1ssCaps (Base, Override); > +} > + > +/** > + Checks if there is an IoAPIC device in the PCIe hierarchy. > + If one is found, this function doesn't check for more and returns > + > + @param[in] BusLimit maximum Bus number that can = be > assigned below this port > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + > + @retval TRUE if IoAPIC device was found > +**/ > +STATIC > +BOOLEAN > +RecursiveIoApicCheck ( > + SBDF Sbdf > + ) > +{ > + SBDF ChildSbdf; > + UINT8 IoApicPresent; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveIoApicCheck %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + IoApicPresent =3D FALSE; > + > + if (IsIoApicDevice (SbdfToBase (Sbdf))) { > + DEBUG ((DEBUG_INFO, "IoApicFound @%x:%x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + return TRUE; > + } > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + IoApicPresent =3D RecursiveIoApicCheck (ChildSbdf); > + if (IoApicPresent) { > + break; > + } > + } > + } > + DEBUG ((DEBUG_INFO, "IoApic status %d @%x:%x:%x:%x\n", IoApicPresent, > Sbdf.Seg, Sbdf.Bus, Sbdf.Dev, Sbdf.Func)); > + return IoApicPresent; > +} > + > +/** > + Calculates Maximum Payload Size supported by PCIe hierarchy. > + Starting from a device, it finds the minimum MPS supported by devices > below it. > + There are many valid strategies for setting MPS. This implementation > chooses > + one that is safest, but doesn't guarantee maximum performance: > + Find minimum MPS under given rootport, then program that minimum > value everywhere below that rootport > + > + @param[in] BusLimit maximum Bus number that can = be > assigned below this port > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + > + @retval MPS supported by PCIe hierarchy, calculated as MIN(MPS of all > devices below) > +**/ > +STATIC > +UINT8 > +RecursiveMpsCheck ( > + SBDF Sbdf > + ) > +{ > + SBDF ChildSbdf; > + UINT8 MyMps; > + UINT8 SubtreeMps; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveMpsCheck %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + MyMps =3D GetMps (Sbdf); > + if (MyMps =3D=3D 0) { > + return MyMps; > + } > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + SubtreeMps =3D RecursiveMpsCheck (ChildSbdf); > + MyMps =3D MIN(MyMps, SubtreeMps); > + } > + } > + return MyMps; > +} > + > +/** > + Sets Maximum Payload Size in PCIe hierarchy. > + Starting from a device, it programs the same MPS value to it and all d= evices > below it. > + There are many valid strategies for setting MPS. This implementation > chooses > + one that is safest, but doesn't guarantee maximum performance: > + Find minimum MPS under given rootport, then program that minimum > value everywhere below that rootport > + > + @param[in] BusLimit maximum Bus number that can = be > assigned below this port > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] Mps Maximum Payload Size to be > programmed > +**/ > +STATIC > +VOID > +RecursiveMpsConfiguration ( > + SBDF Sbdf, > + UINT8 Mps > + ) > +{ > + SBDF ChildSbdf; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveMpsConfiguration %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + RecursiveMpsConfiguration (ChildSbdf, Mps); > + } > + } > + SetMps (Sbdf, Mps); > +} > + > +/** > + Sets Enable Clock Power Management bit for devices that support it. > + A device supports CPM only if all function of this device report CPM s= upport. > + Downstream ports never report CPM capability, so it's only relevant fo= r > upstream ports. > + When this function executes on upstream component, it will check CPM & > set ECPM of downstream component > + When this function executes on downstream component, all devices below > it are guaranteed to > + return CPM=3D0 so it will do nothing > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + > + @retval TRUE =3D this device supports CPM, FALSE =3D it doesn't > +**/ > +STATIC > +BOOLEAN > +RecursiveCpmConfiguration ( > + SBDF Sbdf > + ) > +{ > + SBDF ChildSbdf; > + BOOLEAN ChildCpm; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveCpmConfiguration %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + ChildCpm =3D FALSE; > + > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + ChildCpm =3D TRUE; > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + ChildCpm &=3D RecursiveCpmConfiguration (ChildSbdf); > + } > + if (ChildCpm) { > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + EnableCpm (ChildSbdf); > + } > + } > + } > + return IsCpmSupported (Sbdf); > +} > + > +/** > + Sets Common Clock Configuration bit for devices that share common cloc= k > across link > + Devices on both sides of a PCIE link share common clock if both upstre= am > component > + and function 0 of downstream component report Slot Clock Configuration > bit =3D 1. > + When this function executes on upstream component, it checks SCC of bo= th > sides of the link > + If they both support it, sets CCC for both sides (this means all funct= ions of > downstream component) > + When this function executes on downstream component, it only returns > SCC capability > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] WaitForRetrain decides if this function sho= uld > busy-wait for link retrain > + > + @retval TRUE =3D this device supports SCC, FALSE =3D it doesn't > +**/ > +STATIC > +BOOLEAN > +RecursiveCccConfiguration ( > + SBDF Sbdf, > + BOOLEAN WaitForRetrain > + ) > +{ > + UINT64 Base; > + SBDF ChildSbdf; > + BOOLEAN MyScc; > + BOOLEAN ChildScc; > + BOOLEAN LinkScc; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveCccConfiguration %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + ChildScc =3D 0; > + Base =3D SbdfToBase(Sbdf); > + MyScc =3D GetScc (SbdfToBase(Sbdf), (UINT8)Sbdf.PcieCap); > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + ChildScc |=3D RecursiveCccConfiguration (ChildSbdf, WaitForRetrain= ); > + } > + if (DevType =3D=3D DevTypePcieDownstream) { > + LinkScc =3D MyScc & ChildScc; > + if (LinkScc) { > + EnableCcc (SbdfToBase(Sbdf), (UINT8)Sbdf.PcieCap); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + EnableCcc (SbdfToBase(ChildSbdf), (UINT8)ChildSbdf.PcieCap); > + } > + RetrainLink(Base, (UINT8)Sbdf.PcieCap, WaitForRetrain); > + } > + } > + } > + return MyScc; > +} > + > +/** > + Configures Latency Tolerance Reporting in given device and in PCIe tre= e > below it. > + This function configures Maximum LTR and enables LTR mechanism. It vis= its > devices using depth-first search > + and skips branches behind devices which do not support LTR. > + Maximum LTR: > + This function will set LTR's upper bound for every visited device. M= ax LTR > value is provided as a parameter > + Enable LTR: > + LTR should be enabled top-to-bottom in every visited device that sup= ports > LTR. This function does not > + iterate down behind devices with no LTR support. In effect, LTR will= be > enabled in given device if that device > + and all devices above it on the way to RootComplex do support LTR. > + > + This function expects that bridges have bus numbers already configured > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] LtrLimit Ltr to be programmed to ever= y > endpoint > + > + @retval MaxLTR programmed in this device > +**/ > +STATIC > +VOID > +RecursiveLtrConfiguration ( > + SBDF Sbdf, > + LTR_LIMIT LtrLimit > + ) > +{ > + UINT64 Base; > + SBDF ChildSbdf; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveLtrConfiguration %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + Base =3D SbdfToBase(Sbdf); > + > + if (!IsLtrCapable (Sbdf)) { > + DEBUG ((DEBUG_INFO, "Not LtrCapable %02x:%02x:%02x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + return; > + } > + EnableLtr (Sbdf); > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + RecursiveLtrConfiguration (ChildSbdf, LtrLimit); > + } > + } > + SetLtrLimit (Base, LtrLimit); > +} > + > +/** > + In accordance with PCIe spec, devices with no LTR support are consider= ed to > have no LTR requirements > + which means infinite latency tolerance. This was found to cause proble= ms > with HID and Audio devices without LTR > + support placed behind PCIe switches with LTR support, as Switch's upst= ream > link would be allowed to enter L1.2 > + and cause large latency downstream. To work around such issues and to = fix > some devices with broken > + LTR reporting, Device Override table was introduced. > + This function scans PCIe tree for devices mentioned in override table = and > calculates the strictest > + LTR requirement between them. That value will be programmed into > rootport's LTR override register > + > + This function expects that bridges have bus numbers already configured > + > + @param[in] BusLimit maximum Bus number that can = be > assigned below this port > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] AspmOverride Device specific ASPM policy > override items > + > + @retval MaxLTR programmed in this device > +**/ > +STATIC > +LTR_OVERRIDE > +RecursiveLtrOverrideCheck ( > + SBDF Sbdf, > + OVERRIDE_TABLE *AspmOverride > + ) > +{ > + UINT64 Base; > + SBDF ChildSbdf; > + LTR_OVERRIDE MyLtrOverride; > + LTR_OVERRIDE ChildLtr; > + PCI_DEV_TYPE DevType; > + > + DEBUG ((DEBUG_INFO, "RecursiveLtrOverrideCheck %x:%x:%x\n", Sbdf.Bus, > Sbdf.Dev, Sbdf.Func)); > + > + Base =3D SbdfToBase(Sbdf); > + > + MyLtrOverride =3D GetOverrideLtr (Base, AspmOverride); > + if (HasChildBus (Sbdf, &ChildSbdf)) { > + DevType =3D GetDeviceType (Sbdf); > + while (FindNextPcieChild (DevType, &ChildSbdf)) { > + ChildLtr =3D RecursiveLtrOverrideCheck (ChildSbdf, AspmOverride); > + MyLtrOverride =3D CombineLtr (MyLtrOverride, ChildLtr); > + } > + } > + return MyLtrOverride; > +} > + > +/** > + Configures rootport packet split. > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] Mps maximum packet size > +**/ > +STATIC > +VOID > +ConfigureRpPacketSplit ( > + SBDF RpSbdf, > + UINT8 Mps > + ) > +{ > + UINT64 RpBase; > + > + RpBase =3D SbdfToBase (RpSbdf); > + PciSegmentAndThenOr32 (RpBase + R_PCH_PCIE_CFG_CCFG, (UINT32) > ~(B_PCH_PCIE_CFG_CCFG_UNRS), Mps << N_PCH_PCIE_CFG_CCFG_UNRS); > +} > + > +/** > + Configures LTR override in rootport's proprietary registers. > + > + @param[in] Segment,Bus,Device,Function address of currently visited > PCIe device > + @param[in] RpConfig rootport configuration > + @param[in] TreeLtr combination of LTR override = values > from all devices under this rootport > +**/ > +STATIC > +VOID > +ConfigureRpLtrOverride ( > + SBDF RpSbdf, > + PCH_PCIE_ROOT_PORT_CONFIG *RpConfig, > + OVERRIDE_TABLE *AspmOverride > + ) > +{ > + UINT64 RpBase; > + UINT32 OvrEn; > + UINT32 OvrVal; > + LTR_OVERRIDE TreeLtr; > + > + OvrEn =3D 0; > + OvrVal =3D 0; > + RpBase =3D SbdfToBase (RpSbdf); > + // > + // LTR settings from LTROVR register only get acknowledged on rising e= dge of > LTROVR2[1:0] > + // If those bits were already set (that can happen on a > plug-hotUnplug-hotPlug scenario), > + // they need to be toggled > + // > + if (PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LTROVR2) !=3D 0) { > + PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR2, 0); > + } > + // > + // (*)LatencyOverrideMode =3D 0 -> no override > + // 1 -> override with RP policy values > + // 2 -> override with endpoint's override val= ues > + // > + > + TreeLtr =3D RecursiveLtrOverrideCheck (RpSbdf, AspmOverride); > + > + if (RpConfig->ForceLtrOverride || TreeLtr.ForceOverride) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE; > + } > + if (RpConfig->LtrConfigLock =3D=3D TRUE) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_LOCK; > + } > + > + if (RpConfig->SnoopLatencyOverrideMode =3D=3D 1) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN; > + OvrVal |=3D RpConfig->SnoopLatencyOverrideValue; > + OvrVal |=3D RpConfig->SnoopLatencyOverrideMultiplier << 10; > + OvrVal |=3D B_PCH_PCIE_CFG_LTROVR_LTRSROVR; > + } else if (RpConfig->SnoopLatencyOverrideMode =3D=3D 2) { > + if (TreeLtr.MaxSnoopLatencyRequirement) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN; > + OvrVal |=3D TreeLtr.MaxSnoopLatencyValue; > + OvrVal |=3D TreeLtr.MaxSnoopLatencyScale << 10; > + OvrVal |=3D B_PCH_PCIE_CFG_LTROVR_LTRSROVR; > + } > + } > + if (RpConfig->NonSnoopLatencyOverrideMode =3D=3D 1) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN; > + OvrVal |=3D RpConfig->NonSnoopLatencyOverrideValue << 16; > + OvrVal |=3D RpConfig->NonSnoopLatencyOverrideMultiplier << 26; > + OvrVal |=3D B_PCH_PCIE_CFG_LTROVR_LTRNSROVR; > + } else if (RpConfig->NonSnoopLatencyOverrideMode =3D=3D 2) { > + if (TreeLtr.MaxNoSnoopLatencyRequirement) { > + OvrEn |=3D B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN; > + OvrVal |=3D TreeLtr.MaxNoSnoopLatencyValue << 16; > + OvrVal |=3D TreeLtr.MaxNoSnoopLatencyScale << 26; > + OvrVal |=3D B_PCH_PCIE_CFG_LTROVR_LTRNSROVR; > + } > + } > + PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR, OvrVal); > + PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR2, OvrEn); > + DEBUG ((DEBUG_INFO, "ConfigureRpLtrOverride %x:%x Val %x En %x\n", > RpSbdf.Dev, RpSbdf.Func, OvrVal, OvrEn)); > +} > + > +/** > + This function configures EOI message forwarding for PCIe port. > + If there's an IoAPIC behind this port, forwarding will be enabled > + Otherwise it will be disabled to minimize bus traffic > + > + @param[in] RpSegment address of rootport on PCIe > + @param[in] RpBus address of rootport on PCIe > + @param[in] RpDevice address of rootport on PCIe > + @param[in] RpFunction address of rootport on PCIe > + @param[in] IoApicPresent TRUE if there's IoAPIC behind this rootprot > +**/ > +VOID > +ConfigureEoiForwarding ( > + UINT8 RpSegment, > + UINT8 RpBus, > + UINT8 RpDevice, > + UINT8 RpFunction, > + BOOLEAN IoApicPresent > + ) > +{ > + UINT64 RpBase; > + UINT32 RpIndex; > + > + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, > RpFunction, 0); > + RpIndex =3D PciePortIndex (RpBase); > + > + if (IoApicPresent =3D=3D FALSE) { > + PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_MPC2, > B_PCH_PCIE_CFG_MPC2_EOIFD); > + } else { > + /// > + /// If there is an IOAPIC discovered behind root port program PSF Mu= lticast > registers > + /// accordingly to PCH BWG PSF EOI Multicast Configuration > + /// > + PciSegmentAnd32 (RpBase + R_PCH_PCIE_CFG_MPC2, > (UINT32)~B_PCH_PCIE_CFG_MPC2_EOIFD); > + PsfConfigurEoiForPciePort (RpIndex); > + } > +} > + > +/** > + Configures proprietary parts of L1 substates configuration in rootport > + > + @param[in] RpSbdf segment:bus:device:function coordinates of rootpor= t > +**/ > +STATIC > +VOID > +L1ssProprietaryConfiguration ( > + SBDF RpSbdf > + ) > +{ > + BOOLEAN ClkreqSupported; > + BOOLEAN L1ssEnabled; > + UINT16 PcieCapOffset; > + UINT32 Data32; > + BOOLEAN L1LowSupported; > + UINT64 RpBase; > + > + RpBase =3D SbdfToBase (RpSbdf); > + ClkreqSupported =3D PcieIsPhyLanePgEnabled (RpBase); > + > + PcieCapOffset =3D PcieBaseFindExtendedCapId (RpBase, V_PCIE_EX_L1S_CID= ); > + if (PcieCapOffset =3D=3D 0) { > + L1ssEnabled =3D FALSE; > + } else { > + Data32 =3D PciSegmentRead32 (RpBase + PcieCapOffset + > R_PCIE_EX_L1SCTL1_OFFSET); > + L1ssEnabled =3D Data32 & (B_PCIE_EX_L1SCAP_AL1SS | > B_PCIE_EX_L1SCAP_AL12S | B_PCIE_EX_L1SCAP_PPL11S > |B_PCIE_EX_L1SCAP_PPL12S); > + } > + L1LowSupported =3D ClkreqSupported && IsLtrCapable (RpSbdf) > && !L1ssEnabled; > + > + /// > + /// If L1.SNOOZ and L1.OFF (L1 Sub-States) are not supported and per-p= ort > CLKREQ# is supported, and LTR is supported: > + /// Enable L1.LOW by setting Dxx:Fn:420[17] =3D 1b > + /// > + if (L1LowSupported) { > + PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, (UINT32) > B_PCH_PCIE_CFG_PCIEPMECTL_L1LE); > + } else { > + PciSegmentAnd32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, (UINT32) > ~B_PCH_PCIE_CFG_PCIEPMECTL_L1LE); > + } > + > + if (L1LowSupported || L1ssEnabled) { > + /// > + /// f. Set Dxx:Fn:420h[0] to 1b prior to L1 enabling if any L1subst= ate is > enabled (including L1LOW) > + /// > + PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, > B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE); > + } > +} > + > +/** > + Initializes the following features in rootport and devices behind it: > + Maximum Payload Size (generic) > + Rootport packet split (proprietary) > + EonOfInterrupt forwarding (proprietary) > + Common Clock Configuration (generic) > + > + Generic: any code written according to PCIE Express base specification= can > do that. > + Proprietary: code uses registers and features that are specific to Int= el silicon > + and probably only this Reference Code knows how to handle that. > + > + If OEM implemented generic feature enabling in his platform code or tr= usts > Operating System > + to do it, then those features can be deleted from here. > + > + CCC requires link retrain, which takes a while. CCC must happen before > L0s/L1 programming. > + If there was guarantee no code would access PCI while links retrain, i= t would > be possible to skip this waiting > + > + @param[in] RpSegment address of rootport on PCIe > + @param[in] RpBus address of rootport on PCIe > + @param[in] RpDevice address of rootport on PCIe > + @param[in] RpFunction address of rootport on PCIe > + @param[in] BusMin minimum Bus number that can be assigned below > this rootport > + @param[in] BusMax maximum Bus number that can be assigned below > this rootport > +**/ > +VOID > +RootportDownstreamConfiguration ( > + UINT8 RpSegment, > + UINT8 RpBus, > + UINT8 RpDevice, > + UINT8 RpFunction, > + UINT8 BusMin, > + UINT8 BusMax > + ) > +{ > + UINT8 Mps; > + BOOLEAN IoApicPresent; > + UINT64 RpBase; > + SBDF RpSbdf; > + SBDF_TABLE BridgeCleanupList; > + > + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, > RpFunction, 0); > + if (!(IsDevicePresent (RpBase))) { > + return; > + } > + RpSbdf.Seg =3D RpSegment; > + RpSbdf.Bus =3D RpBus; > + RpSbdf.Dev =3D RpDevice; > + RpSbdf.Func =3D RpFunction; > + RpSbdf.PcieCap =3D PcieBaseFindCapId (RpBase, > EFI_PCI_CAPABILITY_ID_PCIEXP); > + > + DEBUG ((DEBUG_INFO, "RootportDownstreamConfiguration %x:%x\n", > RpDevice, RpFunction)); > + BridgeCleanupList.Count =3D 0; > + RecursiveBusAssignment (RpSbdf, BusMin, BusMax, &BridgeCleanupList); > + > + Mps =3D RecursiveMpsCheck (RpSbdf); > + RecursiveMpsConfiguration (RpSbdf, Mps); > + ConfigureRpPacketSplit (RpSbdf, Mps); > + IoApicPresent =3D RecursiveIoApicCheck (RpSbdf); > + ConfigureEoiForwarding (RpSegment, RpBus, RpDevice, RpFunction, > IoApicPresent); > + RecursiveCccConfiguration (RpSbdf, TRUE); > + > + ClearBusFromTable (&BridgeCleanupList); > +} > + > +/** > + Configures the following power-management related features in rootport > and devices behind it: > + LTR limit (generic) > + LTR override (proprietary) > + Clock Power Management (generic) > + L1 substates (generic except for the override table) > + L1.LOW substate (proprietary) > + L0s and L1 (generic) > + > + Generic: any code written according to PCIE Express base specification= can > do that. > + Proprietary: code uses registers and features that are specific to Int= el silicon > + and probably only this Reference Code knows how to handle that. > + > + If OEM implemented generic feature enabling in his platform code or tr= usts > Operating System > + to do it, then those features can be deleted from here. > + > + @param[in] RpSegment address of rootport on PCIe > + @param[in] RpBus address of rootport on PCIe > + @param[in] RpDevice address of rootport on PCIe > + @param[in] RpFunction address of rootport on PCIe > + @param[in] BusLimit maximum Bus number that can be > assigned below this rootport > + @param[in] AspmOverrideTableSize size of override array > + @param[in] AspmOverrideTable array of device that need exceptio= ns > in configuration > + @param[in] PerformAspmConfiguration enables/disables ASPM > programming > +**/ > +VOID > +RootportDownstreamPmConfiguration ( > + UINT8 RpSegment, > + UINT8 RpBus, > + UINT8 RpDevice, > + UINT8 RpFunction, > + UINT8 BusMin, > + UINT8 BusMax, > + PCH_PCIE_ROOT_PORT_CONFIG *RpConfig, > + UINT32 AspmOverrideTableSize, > + PCH_PCIE_DEVICE_OVERRIDE *AspmOverrideTable > + ) > +{ > + LTR_LIMIT PolicyLtr; > + OVERRIDE_TABLE PmOverrideTable; > + UINT64 RpBase; > + SBDF RpSbdf; > + SBDF_TABLE BridgeCleanupList; > + > + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, > RpFunction, 0); > + if (!(IsDevicePresent (RpBase))) { > + return; > + } > + PmOverrideTable.Size =3D AspmOverrideTableSize; > + PmOverrideTable.Table =3D AspmOverrideTable; > + > + DEBUG ((DEBUG_INFO, "RootportDownstreamPmConfiguration %x:%x\n", > RpDevice, RpFunction)); > + PolicyLtr.MaxNoSnoopLatencyScale =3D (RpConfig->LtrMaxNoSnoopLatency & > 0x1c00) >> 10; > + PolicyLtr.MaxNoSnoopLatencyValue =3D RpConfig->LtrMaxNoSnoopLatency & > 0x3FF; > + PolicyLtr.MaxSnoopLatencyScale =3D (RpConfig->LtrMaxSnoopLatency & > 0x1c00) >> 10; > + PolicyLtr.MaxSnoopLatencyValue =3D RpConfig->LtrMaxSnoopLatency & > 0x3FF; > + > + RpSbdf.Seg =3D RpSegment; > + RpSbdf.Bus =3D RpBus; > + RpSbdf.Dev =3D RpDevice; > + RpSbdf.Func =3D RpFunction; > + RpSbdf.PcieCap =3D PcieBaseFindCapId (RpBase, > EFI_PCI_CAPABILITY_ID_PCIEXP); > + // > + // This code could execute either before or after enumeration. If befo= re, > then buses would not yet be assigned to bridges, > + // making devices deeper in the hierarchy inaccessible. > + // RecursiveBusAssignment will scan whole PCie tree and assign bus > numbers to uninitialized bridges, if there are any > + // List of such bridges will be kept in CleanupList, so that after PM > programming is done, bus numbers can brought to original state > + // > + BridgeCleanupList.Count =3D 0; > + RecursiveBusAssignment(RpSbdf, BusMin, BusMax, &BridgeCleanupList); > + // > + // The 'Recursive...' functions below expect bus numbers to be already > assigned > + // > + RecursiveLtrConfiguration (RpSbdf, PolicyLtr); > + ConfigureRpLtrOverride (RpSbdf, RpConfig, &PmOverrideTable); > + if (RpConfig->EnableCpm) { > + RecursiveCpmConfiguration (RpSbdf); > + } > + // > + // L1 substates can be modified only when L1 is disabled, so this func= tion > must execute > + // before Aspm configuration which enables L1 > + // > + RecursiveL1ssConfiguration (RpSbdf, &PmOverrideTable); > + L1ssProprietaryConfiguration (RpSbdf); > + RecursiveAspmConfiguration (RpSbdf, 0, &PmOverrideTable); > + ClearBusFromTable (&BridgeCleanupList); > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLib.c > new file mode 100644 > index 0000000000..f2d20c625a > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLib.c > @@ -0,0 +1,542 @@ > +/** @file > + This file contains PSF routines for RC usage > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "PchPsfPrivateLibInternal.h" > + > +/** > + Disable device at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfDisableDevice ( > + IN PSF_PORT PsfPort > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN, > + ~0u, > + B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS > + ); > +} > + > +/** > + Hide PciCfgSpace of device at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfHideDevice ( > + IN PSF_PORT PsfPort > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // If there is PCI access right after the PSF hide device, the device = might > + // still be accessible since the PSF cycle is not completed yet, and c= auses > + // the race condition between sideband and primary cycles. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS, > + ~0u, > + B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS > + ); > +} > + > +/** > + Unhide PciCfgSpace of device at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfUnhideDevice ( > + IN PSF_PORT PsfPort > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS, > + (UINT32) ~(B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS), > + 0 > + ); > +} > + > +/** > + Disable device BARs at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > + @param[in] BarDisMask BIT0-BAR0, BIT1-BAR1,... > + Mask corresponds to 32bit wide BARs > +**/ > +VOID > +PsfDisableDeviceBar ( > + IN PSF_PORT PsfPort, > + IN UINT32 BarDisMask > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // BAR0-5 supported > + // > + ASSERT (BarDisMask < BIT6); > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN, > + ~0u, > + BarDisMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS > + ); > +} > + > +/** > + Enable device BARs at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > + @param[in] BarEnMask BIT0-BAR0, BIT1-BAR1,... > + Mask corresponds to 32bit wide BARs > +**/ > +VOID > +PsfEnableDeviceBar ( > + IN PSF_PORT PsfPort, > + IN UINT32 BarEnMask > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // BAR0-5 supported > + // > + ASSERT (BarEnMask < BIT6); > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN, > + (UINT32)~(BarEnMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS), > + 0 > + ); > +} > + > +/** > + Disable device IOSpace at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfDisableDeviceIoSpace ( > + IN PSF_PORT PsfPort > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN, > + ~(UINT32)(B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN), > + 0 > + ); > +} > + > +/** > + Enable device IOSpace at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > +**/ > +VOID > +PsfEnableDeviceIoSpace ( > + IN PSF_PORT PsfPort > + ) > +{ > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN, > + ~0u, > + B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN > + ); > +} > + > +/** > + Set device BARx address at PSF level > + Method not for bridges (e.g. PCIe Root Port) > + > + @param[in] PsfPort PSF PORT data structure > + @param[in] BarNum BAR Number (0:BAR0, 1:BAR1, ...) > + @param[in] BarValue 32bit BAR value > +**/ > +VOID > +PsfSetDeviceBarValue ( > + IN PSF_PORT PsfPort, > + IN UINT8 BarNum, > + IN UINT32 BarValue > + ) > +{ > + ASSERT (BarNum < 6); > + > + if (PSF_IS_PORT_NULL (PsfPort)) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Read back is needed to enforce the sideband and primary ordering. > + // > + PchPcrAndThenOr32WithReadback ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0 + BarNum * 0x4, > + 0, > + BarValue > + ); > +} > + > +/** > + Hide PMC device at PSF level > +**/ > +VOID > +PsfHidePmcDevice ( > + VOID > + ) > +{ > + PsfHideDevice (PsfPmcPort ()); > +} > + > +/** > + Set PMC ABASE value in PSF > + > + @param[in] Address Address for ACPI base address. > +**/ > +VOID > +PsfSetPmcAbase ( > + IN UINT16 Address > + ) > +{ > + PSF_PORT PsfPort; > + > + PsfPort =3D PsfPmcPort (); > + > + ASSERT (PchPcrRead32 (PsfPort.PsfPid, PsfPort.RegBase + > R_PCH_PSFX_PCR_T0_SHDW_BAR4) !=3D 0xFFFFFFFF); > + > + // > + // Disable IOSpace before changing the address > + // > + PsfDisableDeviceIoSpace (PsfPort); > + > + // > + // Program ABASE in PSF PMC space BAR4 > + // > + PsfSetDeviceBarValue (PsfPort, 4, Address); > + > + // > + // Enable IOSpace > + // > + PsfEnableDeviceIoSpace (PsfPort); > +} > + > +/** > + Get PMC ABASE value from PSF > + > + @retval Address Address for ACPI base. > +**/ > +UINT16 > +PsfGetPmcAbase ( > + VOID > + ) > +{ > + UINT16 Address; > + PSF_PORT PsfPort; > + > + PsfPort =3D PsfPmcPort (); > + // > + // Read ABASE from PSF PMC space BAR4 > + // > + Address =3D PchPcrRead16 ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4 > + ); > + > + ASSERT (Address !=3D 0xFFFF); > + > + return Address; > +} > + > +/** > + Get PMC PWRMBASE value from PSF > + > + @retval Address Address for PWRM base. > +**/ > +UINT32 > +PsfGetPmcPwrmBase ( > + VOID > + ) > +{ > + UINT32 Address; > + PSF_PORT PsfPort; > + > + PsfPort =3D PsfPmcPort (); > + // > + // Read PWRMBASE from PSF PMC space BAR0 > + // > + Address =3D PchPcrRead32 ( > + PsfPort.PsfPid, > + PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0 > + ); > + > + ASSERT (Address !=3D 0xFFFFFFFF); > + > + return Address; > +} > + > +/** > + Get PSF SideBand Port ID from PSF ID (1 - PSF1, 2 - PSF2, ...) > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + > + @retval PSF SideBand Port ID > +**/ > +PCH_SBI_PID > +PsfSbPortId ( > + UINT32 PsfId > + ) > +{ > + UINT32 PsfTableIndex; > + PSF_SEGMENT *PsfTable; > + UINT32 PsfTableSize; > + > + PsfSegments (&PsfTable, &PsfTableSize); > + > + for (PsfTableIndex =3D 0; PsfTableIndex < PsfTableSize; PsfTableIndex+= +) { > + if (PsfTable[PsfTableIndex].Id =3D=3D PsfId) { > + return PsfTable[PsfTableIndex].SbPid; > + } > + } > + > + ASSERT (FALSE); > + return 0; > +} > + > + > +/** > + Get PCH Root PSF ID. This is the PSF segment to which OPDMI/DMI is > connected. > + > + @retval PsfId Root PSF ID > +**/ > +UINT32 > +PsfRootId ( > + VOID > + ) > +{ > + PSF_SEGMENT *PsfTable; > + UINT32 PsfTableSize; > + > + PsfSegments (&PsfTable, &PsfTableSize); > + > + return PsfTable[0].Id; > +} > + > +/** > + Add EOI Target in a given PSF > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + @param[in] TargetId EOI Target ID > +**/ > +STATIC > +VOID > +PsfAddEoiTarget ( > + UINT32 PsfId, > + PSF_PORT_DEST_ID TargetId > + ) > +{ > + UINT16 EoiTargetBase; > + UINT16 EoiControlBase; > + UINT8 NumOfEnabledTargets; > + UINT8 MaximalNumberOfTargets; > + PCH_SBI_PID PsfSbiPortId; > + UINT32 Data32; > + UINT8 TargetIndex; > + > + MaximalNumberOfTargets =3D PsfEoiRegData (PsfId, &EoiTargetBase, > &EoiControlBase); > + PsfSbiPortId =3D PsfSbPortId (PsfId); > + > + // > + // Get number of enabled agents from > PSF_x_PSF_MC_CONTROL_MCAST0_RS0_EOI register > + // > + Data32 =3D PchPcrRead32 (PsfSbiPortId, EoiControlBase); > + NumOfEnabledTargets =3D (UINT8) (Data32 >> > N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC); > + > + // > + // Check if target was not already enabled > + // Targets from a different PSF segment are aggregated into single > destination on > + // current PSF segment. > + // > + for (TargetIndex =3D 0; TargetIndex < NumOfEnabledTargets; TargetIndex= ++) { > + Data32 =3D PchPcrRead32 (PsfSbiPortId, EoiTargetBase + TargetIndex *= 4); > + // > + // If target already added don't add it again > + // > + if (Data32 =3D=3D TargetId.RegVal) { > + ASSERT (FALSE); > + return; > + } > + // > + // If target is from different PSF segment than currently being anal= yzed > + // it is enough that its PsfID is matching > + // > + if ((Data32 & B_PCH_PSFX_PCR_TARGET_PSFID) >> > N_PCH_PSFX_PCR_TARGET_PSFID =3D=3D TargetId.Fields.PsfId) { > + return; > + } > + } > + > + // > + // Check if next one can be added > + // > + if (NumOfEnabledTargets >=3D MaximalNumberOfTargets) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Add next target > + // Configure Multicast Destination ID register with target device on P= SF. > + // Configuration must be done in next available > PSF_MC_AGENT_MCAST0_RS0_TGT_EOI register > + // so that other targets are not overridden. is known from the nu= mber > of multicast agents > + // in Multicast Control Register. Value programmed is based on > + // PsfID, PortGroupID, PortID and ChannelID of the target > + // > + PchPcrWrite32 (PsfSbiPortId, EoiTargetBase + NumOfEnabledTargets * 4, > TargetId.RegVal); > + > + // > + // Enable new target > + // Configure PSF_x_PSF_MC_CONTROL_MCAST0_RS0_EOI, increase NumMc > and set MultCEn > + // > + NumOfEnabledTargets++; > + Data32 =3D (NumOfEnabledTargets << > N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC) | > B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN; > + PchPcrWrite32 (PsfSbiPortId, EoiControlBase, Data32); > +} > + > +/** > + Enable EOI Target > + > + @param[in] TargetId Target ID > +**/ > +STATIC > +VOID > +PsfEnableEoiTarget ( > + PSF_PORT_DEST_ID TargetId > + ) > +{ > + UINT32 RootLevelPsf; > + > + RootLevelPsf =3D PsfRootId (); > + > + // > + // Enable EOI target in root PSF > + // > + PsfAddEoiTarget (RootLevelPsf, TargetId); > + > + // > + // Enable EOI target on other PSF segment if target > + // is not located on root PSF > + // > + if (TargetId.Fields.PsfId !=3D RootLevelPsf) { > + PsfAddEoiTarget (TargetId.Fields.PsfId, TargetId); > + } > +} > + > +/** > + This function enables EOI message forwarding in PSF for PCIe ports > + for cases where IOAPIC is present behind this root port. > + > + @param[in] RpIndex Root port index (0 based) > + > + @retval Status > +**/ > +EFI_STATUS > +PsfConfigurEoiForPciePort ( > + IN UINT32 RpIndex > + ) > +{ > + ASSERT (RpIndex < GetPchMaxPciePortNum ()); > + > + // > + // If there is an IOAPIC discovered behind root port program PSF Multi= cast > registers > + // accordingly to PCH BWG PSF EOI Multicast Configuration > + // Since there is a device behind RootPort to which EOI needs to be > forwarded > + // enable multicast (MULTCEN) and increase the number of multicast age= nts > (NUMMC) > + // in Multicast Control Register. > + // > + PsfEnableEoiTarget (PsfPcieDestinationId (RpIndex)); > + > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibCnl.c > new file mode 100644 > index 0000000000..d1c87a9e84 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfP= r > ivateLib/PchPsfPrivateLibCnl.c > @@ -0,0 +1,338 @@ > +/** @file > + This file contains internal PSF routines for PCH PSF lib usage > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "PchPsfPrivateLibInternal.h" > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cPsfRegs[] =3D > +{ > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoI2cPsfRegs[] =3D > +{ > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE > +}; > + > +/** > + Return PSF_PORT for SerialIO I2C device > + > + @param[in] I2cNum Serial IO I2C device (I2C0, I2C1, ....) > + > + @retval PsfPort PSF PORT structure for SerialIO I2C device > +**/ > +PSF_PORT > +PsfSerialIoI2cPort ( > + IN UINT32 I2cNum > + ) > +{ > + PSF_PORT PsfPort; > + > + PsfPort.PsfPid =3D PID_PSF3; > + > + if (IsPchLp ()) { > + if (I2cNum < ARRAY_SIZE(mPchLpSerialIoI2cPsfRegs)) { > + PsfPort.RegBase =3D mPchLpSerialIoI2cPsfRegs[I2cNum]; > + return PsfPort; > + } > + } else { > + if (I2cNum < ARRAY_SIZE(mPchHSerialIoI2cPsfRegs)) { > + PsfPort.RegBase =3D mPchHSerialIoI2cPsfRegs[I2cNum]; > + return PsfPort; > + } > + } > + > + ASSERT(FALSE); > + return PSF_PORT_NULL; > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiPsfRegs[] =3D > +{ > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoSpiPsfRegs[] =3D > +{ > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE > +}; > + > +/** > + Return PSF_PORT for SerialIO SPI device > + > + @param[in] SpiNum Serial IO SPI device (SPI0, SPI1, ....) > + > + @retval PsfPort PSF PORT structure for SerialIO SPI device > +**/ > +PSF_PORT > +PsfSerialIoSpiPort ( > + IN UINT32 SpiNum > + ) > +{ > + PSF_PORT PsfPort; > + > + PsfPort.PsfPid =3D PID_PSF3; > + > + if (IsPchLp ()) { > + if (SpiNum < ARRAY_SIZE(mPchLpSerialIoSpiPsfRegs)) { > + PsfPort.RegBase =3D mPchLpSerialIoSpiPsfRegs[SpiNum]; > + return PsfPort; > + } > + } else { > + if (SpiNum < ARRAY_SIZE(mPchHSerialIoSpiPsfRegs)) { > + PsfPort.RegBase =3D mPchHSerialIoSpiPsfRegs[SpiNum]; > + return PsfPort; > + } > + } > + > + ASSERT(FALSE); > + return PSF_PORT_NULL; > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartPsfRegs[] =3D > +{ > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE, > + R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoUartPsfRegs[] =3D > +{ > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE, > + R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE > +}; > + > +/** > + Return PSF_PORT for SerialIO UART device > + > + @param[in] UartNum Serial IO UART device (UART0, UART1, ....) > + > + @retval PsfPort PSF PORT structure for SerialIO UART device > +**/ > +PSF_PORT > +PsfSerialIoUartPort ( > + IN UINT32 UartNum > + ) > +{ > + PSF_PORT PsfPort; > + > + PsfPort.PsfPid =3D PID_PSF3; > + > + if (IsPchLp ()) { > + if (UartNum < ARRAY_SIZE(mPchLpSerialIoUartPsfRegs)) { > + PsfPort.RegBase =3D mPchLpSerialIoUartPsfRegs[UartNum]; > + return PsfPort; > + } > + } else { > + if (UartNum < ARRAY_SIZE(mPchHSerialIoUartPsfRegs)) { > + PsfPort.RegBase =3D mPchHSerialIoUartPsfRegs[UartNum]; > + return PsfPort; > + } > + } > + > + ASSERT(FALSE); > + return PSF_PORT_NULL; > +} > + > +/** > + Get EOI register data for given PSF ID > + > + @param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...) > + @param[out] EoiTargetBase EOI Target register > + @param[out] EoiControlBase EOI Control register > + > + @retval MaxTargets Number of supported targets > + > +**/ > +UINT8 > +PsfEoiRegData ( > + UINT32 PsfId, > + UINT16 *EoiTargetBase, > + UINT16 *EoiControlBase > + ) > +{ > + UINT8 MaxTargets; > + > + MaxTargets =3D 0; > + *EoiTargetBase =3D 0; > + *EoiControlBase =3D 0; > + > + switch (PsfId) { > + case 1: > + if (IsPchLp ()) { > + *EoiTargetBase =3D > R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 17; > + } else { > + *EoiTargetBase =3D > R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 7; > + } > + break; > + > + case 3: > + *EoiTargetBase =3D > R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 1; > + break; > + > + case 6: > + if (IsPchH ()) { > + *EoiTargetBase =3D > R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 8; > + } > + break; > + > + case 7: > + if (IsPchH ()) { > + *EoiTargetBase =3D > R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 8; > + } > + break; > + > + case 8: > + if (IsPchH ()) { > + *EoiTargetBase =3D > R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI; > + *EoiControlBase =3D > R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI; > + MaxTargets =3D 8; > + } > + break; > + } > + return MaxTargets; > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =3D > +{ > + {0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID =3D 0 > + {0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPB: PSF1, PortID =3D 2 > + {0x18400}, {0x18401}, {0x18402}, {0x18403}, // SPC: PSF1, PortID =3D 4 > + {0x18600}, {0x18601}, {0x18602}, {0x18603} // SPD: PSF1, PortID =3D 6 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchHRpDestId[] =3D > +{ > + {0x68000}, {0x68001}, {0x68002}, {0x68003}, // SPA: PSF6, PortID =3D 0 > + {0x88000}, {0x88001}, {0x88002}, {0x88003}, // SPB: PSF8, PortID =3D 0 > + {0x68100}, {0x68101}, {0x68102}, {0x68103}, // SPC: PSF6, PortID =3D 1 > + {0x78000}, {0x78001}, {0x78002}, {0x78003}, // SPD: PSF7, PortID =3D 0 > + {0x78100}, {0x78101}, {0x78102}, {0x78103}, // SPE: PSF7, PortID =3D 1 > + {0x88100}, {0x88101}, {0x88102}, {0x88103} // SPF: PSF8, PortID =3D 1 > +}; > + > +/** > + PCIe PSF port destination ID (psf_id:port_group_id:port_id:channel_id) > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > + > + @retval Destination ID > +**/ > +PSF_PORT_DEST_ID > +PsfPcieDestinationId ( > + IN UINT32 RpIndex > + ) > +{ > + if (IsPchLp ()) { > + if (RpIndex < ARRAY_SIZE(PchLpRpDestId)) { > + return PchLpRpDestId[RpIndex]; > + } > + } else { > + if (RpIndex < ARRAY_SIZE(PchHRpDestId)) { > + return PchHRpDestId[RpIndex]; > + } > + } > + ASSERT (FALSE); > + return (PSF_PORT_DEST_ID){0}; > +} > + > + > +/** > + Return PSF_PORT for PMC device > + > + @retval PsfPort PSF PORT structure for PMC device > +**/ > +PSF_PORT > +PsfPmcPort ( > + VOID > + ) > +{ > + PSF_PORT PsfPort; > + > + PsfPort.PsfPid =3D PID_PSF3; > + > + if (IsPchLp ()) { > + PsfPort.RegBase =3D R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE; > + } else { > + PsfPort.RegBase =3D R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE; > + } > + return PsfPort; > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =3D > +{ > + {1, PID_PSF1}, > + {2, PID_PSF2}, > + {3, PID_PSF3}, > + {4, PID_PSF4}, > + {5, PID_CSME_PSF} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchHPsfTable[] =3D > +{ > + {1, PID_PSF1}, > + {2, PID_PSF2}, > + {3, PID_PSF3}, > + {4, PID_PSF4}, > + {5, PID_CSME_PSF}, > + {6, PID_PSF6}, > + {7, PID_PSF7}, > + {8, PID_PSF8} > +}; > + > +/** > + Get list of supported PSF segments. > + > + @param[out] PsfTable Array of supported PSF segments > + @param[out] PsfTableLength Length of PsfTable > +**/ > +VOID > +PsfSegments ( > + OUT PSF_SEGMENT **PsfTable, > + OUT UINT32 *PsfTableLength > + ) > +{ > + if (IsPchLp ()) { > + *PsfTable =3D mPchLpPsfTable; > + *PsfTableLength =3D ARRAY_SIZE(mPchLpPsfTable); > + } else { > + *PsfTable =3D mPchHPsfTable; > + *PsfTableLength =3D ARRAY_SIZE(mPchHPsfTable); > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLib.c > new file mode 100644 > index 0000000000..f88febfa48 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PeiPmcPrivateLib.c > @@ -0,0 +1,92 @@ > +/** @file > + PCH private PEI PMC Library for all PCH generations. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "PmcPrivateLibInternal.h" > + > +/** > + Check if PCH PM Timer enabled based on platform policy > + > + @retval TRUE PCH PM Timer is enabled. > + @retval FALSE PCH PM Timer is disabled. > +**/ > +BOOLEAN > +PmcIsPchPmTimerEnabled ( > + VOID > + ) > +{ > + BOOLEAN PchPmTimerEnabled; > + EFI_STATUS Status; > + SI_POLICY_PPI *SiPolicy; > + PCH_PM_CONFIG *PmConfig; > + > + Status =3D PeiServicesLocatePpi ( > + &gSiPolicyPpiGuid, > + 0, > + NULL, > + (VOID **)&SiPolicy > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) > &PmConfig); > + ASSERT_EFI_ERROR (Status); > + > + PchPmTimerEnabled =3D TRUE; > + if (!PmConfig->EnableTcoTimer) { > + PchPmTimerEnabled =3D FALSE; > + } > + > + DEBUG ((DEBUG_INFO, "PmcIsPchPmTimerEnabled () =3D %x\n", > PchPmTimerEnabled)); > + > + return PchPmTimerEnabled; > +} > + > +/** > + Lock down PMC settings > + > + @param[in] SiPolicy The SI Policy PPI instance > +**/ > +VOID > +PmcLockSettings ( > + IN SI_POLICY_PPI *SiPolicy > + ) > +{ > + > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + /// > + /// Set PWRMBASE Offset 0x1048 [24] > + /// > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_ETR3, BIT24); > + > + /// > + /// PM_SYNC_LOCK > + /// Set PWRMBASE Offset 0x18C8 [15] > + /// > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_PMSYNC_MISC_CFG, > B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLib.c > new file mode 100644 > index 0000000000..a6ccf4b96b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLib.c > @@ -0,0 +1,1033 @@ > +/** @file > + PCH private PMC Library for all PCH generations. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PmcPrivateLibInternal.h" > + > +/** > + Send PMC IPC1 Normal Read/Write command > + > + @param[in] Command Command to be issued to PMC IPC 1 > interface > + @param[in] SubCmdId SUB_CMD_ID for provided Command > + @param[in] CmdSize Total size in byte to be sent via PMC IP= C 1 > interface > + @param[in] WriteBufPtr Pointer to Structure of 4 DWORDs to be > issued to PMC IPC 1 interface > + @param[out] ReadBufPtr Pointer to Structure of 4 DWORDs to be > filled by PMC IPC 1 interface > + > + @retval EFI_SUCCESS Command was executed successfully > + @retval EFI_INVALID_PARAMETER Invalid command size > + @retval EFI_DEVICE_ERROR IPC command failed with an error > + @retval EFI_TIMEOUT IPC command did not complete after 1s > +**/ > +EFI_STATUS > +PmcSendCommand ( > + IN UINT8 Command, > + IN UINT8 SubCmdId, > + IN UINT8 CmdSize, > + IN PMC_IPC_COMMAND_BUFFER *WriteBufPtr, > + OUT PMC_IPC_COMMAND_BUFFER *ReadBufPtr > + ) > +{ > + EFI_STATUS Status; > + UINT32 PchPwrmBase; > + UINT32 IpcSts; > + UINTN Timeout; > + > + DEBUG ((DEBUG_INFO, "PmcSendCommand(): IPC_COMMAND=3D0x%02X, > IPC_SUB_CMD =3D 0x%02X, IPC_SIZE=3D0x%02X \n", Command, SubCmdId, > CmdSize)); > + DEBUG ((DEBUG_INFO, "WBUF0=3D0x%08X, WBUF1=3D0x%08X, WBUF2=3D0x%08X, > WBUF3=3D0x%08X \n", WriteBufPtr->Buf0, WriteBufPtr->Buf1, > WriteBufPtr->Buf2, WriteBufPtr->Buf3)); > + > + if (CmdSize > 16) { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Program the Write Buffer 0 with the Data that needs to be written t= o PMC > + // > + PchPwrmBase =3D PmcGetPwrmBase (); > + MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF0), > WriteBufPtr->Buf0); > + MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF1), > WriteBufPtr->Buf1); > + MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF2), > WriteBufPtr->Buf2); > + MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF3), > WriteBufPtr->Buf3); > + // > + // Program the command register with command and size > + // > + MmioWrite32 ( > + PchPwrmBase + R_PMC_PWRM_IPC_CMD, > + (UINT32) ((CmdSize << N_PMC_PWRM_IPC_CMD_SIZE) | > + (SubCmdId << N_PMC_PWRM_IPC_CMD_CMD_ID) | > + (Command << N_PMC_PWRM_IPC_CMD_COMMAND)) > + ); > + > + // > + // Read the IPC_STS register to get BUSY or Error status > + // > + Timeout =3D 0; > + Status =3D EFI_SUCCESS; > + while (TRUE) { > + IpcSts =3D MmioRead32 (PchPwrmBase + R_PMC_PWRM_IPC_STS); > + if ((IpcSts & B_PMC_PWRM_IPC_STS_BUSY) =3D=3D 0) { > + break; > + } > + > + if (Timeout > (1000 * 100)) { > + Status =3D EFI_TIMEOUT; > + break; > + } > + MicroSecondDelay (10); > + Timeout++; > + } > + > + if ((IpcSts & B_PMC_PWRM_IPC_STS_ERROR) !=3D 0) { > + Status =3D EFI_DEVICE_ERROR; > + } > + > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "PmcSendCommand() Error: IPC_STS=3D0x%08X\n", > IpcSts)); > + return Status; > + } > + > + if (ReadBufPtr !=3D NULL) { > + // > + // Fill the ReadBuffer contents with the Data that needs to be read= from > PMC > + // > + ReadBufPtr->Buf0 =3D MmioRead32(PchPwrmBase + > R_PMC_PWRM_IPC_RBUF0); > + ReadBufPtr->Buf1 =3D MmioRead32(PchPwrmBase + > R_PMC_PWRM_IPC_RBUF1); > + ReadBufPtr->Buf2 =3D MmioRead32(PchPwrmBase + > R_PMC_PWRM_IPC_RBUF2); > + ReadBufPtr->Buf3 =3D MmioRead32(PchPwrmBase + > R_PMC_PWRM_IPC_RBUF3); > + > + DEBUG ((DEBUG_INFO, "RBUF0=3D0x%08X, RBUF1=3D0x%08X, RBUF2=3D0x%08X, > RBUF3=3D0x%08X \n", ReadBufPtr->Buf0, ReadBufPtr->Buf1, ReadBufPtr->Buf2, > ReadBufPtr->Buf3)); > + } > + > + return Status; > +} > + > +/** > + This function checks if SCI interrupt is enabled > + > + @retval SCI Enable state > +**/ > +BOOLEAN > +PmcIsSciEnabled ( > + VOID > + ) > +{ > + return ((IoRead8 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT) & > B_ACPI_IO_PM1_CNT_SCI_EN) !=3D 0); > +} > + > +/** > + This function triggers Software GPE > +**/ > +VOID > +PmcTriggerSwGpe ( > + VOID > + ) > +{ > + IoOr32 (PmcGetAcpiBase () + R_ACPI_IO_GPE_CNTL, > B_ACPI_IO_GPE_CNTL_SWGPE_CTRL); > +} > + > +/** > + Set PCH ACPI base address. > + The Address should not be 0 and should be 256 bytes aligned. It is IO = space, > so must not exceed 0xFFFF. > + Only address matching PcdAcpiBaseAddress is the acceptable value for A= CPI > IO Base > + > + @param[in] Address Address for ACPI base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PmcSetAcpiBase ( > + IN UINT16 Address > + ) > +{ > + > + if (Address !=3D PcdGet16 (PcdAcpiBaseAddress)) { > + DEBUG ((DEBUG_ERROR, "PmcSetAcpiBase Error. Invalid Address: %x.\n", > Address)); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + PsfSetPmcAbase (Address); > + return EFI_SUCCESS; > +} > + > +/** > + Set PCH PWRM base address. > + Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for > PWRMBASE > + > + @param[in] Address Address for PWRM base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PmcSetPwrmBase ( > + IN UINT32 Address > + ) > +{ > + UINT64 PmcBase; > + > + if (Address !=3D PCH_PWRM_BASE_ADDRESS) { > + DEBUG ((DEBUG_ERROR, "PmcSetPwrmBase Error. Invalid Address: %x.\n", > Address)); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + PmcBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_PMC, > + PCI_FUNCTION_NUMBER_PCH_PMC, > + 0 > + ); > + if (PciSegmentRead16 (PmcBase) =3D=3D 0xFFFF) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + // > + // Disable PWRMBASE in PMC Device first before changing PWRM base > address. > + // > + PciSegmentAnd16 ( > + PmcBase + PCI_COMMAND_OFFSET, > + (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE > + ); > + > + // > + // Program PWRMBASE in PMC Device > + // > + PciSegmentAndThenOr32 ( > + PmcBase + R_PMC_CFG_BASE, > + (UINT32) (~B_PMC_CFG_PWRM_BASE_MASK), > + Address > + ); > + > + // > + // Enable PWRMBASE in PMC Device > + // > + PciSegmentOr16 ( > + PmcBase + PCI_COMMAND_OFFSET, > + EFI_PCI_COMMAND_MEMORY_SPACE > + ); > + return EFI_SUCCESS; > +} > + > +/** > + This function checks if function disable (static and non-static power = gating) > + configuration is locked > + > + @retval lock state > +**/ > +BOOLEAN > +PmcIsFunctionDisableConfigLocked ( > + VOID > + ) > +{ > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_ST_PG_FDIS_PMC_1) & > B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK) !=3D 0); > +} > + > +/** > + Check if MODPHY SUS PG is supported > + > + @retval Status of MODPHY SUS PG support > +**/ > +BOOLEAN > +PmcIsModPhySusPgSupported ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + // > + // MPHY SUS PG supported on PCH-LP only: > + // > + return TRUE; > + } > + return FALSE; > +} > + > +/** > + This function checks if ISH is function disabled > + by static power gating > + > + @retval ISH device state > +**/ > +BOOLEAN > +PmcIsIshFunctionDisabled ( > + VOID > + ) > +{ > + // > + // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1 > + // > + return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & > B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC) !=3D 0); > +} > + > +/** > + This function checks if ISH device is supported (not disabled by fuse) > + > + @retval ISH support state > +**/ > +BOOLEAN > +PmcIsIshSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_DIS_RD_2 > + // > + return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2)) & > B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function disables ISH device by static power gating. > + For static power gating to take place Global Reset, G3 or DeepSx trans= ition > must happen. > +**/ > +VOID > +PmcStaticDisableIsh ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] =3D 1b to statically disable ISH > Controller > + // > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC); > +} > + > +/** > + This function enables ISH device by disabling static power gating. > + Static power gating disabling takes place after Global Reset, G3 or De= epSx > transition. > +**/ > +VOID > +PmcEnableIsh ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] =3D 0b to enable ISH controller > + // > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > (UINT32) (~B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC)); > +} > + > +/** > + This function checks if GbE is function disabled > + by static power gating > + > + @retval GbE device state > +**/ > +BOOLEAN > +PmcIsGbeFunctionDisabled ( > + VOID > + ) > +{ > + // > + // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1 > + // > + return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & > B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC) !=3D 0); > +} > + > +/** > + This function disables GbE device by static power gating and enables > ModPHY SPD gating (PCH-LP only). > + For static power gating to take place Global Reset, G3 or DeepSx trans= ition > must happen. > +**/ > +VOID > +PmcStaticDisableGbe ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] =3D 1b to statically disable GbE > Controller > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set MSPDRTREQ: > + // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[13] =3D 1 to enable ASL code > trigger request for ModPHY SPD gating. > + // > + PmcGbeModPhyPowerGating (); > + } > +} > + > +/** > + This function enables GbE device by disabling static power gating. > + Static power gating disabling takes place after Global Reset, G3 or De= epSx > transition. > +**/ > +VOID > +PmcEnableGbe ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] =3D 0b to enable GbE controller > + // > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC); > +} > + > +/** > + This function checks if GbE device is supported (not disabled by fuse) > + > + @retval GbE support state > +**/ > +BOOLEAN > +PmcIsGbeSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function disables (non-static power gating) HDA device > +**/ > +VOID > +PmcDisableHda ( > + VOID > + ) > +{ > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, > B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC); > +} > + > +/** > + This function checks if Cnvi device is supported (not disabled by fuse= ) > + > + @retval Cnvi support state > +**/ > +BOOLEAN > +PmcIsCnviSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_CNVI_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function checks if CNVi is function disabled > + by static power gating > + > + @retval GbE device state > +**/ > +BOOLEAN > +PmcIsCnviFunctionDisabled ( > + VOID > + ) > +{ > + // > + // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_ST_PG_FDIS_PMC_1) & > B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC) !=3D 0); > +} > + > +/** > + This function enables CNVi device by disabling static power gating. > + Static power gating disabling takes place after Global Reset, G3 or De= epSx > transition. > +**/ > +VOID > +PmcEnableCnvi ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_1 to enable CNVi controller > + // > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC); > +} > + > +/** > + This function disables CNVi device by static power gating. > + For static power gating to take place Global Reset, G3 or DeepSx trans= ition > must happen. > +**/ > +VOID > +PmcStaticDisableCnvi ( > + VOID > + ) > +{ > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, > B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC); > +} > + > +/** > + This function disables (non-static power gating) PCIe Root Port and en= ables > ModPHY SPD gating (PCH-LP only). > + > + @param[in] RpIndex PCIe Root Port Index (0 based) > +**/ > +VOID > +PmcDisablePcieRootPort ( > + IN UINT32 RpIndex > + ) > +{ > + UINT32 NstPgFdis1Mask; > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + // > + // Set PchPwrmBase + NST_PG_FDIS_1 to function disable PCIE port in PM= C > + // > + if (IsPchH () && RpIndex >=3D 20) { > + NstPgFdis1Mask =3D > B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC << (RpIndex % > 20); > + } else { > + NstPgFdis1Mask =3D B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC > << RpIndex; > + } > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, > NstPgFdis1Mask); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set MSPDRTREQ: > + // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[26:0] =3D 1 to enable ASL > code trigger request for ModPHY SPD gating. > + // > + if (RpIndex <=3D 11) { > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0 << RpIndex); > + } else { > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0 << (RpIndex - 12)); > + } > + } > +} > + > +/** > + This function disables (non-static power gating) xHCI and enables ModP= HY > SPD gating (PCH-LP only). > +**/ > +VOID > +PmcDisableXhci ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 [0] =3D 1b > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, > B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set MSPDRTREQ: > + // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[14] =3D 1 to enable ASL > code trigger request for ModPHY SPD gating. > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI); > + } > +} > + > +/** > + This function disables (non-static power gating) XDCI and enables ModP= HY > SPD gating (PCH-LP only). > +**/ > +VOID > +PmcDisableXdci ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 [26] =3D 1b to disable XDCI Controller= in > PMC > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, > B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set MSPDRTREQ: > + // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[15] =3D 1 to enable ASL code > trigger request for ModPHY SPD gating. > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI); > + } > +} > + > +/** > + This function checks if XDCI device is supported (not disabled by fuse= ) > + > + @retval XDCI support state > +**/ > +BOOLEAN > +PmcIsXdciSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function locks HOST SW power gating control > +**/ > +VOID > +PmcLockHostSwPgCtrl ( > + VOID > + ) > +{ > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1, > B_PMC_PWRM_SW_PG_CTRL_LOCK); > +} > + > +/** > + This function checks if HOST SW Power Gating Control is locked > + > + @retval lock state > +**/ > +BOOLEAN > +PmcIsHostSwPgCtrlLocked ( > + VOID > + ) > +{ > + // > + // Get lock info from PWRMBASE + HSWPGCR1 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1) > & B_PMC_PWRM_SW_PG_CTRL_LOCK) !=3D 0); > +} > + > +/** > + This function checks if LAN wake from DeepSx is enabled > + > + @retval Lan Wake state > +**/ > +BOOLEAN > +PmcIsLanDeepSxWakeEnabled ( > + VOID > + ) > +{ > + // > + // Get wake info from PWRMBASE + DSX_CFG > + // > + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_DSX_CFG) & > (UINT32) B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN) !=3D 0); > +} > + > +/** > + Disables USB2 Core PHY PowerGating during power on for Chipsetinit tab= le > update > +**/ > +VOID > +PmcUsb2CorePhyPowerGatingDisable ( > + VOID > + ) > +{ > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG, (UINT32) > ~B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG); > +} > + > + > +/** > + This function reads CPU Early Power-on Configuration (EPOC) > + > + @retval CPU EPOC value > +**/ > +UINT32 > +PmcGetCpuEpoc ( > + VOID > + ) > +{ > + return MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC); > +} > + > +/** > + This function sets CPU Early Power-on Configuration (EPOC) > + > + @param[in] CpuEpocValue CPU EPOC value > +**/ > +VOID > +PmcSetCpuEpoc ( > + IN UINT32 CpuEpocValue > + ) > +{ > + MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC, > CpuEpocValue); > +} > + > +/** > + This function sets DRAM_RESET# Control Pin value > + > + @param[in] DramResetVal 0: Pin output is low > + 1: Pin output is tri-stated > +**/ > +VOID > +PmcSetDramResetCtlState ( > + IN UINT32 DramResetVal > + ) > +{ > + ASSERT (DramResetVal < 2); > + > + MmioAndThenOr32 ( > + PmcGetPwrmBase () + R_PMC_PWRM_CFG2, > + (UINT32)~B_PMC_PWRM_CFG2_DRAM_RESET_CTL, > + DramResetVal << N_PMC_PWRM_CFG2_DRAM_RESET_CTL > + ); > +} > + > +/** > + This function enables triggering Global Reset of both > + the Host and the ME partitions after CF9h write of 6h or Eh > +**/ > +VOID > +PmcEnableCf9GlobalReset ( > + VOID > + ) > +{ > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) > (B_PMC_PWRM_ETR3_CF9GR)); > +} > + > +/** > + This function disables triggering Global Reset of both > + the Host and the ME partitions after CF9h write of 6h or Eh. > +**/ > +VOID > +PmcDisableCf9GlobalReset ( > + VOID > + ) > +{ > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) > ~B_PMC_PWRM_ETR3_CF9GR); > +} > + > +/** > + This function disables triggering Global Reset of both > + the Host and the ME partitions after CF9h write of 6h or Eh. > + Global Reset configuration is locked after programming > +**/ > +VOID > +PmcDisableCf9GlobalResetWithLock ( > + VOID > + ) > +{ > + MmioAndThenOr32 ( > + PmcGetPwrmBase () + R_PMC_PWRM_ETR3, > + (UINT32) ~B_PMC_PWRM_ETR3_CF9GR, > + (UINT32) B_PMC_PWRM_ETR3_CF9LOCK > + ); > +} > + > +/** > + This function disables CF9 reset without Resume Well reset. > + Cf9 0x6/0xE reset will also reset resume well logic. > +**/ > +VOID > +PmcDisableCf9ResetWithoutResumeWell ( > + VOID > + ) > +{ > + > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) > ~B_PMC_PWRM_ETR3_CWORWRE); > +} > + > +/** > + This function clears RTC Power Failure status (RTC_PWR_FLR) > +**/ > +VOID > +PmcClearRtcPowerFailureStatus ( > + VOID > + ) > +{ > + // > + // Set B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS to 0 to clear it. > + // > + MmioAnd8 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_B), (UINT8) > (~B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS)); > +} > + > +/** > + This function enables PCI Express* PME events > +**/ > +VOID > +PmcEnablePciExpressPmeEvents ( > + VOID > + ) > +{ > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B, > B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN); > +} > + > +/** > + This function sets eSPI SMI Lock > +**/ > +VOID > +PmcLockEspiSmi ( > + VOID > + ) > +{ > + MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A > + 1, > + (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | > B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8), > + B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8 > + ); > +} > + > +/** > + This function checks if eSPI SMI Lock is set > + > + @retval eSPI SMI Lock state > +**/ > +BOOLEAN > +PmcIsEspiSmiLockSet ( > + VOID > + ) > +{ > + return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_A)) & > B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK) !=3D 0); > +} > + > +/** > + This function sets SW SMI Rate. > + > + @param[in] SwSmiRate Refer to PMC_SWSMI_RATE for possible > values > +**/ > +VOID > +PmcSetSwSmiRate ( > + IN PMC_SWSMI_RATE SwSmiRate > + ) > +{ > + UINT32 PchPwrmBase; > + STATIC UINT8 SwSmiRateRegVal[4] =3D { > + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_1_5MS, > + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_16MS, > + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_32MS, > + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_64MS > + }; > + > + ASSERT (SwSmiRate <=3D PmcSwSmiRate64ms); > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + // > + // SWSMI_RATE_SEL BIT (PWRMBASE offset 1020h[7:6]) bits are in RTC wel= l > + // > + MmioAndThenOr8 ( > + PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, > + (UINT8)~B_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL, > + SwSmiRateRegVal[SwSmiRate] > + ); > +} > + > +/** > + This function sets Periodic SMI Rate. > + > + @param[in] PeriodicSmiRate Refer to PMC_PERIODIC_SMI_RATE for > possible values > +**/ > +VOID > +PmcSetPeriodicSmiRate ( > + IN PMC_PERIODIC_SMI_RATE PeriodicSmiRate > + ) > +{ > + UINT32 PchPwrmBase; > + STATIC UINT8 PeriodicSmiRateRegVal[4] =3D { > + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_8S, > + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_16S, > + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_32S, > + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_64S > + }; > + > + ASSERT (PeriodicSmiRate <=3D PmcPeriodicSmiRate64s); > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + MmioAndThenOr8 ( > + PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, > + (UINT8)~B_PMC_PWRM_GEN_PMCON_A_PER_SMI_SEL, > + PeriodicSmiRateRegVal[PeriodicSmiRate] > + ); > +} > + > +/** > + This function reads Power Button Level > + > + @retval State of PWRBTN# signal (0: Low, 1: High) > +**/ > +UINT8 > +PmcGetPwrBtnLevel ( > + VOID > + ) > +{ > + if (MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B) & > B_PMC_PWRM_GEN_PMCON_B_PWRBTN_LVL) { > + return 1; > + } else { > + return 0; > + } > +} > + > +/** > + This function gets Group to GPE0 configuration > + > + @param[out] GpeDw0Value GPIO Group to GPE_DW0 assignment > + @param[out] GpeDw1Value GPIO Group to GPE_DW1 assignment > + @param[out] GpeDw2Value GPIO Group to GPE_DW2 assignment > +**/ > +VOID > +PmcGetGpioGpe ( > + OUT UINT32 *GpeDw0Value, > + OUT UINT32 *GpeDw1Value, > + OUT UINT32 *GpeDw2Value > + ) > +{ > + UINT32 Data32; > + > + Data32 =3D MmioRead32 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_GPIO_CFG)); > + > + *GpeDw0Value =3D ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW0) >> > N_PMC_PWRM_GPIO_CFG_GPE0_DW0); > + *GpeDw1Value =3D ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW1) >> > N_PMC_PWRM_GPIO_CFG_GPE0_DW1); > + *GpeDw2Value =3D ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW2) >> > N_PMC_PWRM_GPIO_CFG_GPE0_DW2); > +} > + > +/** > + This function sets Group to GPE0 configuration > + > + @param[out] GpeDw0Value GPIO Group to GPE_DW0 assignment > + @param[out] GpeDw1Value GPIO Group to GPE_DW1 assignment > + @param[out] GpeDw2Value GPIO Group to GPE_DW2 assignment > +**/ > +VOID > +PmcSetGpioGpe ( > + IN UINT32 GpeDw0Value, > + IN UINT32 GpeDw1Value, > + IN UINT32 GpeDw2Value > + ) > +{ > + UINT32 Data32Or; > + UINT32 Data32And; > + > + // > + // Program GPIO_CFG register > + // > + Data32And =3D (UINT32) ~(B_PMC_PWRM_GPIO_CFG_GPE0_DW2 | > B_PMC_PWRM_GPIO_CFG_GPE0_DW1 | > B_PMC_PWRM_GPIO_CFG_GPE0_DW0); > + Data32Or =3D (UINT32) ((GpeDw2Value << > N_PMC_PWRM_GPIO_CFG_GPE0_DW2) | > + (GpeDw1Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW1) > | > + (GpeDw0Value << > N_PMC_PWRM_GPIO_CFG_GPE0_DW0)); > + > + MmioAndThenOr32 ( > + (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG), > + Data32And, > + Data32Or > + ); > +} > + > +/** > + Disable SLP_S0# assertion when system is in debug mode > +**/ > +VOID > +PmcDisableSlpS0AssertionInDebugMode ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + > + Status =3D PmcSendCommand > (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + Enable SLP_S0# assertion even when system is in debug mode > +**/ > +VOID > +PmcEnableSlpS0AssertionInDebugMode ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + > + Wbuf.Buf0 =3D 1; > + Status =3D PmcSendCommand > (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function gets NMI regsiter. > + > + @retval NMI register setting > +**/ > +UINT32 > +PmcGetNmiControl ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + PMC_IPC_COMMAND_BUFFER Rbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + ZeroMem (&Rbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + // > + // WBUF0 =3D 2 for NMI delivery control and status register (entire re= gister > PCR[ITSS] 0x3330) > + // > + Wbuf.Buf0 =3D V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI; > + Status =3D PmcSendCommand ( > + V_PMC_PWRM_IPC_CMD_COMMAND_PROXY, > + V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ, > + 4, > + &Wbuf, > + &Rbuf > + ); > + ASSERT_EFI_ERROR (Status); > + return Rbuf.Buf0; > +} > + > +/** > + This function sets the NMI register > + > + @param[in] NmiRegister The whole NMI register > +**/ > +VOID > +PmcSetNmiControl ( > + UINT32 NmiRegister > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + // > + // WBUF0 =3D 2 for NMI delivery control and status register (entire re= gister > PCR[ITSS] 0x3330) > + // > + Wbuf.Buf0 =3D V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI; > + Wbuf.Buf1 =3D NmiRegister; > + Status =3D PmcSendCommand ( > + V_PMC_PWRM_IPC_CMD_COMMAND_PROXY, > + V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE, > + 8, > + &Wbuf, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function enables GBE ModPHY SPD gating. > +**/ > +VOID > +PmcGbeModPhyPowerGating ( > + VOID > + ) > +{ > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set B_PCH_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE ModPHY > SPD RT Request > + // > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE); > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibClient.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibClient.c > new file mode 100644 > index 0000000000..2411a2be23 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibClient.c > @@ -0,0 +1,73 @@ > +/** @file > + PCH PMC Private Library implementation for Cannon Lake PCH. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PmcPrivateLibInternal.h" > + > +/** > + This function disables (non-static power gating) SATA and enables ModP= HY > SPD gating (PCH-LP only). > + > + @param[in] SataCtrlIndex SATA controller index > +**/ > +VOID > +PmcDisableSata ( > + IN UINT32 SataCtrlIndex > + ) > +{ > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 [22] =3D 1b to disable SATA Controller= in > PMC > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, > B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // MPHY SUS PG supported on PCH-LP only: > + // > + // Set MSPDRTREQ: > + // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[12] =3D 1 to enable ASL code > trigger request for ModPHY SPD gating. > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA); > + } > +} > + > +/** > + This function checks if SATA device is supported (not disabled by fuse= ) > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA support state > +**/ > +BOOLEAN > +PmcIsSataSupported ( > + UINT32 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS) =3D=3D 0); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibCnl.c > new file mode 100644 > index 0000000000..847be42937 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibCnl.c > @@ -0,0 +1,360 @@ > +/** @file > + PCH PMC Private Library implementation for Cannon Lake PCH. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PmcPrivateLibInternal.h" > + > +/** > + This function disables Trace Hub by enabling power gating > +**/ > +VOID > +PmcDisableTraceHub ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + > + Wbuf.Buf0 =3D BIT0; > + Status =3D PmcSendCommand > (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function enables Trace Hub by disabling power gating > +**/ > +VOID > +PmcEnableTraceHub ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PMC_IPC_COMMAND_BUFFER Wbuf; > + > + ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER)); > + > + Wbuf.Buf0 =3D BIT1; > + Status =3D PmcSendCommand > (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function is part of PMC init and configures which clock wake sign= als > should > + set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent > up to the CPU/PCH > +**/ > +VOID > +PmcInitClockWakeEnable ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + if (IsPchLp () && (PchStepping () < PCH_B0)) { > + /// > + /// PWRMBASE + 0x1880 =3D 0x0 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, > 0x0); > + } else { > + /// > + /// PWRMBASE + 0x1880 =3D 0x2F8FBB01 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, > 0x2F8FBB01); > + } > + > + if (IsPchLp ()) { > + if (PchStepping () < PCH_B0) { > + /// > + /// PWRMBASE + 0x1884 =3D 0x0 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, > 0x0); > + } else { > + /// > + /// PWRMBASE + 0x1884 > + /// PCH-LP: 0x0280C7E1 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, > 0x0280C7E1); > + } > + } else { > + /// > + /// PWRMBASE + 0x1884 > + /// PCH-H: 0x0280D7E1 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, > 0x0280D7E1); > + } > + > + if (IsPchLp () && (PchStepping () < PCH_B0)) { > + /// > + /// PWRMBASE + 0x1888 =3D 0x0 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x0); > + /// > + /// PWRMBASE + 0x188C =3D 0x0 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0); > + } else { > + /// > + /// PWRMBASE + 0x1888 =3D 0x2F8FAB01 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x2F8FAB01); > + > + /// > + /// PWRMBASE + 0x188C > + /// PCH-LP: 0x0280C7E1 > + /// PCH-H: 0x0280D7E1 > + /// > + if (IsPchLp ()) { > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, > 0x0280C7E1); > + } else { > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, > 0x0280D7E1); > + } > + } > + > + if (IsPchLp () && (PchStepping () < PCH_B0)) { > + /// > + /// PWRMBASE + 0x1898 =3D 0x0 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, > 0x0); > + } else { > + /// > + /// PWRMBASE + 0x1898 =3D 0x00018000 > + /// > + MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, > 0x00018000); > + } > +} > + > +/** > + This function configures PWRMBASE + 0x1E00 register > +**/ > +VOID > +PmcConfigureRegPwrm1E00 ( > + VOID > + ) > +{ > + /// > + /// PWRMBASE + 0x1E00[31,30] =3D 1,1 > + /// PWRMBASE + 0x1E00[29] =3D 0 > + /// PWRMBASE + 0x1E00[10:6] =3D 0 > + /// PWRMBASE + 0x1E00[3:0] =3D 2 > + /// > + MmioAndThenOr32 ( > + PmcGetPwrmBase () + R_PMC_PWRM_1E00, > + (UINT32) ~(BIT29 | (0x1F << 6) | 0xF), > + BIT31 | BIT30 | 2 > + ); > +} > + > +/** > + This function configures Misc PM_SYNC events settings > +**/ > +VOID > +PmcConfigurePmSyncEventsSettings ( > + VOID > + ) > +{ > + /// > + /// PWRMBASE + 0x18C0 =3D 0x00000A20 > + /// > + MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_EN_MISC_EVENT, > 0x00000A20); > +} > + > +/** > + This function enables all SerailIo devices. > + Static power gating disabling takes place after Global Reset, G3 or De= epSx > transition. > +**/ > +VOID > +PmcEnableSerialIo ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_2 > + // > + MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, > (UINT32)~B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO); > +} > + > +/** > + This function disables (static power gating) all SerailIo devices. > + For SerialIo controllers they can be power gated only if all of them a= re to be > disabled. > + They cannot be statically power gated separately. > + For static power gating to take place Global Reset, G3 or DeepSx trans= ition > must happen. > +**/ > +VOID > +PmcStaticDisableSerialIo ( > + VOID > + ) > +{ > + // > + // Set PWRMBASE + ST_PG_FDIS_PMC_2 > + // > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, > B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO); > +} > + > +/** > + This function checks if all SerialIo devices are statically disabled (= static > power gating) > + > + @retval SerialIo disable state > +**/ > +BOOLEAN > +PmcIsSerialIoStaticallyDisabled ( > + VOID > + ) > +{ > + // > + // Check if all SerialIo controllers are statically disabled in PMC > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_ST_PG_FDIS_PMC_2) & > B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO) =3D=3D > B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO); > +} > + > +/** > + This function checks if SerialIo device is supported (not disabled by = fuse) > + > + @retval SerialIo support state > +**/ > +BOOLEAN > +PmcIsSerialIoSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function disables (non-static power gating) SCS eMMC controller a= nd > enables ModPHY SPD gating (PCH-LP only). > +**/ > +VOID > +PmcDisableScsEmmc ( > + VOID > + ) > +{ > + ASSERT (IsPchLp ()); > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC > + // > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, > B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC); > +} > + > +/** > + This function disables (non-static power gating) SCS SD Card controlle= r and > enables ModPHY SPD gating (PCH-LP only). > +**/ > +VOID > +PmcDisableScsSdCard ( > + VOID > + ) > +{ > + UINT32 ScsDevicePgMask; > + > + if (IsPchLp ()) { > + ScsDevicePgMask =3D > B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC; > + } else { > + ScsDevicePgMask =3D > B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC; > + } > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC > + // > + MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, > ScsDevicePgMask); > +} > + > +/** > + This function disables (non-static power gating) SCS UFS controller an= d > enables ModPHY SPD gating (PCH-LP only). > + > + @param[in] UfsNum SCS UFS Device > +**/ > +VOID > +PmcDisableScsUfs ( > + IN UINT32 UfsNum > + ) > +{ > + UINT32 PchPwrmBase; > + > + ASSERT ((UfsNum =3D=3D 0) && IsPchLp ()); > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + // > + // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, > B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC); > + > + if (PmcIsModPhySusPgSupported ()) { > + // > + // Set MSPDRTREQ: > + // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[16] =3D 1 to enable ASL > code trigger request for ModPHY SPD gating. > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, > B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2); > + } > +} > + > +/** > + This function checks if SCS eMMC device is supported (not disabled by = fuse) > + > + @retval SCS device support state > +**/ > +BOOLEAN > +PmcIsScsEmmcSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_EMMC_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function checks if SCS SD Card device is supported (not disabled = by fuse) > + > + @retval SCS device support state > +**/ > +BOOLEAN > +PmcIsScsSdCardSupported ( > + VOID > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_SDX_FUSE_SS_DIS) =3D=3D 0); > +} > + > +/** > + This function checks if SCS UFS device is supported (not disabled by f= use) > + > + @param[in] UfsNum SCS UFS Device > + > + @retval SCS device support state > +**/ > +BOOLEAN > +PmcIsScsUfsSupported ( > + IN UINT32 UfsNum > + ) > +{ > + // > + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 > + // > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_FUSE_DIS_RD_2) & > B_PMC_PWRM_FUSE_DIS_RD_2_UFSX2_FUSE_SS_DIS) =3D=3D 0); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibWithS3.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibWithS3.c > new file mode 100644 > index 0000000000..bbe944da5c > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv > ateLib/PmcPrivateLibWithS3.c > @@ -0,0 +1,194 @@ > +/** @file > + PCH private PMC Library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + This function locks down PMC (DebugModeLock) > +**/ > +VOID > +PmcLockWithS3BootScript ( > + VOID > + ) > +{ > + > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + // > + // Set PWRM_CFG[27] prior to OS. > + // > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_CFG, > B_PMC_PWRM_CFG_DBG_MODE_LOCK); > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint32, > + (PchPwrmBase + R_PMC_PWRM_CFG), > + 1, > + (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_CFG) > + ); > + > +} > + > +/** > + This S3 BootScript only function disables triggering Global Reset of b= oth > + the Host and the ME partitions after CF9h write of 6h or Eh. > +**/ > +VOID > +PmcDisableCf9GlobalResetInS3BootScript ( > + VOID > + ) > +{ > + UINT32 Data; > + > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + Data =3D MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3); > + > + Data &=3D (UINT32) ~B_PMC_PWRM_ETR3_CF9GR; > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint32, > + (UINTN) PchPwrmBase + > + R_PMC_PWRM_ETR3, > + 1, > + &Data > + ); > +} > + > +/** > + This S3 BootScript only function disables triggering Global Reset of b= oth > + the Host and the ME partitions after CF9h write of 6h or Eh. > + Global Reset configuration is locked after programming > +**/ > +VOID > +PmcDisableCf9GlobalResetWithLockInS3BootScript ( > + VOID > + ) > +{ > + UINT32 Data; > + > + UINT32 PchPwrmBase; > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + Data =3D MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3); > + > + Data &=3D (UINT32) ~B_PMC_PWRM_ETR3_CF9GR; > + Data |=3D (UINT32) B_PMC_PWRM_ETR3_CF9LOCK; > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint32, > + (UINTN) PchPwrmBase + > + R_PMC_PWRM_ETR3, > + 1, > + &Data > + ); > +} > + > +/** > + This function sets SLP_SX Stretching Policy and adds > + lock setting to S3 Boot Script > +**/ > +VOID > +PmcLockSlpSxStretchingPolicyWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + MmioOr8 ( > + (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2), > + (UINT8) ((B_PMC_PWRM_GEN_PMCON_B_SLPSX_STR_POL_LOCK) >> 16) > + ); > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2), > + 1, > + (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2) > + ); > +} > + > +/** > + This function sets SMI Lock with S3 Boot Script programming > +**/ > +VOID > +PmcLockSmiWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + MmioOr8 ((PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), > B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK); > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), > + 1, > + (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B) > + ); > +} > + > +/** > + This function locks static power gating configuration with S3 Boot Scr= ipt > programming > +**/ > +VOID > +PmcLockFunctionDisableConfigWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) > (B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK)); > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1), > + 1, > + (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1) > + ); > +} > + > +/** > + This function locks PMC Set Strap Message interface with S3 Boot Scrip= t > programming > +**/ > +VOID > +PmcLockSetStrapMsgInterfaceWithS3BootScript ( > + VOID > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + MmioOr32 ((UINTN) (PchPwrmBase + R_PMC_PWRM_SSML), > B_PMC_PWRM_SSML_SSL); > + > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML), > + 1, > + (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML) > + ); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.c > new file mode 100644 > index 0000000000..9c722bce07 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLi= b/ > PeiGpioHelpersLib.c > @@ -0,0 +1,356 @@ > +/** @file > + This file contains routines for PEI GPIO Helpers Lib > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +extern EFI_GUID gGpioLibUnlockHobGuid; > + > +// > +// GPIO Lock HOB > +// Stores information on GPIO pads that should be left unlocked > +// > +typedef struct { > + // > + // GPIO PadConfig unlock data > + // > + UINT32 PadConfig; > + // > + // GPIO Output unlock data > + // > + UINT32 OutputState; > +} GPIO_UNLOCK_HOB_DATA; > + > +/** > + This procedure will get index of GPIO Unlock HOB structure for selecte= d > GroupIndex and DwNum. > + > + @param[in] GroupIndex GPIO group index > + @param[in] DwNum DWORD index for a group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + > + @retval GpioUnlockHobIndex > +**/ > +STATIC > +UINT32 > +GpioUnlockDataIndex ( > + IN UINT32 GroupIndex, > + IN UINT32 DwNum > + ) > +{ > + UINT32 GpioUnlockDataIndex; > + UINT32 Index; > + > + GpioUnlockDataIndex =3D 0; > + > + for (Index =3D 0; Index < GroupIndex; Index++) { > + GpioUnlockDataIndex +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (GpioGetGroupFromGroupIndex (Index))) + 1; > + } > + > + GpioUnlockDataIndex +=3D DwNum; > + return GpioUnlockDataIndex; > +} > + > +/** > + This procedure will create GPIO HOB for storing unlock data > + > + @retval Pointer to GPIO Unlock data structure > +**/ > +STATIC > +GPIO_UNLOCK_HOB_DATA* > +GpioCreateUnlockData ( > + VOID > + ) > +{ > + VOID *HobData; > + GPIO_GROUP Group; > + GPIO_GROUP GroupMin; > + GPIO_GROUP GroupMax; > + UINT32 GpioUnlockDataRecords; > + > + GroupMin =3D GpioGetLowestGroup (); > + GroupMax =3D GpioGetHighestGroup (); > + GpioUnlockDataRecords =3D 0; > + > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { > + GpioUnlockDataRecords +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)) + 1; > + } > + > + HobData =3D BuildGuidHob (&gGpioLibUnlockHobGuid, > GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA)); > + if (HobData =3D=3D NULL) { > + return NULL; > + } > + > + ZeroMem (HobData, GpioUnlockDataRecords * sizeof > (GPIO_UNLOCK_HOB_DATA)); > + > + return (GPIO_UNLOCK_HOB_DATA*)HobData; > +} > + > +/** > + This procedure will Get GPIO Unlock data structure for storing unlock = data. > + If HOB doesn't exist it will be created. > + > + @param[out] GpioUnlockData pointer to GPIO Unlock data struct= ure > + > + @retval Length number of GPIO unlock data records > +**/ > +STATIC > +UINT32 > +GpioGetUnlockData ( > + GPIO_UNLOCK_HOB_DATA **GpioUnlockData > + ) > +{ > + VOID *Hob; > + > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); > + if (Hob =3D=3D NULL) { > + // > + // It is the first time this function is used so create the HOB > + // > + *GpioUnlockData =3D GpioCreateUnlockData (); > + if (*GpioUnlockData =3D=3D NULL) { > + return 0; > + } > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); > + } else { > + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA > (Hob); > + } > + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof > (GPIO_UNLOCK_HOB_DATA); > +} > + > +/** > + This procedure will get pointer to GPIO Unlock data structure. > + > + @param[out] GpioUnlockData pointer to GPIO Unlock data struct= ure > + > + @retval Length number of GPIO unlock data records > +**/ > +STATIC > +UINT32 > +GpioLocateUnlockData ( > + GPIO_UNLOCK_HOB_DATA **GpioUnlockData > + ) > +{ > + VOID *Hob; > + > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); > + if (Hob =3D=3D NULL) { > + *GpioUnlockData =3D NULL; > + return 0; > + } > + > + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA > (Hob); > + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof > (GPIO_UNLOCK_HOB_DATA); > +} > + > +/** > + This procedure stores GPIO pad unlock information > + > + @param[in] GpioPad GPIO pad > + @param[in] GpioLockConfig GPIO Lock Configuration > + > + @retval Status > +**/ > +EFI_STATUS > +GpioStoreUnlockData ( > + IN GPIO_PAD GpioPad, > + IN GPIO_LOCK_CONFIG GpioLockConfig > + ) > +{ > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; > + UINT32 Length; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + UINT32 Index; > + > + if (GpioLockConfig =3D=3D GpioLockDefault) { > + return EFI_SUCCESS; > + } > + > + Length =3D GpioGetUnlockData (&GpioUnlockData); > + if (Length =3D=3D 0) { > + return EFI_NOT_FOUND; > + } > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + Index =3D GpioUnlockDataIndex (GroupIndex, GPIO_GET_DW_NUM > (PadNumber)); > + > + if (Index >=3D Length) { > + return EFI_INVALID_PARAMETER; > + } > + > + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) =3D=3D > GpioPadConfigUnlock) { > + GpioUnlockData[Index].PadConfig |=3D 1 << > (GpioGetPadNumberFromGpioPad (GpioPad) % 32); > + } > + > + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D > GpioOutputStateUnlock) { > + GpioUnlockData[Index].OutputState |=3D 1 << > (GpioGetPadNumberFromGpioPad (GpioPad) % 32); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure stores GPIO group data about pads which PadConfig needs > to be unlocked. > + > + @param[in] GroupIndex GPIO group index > + @param[in] DwNum DWORD index for a group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked > + Bit position - PadNumber > + Bit value - 0: Skip, 1: Leave unlocked > + > + @retval Status > +**/ > +EFI_STATUS > +GpioStoreGroupDwUnlockPadConfigData ( > + IN UINT32 GroupIndex, > + IN UINT32 DwNum, > + IN UINT32 UnlockedPads > + ) > +{ > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; > + UINT32 Length; > + UINT32 Index; > + > + if (UnlockedPads =3D=3D 0) { > + // > + // No pads to be left unlocked > + // > + return EFI_SUCCESS; > + } > + > + Length =3D GpioGetUnlockData (&GpioUnlockData); > + if (Length =3D=3D 0) { > + return EFI_NOT_FOUND; > + } > + > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); > + if (Index >=3D Length) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioUnlockData[Index].PadConfig |=3D UnlockedPads; > + return EFI_SUCCESS; > +} > + > +/** > + This procedure stores GPIO group data about pads which Output state > needs to be unlocked. > + > + @param[in] GroupIndex GPIO group index > + @param[in] DwNum DWORD index for a group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked > + Bit position - PadNumber > + Bit value - 0: Skip, 1: Leave unlocked > + @retval Status > +**/ > +EFI_STATUS > +GpioStoreGroupDwUnlockOutputData ( > + IN UINT32 GroupIndex, > + IN UINT32 DwNum, > + IN UINT32 UnlockedPads > + ) > +{ > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; > + UINT32 Length; > + UINT32 Index; > + > + if (UnlockedPads =3D=3D 0) { > + // > + // No pads to be left unlocked > + // > + return EFI_SUCCESS; > + } > + > + Length =3D GpioGetUnlockData (&GpioUnlockData); > + if (Length =3D=3D 0) { > + return EFI_NOT_FOUND; > + } > + > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); > + if (Index >=3D Length) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioUnlockData[Index].OutputState |=3D UnlockedPads; > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO group data with pads, which PadConfig is > supposed to be left unlock > + > + @param[in] GroupIndex GPIO group index > + @param[in] DwNum DWORD index for a group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked > + Bit position - PadNumber > + Bit value - 0: to be locked, 1: Leave = unlocked > +**/ > +UINT32 > +GpioGetGroupDwUnlockPadConfigMask ( > + IN UINT32 GroupIndex, > + IN UINT32 DwNum > + ) > +{ > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; > + UINT32 Length; > + UINT32 Index; > + > + Length =3D GpioLocateUnlockData (&GpioUnlockData); > + if (Length =3D=3D 0) { > + return 0; > + } > + > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); > + if (Index >=3D Length) { > + return 0; > + } > + > + return GpioUnlockData[Index].PadConfig; > +} > + > +/** > + This procedure will get GPIO group data with pads, which Output is > supposed to be left unlock > + > + @param[in] GroupIndex GPIO group index > + @param[in] DwNum DWORD index for a group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked > + Bit position - PadNumber > + Bit value - 0: to be locked, 1: Leave = unlocked > +**/ > +UINT32 > +GpioGetGroupDwUnlockOutputMask ( > + IN UINT32 GroupIndex, > + IN UINT32 DwNum > + ) > +{ > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; > + UINT32 Length; > + UINT32 Index; > + > + Length =3D GpioLocateUnlockData (&GpioUnlockData); > + if (Length =3D=3D 0) { > + return 0; > + } > + > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); > + if (Index >=3D Length) { > + return 0; > + } > + > + return GpioUnlockData[Index].OutputState; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/GpioNameBufferPei.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/GpioNameBufferPei.c > new file mode 100644 > index 0000000000..1b05378799 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffe= r > Lib/GpioNameBufferPei.c > @@ -0,0 +1,68 @@ > +/** @file > + This file contains GpioMemLib implementation for PEI phase > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > + > +STATIC CONST EFI_GUID mGpioNamesPrivateHobGuid =3D {0x9AE3138D, 0x4EBF, > 0x4E90, {0x87, 0x96, 0x11, 0xD3, 0x10, 0x04, 0x60, 0x0A}}; > + > +STATIC volatile BOOLEAN mGlobalMemoryWorking =3D FALSE; > + > +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX]; > + > +/** > + Returns pointer to the buffer taken from GpioLib private HOB > + > + @retval CHAR8* Pointer to the buffer > +**/ > +STATIC > +CHAR8* > +GetBufferFromHob ( > + VOID > + ) > +{ > + VOID *Hob; > + CHAR8 *GpioNameBuffer; > + > + Hob =3D NULL; > + GpioNameBuffer =3D NULL; > + > + Hob =3D GetFirstGuidHob (&mGpioNamesPrivateHobGuid); > + if (Hob !=3D NULL){ > + GpioNameBuffer =3D (CHAR8*) GET_GUID_HOB_DATA (Hob); > + } else { > + GpioNameBuffer =3D (CHAR8*) BuildGuidHob > (&mGpioNamesPrivateHobGuid, GPIO_NAME_LENGTH_MAX); > + if (GpioNameBuffer =3D=3D NULL){ > + DEBUG ((DEBUG_ERROR, "Failed to setup HOB for GPIO names lib\n")); > + ASSERT (FALSE); > + } > + } > + return GpioNameBuffer; > +} > + > +/** > + Returns pointer to the global buffer to be used by GpioNamesLib > + > + @retval CHAR8* Pointer to the buffer > +**/ > +CHAR8* > +GpioGetStaticNameBuffer ( > + VOID > + ) > +{ > + mGlobalMemoryWorking =3D TRUE; > + > + if (mGlobalMemoryWorking) { > + return mGpioNameBuffer; > + } else { > + return GetBufferFromHob (); > + } > +} > + > -- > 2.16.2.windows.1