From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com [40.107.220.104]) by mx.groups.io with SMTP id smtpd.web08.5488.1622023890545973044 for ; Wed, 26 May 2021 03:11:30 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=PBFgkKUF; spf=pass (domain: os.amperecomputing.com, ip: 40.107.220.104, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VnJrpIBpEYmt8sDcc3+uRxtA/E/3wcv75Exp83ci2naa7qkVmgWa+/IYmUBprkCjGXXIIkP+Z50/hgYNERzEV6p8zlmURj/FROXvcWVBygIj6rnYGrci3TMyjMfh+RtrpET7i0EpxPREBe4ahxrVd0gBvTg0wTZ51220llRQZPLWxChVDLcWC20Vk/axVjnfNYH+WS6rx59CpyiDuU+eXkWhNZv8vQ/EH5Wc5gAKlLcY5HqVy3Qy2Z9HXrgnGqE8vTXZELiUZrVIkk4NJgZpS8Mf0e3KtgTexhCRX14V9EDL9PXFa8XF+5BN53rSoHpCZqbjTbJZqZK57vBaC7PSvA== 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=1USQnIo8jTbdo6+rCwo7/ZiqD0wpacT58b21OdPF1Zk=; b=Gi9tJ3fKjCbhouAG7ho/8+b0NaKwH+yFy/2uRRHE2jgn7Xbs1CFFkVPzDTUpkrf0uqeePpydUfVwE2SVY9rd71AucdrnnzKUjlZMgqoMpUCZ+t1lJjS0eE9sfkIWdeGfdgRRGTOjK9ovV6fy02wOoBmXVwH+U1chM50/Aow2so6oh9CDIHs33qjRiy8HHtIlSwDL7cRs5jO92eKps13fnhZM2cWI6uCEHuVcQDDppyldw7W2dYiPCE4rzpuo4hStNi/lEKdsGdNcnH2ult+k0NcUo+s9vkuqTnx7zejCe4Yqf8PPTOLdTw4d+1soLyZHFRO9WYJkNUqOmGsB+zl8SA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1USQnIo8jTbdo6+rCwo7/ZiqD0wpacT58b21OdPF1Zk=; b=PBFgkKUFIdgjyTONLLTYNahaOEoa3iAEGbn5AzsWPtKTQIGvP5XEXp5yO4h1pOruNcwjioewEruex39K9ByCIOXi5nRcJqwvfz7bvdhrPKNtlGyIelU1FqJEwNFP3oCHSy0kftflx71ceFaagt42VXRCesCixQ0vBE/zOOWGieM= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=os.amperecomputing.com; Received: from DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) by DM5PR0101MB3067.prod.exchangelabs.com (2603:10b6:4:31::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4129.28; Wed, 26 May 2021 10:11:29 +0000 Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::60d2:86dd:1f1c:51dd]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::60d2:86dd:1f1c:51dd%7]) with mapi id 15.20.4173.020; Wed, 26 May 2021 10:11:29 +0000 From: "Nhi Pham" To: devel@edk2.groups.io CC: Vu Nguyen , Thang Nguyen , Chuong Tran , Phong Vo , Leif Lindholm , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Date: Wed, 26 May 2021 17:06:58 +0700 Message-ID: <20210526100724.5359-8-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210526100724.5359-1-nhi@os.amperecomputing.com> References: <20210526100724.5359-1-nhi@os.amperecomputing.com> X-Originating-IP: [118.69.219.201] X-ClientProxiedBy: HKAPR04CA0008.apcprd04.prod.outlook.com (2603:1096:203:d0::18) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (118.69.219.201) by HKAPR04CA0008.apcprd04.prod.outlook.com (2603:1096:203:d0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4173.20 via Frontend Transport; Wed, 26 May 2021 10:11:26 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 45cbaa5e-bb28-41e4-e622-08d9202ea10a X-MS-TrafficTypeDiagnostic: DM5PR0101MB3067: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: T7B4f8ymP1GvqDKS36s3Gh0jgMJC/sknhPap4KRH1AQ04bAYHB8d8EowDGwk5qYnfjE+kZztouGdWu2KU1asy2zRgGN4k3Q7oIlD4PTI9DXvJZb+Qo2LPopcqxk3lWR1ICDBs8K1luLfJXxPw7qg7rxM/EkKI2t/7UCBaFDr6Rh5U4ljnALL0ZHPz8QPpVWvRhYV/x8KvQKrBf2sgXNeG+EeXS/YiE+uDua91Oqp2DtN+fjf7ByGJPkaAqMRsD22ugfFGYaCJ6mHVZwjbGwCLO7ttDGVvMU2/05mq/3N43NtGzAil6Xs1jc/7mpaFWEgV8L1vNXP2vxpXRxzWj8F8ol7AQo/43Gi6kyniZwezVsfQiF6JGpeWdtIOi4QyOMYPPVr+u8ABp631+0rAPp4zRzwhFnSvIsrpPIhvg4JQaUwurnt2N2GlgV5MLGhHZaQ0UggrMO3tbASIL8VZIq5Q12gtt+x+e2HJ6ERP1+xsjIf3VYlfR8MeRU/o+1wbBHrEljgmyKY0SnIjFzSA+rM9ubsrtbd9sLZnhrQ1ziiko3ltTMJi9Rr36HybtoZOe8Ax81RYVnQwHKSyvAxphpjIEN+ixjhOkf68Wg11v7mVvPZ1RWf2EwcdbNWPVeBZSmpnDBhN9ieJgwROu8UaoiV6JcEhm34+eUHJEUZ9AsJrUwQizCFfkIXaE+cm7lLg7xj X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM6PR01MB5849.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(6029001)(4636009)(396003)(39840400004)(346002)(136003)(376002)(366004)(4326008)(26005)(6666004)(1076003)(2616005)(38350700002)(6506007)(83380400001)(86362001)(2906002)(6486002)(8676002)(30864003)(956004)(52116002)(8936002)(186003)(54906003)(66556008)(6916009)(66476007)(6512007)(66946007)(38100700002)(5660300002)(16526019)(478600001)(316002)(69590400013);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?h//3uAYKp15i6aj4HpZIss56Jhn43IWcdrumhEHKRzEpbx7GYsc4tT9VcSt8?= =?us-ascii?Q?zV+tJskpLen2GaCxsCsJ62HQkc2D0gpO6bD0nUu6n/8JM9+qqlTr+OZmVhcX?= =?us-ascii?Q?QpUbyKtCxw116ZWUQwk6Wkz1X7IZyYeh5CMwMPz6t92A1RS+wMQDBkXXpa8Z?= =?us-ascii?Q?PKYNcadB88Qst4uzTMGG+DULicoucTs8ZGZwb6AvgzfC1BQgA1m8rKY++TD9?= =?us-ascii?Q?lCeWBks0nC444Hpv2/lVx3rIUb+uVwAi+uNAW+KVTA3dx4/X/pCT9nlS/U7E?= =?us-ascii?Q?h9EzkjIJw/Iye0xovs0A3NZx3P+mk0zvg+3zMYTsyxefcSgKev5svA6t4WM+?= =?us-ascii?Q?nEainriC+AXGB6vT+bPoeESYiyNOcP2UODVw2BGJ5CTaktwkYfJxHPYl6szX?= =?us-ascii?Q?Cle7g5K+sQacvKqVV4myTUai/mLChuOcCKo4F99mC2/hq/YhrwktsL3E3OlJ?= =?us-ascii?Q?BB2Sns/fKbachNNIP+znMPbBd0IJYUiMjQl+Sd4J6+fNL3RNPSsI57Awox/F?= =?us-ascii?Q?J7yyWzvnhKZjCutX+dNuUBQRU5EpfHkiVPxaAx18VdOVNk4jZ90vaV25ibSM?= =?us-ascii?Q?jeEX9fdVAZJbSqnbfW9i0vHTaBQHobXGHMhA2i73RiegNHQCjHcBcLZxgSrL?= =?us-ascii?Q?a33k/zCeTSE5l7v9DQvLYmOF7BdpXWXJKyBUICT1D/zZg6H60WKobCcpBt8u?= =?us-ascii?Q?r5iJ1WSX1JIKzfyl3iwnxLKP9+SbyRuUJ2sd8ze5HgE3pS7eq1p1JRX0Mu4e?= =?us-ascii?Q?lFazPVVZSMoOT07thKeWlEjdXZKjKRaJZve+hLqUG4Dcc1poqiPZeXGMkWlh?= =?us-ascii?Q?2H1Mkf+8ftNz43suA5Y/sNg47/za2HdYnDS6pFJXPYMiELtBdSfpyUt92v8b?= =?us-ascii?Q?8mPwoAGTRbC8nh+SJUVfB4yML/5/IKniqJJSVZvKgm61xD9liPTjLWdyTvpf?= =?us-ascii?Q?WzhdtpPM3dXH1RkrHF5Ixvls8pwYeFe+V1lu8yESEgRlHPGZ2vPE387iudz1?= =?us-ascii?Q?jukoBfQmSFFo1toXst5o7XhVn49u4ZA15PYFihpClq8+c+0vNhkdfi3KlbsI?= =?us-ascii?Q?iU/SNG1yiu4wjA5NICiATDxP337XH9IZv33jUEkxxbQloBDYwOs20oFfn2B0?= =?us-ascii?Q?sHgMQAHdvjImAk5g8P8yMjNoqFiNkG2QUflgIEORXnLG4rfKlJY7JlfkSNrS?= =?us-ascii?Q?7VldR+Fv491rtVDxUafCHDf3ATYiDrSvZOA4m9fLP7xpbRp+H02pc34G/Xep?= =?us-ascii?Q?I1tqp+FaP34cfMplhZ0wa4V15GuStFPeQyWODYHlbnrdeeCK9TQShtvqi6fc?= =?us-ascii?Q?yukA3Vz5fcCPc1qswb9m8Hio?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 45cbaa5e-bb28-41e4-e622-08d9202ea10a X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 May 2021 10:11:29.3655 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 007nIdurNf5X304lWtXNG/znZObCn8nRtg5g4bipTA9wWJesR4dqEN/+Uks04ewr97zO/dL2Ze4MqVLeZHlULBRRBOQneA9EPcTNAHeDZ6w= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR0101MB3067 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Vu Nguyen The DwGpioLib library provides basic functions to control the GPIO controller on Ampere Altra processor. Cc: Thang Nguyen Cc: Chuong Tran Cc: Phong Vo Cc: Leif Lindholm Cc: Michael D Kinney Cc: Ard Biesheuvel Cc: Nate DeSimone Signed-off-by: Vu Nguyen --- Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 + Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf | 33 ++ Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h | 76 +++++ Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c | 314 ++++++= ++++++++++++++ 4 files changed, 426 insertions(+) diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Amp= ere/AmpereAltraPkg/AmpereAltraPkg.dec index 8be6a329bb26..be827dd19a96 100644 --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec @@ -31,6 +31,9 @@ [LibraryClasses] ## @libraryclass Defines a set of methods to read/write to I2C devices= . I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h =20 + ## @libraryclass Defines a set of methods to get/set GPIO. + GpioLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h + ## @libraryclass Defines a set of methods to communicate with secure p= arition over MM interface. MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommu= nicationLib.h =20 diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf = b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf new file mode 100644 index 000000000000..36ce0c3be2c8 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf @@ -0,0 +1,33 @@ +## @file +# Component description for DwGpioLib library for the Designware GPIO cont= roller. +# +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D DwGpioLib + FILE_GUID =3D E7D9CAE1-6930-46E3-BDF9-0027446E7DF2 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D GpioLib + +[Sources.common] + DwGpioLib.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + IoLib + +[Guids] + gEfiEventVirtualAddressChangeGuid diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h b/Sili= con/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h new file mode 100755 index 000000000000..cb201bc98322 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h @@ -0,0 +1,76 @@ +/** @file + Library implementation for the Designware GPIO controller. + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef GPIO_LIB_H_ +#define GPIO_LIB_H_ + +enum SocGpioConfigMode { + GPIO_CONFIG_OUT_LOW =3D 0, + GPIO_CONFIG_OUT_HI, + GPIO_CONFIG_OUT_LOW_TO_HIGH, + GPIO_CONFIG_OUT_HIGH_TO_LOW, + GPIO_CONFIG_IN, + MAX_GPIO_CONFIG_MODE +}; + +/* + * GpioWriteBit: Use to Set/Clear GPIOs + * Input: + * Pin : Pin Identification + * Val : 1 to Set, 0 to Clear + */ +VOID +EFIAPI +GpioWriteBit ( + IN UINT32 Pin, + IN UINT32 Val + ); + +/* + * GpioReadBit: + * Input: + * Pin : Pin Identification + * Return: + * 1 : On/High + * 0 : Off/Low + */ +UINTN +EFIAPI +GpioReadBit ( + IN UINT32 Pin + ); + +/* + * GpioModeConfig: Use to configure GPIOs as Input/Output + * Input: + * Pin : Pin Identification + * InOut : GPIO_OUT/1 as Output + * GPIO_IN/0 as Input + */ +EFI_STATUS +EFIAPI +GpioModeConfig ( + UINT8 Pin, + UINTN Mode + ); + +/* + * Setup a controller that to be used in runtime service. + * Input: + * Pin: Pin belongs to the controller. + * return: 0 for success. + * Otherwise, error code. + */ +EFI_STATUS +EFIAPI +GpioSetupRuntime ( + IN UINT32 Pin + ); + +#endif /* GPIO_LIB_H_ */ diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c b/= Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c new file mode 100644 index 000000000000..dbb53f7d57d2 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c @@ -0,0 +1,314 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Runtime needs to be 64K alignment */ +#define RUNTIME_ADDRESS_MASK (~(SIZE_64KB - 1)) +#define RUNTIME_ADDRESS_LENGTH SIZE_64KB + +#define GPIO_MUX_VAL(Gpio) (0x00000001 << (Gpio)) +#define GPIO_IN 0 +#define GPIO_OUT 1 + +/* Address GPIO_REG Registers */ +#define GPIO_SWPORTA_DR_ADDR 0x00000000 +#define GPIO_SWPORTA_DDR_ADDR 0x00000004 +#define GPIO_EXT_PORTA_ADDR 0x00000050 + +STATIC UINT64 GpioBaseAddr[] =3D { GPIO_DWAPB_BASE_ADDR }; +STATIC UINT64 GpiBaseAddr[] =3D { GPI_DWAPB_BASE_ADDR }; +STATIC BOOLEAN GpioRuntimeEnableArray[sizeof (GpioBaseAddr) / sizeof (Gp= ioBaseAddr[0])] =3D { FALSE }; +STATIC EFI_EVENT mVirtualAddressChangeEvent =3D NULL; + +UINT64 +GetBaseAddr ( + IN UINT32 Pin + ) +{ + UINT32 NumberOfControllers =3D sizeof (GpioBaseAddr) / sizeof (GpioBaseA= ddr[0]); + UINT32 TotalPins =3D GPIO_DWAPB_PINS_PER_CONTROLLER * NumberOfController= s; + + if (NumberOfControllers =3D=3D 0 || Pin >=3D TotalPins) { + return 0; + } + + return GpioBaseAddr[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER]; +} + +VOID +GpioWrite ( + IN UINT64 Base, + IN UINT32 Val + ) +{ + MmioWrite32 ((UINTN)Base, Val); +} + +VOID +GpioRead ( + IN UINT64 Base, + OUT UINT32 *Val + ) +{ + ASSERT (Val !=3D NULL); + *Val =3D MmioRead32 (Base); +} + +VOID +EFIAPI +GpioWriteBit ( + IN UINT32 Pin, + IN UINT32 Val + ) +{ + UINT64 Reg; + UINT32 GpioPin; + UINT32 ReadVal; + + Reg =3D GetBaseAddr (Pin); + if (Reg =3D=3D 0) { + return; + } + + GpioPin =3D Pin % GPIO_DWAPB_PINS_PER_CONTROLLER; + + Reg +=3D GPIO_SWPORTA_DR_ADDR; + GpioRead (Reg, &ReadVal); + + if (Val !=3D 0) { + GpioWrite (Reg, ReadVal | GPIO_MUX_VAL (GpioPin)); + } else { + GpioWrite (Reg, ReadVal & ~GPIO_MUX_VAL (GpioPin)); + } +} + +UINTN +EFIAPI +GpioReadBit ( + IN UINT32 Pin + ) +{ + UINT64 Reg; + UINT32 Val; + UINT32 GpioPin; + UINT8 Index; + UINT32 MaxIndex; + + Reg =3D GetBaseAddr (Pin); + if (Reg =3D=3D 0) { + return 0; + } + + GpioPin =3D Pin % GPIO_DWAPB_PINS_PER_CONTROLLER; + + /* Check if a base address is GPI */ + MaxIndex =3D sizeof (GpiBaseAddr) / sizeof (GpiBaseAddr[0]); + for (Index =3D 0; Index < MaxIndex; Index++) { + if (Reg =3D=3D GpiBaseAddr[Index]) { + break; + } + } + if (Index =3D=3D MaxIndex) { + /* Only GPIO has GPIO_EXT_PORTA register, not for GPI */ + Reg +=3D GPIO_EXT_PORTA_ADDR; + } + + GpioRead (Reg, &Val); + + return Val & GPIO_MUX_VAL (GpioPin) ? 1 : 0; +} + +EFI_STATUS +GpioConfig ( + IN UINT32 Pin, + IN UINT32 InOut + ) +{ + INTN GpioPin; + UINT32 Val; + UINT64 Reg; + + /* + * Caculate GPIO Pin Number for Direction Register + * GPIO_SWPORTA_DDR for GPIO[31...0] + * GPIO_SWPORTB_DDR for GPIO[51...32] + */ + + Reg =3D GetBaseAddr (Pin); + if (Reg =3D=3D 0) { + return EFI_UNSUPPORTED; + } + + Reg +=3D GPIO_SWPORTA_DDR_ADDR; + GpioPin =3D Pin % GPIO_DWAPB_PINS_PER_CONTROLLER; + GpioRead (Reg, &Val); + + if (InOut =3D=3D GPIO_OUT) { + Val |=3D GPIO_MUX_VAL (GpioPin); + } else { + Val &=3D ~GPIO_MUX_VAL (GpioPin); + } + GpioWrite (Reg, Val); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +GpioModeConfig ( + UINT8 Pin, + UINTN Mode + ) +{ + UINT32 NumberOfControllers =3D sizeof (GpioBaseAddr) / sizeof (UINT64); + UINT32 NumersOfPins =3D NumberOfControllers * GPIO_DWAPB_PINS_PER_CONTRO= LLER; + UINT32 Delay =3D 10; + + if (Mode < GPIO_CONFIG_OUT_LOW + || Mode >=3D MAX_GPIO_CONFIG_MODE + || Pin > NumersOfPins - 1 + || Pin < 0) + { + return EFI_INVALID_PARAMETER; + } + + switch (Mode) { + case GPIO_CONFIG_OUT_LOW: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 0); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low\n", Pin)); + break; + + case GPIO_CONFIG_OUT_HI: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 1); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high\n", Pin)); + break; + + case GPIO_CONFIG_OUT_LOW_TO_HIGH: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 0); + MicroSecondDelay (1000 * Delay); + GpioWriteBit (Pin, 1); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low->high\n", Pi= n)); + break; + + case GPIO_CONFIG_OUT_HIGH_TO_LOW: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 1); + MicroSecondDelay (1000 * Delay); + GpioWriteBit (Pin, 0); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high->low\n", Pi= n)); + break; + + case GPIO_CONFIG_IN: + GpioConfig (Pin, GPIO_IN); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as input\n", Pin)); + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +/** + * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. + * + * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRES= S_CHANGE event. + * It convers pointer to new virtual address. + * + * @param Event Event whose notification function is being invoked= . + * @param Context Pointer to the notification function's context. + */ +VOID +EFIAPI +GpioVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN Count; + + EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr); + for (Count =3D 0; Count < sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0= ]); Count++) { + if (!GpioRuntimeEnableArray[Count]) { + continue; + } + EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr[Count]); + } +} + +/** + Setup a controller that to be used in runtime service. + + @Bus: Bus ID. + @return: 0 for success. + Otherwise, error code. + **/ +EFI_STATUS +EFIAPI +GpioSetupRuntime ( + IN UINT32 Pin + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + + if (GetBaseAddr (Pin) =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + if (mVirtualAddressChangeEvent =3D=3D NULL) { + /* + * Register for the virtual address change event + */ + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + GpioVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mVirtualAddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); + } + + Status =3D gDS->GetMemorySpaceDescriptor ( + GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK, + &Descriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gDS->SetMemorySpaceAttributes ( + GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK, + RUNTIME_ADDRESS_LENGTH, + Descriptor.Attributes | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + return Status; + } + + GpioRuntimeEnableArray[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER] =3D TRUE; + + return Status; +} --=20 2.17.1