From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.98]) by mx.groups.io with SMTP id smtpd.web10.4665.1634883584568091536 for ; Thu, 21 Oct 2021 23:19:44 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=Pqa25QLo; spf=pass (domain: os.amperecomputing.com, ip: 40.107.237.98, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=od7C9A8KMIXCfN9TgU0DPXPry15XWXt8eaosGUguR+O3lwIOxdKhVAILQZzmbv0pABYrODQ8F6LFXYKaSNHI1lWLQUqHMOADKz48iycDFFQefvuqVjplD8/vY+yYiqCMk9zIb5XbFLbu+d5CR3owXK4Tm0ZjubpVjZ5jMnqHhixUz9/TaBIRSV6NTpsceSkBefmTS/a3fYELbPgHsodTfgL1OZLHYicM6Ep3HWNlNA5PJOQUWP5QmXW9nLe8oeGewy8HhFI/Cw1VBIJ5+BPsZqzVTSKm6THWGWbtUX8sgqPgzVdot3r4IjbztZMmexSjykx3GOp0vnZSFjmWDYhgyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jatn/isIPIq+LO1k5eogzMNrEVN4mh5ZrmewEPJ8Ok8=; b=mZHPsGAiISaUK+DNpE0ZOq2yH72h4cw+1xXuKqHfPyedB3ds0TcntX/i4AYW8hoMDIlMY60VpXXpm6EZZKMn1pAxkjnkXCuK9/YsK9L67lS9zuOHSLN2+nvBhWF91OH1JreKrNMSD+ySuaQdaawkiSAKacumSKmQKhpVrii3+yK2PmokhHZMQ/CXVV5p67Djs62Kdq5OR7gluUURLEdsyUv9Lx13A2ggqrI24lCTyqJvvRswAIo9CzZSCDd2k7Rx7hyuUNGrGRKeryyWTJsYge+CKP5wEJBhiGnQObNXO7k2Yj4kxQJUlTh3plfLDTm+6JIqACOHWbSnDvq5IuBkMg== 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=jatn/isIPIq+LO1k5eogzMNrEVN4mh5ZrmewEPJ8Ok8=; b=Pqa25QLoa6VNdn+LVkn4Qz5owyXtBFBuYTych1f+0BPraECcVzb8JvtS3QZumt7BS2gD0iGnYyJ+r9Fpez+X8SvVoC1P46aUMzuD0WAEXc3f7HRZXfA2eBOa838RxgG2XwaRXiTCx4rDckmlERlcw8x+E2ILuTvG6OpIY16fNgc= 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 PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) by PH0PR01MB6103.prod.exchangelabs.com (2603:10b6:510:13::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.16; Fri, 22 Oct 2021 06:19:42 +0000 Received: from PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee]) by PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee%4]) with mapi id 15.20.4628.016; Fri, 22 Oct 2021 06:19:42 +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: [edk2-platforms][PATCH v4 05/31] AmpereAltraPkg: Add DwGpioLib library instance Date: Fri, 22 Oct 2021 13:17:43 +0700 Message-ID: <20211022061809.31087-6-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211022061809.31087-1-nhi@os.amperecomputing.com> References: <20211022061809.31087-1-nhi@os.amperecomputing.com> X-ClientProxiedBy: HK2PR02CA0168.apcprd02.prod.outlook.com (2603:1096:201:1f::28) To PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 Received: from sw004.amperecomputing.com (118.69.219.201) by HK2PR02CA0168.apcprd02.prod.outlook.com (2603:1096:201:1f::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4628.16 via Frontend Transport; Fri, 22 Oct 2021 06:19:39 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e0a81d63-0959-4597-72bd-08d99523ef25 X-MS-TrafficTypeDiagnostic: PH0PR01MB6103: 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: NhY3vIeng8RKqOIEOk3/qMysFsOBV2CrAZktMclQUd2HgPCMllaRsUF7rOGNdIEeG0jFg06BQCTmc7UszXRau9xvNX05I286zC4wd4odID35tf3LZojlgPVP4mMIzMNSoieymYfZzz2AHjftfcH44H+T7saI2JxP1Sws322XC/Lr5x3jCSk2MjmsZvA//fchnCuEJzjq4xZF9WhJPFRdqzIBtdmRhrQZWmZPkSZrB0hJsr9yjUqjoE1NhO5RobsiEWThlsrdcJgiFp7IzjzGIz75RNC4IzTPVUNvLcb1OO0vknaThWfwaJQClgop+4jqLr0H6vvJgrbjvfstbSyNV7vNPDBCnCkfgM/tfm1eRgnHJb3zKYmA5D8aSBlvGiynujDeSY7CF2eorZqRXyfpBnRlUmz0bz5YxpZKngVwyqK3ZPAsVHPt+g70jhv/IEuU1/np1PpiBx+8qJwBnG0qhFimr94rovPBD1VpWCqZLYxjGwpLC4fwDRgabQM5PmtN9RvVcP0N9F0HLMhfgLsv36fL/1EuQ5aoY46oUBeG2tO71Ve3mokB/p+cYrYC/YuqebGNcQcbnpIR1BbpbTBaf5t9qbBA2rx4XzFkkfb0RgCWHd+NdYFKkRpuwjtpl1g2h47uNTIWYiwSAvM4eTXT5U4udrHIyw6CL9YkfW90hneI2gEnv2Qe/RNUTtg7ureBPiDLOUp+hOceW6GFEcQCDg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH0PR01MB7287.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(6029001)(4636009)(366004)(5660300002)(2906002)(86362001)(38100700002)(508600001)(66946007)(6916009)(316002)(186003)(66476007)(4326008)(1076003)(8936002)(956004)(2616005)(8676002)(83380400001)(6512007)(6486002)(26005)(52116002)(66556008)(30864003)(38350700002)(54906003)(6666004)(6506007);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ffHLxHqDUbXOSJaiFK9UrAn+RhV+H/iGqREj18VjxTjVaoST3819oq4a9zYv?= =?us-ascii?Q?we2/hAnnXo1PkD4NWXFPcZB6VcVbDlsrh0OVwksNAGSxFSfwkkDKQIaDYP4I?= =?us-ascii?Q?0OhfVKFRxxos+O+WybTmq1S+rzLh+cGNS1/R43ayfI5lYXjqAafamUVe4UqZ?= =?us-ascii?Q?0DquqkiG+tttVcOgTXpkCxGxtNIJlfX/UYNSZ1PcGbZlCWNAwDpGdrb/Ka2a?= =?us-ascii?Q?UapowsMNJhtOHUiK3zdu0RQvAXBA4bnds7CD/VlRh0TgNtEH8bpTWpzg10MP?= =?us-ascii?Q?DyeFb3SawORPAgQRbNc6rn1IKFiLMHVVPFe7/BIrzEbKXB0d7OZG6Sbw1aTB?= =?us-ascii?Q?W8Nct+/MYcSbZABnkGNIgRmlmxpXMI0dWkrH98TNTB8ektqXPaM05m4b3aPI?= =?us-ascii?Q?MWchD1qXfSvladSTxa1olS7Mu3DEbg5cVYOmL4iYRcEPF0f1+oSuMSQpdR1I?= =?us-ascii?Q?Zm3gF/jKV0Ja0/QggV+oOBvSgT367c6tXkPJpKccQSW7MW7nPWJl4Dvd75tW?= =?us-ascii?Q?kD5UBVFSrdGPrcF4jxRUaAccCiQNjVv8Zs8EP+yJlhdTWnYOVjc2Aag9uVrn?= =?us-ascii?Q?v9+Yts9IGRN2oeY3NlVxhFm3seU9TJ0gZLiUmLh1QNc9fgxJc9uvFkIiN0zW?= =?us-ascii?Q?SYDgFe+dnv09Hgx4/7xjXzx0Hr09KhJwtsbLg6BcL2WdkoybyCmlEKLse7UW?= =?us-ascii?Q?eScJuLqcVyCSEKcP5Vw1V7K7AB43oKwbqypGXWNuKIRvQCQjq882UaXM3R7p?= =?us-ascii?Q?/Tw53nwnPp/JqAoUYEaFF5wudXWPt7/izyKp1r+NH/wrypnrpnFEr8Ar1zKU?= =?us-ascii?Q?QrcY4Boh6+VeAdyE4rFrUhpu0PjevTcNo3mNUJI7bR8CDo0R9h18yfLViF8C?= =?us-ascii?Q?GItMNLdomj27seAqO54J7FcEYnWjEbsfzQB+0ZGYdsHZl3QKEgc/OW5gVJSG?= =?us-ascii?Q?SpyUTidNIfqXUNVtMn3WOLdwC8JJgfwFsI8MQ6vdrf59poe2mEHUg2LRi/yG?= =?us-ascii?Q?vslp6QheAscZYnCymz7ByfFhe54BhC/07KOc1ymCSoPpSonjxf1gZ9aTGOi7?= =?us-ascii?Q?adQI2iaHwLeWxpTpt3LTIlnKAzGWgQODXvGa/lWedjFt8nm7alhiamUR/FvW?= =?us-ascii?Q?JZi9lDXLKLrxxxr5ihJKz7Ghs9c1XUsY6dQ3GocXxOF6apTYGE40dhBhht/N?= =?us-ascii?Q?mg3fNVkwpVOJ4VpykbIiYR+jaTGxXIV0x4f6CxcbNuTf7t9N5ru1et2gGq2n?= =?us-ascii?Q?5oTLeWgBHKENrqCJcWZDA3XME9cRTlHLkREWpSt1wJncYfQcYk54lT7U+vbS?= =?us-ascii?Q?b5fSOUf0z99TXWGTURTRy50C?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: e0a81d63-0959-4597-72bd-08d99523ef25 X-MS-Exchange-CrossTenant-AuthSource: PH0PR01MB7287.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Oct 2021 06:19:42.0737 (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: nhi@amperemail.onmicrosoft.com X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR01MB6103 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: Nhi Pham 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/Include/Platform/Ac01.h | 20 ++ Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c | 314 ++++++= ++++++++++++++ 5 files changed, 446 insertions(+) diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Amp= ere/AmpereAltraPkg/AmpereAltraPkg.dec index 57ee7aafe545..c1226c296dad 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..3c72ce3d48d7 --- /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_ + +typedef enum { + GpioConfigOutLow =3D 0, + GpioConfigOutHigh, + GpioConfigOutLowToHigh, + GpioConfigOutHightToLow, + GpioConfigIn, + MaxGpioConfigMode +} 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, + GPIO_CONFIG_MODE 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/Include/Platform/Ac01.h b/Silico= n/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h index 453d966d6058..1ba1da17117e 100644 --- a/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h @@ -69,4 +69,24 @@ // #define AC01_I2C_BASE_ADDRESS_LIST 0x1000026B0000ULL, 0x10000275000= 0ULL =20 +// +// The Array of Soc Gpio Base Address +// +#define AC01_GPIO_BASE_ADDRESS_LIST 0x1000026f0000, 0x1000026e0000, = 0x1000027b0000, 0x1000026d0000, 0x5000026f0000, 0x5000026e0000, 0x5000027b0= 000, 0x5000026d0000 + +// +// The Array of Soc Gpi Base Address +// +#define AC01_GPI_BASE_ADDRESS_LIST 0x1000026d0000, 0x5000026d0000 + +// +// Number of Pins Per Each Contoller +// +#define AC01_GPIO_PINS_PER_CONTROLLER 8 + +// +// Number of Pins Each Socket +// +#define AC01_GPIO_PINS_PER_SOCKET 32 + #endif /* PLATFORM_AC01_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..319ce43ba71d --- /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 { AC01_GPIO_BASE_ADDRESS_LIST }; +STATIC UINT64 GpiBaseAddr[] =3D { AC01_GPI_BASE_ADDRESS_LIST }; +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 AC01_GPIO_PINS_PER_CONTROLLER * NumberOfControllers= ; + + if (NumberOfControllers =3D=3D 0 || Pin >=3D TotalPins) { + return 0; + } + + return GpioBaseAddr[Pin / AC01_GPIO_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 % AC01_GPIO_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 % AC01_GPIO_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 % AC01_GPIO_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, + GPIO_CONFIG_MODE Mode + ) +{ + UINT32 NumberOfControllers =3D sizeof (GpioBaseAddr) / sizeof (UINT64); + UINT32 NumersOfPins =3D NumberOfControllers * AC01_GPIO_PINS_PER_CONTROL= LER; + UINT32 Delay =3D 10; + + if (Mode < GpioConfigOutLow + || Mode >=3D MaxGpioConfigMode + || Pin > NumersOfPins - 1 + || Pin < 0) + { + return EFI_INVALID_PARAMETER; + } + + switch (Mode) { + case GpioConfigOutLow: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 0); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low\n", Pin)); + break; + + case GpioConfigOutHigh: + GpioConfig (Pin, GPIO_OUT); + GpioWriteBit (Pin, 1); + DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high\n", Pin)); + break; + + case GpioConfigOutLowToHigh: + 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 GpioConfigOutHightToLow: + 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 GpioConfigIn: + 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 / AC01_GPIO_PINS_PER_CONTROLLER] =3D TRUE; + + return Status; +} --=20 2.17.1