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.129]) by mx.groups.io with SMTP id smtpd.web12.4643.1634883587967257231 for ; Thu, 21 Oct 2021 23:19:48 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=AOmzrBz7; spf=pass (domain: os.amperecomputing.com, ip: 40.107.237.129, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hFTK6RM5AkyIZxsWQhdDfxfL4YnzwE++i9I4BGsdVLBL1dMeN+TCSz6iMuRFHN6M1DObgg2OWRMXFV/iBapZbUjt7tENpH6BD1lTXeYoZX0JZx+r0uELI2Mwp+MUCC4uY5Ny9xNB5+nVg4qfAdf7vPK4TEqfR75qa3UDG7jL/X4uycW1ucNdirIMGIU2arBA97lfXBcoAtTifqju9z2MthxSNsTutU0nPtG26QADZ55Px5Q6Nu6m6rdGOGsIXeDtx9R24shL5zdtDsXuZd69AJgh1ozmgd6wG4e+SogKET3vkeehPIJtUbT1nnUhHMl1ehQ2v4UEvgWzkN5w6Q9tEQ== 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=kHpiHfAWiyNVWEzxR0YKOUfL1JEYkr6uXwZE8azdi/k=; b=JJLsMNgFbEMuhwK+kPzt1zkE2mZkBzfAIrobR1Jd8r68qHpfkNwTEPubqskePRcR+p+7Qxw6Hinz2zG1jK2lFO2u0kdNuIhs1F507G08CEPyROX7Aj34myQvHGGOdkatDrWdr8HOOMLtR3I+A6jeGmaH8eguqscCSfNRH7myoVErUW0fjCiqrY+CSufeQF4IZXsO1vu32T5ej0VYgRN5wFBU7GTRL2getdy8GPUt5CPviRUFS38uK5VQAz/GPIYaFYl/KzE/Oh35DJv+pfKXqNXPTNYhQtmMPFVGs1WV+toJWg4/KSThieZoF2tioUDfg3yfTEVcV9+zrQf/7yJESQ== 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=kHpiHfAWiyNVWEzxR0YKOUfL1JEYkr6uXwZE8azdi/k=; b=AOmzrBz7aLsIpQqhVv9LxmbZZ8c81EO6ICLs1USpnm+oea5htUFutmCw1BYniDL72ZutIBCS9VKLOiNG5vIJqHSgXdZ6DP7g3iGyWF4WqrSdy5zdJmwvI7EqzYGM+PfvQnLSloInp0dMkInffOT/QZy1kcvbm9cOhWBpL88FtiE= 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:45 +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:45 +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 06/31] JadePkg: Implement RealTimeClockLib for PCF85063 Date: Fri, 22 Oct 2021 13:17:44 +0700 Message-ID: <20211022061809.31087-7-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:42 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a4fde9ad-f893-4137-e427-08d99523f0f3 X-MS-TrafficTypeDiagnostic: PH0PR01MB6103: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:901; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TL27MzrTfmsqCiOYBXQQK4rvbjAeg0jCrpmvtHeLFVNn0uwe16HioJhBldQ//rBMhhlF9EY2Fo6cAPUyt3L1S3LxT03f1NecnN0AI+NfCdfCnUryap2roFDAVMrm3SmZxDEPU7omyvo2K3oTx7slo7wCl/xopmVNsEcGsJICazg5+/sw8hjLOFajeAxQZn32E4otvEW/E04p5LvzZBA4XQRbp/5TMoFfrTedpalMU3/9Rx5CfBAA3XkrxJ4g6l1EBWVR9Vr7ToBFMFx9UpKxVQDi9vlSK69DKHfI5ZtbRudlW8XR4SD2KsH/kbJ3W5fC9gxmlu4f3a7vGQ+GoD0xLpf67HNnshvR7qZvcYlKrJlb4ezqnNfXmsu+JDpP+eAwWna6qGDCPDlXpW3zq4ZToWBCnm8VxRZ1JsRjy+y0QgC5Imt507gURv1R7TFwWnkN5ntYNyg9PM7P7fOzbVrhS/lt/YTlNUydMzvCq1INQMOkcSbm+10bFVBerd5ciE7vw9mWOxsGGwqrc8TAGW8G9bXsyphCnSIpINk12ZfhekxdOOcud0IpdtMRlZddx0UqO0QQLaZvAWnMdJyweMiq563z7VMAVbz9H8454hKGflwBMdRsfYkbq54M4cEVPOALKMHrmd0EbjO1hjATjlCtvy7VjimlyT3LIQQm5qmOwvNqtelMXc4NHIs79zMeJvsqCyr/LWIRK5brz/YoIsbyqQ== 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:(4636009)(366004)(5660300002)(2906002)(86362001)(38100700002)(19627235002)(508600001)(66946007)(6916009)(316002)(186003)(66476007)(4326008)(1076003)(8936002)(956004)(2616005)(8676002)(83380400001)(6512007)(6486002)(26005)(52116002)(66556008)(30864003)(38350700002)(54906003)(6506007);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?0QvGOUqFBVO7FXdU1ZgbOgPWQO4oBohXzipliGDuWC+cEoh0ClpNOM7jwwK6?= =?us-ascii?Q?4vkUV8UeoosXV7BOBNCyb5lj/111G2w+D/w64waYiNSvJLBeAf5Oqw8P465r?= =?us-ascii?Q?KrjTSnL44HTYv1X1uIvuCQyG2b0Fqplgybphk/Z1TC+KYn1N2JE1lzxtWNA7?= =?us-ascii?Q?yhh+ZEYEplwllH/Oq0JH31hNwfNk5ZyNypK0/i73rrgF8m8kJLw/fXGduekb?= =?us-ascii?Q?uWVqeNAOJ/LlaxTiERgbGgyNEaxpytSnzF6hCZqL0dOHMIg8PhJPGZX5CZ6n?= =?us-ascii?Q?YOclL6Rcxnc6HenuiZaHK5zAHFKLhK+wdIeNZPr2hg8RQpg0gTl0BKKj3MP8?= =?us-ascii?Q?WwE4oJ9w+9tkLvZktpPayHMJkkrnUUElHKnXjftcvsxXflePMf1qciX4GpAJ?= =?us-ascii?Q?WS1Hcr6DQ5DJBACiDCkHWKwrGwikFkkEva2UlaxyxgZbbrHmN+tV6zsAX+3+?= =?us-ascii?Q?56ZyskixCK3pDL7HsZtfIGaWDATLzsNTNy3BCVQF79VvDh2P2QTSqS8Hf/zq?= =?us-ascii?Q?1Vx3GNEYfQm3zUfUyvGYfr+CiOb4KrYKMZrRdWupsW7q27gR8aGaB+bM64NK?= =?us-ascii?Q?QI/fUXigyY8kWTD5wwU4wobLsO/CkuWHUi7DtOd/yS1N59RRjTWGOwj/Q49T?= =?us-ascii?Q?vdE5WgavmB2uv750kMXlvd+OL611Ywk1KPMYKGF8lIoVEPXc8ciizBkQc9Ik?= =?us-ascii?Q?kwKutqYSKr9+Qxd5Ut2GDpnlpZQ8gWw9ngaXTljTqZyANB+Wjeudliu5Ha6x?= =?us-ascii?Q?q0UDZ/7toNlkaj9pNgmwgbe78npKzBv7LEysfoHBMEn67+RdOb3EysdBdZmq?= =?us-ascii?Q?jB8BAj/FioCvA6BtYfujYeDGgo0wgDbvDZtKqD+HY2SQKBDAPxCdQkFQyPqL?= =?us-ascii?Q?JgsZRUVRkvehAH1WYHZpYJ0HX7hentTymss85Rc5QZWOJu+FxV6pcihbJMYh?= =?us-ascii?Q?j8e7P7Ew5iq/WeHZdyZKhZSrpVsFg2c1YuTznQji2eGMHMD0z6WPg5UDwwyE?= =?us-ascii?Q?XGiSxVJfWBj1bGdR2Qm8jtwDzCdrXDglpIAg8MlQyFhN3orK0d3zwMWHbP8X?= =?us-ascii?Q?E6r+MeMqWQLNAVTP+cBAs9QX7U6NpMz+uv2AGL4+X7gKEzu68YTOJwxQ5jpM?= =?us-ascii?Q?m66y+Usv9ZvN7JTbD6yOt67JE9mwEYbVxhSLBrZI9PFlVoYShAqaVTdqzj85?= =?us-ascii?Q?DJA3Omf86y+XmXN+8OzawX7BhSa6zh4OPtZuQSQmcVGk0GGVQmlNgBN2/ASt?= =?us-ascii?Q?vdV52Vi/DqZfVtZG07kTPx3+H+hUIZ1F2CosCU+gV39BwY/TJWZn6wFpjlre?= =?us-ascii?Q?HbBfsxCZlhbSmkPEd2KyaHIR?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: a4fde9ad-f893-4137-e427-08d99523f0f3 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:45.2458 (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 This library adds the support for retrieving and updating system datetime over real RTC PCF85063 device on Mt. Jade platform instead of using virtual RTC. 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.dsc.inc = | 2 + Platform/Ampere/JadePkg/Jade.dsc = | 2 +- Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeC= lockLib.inf | 44 +++ Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h = | 91 ++++++ Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c = | 317 ++++++++++++++++++++ Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeC= lockLib.c | 257 ++++++++++++++++ 6 files changed, 712 insertions(+), 1 deletion(-) diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon= /Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc index bfe66f332c56..f679b818a205 100644 --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc @@ -83,6 +83,8 @@ [LibraryClasses.common] SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemF= irmwareInterfaceLib/SystemFirmwareInterfaceLib.inf AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCp= uLib.inf TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf + I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf + GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunication= Lib/MmCommunicationLib.inf FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf =20 diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jad= e.dsc index a10591933cf7..7b70c5d6b5fb 100644 --- a/Platform/Ampere/JadePkg/Jade.dsc +++ b/Platform/Ampere/JadePkg/Jade.dsc @@ -74,7 +74,7 @@ [LibraryClasses] # # RTC Library: Common RTC # - RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualReal= TimeClockLib.inf + RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLi= b/PCF85063RealTimeClockLib.inf =20 ##########################################################################= ###### # diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85= 063RealTimeClockLib.inf b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeC= lockLib/PCF85063RealTimeClockLib.inf new file mode 100644 index 000000000000..1fe561cc0ec9 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063Real= TimeClockLib.inf @@ -0,0 +1,44 @@ +## @file +# +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + MODULE_TYPE =3D BASE + BASE_NAME =3D PCF85063RealTimeClockLib + FILE_GUID =3D 271569F6-5522-4006-9FF5-F07A59473AA= C + LIBRARY_CLASS =3D RealTimeClockLib + VERSION_STRING =3D 1.0 + +[Sources.common] + PCF85063.c + PCF85063.h + PCF85063RealTimeClockLib.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + +[LibraryClasses] + ArmGenericTimerCounterLib + ArmLib + BaseLib + DebugLib + GpioLib + DxeServicesTableLib + I2cLib + TimeBaseLib + TimerLib + UefiLib + UefiRuntimeLib + +[Guids] + gEfiEventVirtualAddressChangeGuid diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85= 063.h b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h new file mode 100644 index 000000000000..03ce4d29a03f --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h @@ -0,0 +1,91 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCF85063_H_ +#define PCF85063_H_ + +#include + +#include +#include + +// +// I2C bus address that RTC connected to +// +#define I2C_RTC_BUS_ADDRESS 1 + +// +// I2C RTC bus speed +// +#define I2C_RTC_BUS_SPEED 100000 + +// +// I2C chip address that RTC connected to +// +#define I2C_RTC_CHIP_ADDRESS 0x51 + +// +// The GPI PIN that tell if RTC can be access +// +#define I2C_RTC_ACCESS_GPIO_PIN 28 + +/** + * Returns the current time and date information of the hardware platform. + * + * @param Time A pointer to storage to receive a snapsho= t of the current time. + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER Time is NULL. + * @retval EFI_DEVICE_ERROR The time could not be retrieved due to ha= rdware error. + */ +EFI_STATUS +EFIAPI +PlatformGetTime ( + OUT EFI_TIME *Time + ); + +/** + * Set the time and date information to the hardware platform. + * + * @param Time A pointer to storage to set the current t= ime to hardware platform. + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER Time is NULL. + * @retval EFI_DEVICE_ERROR The time could not be set due due to hard= ware error. + **/ +EFI_STATUS +EFIAPI +PlatformSetTime ( + IN EFI_TIME *Time + ); + +/** + * Callback function for hardware platform to convert data pointers to vir= tual address + */ +VOID +EFIAPI +PlatformVirtualAddressChangeEvent ( + VOID + ); + +/** + * Callback function for hardware platform to initialize private data + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval Others The error status indicates the error + */ +EFI_STATUS +EFIAPI +PlatformInitialize ( + VOID + ); + +#endif /* PCF85063_H_ */ diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85= 063.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c new file mode 100644 index 000000000000..bc886b530f3c --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c @@ -0,0 +1,317 @@ +/** @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 +#include +#include +#include + +#include "PCF85063.h" + +#define RTC_TIMEOUT_WAIT_ACCESS 100000 /* 100 miliseconds */ +#define RTC_DEFAULT_MIN_YEAR 2000 +#define RTC_DEFAULT_MAX_YEAR 2099 + +#define RTC_ADDR 0x4 +#define RTC_DATA_BUF_LEN 8 + +/** + * PCF85063 register offsets + */ +#define PCF85063_OFFSET_SEC 0x0 +#define PCF85063_OFFSET_MIN 0x1 +#define PCF85063_OFFSET_HR 0x2 +#define PCF85063_OFFSET_DAY 0x3 +#define PCF85063_OFFSET_WKD 0x4 +#define PCF85063_OFFSET_MON 0x5 +#define PCF85063_OFFSET_YEA 0x6 + +/** + * PCF85063 encoding macros + */ +#define PCF85063_SEC_ENC(s) (((((s) / 10) & 0x7) << 4) | (((s) % 10) & 0xf= )) +#define PCF85063_MIN_ENC(m) (((((m) / 10) & 0x7) << 4) | (((m) % 10) & 0xf= )) +#define PCF85063_HR_ENC(h) (((((h) / 10) & 0x3) << 4) | (((h) % 10) & 0xf= )) +#define PCF85063_DAY_ENC(d) (((((d) / 10) & 0x3) << 4) | (((d) % 10) & 0xf= )) +#define PCF85063_WKD_ENC(w) ((w) & 0x7) +#define PCF85063_MON_ENC(m) (((((m) / 10) & 0x1) << 4) | (((m) % 10) & 0xf= )) +#define PCF85063_YEA_ENC(y) (((((y) / 10) & 0xf) << 4) | (((y) % 10) & 0xf= )) + +/** + * PCF85063 decoding macros + */ +#define PCF85063_SEC_DEC(s) (((((s) & 0x70) >> 4) * 10) + ((s) & 0xf)) +#define PCF85063_MIN_DEC(m) (((((m) & 0x70) >> 4) * 10) + ((m) & 0xf)) +#define PCF85063_HR_DEC(h) (((((h) & 0x30) >> 4) * 10) + ((h) & 0xf)) +#define PCF85063_DAY_DEC(d) (((((d) & 0x30) >> 4) * 10) + ((d) & 0xf)) +#define PCF85063_WKD_DEC(w) ((w) & 0x7) +#define PCF85063_MON_DEC(m) (((((m) & 0x10) >> 4) * 10) + ((m) & 0xf)) +#define PCF85063_YEA_DEC(y) (((((y) & 0xf0) >> 4) * 10) + ((y) & 0xf)) + +/* Buffer pointers to convert Vir2Phys and Phy2Vir */ +STATIC volatile UINT64 RtcBufVir; +STATIC volatile UINT64 RtcBufPhy; + +STATIC +EFI_STATUS +RtcI2cWaitAccess ( + VOID + ) +{ + INTN Timeout; + + Timeout =3D RTC_TIMEOUT_WAIT_ACCESS; + while ((GpioReadBit (I2C_RTC_ACCESS_GPIO_PIN) !=3D 0) && (Timeout > 0)) = { + MicroSecondDelay (100); + Timeout -=3D 100; + } + + if (Timeout <=3D 0) { + DEBUG ((DEBUG_ERROR, "%a: Timeout while waiting access RTC\n", __FUNCT= ION__)); + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +RtcI2cRead ( + IN UINT8 Addr, + IN OUT UINT64 Data, + IN UINT32 DataLen + ) +{ + EFI_STATUS Status; + UINT32 TmpLen; + + if (EFI_ERROR (RtcI2cWaitAccess ())) { + return EFI_DEVICE_ERROR; + } + + Status =3D I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Send the slave address for read + // + TmpLen =3D 1; + Status =3D I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, (UINT8 *= )&Addr, &TmpLen); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Read back the time + // + Status =3D I2cRead (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, NULL, 0, = (UINT8 *)Data, &DataLen); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +RtcI2cWrite ( + IN UINT8 Addr, + IN UINT64 Data, + IN UINT32 DataLen + ) +{ + EFI_STATUS Status; + UINT8 TmpBuf[RTC_DATA_BUF_LEN + 1]; + UINT32 TmpLen; + + if (EFI_ERROR (RtcI2cWaitAccess ())) { + return EFI_DEVICE_ERROR; + } + + if (DataLen > sizeof (TmpBuf) - 1) { + return EFI_INVALID_PARAMETER; + } + + Status =3D I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // The first byte is the address + // + TmpBuf[0] =3D Addr; + TmpLen =3D DataLen + 1; + CopyMem ((VOID *)(TmpBuf + 1), (VOID *)Data, DataLen); + + Status =3D I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, TmpBuf, = &TmpLen); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + * Returns the current time and date information of the hardware platform. + * + * @param Time A pointer to storage to receive a snapsho= t of the current time. + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER Time is NULL. + * @retval EFI_DEVICE_ERROR The time could not be retrieved due to ha= rdware error. + */ +EFI_STATUS +EFIAPI +PlatformGetTime ( + OUT EFI_TIME *Time + ) +{ + EFI_STATUS Status; + UINT8 *Data; + + if (Time =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Status =3D RtcI2cRead (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN); + + Data =3D (UINT8 *)RtcBufVir; + if (Status =3D=3D EFI_SUCCESS) { + Time->Second =3D PCF85063_SEC_DEC (Data[PCF85063_OFFSET_SEC]); + Time->Minute =3D PCF85063_MIN_DEC (Data[PCF85063_OFFSET_MIN]); + Time->Hour =3D PCF85063_HR_DEC (Data[PCF85063_OFFSET_HR]); + Time->Day =3D PCF85063_DAY_DEC (Data[PCF85063_OFFSET_DAY]); + Time->Month =3D PCF85063_MON_DEC (Data[PCF85063_OFFSET_MON]); + Time->Year =3D PCF85063_YEA_DEC (Data[PCF85063_OFFSET_YEA]); + Time->Year +=3D RTC_DEFAULT_MIN_YEAR; + if (Time->Year > RTC_DEFAULT_MAX_YEAR) { + Time->Year =3D RTC_DEFAULT_MAX_YEAR; + } + if (Time->Year < RTC_DEFAULT_MIN_YEAR) { + Time->Year =3D RTC_DEFAULT_MIN_YEAR; + } + } + + return Status; +} + +/** + * Set the time and date information to the hardware platform. + * + * @param Time A pointer to storage to set the current t= ime to hardware platform. + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER Time is NULL. + * @retval EFI_DEVICE_ERROR The time could not be set due due to hard= ware error. + **/ +EFI_STATUS +EFIAPI +PlatformSetTime ( + IN EFI_TIME *Time + ) +{ + UINT8 *Data; + + if (Time =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Time->Year < RTC_DEFAULT_MIN_YEAR || + Time->Year > RTC_DEFAULT_MAX_YEAR) + { + return EFI_INVALID_PARAMETER; + } + + Data =3D (UINT8 *)RtcBufVir; + Data[PCF85063_OFFSET_SEC] =3D PCF85063_SEC_ENC (Time->Second); + Data[PCF85063_OFFSET_MIN] =3D PCF85063_MIN_ENC (Time->Minute); + Data[PCF85063_OFFSET_HR] =3D PCF85063_HR_ENC (Time->Hour); + Data[PCF85063_OFFSET_DAY] =3D PCF85063_DAY_ENC (Time->Day); + Data[PCF85063_OFFSET_MON] =3D PCF85063_MON_ENC (Time->Month); + Data[PCF85063_OFFSET_YEA] =3D PCF85063_YEA_ENC (Time->Year - RTC_DEFAULT= _MIN_YEAR); + + return RtcI2cWrite (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN); +} + +/** + * Callback function for hardware platform to convert data pointers to vir= tual address + */ +VOID +EFIAPI +PlatformVirtualAddressChangeEvent ( + VOID + ) +{ + EfiConvertPointer (0x0, (VOID **)&RtcBufVir); +} + +/** + * Callback function for hardware platform to initialize private data + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval Others The error status indicates the error + */ +EFI_STATUS +EFIAPI +PlatformInitialize ( + VOID + ) +{ + EFI_STATUS Status; + + /* + * Allocate the buffer for RTC data + * The buffer can be accessible after ExitBootServices + */ + RtcBufVir =3D (UINT64)AllocateRuntimeZeroPool (RTC_DATA_BUF_LEN); + ASSERT_EFI_ERROR (RtcBufVir); + RtcBufPhy =3D (UINT64)RtcBufVir; + + Status =3D I2cSetupRuntime (I2C_RTC_BUS_ADDRESS); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a:%d I2cSetupRuntime() failed - %r \n", + __FUNCTION__, + __LINE__, + Status + )); + return Status; + } + + Status =3D GpioSetupRuntime (I2C_RTC_ACCESS_GPIO_PIN); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a:%d GpioSetupRuntime() failed - %r \n", + __FUNCTION__, + __LINE__, + Status + )); + return Status; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85= 063RealTimeClockLib.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClo= ckLib/PCF85063RealTimeClockLib.c new file mode 100644 index 000000000000..ef8c71e92c18 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063Real= TimeClockLib.c @@ -0,0 +1,257 @@ +/** @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 +#include +#include +#include +#include +#include +#include + +#include "PCF85063.h" + +#define TICKS_PER_SEC (ArmGenericTimerGetTimerFreq ()) + +STATIC EFI_EVENT mVirtualAddressChangeEvent =3D NULL; + +STATIC UINT64 mLastSavedSystemCount =3D 0; +STATIC UINT64 mLastSavedTimeEpoch =3D 0; + +/** + * Returns the current time and date information, and the time-keeping cap= abilities + * of the hardware platform. + * + * @param Time A pointer to storage to receive a snapsho= t of the current time. + * @param Capabilities An optional pointer to a buffer to receiv= e the real time clock + * device's capabilities. + * + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER Time is NULL. + * @retval EFI_DEVICE_ERROR The time could not be retrieved due to ha= rdware error. + */ +EFI_STATUS +EFIAPI +LibGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities + ) +{ + EFI_STATUS Status; + UINT64 CurrentSystemCount; + UINT64 TimeElapsed; + UINTN EpochSeconds; + + if ((mLastSavedTimeEpoch =3D=3D 0) || EfiAtRuntime ()) { + Status =3D PlatformGetTime (Time); + if (EFI_ERROR (Status)) { + // Failed to read platform RTC so create fake time + Time->Second =3D 0; + Time->Minute =3D 0; + Time->Hour =3D 10; + Time->Day =3D 1; + Time->Month =3D 1; + Time->Year =3D 2017; + } + + EpochSeconds =3D EfiTimeToEpoch (Time); + if (!EfiAtRuntime ()) { + mLastSavedTimeEpoch =3D EpochSeconds; + mLastSavedSystemCount =3D ArmGenericTimerGetSystemCount (); + } + } else { + CurrentSystemCount =3D ArmGenericTimerGetSystemCount (); + if (CurrentSystemCount >=3D mLastSavedSystemCount) { + TimeElapsed =3D (CurrentSystemCount - mLastSavedSystemCount) / MultU= 64x32 (1, TICKS_PER_SEC); + EpochSeconds =3D mLastSavedTimeEpoch + TimeElapsed; + } else { + // System counter overflow 64 bits + // Call GetTime again to read the date from RTC HW, not using generi= c timer system counter + mLastSavedTimeEpoch =3D 0; + return LibGetTime (Time, Capabilities); + } + } + + // Adjust for the correct timezone + if (Time->TimeZone !=3D EFI_UNSPECIFIED_TIMEZONE) { + EpochSeconds +=3D Time->TimeZone * SEC_PER_MIN; + } + + // Adjust for the correct period + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) =3D=3D EFI_TIME_IN_DAYLIGHT)= { + // Convert to adjusted time, i.e. spring forwards one hour + EpochSeconds +=3D SEC_PER_HOUR; + } + + EpochToEfiTime (EpochSeconds, Time); + + return EFI_SUCCESS; +} + +/** + * Sets the current local time and date information. + * + * @param Time A pointer to the current time. + * + * @retval EFI_SUCCESS The operation completed successfully. + * @retval EFI_INVALID_PARAMETER A time field is out of range. + * @retval EFI_DEVICE_ERROR The time could not be set due due to hard= ware error. + */ +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + EFI_STATUS Status; + UINTN EpochSeconds; + + EpochSeconds =3D EfiTimeToEpoch (Time); + + // Adjust for the correct time zone, i.e. convert to UTC time zone + if (Time->TimeZone !=3D EFI_UNSPECIFIED_TIMEZONE) { + EpochSeconds -=3D Time->TimeZone * SEC_PER_MIN; + } + + // Adjust for the correct period, i.e. fall back one hour + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) =3D=3D EFI_TIME_IN_DAYLIGHT)= { + EpochSeconds -=3D SEC_PER_HOUR; + } + + EpochToEfiTime (EpochSeconds, Time); + + Status =3D PlatformSetTime (Time); + if (EFI_ERROR (Status)) { + return Status; + } + + if (!EfiAtRuntime ()) { + mLastSavedTimeEpoch =3D EpochSeconds; + mLastSavedSystemCount =3D ArmGenericTimerGetSystemCount (); + } + + return EFI_SUCCESS; +} + +/** + * Returns the current wakeup alarm clock setting. + * + * @param Enabled Indicates if the alarm is currently enabl= ed or disabled. + * @param Pending Indicates if the alarm signal is pending = and requires acknowledgement. + * @param Time The current alarm setting. + * + * @retval EFI_SUCCESS The alarm settings were returned. + * @retval EFI_INVALID_PARAMETER Any parameter is NULL. + * @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved du= e to a hardware error. + */ +EFI_STATUS +EFIAPI +LibGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + return EFI_UNSUPPORTED; +} + +/** + * Sets the system wakeup alarm clock time. + * + * @param Enabled Enable or disable the wakeup alarm. + * @param Time If Enable is TRUE, the time to set the wa= keup alarm for. + * + * @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm = was enabled. If + * Enable is FALSE, then the wakeup alarm wa= s disabled. + * @retval EFI_INVALID_PARAMETER A time field is out of range. + * @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a= hardware error. + * @retval EFI_UNSUPPORTED A wakeup timer is not supported on this p= latform. + */ +EFI_STATUS +EFIAPI +LibSetWakeupTime ( + IN BOOLEAN Enabled, + OUT EFI_TIME *Time + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +LibRtcVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Only needed if you are going to support the OS calling RTC functions = in virtual mode. + // You will need to call EfiConvertPointer (). To convert any stored phy= sical addresses + // to virtual address. After the OS transitions to calling in virtual mo= de, all future + // runtime calls will be made in virtual mode. + // + PlatformVirtualAddressChangeEvent (); +} + +/** + * This is the declaration of an EFI image entry point. This can be the en= try point to an application + * written to this specification, an EFI boot service driver, or an EFI ru= ntime driver. + * + * @param ImageHandle Handle that identifies the loaded image. + * @param SystemTable System Table for this image. + * + * @retval EFI_SUCCESS The operation completed successfully. + */ +EFI_STATUS +EFIAPI +LibRtcInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D PlatformInitialize (); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Register for the virtual address change event + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + LibRtcVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mVirtualAddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} --=20 2.17.1