From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 54E2CAC09DD for ; Fri, 15 Sep 2023 05:42:39 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=yiC/2YbwMElU+82YrWNneWpKxOOpka9AY0/xty3t94Y=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1694756557; v=1; b=tlBMaQjpBm8W09gS3xfS90uxpprgDe9qYL4e9O2qsHjNFno9+aQwtLhWOA6cNgKQMTKM/7O6 1iHgTdCey4ytCuq8OqG/ZHBldlMSEb6gpwLyp9nhhH3Co6k2zRNQq02rzN07fwfjYTMKR2y7O1j +UUd4kW5EdlC8UYWGtdMg+Ns= X-Received: by 127.0.0.2 with SMTP id UmPmYY7687511xP3aGJuPFeZ; Thu, 14 Sep 2023 22:42:37 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web10.14805.1694756556965495585 for ; Thu, 14 Sep 2023 22:42:37 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10833"; a="376500387" X-IronPort-AV: E=Sophos;i="6.02,148,1688454000"; d="scan'208";a="376500387" X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Sep 2023 22:42:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10833"; a="779955481" X-IronPort-AV: E=Sophos;i="6.02,148,1688454000"; d="scan'208";a="779955481" X-Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by orsmga001.jf.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 14 Sep 2023 22:42:22 -0700 X-Received: from fmsmsx612.amr.corp.intel.com (10.18.126.92) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Thu, 14 Sep 2023 22:42:21 -0700 X-Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx612.amr.corp.intel.com (10.18.126.92) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Thu, 14 Sep 2023 22:42:21 -0700 X-Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32 via Frontend Transport; Thu, 14 Sep 2023 22:42:21 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.100) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.32; Thu, 14 Sep 2023 22:42:20 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=K6+CSTVtX11qvAQT1sGw+GfDLqO0X/pWar8Sm8s6On7gbD0EBKwnUvFxA3uz5Pj63CUKhGn1Cr2ThK+Fbf3KDixYr5WR1XOxw2SEQH9J50V9d2x4v18HSuP1tynCwUEaaT2Gi7vMn8C2erC1QWB/2OvqoSF+7tl2jUULmR8eXSSgD6+NaQJfCyjkOSLeSBgLXaC1xEOSeh5savlfyF5+7kAeoPimQ0WR5HNHI7vpar8v0yJ3vhwId6IHDJaUcWPvHsoWK7O4eBEXeNZRFnOoaedRv8IoH8EmyKnSaVqdLRUDIIBJP4zdazAPIaIpSin9WdPhtJ6SGQ1gaYOwRoN7Zg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=dHM+cSRoC5cKuK19M/nKPCBkddBTkWj1S3zxEyGnjUM=; b=DNKfnOr9r6dik3+M67jjcHIegUG71ekF63zVxvdd/jQayB53ELbfPMBRVk32x0TIWaAo9phBKTffyEoWvTwLA9Ir/wJ37wMmSAYCTeXOzStAFJMVDzujbPY8dPC77s1g3a9Hzp1f9dEp5tvDIjGp6t+zC8bqY0qNxeo0BbOZXFur9M4p26WSwvdlJaarvNWVSans4i6WfjZw5cuX+ahCKGpAx81Trzw9WRXVm68SP1Vp+UPmhslXWFp53OZgUWijJ7GcK1FLKy1OmWLygliiFeMQ1H3bY2y0yz8GEJ3OiZiH4F4TbtruzF6gEtzandjqWdX/Rd+LH/xINpoVJMG2cw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none X-Received: from MW4PR11MB5776.namprd11.prod.outlook.com (2603:10b6:303:183::9) by MW6PR11MB8389.namprd11.prod.outlook.com (2603:10b6:303:23d::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.20; Fri, 15 Sep 2023 05:42:11 +0000 X-Received: from MW4PR11MB5776.namprd11.prod.outlook.com ([fe80::2ec0:108e:7afe:f1a4]) by MW4PR11MB5776.namprd11.prod.outlook.com ([fe80::2ec0:108e:7afe:f1a4%5]) with mapi id 15.20.6768.029; Fri, 15 Sep 2023 05:42:11 +0000 From: "Chaganty, Rangasai V" To: "Kasbekar, Saloni" , "devel@edk2.groups.io" CC: "Desimone, Nathaniel L" , "Chuang, Rosen" Subject: Re: [edk2-devel] [PATCH v2 01/10] AlderlakeSiliconPkg/IpBlock: Add CpuPcieRp, Espi, Gpio components Thread-Topic: [PATCH v2 01/10] AlderlakeSiliconPkg/IpBlock: Add CpuPcieRp, Espi, Gpio components Thread-Index: AQHZ54+LXc4zB7lkqECuA/X+aeRII7AbX5QA Date: Fri, 15 Sep 2023 05:42:11 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MW4PR11MB5776:EE_|MW6PR11MB8389:EE_ x-ms-office365-filtering-correlation-id: e21408b3-ae71-42c8-38ae-08dbb5ae81f5 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: 7QJJZdL03ef1m7z81lJViv0y52oxTBuGSFxVsraRj6wyMKy6q58dG3iv9wXow9NrY4YcFgfgCQGkNb09ozLFOarHOSDkguQ+aULgYbRM4iPy556k5vQWAICNx57B7xJV4IzSAG3N4tsv5ns6/UyO91hPMrbJ8wxB4eemYX0L2YKhJr/m/ttpO7ZmMeGSAYlgYj78+9sb1UO8NJZ08k5OeEqHpqvNbk1QiIeHJ0sqjogiQwDLV1U/IDxurffmYLd75MXs/eK+T90jlw4p8WQp02h5BWSbQoWn0nqJRhvfe7XgaowdRYKo4nn99fYicXQB/KLnyX91bEEuCr6vlsKwqy/nSZBHF7B3oCFkLajhXsG0Kgix+iHp/NqQ/ZElG85Y4IR2gBhGsZt9d2Rtfbgr9eo3ZZL0UPDXVs4s4NBpLvMoML8WxD5wDiZWY5qmWaYgM/tIvM/oBb+jq2DSASoN4kiB2HE52S/zc46w6lJh/AcVSAHGS/MgJdjtu+s3i1NGyOQ8qTqsF8AfHsGlmKlOOs/DMifHeYEtyHWekc88ow5PDTzmIOa5cAtp8/ZmnajMqR83eM+z14iJmifs7iVBCqOS26jEnwHp0MrNglGWTUf8uw5eDdzLsxPUdjvUmw4z x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?DkIqZ289leb68UB/2s73bJkTuPmUVL5EM7EVjle/1Rk5F6SUXudGYd5NT3PU?= =?us-ascii?Q?wejt3y99pwRVpagOPGCsUx202CL+GxJWewejuasfOnqLTkrZvd9TPs+AyyL7?= =?us-ascii?Q?Esrbw76/newqrTEdG27grA9yI8aFwPJtEcvnQDQLzxFLPFCn34L5yoay++rc?= =?us-ascii?Q?fg05KQyOAbrYVP4mPvStirYtLb0z6XE2SAzoFGla/wTIA+ILI3rikCVH3ScE?= =?us-ascii?Q?KDN/a8nn5qGJnerVI+YGBgbhOm1fV0CKmWC6GRUCdnR0mTnKZLNmUwdANVHl?= =?us-ascii?Q?z4uHgdP9KBpUX+kturJiR4gcIxB0l+RYSD4GVjrbb6+zd7Y7JFx1atIuD1ox?= =?us-ascii?Q?cp0ZTNt2LmAmDnUfudqJ9KD+X/Cl2MNV9y2Z40mGrAN6byYKHJe93R7lO+as?= =?us-ascii?Q?OH4kU+/IRmyTJpAdXW7QAVKigfXkVeP7nXr+dZPROh60tEeUavBz3hzaXfoM?= =?us-ascii?Q?gMwyxdt74Hb7PIe/h+AgVv6d7imwFZSsgSZHUQglpXwDz6Vjn8OWNK+Sr3yL?= =?us-ascii?Q?BtiL7i82niQHgsdaN1Jn5qtr9qhyYZSbByyDXLQXXYzNGRoSL7N9cO/IJLAy?= =?us-ascii?Q?StgakWqeDy8bMsnXHhor6nEPqNEGQLfX2I+xUS8kg3Oj7vmV3Ah1HrX1ZOMm?= =?us-ascii?Q?u2KMeOHWHLD7bNkgCbOC7jnOc+3HeAk11l7O9MhBVosrUwVUMhSI+286mX7+?= =?us-ascii?Q?HpITHRal8BcUZCbZfBPqSGmAUl7GFlRMN0ZKhQS0dYlO0odeR+rmZpQNua44?= =?us-ascii?Q?VMj+XgdPmpfeoXBzV/6AR6AXBD3spu/xnsOL/UEOPVuvXsqdqHyDeNHgeDS7?= =?us-ascii?Q?Wg/9nofupro53JGh/G4sipb6WZ3SBFeefYz14WBthm3ar57ZDWd7EBqyT7+N?= =?us-ascii?Q?01Azz8PXan3twMQFjPErHIoFKnVjwPvkjGIS5ChPGmAUHCR6i6VdGsx4RASz?= =?us-ascii?Q?XkPgmjn+AJJia7Q3VQ6JYpDLcTvcbSBP8gtKsuqYo96etoo5gQ3kNIsi3zJK?= =?us-ascii?Q?vl9rNyP2mMz9TuRUgMgLuvGsUr4D2O0FN6F0TKkDKLosnn8/aZL8did76TvB?= =?us-ascii?Q?kWXkwxNAONBgQPWjo25Rse8v35O3oYLveMAh+OUBYMxm8w96GL/iHM/XQvnI?= =?us-ascii?Q?YxL/fOINxymiiYd976U0rVdb0VZx+UeyCLSBKE1mKmV5SWMuJlCAg54U81xR?= =?us-ascii?Q?CNap6sBJSd5WZqodHwsM3YIV4rCYq+8MuQCeYHDRTXI7KleESWVKCeSjcDZD?= =?us-ascii?Q?GnTowaXSDBOmCazaciwnw4dwABf4bJY3wnr+a28SKaTMRpvL3+OYCDPfkZvu?= =?us-ascii?Q?ScmGmozqj2SwnI93YsdaZexam5f/ruYdzaf4ZmH4RPaueEJ9pnmomDUAkXWg?= =?us-ascii?Q?vUw19go6bCo4+6zQwRfHnzwbQO+ngzkMS6yCzwCBLHuX2VfbK3A9pcPSooOi?= =?us-ascii?Q?ioJYk6t0LSgpOBIbOAK9PN0YnStk7jKW554K3gGid2i6vbk+kjD2QZpUUu3w?= =?us-ascii?Q?QGVxISdZMPqbCFREBRmBXXL3+4lJyWiXtiBGgHJUuPHLRhXY7OyzDL2vcBcb?= =?us-ascii?Q?Xq7oQIAPzgk4UFrf3jf5xWlPkVoo46lbrs1umMLcKVtjd4qnp+QHRYbycI1C?= =?us-ascii?Q?xg=3D=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MW4PR11MB5776.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: e21408b3-ae71-42c8-38ae-08dbb5ae81f5 X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Sep 2023 05:42:11.1886 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: EVxhvZYAoiyB/Oppt0ikhkQj+/NKRWBe18r2WiuyViQY44ht987prOFfKdDxBooHIYaIkbfrruuX78FU4DrfxcldaOZ2XxvIlXBBXnUVs64= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW6PR11MB8389 X-OriginatorOrg: intel.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,rangasai.v.chaganty@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: BfHzd8ru1CBoBgXeXx6AVuv3x7686176AA= Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=tlBMaQjp; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}"); dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Reviewed-by: Sai Chaganty -----Original Message----- From: Kasbekar, Saloni =20 Sent: Thursday, September 14, 2023 9:46 PM To: devel@edk2.groups.io Cc: Kasbekar, Saloni ; Chaganty, Rangasai V ; Desimone, Nathaniel L ; Chuang, Rosen Subject: [PATCH v2 01/10] AlderlakeSiliconPkg/IpBlock: Add CpuPcieRp, Espi,= Gpio components Adds the following modules: - IpBlock/CpuPcieRp/Include - IpBlock/Espi/Library - IpBlock/Gpio/IncludePrivate - IpBlock/Gpio/Library - IpBlock/Gpio/LibraryPrivate Cc: Sai Chaganty Cc: Nate DeSimone Cc: Rosen Chuang Signed-off-by: Saloni Kasbekar --- .../IpBlock/CpuPcieRp/Include/CpuPcieInfo.h | 25 + .../Espi/Library/PeiDxeSmmEspiLib/EspiLib.c | 58 ++ .../PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf | 38 ++ .../IncludePrivate/Library/GpioHelpersLib.h | 50 ++ .../IncludePrivate/Library/GpioNativePads.h | 245 ++++++++ .../IncludePrivate/Library/GpioPrivateLib.h | 350 +++++++++++ .../Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c | 546 ++++++++++++++++++ .../Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c | 522 +++++++++++++++++ .../Library/PeiDxeSmmGpioLib/GpioLibrary.h | 29 + .../Library/PeiDxeSmmGpioLib/GpioNativeLib.c | 177 ++++++ .../PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf | 44 ++ .../BaseGpioHelpersLibNull.c | 51 ++ .../BaseGpioHelpersLibNull.inf | 25 + .../GpioNativePrivateLibInternal.h | 48 ++ .../PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c | 267 +++++++++ .../GpioPrivateLibPch.c | 172 ++++++ .../GpioPrivateLibVer2.c | 81 +++ .../PeiDxeSmmGpioPrivateLibVer2.inf | 40 ++ .../PeiGpioHelpersLib/PeiGpioHelpersLib.c | 218 +++++++ .../PeiGpioHelpersLib/PeiGpioHelpersLib.inf | 46 ++ 20 files changed, 3032 insertions(+) create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Inc= lude/CpuPcieInfo.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/= PeiDxeSmmEspiLib/EspiLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/= PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludeP= rivate/Library/GpioHelpersLib.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludeP= rivate/Library/GpioNativePads.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludeP= rivate/Library/GpioPrivateLib.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/= PeiDxeSmmGpioLib/GpioInit.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/= PeiDxeSmmGpioLib/GpioLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/= PeiDxeSmmGpioLib/GpioLibrary.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/= PeiDxeSmmGpioLib/GpioNativeLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/= PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryP= rivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Cp= uPcieInfo.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/C= puPcieInfo.h new file mode 100644 index 0000000000..a6f8b16d10 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieIn= fo.h @@ -0,0 +1,25 @@ +/** @file + This file contains definitions of PCIe controller information + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _CPU_PCIE_INFO_H_ +#define _CPU_PCIE_INFO_H_ + +#define PCIE_HWEQ_COEFFS_MAX 5 + + +// +// SA PCI Express* Port configuration +// + +#define CPU_PCIE_MAX_ROOT_PORTS 4 +#define CPU_PCIE_MAX_CONTROLLERS 3 + +#define SA_PEG_MAX_FUN 0x04 +#define SA_PEG_MAX_LANE 0x14 + + + +#endif diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeS= mmEspiLib/EspiLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Librar= y/PeiDxeSmmEspiLib/EspiLib.c new file mode 100644 index 0000000000..2e4d1375ca --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiL= ib/EspiLib.c @@ -0,0 +1,58 @@ +/** @file + This file contains routines for eSPI + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/** + Checks if second device capability is enabled + + @retval TRUE There's second device + @retval FALSE There's no second device +**/ +BOOLEAN +IsEspiSecondSlaveSupported ( + VOID + ) +{ + return ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS) & B_ESPI_PCR_= SOFTSTRAPS_CS1_EN) !=3D 0); +} + + +/** + Is eSPI enabled in strap. + + @retval TRUE Espi is enabled in strap + @retval FALSE Espi is disabled in strap +**/ +BOOLEAN +IsEspiEnabled ( + VOID + ) +{ + return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & B_ESPI_PCR_CFG_= VAL_ESPI_EN) !=3D 0; +} + +typedef enum { + EspiSlaveOperationConfigRead, + EspiSlaveOperationConfigWrite, + EspiSlaveOperationStatusRead, + EspiSlaveOperationInBandReset +} ESPI_SLAVE_OPERATION; + + + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeS= mmEspiLib/PeiDxeSmmEspiLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/= Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf new file mode 100644 index 0000000000..e8db1e4e8d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiL= ib/PeiDxeSmmEspiLib.inf @@ -0,0 +1,38 @@ +## @file +# Component description file for the PeiDxeSmmPchEspiLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION =3D 0x00010017 +BASE_NAME =3D PeiDxeSmmEspiLib +FILE_GUID =3D 7F25F990-7989-4413-B414-1EDE557E9389 +VERSION_STRING =3D 1.0 +MODULE_TYPE =3D BASE +LIBRARY_CLASS =3D EspiLib +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PchPcrLib +TimerLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +EspiLib.c diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioHelpersLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/I= ncludePrivate/Library/GpioHelpersLib.h new file mode 100644 index 0000000000..cf67c81ed0 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioHelpersLib.h @@ -0,0 +1,50 @@ +/** @file + Header file for GPIO Helpers Lib implementation. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_HELPERS_LIB_H_ +#define _GPIO_HELPERS_LIB_H_ + +#include + +/** + This procedure stores GPIO group data about pads which PadConfig needs t= o be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] PadsToLock DWORD bitmask for pads which are going t= o 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 + ); + +/** + This procedure stores GPIO group data about pads which Output state need= s 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 pe= r group DwNum must be 0. + @param[in] PadsToLock DWORD bitmask for pads which are going t= o 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 + ); + +#endif // _GPIO_HELPERS_LIB_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioNativePads.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/I= ncludePrivate/Library/GpioNativePads.h new file mode 100644 index 0000000000..dbd13963fa --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioNativePads.h @@ -0,0 +1,245 @@ +/** @file + Header file for GPIO Native pads support + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_NATIVE_PADS_H_ +#define _GPIO_NATIVE_PADS_H_ + +// +// GpioPad can contain additional information used to provide data on +// native functions. Please refer to description of GPIO_NATIVE_PAD +// +// FFFF CCCC TTTG GGGG TTTT TTTP PPPP PPPP +// +// F - 2^4 =3D 16, native function number +// C - 2^4 =3D 16, chipset ID +// T - 2^10 =3D 1024 , abstract type representing native mode of a pad (e.= g. SERIALIO_UART2_TX) +// G - 2^5 =3D 32, group +// P - 2^9 =3D 512, pad number +// +// F & T contain additional optional settings used for native pads +// +#define GPIO_NATIVE_PAD_DEF(GpioNativePad, NativeMode, NativeFunction) \ + (GpioNativePad | (NativeMode << 28) | ((NativeFunction & 0x7F) << 9) | (= (NativeFunction & 0x380) << 14)) + +#define GPIO_NATIVE_GET_FUNCTION(GpioNativePad) ((((GpioNativePad) & 0xFE0= 0) >> 9) | (((GpioNativePad) & 0xE00000) >> 14)) +#define GPIO_NATIVE_GET_PAD_FN(GpioNativePad) (((GpioNativePad) >> 28) &= 0xF) +#define GPIO_NATIVE_GET_PAD_MODE(GpioNativePad) ((GPIO_NATIVE_GET_PAD_FN(G= pioNativePad) << 1) | 1) +#define GPIO_NATIVE_TO_GPIO_PAD(GpioNativePad) (GpioNativePad & 0xF1F01FF= ) + +// +// Below defines and macros are used to build abstract type +// to help encode native pin information in GPIO_PAD +// + +// +// Macro used to define GPIO native function. +// defines range that can be used to encode given native signal. +// Numbering must be unique and cannot overlap. +// If there are many instances of similar signal (e.g. per controller) the= lower +// word will store value for a given instance in the form: Min + Instance +// Upper word (Max) is left untouched and later used for verification +// +#define GPIO_NATIVE_FUNCTION_DEF(Min, Max) (((Max) << 16) + (= Min)) +#define GPIO_NATIVE_FUNCTION_GET_MAX(NativeFunction) (((NativeFunction)= >> 16) & 0xFFFF) +#define GPIO_NATIVE_FUNCTION_GET_VALUE(NativeFunction) ((NativeFunction) = & 0xFFFF) + +// +// Macro GPIO_NATIVE_FUNCTION_GET_SIGNAL is created as synonym to macro GP= IO_NATIVE_FUNCTION_GET_MAX +// GPIO_NATIVE_FUNCTION_GET_SIGNAL used with below defines is more descrip= tive and easier to read +// ex. +// - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_SERIAL_IO_UART_RX) +// - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_ISH_GP) +// - ... +// +#define GPIO_NATIVE_FUNCTION_GET_SIGNAL(NativeFunction) (GPIO_NATIVE_FUNCT= ION_GET_MAX(NativeFunction)) + +// +// GPIO native modes +// Those defines are internal to this header. +// GPIO_FUNCTION__(index) defines should be used by other modu= les instead. +// +#define GPIO_SERIAL_IO_UART_RX GPIO_NATIVE_FUNCTION_DEF(1,8) +#define GPIO_SERIAL_IO_UART_TX GPIO_NATIVE_FUNCTION_DEF(9,16) +#define GPIO_SERIAL_IO_UART_RTS GPIO_NATIVE_FUNCTION_DEF(17,24) +#define GPIO_SERIAL_IO_UART_CTS GPIO_NATIVE_FUNCTION_DEF(25,31) +#define GPIO_SERIAL_IO_SPI_MOSI GPIO_NATIVE_FUNCTION_DEF(32,39) +#define GPIO_SERIAL_IO_SPI_MISO GPIO_NATIVE_FUNCTION_DEF(40,47) +#define GPIO_SERIAL_IO_SPI_CLK GPIO_NATIVE_FUNCTION_DEF(48,55) +#define GPIO_SERIAL_IO_SPI_CS GPIO_NATIVE_FUNCTION_DEF(56,71) +#define GPIO_ISH_GP GPIO_NATIVE_FUNCTION_DEF(80,143) +#define GPIO_ISH_UART_RX GPIO_NATIVE_FUNCTION_DEF(144,151) +#define GPIO_ISH_UART_TX GPIO_NATIVE_FUNCTION_DEF(152,159) +#define GPIO_ISH_UART_RTS GPIO_NATIVE_FUNCTION_DEF(160,167) +#define GPIO_ISH_UART_CTS GPIO_NATIVE_FUNCTION_DEF(168,175) +#define GPIO_ISH_SPI_MOSI GPIO_NATIVE_FUNCTION_DEF(184,191) +#define GPIO_ISH_SPI_MISO GPIO_NATIVE_FUNCTION_DEF(192,199) +#define GPIO_ISH_SPI_CLK GPIO_NATIVE_FUNCTION_DEF(200,207) +#define GPIO_ISH_SPI_CS GPIO_NATIVE_FUNCTION_DEF(208,223) +#define GPIO_ISH_I2C_SCL GPIO_NATIVE_FUNCTION_DEF(232,239) +#define GPIO_ISH_I2C_SDA GPIO_NATIVE_FUNCTION_DEF(240,247) +#define GPIO_THC_SPI_INT GPIO_NATIVE_FUNCTION_DEF(248,251) +#define GPIO_DMIC_DATA GPIO_NATIVE_FUNCTION_DEF(258,261) +#define GPIO_DMIC_CLKA GPIO_NATIVE_FUNCTION_DEF(262,265) +#define GPIO_DMIC_CLKB GPIO_NATIVE_FUNCTION_DEF(266,269) +#define GPIO_DDSP_HPD0 GPIO_NATIVE_FUNCTION_DEF(270,285) +#define GPIO_PANEL_AVDD_EN GPIO_NATIVE_FUNCTION_DEF(286,289) +#define GPIO_PANEL_BKLTEN GPIO_NATIVE_FUNCTION_DEF(290,293) +#define GPIO_PANEL_BKLTCTL GPIO_NATIVE_FUNCTION_DEF(294,297) +#define GPIO_PANEL_RESET GPIO_NATIVE_FUNCTION_DEF(298,301) +#define GPIO_PANEL_AVEE_EN GPIO_NATIVE_FUNCTION_DEF(302,305) +#define GPIO_PANEL_VIO_EN GPIO_NATIVE_FUNCTION_DEF(306,309) +#define GPIO_PANEL_HPD GPIO_NATIVE_FUNCTION_DEF(310,313) +#define GPIO_PANEL_TE_EN GPIO_NATIVE_FUNCTION_DEF(314,317) +#define GPIO_HDMI_GMBUS_SCL GPIO_NATIVE_FUNCTION_DEF(318,325) +#define GPIO_HDMI_GMBUS_SDA GPIO_NATIVE_FUNCTION_DEF(326,333) +#define GPIO_SERIAL_IO_I2C_SCL GPIO_NATIVE_FUNCTION_DEF(338,353) +#define GPIO_SERIAL_IO_I2C_SDA GPIO_NATIVE_FUNCTION_DEF(354,369) +#define GPIO_SD_DATA GPIO_NATIVE_FUNCTION_DEF(374,377) +#define GPIO_EMMC_DATA GPIO_NATIVE_FUNCTION_DEF(384,391) +#define GPIO_THC_CLK_LOOPBACK GPIO_NATIVE_FUNCTION_DEF(395,396) +#define GPIO_MIPI_PANEL_RESET GPIO_NATIVE_FUNCTION_DEF(401,404) +#define GPIO_MIPI_SEC_POW_EN_AVEE GPIO_NATIVE_FUNCTION_DEF(405,408) +#define GPIO_MIPI_SEC_POW_EN_AVDD GPIO_NATIVE_FUNCTION_DEF(409,412) +#define GPIO_THC_WOT GPIO_NATIVE_FUNCTION_DEF(413,414) +#define GPIO_SATA_DEVSLP GPIO_NATIVE_FUNCTION_DEF(415,446) +#define GPIO_PCIE_CLKREQ GPIO_NATIVE_FUNCTION_DEF(447,478) + +// +// Serial IO UART +// + +#define GPIO_FUNCTION_SERIAL_IO_UART_RX(UartDev) (GPIO_SERIAL_IO_UART_RX = + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_TX(UartDev) (GPIO_SERIAL_IO_UART_TX = + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_RTS(UartDev) (GPIO_SERIAL_IO_UART_RTS= + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_CTS(UartDev) (GPIO_SERIAL_IO_UART_CTS= + ((UINT32)UartDev)) + +// +// Serial IO SPI +// +#define GPIO_SERIAL_IO_SPI_RANGE 8 // Number of SerialIo SPIx controller= s supported in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_SERIAL_IO_SPI_MOSI(SpiDev) (GPIO_SERIAL_IO_SPI_= MOSI + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_MISO(SpiDev) (GPIO_SERIAL_IO_SPI_= MISO + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_CLK(SpiDev) (GPIO_SERIAL_IO_SPI_= CLK + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_CS(SpiDev, CsNum) (GPIO_SERIAL_IO_SPI_= CS + ((UINT32)SpiDev) + ((UINT32)CsNum) * GPIO_SERIAL_IO_SPI_RANGE) + +// +// Serial IO I2C +// + +#define GPIO_FUNCTION_SERIAL_IO_I2C_SCL(I2cDev) (GPIO_SERIAL_IO_I2C_SCL + = ((UINT32)I2cDev)) +#define GPIO_FUNCTION_SERIAL_IO_I2C_SDA(I2cDev) (GPIO_SERIAL_IO_I2C_SDA + = ((UINT32)I2cDev)) + +// +// ISH GP +// + +#define GPIO_FUNCTION_ISH_GP(GpNum) (GPIO_ISH_GP + ((UINT32)GpNum)) + +// +// ISH UART +// + +#define GPIO_FUNCTION_ISH_UART_RX(UartDev) (GPIO_ISH_UART_RX + ((UINT32)U= artDev)) +#define GPIO_FUNCTION_ISH_UART_TX(UartDev) (GPIO_ISH_UART_TX + ((UINT32)U= artDev)) +#define GPIO_FUNCTION_ISH_UART_RTS(UartDev) (GPIO_ISH_UART_RTS + ((UINT32)= UartDev)) +#define GPIO_FUNCTION_ISH_UART_CTS(UartDev) (GPIO_ISH_UART_CTS + ((UINT32)= UartDev)) + +// +// ISH SPI +// +#define GPIO_ISH_SPI_RANGE 8 // Number of ISH SPI controllers supported = in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_ISH_SPI_MOSI(SpiDev) (GPIO_ISH_SPI_MOSI + ((UIN= T32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_MISO(SpiDev) (GPIO_ISH_SPI_MISO + ((UIN= T32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_CLK(SpiDev) (GPIO_ISH_SPI_CLK + ((UINT= 32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_CS(SpiDev, CsNum) (GPIO_ISH_SPI_CS + ((UINT3= 2)SpiDev) + ((UINT32)CsNum) * GPIO_ISH_SPI_RANGE) + +// +// ISH I2C +// + +#define GPIO_FUNCTION_ISH_I2C_SCL(I2cDev) (GPIO_ISH_I2C_SCL + ((UINT32)I2c= Dev)) +#define GPIO_FUNCTION_ISH_I2C_SDA(I2cDev) (GPIO_ISH_I2C_SDA + ((UINT32)I2c= Dev)) + +// +// SD Card +// +#define GPIO_FUNCTION_SD_DATA(Index) (GPIO_SD_DATA + ((UINT32)Index= )) + +// +// EMMC +// +#define GPIO_FUNCTION_EMMC_DATA(Index) (GPIO_EMMC_DATA + ((UINT32)Ind= ex)) + +// +// THC SPI +// + +#define GPIO_FUNCTION_THC_SPI_INT(SpiDev) (GPIO_THC_SPI_INT + ((UINT32)Spi= Dev)) +#define GPIO_FUNCTION_THC_CLK_LOOPBACK(SpiDev) (GPIO_THC_CLK_LOOPBACK + ((= UINT32)SpiDev)) +#define GPIO_FUNCTION_THC_WOT(SpiDev) (GPIO_THC_WOT + ((UINT32)SpiDev)) + + +// +// DMIC +// + +#define GPIO_FUNCTION_DMIC_DATA(DmicDev) (GPIO_DMIC_DATA + ((UINT32)DmicD= ev)) +#define GPIO_FUNCTION_DMIC_CLKA(DmicDev) (GPIO_DMIC_CLKA + ((UINT32)DmicD= ev)) +#define GPIO_FUNCTION_DMIC_CLKB(DmicDev) (GPIO_DMIC_CLKB + ((UINT32)DmicD= ev)) +#define GPIO_FUNCTION_DMIC_CLK(DmicDev) (GPIO_DMIC_CLKA + ((UINT32)DmicD= ev)) // If there is no split between channel A/B use A range for such Clock= s + + +// +// DDSP HPD +// + +#define GPIO_FUNCTION_DDSP_HPD(HpdIndex) \ + (HpdIndex > 7) ? GPIO_DDSP_HPD0 + 8 + (HpdIndex) - 'A' : GPIO_DDSP_HPD0 = + HpdIndex + +// +// HDMI_GMBUS +// + +#define GPIO_FUNCTION_HDMI_SCL(DdiPort) (GPIO_HDMI_GMBUS_SCL + ((UINT32)Dd= iPort)) +#define GPIO_FUNCTION_HDMI_SDA(DdiPort) (GPIO_HDMI_GMBUS_SDA + ((UINT32)Dd= iPort)) + +// +// Panel +// + +#define GPIO_FUNCTION_PANEL_AVDD_EN(PanelDev) (GPIO_PANEL_AVDD_EN = + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_BKLTEN(PanelDev) (GPIO_PANEL_BKLTEN += ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_BKLTCTL(PanelDev) (GPIO_PANEL_BKLTCTL = + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_RESET(PanelDev) (GPIO_PANEL_RESET + = ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_AVEE_EN(PanelDev) (GPIO_PANEL_AVEE_EN = + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_VIO_EN(PanelDev) (GPIO_PANEL_VIO_EN += ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_HPD(PanelDev) (GPIO_PANEL_HPD + ((= UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_TE_EN(PanelDev) (GPIO_PANEL_TE_EN + = ((UINT32)PanelDev)) + +// +// MIPI +// +#define GPIO_FUNCTION_MIPI_PANEL_RESET(PanelDev) (GPIO_MIPI_PANEL_RES= ET + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVEE(PanelDev) (GPIO_MIPI_SEC_POW_E= N_AVEE + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVDD(PanelDev) (GPIO_MIPI_SEC_POW_E= N_AVDD + ((UINT32)PanelDev)) + + +// +// SATA DevSlp +// +#define GPIO_SATA_DEVSLP_RANGE 32 // Number of SATA DevSlp instances per= controller supported in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_SATA_DEVSLP(CsNum, SataDevSlpIndex) (GPIO_SATA_= DEVSLP + ((UINT32)SataDevSlpIndex) + ((UINT32)CsNum) * GPIO_SATA_DEVSLP_RAN= GE) + +// +// SRC CLKREQ +// + +#define GPIO_FUNCTION_PCIE_CLKREQ(ClkReqIndex) (GPIO_PCIE_CLKREQ + ((= UINT32)ClkReqIndex)) + +#endif // _GPIO_NATIVE_PADS_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioPrivateLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/I= ncludePrivate/Library/GpioPrivateLib.h new file mode 100644 index 0000000000..a757a4b057 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioPrivateLib.h @@ -0,0 +1,350 @@ +/** @file + Header file for GpioPrivateLib. + All function in this library is available for PEI, DXE, and SMM, + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_PRIVATE_LIB_H_ +#define _GPIO_PRIVATE_LIB_H_ + +#include +#include +#include + +/** + GPIO Standby State configuration + Standby State options for GPIO Pads +**/ +typedef enum { + GpioIosStateDefault =3D 0x0, + GpioIosStateLatchLastValue =3D (0x0 << 1) | 0x01, ///< Latch last valu= e driven on TX, TX Enable and RX Enable + GpioIosStateTx0Rx0RxDis =3D (0x1 << 1) | 0x01, ///< TX: 0, RX: 0 (i= nternally), RX disabled + GpioIosStateTx0Rx1RxDis =3D (0x2 << 1) | 0x01, ///< TX: 0, RX: 1 (i= nternally), RX disabled + GpioIosStateTx1Rx0RxDis =3D (0x3 << 1) | 0x01, ///< TX: 1, RX: 0 (i= nternally), RX disabled + GpioIosStateTx1Rx1RxDis =3D (0x4 << 1) | 0x01, ///< TX: 1, RX: 1 (i= nternally), RX disabled + GpioIosStateTx0RxEn =3D (0x5 << 1) | 0x01, ///< TX: 0, RX enabl= ed + GpioIosStateTx1RxEn =3D (0x6 << 1) | 0x01, ///< TX: 1, RX enabl= ed + GpioIosStateHizRx0 =3D (0x7 << 1) | 0x01, ///< Hi-Z, RX: 0 (in= ternally) + GpioIosStateHizRx1 =3D (0x8 << 1) | 0x01, ///< Hi-Z, RX: 1 (in= ternally) + GpioIosStateTxDisRxEn =3D (0x9 << 1) | 0x01, ///< TX Disabled and= RX Enabled (i.e. wake or interrupt) + GpioIosStateMasked =3D (0xF << 1) | 0x01 ///< IO Standby sign= al is masked for this pad. In this mode, a pad operates as if IOStandby has= not been asserted. +} GPIO_IOSTANDBY_STATE; + +/** + GPIO Standby Term configuration + Standby Termination options for GPIO Pads +**/ +typedef enum { + GpioIosTermDefault =3D 0x00, + GpioIosTermSame =3D (0x00 << 1) | 0x01, ///< Same as state sp= ecified in Term + GpioIosTermPuDisPdDis =3D (0x01 << 1) | 0x01, ///< Disable Pullup a= nd Pulldown + GpioIosTermPuDisPdEn =3D (0x02 << 1) | 0x01, ///< Enable Pulldown + GpioIosTermPuEnPdDis =3D (0x03 << 1) | 0x01 ///< Enable Pullup +} GPIO_IOSTANDBY_TERM; + +// +// Structure for native pin data +// +typedef struct { + GPIO_PAD Pad; + GPIO_PAD_MODE Mode; + GPIO_IOSTANDBY_STATE IosState; + GPIO_IOSTANDBY_TERM IosTerm; +} GPIO_PAD_NATIVE_FUNCTION; + +// +// Structure for Serial GPIO pin definition +// +typedef struct { + GPIO_PAD_NATIVE_FUNCTION Sclock; + GPIO_PAD_NATIVE_FUNCTION Sload; + GPIO_PAD_NATIVE_FUNCTION Sdataout; +} SGPIO_PINS; + +// +// Structure for USB Virtual Wire OverCurrent Pad Mode group +// +typedef struct { + GPIO_PAD OcRxPad; + GPIO_PAD OcTxPad; +} GPIO_VWOC_FUNCTION; + +// +// Below defines are based on GPIO_CONFIG structure fields +// +#define B_GPIO_PAD_MODE_MASK 0xF +#define N_GPIO_PAD_MODE_BIT_POS 0 +#define B_GPIO_DIRECTION_DIR_MASK 0x7 +#define N_GPIO_DIRECTION_DIR_BIT_POS 0 +#define B_GPIO_DIRECTION_INV_MASK 0x18 +#define N_GPIO_DIRECTION_INV_BIT_POS 3 +#define B_GPIO_OUTPUT_MASK 0x3 +#define N_GPIO_OUTPUT_BIT_POS 0 +#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS 0 +#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS 5 +#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS 0 +#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS 0 + +// +// Structure for storing information about registers offset, community, +// maximal pad number for available groups +// +typedef struct { + PCH_SBI_PID Community; + UINT16 PadOwnOffset; + UINT16 HostOwnOffset; + UINT16 GpiIsOffset; + UINT16 GpiIeOffset; + UINT16 GpiGpeStsOffset; + UINT16 GpiGpeEnOffset; + UINT16 SmiStsOffset; + UINT16 SmiEnOffset; + UINT16 NmiStsOffset; + UINT16 NmiEnOffset; + UINT16 PadCfgLockOffset; + UINT16 PadCfgLockTxOffset; + UINT16 PadCfgOffset; + UINT16 PadPerGroup; +} GPIO_GROUP_INFO; + +// +// If in GPIO_GROUP_INFO structure certain register doesn't exist +// it will have value equal to NO_REGISTER_FOR_PROPERTY +// +#define NO_REGISTER_FOR_PROPERTY 0xFFFF + +#define GPIO_PAD_DEF(Group,Pad) (UINT32)(((Group) << 16) + = (Pad)) +#define GPIO_GROUP_DEF(GroupIndex,ChipsetId) ((GroupIndex) | ((ChipsetId= ) << 8)) +#define GPIO_GET_GROUP_INDEX(Group) ((Group) & 0x1F) +#define GPIO_GET_GROUP_FROM_PAD(GpioPad) (((GpioPad) & 0x0F1F0000) >= > 16) +#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) GPIO_GET_GROUP_INDEX (GPIO_= GET_GROUP_FROM_PAD(GpioPad)) +#define GPIO_GET_PAD_NUMBER(GpioPad) ((GpioPad) & 0x1FF) +#define GPIO_GET_CHIPSET_ID(GpioPad) (((GpioPad) >> 24) & 0xF) + +#define GPIO_GET_PAD_POSITION(PadNumber) ((PadNumber) % 32) +#define GPIO_GET_DW_NUM(PadNumber) ((PadNumber) / 32u) + +/** + 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 + ); + +typedef struct { + CONST CHAR8* GpioGroupPrefix; + CONST GPIO_PAD FirstUniqueGpio; + CONST CHAR8** GroupUniqueNames; + CONST UINT32 UniqueNamesTableSize; +} GPIO_GROUP_NAME_INFO; + +// +// Helper macros for initializing GPIO_GROUP_NAME_INFO structures +// +#define GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTable) \ + {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE (GroupUni= queNamesTable)} + +#define GPIO_GROUP_NAME_BASIC(GroupName) \ + {GroupName, 0, NULL, 0} + +/** + Get GPIO Chipset ID specific to PCH generation and series +**/ +UINT32 +GpioGetThisChipsetId ( + VOID + ); + +/** + This procedure is used to check if GpioPad is valid for certain chipset + + @param[in] GpioPad GPIO pad + + @retval TRUE This pin is valid on this chipset + FALSE Incorrect pin +**/ +BOOLEAN +GpioIsCorrectPadForThisChipset ( + IN GPIO_PAD GpioPad + ); + + +/** + 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 R= egisters + @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 + ); + +/** + This procedure calculates Pad Configuration Register DW offset + + @param[in] GpioPad GPIO pad + @param[in] DwReg Index of the configuration register + + @retval DW Register offset +**/ +UINT32 +GpioGetGpioPadCfgAddressFromGpioPad ( + IN GPIO_PAD GpioPad, + IN UINT32 DwReg + ); + + +/** + 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 lib= API + @retval FALSE GPIO pad is invalid and cannot be used with GPI= O lib API +**/ +BOOLEAN +GpioIsPadValid ( + IN GPIO_PAD GpioPad + ); + +/** + 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 + ); + +/** + Check if 0x13 opcode supported for writing to GPIO lock unlock register + + @retval TRUE It's supported + @retval FALSE It's not supported +**/ +BOOLEAN +IsGpioLockOpcodeSupported ( + VOID + ); + +/** + Gpio Minimum Set + + Set of Gpio Minimum function to use in Pre Mem phase. + To optimise execution and reduce memory footprint thse minimum version + of 'full' functions are stripped from: + - GpioPad PCH validation + - GpioPad Group belonging validation + - GpioPad Host ownership validation + - IoStandbyState configuration + The use of below functions has to be careful and with full + understanding of all pros and cons. Please refer to GpioPrivateLib.c + to familiarize with details of implementation. +**/ + +/** + This procedure reads GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + + @retval Register value or "F"s in case of errors +**/ +UINT32 +GpioRegisterAccessRead32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register + ); + +/** + This procedure writes GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + @param[in] AndValue And value + @param[in] OrValue Or value + + @retval EFI_DEVICE_ERROR vGPIO BAR not programmed + EFI_SUCCESS Operation completed successfully +**/ +EFI_STATUS +GpioRegisterAccessAndThenOr32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register, + IN UINT32 AndValue, + IN UINT32 OrValue + ); + +/** + This procedure will calculate PADCFG register value based on GpioConfig = data + The procedure can be various depending on chipset generation. + Available configuration options and corresponding registers fields + can distributed in different way in configuration registers. + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfig ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ); + +/** + This procedure will write GPIO Lock/LockTx register + - For PCH SBI message is used. + - For IBL MMIO access is used. + + @param[in] RegValue GPIO register (Lock or LockTx) value + @param[in] RegOffset GPIO register (Lock or LockTx) base offs= et + @param[in] DwNum Register number for current group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] GroupIndex GPIO group index in the GpioGroupInfo ta= ble + + @retval EFI_SUCCESS The function completed successfully + EFI_UNSUPPORTED Feature is not supported for this group = or pad +**/ +EFI_STATUS +GpioInternalWriteLockRegister ( + IN UINT32 RegValue, + IN UINT32 RegOffset, + IN UINT32 DwNum, + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 GroupIndex + ); + +#endif // _GPIO_PRIVATE_LIB_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioInit.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Libra= ry/PeiDxeSmmGpioLib/GpioInit.c new file mode 100644 index 0000000000..cf6f92a50d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioInit.c @@ -0,0 +1,546 @@ +/** @file + This file contains routines for GPIO initialization + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" + +// +// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function +// to cache values which will be programmed into respective GPIO registers +// after all GpioPads are processed. This way MMIO accesses are decreased +// and instead of doing one programming for one GpioPad there is only +// one access for whole register. +// +typedef struct { + UINT32 HostSoftOwnReg; + UINT32 HostSoftOwnRegMask; + UINT32 GpiGpeEnReg; + UINT32 GpiGpeEnRegMask; + UINT32 GpiNmiEnReg; + UINT32 GpiNmiEnRegMask; + UINT32 GpiSmiEnReg; + UINT32 GpiSmiEnRegMask; + UINT32 ConfigUnlockMask; + UINT32 OutputUnlockMask; +} GPIO_GROUP_DW_DATA; + +// +// GPIO_GROUP_DW_NUMBER contains number of DWords required to +// store Pad data for all groups. Each pad uses one bit. +// +// For Cannonlake only vGPIO group has >32 pads but those pads +// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be 1 +// +#define GPIO_GROUP_DW_NUMBER 1 + +/** + Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock). + + @param[in] PadNumber GPIO pad number + @param[in] GpioConfig GPIO Config data + @param[in out] DwRegsValues Values for GPIO DW Registers + + @retval None +**/ +STATIC +VOID +GpioDwRegValueFromGpioConfig ( + IN UINT32 PadNumber, + IN CONST GPIO_CONFIG *GpioConfig, + IN OUT GPIO_GROUP_DW_DATA *GroupDwData + ) +{ + UINT32 PadBitPosition; + UINT32 DwNum; + + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); + DwNum =3D GPIO_GET_DW_NUM (PadNumber); + + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { + ASSERT (FALSE); + return; + } + // + // Update value to be programmed in HOSTSW_OWN register + // + GroupDwData[DwNum].HostSoftOwnRegMask |=3D (GpioConfig->HostSoftPadOwn &= 0x1) << PadBitPosition; + GroupDwData[DwNum].HostSoftOwnReg |=3D (GpioConfig->HostSoftPadOwn >> 0x= 1) << PadBitPosition; + + // + // Update value to be programmed in GPI_GPE_EN register + // + GroupDwData[DwNum].GpiGpeEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition; + GroupDwData[DwNum].GpiGpeEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntSci) >> 3) << PadBitPosition; + + // + // Update value to be programmed in GPI_NMI_EN register + // + GroupDwData[DwNum].GpiNmiEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition; + GroupDwData[DwNum].GpiNmiEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntNmi) >> 1) << PadBitPosition; + + // + // Update value to be programmed in GPI_SMI_EN register + GroupDwData[DwNum].GpiSmiEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition; + GroupDwData[DwNum].GpiSmiEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntSmi) >> 2) << PadBitPosition; + if ((GpioConfig->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) { + GroupDwData[DwNum].HostSoftOwnRegMask |=3D 1 << PadBitPosition; + GroupDwData[DwNum].HostSoftOwnReg |=3D 1 << PadBitPosition; + } + + // + // Update information on Pad Configuration Lock + // + GroupDwData[DwNum].ConfigUnlockMask |=3D ((GpioConfig->LockConfig >> 1) = & 0x1) << PadBitPosition; + + // + // Update information on Pad Configuration Lock Tx + // + GroupDwData[DwNum].OutputUnlockMask |=3D ((GpioConfig->LockConfig >> 3) = & 0x1) << PadBitPosition; + + // + // if pad in GpioMode is an output default action should be to leave out= put unlocked + // + if ((GpioConfig->PadMode =3D=3D GpioPadModeGpio) && + (GpioConfig->Direction =3D=3D GpioDirOut) && + ((GpioConfig->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D= =3D GpioLockDefault)) { + GroupDwData[DwNum].OutputUnlockMask |=3D 0x1 << PadBitPosition; + } +} + +/** + This internal procedure will scan GPIO initialization table and unlock + all pads present in it + + @param[in] NumberOfItem Number of GPIO pad records in tabl= e + @param[in] GpioInitTableAddress GPIO initialization table + @param[in] Index Index of GPIO Initialization table= record + + @retval EFI_SUCCESS The function completed successfull= y + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioUnlockPadsForAGroup ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress, + IN UINT32 Index + ) +{ + UINT32 PadsToUnlock[GPIO_GROUP_DW_NUMBER]; + UINT32 DwNum; + UINT32 PadBitPosition; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + CONST GPIO_INIT_CONFIG *GpioData; + GPIO_GROUP Group; + UINT32 GroupIndex; + UINT32 PadNumber; + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GpioData =3D &GpioInitTableAddress[Index]; + Group =3D GpioGetGroupFromGpioPad (GpioData->GpioPad); + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); + + ZeroMem (PadsToUnlock, sizeof (PadsToUnlock)); + // + // Loop through pads for one group. If pad belongs to a different group = then + // break and move to register programming. + // + while (Index < NumberOfItems) { + + GpioData =3D &GpioInitTableAddress[Index]; + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) = { + //if next pad is from different group then break loop + break; + } + + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); + // + // Check if legal pin number + // + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible r= ange for group %d\n", PadNumber, GroupIndex)); + return EFI_INVALID_PARAMETER; + } + + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); + DwNum =3D GPIO_GET_DW_NUM (PadNumber); + + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + // + // Update pads which need to be unlocked + // + PadsToUnlock[DwNum] |=3D 0x1 << PadBitPosition; + + //Move to next item + Index++; + } + + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].= PadPerGroup - 1); DwNum++) { + // + // Unlock pads + // + if (PadsToUnlock[DwNum] !=3D 0) { + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadsToUnlock[DwNum]); + GpioUnlockPadCfgTxForGroupDw (Group, DwNum, PadsToUnlock[DwNum]); + } + } + + return EFI_SUCCESS; +} + +/** + This procedure will initialize multiple PCH GPIO pins + + @param[in] NumberofItem Number of GPIO pads to be updated + @param[in] GpioInitTableAddress GPIO initialization table + + @retval EFI_SUCCESS The function completed successfull= y + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioConfigurePch ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress + ) +{ + UINT32 Index; + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; + UINT32 PadCfgReg; + GPIO_GROUP_DW_DATA GroupDwData[GPIO_GROUP_DW_NUMBER]; + UINT32 DwNum; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + GPIO_PAD_OWN PadOwnVal; + CONST GPIO_INIT_CONFIG *GpioData; + UINT32 GroupIndex; + UINT32 PadNumber; + UINT32 DwRegIndex; + + PadOwnVal =3D GpioPadOwnHost; + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + Index =3D 0; + while (Index < NumberOfItems) { + + GpioData =3D &GpioInitTableAddress[Index]; + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); + + DEBUG_CODE_BEGIN(); + if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on= this chipset!\n", GpioData->GpioPad)); + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + DEBUG_CODE_END (); + + // + // Unlock pads for a given group which are going to be reconfigured + // + // + // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, lock = settings + // will get back to default only after G3 or DeepSx transition. On the= other hand GpioPads + // configuration is controlled by a configurable type of reset - PadRs= tCfg. This means that if + // PadRstCfg !=3D Powergood GpioPad will have its configuration locked= despite it being not the + // one desired by BIOS. Before reconfiguring all pads they will get un= locked. + // + GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, Index); + + ZeroMem (GroupDwData, sizeof (GroupDwData)); + // + // Loop through pads for one group. If pad belongs to a different grou= p then + // break and move to register programming. + // + while (Index < NumberOfItems) { + + GpioData =3D &GpioInitTableAddress[Index]; + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)= ) { + //if next pad is from different group then break loop + break; + } + + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); + + DEBUG_CODE_BEGIN (); + // + // Check if legal pin number + // + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible= range for group %d\n", PadNumber, GroupIndex)); + return EFI_INVALID_PARAMETER; + } + + // + // Check if selected GPIO Pad is not owned by CSME/ISH + // + GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal); + + if (PadOwnVal !=3D GpioPadOwnHost) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by host = (Group=3D%d, Pad=3D%d)!\n", GroupIndex, PadNumber)); + DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync b= etween CSME and BIOS configuration. \n")); + DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should not = do any configuration by BIOS.\n")); + //Move to next item + goto move_to_next_index; + } + + // + // Check if Pad enabled for SCI is to be in unlocked state + // + if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) =3D=3D Gpio= IntSci) && + ((GpioData->GpioConfig.LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_= LOCK_MASK) !=3D GpioPadConfigUnlock)){ + DEBUG ((DEBUG_ERROR, "GPIO ERROR: GPIO used for SCI is not unlocke= d!\n")); + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + DEBUG_CODE_END (); + + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); + // + // Get GPIO PADCFG register value from GPIO config data + // + GpioPadCfgRegValueFromGpioConfig ( + GpioData->GpioPad, + &GpioData->GpioConfig, + PadCfgDwReg, + PadCfgDwRegMask + ); + + // + // Write PADCFG DW0, DW1, DW2 registers + // + for (DwRegIndex =3D 0; DwRegIndex <=3D 2; DwRegIndex++) { + PadCfgReg =3D GpioGetGpioPadCfgAddressFromGpioPad (GpioData->GpioP= ad, DwRegIndex); + if (PadCfgReg !=3D 0) { + GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], PadCf= gReg, ~PadCfgDwRegMask[DwRegIndex], PadCfgDwReg[DwRegIndex]); + } + } + + // + // Get GPIO DW register values from GPIO config data + // + GpioDwRegValueFromGpioConfig ( + PadNumber, + &GpioData->GpioConfig, + GroupDwData + ); + + move_to_next_index: + //Move to next item + Index++; + } + + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex= ].PadPerGroup); DwNum++) { + // + // Write HOSTSW_OWN registers + // + if (GpioGroupInfo[GroupIndex].HostOwnOffset !=3D NO_REGISTER_FOR_PRO= PERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].HostSoftOwnRegMask, + GroupDwData[DwNum].HostSoftOwnReg + ); + } + + // + // Write GPI_GPE_EN registers + // + if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset !=3D NO_REGISTER_FOR_PR= OPERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiGpeEnRegMask, + GroupDwData[DwNum].GpiGpeEnReg + ); + } + + // + // Write GPI_NMI_EN registers + // + if (GpioGroupInfo[GroupIndex].NmiEnOffset !=3D NO_REGISTER_FOR_PROPE= RTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiNmiEnRegMask, + GroupDwData[DwNum].GpiNmiEnReg + ); + } else if (GroupDwData[DwNum].GpiNmiEnReg !=3D 0x0) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting = NMI\n", GroupIndex)); + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + } + + // + // Write GPI_SMI_EN registers + // + if (GpioGroupInfo[GroupIndex].SmiEnOffset !=3D NO_REGISTER_FOR_PROPE= RTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiSmiEnRegMask, + GroupDwData[DwNum].GpiSmiEnReg + ); + } else if (GroupDwData[DwNum].GpiSmiEnReg !=3D 0x0) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting = SMI\n", GroupIndex)); + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + } + + // + // Update Pad Configuration unlock data + // + if (GroupDwData[DwNum].ConfigUnlockMask) { + GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, GroupDwDat= a[DwNum].ConfigUnlockMask); + } + + // + // Update Pad Output unlock data + // + if (GroupDwData[DwNum].OutputUnlockMask) { + GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, GroupDwData[D= wNum].OutputUnlockMask); + } + } + } + + return EFI_SUCCESS; +} + +/** + This procedure will clear all status bits of any GPIO interrupts. + + @param[in] none + + @retval EFI_SUCCESS The function completed successfull= y + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioClearAllGpioInterrupts ( + VOID + ) +{ + GPIO_GROUP Group; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + GPIO_GROUP GpioGroupLowest; + GPIO_GROUP GpioGroupHighest; + UINT32 GroupIndex; + UINT32 GpioGroupInfoLength; + UINT32 DwNum; + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GpioGroupLowest =3D GpioGetLowestGroup (); + GpioGroupHighest =3D GpioGetHighestGroup (); + + for (Group =3D GpioGroupLowest; Group <=3D GpioGroupHighest; Group++) { + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + // + // Check if group has GPI IS register + // + if (GpioGroupInfo[GroupIndex].GpiIsOffset !=3D NO_REGISTER_FOR_PROPERT= Y) { + // + // Clear all GPI_IS Status bits by writing '1' + // + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has GPI_GPE_STS register + // + if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset !=3D NO_REGISTER_FOR_PRO= PERTY) { + // + // Clear all GPI_GPE_STS Status bits by writing '1' + // + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has SMI_STS register + // + if (GpioGroupInfo[GroupIndex].SmiStsOffset !=3D NO_REGISTER_FOR_PROPER= TY) { + // + // Clear all SMI_STS Status bits by writing '1' + // + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has NMI_STS register + // + if (GpioGroupInfo[GroupIndex].NmiStsOffset !=3D NO_REGISTER_FOR_PROPER= TY) { + // + // Clear all NMI_STS Status bits by writing '1' + // + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + } + return EFI_SUCCESS; +} + +/** + This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG = structure. + Structure contains fields that can be used to configure each pad. + Pad not configured using GPIO_INIT_CONFIG will be left with hardware def= ault values. + Separate fields could be set to hardware default if it does not matter, = except + GpioPad and PadMode. + Function will work in most efficient way if pads which belong to the sam= e group are + placed in adjacent records of the table. + Although function can enable pads for Native mode, such programming is d= one + by reference code when enabling related silicon feature. + + @param[in] NumberofItem Number of GPIO pads to be updated + @param[in] GpioInitTableAddress GPIO initialization table + + @retval EFI_SUCCESS The function completed successfull= y + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioConfigurePads ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress + ) +{ + EFI_STATUS Status; + + Status =3D GpioConfigurePch (NumberOfItems, GpioInitTableAddress); + + GpioClearAllGpioInterrupts (); + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Librar= y/PeiDxeSmmGpioLib/GpioLib.c new file mode 100644 index 0000000000..19daed97c0 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioLib.c @@ -0,0 +1,522 @@ +/** @file + This file contains routines for GPIO + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" +#include + +/** + This procedure will check if GpioGroup argument is correct and + supplied DW reg number can be used for this group to access DW registers= . + Function will check below conditions: + - Valid GpioGroup + - DwNum is has valid value for this group + + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (parameter app= licable in accessing whole register). + For group which has less then 32 pads per group = DwNum must be 0. + + @retval TRUE DW Reg number and GpioGroup is valid + @retval FALSE DW Reg number and GpioGroup is invalid +**/ +STATIC +BOOLEAN +GpioIsGroupAndDwNumValid ( + IN GPIO_GROUP Group, + IN UINT32 DwNum + ) +{ + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + + if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()) = || (GroupIndex >=3D GpioGroupInfoLength)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within ra= nge of possible groups for this PCH\n", GroupIndex)); + goto Error; + } + + // + // Check if DwNum argument does not exceed number of DWord registers + // resulting from available pads for certain group + // + if (DwNum > GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1))= { + goto Error; + } + + return TRUE; +Error: + ASSERT (FALSE); + return FALSE; +} + +// +// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() fu= nctions +// +typedef enum { + GpioHostOwnershipRegister =3D 0, + GpioGpeEnableRegister, + GpioGpeStatusRegister, + GpioSmiEnableRegister, + GpioSmiStatusRegister, + GpioNmiEnableRegister, + GpioPadConfigLockRegister, + GpioPadLockOutputRegister +} GPIO_REG; + +/** + This procedure will read GPIO register + + @param[in] RegType GPIO register type + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (param= eter applicable in accessing whole register). + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[out] ReadVal Read data + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad +**/ +STATIC +EFI_STATUS +GpioReadReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *ReadVal + ) +{ + UINT32 RegOffset; + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + + RegOffset =3D NO_REGISTER_FOR_PROPERTY; + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioHostOwnershipRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; + break; + case GpioGpeEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; + break; + case GpioGpeStatusRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; + break; + case GpioSmiEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; + break; + case GpioSmiStatusRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; + break; + case GpioNmiEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; + break; + case GpioPadConfigLockRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; + break; + case GpioPadLockOutputRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; + break; + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // + if ((RegType =3D=3D GpioPadConfigLockRegister) || (RegType =3D=3D GpioPa= dLockOutputRegister)) { + // + // PadConfigLock and OutputLock registers when used for group containi= ng more than 32 pads + // are not placed in a continuous way, e.g: + // 0x0 - PadConfigLock_DW0 + // 0x4 - OutputLock_DW0 + // 0x8 - PadConfigLock_DW1 + // 0xC - OutputLock_DW1 + // + RegOffset +=3D DwNum * 0x8; + } else { + RegOffset +=3D DwNum * 0x4; + } + + *ReadVal =3D GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], RegOf= fset); + + return EFI_SUCCESS; +} + +/** + This procedure will write GPIO register + + @param[in] RegType GPIO register type + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (param= eter applicable in accessing whole register). + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] RegAndMask Mask which will be AND'ed with register = value + @param[in] RegOrMask Mask which will be OR'ed with register v= alue + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad +**/ +STATIC +EFI_STATUS +GpioWriteReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 RegAndMask, + IN UINT32 RegOrMask + ) +{ + UINT32 RegOffset; + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadCfgLock; + BOOLEAN Lockable; + + Lockable =3D FALSE; + PadCfgLock =3D 0; + RegOffset =3D NO_REGISTER_FOR_PROPERTY; + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioHostOwnershipRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; + break; + case GpioGpeEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; + Lockable =3D TRUE; + break; + case GpioGpeStatusRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; + break; + case GpioSmiEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; + Lockable =3D TRUE; + break; + case GpioSmiStatusRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; + break; + case GpioNmiEnableRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; + Lockable =3D TRUE; + break; + case GpioPadConfigLockRegister: + case GpioPadLockOutputRegister: + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + if (Lockable) { + GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock); + if (PadCfgLock) { + // + // Check if for pads which are going to be reconfigured lock is set. + // + if ((~RegAndMask | RegOrMask) & PadCfgLock) { + // + // Unlock all pads for this Group DW reg for simplicity + // even if not all of those pads will have their settings reprogra= mmed + // + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock); + } else { + // + // No need to perform an unlock as pads which are going to be reco= nfigured + // are not in locked state + // + PadCfgLock =3D 0; + } + } + } + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // + RegOffset +=3D DwNum * 0x4; + + GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], RegOffset, Re= gAndMask,RegOrMask); + + if (Lockable && PadCfgLock) { + // + // Lock previously unlocked pads + // + GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock); + } + + return EFI_SUCCESS; +} + +/** + This procedure will write GPIO Lock/LockTx register using SBI. + + @param[in] RegType GPIO register (Lock or LockTx) + @param[in] Group GPIO group number + @param[in] DwNum Register number for current group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] LockRegAndMask Mask which will be AND'ed with Lock regi= ster value + @param[in] LockRegOrMask Mask which will be Or'ed with Lock regis= ter value + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad +**/ +STATIC +EFI_STATUS +GpioWriteLockReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 LockRegAndMask, + IN UINT32 LockRegOrMask + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 RegOffset; + UINT32 OldLockVal; + UINT32 NewLockVal; + UINT32 GroupIndex; + + OldLockVal =3D 0; + NewLockVal =3D 0; + + RegOffset =3D NO_REGISTER_FOR_PROPERTY; + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioPadConfigLockRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; + GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal); + break; + case GpioPadLockOutputRegister: + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal); + break; + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + NewLockVal =3D (OldLockVal & LockRegAndMask) | LockRegOrMask; + + return GpioInternalWriteLockRegister (NewLockVal, RegOffset, DwNum, Gpio= GroupInfo, GroupIndex); +} + +/** + This procedure will get Gpio Pad Ownership + + @param[in] GpioPad GPIO pad + @param[out] PadOwnVal Value of Pad Ownership + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioGetPadOwnership ( + IN GPIO_PAD GpioPad, + OUT GPIO_PAD_OWN *PadOwnVal + ) +{ + UINT32 Mask; + UINT32 RegOffset; + UINT32 GroupIndex; + UINT32 PadNumber; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadOwnRegValue; + + if (!GpioIsPadValid (GpioPad)) { + return EFI_INVALID_PARAMETER; + } + + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Check if selected register exists + // + if (GpioGroupInfo[GroupIndex].PadOwnOffset =3D=3D NO_REGISTER_FOR_PROPER= TY) { + *PadOwnVal =3D GpioPadOwnHost; + return EFI_UNSUPPORTED; + } + // + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. + // One DWord register contains information for 8 pads. + // + RegOffset =3D GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) = * 0x4; + + // + // Calculate pad bit position within DWord register + // + PadNumber %=3D 8; + Mask =3D (BIT1 | BIT0) << (PadNumber * 4); + + PadOwnRegValue =3D GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex],= RegOffset); + + *PadOwnVal =3D (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> (PadNumber * 4= )); + + return EFI_SUCCESS; +} + +/** + This procedure will check state of Pad Config Lock for pads within one g= roup + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLock register number for current g= roup. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[out] PadCfgLockRegVal Value of PadCfgLock register + Bit position - PadNumber + Bit value - 0: NotLocked, 1: Locked + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number +**/ +EFI_STATUS +GpioGetPadCfgLockForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *PadCfgLockRegVal + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioReadReg ( + GpioPadConfigLockRegister, + Group, + DwNum, + PadCfgLockRegVal + ); +} +/** + This procedure will check state of Pad Config Tx Lock for pads within on= e group + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLockTx register number for current= group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[out] PadCfgLockTxRegVal Value of PadCfgLockTx register + Bit position - PadNumber + Bit value - 0: NotLockedTx, 1: LockedTx + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number +**/ +EFI_STATUS +GpioGetPadCfgLockTxForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *PadCfgLockTxRegVal + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioReadReg ( + GpioPadLockOutputRegister, + Group, + DwNum, + PadCfgLockTxRegVal + ); +} +/** + This procedure will clear PadCfgLock for selected pads within one group. + This function should be used only inside SMI. + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLock register number for current g= roup. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] PadsToUnlock Bitmask for pads which are going to be u= nlocked, + Bit position - PadNumber + Bit value - 0: DoNotUnlock, 1: Unlock + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioUnlockPadCfgForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 PadsToUnlock + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioWriteLockReg ( + GpioPadConfigLockRegister, + Group, + DwNum, + ~PadsToUnlock, + 0 + ); +} +/** + This procedure will clear PadCfgLockTx for selected pads within one grou= p. + This function should be used only inside SMI. + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLockTx register number for current= group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] PadsToUnlockTx Bitmask for pads which are going to be u= nlocked, + Bit position - PadNumber + Bit value - 0: DoNotUnLockTx, 1: LockTx + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioUnlockPadCfgTxForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 PadsToUnlockTx + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioWriteLockReg ( + GpioPadLockOutputRegister, + Group, + DwNum, + ~PadsToUnlockTx, + 0 + ); +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioLibrary.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Li= brary/PeiDxeSmmGpioLib/GpioLibrary.h new file mode 100644 index 0000000000..2c2b4ee75c --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioLibrary.h @@ -0,0 +1,29 @@ +/** @file + Header file for GPIO Lib implementation. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_LIBRARY_H_ +#define _GPIO_LIBRARY_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Number of PADCFG_DW registers +// +#define GPIO_PADCFG_DW_REG_NUMBER 4 + +#endif // _GPIO_LIBRARY_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioNativeLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/= Library/PeiDxeSmmGpioLib/GpioNativeLib.c new file mode 100644 index 0000000000..4e4c53e588 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioNativeLib.c @@ -0,0 +1,177 @@ +/** @file + This file contains routines for GPIO native and chipset specific usage + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" + +/** + This procedure will get number of pads for certain GPIO group + + @param[in] Group GPIO group number + + @retval Value Pad number for group + If illegal group number then return 0 +**/ +UINT32 +GpioGetPadPerGroup ( + IN GPIO_GROUP Group + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 GroupIndex; + // + // Check if group argument exceeds GPIO GROUP INFO array + // + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); + + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) { + return 0; + } else { + return GpioGroupInfo[GroupIndex].PadPerGroup; + } +} + +/** + This procedure will get number of groups + + @param[in] none + + @retval Value Group number +**/ +UINT32 +GpioGetNumberOfGroups ( + VOID + ) +{ + UINT32 GpioGroupInfoLength; + + GpioGetGroupInfoTable (&GpioGroupInfoLength); + return GpioGroupInfoLength; +} +/** + This procedure will get lowest group + + @param[in] none + + @retval Value Lowest Group +**/ +GPIO_GROUP +GpioGetLowestGroup ( + VOID + ) +{ + return GpioGetGroupFromGroupIndex (0); +} +/** + This procedure will get highest group + + @param[in] none + + @retval Value Highest Group +**/ +GPIO_GROUP +GpioGetHighestGroup ( + VOID + ) +{ + return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1); +} + +/** + This procedure will get group number + + @param[in] GpioPad Gpio Pad + + @retval Value Group number +**/ +GPIO_GROUP +GpioGetGroupFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return GPIO_GET_GROUP_FROM_PAD (GpioPad); +} + +/** + This procedure will get group index (0 based) + + @param[in] GpioPad Gpio Pad + + @retval Value Group Index +**/ +UINT32 +GpioGetGroupIndexFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad); +} + +/** + This procedure will get group index (0 based) from group + + @param[in] GpioGroup Gpio Group + + @retval Value Group Index +**/ +UINT32 +GpioGetGroupIndexFromGroup ( + IN GPIO_GROUP GpioGroup + ) +{ + return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup); +} + +/** + This procedure will get group from group index (0 based) + + @param[in] GroupIndex Group Index + + @retval GpioGroup Gpio Group +**/ +GPIO_GROUP +GpioGetGroupFromGroupIndex ( + IN UINT32 GroupIndex + ) +{ + return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); +} + +/** + This procedure will get pad number (0 based) from Gpio Pad + + @param[in] GpioPad Gpio Pad + + @retval Value Pad Number +**/ +UINT32 +GpioGetPadNumberFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad); +} +/** + This procedure will return GpioPad from Group and PadNumber + + @param[in] Group GPIO group + @param[in] PadNumber GPIO PadNumber + + @retval GpioPad GpioPad +**/ +GPIO_PAD +GpioGetGpioPadFromGroupAndPadNumber ( + IN GPIO_GROUP Group, + IN UINT32 PadNumber + ) +{ + if (IsPchLp ()) { + return GPIO_PAD_DEF (Group,PadNumber); + } else { + return GPIO_PAD_DEF (Group,PadNumber); + } +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/= Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf new file mode 100644 index 0000000000..21fb4417c1 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/PeiDxeSmmGpioLib.inf @@ -0,0 +1,44 @@ +## @file +# Component description file for the PeiDxeSmmGpioLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION =3D 0x00010017 +BASE_NAME =3D PeiDxeSmmGpioLib +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662BD7B763F2 +VERSION_STRING =3D 1.0 +MODULE_TYPE =3D BASE +LIBRARY_CLASS =3D GpioLib +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PrintLib +PchCycleDecodingLib +PchSbiAccessLib +PmcPrivateLib +GpioPrivateLib +GpioHelpersLib + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +GpioLib.c +GpioNativeLib.c +GpioInit.c +GpioLibrary.h diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/AlderlakeSi= liconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpers= LibNull.c new file mode 100644 index 0000000000..b4b6c14329 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpi= oHelpersLibNull/BaseGpioHelpersLibNull.c @@ -0,0 +1,51 @@ +/** @file + This file contains NULL implementation for GPIO Helpers Lib + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include + +/** + This procedure stores GPIO group data about pads which PadConfig needs t= o be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o 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 + ) +{ + return EFI_SUCCESS; +} + +/** + This procedure stores GPIO group data about pads which Output state need= s 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 pe= r group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o 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 + ) +{ + return EFI_SUCCESS; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/Alderlake= SiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpe= rsLibNull.inf new file mode 100644 index 0000000000..91d81af4b9 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpi= oHelpersLibNull/BaseGpioHelpersLibNull.inf @@ -0,0 +1,25 @@ +## @file +# Component description file for the NULL GpioHelpersLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION =3D 0x00010017 +BASE_NAME =3D BaseGpioHelpersLib +FILE_GUID =3D AB282608-2A50-4AE3-9242-64064ECF40D4 +VERSION_STRING =3D 1.0 +MODULE_TYPE =3D BASE +LIBRARY_CLASS =3D GpioHelpersLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +BaseGpioHelpersLibNull.c + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h b/Silicon/Intel/Alde= rlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNat= ivePrivateLibInternal.h new file mode 100644 index 0000000000..480990cb62 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioNativePrivateLibInternal.h @@ -0,0 +1,48 @@ +/** @file + Header file for GPIO Private Lib Internal functions. + + Copyright (c) 2022, 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 + + +/** + This function provides recommended GPIO IO Standby configuration for a g= iven native function + + @param[in] PadFunction PadFunction for a specific native sig= nal. Please refer to GpioNativePads.h + @param[out] StandbyState IO Standby State for specified native= function + @param[out] StandbyTerm IO Standby Termination for specified = native function + + @retval Status +**/ +EFI_STATUS +GpioGetFunctionIoStandbyConfig ( + IN UINT32 PadFunction, + OUT GPIO_IOSTANDBY_STATE *StandbyState, + OUT GPIO_IOSTANDBY_TERM *StandbyTerm + ); + +/** + This procedure will calculate PADCFG register value based on GpioConfig = data + For physical/local/hard (not virtual) GPIO pads + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfigHardGpio ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ); + +#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/AlderlakeSiliconPk= g/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c new file mode 100644 index 0000000000..7d5fa9fafd --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioPrivateLib.c @@ -0,0 +1,267 @@ +/** @file + This file contains GPIO routines for RC usage + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#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 chipset + + @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 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 R= egisters + @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_PROPERT= Y) { + 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: GPIO not owned by host!\n")); + return EFI_INVALID_PARAMETER; + } + DEBUG_CODE_END (); + + *GpiSmiBitOffset =3D (UINT8)(PadNumber % 32); + + HostSwOwnRegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset + (PadNum= ber / 32) * 0x4; + *GpiHostSwOwnRegAddress =3D PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].C= ommunity, HostSwOwnRegOffset); + + SmiStsRegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumber = / 32) * 0x4; + *GpiSmiStsRegAddress =3D PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Comm= unity, SmiStsRegOffset); + + return EFI_SUCCESS; +} + +/** + 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 lib= API + @retval FALSE GPIO pad is invalid and cannot be used with GPI= O lib API +**/ +BOOLEAN +GpioIsPadValid ( + IN GPIO_PAD GpioPad + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadNumber; + UINT32 GroupIndex; + + if (!GpioIsCorrectPadForThisChipset (GpioPad)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on t= his chipset!\n", GpioPad)); + goto Error; + } + + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Check if legal pin number + // + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range of gro= up (max: %d)\n", + = PadNumber, + = GpioGroupInfo[GroupIndex].PadPerGroup)); + 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; + + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Create Pad Configuration register offset + // + PadCfgReg =3D GpioGetGpioPadCfgAddressFromGpioPad (GpioPad, DwReg); + return GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], PadCfgReg); +} + + +/** + This procedure will calculate PADCFG register value based on GpioConfig = data + For physical/local/hard (not virtual) GPIO pads + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfigHardGpio ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ) +{ + // + // Configure how interrupt is triggered (RxEvCfg) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & B_GPIO_INT_CON= FIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) =3D=3D GpioHardwa= reDefault) ? 0x0 : B_GPIO_PCR_RX_LVL_EDG); + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_I= NT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX= _LVL_EDG); + + // + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & B_GPIO_INT_CON= FIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) =3D=3D GpioHa= rdwareDefault) ? 0x0 : (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE = | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE)); + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_I= NT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PC= R_RX_NMI_ROUTE); + + // + // Configure GPIO direction (GPIORxDis and GPIOTxDis) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & B_GPIO_DIRECTION_DIR= _MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 := (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS)); + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK= ) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << N_GPIO_PCR_TXDIS); + + // + // Configure GPIO input inversion (RXINV) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & B_GPIO_DIRECTION_INV= _MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 = : B_GPIO_PCR_RXINV); + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK= ) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << N_GPIO_PCR_RXINV); + + // + // Configure GPIO output state (GPIOTxState) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK= ) >> N_GPIO_OUTPUT_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_= TX_STATE); + PadCfgDwReg[0] |=3D (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> = (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE); + + // + // Configure GPIO RX raw override to '1' (RXRAW1) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OtherSettings & B_GPIO_OTHER_CON= FIG_RXRAW_MASK) >> N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) =3D=3D GpioHardwareDe= fault) ? 0x0 : B_GPIO_PCR_RX_RAW1); + PadCfgDwReg[0] |=3D (((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_R= XRAW_MASK) >> (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW= 1); + + // + // Configure GPIO Pad Mode (PMode) + // + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) = >> N_GPIO_PAD_MODE_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_= PAD_MODE); + PadCfgDwReg[0] |=3D (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> (N= _GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE); + + // + // Configure GPIO termination (Term) + // + PadCfgDwRegMask[1] |=3D ((((GpioConfig->ElectricalConfig & B_GPIO_ELECTR= ICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_P= OS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM); + PadCfgDwReg[1] |=3D (((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_= CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS += 1)) << N_GPIO_PCR_TERM); + + return EFI_SUCCESS; +} + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c b/Silicon/Intel/AlderlakeSilico= nPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.= c new file mode 100644 index 0000000000..3d16fd2acd --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioPrivateLibPch.c @@ -0,0 +1,172 @@ +/** @file + This file contains hard/physical/local (not virtual) GPIO information + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "GpioNativePrivateLibInternal.h" + +/** + This procedure calculates Pad Configuration Register DW offset + + @param[in] GpioPad GPIO pad + @param[in] DwReg Index of the configuration register + + @retval DW Register offset +**/ +UINT32 +GpioGetGpioPadCfgAddressFromGpioPad ( + IN GPIO_PAD GpioPad, + IN UINT32 DwReg + ) +{ + 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 + DwReg * 4 = + S_GPIO_PCR_PADCFG * PadNumber; + + return PadCfgRegAddress; +} + +/** + This procedure reads GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + + @retval Register value or "F"s in case of errors +**/ +UINT32 +GpioRegisterAccessRead32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register + ) +{ + return MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register))= ; +} + +/** + This procedure writes GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + @param[in] AndValue And value + @param[in] OrValue Or value + + @retval EFI_SUCCESS Operation completed successfully +**/ +EFI_STATUS +GpioRegisterAccessAndThenOr32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register, + IN UINT32 AndValue, + IN UINT32 OrValue + ) +{ + MmioAndThenOr32 ( + PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register), + AndValue, + OrValue + ); + return EFI_SUCCESS; +} + +/** + This procedure will calculate PADCFG register value based on GpioConfig = data + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfig ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ) +{ + return GpioPadCfgRegValueFromGpioConfigHardGpio (GpioPad, GpioConfig, Pa= dCfgDwReg, PadCfgDwRegMask); +} + +/** + This procedure will write GPIO Lock/LockTx register + - For PCH SBI message is used. + + @param[in] RegValue GPIO register (Lock or LockTx) value + @param[in] RegOffset GPIO register (Lock or LockTx) base offs= et + @param[in] DwNum Register number for current group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] GroupIndex GPIO group index in the GpioGroupInfo ta= ble + + @retval EFI_SUCCESS The function completed successfully + EFI_UNSUPPORTED Feature is not supported for this group = or pad +**/ +EFI_STATUS +GpioInternalWriteLockRegister ( + IN UINT32 RegValue, + IN UINT32 RegOffset, + IN UINT32 DwNum, + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 GroupIndex + ) +{ + EFI_STATUS Status; + PCH_SBI_OPCODE Opcode; + UINT8 Response; + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // PadConfigLock and OutputLock registers when used for group containing= more than 32 pads + // are not placed in a continuous way, e.g: + // 0x0 - PadConfigLock_DW0 + // 0x4 - OutputLock_DW0 + // 0x8 - PadConfigLock_DW1 + // 0xC - OutputLock_DW1 + // + RegOffset +=3D DwNum * 0x8; + + if (IsGpioLockOpcodeSupported ()) { + Opcode =3D GpioLockUnlock; + } else { + Opcode =3D PrivateControlWrite; + } + + Status =3D PchSbiExecutionEx ( + GpioGroupInfo[GroupIndex].Community, + RegOffset, + Opcode, + FALSE, + 0x000F, + 0x0000, + 0x0000, + &RegValue, + &Response + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c b/Silicon/Intel/AlderlakeSilic= onPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer= 2.c new file mode 100644 index 0000000000..1348643553 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioPrivateLibVer2.c @@ -0,0 +1,81 @@ +/** @file + This file contains VER2 specific GPIO information + + Copyright (c) 2022, 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 +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] =3D { + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= B_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_B_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_B_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_B_PAD_MAX}, //TGL PCH-LP GPP_B + {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= A_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_A_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_A_PAD_MAX}, //TGL PCH-LP GPP_A + {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_R_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= R_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_R_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_R_PAD_MAX}, //TGL PCH-LP GPP_R + {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPD_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IS, = R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_= GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPD_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX, = R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPD_PAD_MAX}, //TGL PCH-LP GPD + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_S_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= S_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_S_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_S_PAD_MAX}, //TGL PCH-LP GPP_S + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= H_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_L= P_GPIO_PCR_GPP_H_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_H_PAD_MAX}, //TGL PCH-LP GPP_H + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= D_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_D_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_D_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_D_PAD_MAX}, //TGL PCH-LP GPP_D + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= C_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_C_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_C_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_C_PAD_MAX}, //TGL PCH-LP GPP_C + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= F_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_F_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_F_PAD_MAX}, //TGL PCH-LP GPP_F + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= E_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_E_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_E_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_E_PAD_MAX}, //TGL PCH-LP GPP_E +}; + +/** + 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 + ) +{ + *GpioGroupInfoTableLength =3D ARRAY_SIZE (mPchLpGpioGroupInfo); + return mPchLpGpioGroupInfo; +} + +/** + Get GPIO Chipset ID specific to PCH generation and series +**/ +UINT32 +GpioGetThisChipsetId ( + VOID + ) +{ + return GPIO_VER2_LP_CHIPSET_ID; +} + +/** + Check if 0x13 opcode supported for writing to GPIO lock unlock register + + @retval TRUE It's supported + @retval FALSE It's not supported +**/ +BOOLEAN +IsGpioLockOpcodeSupported ( + VOID + ) +{ + return TRUE; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf b/Silicon/Intel/Ald= erlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxe= SmmGpioPrivateLibVer2.inf new file mode 100644 index 0000000000..2e9a6b7336 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf @@ -0,0 +1,40 @@ +## @file +# Component description file for the PeiDxeSmmGpioPrivateLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] +INF_VERSION =3D 0x00010017 +BASE_NAME =3D PeiDxeSmmGpioPrivateLibVer2 +FILE_GUID =3D 680A81B0-A087-4687-B5B4-146DA30042D6 +VERSION_STRING =3D 1.0 +MODULE_TYPE =3D BASE +LIBRARY_CLASS =3D GpioPrivateLib +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + + +[LibraryClasses] + BaseLib + IoLib + DebugLib + PmcLib + PchInfoLib + GpioLib + GpioHelpersLib + + +[Packages] + MdePkg/MdePkg.dec + AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] + GpioPrivateLib.c + GpioPrivateLibVer2.c + GpioPrivateLibPch.c diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/AlderlakeSiliconPkg/I= pBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c new file mode 100644 index 0000000000..9d47e6bfd5 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= HelpersLib/PeiGpioHelpersLib.c @@ -0,0 +1,218 @@ +/** @file + This file contains routines for PEI GPIO Helpers Lib + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#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 selected = 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 pe= r 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 (GpioGetG= roupFromGroupIndex (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 da= ta. + If HOB doesn't exist it will be created. + + @param[out] GpioUnlockData pointer to GPIO Unlock data structur= e + + @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 stores GPIO group data about pads which PadConfig needs t= o be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads pe= r group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o 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 need= s 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 pe= r group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o 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; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/AlderlakeSiliconPkg= /IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf new file mode 100644 index 0000000000..c1886b22f9 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= HelpersLib/PeiGpioHelpersLib.inf @@ -0,0 +1,46 @@ +## @file +# Component description file for the PeiGpioHelpersLib +# +# Copyright (c) 2022, 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 the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +HobLib +GpioLib +ConfigBlockLib +PeiServicesLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +PeiGpioHelpersLib.c + + +[Guids] +gGpioLibUnlockHobGuid + +[Ppis] +gSiPreMemPolicyPpiGuid --=20 2.36.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108688): https://edk2.groups.io/g/devel/message/108688 Mute This Topic: https://groups.io/mt/101373944/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-