From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM04-MW2-obe.outbound.protection.outlook.com (NAM04-MW2-obe.outbound.protection.outlook.com [40.107.101.90]) by mx.groups.io with SMTP id smtpd.web12.10036.1631721574597518376 for ; Wed, 15 Sep 2021 08:59:34 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=lfgC2zYx; spf=pass (domain: os.amperecomputing.com, ip: 40.107.101.90, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OhRxfdNzLdzGp66GK/Twkde2nCL4Zov6KTnNbeOYpO8V2W7akAVesFMuG9nruczsYVCPqIgi+yotSKYKglitJZ/Ozd2ZuN5wuyw9XuSxmKJSUw01cb6dgdhk7F7d8JE+v6waMPWk0sVOgMRuxwi2qjiHNGVLiSliLSJtInk4JnnT7vMDVrd7qil5YhTYh/OIkE9y+PCfaOWDhooup8Tg8HJiTuBe2hF6tzrzliTRkNpfMLQi6bZ+Z8pIOyADM6j2PdA68NEuFcRFTQaiuWmCcaPW4rL13tuYL6UDvz2fff8ZfrhhQQC+ZTiS49ZGxYKRleiYm2YPn0CRxvdjD7rUhg== 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; bh=jbQ9ue+GrnNMy72qv4vYV9xohmQOGMRu/4sjNmzUDSQ=; b=bsLnxWsB6FinqdEgA/GI/qGLPTS9NA5q7RtVnc0ROVbgSGo8SZIb2yetcD7unFD1nIRgzaSdKm3UsmXz2ghoZUHGHyT2nfP7+q8kNxueLyOIO+2Qwo8+6SIXQK6Vma72iqJER5GTb5qq//rqM22eNO+Lp1nf5i3RA9WdBKNnuj7sUl2bgjDcgf473bYASgF4zVeqLraRT9s+a9cCuascNon+r+Gp//eU6sxaWSyUwa7WC0zdqOe+Oj69mStKHdRyH8V6gPkT2ujIN5+vFDjlwOMvOydVeVDYbzVwP+LGpIUbtzb5wd27H+KBUOr5r6mWsb3KBUXxbSzGvt3Hz79O0A== 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=jbQ9ue+GrnNMy72qv4vYV9xohmQOGMRu/4sjNmzUDSQ=; b=lfgC2zYx+ctMyvqwr0c7psX9TNVA+W4ZsLhBX4mhfuELck+088l86bgzxQ99SCnQ+srJg8fZ52ymoHKegdmYeTT59AI9JZOHRgrH2aGRA2jY1Z6SAQImLYfXG71V7/m+JofaZ9GZTYB07z0OoxXvz6SDmOze7iEekGIyCSxDw0Y= 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 DM6PR01MB5513.prod.exchangelabs.com (2603:10b6:5:151::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.17; Wed, 15 Sep 2021 15:59:33 +0000 Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::8eb:704f:2ba7:9bc3]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::8eb:704f:2ba7:9bc3%4]) with mapi id 15.20.4523.014; Wed, 15 Sep 2021 15:59:33 +0000 From: "Nhi Pham" To: devel@edk2.groups.io CC: patches@amperecomputing.com, nhi@os.amperecomputing.com, vunguyen@os.amperecomputing.com, Thang Nguyen , Chuong Tran , Phong Vo , Leif Lindholm , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: [PATCH v3 06/28] AmpereAltraPkg: Add DwGpioLib library Date: Wed, 15 Sep 2021 22:55:05 +0700 Message-ID: <20210915155527.8176-7-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210915155527.8176-1-nhi@os.amperecomputing.com> References: <20210915155527.8176-1-nhi@os.amperecomputing.com> X-ClientProxiedBy: HK2PR0302CA0012.apcprd03.prod.outlook.com (2603:1096:202::22) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 Received: from sw004.amperecomputing.com (118.69.219.201) by HK2PR0302CA0012.apcprd03.prod.outlook.com (2603:1096:202::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.5 via Frontend Transport; Wed, 15 Sep 2021 15:59:29 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 25eb6396-8497-46f8-477e-08d97861cee8 X-MS-TrafficTypeDiagnostic: DM6PR01MB5513: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: zXOm4o82C/4yTMT1Ivqh48qNRl/A26dTtkyOUIvEpiCVJGijwkh5hiGa2ZsKZQzmtQtjk/PLuQ8F2eoGEr6hStrMxHw1w+f32ZgG3kJlR1ltBlHsAiR+anrw+aX38CXMspfJWJnsfS8EqbUwJIAsbwJtzBaUS/TTba95xQisvIaEa/+E1+gZa4pd81xKoTXn9XxMUOXTUF2mYMLzV3Qhx+UC4USvX9EzWeIfn/hX7we6muP1W5lYIIvoae4zl5BUlCwohYszAQtIyDWcyDWZ4wKe8rh1Pnsle7HTTIzDo3Ro+91JUrkIUURwSPzi2EYRrbYXywoKajX5E/UCTb8MBG5GatXqcMOnTB88EeEAsA0eFiFI2dyL3x98fd77NiERbYmwOpQZY6Tud8SlgxQB2cpq+2znldQN+4d0qPNawccfjm9gIE6MiSKkurp7xR3NN8Dg38r7+vBvrBARTzExi4d6Sv1GXOXTkHd7Ydddss5LMqljz7oTIHHu0o5FXdSOxVETcOs2vlMmAaMAjOafXAZHMYZWW9ajalL0Ixc7iXeZDRRVAmqXqzArQF9PFwKLH192hKIF5v5JDwzTrwojMvwhAVi8KhVY77l+IZsbiV5GatnhdRcBdnaey8MPKZ7Qvg8afRrmaVQhW3plsb+/Q2LC9ZXlovxd2h8G0Z8FlmCk8hwGHZSNvwqsjJLiF2CzDQva3YGszWClE3KYcFVOuw== 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)(376002)(136003)(366004)(396003)(39850400004)(346002)(316002)(30864003)(1076003)(5660300002)(83380400001)(54906003)(6506007)(6666004)(4326008)(8676002)(186003)(956004)(6512007)(86362001)(38100700002)(6486002)(38350700002)(478600001)(66946007)(66476007)(66556008)(2616005)(26005)(6916009)(8936002)(52116002)(2906002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?O6pMQvv2Wqv+AGO1QVTjvtyIi3x8gVm8gQPrAcswfRC2daXQmZHrRyv14u65?= =?us-ascii?Q?A7Nm0/75+qCSBVWud294hx+IcTEia/Fdycj6eNgrRw4r3lCXslFX7GdFvjsI?= =?us-ascii?Q?GpzM11IPkVSCc1CZsulzeIyt8H+SOVT758OEfoL7h/M61LOaMHZVIgfK4bG6?= =?us-ascii?Q?lzrOTMhy2wE/g5FEZ70Zut4cx3udvaG2HrAyXkKrzL2fUmABISlctwq6NMaH?= =?us-ascii?Q?rEqy87K8Ivd/0JaW50zBYnuaBrHqXScWMMid4agebBI/5HhWE1IefOHfEeow?= =?us-ascii?Q?6Ni5oIZt3skXrgj4nh+/a7TdGhfdmvgxZa/+PsQhZyYHDrdLU2qx9mcrKjQi?= =?us-ascii?Q?rCuw8J4cko1B3Ugy5E/hrHQOETCYr9FQPEWjoe+TzQnwkk/qTEHRKRyJ4sZ8?= =?us-ascii?Q?HiL04Pzzis1pnFeIwzBN4VPm+ac9SzNj3Q1UdJTQPLKUiVeW1GS8FnxqNBNK?= =?us-ascii?Q?wT4Aq6wrXjzIFemwrdIBvFbahtw8nN6EgUpcz1on8YQL+7pKmEzW3zjDq6Fm?= =?us-ascii?Q?MMCzywk2I8RKje+TRBpDZBJIdCjuOWmGo+mMSPD/pR/D8/Bvvy3U2Dvrr/q1?= =?us-ascii?Q?EJF5efRes2qZakYkCwUn8Hw7UBYbaBxwjDXx0jE3X/eEWKifBJBY8wRqIV+q?= =?us-ascii?Q?SrcGl6TA/UXhj0wI0aD9IJq1axAkyZ4UZEYja2rCou3bJvz1wDptyu2rgpcY?= =?us-ascii?Q?L152JzQDteTYfNU4SOjFKumGUWsJTzxmCZwijTBwr1JH6dupdgNsWzG6dHcj?= =?us-ascii?Q?4hINu06NyClqwruQGa5eNErQonyt9lQGOIKsFspHOEYma8J42gCtIIEODO2v?= =?us-ascii?Q?vo1xxKUiNxzjGNdTjj8uPf1gDIsRrJs42/jdZSfcFAhU83Nrp7SHv3uK96uk?= =?us-ascii?Q?kvF89OvN/mHhvUriWjjEIUVTxplaVslcACjLiyVskzkvW8dvZrHZvwQn5D2J?= =?us-ascii?Q?PuD9AgjfLXw1A7Guz/kk1F0goWYDLL9d70BA9LoWMlG7mmDpxi+eskONKiye?= =?us-ascii?Q?O8bz+e03/LNuuJKdgrzg+Rjv4y2spmpADi2WWljMOeRZ2tPjGbG2haGwhQX2?= =?us-ascii?Q?780d7hknD4upWRRmIiczQyWytJVMtRVSCY/nT6DWx44FISPmowRHgDlk62pA?= =?us-ascii?Q?w5Lka4hxWA+zd0hrSDOZNzIR3ouVn+gZYywKvTyZc+jajdxCT/2xlhWq4iwi?= =?us-ascii?Q?lKD7B0UJDefjohNrSFeBdj6SJH+47KvVEs+xSIIBs+n/DREe298+G3g8S8PE?= =?us-ascii?Q?3GomY59qWihjQ/dChTnCpVJbeQ/X7CX9W3hDRQAtYX6RBFN41s4sZymAQhdE?= =?us-ascii?Q?d4BtdwcMPKTKmVpADQ/Dnjfb?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 25eb6396-8497-46f8-477e-08d97861cee8 X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Sep 2021 15:59:33.2393 (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: cZ2umoG+5PvoWcHycF+r/CsSo+q1WjhMGQZXSydAliyqLVOSCO4P7ebIISd4DR46xUETonHyPlTDHtBMk5q3dmjH0bQrYbDuOs8aeL5gc0E= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB5513 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 Reviewed-by: Leif Lindholm --- 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 100644 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