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.102]) by mx.groups.io with SMTP id smtpd.web11.9773.1637167788275480888 for ; Wed, 17 Nov 2021 08:49:48 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=DlZACvzW; spf=pass (domain: os.amperecomputing.com, ip: 40.107.220.102, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TEe+zdYSUHz6GpSs6dFgoDKAEPDOdblVB1ifpSlrnhYXtRnZbIB+wf74tCNvCeEp3iKHN8yOZq/3VLx7MvztcNAE8yPx3eC3BCtPUIuK4jlyhInMYR2DeoXzrjWzbpKhcT/rLYiZkNtDBR4QVqhoU0WQSNlSt6WDIqSmuua66iNqihmQuBBRivpavIsy02kX6ZFNtGmJp2q6P0pScrUKFtAyzBUiHOqlOkypdZ4cGGuV3Yf4dGpoB4XC8cz7IzndRlqE3eTlhFOpl4yRBFfQ82ekPr3XqAZzKtknk3xlGgyC40VdnYAx22g1Oyp14guXXI5m4V3en9nL3MHLPZ1ALA== 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=IltRqOGFZ4gWtQJr+ai1zVyQSvMPRZVrtNnHpe6u3mUzMhN+2+ZFwK0672YOCW736Dw1oDHw3Pn/3t/EYdNxY77Xo0Nk9awYspwaG7zhi02t0jlVZqbbAZ0rjqWzSbpc/pSjJ5V++j+jPBtOk+XQlvybFtDlnVZHm9LRbFi/jVti9pkoDwjSw9E27cA/gFVYnMz9gW1vN8NI4hgTX7dR3JC4rszQCk3UuEIJ4LOki573RtyPBaqyvlGMeg3IZrsnmFbWORQ96VPeYLXFHHS9YzQL1k1l284VMylu68ImD8RCdu6WpD5JaE+CWFAy7jBqPN6A8Mg7Y5Y0mXpgD0Enxg== 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=DlZACvzWz1EcT1RIMKF6tmw1ZPVK0YF3P+f5o6IDaXWlIMvthbr9SyWyVvlbhdQdDgN3yRwBRkh7r1gEQIr3SYFdxeqF9tNI00K2tRTU8H5mgKepAM7cYTlN51wjUmW2XN4AFE76l+V84P7xuBFcQ9iOMmX73CLkjri76J4Gaz4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=os.amperecomputing.com; Received: from PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) by PH0PR01MB6454.prod.exchangelabs.com (2603:10b6:510:1b::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.20; Wed, 17 Nov 2021 16:49:47 +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.4713.019; Wed, 17 Nov 2021 16:49:47 +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 v5 04/30] AmpereAltraPkg: Add DwGpioLib library instance Date: Wed, 17 Nov 2021 23:47:01 +0700 Message-ID: <20211117164727.10922-5-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211117164727.10922-1-nhi@os.amperecomputing.com> References: <20211117164727.10922-1-nhi@os.amperecomputing.com> X-ClientProxiedBy: HKAPR04CA0001.apcprd04.prod.outlook.com (2603:1096:203:d0::11) 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 HKAPR04CA0001.apcprd04.prod.outlook.com (2603:1096:203:d0::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.21 via Frontend Transport; Wed, 17 Nov 2021 16:49:43 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a9710e59-4d4b-4708-bed1-08d9a9ea4350 X-MS-TrafficTypeDiagnostic: PH0PR01MB6454: 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: G43mCXZgZ1A9cKZhZvPHqOxYBg9TYy5kAErohfsB+/G0HPBbYA9+RkkfML4KY7VvnEK6HFHyWovMMGiEgQEksYsJ4xRBV3ZoheT9OmJ3ymq86p0nj7x/SMo+Dt46U6DRdsD9UEI2QMKdBBoShvTeKd/jKsB1Sr7ds+n11pmKVyfjWmYxoe7fJHLv8sqUR52doJVKu1Pl3vpyTGjGdotokn60Bley7eY+iw17LqW4c/zp8PT6lIOTbIWMJlKQKqC5DrIj+plT9YSw/YWM4tbPxrlKCUcjKR25DP0d28KfgtptAB0W0TVg4yGtxyd+GtTtyrYSIndn97XXioCB2aRdbCC8Yx9YdTsxT3+Z3PMddRVoCdijJIOxSPSoG766mkj6eqKH3uETicZwn4lS7g66CkHkDRJ1YPUpl/a9q/CBWaQ0V4kC0bN2YQErLhO3iqsEScg9NiBet2Lds/NIJ77nNLqV45ujhz2yGSvte4qA0gJklSGjeUyj7RCEvDYbgAmH6AyThkNql88xtvViv1KVzrNqzt/Yx2reuVQIWl61ZEU056M4dF4NADgHUKpA1XxoEed+4m2ypFjt0JmSAVV9gygjnxTT/2x1N4v5yQP8r/RXux09sCyiRjlKW8p19trDUQb/8GM2K8hbHjzi+Z0SUfL4QpiIL3A10nSu+bDpuHd32DMYlUVl2rwSn2EhJX5eMWpr3aM3cKfpzgZ9Mwvcnw== 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)(6666004)(8936002)(66476007)(52116002)(186003)(86362001)(2906002)(1076003)(83380400001)(54906003)(4326008)(66556008)(26005)(38100700002)(38350700002)(30864003)(6506007)(6916009)(6486002)(2616005)(956004)(5660300002)(6512007)(316002)(8676002)(66946007)(508600001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?mh8njxZ/K0autEMDG0SFONj4qHfT5xt89swhTiE3F0kp0TIbcmeB5YDehYJ8?= =?us-ascii?Q?JouFi00ZCAWB97ltR8B4jXpwpHwMBTr8iFhRA9EMIVHMNRh8WkA1d+VtuIzB?= =?us-ascii?Q?FlzD+FTONqel4Jbt7nFY+YmFBDQrpDh5RakkXHPanEPOQA9isMn617XlOCb1?= =?us-ascii?Q?w77rKJKz+HEkclQVXNpgS8c0UUE995GPycWuBtgPykLWL02T114/YiCq76lk?= =?us-ascii?Q?F3sbnc169eA2L8g5RtcZ9O/XWEklaVE4zJPTBluuJqqgPDbwu2GddnFq3xRp?= =?us-ascii?Q?hamnHT+2iWewOpz1R/ElQhEZzm9jQfjCt6i9mDqMkN0IxHsuZzzk3ZKZqrHD?= =?us-ascii?Q?n9u2tqJAT0jcRb3YTb3ds5HsXFlnbC2mmf/Yb/fbChyOufI30U9AqCA5xg86?= =?us-ascii?Q?KgheHOfBnWi1IpwL5ERbNb4syrQNpVC9p8nmGveDiQkfhzbjhztxwFJipTLv?= =?us-ascii?Q?f/9kjqJfBtv7Ur3zP6KK7CC+fdc8o/2iJxZ0i9UXxhHKPkIkQzNxZ6FnuUn7?= =?us-ascii?Q?WCCg6SieNZBXsSHXR8gLps5gWc1joPeDEt54DW1NkhZRd9Htw11/del1iNeG?= =?us-ascii?Q?M4s+ph2PouqfikcysiM3DsgV6VOA1R6CrOYIxJjgQrYh+e4JussAAq6AV3zI?= =?us-ascii?Q?MjyeTgaeM8G+GvloAD7zJ1EJyfwJx4ohK7GJ1AmM6DFva96Q64I6JOs8P572?= =?us-ascii?Q?ks5Tjuuaw6jMGQ5bOjBxq+tkymMIQmnXdjts7vehVYG1BMDxL/hMrp+4+Qzq?= =?us-ascii?Q?/mWo/o0A8lx4Syhnx7PRJ5G5wnVDret4rYfYvUa1hDNH3qOO45iL0NBChUYT?= =?us-ascii?Q?wmhO8a1W9Qj1sv32wlHdHbaVTXdXiPs2d19AvS7lHWBo6FvLDHegjaF33Qki?= =?us-ascii?Q?Ql/R+wsugq4kgU4/MckUDHNcx+xX4itE8Wm35icPE33oqJz8VTvtpm79mAx3?= =?us-ascii?Q?WBpH6C04nhXuvpwQ6E4W558BX4+uF1eHCXgxMNaX4ctOlmZp1PrEgg7lYUI3?= =?us-ascii?Q?F4yA0fR6n2t1sMNjB1bKZDJqaqCoQdz7OAhWPBPSg9UkfdTyCdhRheYWtNGS?= =?us-ascii?Q?VXllGabKhZ8aK6kHsrKR6P7HKBe/6f6khlqZ37KQ2aPTPDnfsOrO1LbwHfOO?= =?us-ascii?Q?YWXhOuIAjEJByKNoc/Pc8/wg8f4t1uer4D9sYc/VEEO7ngejcALVkIU2bIFA?= =?us-ascii?Q?3/Rp+Qc6iC61Yt0xY83xFQCCnjpozleyH8CmbIYFjaL37a/QVF2jjat3/2bX?= =?us-ascii?Q?eGYfd0WohZi0EctapA0iKtKzsO0RCgUWbM56Xhejg+x5QsP0pEid/KIWchRY?= =?us-ascii?Q?opxswusT0uqjSoC/eZUqOEO17QzqBhrz3IVFhtSkqaY8bkhmZHKXsAT16O+B?= =?us-ascii?Q?4MMXGlulBR/EqcksTR/VuSA18TvzoLeHmh1uiqH+iv7t9T8nhYOHVWSYpOlw?= =?us-ascii?Q?QTW8cwqc1K9S56d+mvG0KPlOEjB9qCjovuZFsaPwyKN3SnXkELoJeP6C+odd?= =?us-ascii?Q?AtcR9njSLDd75W/xOHW8+EvoXewvcANcHtv0Nd16b3yHsUzlA6u8IuG+ZV3Y?= =?us-ascii?Q?+Epj6mqPTyOpS6Z0IU5R2Zn+ipA0nnx+yipzMHqB4VDBWUtLvLoqUjp4URNk?= =?us-ascii?Q?pUWj0gKH/CeoWp6VoTikwTYcfledbIHmxWMw7JyIETKOr/KvzaDFeZT5sQYW?= =?us-ascii?Q?SA3zJw=3D=3D?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: a9710e59-4d4b-4708-bed1-08d9a9ea4350 X-MS-Exchange-CrossTenant-AuthSource: PH0PR01MB7287.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Nov 2021 16:49:46.9369 (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: coFP4JK+A8H8WoQVYW+cHt0Vb3wHb47NyNRPRPXreFkhLKj0Ewp0/xTxfD1HNggnriRRAnaDxBeUFwmjU+yxz7c5k5w2yfD16EcdX6WqVcw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR01MB6454 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