From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com []) by mx.groups.io with SMTP id smtpd.web11.2882.1612410873568678350 for ; Wed, 03 Feb 2021 19:54:34 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=layMH5xp; spf=fail (domain: intel.com, ip: , mailfrom: nathaniel.l.desimone@intel.com) IronPort-SDR: VjRwakw7Wbi5x5rzkjLgX40zg0FrK264Qfw1GsTPnkH1cXClKPRPFXQu6Arf5Cp1554tkv+vic 0k4GNtMbJkQQ== X-IronPort-AV: E=McAfee;i="6000,8403,9884"; a="168274805" X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="168274805" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 19:54:33 -0800 IronPort-SDR: vYnYZ+2aSX9YT57Yb2d9piIZpubeq1r4a05Hbtfj1BR+/l6YX3mdfAeArUCXqbPfHpKT6fuFsU shEzabFlqvTQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="371932177" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by fmsmga008.fm.intel.com with ESMTP; 03 Feb 2021 19:54:32 -0800 Received: from fmsmsx607.amr.corp.intel.com (10.18.126.87) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Wed, 3 Feb 2021 19:54:32 -0800 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx607.amr.corp.intel.com (10.18.126.87) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2 via Frontend Transport; Wed, 3 Feb 2021 19:54:32 -0800 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (104.47.57.169) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Wed, 3 Feb 2021 19:54:31 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hjwcflZ73L1cZ+AXSWK8slB5hh6cwOhpQElNegdCTXVSJ0i++9mwANTvx8/TT4rAL/u9U/adcxL/Mk/Avxyzm5AoNUV0Z71IaTB7RP+AWxyb3l7KKG01HdPM6biKN1JB+iJIiTWejtt17a0ct0mKiF9DRUDp7VFS6EN297YTwqaHXKvYBieqc183TYBPPUslrqm2tEoVcXMAhUOjcsUnjKYPhQXfrtQrHfN/xOm/ie9wuTF8m32KOAydtN8thbNYtqx0ZILOffAgOS6+wUlQj1xIbAnJLFFbf477kptlRhI/fHrsWE19tgeVEl+CFi77d3Tjd2xg5YQNbGVUI8WJqA== 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-SenderADCheck; bh=J/P7P/vmEYriL5rlkFuvHOKIPTrmrqI0talVhJQnMCQ=; b=M3PouQ6KCI0jKREfr6n5XDcCouLKZ9VzjL7JNx/SiQxnEajAlAKyHwYEX3SYmQqA8x3/AK7nFHfgyasPUPQ+FKuVQsTXr8oBCfpNUPHqXZxkKDiW6Th+6RUZdw+VLn/1DCQf8ALs7FIXIgyB389phSKlEb3gc0HqPeq3Hu7dgPMSlC/HokgQtOj7gbQ8HNXfKTPHYPqfqozA5AXM6cKWRPUJ0S8E+Nt5WVTpzOy+r/eSK8TiEKMqVT215h2XEnwiqz6/jaiCOJOAkfqb0tXOvmp+L4lNyEgkG/OEJ9pQ3cOK3cwtzXjeD71zp9Xs76nM+wK0q+U4F+1Z9pEwg914pw== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=J/P7P/vmEYriL5rlkFuvHOKIPTrmrqI0talVhJQnMCQ=; b=layMH5xpM3+JtGq4H8QeSPLMmyh6IYy+CU4D5DAM0b6dtgesXiJDTE05itzJqXIQ++oy7pF6/QX5JLrNl02b8+JE6ertObITh7Ec3rA78wge+BDk9NRrlRkyfrvsb+tq1mxIOJSfbg939ygpsOg/OIEuh4oTj871VEIx7P62u1E= Received: from BN6PR1101MB2147.namprd11.prod.outlook.com (2603:10b6:405:57::23) by BN6PR11MB1329.namprd11.prod.outlook.com (2603:10b6:404:47::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3805.19; Thu, 4 Feb 2021 03:54:26 +0000 Received: from BN6PR1101MB2147.namprd11.prod.outlook.com ([fe80::203e:ed6b:a572:6453]) by BN6PR1101MB2147.namprd11.prod.outlook.com ([fe80::203e:ed6b:a572:6453%3]) with mapi id 15.20.3805.024; Thu, 4 Feb 2021 03:54:26 +0000 From: "Nate DeSimone" To: "Luo, Heng" , "devel@edk2.groups.io" CC: "Chaganty, Rangasai V" Subject: Re: [PATCH 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Thread-Topic: [PATCH 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Thread-Index: AQHW+DrXUFCnN+fSQ0aBbR+1jStsvapHYlPQ Date: Thu, 4 Feb 2021 03:54:26 +0000 Message-ID: References: <20210201013657.1833-1-heng.luo@intel.com> <20210201013657.1833-17-heng.luo@intel.com> In-Reply-To: <20210201013657.1833-17-heng.luo@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-reaction: no-action dlp-version: 11.5.1.3 dlp-product: dlpe-windows authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [50.53.190.176] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 129342fb-3909-432d-4e94-08d8c8c090f2 x-ms-traffictypediagnostic: BN6PR11MB1329: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:5516; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 0oWWB5HPmJZOjcoJOUw00t7EzOqr+g43UUGx6JeGAyzQodAMYNpZqRLfXlrMhuIq1NeUY30ogcd6nwbipjEghmjjt4rZz/+6WUNVE5xgT6ceiWwEVMi57p0fewyLB390eBH+OhrQ20KTafgmMdMmLCnks8ILH75OPXdyWpyQKe3p0A4ir0EjiohshRV+C95cFrwKjGoeBVWGkMRJhtX4Cr1Snzh92qrdsC3i/Z3V62UPaaTLS5KrDgNifmXz/wEG+3yO1KiZyqOduSm3VJRtcu6hA/PGWzaz1jcqLoGnnt4Cpv1SA123vZBV0Vp8t2k4a14x5ipwu7k3HXnePclWCbkx0twg9ItO7qcyeh7TAgbHzWfpJSV1wjAVEo/q6IOdciHrJcGP4DWeY5zwNBmsVmceD2PBwwDXG2xevJES2KixiyTUo3kIZAX4c3uyrD2XvwJ3AEVNAH3AV/YWJbFc2S0RzXk+lsmccl2QZxfCAIkta9cIo/hwa2WgED1lISQGjeHE//Ej+gz0cBK/VXjCPsWd+xeMh4nwtSGEqGVApWxqlxeHSO+0cvHp/IOR5uIbFlWmKI6Gyqs7nWWLONUzaBZvmvLNHo7yhxFZ9yJzdeqgJHj8aTOaF06IzMxdMcQ1dgi6BZm7R3KP9esJtPEYOQ== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN6PR1101MB2147.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(6029001)(396003)(346002)(136003)(366004)(376002)(39860400002)(7696005)(966005)(52536014)(86362001)(83380400001)(76116006)(66476007)(9686003)(66446008)(8936002)(26005)(107886003)(478600001)(19627235002)(5660300002)(64756008)(4326008)(186003)(110136005)(55016002)(71200400001)(66946007)(8676002)(53546011)(33656002)(2906002)(30864003)(66556008)(316002)(6506007)(569008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?oEKEgDZHHW21EnZksu1/laC1p+cfDRx+kiSG1/PySW2ZqeEFonNbZYi7Xm40?= =?us-ascii?Q?O0gpxjhB4Jb/r0ReLlQzEzW6oCOIdUNuVAOa7QrQBq06jwDVpPlHUbXPrVwC?= =?us-ascii?Q?xnZZyLlxzmOhy3VEgWn35qCBrpyt5p9aHKqcKyKeeLidcclphxum6ABtDZpH?= =?us-ascii?Q?ntGAB3K11Nc6pc3jMOuQXvDhmh9dkIKh75G/XkSZDmUmds7iZwC+gU7d83uh?= =?us-ascii?Q?bfo8cJ2mSFvSXKMm01EGul4xyuGDnubTYxEpL/1ALCoB6H0QRTXKF2fTuO0d?= =?us-ascii?Q?iPhcuqlZTeeLGQSxVWz6C96ft6xWInwDBgZaBIT4+bnR8sGMUBgBFgz3taVO?= =?us-ascii?Q?bD0L+UULoWpnePYzVxIYUX2cK2IO1YRzJgJlpDGagIPgV2kYSOIWqfcz2cfF?= =?us-ascii?Q?r3dOcE8nWDtFRME5fl3+yPqViI0LZwoj0d+ZShODXZf9cnEl90sEmKis5VHo?= =?us-ascii?Q?4n/Cct2u8YiDt72gIYwG4CdeOHf9txn/SSUrpHmaVOrl2KnosilEznX7ODJO?= =?us-ascii?Q?mXpnYHZd+IYd9AlVUtW0OvBfIiSpW3zaki34DT5oSkL/8+F8U+1GSe8guxU0?= =?us-ascii?Q?Gm2rOhAyHHey5ceTVDF6EHU4dikPBSQPJJ/Ctlf1/5qwAsKEx0CKmovrqO1D?= =?us-ascii?Q?RKiltiZogLDw2lSzRL2KPOeIr2ao5UaBKfD+VrlzD1Edr7EUHZRlzUGtL+A0?= =?us-ascii?Q?Miuahnk/WCKaSWsfp9n5ECcP1Au/+FI3hSDdWmzOaDms9r+HN45NFo6RFa/g?= =?us-ascii?Q?PSYs0C7+Id5u8xKC4ifud3NrqAfG8LjkGMKuuTMXdNOLpVaTyy/wlWYxWVNn?= =?us-ascii?Q?Yg6pcXv44kmWQmEN73HU8iNTqTrt1eSeLeq+PjrUJFMty7fDEqrUOce8S+bM?= =?us-ascii?Q?x9skE5ZRh12/7sE6pieZhp2Hn6sGlRl+HCpEc7dAgBsFY7cCZDyCjRwJU+dD?= =?us-ascii?Q?urQ/c3Ec0VoKZ2NsQZZM4fKqqk/P/cvEkUo5aiIVH3KCpuDG47eZxNSbJ+If?= =?us-ascii?Q?VbRagVi3qPZfh8wRNviyimxBlRUiviog6/FNVZWrc3UDgrp/dfWKhU5Fe2NU?= =?us-ascii?Q?rwbckoVeAs+hcEqPVeCzZ5qgeAMItzDKYKr1zOSssyqbgjSvSmZ0q5wCGBap?= =?us-ascii?Q?LcZTHO2xY8/EJBSnDKaaq8W2mt/AtorcUgcljUVuEt2EnhHY4lnLmtpJzbzB?= =?us-ascii?Q?/XYha/A+Q6nxc4Yz3wfZM0HsCt4s+3cXBxH6kpzuTijpRfd67c0eZtu/z+8I?= =?us-ascii?Q?wc0Qauz+10rVfZ5cMc2Doj+/CTijlXtespuTcZb/nPBRh3EAFKOk0CmHfpgn?= =?us-ascii?Q?8CkFm/bCH6wtIx4KCUJIqMAF?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN6PR1101MB2147.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 129342fb-3909-432d-4e94-08d8c8c090f2 X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Feb 2021 03:54:26.1101 (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: +l6CltNyi1jvScOvGwWG4EpYaFB3Q4T6lESZYaCtupz5gg0giFrzytqGPxzw1KNmqG9UhGxgnnvE9vQySMgBljwDN4Zaq0ELLWYDnakrWwI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR11MB1329 Return-Path: nathaniel.l.desimone@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Nate DeSimone > -----Original Message----- > From: Luo, Heng > Sent: Sunday, January 31, 2021 5:37 PM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V ; Desimone, > Nathaniel L > Subject: [PATCH 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3171 >=20 > Adds the following files: > * IpBlock/Gpio/Include > * IpBlock/Gpio/IncludePrivate > * IpBlock/Gpio/Library > * IpBlock/Gpio/LibraryPrivate >=20 > Cc: Sai Chaganty > Cc: Nate DeSimone > Signed-off-by: Heng Luo > --- >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckC= o > nflictLib.h | 43 ++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Dxe= Gpi > oPolicyLib.h | 55 +++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpi= oH > elpersLib.h | 105 > +++++++++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpi= oN > ameBufferLib.h | 23 +++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpi= oPri > vateLib.h | 1197 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfl= ic > tLib/BaseGpioCheckConflictLib.c | 140 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfl= ic > tLib/BaseGpioCheckConflictLib.inf | 29 +++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfl= ic > tLibNull/BaseGpioCheckConflictLibNull.c | 35 +++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfl= ic > tLibNull/BaseGpioCheckConflictLibNull.inf | 26 ++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/G > pioInit.c | 558 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/G > pioLib.c | 2387 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/G > pioLibrary.h | 82 +++++++++++++++++++++= +++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/G > pioNames.c | 86 +++++++++++++++++++++= +++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/G > pioNativeLib.c | 193 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/P > eiDxeSmmGpioLib.inf | 49 ++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHel= pe > rsLibNull/BaseGpioHelpersLibNull.c | 119 > ++++++++++++++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHel= pe > rsLibNull/BaseGpioHelpersLibNull.inf | 26 ++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioName > BufferLib/DxeGpioNameBufferLib.inf | 32 ++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioName > BufferLib/GpioNameBufferDxe.c | 19 +++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPoli= cyL > ib/DxeGpioPolicyLib.c | 87 > ++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPoli= cyL > ib/DxeGpioPolicyLib.inf | 31 ++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGp= i > oPrivateLib/GpioNamesVer2.c | 88 > +++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGp= i > oPrivateLib/GpioPrivateLib.c | 395 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGp= i > oPrivateLib/GpioPrivateLibVer2.c | 131 > ++++++++++++++++++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGp= i > oPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf | 46 +++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelp= ers > Lib/PeiGpioHelpersLib.c | 413 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelp= ers > Lib/PeiGpioHelpersLib.inf | 48 ++++++++++++++++++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioName= B > ufferLib/GpioNameBufferPei.c | 67 ++++++++++++++++++++++= +++ >=20 > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioName= B > ufferLib/PeiGpioNameBufferLib.inf | 35 +++++++++++++ > 29 files changed, 6545 insertions(+) >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioChec= kC > onflictLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioChec= kC > onflictLib.h > new file mode 100644 > index 0000000000..5e3dd90ae6 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioChec= kC > onflictLib.h > @@ -0,0 +1,43 @@ > +/** @file >=20 > + Header file for checking Gpio PadMode conflict. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _GPIO_CHECK_CONFLICT_LIB_H_ >=20 > +#define _GPIO_CHECK_CONFLICT_LIB_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +extern EFI_GUID gGpioCheckConflictHobGuid; >=20 > + >=20 > +typedef struct { >=20 > + GPIO_PAD GpioPad; >=20 > + UINT32 GpioPadMode:5; >=20 > + UINT32 Reserved:27; >=20 > +} GPIO_PAD_MODE_INFO; >=20 > + >=20 > +/** >=20 > + Check Gpio PadMode conflict and report it. >=20 > +**/ >=20 > +VOID >=20 > +GpioCheckConflict ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This library will create one Hob for each Gpio config table >=20 > + without PadMode is GpioHardwareDefault >=20 > + >=20 > + @param[in] GpioDefinition Point to Platform Gpio table >=20 > + @param[in] GpioTableCount Number of Gpio table entries >=20 > +**/ >=20 > +VOID >=20 > +CreateGpioCheckConflictHob ( >=20 > + IN GPIO_INIT_CONFIG *GpioDefinition, >=20 > + IN UINT32 GpioTableCount >=20 > + ); >=20 > + >=20 > +#endif // _GPIO_CHECK_CONFLICT_LIB_H_ >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/D= xe > GpioPolicyLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/D= xe > GpioPolicyLib.h > new file mode 100644 > index 0000000000..d86e6624b7 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/D= xe > GpioPolicyLib.h > @@ -0,0 +1,55 @@ > +/** @file >=20 > + DXE Gpio policy library. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _DXE_GPIO_POLICY_LIB_H_ >=20 > +#define _DXE_GPIO_POLICY_LIB_H_ >=20 > + >=20 > +#include >=20 > + >=20 > +/** >=20 > + Print GPIO_DXE_CONFIG and serial out. >=20 > + >=20 > + @param[in] PchPolicy Pointer to a PCH_POLICY_PROTOCOL >=20 > +**/ >=20 > +VOID >=20 > +GpioDxePrintConfig ( >=20 > + IN PCH_POLICY_PROTOCOL *PchPolicy >=20 > + ); >=20 > + >=20 > +/** >=20 > + Load DXE Config block default for GPIO >=20 > + >=20 > + @param[in] ConfigBlockPointer Pointer to config block >=20 > +**/ >=20 > +VOID >=20 > +GpioDxeLoadConfigDefault ( >=20 > + IN VOID *ConfigBlockPointer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get Gpio config block table size. >=20 > + >=20 > + @retval Size of config block >=20 > +**/ >=20 > +UINT16 >=20 > +GpioDxeGetConfigBlockTotalSize ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + Add Gpio ConfigBlock. >=20 > + >=20 > + @param[in] ConfigBlockTableAddress The pointer to config block tabl= e >=20 > + >=20 > + @retval EFI_SUCCESS The policy default is initialize= d. >=20 > + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create > buffer >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioDxeAddConfigBlock ( >=20 > + IN VOID *ConfigBlockTableAddress >=20 > + ); >=20 > + >=20 > +#endif // _DXE_GPIO_POLICY_LIB_H_ >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > HelpersLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > HelpersLib.h > new file mode 100644 > index 0000000000..d2a8d24c8a > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > HelpersLib.h > @@ -0,0 +1,105 @@ > +/** @file >=20 > + Header file for GPIO Helpers Lib implementation. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _GPIO_HELPERS_LIB_H_ >=20 > +#define _GPIO_HELPERS_LIB_H_ >=20 > + >=20 > +#include >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO pad unlock information >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] GpioLockConfig GPIO Lock Configuration >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreUnlockData ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_LOCK_CONFIG GpioLockConfig >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which PadConfig needs > to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToLock DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockPadConfigData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which Output state > needs to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToLock DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockOutputData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which PadConfig is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockPadConfigMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which Output is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockOutputMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ); >=20 > + >=20 > +/** >=20 > + Returns Gpio Override Level1 Information >=20 > + >=20 > + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioOverrideLevel1Enabled ( >=20 > + VOID >=20 > + ); >=20 > +#endif // _GPIO_HELPERS_LIB_H_ >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > NameBufferLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > NameBufferLib.h > new file mode 100644 > index 0000000000..c60709c637 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > NameBufferLib.h > @@ -0,0 +1,23 @@ > +/** @file >=20 > + Header file for GpioMemLib. This library provides GpioLib with static > memory to hold GpioName. >=20 > + Static memory is handled differently in PEI and DXE phase. For PEI pre > mem we use private HOB to store >=20 > + gpio name since .data section is read only. For PEI post mem and DXE > simple static buffer is used. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _GPIO_NAME_BUFFER_LIB_H_ >=20 > +#define _GPIO_NAME_BUFFER_LIB_H_ >=20 > + >=20 > +#define GPIO_NAME_LENGTH_MAX 32 >=20 > + >=20 > +/** >=20 > + Returns pointer to the global buffer to be used by GpioNamesLib >=20 > + >=20 > + @retval CHAR8* Pointer to the buffer >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioGetStaticNameBuffer ( >=20 > + VOID >=20 > + ); >=20 > +#endif >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > PrivateLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > PrivateLib.h > new file mode 100644 > index 0000000000..be41f80c24 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/G= pio > PrivateLib.h > @@ -0,0 +1,1197 @@ > +/** @file >=20 > + Header file for GpioPrivateLib. >=20 > + All function in this library is available for PEI, DXE, and SMM, >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _GPIO_PRIVATE_LIB_H_ >=20 > +#define _GPIO_PRIVATE_LIB_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + GPIO Standby State configuration >=20 > + Standby State options for GPIO Pads >=20 > +**/ >=20 > +typedef enum { >=20 > + GpioIosStateDefault =3D 0x0, >=20 > + GpioIosStateLatchLastValue =3D (0x0 << 1) | 0x01, ///< Latch last va= lue > driven on TX, TX Enable and RX Enable >=20 > + GpioIosStateTx0Rx0RxDis =3D (0x1 << 1) | 0x01, ///< TX: 0, RX: 0 > (internally), RX disabled >=20 > + GpioIosStateTx0Rx1RxDis =3D (0x2 << 1) | 0x01, ///< TX: 0, RX: 1 > (internally), RX disabled >=20 > + GpioIosStateTx1Rx0RxDis =3D (0x3 << 1) | 0x01, ///< TX: 1, RX: 0 > (internally), RX disabled >=20 > + GpioIosStateTx1Rx1RxDis =3D (0x4 << 1) | 0x01, ///< TX: 1, RX: 1 > (internally), RX disabled >=20 > + GpioIosStateTx0RxEn =3D (0x5 << 1) | 0x01, ///< TX: 0, RX ena= bled >=20 > + GpioIosStateTx1RxEn =3D (0x6 << 1) | 0x01, ///< TX: 1, RX ena= bled >=20 > + GpioIosStateHizRx0 =3D (0x7 << 1) | 0x01, ///< Hi-Z, RX: 0 (= internally) >=20 > + GpioIosStateHizRx1 =3D (0x8 << 1) | 0x01, ///< Hi-Z, RX: 1 (= internally) >=20 > + GpioIosStateTxDisRxEn =3D (0x9 << 1) | 0x01, ///< TX Disabled a= nd RX > Enabled (i.e. wake or interrupt) >=20 > + GpioIosStateMasked =3D (0xF << 1) | 0x01 ///< IO Standby si= gnal is > masked for this pad. In this mode, a pad operates as if IOStandby has not > been asserted. >=20 > +} GPIO_IOSTANDBY_STATE; >=20 > + >=20 > +/** >=20 > + GPIO Standby Term configuration >=20 > + Standby Termination options for GPIO Pads >=20 > +**/ >=20 > +typedef enum { >=20 > + GpioIosTermDefault =3D 0x00, >=20 > + GpioIosTermSame =3D (0x00 << 1) | 0x01, ///< Same as state = specified > in Term >=20 > + GpioIosTermPuDisPdDis =3D (0x01 << 1) | 0x01, ///< Disable Pullup= and > Pulldown >=20 > + GpioIosTermPuDisPdEn =3D (0x02 << 1) | 0x01, ///< Enable Pulldow= n >=20 > + GpioIosTermPuEnPdDis =3D (0x03 << 1) | 0x01 ///< Enable Pullup >=20 > +} GPIO_IOSTANDBY_TERM; >=20 > + >=20 > +// >=20 > +// Structure for native pin data >=20 > +// >=20 > +typedef struct { >=20 > + GPIO_PAD Pad; >=20 > + GPIO_PAD_MODE Mode; >=20 > + GPIO_IOSTANDBY_STATE IosState; >=20 > + GPIO_IOSTANDBY_TERM IosTerm; >=20 > +} GPIO_PAD_NATIVE_FUNCTION; >=20 > + >=20 > +// >=20 > +// Structure for Serial GPIO pin definition >=20 > +// >=20 > +typedef struct { >=20 > + GPIO_PAD_NATIVE_FUNCTION Sclock; >=20 > + GPIO_PAD_NATIVE_FUNCTION Sload; >=20 > + GPIO_PAD_NATIVE_FUNCTION Sdataout; >=20 > +} SGPIO_PINS; >=20 > + >=20 > +// >=20 > +// Structure for USB Virtual Wire OverCurrent Pad Mode group >=20 > +// >=20 > +typedef struct { >=20 > + GPIO_PAD OcRxPad; >=20 > + GPIO_PAD OcTxPad; >=20 > +} GPIO_VWOC_FUNCTION; >=20 > + >=20 > +// >=20 > +// Below defines are based on GPIO_CONFIG structure fields >=20 > +// >=20 > +#define B_GPIO_PAD_MODE_MASK 0xF >=20 > +#define N_GPIO_PAD_MODE_BIT_POS 0 >=20 > +#define B_GPIO_HOSTSW_OWN_MASK 0x3 >=20 > +#define N_GPIO_HOSTSW_OWN_BIT_POS 0 >=20 > +#define B_GPIO_DIRECTION_MASK 0x1F >=20 > +#define B_GPIO_DIRECTION_DIR_MASK 0x7 >=20 > +#define N_GPIO_DIRECTION_DIR_BIT_POS 0 >=20 > +#define B_GPIO_DIRECTION_INV_MASK 0x18 >=20 > +#define N_GPIO_DIRECTION_INV_BIT_POS 3 >=20 > +#define B_GPIO_OUTPUT_MASK 0x3 >=20 > +#define N_GPIO_OUTPUT_BIT_POS 0 >=20 > +#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS 0 >=20 > +#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS 5 >=20 > +#define B_GPIO_RESET_CONFIG_RESET_MASK 0x3F >=20 > +#define N_GPIO_RESET_CONFIG_OLD_RESET_TYPE BIT1 >=20 > +#define B_GPIO_RESET_CONFIG_OLD_RESET_MASK 0xF >=20 > +#define N_GPIO_RESET_CONFIG_RESET_BIT_POS 0 >=20 > +#define B_GPIO_RESET_CONFIG_GPD_RESET_MASK (BIT5 | BIT4) >=20 > +#define B_GPIO_RESET_CONFIG_GPP_RESET_MASK (BIT3 | BIT2) >=20 > +#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS 0 >=20 > +#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS 0 >=20 > +#define B_GPIO_GPIO_IOSTANDBY_STATE_MASK ((0xF << 1) | > 0x01) >=20 > +#define B_GPIO_GPIO_IOSTANDBY_STATE_POS 0 >=20 > +#define B_GPIO_GPIO_IOSTANDBY_TERM_MASK ((0x2 << 1) | > 0x01) >=20 > +#define B_GPIO_GPIO_IOSTANDBY_TERM_POS 0 >=20 > + >=20 > +// >=20 > +// Structure for storing information about registers offset, community, >=20 > +// maximal pad number for available groups >=20 > +// >=20 > +typedef struct { >=20 > + PCH_SBI_PID Community; >=20 > + UINT16 PadOwnOffset; >=20 > + UINT16 HostOwnOffset; >=20 > + UINT16 GpiIsOffset; >=20 > + UINT16 GpiIeOffset; >=20 > + UINT16 GpiGpeStsOffset; >=20 > + UINT16 GpiGpeEnOffset; >=20 > + UINT16 SmiStsOffset; >=20 > + UINT16 SmiEnOffset; >=20 > + UINT16 NmiStsOffset; >=20 > + UINT16 NmiEnOffset; >=20 > + UINT16 PadCfgLockOffset; >=20 > + UINT16 PadCfgLockTxOffset; >=20 > + UINT16 PadCfgOffset; >=20 > + UINT16 PadPerGroup; >=20 > +} GPIO_GROUP_INFO; >=20 > + >=20 > +// >=20 > +// If in GPIO_GROUP_INFO structure certain register doesn't exist >=20 > +// it will have value equal to NO_REGISTER_FOR_PROPERTY >=20 > +// >=20 > +#define NO_REGISTER_FOR_PROPERTY 0xFFFF >=20 > + >=20 > +#define GPIO_PAD_DEF(Group,Pad) (UINT32)(((Group) << 16) = + > (Pad)) >=20 > +#define GPIO_GROUP_DEF(GroupIndex,ChipsetId) ((GroupIndex) | > ((ChipsetId) << 8)) >=20 > +#define GPIO_GET_GROUP_INDEX(Group) ((Group) & 0x1F) >=20 > +#define GPIO_GET_GROUP_FROM_PAD(GpioPad) (((GpioPad) & > 0x0F1F0000) >> 16) >=20 > +#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) > GPIO_GET_GROUP_INDEX (GPIO_GET_GROUP_FROM_PAD(GpioPad)) >=20 > +#define GPIO_GET_PAD_NUMBER(GpioPad) ((GpioPad) & 0x1FF) >=20 > +#define GPIO_GET_CHIPSET_ID(GpioPad) (((GpioPad) >> 24) & 0xF) >=20 > + >=20 > +#define GPIO_GET_PAD_POSITION(PadNumber) ((PadNumber) % 32) >=20 > +#define GPIO_GET_DW_NUM(PadNumber) ((PadNumber) / 32u) >=20 > + >=20 > +/** >=20 > + This procedure will retrieve address and length of GPIO info table >=20 > + >=20 > + @param[out] GpioGroupInfoTableLength Length of GPIO group table >=20 > + >=20 > + @retval Pointer to GPIO group table >=20 > +**/ >=20 > +CONST GPIO_GROUP_INFO* >=20 > +GpioGetGroupInfoTable ( >=20 > + OUT UINT32 *GpioGroupInfoTableLength >=20 > + ); >=20 > + >=20 > +typedef struct { >=20 > + CONST CHAR8* GpioGroupPrefix; >=20 > + CONST GPIO_PAD FirstUniqueGpio; >=20 > + CONST CHAR8** GroupUniqueNames; >=20 > + CONST UINT32 UniqueNamesTableSize; >=20 > +} GPIO_GROUP_NAME_INFO; >=20 > + >=20 > +// >=20 > +// Helper macros for initializing GPIO_GROUP_NAME_INFO structures >=20 > +// >=20 > +#define > GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTa > ble) \ >=20 > + {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE > (GroupUniqueNamesTable)} >=20 > + >=20 > +#define GPIO_GROUP_NAME_BASIC(GroupName) \ >=20 > + {GroupName, 0, NULL, 0} >=20 > + >=20 > +/** >=20 > + Returns GPIO_GROUP_NAME_INFO corresponding to the give GpioPad >=20 > + >=20 > + @param[in] GroupIndex Group index >=20 > + >=20 > + @retval GPIO_GROUP_NAME_INFO* Pointer to the > GPIO_GROUP_NAME_INFO >=20 > + @retval NULL If no group descriptor was found >=20 > +**/ >=20 > +CONST >=20 > +GPIO_GROUP_NAME_INFO* >=20 > +GpioGetGroupNameInfo ( >=20 > + IN UINT32 GroupIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get GPIO Chipset ID specific to PCH generation and series >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetThisChipsetId ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure is used to check if GpioPad is valid for certain chipse= t >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE This pin is valid on this chipset >=20 > + FALSE Incorrect pin >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsCorrectPadForThisChipset ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + Generates GPIO name from GpioPad >=20 > + This function returns pointer to the static buffer. >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + >=20 > + @retval CHAR8* Pointer to the GPIO name >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioName ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + Generates GPIO name from GpioNativePad >=20 > + This function returns pointer to the static buffer. >=20 > + >=20 > + @param[in] GpioNativePad GpioNativePad >=20 > + >=20 > + @retval CHAR8* Pointer to the GPIO name >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioPinMuxName ( >=20 > + IN GPIO_NATIVE_PAD GpioNativePad >=20 > + ); >=20 > + >=20 > +/** >=20 > + Generates GPIO Pad Termination string >=20 > + This function returns pointer to the static buffer. >=20 > + >=20 > + @param[in] GpioPadTermination GPIO Pad Termination >=20 > + >=20 > + @retval CHAR8* Painter to the pad termianation string >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioGetPadTerminationString ( >=20 > + IN GPIO_ELECTRICAL_CONFIG PadTermination >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will get value of selected gpio register >=20 > + >=20 > + @param[in] Group GPIO group number >=20 > + @param[in] Offset GPIO register offset >=20 > + @param[out] RegVal Value of gpio register >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetReg ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 Offset, >=20 > + OUT UINT32 *RegVal >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set value of selected gpio register >=20 > + >=20 > + @param[in] Group GPIO group number >=20 > + @param[in] Offset GPIO register offset >=20 > + @param[in] RegVal Value of gpio register >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetReg ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 Offset, >=20 > + IN UINT32 RegVal >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure is used by PchSmiDispatcher and will return information >=20 > + needed to register GPI SMI. >=20 > + >=20 > + @param[in] Index GPI SMI number >=20 > + @param[out] GpioPin GPIO pin >=20 > + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi > Registers >=20 > + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN > register >=20 > + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadAndSmiRegs ( >=20 > + IN UINT32 Index, >=20 > + OUT GPIO_PAD *GpioPin, >=20 > + OUT UINT8 *GpiSmiBitOffset, >=20 > + OUT UINT32 *GpiHostSwOwnRegAddress, >=20 > + OUT UINT32 *GpiSmiStsRegAddress >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO Driver IRQ number >=20 > + >=20 > + @param[in] Irq Irq number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid IRQ number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetIrq ( >=20 > + IN UINT8 Irq >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides GPIO Community PortIDs >=20 > + >=20 > + @param[out] NativePinsTable Table with GPIO COMMx SBI P= ortIDs >=20 > + >=20 > + @retval Number of communities >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetComSbiPortIds ( >=20 > + OUT PCH_SBI_PID **GpioComSbiIds >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides list of GPIO for which IO Standby State configu= ration >=20 > + has to be set as 'Masked' >=20 > + >=20 > + @param[out] GpioPadsList Table with pads >=20 > + >=20 > + @retval Number of pads >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetIoStandbyStateConfigurationPadsList ( >=20 > + OUT GPIO_PAD_NATIVE_FUNCTION **GpioPadsList >=20 > + ); >=20 > + >=20 > + >=20 > +/** >=20 > + This procedure will perform special handling of GPP_A_12. >=20 > + >=20 > + @param[in] None >=20 > + >=20 > + @retval None >=20 > +**/ >=20 > +VOID >=20 > +GpioA12SpecialHandling ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +// >=20 > +// Structure which stores information needed to map GPIO Group >=20 > +// to 1-Tier GPE. Configuration is needed both in PMC and GPIO IP. >=20 > +// Because GPE_DWx can handle only 32 pins only single double word can >=20 > +// be mapped at a time. Each DW for a group has different configuration = in > PMC and GPIO >=20 > +// >=20 > +typedef struct { >=20 > + GPIO_GROUP Group; >=20 > + UINT8 GroupDw; >=20 > + UINT8 PmcGpeDwxVal; >=20 > +} GPIO_GROUP_TO_GPE_MAPPING; >=20 > + >=20 > +/** >=20 > + Get information for GPIO Group required to program GPIO and PMC for > desired 1-Tier GPE mapping >=20 > + >=20 > + @param[out] GpioGroupToGpeMapping Table with GPIO Group to > GPE mapping >=20 > + @param[out] GpioGroupToGpeMappingLength GPIO Group to GPE > mapping table length >=20 > +**/ >=20 > +VOID >=20 > +GpioGetGroupToGpeMapping ( >=20 > + OUT GPIO_GROUP_TO_GPE_MAPPING **GpioGroupToGpeMapping, >=20 > + OUT UINT32 *GpioGroupToGpeMappingLength >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will return Port ID of GPIO Community from GpioPad >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + >=20 > + @retval GpioCommunityPortId Port ID of GPIO Community >=20 > +**/ >=20 > +UINT8 >=20 > +GpioGetGpioCommunityPortIdFromGpioPad ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will return PadCfg address from GpioPad >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + >=20 > + @retval GpioPadCfgAddress PadCfg Address of GpioPad >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGpioPadCfgAddressFromGpioPad ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure is used to unlock all GPIO pads. >=20 > + This function can only be called when platform is still in HOSTIA_BOOT= _SAI. >=20 > +**/ >=20 > +VOID >=20 > +GpioUnlockAllPads ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will check if GpioPad is owned by host. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE GPIO pad is owned by host >=20 > + @retval FALSE GPIO pad is not owned by host and should not = be > used with GPIO lib API >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsPadHostOwned ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > + >=20 > +/** >=20 > + This procedure will check if GpioPad argument is valid. >=20 > + Function will check below conditions: >=20 > + - GpioPad represents a pad for current PCH >=20 > + - GpioPad belongs to valid GpioGroup >=20 > + - GPIO PadNumber is not greater than number of pads for this group >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE GPIO pad is valid and can be used with GPIO l= ib API >=20 > + @retval FALSE GPIO pad is invalid and cannot be used with G= PIO lib > API >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsPadValid ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will read GPIO Pad Configuration register >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 >=20 > + >=20 > + @retval PadCfgRegValue PADCFG_DWx value >=20 > +**/ >=20 > +UINT32 >=20 > +GpioReadPadCfgReg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT8 DwReg >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will write or read GPIO Pad Configuration register >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 >=20 > + @param[in] PadCfgAndMask Mask to be AND'ed with PADCFG reg > value >=20 > + @param[in] PadCfgOrMask Mask to be OR'ed with PADCFG reg value >=20 > + >=20 > + @retval none >=20 > +**/ >=20 > +VOID >=20 > +GpioWritePadCfgReg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT8 DwReg, >=20 > + IN UINT32 PadCfgAndMask, >=20 > + IN UINT32 PadCfgOrMask >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will Enable USB Virtual Wire Overcurrent pin >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetVwOverCurrentPin ( >=20 > + IN GPIO_VWOC_FUNCTION GpioPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set Native Function IOSF-SB Virtual Wire Message > Generation bit >=20 > + in DW0 of requested GPIO Pad >=20 > + >=20 > + @param[in] GPIO_PAD GpioPad >=20 > +**/ >=20 > +VOID >=20 > +GpioSetNafVweBit ( >=20 > + IN CONST GPIO_PAD PadCfg >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO mode >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] PadModeValue GPIO pad mode value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadMode ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_PAD_MODE PadModeValue >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO pad to native mode. >=20 > + To be used if no other settings are to be configured when enabling nat= ive > mode. >=20 > + >=20 > + @param[in] GpioNativePad GPIO Pad with native mode information >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetNativePad ( >=20 > + IN GPIO_NATIVE_PAD GpioNativePad >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO pad to native function based on provided > native function >=20 > + and platform muxing selection (if needed). >=20 > + >=20 > + @param[in] PadFunction PadMode for a specific native signal. = Please > refer to GpioNativePads.h >=20 > + @param[in] PinMux GPIO Native pin mux platform config. >=20 > + This argument is optional and needs to= be >=20 > + provided only if feature can be enable= d >=20 > + on multiple pads >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetNativePadByFunction ( >=20 > + IN UINT32 PadFunction, >=20 > + IN UINT32 PinMux >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO mode >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadModeValue GPIO pad mode value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadMode ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT GPIO_PAD_MODE *PadModeValue >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will check if group is within DeepSleepWell. >=20 > + >=20 > + @param[in] Group GPIO Group >=20 > + >=20 > + @retval GroupWell TRUE: This is DSW Group >=20 > + FALSE: This is not DSW Group >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsDswGroup ( >=20 > + IN GPIO_GROUP Group >=20 > + ); >=20 > + >=20 > +/** >=20 > + The function performs GPIO Power Management programming. >=20 > +**/ >=20 > +VOID >=20 > +GpioConfigurePm ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function performs initial IO Standby State related configurations >=20 > +**/ >=20 > +VOID >=20 > +GpioConfigureIoStandbyState ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables SCS SD Card controller card detect pin >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableScsSdCardDetect ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets HDA SSP interface pins into native mode >=20 > + >=20 > + @param[in] SspInterfaceNumber SSPx interface number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableHdaSsp ( >=20 > + IN UINT32 SspInterfaceNumber >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets HDA SSP Master Clock into native mode >=20 > + >=20 > + @param[in] MclkIndex MCLK index >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableHdaSspMasterClock ( >=20 > + IN UINT32 MclkIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets HDA SoundWire interface pins into native mode >=20 > + >=20 > + @param[in] SndwInterfaceNumber SNDWx interface number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableHdaSndw ( >=20 > + IN UINT32 SndwInterfaceNumber >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides SPI IO pin for Touch Host Controller >=20 > + >=20 > + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1 >=20 > + @param[in] IoIndex IoIndex Valid from 0 (SPI_IO_0) = to 3 > (SPI_IO_3) >=20 > + >=20 > + @retval NativePin Native Pin Configuration, 0 if S= piIndex or > IoIndex is invalid >=20 > +**/ >=20 > +GPIO_PAD_NATIVE_FUNCTION >=20 > +GpioGetThcSpiIo ( >=20 > + IN UINT32 SpiIndex, >=20 > + IN UINT32 IoIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides SPI ChipSelect pin for Touch Host Controller >=20 > + >=20 > + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1 >=20 > + >=20 > + @retval NativePin Native Pin Configuration, 0 if S= piIndex is invalid >=20 > +**/ >=20 > +GPIO_PAD_NATIVE_FUNCTION >=20 > +GpioGetThcSpiCs ( >=20 > + IN UINT32 SpiIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides SPI Clock pin for Touch Host Controller >=20 > + >=20 > + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1 >=20 > + >=20 > + @retval NativePin Native Pin Configuration, 0 if S= piIndex is invalid >=20 > +**/ >=20 > +GPIO_PAD_NATIVE_FUNCTION >=20 > +GpioGetThcSpiClk ( >=20 > + IN UINT32 SpiIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides SPI Reset pin for Touch Host Controller >=20 > + >=20 > + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1 >=20 > + >=20 > + @retval NativePin Native Pin Configuration, 0 if S= piIndex is invalid >=20 > +**/ >=20 > +GPIO_PAD_NATIVE_FUNCTION >=20 > +GpioGetThcSpiReset ( >=20 > + IN UINT32 SpiIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets SMBUS controller pins into native mode >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSmbus ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets SMBUS ALERT pins into native mode >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSmbusAlert ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides Serial GPIO pins >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[out] SgpioPins SATA Serial GPIO pins >=20 > +**/ >=20 > +VOID >=20 > +GpioGetSataSgpioPins ( >=20 > + IN UINT32 SataCtrlIndex, >=20 > + OUT SGPIO_PINS *SgpioPins >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets Serial GPIO pins into native mode >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[in] SataPort SATA port number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSataSgpio ( >=20 > + IN UINT32 SataCtrlIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables USB OverCurrent pins by setting >=20 > + USB2 OCB pins into native mode >=20 > + >=20 > + @param[in] OcPinNumber USB OC pin number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableUsbOverCurrent ( >=20 > + IN UINTN OcPinNumber >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables USB Virtual Wire OverCurrent pins by OcPinNumber= . >=20 > + >=20 > + @param[in] OcPinNumber USB OC pin number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableUsbVwOverCurrent ( >=20 > + IN UINTN OcPinNumber >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets SATA DevSlp pins into native mode >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[in] SataPort SATA port number >=20 > + @param[in] ResetType GPIO reset type (see GPIO_RESET_CONFIG= in > GpioConfig.h) >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSataDevSlpPin ( >=20 > + IN UINT32 SataCtrlIndex, >=20 > + IN UINTN SataPort, >=20 > + IN UINT32 ResetType >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function checks if SataDevSlp pin is in native mode >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[in] SataPort SATA port >=20 > + @param[out] DevSlpPad DevSlpPad >=20 > + This is an optional parameter and may = be NULL. >=20 > + >=20 > + @retval TRUE DevSlp is in native mode >=20 > + FALSE DevSlp is not in native mode >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsSataDevSlpPinEnabled ( >=20 > + IN UINT32 SataCtrlIndex, >=20 > + IN UINTN SataPort, >=20 > + OUT GPIO_PAD *DevSlpPad OPTIONAL >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets SATAGPx pin into native mode >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[in] SataPort SATA port number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSataGpPin ( >=20 > + IN UINT32 SataCtrlIndex, >=20 > + IN UINTN SataPort >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function provides SATA GP pin data >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @param[in] SataPort SATA port number >=20 > + @param[out] NativePin SATA GP pin >=20 > +**/ >=20 > +VOID >=20 > +GpioGetSataGpPin ( >=20 > + IN UINT32 SataCtrlIndex, >=20 > + IN UINTN SataPort, >=20 > + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets SATA LED pin into native mode. SATA LED indicates >=20 > + SATA controller activity >=20 > + >=20 > + @param[in] SataCtrlIndex SATA controller index >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableSataLed ( >=20 > + IN UINT32 SataCtrlIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + Returns pad for given CLKREQ# index. >=20 > + >=20 > + @param[in] ClkreqIndex CLKREQ# number >=20 > + >=20 > + @return CLKREQ# pad. >=20 > +**/ >=20 > +GPIO_PAD >=20 > +GpioGetClkreqPad ( >=20 > + IN UINT32 ClkreqIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + Enables CLKREQ# pad in native mode. >=20 > + >=20 > + @param[in] ClkreqIndex CLKREQ# number >=20 > + >=20 > + @return none >=20 > +**/ >=20 > +VOID >=20 > +GpioEnableClkreq ( >=20 > + IN UINT32 ClkreqIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets PCHHOT pin into native mode >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnablePchHot ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets VRALERTB pin into native mode >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableVrAlert ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets CPU GP pins into native mode >=20 > + >=20 > + @param[in] CpuGpPinNum CPU GP pin number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableCpuGpPin ( >=20 > + IN UINT32 CpuGpPinNum >=20 > + ); >=20 > + >=20 > +/** >=20 > +This function sets CPU C10 Gate pins into native mode >=20 > + >=20 > +@retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableCpuC10GatePin ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +// >=20 > +// DDPx pins >=20 > +// >=20 > +typedef enum { >=20 > + GpioDdp1 =3D 0x01, >=20 > + GpioDdp2 =3D 0x02, >=20 > + GpioDdp3 =3D 0x03, >=20 > + GpioDdp4 =3D 0x04, >=20 > + GpioDdpA =3D 0x10, >=20 > + GpioDdpB =3D 0x11, >=20 > + GpioDdpC =3D 0x12, >=20 > + GpioDdpD =3D 0x13, >=20 > + GpioDdpF =3D 0x15, >=20 > +} GPIO_DDP; >=20 > + >=20 > +/** >=20 > + This function sets DDP pins into native mode >=20 > + >=20 > + @param[in] DdpInterface DDPx interface >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableDpInterface ( >=20 > + IN GPIO_DDP DdpInterface >=20 > + ); >=20 > + >=20 > +// >=20 > +// DDI Port TBT_LSX interface >=20 > +// >=20 > +typedef enum { >=20 > + GpioTbtLsxDdi1, >=20 > + GpioTbtLsxDdi2, >=20 > + GpioTbtLsxDdi3, >=20 > + GpioTbtLsxDdi4, >=20 > + GpioTbtLsxDdi5, >=20 > + GpioTbtLsxDdi6 >=20 > +} GPIO_TBT_LSX; >=20 > + >=20 > +/** >=20 > + This function sets TBT_LSx pin into native mode >=20 > + >=20 > + @param[in] TbtLsxDdiPort TBT_LSx DDI Port Number >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableTbtLsxInterface ( >=20 > + IN GPIO_TBT_LSX TbtLsxDdiPort >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function configures GPIO connection between CNVi and CRF >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioConfigureCnviCrfConnection ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets CNVi Bluetooth Enable value >=20 > + >=20 > + @param[in] Value CNVi BT enable value >=20 > + 0: Disable, 1: Enable >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetCnviBtEnState ( >=20 > + IN UINT32 Value >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets CNVi Bluetooth Wireless Charging support >=20 > + >=20 > + @param[in] BtWirelessCharging CNVi BT Wireless Charging support >=20 > + 0: Normal BT operation (no Wireless Ch= arging support) >=20 > + 1: Enable BT Wireless Charging >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetCnviBtWirelessCharging ( >=20 > + IN UINT32 BtWirelessCharging >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables and configures CNVi Bluetooth Host wake-up > interrupt >=20 > + >=20 > + @param[in] None >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioConfigureCnviBtHostWakeInt ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables IMGU CLKOUT native pin >=20 > + >=20 > + @param[in] ImguClkOutPinIndex The index of IMGU CLKOUT natine pin >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableImguClkOut ( >=20 > + IN UINT8 ImguClkOutPinIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + Power button debounce configuration >=20 > + Debounce time can be specified in microseconds. Only certain values > according >=20 > + to below formula are supported: >=20 > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock > period). >=20 > + RTC clock with f =3D 32 KHz is used for glitch filter. >=20 > + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us). >=20 > + Supported DebounceTime values are following: >=20 > + DebounceTime =3D 0 -> Debounce feature disabled >=20 > + DebounceTime > 0 && < 250us -> Not supported >=20 > + DebounceTime =3D 250us - 1024000us -> Supported range (DebounceTime = =3D > 250us * 2^n) >=20 > + For values not supported by HW, they will be rounded down to closest > supported one >=20 > + >=20 > + @param[in] DebounceTime Debounce Time in microseconds >=20 > + If Debounce Time =3D 0, Debouncer feature w= ill be disabled >=20 > + Function will set DebounceTime argument to = rounded > supported value >=20 > +**/ >=20 > +VOID >=20 > +GpioSetPwrBtnDebounceTimer ( >=20 > + IN UINT32 DebounceTime >=20 > + ); >=20 > + >=20 > + >=20 > +/** >=20 > + VCCIO level selection >=20 > +**/ >=20 > +typedef enum { >=20 > + GpioVcc3v3, >=20 > + GpioVcc1v8, >=20 > + MaxVccioSel >=20 > +} GPIO_VCCIO_SEL; >=20 > +/** >=20 > + The function sets VCCIOSEL >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] VccioSel Pad voltage >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED The Pin is owned by others >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or parameter >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetVccLevel ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_VCCIO_SEL VccioSel >=20 > + ); >=20 > + >=20 > +/** >=20 > + SBU (Sideband use) pins are used as auxiliary signals for Type C conne= ctor, >=20 > + which are hard-wired to BSSB_LS natively for debug function. >=20 > + when USB-C is enablde and debug not needed, disable pins (BSSB) used > for debug through TypeC connector, >=20 > + program SBU pins to high-Z/open circuit per USB-C spec. >=20 > + >=20 > + @param[in] UsbTcPortEnBitmap USB Type C port enabled bitmap >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED SBU pads are not supported >=20 > + @retval EFI_INVALID_PARAMETER Invalid input parameter >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioDisableTypeCSbuDebug ( >=20 > + IN UINT32 UsbTcPortEnBitmap >=20 > + ); >=20 > + >=20 > +/** >=20 > + When 2-wire DCI OOB is connected via SBU from Type C port, need set IO > Standby state to masked (to operate as if no standby signal asserted) >=20 > + to remain connection in low power state. >=20 > + >=20 > + @param[in] DciPortId DCI connection port ID >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED SBU pads are not supported >=20 > + @retval EFI_INVALID_PARAMETER Invalid input parameter >=20 > +**/ >=20 > +EFI_STATUS >=20 > +Gpio2WireDciOobSetting ( >=20 > + IN UINT8 DciPortId >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function enables the virtual wire msg bus from GPIO controller >=20 > + to FIA. The virtual wire is used to transfer CLKREQ assert/de-assert >=20 > + msg for CPU PCIe ports. Each of the PCIe ports has its dedicated VW >=20 > + msg. >=20 > + >=20 > + @param[in] PortIndex Index of the CPU PCIe port for which V= W >=20 > + should be enabled. >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED Failed to set native mode. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableCpuPcieVwClkReqMsgBus ( >=20 > + IN UINT32 PortIndex >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets Time Sync Gpio into native mode >=20 > + >=20 > + @param[in] Index index >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableTimeSync ( >=20 > + IN UINT32 Index >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function sets Tsn into native mode >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioEnableTsn ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + This function is to be used In GpioLockPads() to override a lock reque= st by > SOC code. >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum Register number for current group (paramete= r > applicable in accessing whole register). >=20 > + For group which has less then 32 pads per g= roup DwNum > must be 0. >=20 > + @param[out] *UnlockCfgPad DWORD bitmask for pads which are going to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave unloc= ked >=20 > + @param[out] *UnlockTxPad DWORD bitmask for pads which are going to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave unloc= ked >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid input parameter >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioUnlockOverride ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + OUT UINT32 *UnlockCfgPad, >=20 > + OUT UINT32 *UnlockTxPad >=20 > + ); >=20 > + >=20 > +/** >=20 > + Check if 0x13 opcode supported for writing to GPIO lock unlock registe= r >=20 > + >=20 > + @retval TRUE It's supported >=20 > + @retval FALSE It's not supported >=20 > +**/ >=20 > +BOOLEAN >=20 > +IsGpioLockOpcodeSupported ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + Configures IO standby related settings for the GPIO pad. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] IoStandbyState GPIO pad IO Standby state >=20 > + @param[in] IoStandbyTerm GPIO pad IO Standby termination >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioConfigurePadIoStandby ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_IOSTANDBY_STATE IoStandbyState, >=20 > + IN GPIO_IOSTANDBY_TERM IoStandbyTerm >=20 > + ); >=20 > + >=20 > +/** >=20 > + Checks if GPIO PinMux corresponds to I2C4 B >=20 > + >=20 > + @param[in] SdaPinMux GPIO pad pinmux for SDA >=20 > + @param[in] SclPinMux GPIO pad pinmux for SCL >=20 > + >=20 > + @retval TRUE PinMux corresponds to I2C4 B >=20 > + FALSE PinMux equals to I2C4 A >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioIsSerialIoI2c4bMuxed ( >=20 > + IN UINT32 SdaPinMux, >=20 > + IN UINT32 SclPinMux >=20 > + ); >=20 > + >=20 > +#endif // _GPIO_PRIVATE_LIB_H_ >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.c > new file mode 100644 > index 0000000000..5a6360931b > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.c > @@ -0,0 +1,140 @@ > +/** @file >=20 > + Implementation of BaseGpioCheckConflictLib. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + Check Gpio PadMode conflict and report it. >=20 > + >=20 > + @retval none. >=20 > +**/ >=20 > +VOID >=20 > +GpioCheckConflict ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + EFI_HOB_GUID_TYPE *GpioCheckConflictHob; >=20 > + GPIO_PAD_MODE_INFO *GpioCheckConflictHobData; >=20 > + UINT32 HobDataSize; >=20 > + UINT32 GpioCount; >=20 > + UINT32 GpioIndex; >=20 > + GPIO_CONFIG GpioActualConfig; >=20 > + >=20 > + GpioCheckConflictHob =3D NULL; >=20 > + GpioCheckConflictHobData =3D NULL; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "GpioCheckConflict Start..\n")); >=20 > + >=20 > + // >=20 > + // Use Guid to find HOB. >=20 > + // >=20 > + GpioCheckConflictHob =3D (EFI_HOB_GUID_TYPE *) GetFirstGuidHob > (&gGpioCheckConflictHobGuid); >=20 > + if (GpioCheckConflictHob =3D=3D NULL) { >=20 > + DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] No GPIO HOB found.\n")); >=20 > + } else { >=20 > + while (GpioCheckConflictHob !=3D NULL) { >=20 > + // >=20 > + // Find the Data area pointer and Data size from the Hob >=20 > + // >=20 > + GpioCheckConflictHobData =3D (GPIO_PAD_MODE_INFO *) > GET_GUID_HOB_DATA (GpioCheckConflictHob); >=20 > + HobDataSize =3D GET_GUID_HOB_DATA_SIZE (GpioCheckConflictHob); >=20 > + >=20 > + GpioCount =3D HobDataSize / sizeof (GPIO_PAD_MODE_INFO); >=20 > + DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] Hob : GpioCount =3D > %d\n", GpioCount)); >=20 > + >=20 > + // >=20 > + // Probe Gpio entries in Hob and compare which are conflicted >=20 > + // >=20 > + for (GpioIndex =3D 0; GpioIndex < GpioCount ; GpioIndex++) { >=20 > + GpioGetPadConfig (GpioCheckConflictHobData[GpioIndex].GpioPad, > &GpioActualConfig); >=20 > + if (GpioCheckConflictHobData[GpioIndex].GpioPadMode !=3D > GpioActualConfig.PadMode) { >=20 > + DEBUG ((DEBUG_ERROR, "[GPIO Conflict Check] Identified conflic= t on > pad %a (actual: 0x%X, expected: 0x%X)\n", >=20 > + GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad)= , >=20 > + GpioActualConfig.PadMode, >=20 > + GpioCheckConflictHobData[GpioIndex].GpioPadMode)); >=20 > + } >=20 > + } >=20 > + // >=20 > + // Find next Hob and return the Hob pointer by the specific Hob Gu= id >=20 > + // >=20 > + GpioCheckConflictHob =3D GET_NEXT_HOB (GpioCheckConflictHob); >=20 > + GpioCheckConflictHob =3D GetNextGuidHob > (&gGpioCheckConflictHobGuid, GpioCheckConflictHob); >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "GpioCheckConflict End.\n")); >=20 > + } >=20 > + >=20 > + return; >=20 > +} >=20 > + >=20 > +/** >=20 > + This libaray will create one Hob for each Gpio config table >=20 > + without PadMode is GpioHardwareDefault >=20 > + >=20 > + @param[in] GpioDefinition Point to Platform Gpio table >=20 > + @param[in] GpioTableCount Number of Gpio table entries >=20 > + >=20 > + @retval none. >=20 > +**/ >=20 > +VOID >=20 > +CreateGpioCheckConflictHob ( >=20 > + IN GPIO_INIT_CONFIG *GpioDefinition, >=20 > + IN UINT32 GpioTableCount >=20 > + ) >=20 > +{ >=20 > + >=20 > + UINT32 Index; >=20 > + UINT32 GpioIndex; >=20 > + GPIO_PAD_MODE_INFO *GpioCheckConflictHobData; >=20 > + UINT16 GpioCount; >=20 > + >=20 > + GpioCount =3D 0; >=20 > + GpioIndex =3D 0; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob Start \n")); >=20 > + >=20 > + for (Index =3D 0; Index < GpioTableCount ; Index++) { >=20 > + if (GpioDefinition[Index].GpioConfig.PadMode =3D=3D GpioHardwareDefa= ult) > { >=20 > + continue; >=20 > + } else { >=20 > + // >=20 > + // Calculate non-default GPIO number >=20 > + // >=20 > + GpioCount++; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Build a HOB tagged with a GUID for identification and returns >=20 > + // the start address of GUID HOB data. >=20 > + // >=20 > + GpioCheckConflictHobData =3D (GPIO_PAD_MODE_INFO *) BuildGuidHob > (&gGpioCheckConflictHobGuid , GpioCount * sizeof > (GPIO_PAD_MODE_INFO)); >=20 > + >=20 > + // >=20 > + // Record Non Default Gpio entries to the Hob >=20 > + // >=20 > + for (Index =3D 0; Index < GpioTableCount; Index++) { >=20 > + if (GpioDefinition[Index].GpioConfig.PadMode =3D=3D GpioHardwareDefa= ult) > { >=20 > + continue; >=20 > + } else { >=20 > + if (GpioCheckConflictHobData !=3D NULL) { >=20 > + GpioCheckConflictHobData[GpioIndex].GpioPad =3D > GpioDefinition[Index].GpioPad; >=20 > + GpioCheckConflictHobData[GpioIndex].GpioPadMode =3D > GpioDefinition[Index].GpioConfig.PadMode; >=20 > + GpioIndex++; >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n")); >=20 > + return; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.inf > new file mode 100644 > index 0000000000..f7e1de774d > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLib/BaseGpioCheckConflictLib.inf > @@ -0,0 +1,29 @@ > +## @file >=20 > +# Component information file for BaseGpioCheckConflictLib. >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010017 >=20 > + BASE_NAME =3D BaseGpioCheckConflictLib >=20 > + FILE_GUID =3D C19A848A-F013-4DBF-9C23-F0F74DEA6F1= 4 >=20 > + MODULE_TYPE =3D BASE >=20 > + VERSION_STRING =3D 1.0 >=20 > + LIBRARY_CLASS =3D GpioCheckConflictLib >=20 > + >=20 > +[LibraryClasses] >=20 > + DebugLib >=20 > + HobLib >=20 > + GpioLib >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Sources] >=20 > + BaseGpioCheckConflictLib.c >=20 > + >=20 > +[Guids] >=20 > + gGpioCheckConflictHobGuid >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.c > new file mode 100644 > index 0000000000..2f83f95b27 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.c > @@ -0,0 +1,35 @@ > +/** @file >=20 > + Implementation of BaseGpioCheckConflicLibNull. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > + >=20 > +#include >=20 > + >=20 > +/** >=20 > + Check Gpio PadMode conflict and report it. >=20 > +**/ >=20 > +VOID >=20 > +GpioCheckConflict ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return; >=20 > +} >=20 > + >=20 > +/** >=20 > + This libaray will create one Hob for each Gpio config table >=20 > + without PadMode is GpioHardwareDefault >=20 > + >=20 > + @param[in] GpioDefinition Point to Platform Gpio table >=20 > + @param[in] GpioTableCount Number of Gpio table entries >=20 > +**/ >=20 > +VOID >=20 > +CreateGpioCheckConflictHob ( >=20 > + IN GPIO_INIT_CONFIG *GpioDefinition, >=20 > + IN UINT32 GpioTableCount >=20 > + ) >=20 > +{ >=20 > + return; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.inf > new file mode 100644 > index 0000000000..1c226d7c16 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckCon= f > lictLibNull/BaseGpioCheckConflictLibNull.inf > @@ -0,0 +1,26 @@ > +## @file >=20 > +# Component information file for BaseGpioCheckConflictLib. >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010017 >=20 > + BASE_NAME =3D BaseGpioCheckConflictLibNull >=20 > + FILE_GUID =3D C19A848A-F013-4DBF-9C23-F0F74DEA6F1= 4 >=20 > + MODULE_TYPE =3D BASE >=20 > + VERSION_STRING =3D 1.0 >=20 > + LIBRARY_CLASS =3D GpioCheckConflictLib >=20 > + >=20 > +[LibraryClasses] >=20 > + DebugLib >=20 > + HobLib >=20 > + GpioLib >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Sources] >=20 > + BaseGpioCheckConflictLibNull.c >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > GpioInit.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioInit.c > new file mode 100644 > index 0000000000..99dbbf0ca6 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioInit.c > @@ -0,0 +1,558 @@ > +/** @file >=20 > + This file contains routines for GPIO initialization >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include "GpioLibrary.h" >=20 > +#include >=20 > +#include >=20 > + >=20 > +// >=20 > +// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch > function >=20 > +// to cache values which will be programmed into respective GPIO registe= rs >=20 > +// after all GpioPads are processed. This way MMIO accesses are decrease= d >=20 > +// and instead of doing one programming for one GpioPad there is only >=20 > +// one access for whole register. >=20 > +// >=20 > +typedef struct { >=20 > + UINT32 HostSoftOwnReg; >=20 > + UINT32 HostSoftOwnRegMask; >=20 > + UINT32 GpiGpeEnReg; >=20 > + UINT32 GpiGpeEnRegMask; >=20 > + UINT32 GpiNmiEnReg; >=20 > + UINT32 GpiNmiEnRegMask; >=20 > + UINT32 GpiSmiEnReg; >=20 > + UINT32 GpiSmiEnRegMask; >=20 > + UINT32 ConfigUnlockMask; >=20 > + UINT32 OutputUnlockMask; >=20 > +} GPIO_GROUP_DW_DATA; >=20 > + >=20 > +// >=20 > +// GPIO_GROUP_DW_NUMBER contains number of DWords required to >=20 > +// store Pad data for all groups. Each pad uses one bit. >=20 > +// >=20 > +#define GPIO_GROUP_DW_NUMBER 1 >=20 > + >=20 > +/** >=20 > + Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock). >=20 > + >=20 > + @param[in] PadNumber GPIO pad number >=20 > + @param[in] GpioConfig GPIO Config data >=20 > + @param[in out] DwRegsValues Values for GPIO DW Registers >=20 > + >=20 > + @retval None >=20 > +**/ >=20 > +STATIC >=20 > +VOID >=20 > +GpioDwRegValueFromGpioConfig ( >=20 > + IN UINT32 PadNumber, >=20 > + IN CONST GPIO_CONFIG *GpioConfig, >=20 > + IN OUT GPIO_GROUP_DW_DATA *GroupDwData >=20 > + ) >=20 > +{ >=20 > + UINT32 PadBitPosition; >=20 > + UINT32 DwNum; >=20 > + >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + >=20 > + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { >=20 > + ASSERT (FALSE); >=20 > + return; >=20 > + } >=20 > + // >=20 > + // Update value to be programmed in HOSTSW_OWN register >=20 > + // >=20 > + GroupDwData[DwNum].HostSoftOwnRegMask |=3D (GpioConfig- > >HostSoftPadOwn & 0x1) << PadBitPosition; >=20 > + GroupDwData[DwNum].HostSoftOwnReg |=3D (GpioConfig- > >HostSoftPadOwn >> 0x1) << PadBitPosition; >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_GPE_EN register >=20 > + // >=20 > + GroupDwData[DwNum].GpiGpeEnRegMask |=3D (GpioConfig- > >InterruptConfig & 0x1) << PadBitPosition; >=20 > + GroupDwData[DwNum].GpiGpeEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntSci) >> 3) << PadBitPosition; >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_NMI_EN register >=20 > + // >=20 > + GroupDwData[DwNum].GpiNmiEnRegMask |=3D (GpioConfig- > >InterruptConfig & 0x1) << PadBitPosition; >=20 > + GroupDwData[DwNum].GpiNmiEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntNmi) >> 1) << PadBitPosition; >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_SMI_EN register >=20 > + GroupDwData[DwNum].GpiSmiEnRegMask |=3D (GpioConfig- > >InterruptConfig & 0x1) << PadBitPosition; >=20 > + GroupDwData[DwNum].GpiSmiEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntSmi) >> 2) << PadBitPosition; >=20 > + if ((GpioConfig->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) { >=20 > + GroupDwData[DwNum].HostSoftOwnRegMask |=3D 1 << PadBitPosition; >=20 > + GroupDwData[DwNum].HostSoftOwnReg |=3D 1 << PadBitPosition; >=20 > + } >=20 > + >=20 > + // >=20 > + // Update information on Pad Configuration Lock >=20 > + // >=20 > + GroupDwData[DwNum].ConfigUnlockMask |=3D ((GpioConfig->LockConfig > >> 1) & 0x1) << PadBitPosition; >=20 > + >=20 > + // >=20 > + // Update information on Pad Configuration Lock Tx >=20 > + // >=20 > + GroupDwData[DwNum].OutputUnlockMask |=3D ((GpioConfig->LockConfig > >> 3) & 0x1) << PadBitPosition; >=20 > + >=20 > + // >=20 > + // if pad in GpioMode is an output default action should be to leave o= utput > unlocked >=20 > + // >=20 > + if ((GpioConfig->PadMode =3D=3D GpioPadModeGpio) && >=20 > + (GpioConfig->Direction =3D=3D GpioDirOut) && >=20 > + ((GpioConfig->LockConfig & > B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D GpioLockDefault)) { >=20 > + GroupDwData[DwNum].OutputUnlockMask |=3D 0x1 << PadBitPosition; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + This internal procedure will scan GPIO initialization table and unlock >=20 > + all pads present in it >=20 > + >=20 > + @param[in] NumberOfItem Number of GPIO pad records in ta= ble >=20 > + @param[in] GpioInitTableAddress GPIO initialization table >=20 > + @param[in] Index Index of GPIO Initialization tab= le record >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioUnlockPadsForAGroup ( >=20 > + IN UINT32 NumberOfItems, >=20 > + IN GPIO_INIT_CONFIG *GpioInitTableAddress, >=20 > + IN UINT32 Index >=20 > + ) >=20 > +{ >=20 > + UINT32 PadsToUnlock[GPIO_GROUP_DW_NUMBER]; >=20 > + UINT32 DwNum; >=20 > + UINT32 PadBitPosition; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + CONST GPIO_INIT_CONFIG *GpioData; >=20 > + GPIO_GROUP Group; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + GpioData =3D &GpioInitTableAddress[Index]; >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioData->GpioPad); >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); >=20 > + >=20 > + ZeroMem (PadsToUnlock, sizeof (PadsToUnlock)); >=20 > + // >=20 > + // Loop through pads for one group. If pad belongs to a different grou= p > then >=20 > + // break and move to register programming. >=20 > + // >=20 > + while (Index < NumberOfItems) { >=20 > + >=20 > + GpioData =3D &GpioInitTableAddress[Index]; >=20 > + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData- > >GpioPad)) { >=20 > + //if next pad is from different group then break loop >=20 > + break; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); >=20 > + // >=20 > + // Check if legal pin number >=20 > + // >=20 > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds > possible range for group %d\n", PadNumber, GroupIndex)); >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + >=20 > + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { >=20 > + ASSERT (FALSE); >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + // >=20 > + // Update pads which need to be unlocked >=20 > + // >=20 > + PadsToUnlock[DwNum] |=3D 0x1 << PadBitPosition; >=20 > + >=20 > + //Move to next item >=20 > + Index++; >=20 > + } >=20 > + >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + // >=20 > + // Unlock pads >=20 > + // >=20 > + if (PadsToUnlock[DwNum] !=3D 0) { >=20 > + GpioUnlockPadCfgForGroupDw (Group, DwNum, > PadsToUnlock[DwNum]); >=20 > + GpioUnlockPadCfgTxForGroupDw (Group, DwNum, > PadsToUnlock[DwNum]); >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will initialize multiple PCH GPIO pins >=20 > + >=20 > + @param[in] NumberofItem Number of GPIO pads to be update= d >=20 > + @param[in] GpioInitTableAddress GPIO initialization table >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioConfigurePch ( >=20 > + IN UINT32 NumberOfItems, >=20 > + IN GPIO_INIT_CONFIG *GpioInitTableAddress >=20 > + ) >=20 > +{ >=20 > + UINT32 Index; >=20 > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; >=20 > + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; >=20 > + UINT32 PadCfgReg; >=20 > + GPIO_GROUP_DW_DATA GroupDwData[GPIO_GROUP_DW_NUMBER]; >=20 > + UINT32 DwNum; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + GPIO_PAD_OWN PadOwnVal; >=20 > + CONST GPIO_INIT_CONFIG *GpioData; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + PCH_SBI_PID GpioCom; >=20 > + >=20 > + PadOwnVal =3D GpioPadOwnHost; >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + Index =3D 0; >=20 > + while (Index < NumberOfItems) { >=20 > + >=20 > + GpioData =3D &GpioInitTableAddress[Index]; >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); >=20 > + GpioCom =3D GpioGroupInfo[GroupIndex].Community; >=20 > + >=20 > + DEBUG_CODE_BEGIN(); >=20 > + if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) > used on this chipset!\n", GpioData->GpioPad)); >=20 > + ASSERT (FALSE); >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + DEBUG_CODE_END (); >=20 > + >=20 > + // >=20 > + // Unlock pads for a given group which are going to be reconfigured >=20 > + // >=20 > + // >=20 > + // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, > lock settings >=20 > + // will get back to default only after G3 or DeepSx transition. On t= he other > hand GpioPads >=20 > + // configuration is controlled by a configurable type of reset - Pad= RstCfg. > This means that if >=20 > + // PadRstCfg !=3D Powergood GpioPad will have its configuration lock= ed > despite it being not the >=20 > + // one desired by BIOS. Before reconfiguring all pads they will get > unlocked. >=20 > + // >=20 > + GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, > Index); >=20 > + >=20 > + ZeroMem (GroupDwData, sizeof (GroupDwData)); >=20 > + // >=20 > + // Loop through pads for one group. If pad belongs to a different gr= oup > then >=20 > + // break and move to register programming. >=20 > + // >=20 > + while (Index < NumberOfItems) { >=20 > + >=20 > + GpioData =3D &GpioInitTableAddress[Index]; >=20 > + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData- > >GpioPad)) { >=20 > + //if next pad is from different group then break loop >=20 > + break; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); >=20 > + >=20 > + DEBUG_CODE_BEGIN (); >=20 > + // >=20 > + // Check if legal pin number >=20 > + // >=20 > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds > possible range for group %d\n", PadNumber, GroupIndex)); >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if selected GPIO Pad is not owned by CSME/ISH >=20 > + // >=20 > + GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal); >=20 > + >=20 > + if (PadOwnVal !=3D GpioPadOwnHost) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by > host (Group=3D%d, Pad=3D%d)!\n", GroupIndex, PadNumber)); >=20 > + DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync > between CSME and BIOS configuration. \n")); >=20 > + DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should no= t > do any configuration by BIOS.\n")); >=20 > + //Move to next item >=20 > + Index++; >=20 > + continue; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if Pad enabled for SCI is to be in unlocked state >=20 > + // >=20 > + if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) =3D=3D Gp= ioIntSci) > && >=20 > + ((GpioData->GpioConfig.LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) !=3D > GpioPadConfigUnlock)){ >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a used for SCI is not > unlocked!\n", GpioName (GpioData->GpioPad))); >=20 > + ASSERT (FALSE); >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + DEBUG_CODE_END (); >=20 > + >=20 > + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); >=20 > + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); >=20 > + // >=20 > + // Get GPIO PADCFG register value from GPIO config data >=20 > + // >=20 > + GpioPadCfgRegValueFromGpioConfig ( >=20 > + GpioData->GpioPad, >=20 > + &GpioData->GpioConfig, >=20 > + PadCfgDwReg, >=20 > + PadCfgDwRegMask >=20 > + ); >=20 > + >=20 > + // >=20 > + // Create PADCFG register offset using group and pad number >=20 > + // >=20 > + PadCfgReg =3D S_GPIO_PCR_PADCFG * PadNumber + > GpioGroupInfo[GroupIndex].PadCfgOffset; >=20 > + >=20 > + // >=20 > + // Write PADCFG DW0 register >=20 > + // >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg), >=20 > + ~PadCfgDwRegMask[0], >=20 > + PadCfgDwReg[0] >=20 > + ); >=20 > + // >=20 > + // Write PADCFG DW1 register >=20 > + // >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x4), >=20 > + ~PadCfgDwRegMask[1], >=20 > + PadCfgDwReg[1] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Write PADCFG DW2 register >=20 > + // >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x8), >=20 > + ~PadCfgDwRegMask[2], >=20 > + PadCfgDwReg[2] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Get GPIO DW register values from GPIO config data >=20 > + // >=20 > + GpioDwRegValueFromGpioConfig ( >=20 > + PadNumber, >=20 > + &GpioData->GpioConfig, >=20 > + GroupDwData >=20 > + ); >=20 > + >=20 > + //Move to next item >=20 > + Index++; >=20 > + } >=20 > + >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + // >=20 > + // Write HOSTSW_OWN registers >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].HostOwnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4), >=20 > + ~GroupDwData[DwNum].HostSoftOwnRegMask, >=20 > + GroupDwData[DwNum].HostSoftOwnReg >=20 > + ); >=20 > + } >=20 > + >=20 > + // >=20 > + // Write GPI_GPE_EN registers >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4), >=20 > + ~GroupDwData[DwNum].GpiGpeEnRegMask, >=20 > + GroupDwData[DwNum].GpiGpeEnReg >=20 > + ); >=20 > + } >=20 > + >=20 > + // >=20 > + // Write GPI_NMI_EN registers >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].NmiEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4), >=20 > + ~GroupDwData[DwNum].GpiNmiEnRegMask, >=20 > + GroupDwData[DwNum].GpiNmiEnReg >=20 > + ); >=20 > + } else if (GroupDwData[DwNum].GpiNmiEnReg !=3D 0x0) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads > supporting NMI\n", GroupIndex)); >=20 > + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); >=20 > + } >=20 > + >=20 > + // >=20 > + // Write GPI_SMI_EN registers >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].SmiEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4), >=20 > + ~GroupDwData[DwNum].GpiSmiEnRegMask, >=20 > + GroupDwData[DwNum].GpiSmiEnReg >=20 > + ); >=20 > + } else if (GroupDwData[DwNum].GpiSmiEnReg !=3D 0x0) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads > supporting SMI\n", GroupIndex)); >=20 > + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); >=20 > + } >=20 > + >=20 > + // >=20 > + // Update Pad Configuration unlock data >=20 > + // >=20 > + if (GroupDwData[DwNum].ConfigUnlockMask) { >=20 > + GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, > GroupDwData[DwNum].ConfigUnlockMask); >=20 > + } >=20 > + >=20 > + // >=20 > + // Update Pad Output unlock data >=20 > + // >=20 > + if (GroupDwData[DwNum].OutputUnlockMask) { >=20 > + GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, > GroupDwData[DwNum].OutputUnlockMask); >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will clear all status bits of any GPIO interrupts. >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioClearAllGpioInterrupts ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + GPIO_GROUP GpioGroupLowest; >=20 > + GPIO_GROUP GpioGroupHighest; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 DwNum; >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + GpioGroupLowest =3D GpioGetLowestGroup (); >=20 > + GpioGroupHighest =3D GpioGetHighestGroup (); >=20 > + >=20 > + for (Group =3D GpioGroupLowest; Group <=3D GpioGroupHighest; Group++) = { >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + // >=20 > + // Check if group has GPI IS register >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].GpiIsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + // >=20 > + // Clear all GPI_IS Status bits by writing '1' >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + MmioWrite32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4), >=20 > + 0xFFFFFFFF >=20 > + ); >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if group has GPI_GPE_STS register >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + // >=20 > + // Clear all GPI_GPE_STS Status bits by writing '1' >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + MmioWrite32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4), >=20 > + 0xFFFFFFFF >=20 > + ); >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if group has SMI_STS register >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].SmiStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + // >=20 > + // Clear all SMI_STS Status bits by writing '1' >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + MmioWrite32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4), >=20 > + 0xFFFFFFFF >=20 > + ); >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if group has NMI_STS register >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].NmiStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + // >=20 > + // Clear all NMI_STS Status bits by writing '1' >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { >=20 > + MmioWrite32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4), >=20 > + 0xFFFFFFFF >=20 > + ); >=20 > + } >=20 > + } >=20 > + >=20 > + } >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFI= G > structure. >=20 > + Structure contains fields that can be used to configure each pad. >=20 > + Pad not configured using GPIO_INIT_CONFIG will be left with hardware > default values. >=20 > + Separate fields could be set to hardware default if it does not matter= , > except >=20 > + GpioPad and PadMode. >=20 > + Function will work in most efficient way if pads which belong to the s= ame > group are >=20 > + placed in adjacent records of the table. >=20 > + Although function can enable pads for Native mode, such programming is > done >=20 > + by reference code when enabling related silicon feature. >=20 > + >=20 > + @param[in] NumberofItem Number of GPIO pads to be update= d >=20 > + @param[in] GpioInitTableAddress GPIO initialization table >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioConfigurePads ( >=20 > + IN UINT32 NumberOfItems, >=20 > + IN GPIO_INIT_CONFIG *GpioInitTableAddress >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D GpioConfigurePch (NumberOfItems, GpioInitTableAddress); >=20 > + >=20 > + CreateGpioCheckConflictHob (GpioInitTableAddress, NumberOfItems); >=20 > + >=20 > + GpioClearAllGpioInterrupts (); >=20 > + return Status; >=20 > +} >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > GpioLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioLib.c > new file mode 100644 > index 0000000000..d6c13fe581 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioLib.c > @@ -0,0 +1,2387 @@ > +/** @file >=20 > + This file contains routines for GPIO >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include "GpioLibrary.h" >=20 > +#include >=20 > + >=20 > +/** >=20 > + This procedure will check if GpioGroup argument is correct and >=20 > + supplied DW reg number can be used for this group to access DW registe= rs. >=20 > + Function will check below conditions: >=20 > + - Valid GpioGroup >=20 > + - DwNum is has valid value for this group >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum Register number for current group (parameter > applicable in accessing whole register). >=20 > + For group which has less then 32 pads per grou= p DwNum must > be 0. >=20 > + >=20 > + @retval TRUE DW Reg number and GpioGroup is valid >=20 > + @retval FALSE DW Reg number and GpioGroup is invalid >=20 > +**/ >=20 > +STATIC >=20 > +BOOLEAN >=20 > +GpioIsGroupAndDwNumValid ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + UINT32 GroupIndex; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + >=20 > + if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup > ()) || (GroupIndex >=3D GpioGroupInfoLength)) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not > within range of possible groups for this PCH\n", GroupIndex)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if DwNum argument does not exceed number of DWord registers >=20 > + // resulting from available pads for certain group >=20 > + // >=20 > + if (DwNum > GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup - 1)){ >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + return TRUE; >=20 > +Error: >=20 > + ASSERT (FALSE); >=20 > + return FALSE; >=20 > +} >=20 > + >=20 > +// >=20 > +// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() > functions >=20 > +// >=20 > +typedef enum { >=20 > + GpioHostOwnershipRegister =3D 0, >=20 > + GpioGpeEnableRegister, >=20 > + GpioGpeStatusRegister, >=20 > + GpioSmiEnableRegister, >=20 > + GpioSmiStatusRegister, >=20 > + GpioNmiEnableRegister, >=20 > + GpioPadConfigLockRegister, >=20 > + GpioPadLockOutputRegister >=20 > +} GPIO_REG; >=20 > + >=20 > +/** >=20 > + This procedure will read GPIO register >=20 > + >=20 > + @param[in] RegType GPIO register type >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[out] ReadVal Read data >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED Feature is not supported for this grou= p or > pad >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioReadReg ( >=20 > + IN GPIO_REG RegType, >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + OUT UINT32 *ReadVal >=20 > + ) >=20 > +{ >=20 > + UINT32 RegOffset; >=20 > + UINT32 GroupIndex; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + >=20 > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + switch (RegType) { >=20 > + case GpioHostOwnershipRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; >=20 > + break; >=20 > + case GpioGpeEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; >=20 > + break; >=20 > + case GpioGpeStatusRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; >=20 > + break; >=20 > + case GpioSmiEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; >=20 > + break; >=20 > + case GpioSmiStatusRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; >=20 > + break; >=20 > + case GpioNmiEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; >=20 > + break; >=20 > + case GpioPadConfigLockRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; >=20 > + break; >=20 > + case GpioPadLockOutputRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; >=20 > + break; >=20 > + default: >=20 > + break; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if selected register exists >=20 > + // >=20 > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // If there are more then 32 pads per group then certain >=20 > + // group information would be split into more then one DWord register. >=20 > + // >=20 > + if ((RegType =3D=3D GpioPadConfigLockRegister) || (RegType =3D=3D > GpioPadLockOutputRegister)) { >=20 > + // >=20 > + // PadConfigLock and OutputLock registers when used for group > containing more than 32 pads >=20 > + // are not placed in a continuous way, e.g: >=20 > + // 0x0 - PadConfigLock_DW0 >=20 > + // 0x4 - OutputLock_DW0 >=20 > + // 0x8 - PadConfigLock_DW1 >=20 > + // 0xC - OutputLock_DW1 >=20 > + // >=20 > + RegOffset +=3D DwNum * 0x8; >=20 > + } else { >=20 > + RegOffset +=3D DwNum * 0x4; >=20 > + } >=20 > + >=20 > + *ReadVal =3D MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, RegOffset)); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will write GPIO register >=20 > + >=20 > + @param[in] RegType GPIO register type >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] RegAndMask Mask which will be AND'ed with registe= r > value >=20 > + @param[in] RegOrMask Mask which will be OR'ed with register= value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED Feature is not supported for this grou= p or > pad >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioWriteReg ( >=20 > + IN GPIO_REG RegType, >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 RegAndMask, >=20 > + IN UINT32 RegOrMask >=20 > + ) >=20 > +{ >=20 > + UINT32 RegOffset; >=20 > + UINT32 GroupIndex; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 PadCfgLock; >=20 > + BOOLEAN Lockable; >=20 > + >=20 > + Lockable =3D FALSE; >=20 > + PadCfgLock =3D 0; >=20 > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + switch (RegType) { >=20 > + case GpioHostOwnershipRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; >=20 > + break; >=20 > + case GpioGpeEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; >=20 > + Lockable =3D TRUE; >=20 > + break; >=20 > + case GpioGpeStatusRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; >=20 > + break; >=20 > + case GpioSmiEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; >=20 > + Lockable =3D TRUE; >=20 > + break; >=20 > + case GpioSmiStatusRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; >=20 > + break; >=20 > + case GpioNmiEnableRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; >=20 > + Lockable =3D TRUE; >=20 > + break; >=20 > + case GpioPadConfigLockRegister: >=20 > + case GpioPadLockOutputRegister: >=20 > + default: >=20 > + break; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if selected register exists >=20 > + // >=20 > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (Lockable) { >=20 > + GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock); >=20 > + if (PadCfgLock) { >=20 > + // >=20 > + // Check if for pads which are going to be reconfigured lock is se= t. >=20 > + // >=20 > + if ((~RegAndMask | RegOrMask) & PadCfgLock) { >=20 > + // >=20 > + // Unlock all pads for this Group DW reg for simplicity >=20 > + // even if not all of those pads will have their settings reprog= rammed >=20 > + // >=20 > + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock); >=20 > + } else { >=20 > + // >=20 > + // No need to perform an unlock as pads which are going to be > reconfigured >=20 > + // are not in locked state >=20 > + // >=20 > + PadCfgLock =3D 0; >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // If there are more then 32 pads per group then certain >=20 > + // group information would be split into more then one DWord register. >=20 > + // >=20 > + RegOffset +=3D DwNum * 0x4; >=20 > + >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > RegOffset), >=20 > + RegAndMask, >=20 > + RegOrMask >=20 > + ); >=20 > + >=20 > + if (Lockable && PadCfgLock) { >=20 > + // >=20 > + // Lock previously unlocked pads >=20 > + // >=20 > + GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock); >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will write GPIO Lock/LockTx register using SBI. >=20 > + >=20 > + @param[in] RegType GPIO register (Lock or LockTx) >=20 > + @param[in] Group GPIO group number >=20 > + @param[in] DwNum Register number for current group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] LockRegAndMask Mask which will be AND'ed with Lock > register value >=20 > + @param[in] LockRegOrMask Mask which will be Or'ed with Lock > register value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_UNSUPPORTED Feature is not supported for this grou= p or > pad >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +GpioWriteLockReg ( >=20 > + IN GPIO_REG RegType, >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 LockRegAndMask, >=20 > + IN UINT32 LockRegOrMask >=20 > + ) >=20 > +{ >=20 > + UINT8 Response; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 RegOffset; >=20 > + UINT32 OldLockVal; >=20 > + UINT32 NewLockVal; >=20 > + UINT32 GroupIndex; >=20 > + EFI_STATUS Status; >=20 > + PCH_SBI_OPCODE Opcode; >=20 > + >=20 > + OldLockVal =3D 0; >=20 > + NewLockVal =3D 0; >=20 > + >=20 > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + switch (RegType) { >=20 > + case GpioPadConfigLockRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; >=20 > + GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal); >=20 > + break; >=20 > + case GpioPadLockOutputRegister: >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; >=20 > + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal); >=20 > + break; >=20 > + default: >=20 > + break; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if selected register exists >=20 > + // >=20 > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // If there are more then 32 pads per group then certain >=20 > + // group information would be split into more then one DWord register. >=20 > + // PadConfigLock and OutputLock registers when used for group > containing more than 32 pads >=20 > + // are not placed in a continuous way, e.g: >=20 > + // 0x0 - PadConfigLock_DW0 >=20 > + // 0x4 - OutputLock_DW0 >=20 > + // 0x8 - PadConfigLock_DW1 >=20 > + // 0xC - OutputLock_DW1 >=20 > + // >=20 > + RegOffset +=3D DwNum *0x8; >=20 > + >=20 > + NewLockVal =3D (OldLockVal & LockRegAndMask) | LockRegOrMask; >=20 > + >=20 > + if (IsGpioLockOpcodeSupported ()) { >=20 > + Opcode =3D GpioLockUnlock; >=20 > + } else { >=20 > + Opcode =3D PrivateControlWrite; >=20 > + } >=20 > + >=20 > + Status =3D PchSbiExecutionEx ( >=20 > + GpioGroupInfo[GroupIndex].Community, >=20 > + RegOffset, >=20 > + Opcode, >=20 > + FALSE, >=20 > + 0x000F, >=20 > + 0x0000, >=20 > + 0x0000, >=20 > + &NewLockVal, >=20 > + &Response >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This internal procedure will calculate GPIO_RESET_CONFIG value (new > type) >=20 > + based on provided PadRstCfg for a specific GPIO Pad. >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] PadRstCfg GPIO PadRstCfg value >=20 > + >=20 > + @retval GpioResetConfig GPIO Reset configuration (new type) >=20 > +**/ >=20 > +GPIO_RESET_CONFIG >=20 > +GpioResetConfigFromPadRstCfg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT32 PadRstCfg >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + >=20 > + static GPIO_RESET_CONFIG PadRstCfgToGpioResetConfigMap[] =3D { >=20 > + GpioDswReset, >=20 > + GpioHostDeepReset, >=20 > + GpioPlatformReset, >=20 > + GpioResumeReset}; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + >=20 > + if (PadRstCfg < 4) { >=20 > + if (!GpioIsDswGroup(Group) && PadRstCfg =3D=3D 3) { >=20 > + DEBUG ((DEBUG_ERROR, "ERROR: Pad %a is configured to be reset by > Global Reset without being part of DSW group\n", GpioName (GpioPad))); >=20 > + } >=20 > + return PadRstCfgToGpioResetConfigMap[PadRstCfg]; >=20 > + } >=20 > + return GpioResetDefault; >=20 > +} >=20 > + >=20 > +/** >=20 > + This internal procedure will calculate PadRstCfg register value based >=20 > + on provided GPIO Reset configuration for a certain pad. >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] GpioResetConfig GPIO Reset configuration >=20 > + @param[out] PadRstCfg GPIO PadRstCfg value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid configuration >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioPadRstCfgFromResetConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_RESET_CONFIG GpioResetConfig, >=20 > + OUT UINT32 *PadRstCfg >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + >=20 > + switch (GpioResetConfig) { >=20 > + case GpioResetDefault: >=20 > + *PadRstCfg =3D 0x0; >=20 > + break; >=20 > + case GpioHostDeepReset: >=20 > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_DEEP_RST; >=20 > + break; >=20 > + case GpioPlatformReset: >=20 > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_GPIO_RST; >=20 > + break; >=20 > + case GpioResumeReset: >=20 > + if (GpioIsDswGroup (Group)) { >=20 > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_RESUME_RST; >=20 > + } else { >=20 > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD; >=20 > + } >=20 > + break; >=20 > + case GpioDswReset: >=20 > + if (GpioIsDswGroup (Group)) { >=20 > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD; >=20 > + } else { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Only GPD group pads can use > GpioDswReset: %a\n", GpioName (GpioPad))); >=20 > + goto Error; >=20 > + } >=20 > + break; >=20 > + default: >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +Error: >=20 > + ASSERT (FALSE); >=20 > + return EFI_INVALID_PARAMETER; >=20 > +} >=20 > + >=20 > +/** >=20 > + This internal procedure will get GPIO_CONFIG data from PADCFG register= s > value >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] PadCfgDwReg PADCFG DWx register values >=20 > + @param[out] GpioData GPIO Configuration data >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +STATIC >=20 > +VOID >=20 > +GpioConfigFromPadCfgRegValue ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN CONST UINT32 *PadCfgDwReg, >=20 > + OUT GPIO_CONFIG *GpioConfig >=20 > + ) >=20 > +{ >=20 > + UINT32 PadRstCfg; >=20 > + >=20 > + // >=20 > + // Get Reset Type (PadRstCfg) >=20 > + // >=20 > + PadRstCfg =3D (PadCfgDwReg[0] & B_GPIO_PCR_RST_CONF) >> > N_GPIO_PCR_RST_CONF; >=20 > + >=20 > + GpioConfig->PowerConfig =3D GpioResetConfigFromPadRstCfg ( >=20 > + GpioPad, >=20 > + PadRstCfg >=20 > + ); >=20 > + >=20 > + // >=20 > + // Get how interrupt is triggered (RxEvCfg) >=20 > + // >=20 > + GpioConfig->InterruptConfig =3D ((PadCfgDwReg[0] & > B_GPIO_PCR_RX_LVL_EDG) >> (N_GPIO_PCR_RX_LVL_EDG - > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1))) | (0x1 << > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS); >=20 > + >=20 > + // >=20 > + // Get interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) >=20 > + // >=20 > + GpioConfig->InterruptConfig |=3D ((PadCfgDwReg[0] & > (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | > B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE)) >> > (N_GPIO_PCR_RX_NMI_ROUTE - > (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1))) | (0x1 << > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS); >=20 > + >=20 > + // >=20 > + // Get GPIO direction (GPIORxDis and GPIOTxDis) >=20 > + // >=20 > + GpioConfig->Direction =3D ((PadCfgDwReg[0] & (B_GPIO_PCR_RXDIS | > B_GPIO_PCR_TXDIS)) >> (N_GPIO_PCR_TXDIS - > (N_GPIO_DIRECTION_DIR_BIT_POS + 1))) | (0x1 << > N_GPIO_DIRECTION_DIR_BIT_POS); >=20 > + >=20 > + // >=20 > + // Get GPIO input inversion (RXINV) >=20 > + // (Only meaningful if input enabled) >=20 > + // >=20 > + if((PadCfgDwReg[0] & B_GPIO_PCR_RXDIS) =3D=3D 0) { >=20 > + GpioConfig->Direction |=3D ((PadCfgDwReg[0] & B_GPIO_PCR_RXINV) >> > (N_GPIO_PCR_RXINV - (N_GPIO_DIRECTION_INV_BIT_POS + 1))) | (0x1 << > N_GPIO_DIRECTION_INV_BIT_POS); >=20 > + } >=20 > + >=20 > + // >=20 > + // Get GPIO output state (GPIOTxState) >=20 > + // >=20 > + GpioConfig->OutputState =3D ((PadCfgDwReg[0] & B_GPIO_PCR_TX_STATE) > << (N_GPIO_PCR_TX_STATE + (N_GPIO_OUTPUT_BIT_POS + 1))) | (0x1 << > N_GPIO_OUTPUT_BIT_POS); >=20 > + >=20 > + // >=20 > + // Configure GPIO RX raw override to '1' (RXRAW1) >=20 > + // >=20 > + GpioConfig->OtherSettings =3D ((PadCfgDwReg[0] & > B_GPIO_PCR_RX_RAW1) >> (N_GPIO_PCR_RX_RAW1 - > (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1))) | (0x1 << > N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS); >=20 > + >=20 > + // >=20 > + // Get GPIO Pad Mode (PMode) >=20 > + // >=20 > + GpioConfig->PadMode =3D ((PadCfgDwReg[0] & B_GPIO_PCR_PAD_MODE) > >> (N_GPIO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 > << N_GPIO_PAD_MODE_BIT_POS); >=20 > + >=20 > + // >=20 > + // Get GPIO termination (Term) >=20 > + // >=20 > + GpioConfig->ElectricalConfig =3D ((PadCfgDwReg[1] & B_GPIO_PCR_TERM) > >> (N_GPIO_PCR_TERM - > (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1))) | (0x1 << > N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will read multiple GPIO settings >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[out] GpioData GPIO data structure >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT GPIO_CONFIG *GpioData >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; >=20 > + UINT32 RegVal; >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 PadBitPosition; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Read PADCFG DW0 register >=20 > + // >=20 > + PadCfgDwReg[0] =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + // >=20 > + // Read PADCFG DW1 register >=20 > + // >=20 > + PadCfgDwReg[1] =3D GpioReadPadCfgReg (GpioPad, 1); >=20 > + >=20 > + // >=20 > + // Read PADCFG DW2 register >=20 > + // >=20 > + PadCfgDwReg[2] =3D GpioReadPadCfgReg (GpioPad, 2); >=20 > + >=20 > + GpioConfigFromPadCfgRegValue ( >=20 > + GpioPad, >=20 > + PadCfgDwReg, >=20 > + GpioData >=20 > + ); >=20 > + >=20 > + // >=20 > + // Read HOSTSW_OWN registers >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioHostOwnershipRegister, >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &RegVal >=20 > + ); >=20 > + >=20 > + // >=20 > + // Get Host Software Ownership >=20 > + // >=20 > + GpioData->HostSoftPadOwn =3D (((RegVal >> PadBitPosition) & 0x1) << > (N_GPIO_HOSTSW_OWN_BIT_POS + 1)) | (0x1 << > N_GPIO_HOSTSW_OWN_BIT_POS); >=20 > + >=20 > + // >=20 > + // Read PADCFGLOCK register >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioPadConfigLockRegister, >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &RegVal >=20 > + ); >=20 > + >=20 > + // >=20 > + // Get Pad Configuration Lock state >=20 > + // >=20 > + GpioData->LockConfig =3D ((!((RegVal >> PadBitPosition) & 0x1)) << 1) = | BIT0; >=20 > + >=20 > + // >=20 > + // Read PADCFGLOCKTX register >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioPadLockOutputRegister, >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &RegVal >=20 > + ); >=20 > + >=20 > + // >=20 > + // Get Pad Configuration Lock Tx state >=20 > + // >=20 > + GpioData->LockConfig |=3D ((!((RegVal >> PadBitPosition) & 0x1)) << 3)= | > BIT2; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will calculate PADCFG register value based on GpioConfi= g > data >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] GpioConfig GPIO Configuration data >=20 > + @param[out] PadCfgDwReg PADCFG DWx register value >=20 > + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register > bits to be modified >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioPadCfgRegValueFromGpioConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN CONST GPIO_CONFIG *GpioConfig, >=20 > + OUT UINT32 *PadCfgDwReg, >=20 > + OUT UINT32 *PadCfgDwRegMask >=20 > + ) >=20 > +{ >=20 > + UINT32 PadRstCfg; >=20 > + >=20 > + // >=20 > + // Configure Reset Type (PadRstCfg) >=20 > + // Reset configuration depends on group type. >=20 > + // This field requires support for new and deprecated settings. >=20 > + // >=20 > + GpioPadRstCfgFromResetConfig ( >=20 > + GpioPad, >=20 > + GpioConfig->PowerConfig, >=20 > + &PadRstCfg >=20 > + ); >=20 > + >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PowerConfig & > B_GPIO_RESET_CONFIG_RESET_MASK) >> > N_GPIO_RESET_CONFIG_RESET_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : > B_GPIO_PCR_RST_CONF); >=20 > + PadCfgDwReg[0] |=3D PadRstCfg << N_GPIO_PCR_RST_CONF; >=20 > + >=20 > + // >=20 > + // Configure how interrupt is triggered (RxEvCfg) >=20 > + // >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : > B_GPIO_PCR_RX_LVL_EDG); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << > N_GPIO_PCR_RX_LVL_EDG); >=20 > + >=20 > + // >=20 > + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) >=20 > + // >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) =3D=3D GpioHardwareDefault) ? > 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)); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << > N_GPIO_PCR_RX_NMI_ROUTE); >=20 > + >=20 > + // >=20 > + // Configure GPIO direction (GPIORxDis and GPIOTxDis) >=20 > + // >=20 > + 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)); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & > B_GPIO_DIRECTION_DIR_MASK) >> (N_GPIO_DIRECTION_DIR_BIT_POS + > 1)) << N_GPIO_PCR_TXDIS); >=20 > + >=20 > + // >=20 > + // Configure GPIO input inversion (RXINV) >=20 > + // >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & > B_GPIO_DIRECTION_INV_MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RXINV); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & > B_GPIO_DIRECTION_INV_MASK) >> (N_GPIO_DIRECTION_INV_BIT_POS + > 1)) << N_GPIO_PCR_RXINV); >=20 > + >=20 > + // >=20 > + // Configure GPIO output state (GPIOTxState) >=20 > + // >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OutputState & > B_GPIO_OUTPUT_MASK) >> N_GPIO_OUTPUT_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TX_STATE); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->OutputState & > B_GPIO_OUTPUT_MASK) >> (N_GPIO_OUTPUT_BIT_POS + 1)) << > N_GPIO_PCR_TX_STATE); >=20 > + >=20 > + // >=20 > + // Configure GPIO RX raw override to '1' (RXRAW1) >=20 > + // >=20 > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OtherSettings & > B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> > N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 > : B_GPIO_PCR_RX_RAW1); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->OtherSettings & > B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> > (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << > N_GPIO_PCR_RX_RAW1); >=20 > + >=20 > + // >=20 > + // Configure GPIO Pad Mode (PMode) >=20 > + // >=20 > + 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); >=20 > + PadCfgDwReg[0] |=3D (((GpioConfig->PadMode & > B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << > N_GPIO_PCR_PAD_MODE); >=20 > + >=20 > + // >=20 > + // Configure GPIO termination (Term) >=20 > + // >=20 > + PadCfgDwRegMask[1] |=3D ((((GpioConfig->ElectricalConfig & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM); >=20 > + PadCfgDwReg[1] |=3D (((GpioConfig->ElectricalConfig & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << > N_GPIO_PCR_TERM); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will configure multiple GPIO settings >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] GpioData GPIO data structure >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_CONFIG *GpioData >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; >=20 > + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; >=20 > + UINT32 HostSoftOwnReg; >=20 > + UINT32 HostSoftOwnRegMask; >=20 > + UINT32 GpiGpeEnReg; >=20 > + UINT32 GpiGpeEnRegMask; >=20 > + UINT32 GpiNmiEnReg; >=20 > + UINT32 GpiNmiEnRegMask; >=20 > + UINT32 GpiSmiEnReg; >=20 > + UINT32 GpiSmiEnRegMask; >=20 > + GPIO_GROUP Group; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + UINT32 PadBitPosition; >=20 > + UINT32 DwNum; >=20 > + GPIO_LOCK_CONFIG LockConfig; >=20 > + >=20 > + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); >=20 > + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if Pad enabled for SCI is to be in unlocked state >=20 > + // >=20 > + if (((GpioData->InterruptConfig & GpioIntSci) =3D=3D GpioIntSci) && >=20 > + ((GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) !=3D > GpioPadConfigUnlock)){ >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a for SCI is not unlocked!\n", > GpioName (GpioPad))); >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Get GPIO PADCFG register value from GPIO config data >=20 > + // >=20 > + GpioPadCfgRegValueFromGpioConfig ( >=20 > + GpioPad, >=20 > + GpioData, >=20 > + PadCfgDwReg, >=20 > + PadCfgDwRegMask >=20 > + ); >=20 > + >=20 > + // >=20 > + // Write PADCFG DW0 register >=20 > + // >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + ~PadCfgDwRegMask[0], >=20 > + PadCfgDwReg[0] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Write PADCFG DW1 register >=20 > + // >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 1, >=20 > + ~PadCfgDwRegMask[1], >=20 > + PadCfgDwReg[1] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Write PADCFG DW2 register >=20 > + // >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 2, >=20 > + ~PadCfgDwRegMask[2], >=20 > + PadCfgDwReg[2] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Update value to be programmed in HOSTSW_OWN register >=20 > + // >=20 > + if ((GpioData->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) { >=20 > + HostSoftOwnRegMask =3D 1 << PadBitPosition; >=20 > + HostSoftOwnReg =3D 1 << PadBitPosition; >=20 > + } else { >=20 > + HostSoftOwnRegMask =3D (GpioData->HostSoftPadOwn & 0x1) << > PadBitPosition; >=20 > + HostSoftOwnReg =3D (GpioData->HostSoftPadOwn >> 0x1) << > PadBitPosition; >=20 > + } >=20 > + >=20 > + // >=20 > + // Write HOSTSW_OWN registers >=20 > + // >=20 > + GpioWriteReg ( >=20 > + GpioHostOwnershipRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~HostSoftOwnRegMask, >=20 > + HostSoftOwnReg >=20 > + ); >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_GPE_EN register >=20 > + // >=20 > + GpiGpeEnRegMask =3D (GpioData->InterruptConfig & 0x1) << > PadBitPosition; >=20 > + GpiGpeEnReg =3D ((GpioData->InterruptConfig & GpioIntSci) >> 3) << > PadBitPosition; >=20 > + >=20 > + // >=20 > + // Write GPI_GPE_EN registers >=20 > + // >=20 > + GpioWriteReg ( >=20 > + GpioGpeEnableRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~GpiGpeEnRegMask, >=20 > + GpiGpeEnReg >=20 > + ); >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_NMI_EN register >=20 > + // >=20 > + GpiNmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << > PadBitPosition; >=20 > + GpiNmiEnReg =3D ((GpioData->InterruptConfig & GpioIntNmi) >> 1) << > PadBitPosition; >=20 > + >=20 > + Status =3D GpioWriteReg ( >=20 > + GpioNmiEnableRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~GpiNmiEnRegMask, >=20 > + GpiNmiEnReg >=20 > + ); >=20 > + if (Status =3D=3D EFI_UNSUPPORTED) { >=20 > + if (GpiNmiEnReg =3D=3D 0) { >=20 > + // >=20 > + // Not all GPIO have NMI capabilities. Since we always try to prog= ram this > register, >=20 > + // even when not enabling NMI for a pad so do not report such acce= ss as > an error >=20 > + // >=20 > + Status =3D EFI_SUCCESS; >=20 > + } else { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting NMI\n", GpioGetGroupName (GroupIndex))); >=20 > + ASSERT (FALSE); >=20 > + return Status; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Update value to be programmed in GPI_SMI_EN register >=20 > + // >=20 > + GpiSmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPositio= n; >=20 > + GpiSmiEnReg =3D ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << > PadBitPosition; >=20 > + >=20 > + Status =3D GpioWriteReg ( >=20 > + GpioSmiEnableRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~GpiSmiEnRegMask, >=20 > + GpiSmiEnReg >=20 > + ); >=20 > + if (Status =3D=3D EFI_UNSUPPORTED) { >=20 > + if (GpiSmiEnReg =3D=3D 0) { >=20 > + // >=20 > + // Not all GPIO have SMI capabilities. Since we always try to prog= ram this > register, >=20 > + // even when not enabling SMI for a pad so do not report such acce= ss as > an error >=20 > + // >=20 > + Status =3D EFI_SUCCESS; >=20 > + } else { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting SMI\n", GpioGetGroupName (GroupIndex))); >=20 > + ASSERT (FALSE); >=20 > + return Status; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Store unlock data >=20 > + // >=20 > + if (GpioData->LockConfig !=3D GpioLockDefault) { >=20 > + LockConfig =3D GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK; >=20 > + // >=20 > + // If pad in GpioMode is an output default action should be to leave > output unlocked >=20 > + // >=20 > + if ((GpioData->PadMode =3D=3D GpioPadModeGpio) && >=20 > + (GpioData->Direction =3D=3D GpioDirOut) && >=20 > + ((GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D GpioLockDefault)) { >=20 > + LockConfig |=3D GpioOutputStateUnlock; >=20 > + } else { >=20 > + LockConfig |=3D GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK; >=20 > + } >=20 > + Status =3D GpioStoreUnlockData (GpioPad, LockConfig); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO output level >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Output value >=20 > + 0: OutputLow, 1: OutputHigh >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetOutputValue ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT32 Value >=20 > + ) >=20 > +{ >=20 > + if (Value > 1) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~B_GPIO_PCR_TX_STATE, >=20 > + Value << N_GPIO_PCR_TX_STATE >=20 > + ); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO output level >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] OutputVal GPIO Output value >=20 > + 0: OutputLow, 1: OutputHigh >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetOutputValue ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *OutputVal >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + *OutputVal =3D (PadCfgReg & B_GPIO_PCR_TX_STATE) >> > N_GPIO_PCR_TX_STATE; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO input level >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] InputVal GPIO Input value >=20 > + 0: InputLow, 1: InpuHigh >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetInputValue ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *InputVal >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + *InputVal =3D (PadCfgReg & B_GPIO_PCR_RX_STATE) >> > N_GPIO_PCR_RX_STATE; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO IOxAPIC interrupt number >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] IrqNum IRQ number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadIoApicIrqNumber ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *IrqNum >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 1); >=20 > + >=20 > + *IrqNum =3D (PadCfgReg & B_GPIO_PCR_INTSEL) >> N_GPIO_PCR_INTSEL; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will configure GPIO input inversion >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Value for GPIO input inversion >=20 > + 0: No input inversion, 1: Invert input >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetInputInversion ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT32 Value >=20 > + ) >=20 > +{ >=20 > + if (Value > 1) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~B_GPIO_PCR_RXINV, >=20 > + Value << N_GPIO_PCR_RXINV >=20 > + ); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO pad input inversion value >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] InvertState GPIO inversion state >=20 > + 0: No input inversion, 1: Inverted inp= ut >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetInputInversion ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *InvertState >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + *InvertState =3D (PadCfgReg & B_GPIO_PCR_RXINV) >> > N_GPIO_PCR_RXINV; >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO interrupt settings >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Value of Level/Edge >=20 > + use GPIO_INT_CONFIG as argument >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadInterruptConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_INT_CONFIG Value >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 RxLvlEdgeValue; >=20 > + UINT32 IntRouteValue; >=20 > + UINT32 PadNumber; >=20 > + UINT32 GpeEnable; >=20 > + UINT32 NmiEnable; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + if (((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) !=3D GpioHardwareDefault) { >=20 > + RxLvlEdgeValue =3D ((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << > N_GPIO_PCR_RX_LVL_EDG; >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~B_GPIO_PCR_RX_LVL_EDG, >=20 > + RxLvlEdgeValue >=20 > + ); >=20 > + } >=20 > + >=20 > + if (((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) !=3D GpioHardwareDefault) { >=20 > + >=20 > + IntRouteValue =3D ((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) > >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << > N_GPIO_PCR_RX_NMI_ROUTE; >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~(B_GPIO_PCR_RX_NMI_ROUTE | > B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | > B_GPIO_PCR_RX_APIC_ROUTE), >=20 > + IntRouteValue >=20 > + ); >=20 > + >=20 > + if ((Value & GpioIntSci) =3D=3D GpioIntSci) { >=20 > + GpeEnable =3D 0x1; >=20 > + } else { >=20 > + GpeEnable =3D 0x0; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioWriteReg ( >=20 > + GpioGpeEnableRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)), >=20 > + GpeEnable << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > + >=20 > + if ((Value & GpioIntNmi) =3D=3D GpioIntNmi) { >=20 > + NmiEnable =3D 0x1; >=20 > + } else { >=20 > + NmiEnable =3D 0x0; >=20 > + } >=20 > + >=20 > + Status =3D GpioWriteReg ( >=20 > + GpioNmiEnableRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)), >=20 > + NmiEnable << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > + if (Status =3D=3D EFI_UNSUPPORTED) { >=20 > + if (NmiEnable =3D=3D 0) { >=20 > + // >=20 > + // Not all GPIO have NMI capabilities. Since we always try to pr= ogram > this register, >=20 > + // even when not enabling NMI for a pad so do not report such ac= cess > as an error >=20 > + // >=20 > + return EFI_SUCCESS; >=20 > + } else { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting NMI\n", GpioGetGroupName (GpioGetGroupIndexFromGpioPad > (GpioPad)))); >=20 > + } >=20 > + } >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO electrical settings >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Value of termination >=20 > + use GPIO_ELECTRICAL_CONFIG as argument >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadElectricalConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_ELECTRICAL_CONFIG Value >=20 > + ) >=20 > +{ >=20 > + UINT32 TermValue; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) !=3D > GpioHardwareDefault) { >=20 > + TermValue =3D ((Value & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << > N_GPIO_PCR_TERM; >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 1, >=20 > + (UINT32)~B_GPIO_PCR_TERM, >=20 > + TermValue >=20 > + ); >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO Reset settings >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Value for Pad Reset Configuration >=20 > + use GPIO_RESET_CONFIG as argument >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadResetConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_RESET_CONFIG Value >=20 > + ) >=20 > +{ >=20 > + UINT32 PadRstCfg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (((Value & B_GPIO_RESET_CONFIG_RESET_MASK) >> > N_GPIO_RESET_CONFIG_RESET_BIT_POS) !=3D GpioHardwareDefault) { >=20 > + >=20 > + // >=20 > + // Reset configuration depends on group type. >=20 > + // This field requires support for new and deprecated settings. >=20 > + // >=20 > + GpioPadRstCfgFromResetConfig ( >=20 > + GpioPad, >=20 > + Value, >=20 > + &PadRstCfg >=20 > + ); >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~B_GPIO_PCR_RST_CONF, >=20 > + PadRstCfg << N_GPIO_PCR_RST_CONF >=20 > + ); >=20 > + } >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO Reset settings >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] Value Value of Pad Reset Configuration >=20 > + based on GPIO_RESET_CONFIG >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadResetConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_RESET_CONFIG *Value >=20 > + ) >=20 > +{ >=20 > + UINT32 PadRstCfg; >=20 > + UINT32 PadCfgDw0Reg; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgDw0Reg =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + // >=20 > + // Get Reset Type (PadRstCfg) >=20 > + // >=20 > + PadRstCfg =3D (PadCfgDw0Reg & B_GPIO_PCR_RST_CONF) >> > N_GPIO_PCR_RST_CONF; >=20 > + >=20 > + *Value =3D GpioResetConfigFromPadRstCfg ( >=20 > + GpioPad, >=20 > + PadRstCfg >=20 > + ); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This procedure will get Gpio Pad Host Software Ownership >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadHostSwOwn Value of Host Software Pad Owner >=20 > + 0: ACPI Mode, 1: GPIO Driver mode >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetHostSwOwnershipForPad ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *PadHostSwOwn >=20 > + ) >=20 > +{ >=20 > + UINT32 PadNumber; >=20 > + UINT32 HostSwRegVal; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioReadReg ( >=20 > + GpioHostOwnershipRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &HostSwRegVal >=20 > + ); >=20 > + >=20 > + *PadHostSwOwn =3D (HostSwRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set Gpio Pad Host Software Ownership >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] PadHostSwOwn Pad Host Software Owner >=20 > + 0: ACPI Mode, 1: GPIO Driver mode >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetHostSwOwnershipForPad ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT32 PadHostSwOwn >=20 > + ) >=20 > +{ >=20 > + UINT32 PadNumber; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad) || (PadHostSwOwn > 1)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + return GpioWriteReg ( >=20 > + GpioHostOwnershipRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)), >=20 > + PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get Gpio Pad Ownership >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadOwnVal Value of Pad Ownership >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadOwnership ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT GPIO_PAD_OWN *PadOwnVal >=20 > + ) >=20 > +{ >=20 > + UINT32 Mask; >=20 > + UINT32 RegOffset; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 PadOwnRegValue; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + // >=20 > + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. >=20 > + // One DWord register contains information for 8 pads. >=20 > + // >=20 > + RegOffset =3D GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber > >> 3) * 0x4; >=20 > + >=20 > + // >=20 > + // Calculate pad bit position within DWord register >=20 > + // >=20 > + PadNumber %=3D 8; >=20 > + Mask =3D (BIT1 | BIT0) << (PadNumber * 4); >=20 > + >=20 > + PadOwnRegValue =3D MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, RegOffset)); >=20 > + >=20 > + *PadOwnVal =3D (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> > (PadNumber * 4)); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check state of Pad Config Lock for pads within one > group >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLock register number for current > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[out] PadCfgLockRegVal Value of PadCfgLock register >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: NotLocked, 1: Locked >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadCfgLockForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + OUT UINT32 *PadCfgLockRegVal >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioReadReg ( >=20 > + GpioPadConfigLockRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + PadCfgLockRegVal >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check state of Pad Config Lock for selected pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadCfgLock PadCfgLock for selected pad >=20 > + 0: NotLocked, 1: Locked >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadCfgLock ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *PadCfgLock >=20 > + ) >=20 > +{ >=20 > + UINT32 PadNumber; >=20 > + UINT32 PadCfgLockRegVal; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioReadReg ( >=20 > + GpioPadConfigLockRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &PadCfgLockRegVal >=20 > + ); >=20 > + >=20 > + *PadCfgLock =3D (PadCfgLockRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check state of Pad Config Tx Lock for pads within = one > group >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLockTx register number for curre= nt > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[out] PadCfgLockTxRegVal Value of PadCfgLockTx register >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: NotLockedTx, 1: LockedT= x >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadCfgLockTxForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + OUT UINT32 *PadCfgLockTxRegVal >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioReadReg ( >=20 > + GpioPadLockOutputRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + PadCfgLockTxRegVal >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check state of Pad Config Tx Lock for selected pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadCfgLock PadCfgLockTx for selected pad >=20 > + 0: NotLockedTx, 1: LockedTx >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadCfgLockTx ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *PadCfgLockTx >=20 > + ) >=20 > +{ >=20 > + UINT32 PadNumber; >=20 > + UINT32 PadCfgLockTxRegVal; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioReadReg ( >=20 > + GpioPadLockOutputRegister, >=20 > + GpioGetGroupFromGpioPad (GpioPad), >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + &PadCfgLockTxRegVal >=20 > + ); >=20 > + >=20 > + *PadCfgLockTx =3D (PadCfgLockTxRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will clear PadCfgLock for selected pads within one grou= p. >=20 > + This function should be used only inside SMI. >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLock register number for current > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToUnlock Bitmask for pads which are going to be > unlocked, >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: DoNotUnlock, 1: Unlock >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioUnlockPadCfgForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 PadsToUnlock >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioWriteLockReg ( >=20 > + GpioPadConfigLockRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~PadsToUnlock, >=20 > + 0 >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will clear PadCfgLock for selected pad. >=20 > + This function should be used only inside SMI. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioUnlockPadCfg ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + return GpioUnlockPadCfgForGroupDw ( >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + 1 << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set PadCfgLock for selected pads within one group >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLock register number for current > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToLock Bitmask for pads which are going to be > locked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: DoNotLock, 1: Lock >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioLockPadCfgForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 PadsToLock >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioWriteLockReg ( >=20 > + GpioPadConfigLockRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~0u, >=20 > + PadsToLock >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set PadCfgLock for selected pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioLockPadCfg ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + return GpioLockPadCfgForGroupDw ( >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + 1 << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will clear PadCfgLockTx for selected pads within one gr= oup. >=20 > + This function should be used only inside SMI. >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLockTx register number for curre= nt > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToUnlockTx Bitmask for pads which are going to be > unlocked, >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: DoNotUnLockTx, 1: LockT= x >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioUnlockPadCfgTxForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 PadsToUnlockTx >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioWriteLockReg ( >=20 > + GpioPadLockOutputRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~PadsToUnlockTx, >=20 > + 0 >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will clear PadCfgLockTx for selected pad. >=20 > + This function should be used only inside SMI. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioUnlockPadCfgTx ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + return GpioUnlockPadCfgTxForGroupDw ( >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + 1 << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set PadCfgLockTx for selected pads within one grou= p >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] DwNum PadCfgLock register number for current > group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] PadsToLockTx Bitmask for pads which are going to be > locked, >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: DoNotLockTx, 1: LockTx >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioLockPadCfgTxForGroupDw ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 PadsToLockTx >=20 > + ) >=20 > +{ >=20 > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + return GpioWriteLockReg ( >=20 > + GpioPadLockOutputRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~0u, >=20 > + PadsToLockTx >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set PadCfgLockTx for selected pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioLockPadCfgTx ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + return GpioLockPadCfgTxForGroupDw ( >=20 > + Group, >=20 > + GPIO_GET_DW_NUM (PadNumber), >=20 > + 1 << GPIO_GET_PAD_POSITION (PadNumber) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get Group to GPE mapping. >=20 > + It will assume that only first 32 pads can be mapped to GPE. >=20 > + To handle cases where groups have more than 32 pads and higher part of > group >=20 > + can be mapped please refer to GpioGetGroupDwToGpeDwX() >=20 > + >=20 > + @param[out] GroupToGpeDw0 GPIO group to be mapped to GPE_DW0 >=20 > + @param[out] GroupToGpeDw1 GPIO group to be mapped to GPE_DW1 >=20 > + @param[out] GroupToGpeDw2 GPIO group to be mapped to GPE_DW2 >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGroupToGpeDwX ( >=20 > + IN GPIO_GROUP *GroupToGpeDw0, >=20 > + IN GPIO_GROUP *GroupToGpeDw1, >=20 > + IN GPIO_GROUP *GroupToGpeDw2 >=20 > + ) >=20 > +{ >=20 > + UINT32 GroupDw[3]; >=20 > + UINT32 Index; >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D GpioGetGroupDwToGpeDwX ( >=20 > + GroupToGpeDw0, >=20 > + &GroupDw[0], >=20 > + GroupToGpeDw1, >=20 > + &GroupDw[1], >=20 > + GroupToGpeDw2, >=20 > + &GroupDw[2] >=20 > + ); >=20 > + >=20 > + for (Index =3D 0; Index < ARRAY_SIZE (GroupDw); Index++) { >=20 > + if (GroupDw[Index] !=3D 0) { >=20 > + Status =3D EFI_UNSUPPORTED; >=20 > + ASSERT (FALSE); >=20 > + } >=20 > + } >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get Group to GPE mapping. If group has more than 3= 2 > bits >=20 > + it is possible to map only single DW of pins (e.g. 0-31, 32-63) becaus= e >=20 > + ACPI GPE_DWx register is 32 bits large. >=20 > + >=20 > + @param[out] GroupToGpeDw0 GPIO group mapped to GPE_DW0 >=20 > + @param[out] GroupDwForGpeDw0 DW of pins mapped to GPE_DW0 >=20 > + @param[out] GroupToGpeDw1 GPIO group mapped to GPE_DW1 >=20 > + @param[out] GroupDwForGpeDw1 DW of pins mapped to GPE_DW1 >=20 > + @param[out] GroupToGpeDw2 GPIO group mapped to GPE_DW2 >=20 > + @param[out] GroupDwForGpeDw2 DW of pins mapped to GPE_DW2 >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGroupDwToGpeDwX ( >=20 > + OUT GPIO_GROUP *GroupToGpeDw0, >=20 > + OUT UINT32 *GroupDwForGpeDw0, >=20 > + OUT GPIO_GROUP *GroupToGpeDw1, >=20 > + OUT UINT32 *GroupDwForGpeDw1, >=20 > + OUT GPIO_GROUP *GroupToGpeDw2, >=20 > + OUT UINT32 *GroupDwForGpeDw2 >=20 > + ) >=20 > +{ >=20 > + UINT32 PmcGpeDwXValue[3]; >=20 > + GPIO_GROUP GroupToGpeDwX[3]; >=20 > + UINT32 GroupDwForGpeDwX[3]; >=20 > + UINT8 GpeDwXIndex; >=20 > + UINT32 Index; >=20 > + GPIO_GROUP_TO_GPE_MAPPING *GpioGpeMap; >=20 > + UINT32 GpioGpeMapLength; >=20 > + >=20 > + ZeroMem (GroupToGpeDwX, sizeof (GroupToGpeDwX)); >=20 > + ZeroMem (GroupDwForGpeDwX, sizeof (GroupDwForGpeDwX)); >=20 > + >=20 > + PmcGetGpioGpe (&PmcGpeDwXValue[0], &PmcGpeDwXValue[1], > &PmcGpeDwXValue[2]); >=20 > + GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength); >=20 > + for (GpeDwXIndex =3D 0; GpeDwXIndex < 3; GpeDwXIndex++) { >=20 > + for (Index =3D 0; Index < GpioGpeMapLength; Index++) { >=20 > + >=20 > + if (GpioGpeMap[Index].PmcGpeDwxVal =3D=3D > PmcGpeDwXValue[GpeDwXIndex]) { >=20 > + GroupToGpeDwX[GpeDwXIndex] =3D GpioGpeMap[Index].Group; >=20 > + GroupDwForGpeDwX[GpeDwXIndex] =3D > GpioGpeMap[Index].GroupDw; >=20 > + break; >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + if ((GroupToGpeDwX[0] =3D=3D 0) || >=20 > + (GroupToGpeDwX[1] =3D=3D 0) || >=20 > + (GroupToGpeDwX[2] =3D=3D 0)) { >=20 > + ASSERT (FALSE); >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + *GroupToGpeDw0 =3D GroupToGpeDwX[0]; >=20 > + *GroupDwForGpeDw0 =3D GroupDwForGpeDwX[0]; >=20 > + *GroupToGpeDw1 =3D GroupToGpeDwX[1]; >=20 > + *GroupDwForGpeDw1 =3D GroupDwForGpeDwX[1]; >=20 > + *GroupToGpeDw2 =3D GroupToGpeDwX[2]; >=20 > + *GroupDwForGpeDw2 =3D GroupDwForGpeDwX[2]; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPE number for provided GpioPad. >=20 > + PCH allows to configure mapping between GPIO groups and related GPE > (GpioSetGroupToGpeDwX()) >=20 > + what results in the fact that certain Pad can cause different General > Purpose Event. Only three >=20 > + GPIO groups can be mapped to cause unique GPE (1-tier), all others gro= ups > will be under one common >=20 > + event (GPE_111 for 2-tier). >=20 > + >=20 > + 1-tier: >=20 > + Returned GpeNumber is in range <0,95>. GpioGetGpeNumber() can be > used >=20 > + to determine what _LXX ACPI method would be called on event on > selected GPIO pad >=20 > + >=20 > + 2-tier: >=20 > + Returned GpeNumber is 0x6F (111). All GPIO pads which are not mapped > to 1-tier GPE >=20 > + will be under one master GPE_111 which is linked to _L6F ACPI method. = If > it is needed to determine >=20 > + what Pad from 2-tier has caused the event, _L6F method should check > GPI_GPE_STS and GPI_GPE_EN >=20 > + registers for all GPIO groups not mapped to 1-tier GPE. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] GpeNumber GPE number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGpeNumber ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINT32 *GpeNumber >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP GroupToGpeDwX[3]; >=20 > + UINT32 GroupDw[3]; >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 Index; >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Get GPIO groups mapping to 1-tier GPE >=20 > + // This mapping is dependent on GPIO IP implementation >=20 > + // and may change between chipset generations >=20 > + // >=20 > + GpioGetGroupDwToGpeDwX ( >=20 > + &GroupToGpeDwX[0], &GroupDw[0], >=20 > + &GroupToGpeDwX[1], &GroupDw[1], >=20 > + &GroupToGpeDwX[2], &GroupDw[2] >=20 > + ); >=20 > + >=20 > + // >=20 > + // Check if pad is routed to 1-Tier GPE >=20 > + // >=20 > + for (Index =3D 0; Index < 3; Index++) { >=20 > + if ((Group =3D=3D GroupToGpeDwX[Index]) && (PadNumber >=3D (32 * > GroupDw[Index])) && (PadNumber < (32 * (GroupDw[Index] + 1)))) { >=20 > + *GpeNumber =3D PadNumber + (32 * Index) - (32 * GroupDw[Index]); >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // If Group number doesn't match any of above then >=20 > + // it means that the pad is routed to 2-tier GPE >=20 > + // which corresponds to GPE_111 (0x6F) >=20 > + // >=20 > + *GpeNumber =3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to clear SMI STS for a specified Pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioClearGpiSmiSts ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 DwNum; >=20 > + UINT32 PadBitPosition; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + >=20 > + // >=20 > + // Clear GPI SMI Status bit by writing '1' >=20 > + // >=20 > + return GpioWriteReg ( >=20 > + GpioSmiStatusRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + 0u, >=20 > + (UINT32) (BIT0 << PadBitPosition) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used by PchSmiDispatcher and will clear >=20 > + all GPI SMI Status bits >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioClearAllGpiSmiSts ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + UINT32 DwNum; >=20 > + GPIO_GROUP Group; >=20 > + GPIO_GROUP GroupMin; >=20 > + GPIO_GROUP GroupMax; >=20 > + >=20 > + GroupMin =3D GpioGetLowestGroup (); >=20 > + GroupMax =3D GpioGetHighestGroup (); >=20 > + >=20 > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { >=20 > + // >=20 > + // Clear all GPI SMI STS >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGetPadPerGroup (Group)); DwNum++) { >=20 > + GpioWriteReg ( >=20 > + GpioSmiStatusRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + 0u, >=20 > + 0xFFFFFFFF >=20 > + ); >=20 > + } >=20 > + } >=20 > + return EFI_SUCCESS; >=20 > + >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to disable all GPI SMI >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioDisableAllGpiSmi ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + UINT32 DwNum; >=20 > + GPIO_GROUP Group; >=20 > + GPIO_GROUP GroupMin; >=20 > + GPIO_GROUP GroupMax; >=20 > + UINT32 SmiEnRegVal; >=20 > + >=20 > + GroupMin =3D GpioGetLowestGroup (); >=20 > + GroupMax =3D GpioGetHighestGroup (); >=20 > + >=20 > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { >=20 > + // >=20 > + // Disable all GPI SMI >=20 > + // >=20 > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGetPadPerGroup (Group)); DwNum++) { >=20 > + // >=20 > + // Check which pins have SMI_EN set >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioSmiEnableRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + &SmiEnRegVal >=20 > + ); >=20 > + // >=20 > + // Set HOSTSW_OWN to GPIO mode (1) for those pins to disable SMI > capability >=20 > + // >=20 > + GpioWriteReg ( >=20 > + GpioHostOwnershipRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + ~0u, >=20 > + SmiEnRegVal >=20 > + ); >=20 > + } >=20 > + } >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to register GPI SMI dispatch function. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] GpiNum GPI number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGpiSmiNum ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT UINTN *GpiNum >=20 > + ) >=20 > +{ >=20 > + UINT32 GroupIndex; >=20 > + UINT32 Index; >=20 > + UINT32 PadNumber; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + *GpiNum =3D 0; >=20 > + >=20 > + for (Index =3D 0; Index < GroupIndex; Index++) { >=20 > + *GpiNum +=3D (UINTN) (GpioGroupInfo[Index].PadPerGroup); >=20 > + } >=20 > + *GpiNum +=3D (UINTN) PadNumber; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to check GPIO inputs belongs to 2 tier or 1 tie= r > architecture >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval Data 0 means 1-tier, 1 means 2-tier >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioCheckFor2Tier ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + UINT32 Data32; >=20 > + >=20 > + GpioGetGpeNumber (GpioPad, &Data32); >=20 > + if (Data32 =3D=3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER) { >=20 > + return TRUE; >=20 > + } >=20 > + >=20 > + return FALSE; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to clear GPE STS for a specified GpioPad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioClearGpiGpeSts ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 DwNum; >=20 > + UINT32 PadBitPosition; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check for 2-tier >=20 > + // >=20 > + if (!(GpioCheckFor2Tier (GpioPad))) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + >=20 > + // >=20 > + // Clear GPI GPE Status bit by writing '1' >=20 > + // >=20 > + return GpioWriteReg ( >=20 > + GpioGpeStatusRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + 0u, >=20 > + (UINT32) (BIT0 << PadBitPosition) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to read GPE STS for a specified Pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] GpeSts Gpe status for given pad >=20 > + The GpeSts is true if the status regis= ter is set for given Pad > number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGpiGpeSts ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT BOOLEAN *GpeSts >=20 > + ) >=20 > +{ >=20 > + UINT32 GpeStsRegVal; >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 DwNum; >=20 > + UINT32 PadBitPosition; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check for 2-tier >=20 > + // >=20 > + if (!(GpioCheckFor2Tier (GpioPad))) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + >=20 > + // >=20 > + // Read GPI GPE Status bits >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioGpeStatusRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + &GpeStsRegVal >=20 > + ); >=20 > + >=20 > + *GpeSts =3D ((GpeStsRegVal >> PadBitPosition) & 0x1) !=3D 0; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used to get SMI STS for a specified Pad >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] SmiSts Smi status for given pad >=20 > + The SmiSts is true if the status regis= ter is set for given Pad > number >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetGpiSmiSts ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT BOOLEAN *SmiSts >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + UINT32 PadNumber; >=20 > + UINT32 DwNum; >=20 > + UINT32 PadBitPosition; >=20 > + UINT32 SmiStsRegister; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + Group =3D GpioGetGroupFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); >=20 > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); >=20 > + >=20 > + // >=20 > + // Read the SMI Register >=20 > + // >=20 > + GpioReadReg ( >=20 > + GpioSmiStatusRegister, >=20 > + Group, >=20 > + DwNum, >=20 > + &SmiStsRegister >=20 > + ); >=20 > + >=20 > + *SmiSts =3D (SmiStsRegister & (BIT0 << PadBitPosition)) !=3D 0; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > GpioLibrary.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioLibrary.h > new file mode 100644 > index 0000000000..d197ee4898 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioLibrary.h > @@ -0,0 +1,82 @@ > +/** @file >=20 > + Header file for GPIO Lib implementation. >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#ifndef _GPIO_LIBRARY_H_ >=20 > +#define _GPIO_LIBRARY_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +// >=20 > +// Number of PADCFG_DW registers >=20 > +// >=20 > +#define GPIO_PADCFG_DW_REG_NUMBER 4 >=20 > + >=20 > +/** >=20 > + This internal procedure will calculate GPIO_RESET_CONFIG value (new > type) >=20 > + based on provided PadRstCfg for a specific GPIO Pad. >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] PadRstCfg GPIO PadRstCfg value >=20 > + >=20 > + @retval GpioResetConfig GPIO Reset configuration (new type) >=20 > +**/ >=20 > +GPIO_RESET_CONFIG >=20 > +GpioResetConfigFromPadRstCfg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT32 PadRstCfg >=20 > + ); >=20 > + >=20 > +/** >=20 > + This internal procedure will calculate PadRstCfg register value based >=20 > + on provided GPIO Reset configuration for a certain pad. >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] GpioResetConfig GPIO Reset configuration >=20 > + @param[out] PadRstCfg GPIO PadRstCfg value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfu= lly >=20 > + @retval EFI_INVALID_PARAMETER Invalid configuration >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioPadRstCfgFromResetConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_RESET_CONFIG GpioResetConfig, >=20 > + OUT UINT32 *PadRstCfg >=20 > + ); >=20 > + >=20 > +/** >=20 > + This procedure will calculate PADCFG register value based on GpioConfi= g > data >=20 > + >=20 > + @param[in] GpioPad GPIO Pad >=20 > + @param[in] GpioConfig GPIO Configuration data >=20 > + @param[out] PadCfgDwReg PADCFG DWx register value >=20 > + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register > bits to be modified >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioPadCfgRegValueFromGpioConfig ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN CONST GPIO_CONFIG *GpioConfig, >=20 > + OUT UINT32 *PadCfgDwReg, >=20 > + OUT UINT32 *PadCfgDwRegMask >=20 > + ); >=20 > + >=20 > +#endif // _GPIO_LIBRARY_H_ >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > GpioNames.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioNames.c > new file mode 100644 > index 0000000000..d21e77ba60 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioNames.c > @@ -0,0 +1,86 @@ > +/** @file >=20 > + This file contains GPIO name library implementation >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > + >=20 > +#include "GpioLibrary.h" >=20 > +#include >=20 > + >=20 > +/** >=20 > + Generates GPIO group name from GpioPad >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + >=20 > + @retval CHAR8* Pointer to the GPIO group name >=20 > +**/ >=20 > +CONST >=20 > +CHAR8* >=20 > +GpioGetGroupName ( >=20 > + IN UINT32 GroupIndex >=20 > + ) >=20 > +{ >=20 > + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo; >=20 > + >=20 > + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex); >=20 > + if (GroupNameInfo =3D=3D NULL) { >=20 > + return NULL; >=20 > + } else { >=20 > + return GroupNameInfo->GpioGroupPrefix; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Generates GPIO name from GpioPad >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + @param[out] GpioNameBuffer Caller allocated buffer of > GPIO_NAME_LENGTH_MAX size >=20 > + @param[in] GpioNameBufferSize Size of the buffer >=20 > + >=20 > + @retval CHAR8* Pointer to the GPIO name >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioGetPadName ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT CHAR8* GpioNameBuffer, >=20 > + IN UINT32 GpioNameBufferSize >=20 > + ) >=20 > +{ >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + UINT32 FirstUniquePadNumber; >=20 > + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo; >=20 > + >=20 > + if (GpioNameBuffer =3D=3D NULL) { >=20 > + ASSERT (FALSE); >=20 > + return NULL; >=20 > + } >=20 > + if ((GpioNameBufferSize < GPIO_NAME_LENGTH_MAX) || > !GpioIsPadValid (GpioPad)) { >=20 > + ASSERT (FALSE); >=20 > + *GpioNameBuffer =3D 0; >=20 > + return NULL; >=20 > + } >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex); >=20 > + if (GroupNameInfo =3D=3D NULL) { >=20 > + return NULL; >=20 > + } >=20 > + >=20 > + FirstUniquePadNumber =3D GpioGetPadNumberFromGpioPad > (GroupNameInfo->FirstUniqueGpio); >=20 > + if ((PadNumber < FirstUniquePadNumber) || (GroupNameInfo- > >GroupUniqueNames =3D=3D NULL)) { >=20 > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, > "GPIO_%a%d", GpioGetGroupName (GroupIndex), PadNumber); >=20 > + } else { >=20 > + if ((PadNumber - FirstUniquePadNumber) < GroupNameInfo- > >UniqueNamesTableSize) { >=20 > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a", > GroupNameInfo->GroupUniqueNames[PadNumber - > FirstUniquePadNumber]); >=20 > + } else { >=20 > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, > "GPIO_%08X", GpioPad); >=20 > + ASSERT (FALSE); >=20 > + } >=20 > + } >=20 > + >=20 > + return GpioNameBuffer; >=20 > +} >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > GpioNativeLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioNativeLib.c > new file mode 100644 > index 0000000000..97244c665b > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /GpioNativeLib.c > @@ -0,0 +1,193 @@ > +/** @file >=20 > + This file contains routines for GPIO native and chipset specific usage >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include "GpioLibrary.h" >=20 > + >=20 > +/** >=20 > + This procedure will get number of pads for certain GPIO group >=20 > + >=20 > + @param[in] Group GPIO group number >=20 > + >=20 > + @retval Value Pad number for group >=20 > + If illegal group number then return 0 >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetPadPerGroup ( >=20 > + IN GPIO_GROUP Group >=20 > + ) >=20 > +{ >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 GroupIndex; >=20 > + // >=20 > + // Check if group argument exceeds GPIO GROUP INFO array >=20 > + // >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); >=20 > + >=20 > + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) { >=20 > + return 0; >=20 > + } else { >=20 > + return GpioGroupInfo[GroupIndex].PadPerGroup; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get number of groups >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Value Group number >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetNumberOfGroups ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + UINT32 GpioGroupInfoLength; >=20 > + >=20 > + GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + return GpioGroupInfoLength; >=20 > +} >=20 > +/** >=20 > + This procedure will get lowest group >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Value Lowest Group >=20 > +**/ >=20 > +GPIO_GROUP >=20 > +GpioGetLowestGroup ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return GpioGetGroupFromGroupIndex (0); >=20 > +} >=20 > +/** >=20 > + This procedure will get highest group >=20 > + >=20 > + @param[in] none >=20 > + >=20 > + @retval Value Highest Group >=20 > +**/ >=20 > +GPIO_GROUP >=20 > +GpioGetHighestGroup ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get group number >=20 > + >=20 > + @param[in] GpioPad Gpio Pad >=20 > + >=20 > + @retval Value Group number >=20 > +**/ >=20 > +GPIO_GROUP >=20 > +GpioGetGroupFromGpioPad ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + return GPIO_GET_GROUP_FROM_PAD (GpioPad); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get group index (0 based) >=20 > + >=20 > + @param[in] GpioPad Gpio Pad >=20 > + >=20 > + @retval Value Group Index >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupIndexFromGpioPad ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get group index (0 based) from group >=20 > + >=20 > + @param[in] GpioGroup Gpio Group >=20 > + >=20 > + @retval Value Group Index >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupIndexFromGroup ( >=20 > + IN GPIO_GROUP GpioGroup >=20 > + ) >=20 > +{ >=20 > + return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get group from group index (0 based) >=20 > + >=20 > + @param[in] GroupIndex Group Index >=20 > + >=20 > + @retval GpioGroup Gpio Group >=20 > +**/ >=20 > +GPIO_GROUP >=20 > +GpioGetGroupFromGroupIndex ( >=20 > + IN UINT32 GroupIndex >=20 > + ) >=20 > +{ >=20 > + return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get pad number (0 based) from Gpio Pad >=20 > + >=20 > + @param[in] GpioPad Gpio Pad >=20 > + >=20 > + @retval Value Pad Number >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetPadNumberFromGpioPad ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad); >=20 > +} >=20 > +/** >=20 > + This procedure will return GpioPad from Group and PadNumber >=20 > + >=20 > + @param[in] Group GPIO group >=20 > + @param[in] PadNumber GPIO PadNumber >=20 > + >=20 > + @retval GpioPad GpioPad >=20 > +**/ >=20 > +GPIO_PAD >=20 > +GpioGetGpioPadFromGroupAndPadNumber ( >=20 > + IN GPIO_GROUP Group, >=20 > + IN UINT32 PadNumber >=20 > + ) >=20 > +{ >=20 > + return GPIO_PAD_DEF (Group,PadNumber); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will return GpioPad from GroupIndex and PadNumber >=20 > + >=20 > + @param[in] GroupIndex GPIO GroupIndex >=20 > + @param[in] PadNumber GPIO PadNumber >=20 > + >=20 > + @retval GpioPad GpioPad >=20 > +**/ >=20 > +GPIO_PAD >=20 > +GpioGetGpioPadFromGroupIndexAndPadNumber ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 PadNumber >=20 > + ) >=20 > +{ >=20 > + GPIO_GROUP Group; >=20 > + >=20 > + Group =3D GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); >=20 > + return GPIO_PAD_DEF (Group, PadNumber); >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib= / > PeiDxeSmmGpioLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /PeiDxeSmmGpioLib.inf > new file mode 100644 > index 0000000000..0a888a38ba > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib > /PeiDxeSmmGpioLib.inf > @@ -0,0 +1,49 @@ > +## @file >=20 > +# Component description file for the PeiDxeSmmGpioLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D PeiDxeSmmGpioLib >=20 > +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662BD7B763F2 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D BASE >=20 > +LIBRARY_CLASS =3D GpioLib >=20 > +# >=20 > +# The following information is for reference only and not required by th= e > build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC >=20 > +# >=20 > + >=20 > + >=20 > + >=20 > +[LibraryClasses] >=20 > +BaseLib >=20 > +IoLib >=20 > +DebugLib >=20 > +PrintLib >=20 > +PchCycleDecodingLib >=20 > +PchSbiAccessLib >=20 > +PmcPrivateLib >=20 > +GpioPrivateLib >=20 > +SataLib >=20 > +GpioHelpersLib >=20 > +GpioCheckConflictLib >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Pcd] >=20 > + >=20 > +[Sources] >=20 > +GpioLib.c >=20 > +GpioNativeLib.c >=20 > +GpioInit.c >=20 > +GpioNames.c >=20 > +GpioLibrary.h >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.c > new file mode 100644 > index 0000000000..2c7a1987d9 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.c > @@ -0,0 +1,119 @@ > +/** @file >=20 > + This file contains NULL implementation for GPIO Helpers Lib >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO pad unlock information >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] GpioLockConfig GPIO Lock Configuration >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreUnlockData ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_LOCK_CONFIG GpioLockConfig >=20 > + ) >=20 > +{ >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which PadConfig needs > to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockPadConfigData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ) >=20 > +{ >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which Output state > needs to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockOutputData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ) >=20 > +{ >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which PadConfig is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockPadConfigMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + return 0; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which Output is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockOutputMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + return 0; >=20 > +} >=20 > + >=20 > +/** >=20 > + Returns Gpio Override Level1 Information >=20 > + >=20 > + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioOverrideLevel1Enabled ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return FALSE; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.inf > new file mode 100644 > index 0000000000..756359d1e3 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioH= el > persLibNull/BaseGpioHelpersLibNull.inf > @@ -0,0 +1,26 @@ > +## @file >=20 > +# Component description file for the NULL GpioHelpersLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D BaseGpioHelpersLib >=20 > +FILE_GUID =3D AB282608-2A50-4AE3-9242-64064ECF40D4 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D BASE >=20 > +LIBRARY_CLASS =3D GpioHelpersLib >=20 > + >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > + >=20 > +[Sources] >=20 > +BaseGpioHelpersLibNull.c >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/DxeGpioNameBufferLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/DxeGpioNameBufferLib.inf > new file mode 100644 > index 0000000000..43860b7d20 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/DxeGpioNameBufferLib.inf > @@ -0,0 +1,32 @@ > +## @file >=20 > +# Component description file for the DxeGpioMemLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D DxeGpioNameBufferLib >=20 > +FILE_GUID =3D 16EC6AA8-81D5-4847-B6CB-662CDAB863F2 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D DXE_DRIVER >=20 > +LIBRARY_CLASS =3D GpioNameBufferLib >=20 > +# >=20 > +# The following information is for reference only and not required by th= e > build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC >=20 > +# >=20 > + >=20 > +[LibraryClasses] >=20 > +BaseLib >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Sources] >=20 > +GpioNameBufferDxe.c >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/GpioNameBufferDxe.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/GpioNameBufferDxe.c > new file mode 100644 > index 0000000000..87dc9a2cd5 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNa= m > eBufferLib/GpioNameBufferDxe.c > @@ -0,0 +1,19 @@ > +/** @file >=20 > + This file contains implementation of the GpioMemLib for DXE phase >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > + >=20 > +#include >=20 > + >=20 > +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX]; >=20 > + >=20 > +CHAR8* >=20 > +GpioGetStaticNameBuffer ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return mGpioNameBuffer; >=20 > +} >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.c > new file mode 100644 > index 0000000000..e9fe6f04e0 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.c > @@ -0,0 +1,87 @@ > +/** @file >=20 > + This file provides services for Gpio policy function >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + Print GPIO_DXE_CONFIG and serial out. >=20 > + >=20 > + @param[in] PchPolicy Pointer to a PCH_POLICY_PROTOCOL >=20 > +**/ >=20 > +VOID >=20 > +GpioDxePrintConfig ( >=20 > + IN PCH_POLICY_PROTOCOL *PchPolicy >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + GPIO_DXE_CONFIG *GpioDxeConfig; >=20 > + >=20 > + Status =3D GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (V= OID > *) &GpioDxeConfig); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "------------------ GPIO DXE Config --------------= ---- > \n")); >=20 > + DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", GpioDxeConfig- > >HideGpioAcpiDevice)); >=20 > +} >=20 > + >=20 > +/** >=20 > + Load DXE Config block default for GPIO >=20 > + >=20 > + @param[in] ConfigBlockPointer Pointer to config block >=20 > +**/ >=20 > +VOID >=20 > +GpioDxeLoadConfigDefault ( >=20 > + IN VOID *ConfigBlockPointer >=20 > + ) >=20 > +{ >=20 > + GPIO_DXE_CONFIG *GpioDxeConfig; >=20 > + GpioDxeConfig =3D ConfigBlockPointer; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Name =3D > %g\n", &GpioDxeConfig->Header.GuidHob.Name)); >=20 > + DEBUG ((DEBUG_INFO, "GpioDxeConfig- > >Header.GuidHob.Header.HobLength =3D 0x%x\n", GpioDxeConfig- > >Header.GuidHob.Header.HobLength)); >=20 > + >=20 > + GpioDxeConfig->HideGpioAcpiDevice =3D 0; >=20 > +} >=20 > + >=20 > +STATIC COMPONENT_BLOCK_ENTRY mGpioBlocks =3D { >=20 > + &gGpioDxeConfigGuid, >=20 > + sizeof (GPIO_DXE_CONFIG), >=20 > + GPIO_DXE_CONFIG_REVISION, >=20 > + GpioDxeLoadConfigDefault >=20 > +}; >=20 > + >=20 > +/** >=20 > + Get Gpio config block table size. >=20 > + >=20 > + @retval Size of config block >=20 > +**/ >=20 > +UINT16 >=20 > +GpioDxeGetConfigBlockTotalSize ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return mGpioBlocks.Size; >=20 > +} >=20 > + >=20 > +/** >=20 > + Add Gpio ConfigBlock. >=20 > + >=20 > + @param[in] ConfigBlockTableAddress The pointer to config block tabl= e >=20 > + >=20 > + @retval EFI_SUCCESS The policy default is initialize= d. >=20 > + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create > buffer >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioDxeAddConfigBlock ( >=20 > + IN VOID *ConfigBlockTableAddress >=20 > + ) >=20 > +{ >=20 > + return AddComponentConfigBlocks (ConfigBlockTableAddress, > &mGpioBlocks, 1); >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.inf > new file mode 100644 > index 0000000000..1b9d53f40c > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPo= lic > yLib/DxeGpioPolicyLib.inf > @@ -0,0 +1,31 @@ > +## @file >=20 > +# Component description file for the Gpio policy library >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D DxeGpioPolicyLib >=20 > +FILE_GUID =3D 2D2B8ECA-E343-4036-A289-3F39545AEA06 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D BASE >=20 > +LIBRARY_CLASS =3D DxeGpioPolicyLib >=20 > + >=20 > +[LibraryClasses] >=20 > +DebugLib >=20 > +ConfigBlockLib >=20 > +SiConfigBlockLib >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Sources] >=20 > +DxeGpioPolicyLib.c >=20 > + >=20 > +[Guids] >=20 > +gGpioDxeConfigGuid ## CONSUMES >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioNamesVer2.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioNamesVer2.c > new file mode 100644 > index 0000000000..4084583122 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioNamesVer2.c > @@ -0,0 +1,88 @@ > +/** @file >=20 > + This file contains GPIO name library implementation specific to Ver2 >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +STATIC CONST CHAR8* mGpioGppbNames[] =3D { >=20 > + "GSPI0_CLK_LOOPBK", >=20 > + "GSPI1_CLK_LOOPBK" >=20 > +}; >=20 > + >=20 > +STATIC CONST CHAR8* mGpioGppaNames[] =3D { >=20 > + "SPI0_CLK_LOOPBK", >=20 > + "ESPI_CLK_LOOPBK" >=20 > +}; >=20 > + >=20 > +STATIC CONST CHAR8* mPchLpGpioGpdNames[] =3D { >=20 > + "INPUT3VSEL", >=20 > + "SLP_LANB", >=20 > + "SLP_SUSB", >=20 > + "SLP_WAKEB", >=20 > + "SLP_DRAM_RESETB" >=20 > +}; >=20 > + >=20 > +STATIC CONST CHAR8* mPchLpGpioGppdNames[] =3D { >=20 > + "GSPI2_CLK_LOOPBK" >=20 > +}; >=20 > + >=20 > +STATIC CONST CHAR8* mGpioGppfNames[] =3D { >=20 > + "GPPF_CLK_LOOPBK" >=20 > +}; >=20 > + >=20 > +STATIC CONST CHAR8* mGpioGppeNames[] =3D { >=20 > + "GPPE_CLK_LOOPBK" >=20 > +}; >=20 > + >=20 > + >=20 > +STATIC CONST GPIO_GROUP_NAME_INFO mPchLpGroupDescriptors[] =3D { >=20 > + GPIO_GROUP_NAME("GPP_B", GPIO_VER2_LP_GSPI0_CLK_LOOPBK, > mGpioGppbNames), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME("GPP_A", GPIO_VER2_LP_ESPI_CLK_LOOPBK, > mGpioGppaNames), >=20 > + GPIO_GROUP_NAME_BASIC("GPP_R"), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME("GPD", GPIO_VER2_LP_INPUT3VSEL, > mPchLpGpioGpdNames), >=20 > + GPIO_GROUP_NAME_BASIC("GPP_S"), >=20 > + GPIO_GROUP_NAME_BASIC("GPP_H"), >=20 > + GPIO_GROUP_NAME("GPP_D", GPIO_VER2_LP_GSPI2_CLK_LOOPBK, > mPchLpGpioGppdNames), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME_BASIC("GPP_C"), >=20 > + GPIO_GROUP_NAME("GPP_F", GPIO_VER2_LP_GPPF_CLK_LOOPBK, > mGpioGppfNames), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME("GPP_E", GPIO_VER2_LP_GPPE_CLK_LOOPBK, > mGpioGppeNames), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME_BASIC(""), >=20 > + GPIO_GROUP_NAME_BASIC("") >=20 > +}; >=20 > + >=20 > +/** >=20 > + Returns GPIO_GROUP_NAME_INFO corresponding to the given GpioPad >=20 > + >=20 > + @param[in] GroupIndex Group index >=20 > + >=20 > + @retval GPIO_GROUP_NAME_INFO* Pointer to the > GPIO_GROUP_NAME_INFO >=20 > + @reval NULL If no group descriptor was found >=20 > +**/ >=20 > +CONST >=20 > +GPIO_GROUP_NAME_INFO* >=20 > +GpioGetGroupNameInfo ( >=20 > + IN UINT32 GroupIndex >=20 > + ) >=20 > +{ >=20 > + if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) { >=20 > + return &mPchLpGroupDescriptors[GroupIndex]; >=20 > + } >=20 > + >=20 > + ASSERT (FALSE); >=20 > + return NULL; >=20 > +} >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLib.c > new file mode 100644 > index 0000000000..f750d77e9a > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLib.c > @@ -0,0 +1,395 @@ > +/** @file >=20 > + This file contains GPIO routines for RC usage >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + This procedure is used to check if GpioPad is valid for certain chipse= t >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE This pin is valid on this chipset >=20 > + FALSE Incorrect pin >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsCorrectPadForThisChipset ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + return ((GPIO_GET_CHIPSET_ID (GpioPad) =3D=3D GpioGetThisChipsetId ()) > && >=20 > + (GpioGetGroupIndexFromGpioPad (GpioPad) < > GpioGetNumberOfGroups ())); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure is used by PchSmiDispatcher and will return information >=20 > + needed to register GPI SMI. >=20 > + >=20 > + @param[in] Index GPI SMI number >=20 > + @param[out] GpioPin GPIO pin >=20 > + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi > Registers >=20 > + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN > register >=20 > + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadAndSmiRegs ( >=20 > + IN UINT32 Index, >=20 > + OUT GPIO_PAD *GpioPin, >=20 > + OUT UINT8 *GpiSmiBitOffset, >=20 > + OUT UINT32 *GpiHostSwOwnRegAddress, >=20 > + OUT UINT32 *GpiSmiStsRegAddress >=20 > + ) >=20 > +{ >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + GPIO_GROUP GpioGroup; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 SmiStsRegOffset; >=20 > + UINT32 HostSwOwnRegOffset; >=20 > + GPIO_PAD_OWN PadOwnVal; >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + PadNumber =3D 0; >=20 > + GroupIndex =3D 0; >=20 > + for (GroupIndex =3D 0; GroupIndex < GpioGroupInfoLength; GroupIndex++) > { >=20 > + PadNumber =3D Index; >=20 > + if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) { >=20 > + // >=20 > + // Found group and pad number >=20 > + // >=20 > + break; >=20 > + } >=20 > + Index =3D Index - GpioGroupInfo[GroupIndex].PadPerGroup; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if legal pad number >=20 > + // >=20 > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup){ >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if selected group has GPI SMI Enable and Status registers >=20 > + // >=20 > + if (GpioGroupInfo[GroupIndex].SmiEnOffset =3D=3D > NO_REGISTER_FOR_PROPERTY) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + GpioGroup =3D GpioGetGroupFromGroupIndex (GroupIndex); >=20 > + *GpioPin =3D GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, > PadNumber); >=20 > + >=20 > + DEBUG_CODE_BEGIN (); >=20 > + // >=20 > + // Check if selected GPIO Pad is not owned by CSME/ISH/IE >=20 > + // >=20 > + GpioGetPadOwnership (*GpioPin, &PadOwnVal); >=20 > + if (PadOwnVal !=3D GpioPadOwnHost) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a not owned by host!\n", > GpioName (*GpioPin))); >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + DEBUG_CODE_END (); >=20 > + >=20 > + *GpiSmiBitOffset =3D (UINT8)(PadNumber % 32); >=20 > + >=20 > + HostSwOwnRegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset + > (PadNumber / 32) * 0x4; >=20 > + *GpiHostSwOwnRegAddress =3D PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, HostSwOwnRegOffset); >=20 > + >=20 > + SmiStsRegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset + > (PadNumber / 32) * 0x4; >=20 > + *GpiSmiStsRegAddress =3D PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, SmiStsRegOffset); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check if GpioPad is owned by host. >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE GPIO pad is owned by host >=20 > + @retval FALSE GPIO pad is not owned by host and should not = be > used with GPIO lib API >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsPadHostOwned ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + GPIO_PAD_OWN PadOwnVal; >=20 > + >=20 > + // >=20 > + // Check if selected GPIO Pad is not owned by CSME/ISH >=20 > + // If GPIO is not owned by Host all access to PadCfg will be dropped >=20 > + // >=20 > + GpioGetPadOwnership (GpioPad, &PadOwnVal); >=20 > + if (PadOwnVal !=3D GpioPadOwnHost) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a is not owned by host!\n", > GpioName (GpioPad))); >=20 > + return FALSE; >=20 > + } >=20 > + >=20 > + return TRUE; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will check if GpioPad argument is valid. >=20 > + Function will check below conditions: >=20 > + - GpioPad represents a pad for current PCH >=20 > + - GpioPad belongs to valid GpioGroup >=20 > + - GPIO PadNumber is not greater than number of pads for this group >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + >=20 > + @retval TRUE GPIO pad is valid and can be used with GPIO l= ib API >=20 > + @retval FALSE GPIO pad is invalid and cannot be used with G= PIO lib > API >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsPadValid ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 PadNumber; >=20 > + UINT32 GroupIndex; >=20 > + >=20 > + if (!GpioIsCorrectPadForThisChipset (GpioPad)) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used > on this chipset!\n", GpioPad)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + // >=20 > + // Check if legal pin number >=20 > + // >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { >=20 > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range > of %a group (max: %d)\n", >=20 > + = PadNumber, >=20 > + = GpioGetGroupName > (GroupIndex), >=20 > + > GpioGroupInfo[GroupIndex].PadPerGroup)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + return TRUE; >=20 > +Error: >=20 > + ASSERT (FALSE); >=20 > + return FALSE; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will read GPIO Pad Configuration register >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 >=20 > + >=20 > + @retval PadCfgRegValue PADCFG_DWx value >=20 > +**/ >=20 > +UINT32 >=20 > +GpioReadPadCfgReg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT8 DwReg >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + // >=20 > + // Create Pad Configuration register offset >=20 > + // >=20 > + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + > S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg; >=20 > + >=20 > + return MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, PadCfgReg)); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will write or read GPIO Pad Configuration register >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 >=20 > + @param[in] PadCfgAndMask Mask to be AND'ed with PADCFG reg > value >=20 > + @param[in] PadCfgOrMask Mask to be OR'ed with PADCFG reg value >=20 > + >=20 > + @retval none >=20 > +**/ >=20 > +VOID >=20 > +GpioWritePadCfgReg ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN UINT8 DwReg, >=20 > + IN UINT32 PadCfgAndMask, >=20 > + IN UINT32 PadCfgOrMask >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgReg; >=20 > + CONST GPIO_GROUP_INFO *GpioGroupInfo; >=20 > + UINT32 GpioGroupInfoLength; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + UINT32 PadCfgLock; >=20 > + UINT32 PadCfgLockTx; >=20 > + >=20 > + PadCfgLock =3D 0; >=20 > + PadCfgLockTx =3D 0; >=20 > + >=20 > + // >=20 > + // Check if Pad Configuration (except output state) is to be changed. >=20 > + // If AND and OR masks will indicate that configuration fields (other = than > output control) >=20 > + // are to be modified it means that there is a need to perform an unlo= ck (if > set) >=20 > + // >=20 > + if ((~PadCfgAndMask | PadCfgOrMask) & > (UINT32)~B_GPIO_PCR_TX_STATE) { >=20 > + GpioGetPadCfgLock (GpioPad, &PadCfgLock); >=20 > + if (PadCfgLock) { >=20 > + GpioUnlockPadCfg (GpioPad); >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if Pad Output state is to be changed >=20 > + // If AND and OR masks will indicate that output control >=20 > + // is to be modified it means that there is a need to perform an unloc= k (if > set) >=20 > + // >=20 > + if ((~PadCfgAndMask | PadCfgOrMask) & B_GPIO_PCR_TX_STATE) { >=20 > + GpioGetPadCfgLockTx (GpioPad, &PadCfgLockTx); >=20 > + if (PadCfgLockTx) { >=20 > + GpioUnlockPadCfgTx (GpioPad); >=20 > + } >=20 > + } >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + >=20 > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); >=20 > + >=20 > + // >=20 > + // Create Pad Configuration register offset >=20 > + // >=20 > + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + > S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg; >=20 > + >=20 > + MmioAndThenOr32 ( >=20 > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > PadCfgReg), >=20 > + PadCfgAndMask, >=20 > + PadCfgOrMask >=20 > + ); >=20 > + >=20 > + if (PadCfgLock) { >=20 > + GpioLockPadCfg (GpioPad); >=20 > + } >=20 > + if (PadCfgLockTx) { >=20 > + GpioLockPadCfgTx (GpioPad); >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will set GPIO mode >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] PadModeValue GPIO pad mode value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid group or pad number >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioSetPadMode ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_PAD_MODE PadModeValue >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgOrMask; >=20 > + >=20 > + PadCfgOrMask =3D 0; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if (PadModeValue !=3D (GPIO_PAD_MODE)GpioHardwareDefault) { >=20 > + >=20 > + PadCfgOrMask =3D (((PadModeValue & B_GPIO_PAD_MODE_MASK) >> > (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE); >=20 > + >=20 > + GpioWritePadCfgReg ( >=20 > + GpioPad, >=20 > + 0, >=20 > + (UINT32)~B_GPIO_PCR_PAD_MODE, >=20 > + PadCfgOrMask >=20 > + ); >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO mode >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[out] PadModeValue GPIO pad mode value >=20 > + >=20 > + @retval EFI_SUCCESS The function completed successfully >=20 > + @retval EFI_INVALID_PARAMETER Invalid GpioPad >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioGetPadMode ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + OUT GPIO_PAD_MODE *PadModeValue >=20 > + ) >=20 > +{ >=20 > + UINT32 PadCfgRegValue; >=20 > + >=20 > + if (!GpioIsPadValid (GpioPad)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (!GpioIsPadHostOwned (GpioPad)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + PadCfgRegValue =3D GpioReadPadCfgReg (GpioPad, 0); >=20 > + >=20 > + *PadModeValue =3D (GPIO_PAD_MODE)(((PadCfgRegValue & > B_GPIO_PCR_PAD_MODE) >> (N_GPIO_PCR_PAD_MODE - > (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << > N_GPIO_PAD_MODE_BIT_POS)); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + Generates GPIO name from GpioPad >=20 > + This function returns pointer to the static buffer >=20 > + >=20 > + @param[in] GpioPad GpioPad >=20 > + >=20 > + @retval CHAR8* Pointer to the gpio name string >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioName ( >=20 > + IN GPIO_PAD GpioPad >=20 > + ) >=20 > +{ >=20 > + return GpioGetPadName (GpioPad, GpioGetStaticNameBuffer (), > GPIO_NAME_LENGTH_MAX); >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLibVer2.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLibVer2.c > new file mode 100644 > index 0000000000..9fea5daa28 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/GpioPrivateLibVer2.c > @@ -0,0 +1,131 @@ > +/** @file >=20 > + This file contains VER2 specific GPIO information >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO > mPchLpGpioGroupInfo[] =3D { >=20 > + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, > R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK, > R_GPIO_VER2_PCH_LP_GPIO_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 >=20 > + {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_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 >=20 > + {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_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 >=20 > + {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_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 >=20 > + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_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 >=20 > + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > R_GPIO_VER2_PCH_LP_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 >=20 > + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, > R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK, > R_GPIO_VER2_PCH_LP_GPIO_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 >=20 > + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, > R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK, > R_GPIO_VER2_PCH_LP_GPIO_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 >=20 > + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, > R_GPIO_VER2_PCH_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_FOR_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 >=20 > + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, > R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, > R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK, > R_GPIO_VER2_PCH_LP_GPIO_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 >=20 > + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0}, >=20 > + {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, > NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERT= Y, > 0} >=20 > +}; >=20 > + >=20 > +/** >=20 > + This procedure will retrieve address and length of GPIO info table >=20 > + >=20 > + @param[out] GpioGroupInfoTableLength Length of GPIO group table >=20 > + >=20 > + @retval Pointer to GPIO group table >=20 > + >=20 > +**/ >=20 > +CONST GPIO_GROUP_INFO* >=20 > +GpioGetGroupInfoTable ( >=20 > + OUT UINT32 *GpioGroupInfoTableLength >=20 > + ) >=20 > +{ >=20 > + *GpioGroupInfoTableLength =3D ARRAY_SIZE (mPchLpGpioGroupInfo); >=20 > + return mPchLpGpioGroupInfo; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get GPIO Chipset ID specific to PCH generation and series >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetThisChipsetId ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return GPIO_VER2_LP_CHIPSET_ID; >=20 > +} >=20 > + >=20 > +/** >=20 > + This internal procedure will check if group is within DeepSleepWell. >=20 > + >=20 > + @param[in] Group GPIO Group >=20 > + >=20 > + @retval GroupWell TRUE: This is DSW Group >=20 > + FALSE: This is not DSW Group >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioIsDswGroup ( >=20 > + IN GPIO_GROUP Group >=20 > + ) >=20 > +{ >=20 > + if (Group =3D=3D GPIO_VER2_LP_GROUP_GPD) { >=20 > + return TRUE; >=20 > + } else { >=20 > + return FALSE; >=20 > + } >=20 > +} >=20 > + >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING > mPchLpGpioGroupToGpeMapping[] =3D { >=20 > + {GPIO_VER2_LP_GROUP_GPP_B, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_A, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_R, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_R}, >=20 > + {GPIO_VER2_LP_GROUP_GPD, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD }, >=20 > + {GPIO_VER2_LP_GROUP_GPP_S, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_S}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_H, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_D, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_C, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_F, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F}, >=20 > + {GPIO_VER2_LP_GROUP_GPP_E, 0, > V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E} >=20 > +}; >=20 > + >=20 > +/** >=20 > + Get information for GPIO Group required to program GPIO and PMC for > desired 1-Tier GPE mapping >=20 > + >=20 > + @param[out] GpioGroupToGpeMapping Table with GPIO Group to > GPE mapping >=20 > + @param[out] GpioGroupToGpeMappingLength GPIO Group to GPE > mapping table length >=20 > +**/ >=20 > +VOID >=20 > +GpioGetGroupToGpeMapping ( >=20 > + OUT GPIO_GROUP_TO_GPE_MAPPING **GpioGroupToGpeMapping, >=20 > + OUT UINT32 *GpioGroupToGpeMappingLength >=20 > + ) >=20 > +{ >=20 > + *GpioGroupToGpeMapping =3D mPchLpGpioGroupToGpeMapping; >=20 > + *GpioGroupToGpeMappingLength =3D ARRAY_SIZE > (mPchLpGpioGroupToGpeMapping); >=20 > +} >=20 > + >=20 > +/** >=20 > + Check if 0x13 opcode supported for writing to GPIO lock unlock registe= r >=20 > + >=20 > + @retval TRUE It's supported >=20 > + @retval FALSE It's not supported >=20 > +**/ >=20 > +BOOLEAN >=20 > +IsGpioLockOpcodeSupported ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + return TRUE; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf > new file mode 100644 > index 0000000000..a355f407f8 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmm > GpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf > @@ -0,0 +1,46 @@ > +## @file >=20 > +# Component description file for the PeiDxeSmmGpioPrivateLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D PeiDxeSmmGpioPrivateLibVer2 >=20 > +FILE_GUID =3D 680A81B0-A087-4687-B5B4-146DA30042D6 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D BASE >=20 > +LIBRARY_CLASS =3D GpioPrivateLib >=20 > +# >=20 > +# The following information is for reference only and not required by th= e > build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC >=20 > +# >=20 > + >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseLib >=20 > + IoLib >=20 > + DebugLib >=20 > + PmcLib >=20 > + PchInfoLib >=20 > + GpioLib >=20 > + GpioNameBufferLib >=20 > + SataLib >=20 > + GpioHelpersLib >=20 > + >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > + >=20 > +[Sources] >=20 > + GpioPrivateLib.c >=20 > + GpioPrivateLibVer2.c >=20 > + GpioNamesVer2.c >=20 > + >=20 > +[Pcd] >=20 > +gSiPkgTokenSpaceGuid.PcdEmbeddedEnable ## CONSU= MES >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.c > new file mode 100644 > index 0000000000..84bf655ab9 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.c > @@ -0,0 +1,413 @@ > +/** @file >=20 > + This file contains routines for PEI GPIO Helpers Lib >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +extern EFI_GUID gGpioLibUnlockHobGuid; >=20 > + >=20 > +// >=20 > +// GPIO Lock HOB >=20 > +// Stores information on GPIO pads that should be left unlocked >=20 > +// >=20 > +typedef struct { >=20 > + // >=20 > + // GPIO PadConfig unlock data >=20 > + // >=20 > + UINT32 PadConfig; >=20 > + // >=20 > + // GPIO Output unlock data >=20 > + // >=20 > + UINT32 OutputState; >=20 > +} GPIO_UNLOCK_HOB_DATA; >=20 > + >=20 > +/** >=20 > + This procedure will get index of GPIO Unlock HOB structure for selecte= d > GroupIndex and DwNum. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + >=20 > + @retval GpioUnlockHobIndex >=20 > +**/ >=20 > +STATIC >=20 > +UINT32 >=20 > +GpioUnlockDataIndex ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + UINT32 GpioUnlockDataIndex; >=20 > + UINT32 Index; >=20 > + >=20 > + GpioUnlockDataIndex =3D 0; >=20 > + >=20 > + for (Index =3D 0; Index < GroupIndex; Index++) { >=20 > + GpioUnlockDataIndex +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (GpioGetGroupFromGroupIndex (Index))) + 1; >=20 > + } >=20 > + >=20 > + GpioUnlockDataIndex +=3D DwNum; >=20 > + return GpioUnlockDataIndex; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will create GPIO HOB for storing unlock data >=20 > + >=20 > + @retval Pointer to GPIO Unlock data structure >=20 > +**/ >=20 > +STATIC >=20 > +GPIO_UNLOCK_HOB_DATA* >=20 > +GpioCreateUnlockData ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + VOID *HobData; >=20 > + GPIO_GROUP Group; >=20 > + GPIO_GROUP GroupMin; >=20 > + GPIO_GROUP GroupMax; >=20 > + UINT32 GpioUnlockDataRecords; >=20 > + >=20 > + GroupMin =3D GpioGetLowestGroup (); >=20 > + GroupMax =3D GpioGetHighestGroup (); >=20 > + GpioUnlockDataRecords =3D 0; >=20 > + >=20 > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { >=20 > + GpioUnlockDataRecords +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)) + 1; >=20 > + } >=20 > + >=20 > + HobData =3D BuildGuidHob (&gGpioLibUnlockHobGuid, > GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA)); >=20 > + if (HobData =3D=3D NULL) { >=20 > + return NULL; >=20 > + } >=20 > + >=20 > + ZeroMem (HobData, GpioUnlockDataRecords * sizeof > (GPIO_UNLOCK_HOB_DATA)); >=20 > + >=20 > + return (GPIO_UNLOCK_HOB_DATA*)HobData; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will Get GPIO Unlock data structure for storing unlock = data. >=20 > + If HOB doesn't exist it will be created. >=20 > + >=20 > + @param[out] GpioUnlockData pointer to GPIO Unlock data struct= ure >=20 > + >=20 > + @retval Length number of GPIO unlock data records >=20 > +**/ >=20 > +STATIC >=20 > +UINT32 >=20 > +GpioGetUnlockData ( >=20 > + GPIO_UNLOCK_HOB_DATA **GpioUnlockData >=20 > + ) >=20 > +{ >=20 > + VOID *Hob; >=20 > + >=20 > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); >=20 > + if (Hob =3D=3D NULL) { >=20 > + // >=20 > + // It is the first time this function is used so create the HOB >=20 > + // >=20 > + *GpioUnlockData =3D GpioCreateUnlockData (); >=20 > + if (*GpioUnlockData =3D=3D NULL) { >=20 > + return 0; >=20 > + } >=20 > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); >=20 > + } else { >=20 > + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) > GET_GUID_HOB_DATA (Hob); >=20 > + } >=20 > + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof > (GPIO_UNLOCK_HOB_DATA); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get pointer to GPIO Unlock data structure. >=20 > + >=20 > + @param[out] GpioUnlockData pointer to GPIO Unlock data struct= ure >=20 > + >=20 > + @retval Length number of GPIO unlock data records >=20 > +**/ >=20 > +STATIC >=20 > +UINT32 >=20 > +GpioLocateUnlockData ( >=20 > + GPIO_UNLOCK_HOB_DATA **GpioUnlockData >=20 > + ) >=20 > +{ >=20 > + VOID *Hob; >=20 > + >=20 > + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid); >=20 > + if (Hob =3D=3D NULL) { >=20 > + *GpioUnlockData =3D NULL; >=20 > + return 0; >=20 > + } >=20 > + >=20 > + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA > (Hob); >=20 > + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof > (GPIO_UNLOCK_HOB_DATA); >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO pad unlock information >=20 > + >=20 > + @param[in] GpioPad GPIO pad >=20 > + @param[in] GpioLockConfig GPIO Lock Configuration >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreUnlockData ( >=20 > + IN GPIO_PAD GpioPad, >=20 > + IN GPIO_LOCK_CONFIG GpioLockConfig >=20 > + ) >=20 > +{ >=20 > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; >=20 > + UINT32 Length; >=20 > + UINT32 GroupIndex; >=20 > + UINT32 PadNumber; >=20 > + UINT32 Index; >=20 > + >=20 > + if (GpioLockConfig =3D=3D GpioLockDefault) { >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + Length =3D GpioGetUnlockData (&GpioUnlockData); >=20 > + if (Length =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); >=20 > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); >=20 > + Index =3D GpioUnlockDataIndex (GroupIndex, GPIO_GET_DW_NUM > (PadNumber)); >=20 > + >=20 > + if (Index >=3D Length) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) > =3D=3D GpioPadConfigUnlock) { >=20 > + GpioUnlockData[Index].PadConfig |=3D 1 << > (GpioGetPadNumberFromGpioPad (GpioPad) % 32); >=20 > + } >=20 > + >=20 > + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D > GpioOutputStateUnlock) { >=20 > + GpioUnlockData[Index].OutputState |=3D 1 << > (GpioGetPadNumberFromGpioPad (GpioPad) % 32); >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which PadConfig needs > to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockPadConfigData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ) >=20 > +{ >=20 > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; >=20 > + UINT32 Length; >=20 > + UINT32 Index; >=20 > + >=20 > + if (UnlockedPads =3D=3D 0) { >=20 > + // >=20 > + // No pads to be left unlocked >=20 > + // >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + Length =3D GpioGetUnlockData (&GpioUnlockData); >=20 > + if (Length =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); >=20 > + if (Index >=3D Length) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + GpioUnlockData[Index].PadConfig |=3D UnlockedPads; >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure stores GPIO group data about pads which Output state > needs to be unlocked. >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @param[in] UnlockedPads DWORD bitmask for pads which are going > to be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: Skip, 1: Leave unlocked >=20 > + @retval Status >=20 > +**/ >=20 > +EFI_STATUS >=20 > +GpioStoreGroupDwUnlockOutputData ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum, >=20 > + IN UINT32 UnlockedPads >=20 > + ) >=20 > +{ >=20 > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; >=20 > + UINT32 Length; >=20 > + UINT32 Index; >=20 > + >=20 > + if (UnlockedPads =3D=3D 0) { >=20 > + // >=20 > + // No pads to be left unlocked >=20 > + // >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + Length =3D GpioGetUnlockData (&GpioUnlockData); >=20 > + if (Length =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); >=20 > + if (Index >=3D Length) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + GpioUnlockData[Index].OutputState |=3D UnlockedPads; >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which PadConfig is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockPadConfigMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; >=20 > + UINT32 Length; >=20 > + UINT32 Index; >=20 > + >=20 > + Length =3D GpioLocateUnlockData (&GpioUnlockData); >=20 > + if (Length =3D=3D 0) { >=20 > + return 0; >=20 > + } >=20 > + >=20 > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); >=20 > + if (Index >=3D Length) { >=20 > + return 0; >=20 > + } >=20 > + >=20 > + return GpioUnlockData[Index].PadConfig; >=20 > +} >=20 > + >=20 > +/** >=20 > + This procedure will get GPIO group data with pads, which Output is > supposed to be left unlock >=20 > + >=20 > + @param[in] GroupIndex GPIO group index >=20 > + @param[in] DwNum DWORD index for a group. >=20 > + For group which has less then 32 pads = per group DwNum > must be 0. >=20 > + @retval UnlockedPads DWORD bitmask for pads which are going= to > be left unlocked >=20 > + Bit position - PadNumber >=20 > + Bit value - 0: to be locked, 1: Leave = unlocked >=20 > +**/ >=20 > +UINT32 >=20 > +GpioGetGroupDwUnlockOutputMask ( >=20 > + IN UINT32 GroupIndex, >=20 > + IN UINT32 DwNum >=20 > + ) >=20 > +{ >=20 > + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; >=20 > + UINT32 Length; >=20 > + UINT32 Index; >=20 > + >=20 > + Length =3D GpioLocateUnlockData (&GpioUnlockData); >=20 > + if (Length =3D=3D 0) { >=20 > + return 0; >=20 > + } >=20 > + >=20 > + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum); >=20 > + if (Index >=3D Length) { >=20 > + return 0; >=20 > + } >=20 > + >=20 > + return GpioUnlockData[Index].OutputState; >=20 > +} >=20 > + >=20 > +/** >=20 > + Obtains GpioOverride Information from PreMem config >=20 > + >=20 > + @retval TRUE GPIO Override obtained successfully >=20 > + FALSE Unable to obtain GPIO Override data >=20 > +**/ >=20 > +BOOLEAN >=20 > +STATIC >=20 > +GetGpioOverrideFromConfigBlock ( >=20 > + IN OUT UINT8 *GpioOverride >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi; >=20 > + PCH_GENERAL_PREMEM_CONFIG *PchGeneralPreMemConfig; >=20 > + >=20 > + Status =3D PeiServicesLocatePpi ( >=20 > + &gSiPreMemPolicyPpiGuid, >=20 > + 0, >=20 > + NULL, >=20 > + (VOID **) &SiPreMemPolicyPpi >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + return FALSE; >=20 > + } >=20 > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig); >=20 > + if (EFI_ERROR (Status)) { >=20 > + return FALSE; >=20 > + } >=20 > + *GpioOverride =3D (UINT8) PchGeneralPreMemConfig->GpioOverride; >=20 > + >=20 > + return TRUE; >=20 > +} >=20 > + >=20 > +/** >=20 > + Returns Gpio Override Level1 Information >=20 > + >=20 > + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled >=20 > +**/ >=20 > +BOOLEAN >=20 > +GpioOverrideLevel1Enabled ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + UINT8 GpioOverride; >=20 > + >=20 > + GpioOverride =3D 0; >=20 > + >=20 > + if (GetGpioOverrideFromConfigBlock (&GpioOverride)) { >=20 > + if (GpioOverride =3D=3D 1) { return TRUE; } >=20 > + } >=20 > + >=20 > + return FALSE; >=20 > +} >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.inf > new file mode 100644 > index 0000000000..d70c2a1352 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHe= lp > ersLib/PeiGpioHelpersLib.inf > @@ -0,0 +1,48 @@ > +## @file >=20 > +# Component description file for the PeiGpioHelpersLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D PeiGpioHelpersLib >=20 > +FILE_GUID =3D 1838E1E7-3CC4-4A74-90D9-B421EF2A579F >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D PEIM >=20 > +LIBRARY_CLASS =3D GpioHelpersLib >=20 > +# >=20 > +# The following information is for reference only and not required by th= e > build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC >=20 > +# >=20 > + >=20 > + >=20 > +[LibraryClasses] >=20 > +BaseLib >=20 > +IoLib >=20 > +DebugLib >=20 > +HobLib >=20 > +GpioLib >=20 > +PeiServicesLib >=20 > + >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > + >=20 > +[Sources] >=20 > +PeiGpioHelpersLib.c >=20 > + >=20 > + >=20 > +[Guids] >=20 > +gGpioLibUnlockHobGuid >=20 > +gPchGeneralPreMemConfigGuid ## CONSUMES >=20 > + >=20 > +[Ppis] >=20 > +gSiPreMemPolicyPpiGuid >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/GpioNameBufferPei.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/GpioNameBufferPei.c > new file mode 100644 > index 0000000000..920d9a2cbc > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/GpioNameBufferPei.c > @@ -0,0 +1,67 @@ > +/** @file >=20 > + This file contains GpioMemLib implementation for PEI phase >=20 > + >=20 > + Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +STATIC CONST EFI_GUID mGpioNamesPrivateHobGuid =3D {0x9AE3138D, > 0x4EBF, 0x4E90, {0x87, 0x96, 0x11, 0xD3, 0x10, 0x04, 0x60, 0x0A}}; >=20 > + >=20 > +STATIC volatile BOOLEAN mGlobalMemoryWorking =3D FALSE; >=20 > + >=20 > +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX]; >=20 > + >=20 > +/** >=20 > + Returns pointer to the buffer taken from GpioLib private HOB >=20 > + >=20 > + @retval CHAR8* Pointer to the buffer >=20 > +**/ >=20 > +STATIC >=20 > +CHAR8* >=20 > +GetBufferFromHob ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + VOID *Hob; >=20 > + CHAR8 *GpioNameBuffer; >=20 > + >=20 > + Hob =3D NULL; >=20 > + GpioNameBuffer =3D NULL; >=20 > + >=20 > + Hob =3D GetFirstGuidHob (&mGpioNamesPrivateHobGuid); >=20 > + if (Hob !=3D NULL){ >=20 > + GpioNameBuffer =3D (CHAR8*) GET_GUID_HOB_DATA (Hob); >=20 > + } else { >=20 > + GpioNameBuffer =3D (CHAR8*) BuildGuidHob > (&mGpioNamesPrivateHobGuid, GPIO_NAME_LENGTH_MAX); >=20 > + if (GpioNameBuffer =3D=3D NULL){ >=20 > + DEBUG ((DEBUG_ERROR, "Failed to setup HOB for GPIO names lib\n")); >=20 > + ASSERT (FALSE); >=20 > + } >=20 > + } >=20 > + return GpioNameBuffer; >=20 > +} >=20 > + >=20 > +/** >=20 > + Returns pointer to the global buffer to be used by GpioNamesLib >=20 > + >=20 > + @retval CHAR8* Pointer to the buffer >=20 > +**/ >=20 > +CHAR8* >=20 > +GpioGetStaticNameBuffer ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + mGlobalMemoryWorking =3D TRUE; >=20 > + >=20 > + if (mGlobalMemoryWorking) { >=20 > + return mGpioNameBuffer; >=20 > + } else { >=20 > + return GetBufferFromHob (); >=20 > + } >=20 > +} >=20 > + >=20 > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/PeiGpioNameBufferLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/PeiGpioNameBufferLib.inf > new file mode 100644 > index 0000000000..0525a42a8d > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNa= m > eBufferLib/PeiGpioNameBufferLib.inf > @@ -0,0 +1,35 @@ > +## @file >=20 > +# Component description file for the PeiGpioMemLib >=20 > +# >=20 > +# Copyright (c) 2021, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + >=20 > +[Defines] >=20 > +INF_VERSION =3D 0x00010017 >=20 > +BASE_NAME =3D PeiGpioNameBufferLib >=20 > +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662CDAB863F2 >=20 > +VERSION_STRING =3D 1.0 >=20 > +MODULE_TYPE =3D PEIM >=20 > +LIBRARY_CLASS =3D GpioNameBufferLib >=20 > +# >=20 > +# The following information is for reference only and not required by th= e > build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 >=20 > +# >=20 > + >=20 > +[LibraryClasses] >=20 > +HobLib >=20 > +BaseLib >=20 > +IoLib >=20 > +DebugLib >=20 > + >=20 > +[Packages] >=20 > +MdePkg/MdePkg.dec >=20 > +TigerlakeSiliconPkg/SiPkg.dec >=20 > + >=20 > +[Sources] >=20 > +GpioNameBufferPei.c >=20 > + >=20 > -- > 2.24.0.windows.2