From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=92.121.34.13; helo=inva020.nxp.com; envelope-from=meenakshi.aggarwal@nxp.com; receiver=edk2-devel@lists.01.org Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 39D312119590F for ; Wed, 28 Nov 2018 01:16:25 -0800 (PST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id F288B1A0322; Wed, 28 Nov 2018 10:16:23 +0100 (CET) Received: from inv0113.in-blr01.nxp.com (inv0113.in-blr01.nxp.com [165.114.116.118]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 555FD1A0315; Wed, 28 Nov 2018 10:16:23 +0100 (CET) Received: from uefi-OptiPlex-790.ap.freescale.net (uefi-OptiPlex-790.ap.freescale.net [10.232.132.78]) by inv0113.in-blr01.nxp.com (Postfix) with ESMTP id 5FC30340; Wed, 28 Nov 2018 14:46:22 +0530 (IST) From: Meenakshi Aggarwal To: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, michael.d.kinney@intel.com, edk2-devel@lists.01.org Date: Wed, 28 Nov 2018 20:31:34 +0530 Message-Id: <1543417315-5763-21-git-send-email-meenakshi.aggarwal@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1543417315-5763-1-git-send-email-meenakshi.aggarwal@nxp.com> References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> <1543417315-5763-1-git-send-email-meenakshi.aggarwal@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH edk2-platforms 20/41] Silicon/NXP:Add support for PCF2129 Real Time Clock Library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Nov 2018 09:16:25 -0000 From: Vabhav Library to provide functions for NXP pcf2129 real time clock library Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav Signed-off-by: Meenakshi Aggarwal --- Platform/NXP/NxpQoriqLs.dsc.inc | 1 + Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h | 52 +++ Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c | 389 +++++++++++++++++++++ .../NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec | 29 ++ .../NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf | 47 +++ 5 files changed, 518 insertions(+) create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf diff --git a/Platform/NXP/NxpQoriqLs.dsc.inc b/Platform/NXP/NxpQoriqLs.dsc.inc index 972dadc..5529a04 100644 --- a/Platform/NXP/NxpQoriqLs.dsc.inc +++ b/Platform/NXP/NxpQoriqLs.dsc.inc @@ -34,6 +34,7 @@ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf + TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h new file mode 100644 index 0000000..c862954 --- /dev/null +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h @@ -0,0 +1,52 @@ +/** Pcf2129Rtc.h +* +* Copyright 2017 NXP +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __PCF2129RTC_H__ +#define __PCF2129RTC_H__ + +/* + * RTC register addresses + */ +#define PCF2129_CTRL1_REG_ADDR 0x00 // Control Register 1 +#define PCF2129_CTRL2_REG_ADDR 0x01 // Control Register 2 +#define PCF2129_CTRL3_REG_ADDR 0x02 // Control Register 3 +#define PCF2129_SEC_REG_ADDR 0x03 +#define PCF2129_MIN_REG_ADDR 0x04 +#define PCF2129_HR_REG_ADDR 0x05 +#define PCF2129_DAY_REG_ADDR 0x06 +#define PCF2129_WEEKDAY_REG_ADDR 0x07 +#define PCF2129_MON_REG_ADDR 0x08 +#define PCF2129_YR_REG_ADDR 0x09 + +#define PCF2129_CTRL3_BIT_BLF BIT2 /* Battery Low Flag*/ + +/* + * Masks for RTC registers + */ +#define PCF2129_SECONDS_MASK 0x7F +#define PCF2129_MINUTES_MASK 0x7F +#define PCF2129_HOURS_MASK 0x3F +#define PCF2129_DAYS_MASK 0x3F +#define PCF2129_MONTHS_MASK 0x1F + +#define EPOCH_BASE_1990 1990 +#define EPOCH_BASE_2000 2000 + +typedef struct { + UINTN OperationCount; + EFI_I2C_OPERATION SetAddressOp; + EFI_I2C_OPERATION GetSetDateTimeOp; +} RTC_I2C_REQUEST; + +#endif // __PCF2129RTC_H__ diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c new file mode 100644 index 0000000..90bad66 --- /dev/null +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c @@ -0,0 +1,389 @@ +/** @PCF2129RtcLib.c + Implement EFI RealTimeClock with runtime services via RTC Lib for PCF2129 RTC. + + Based on RTC implementation available in + EmbeddedPkg/Library/TemplateRealTimeClockLib/RealTimeClockLib.c + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Pcf2129Rtc.h" + +STATIC VOID *mDriverEventRegistration; +STATIC EFI_HANDLE mI2cMasterHandle; +STATIC EFI_I2C_MASTER_PROTOCOL *mI2cMaster; + +/** + Write RTC register. + + @param RtcRegAddr Register offset of RTC to write. + @param Val Value to be written + +**/ + +STATIC +VOID +RtcWrite ( + IN UINT8 RtcRegAddr, + IN UINT8 Val + ) +{ + RTC_I2C_REQUEST Req; + EFI_STATUS Status; + + Req.OperationCount = 2; + + Req.SetAddressOp.Flags = 0; + Req.SetAddressOp.LengthInBytes = 0; + Req.SetAddressOp.Buffer = &RtcRegAddr; + + Req.GetSetDateTimeOp.Flags = 0; + Req.GetSetDateTimeOp.LengthInBytes = sizeof (Val); + Req.GetSetDateTimeOp.Buffer = &Val; + + Status = mI2cMaster->StartRequest ( + mI2cMaster, + FixedPcdGet8 (PcdI2cSlaveAddress), + (VOID *)&Req, + NULL, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RTC write error at Addr:0x%x\n", RtcRegAddr)); + } + +} + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param Time A pointer to storage to receive a snapshot of the current time. + @param Capabilities An optional pointer to a buffer to receive 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 hardware error. + +**/ + +EFI_STATUS +EFIAPI +LibGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities + ) +{ + EFI_STATUS Status; + UINT8 Buffer[10]; + RTC_I2C_REQUEST Req; + UINT8 RtcRegAddr; + UINT16 EpochBase; + + Status = EFI_SUCCESS; + RtcRegAddr = PCF2129_CTRL1_REG_ADDR; + Buffer[0] = 0; + + if (mI2cMaster == NULL) { + return EFI_DEVICE_ERROR; + } + + RtcWrite (PCF2129_CTRL1_REG_ADDR, Buffer[0]); + + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + Req.OperationCount = 2; + + Req.SetAddressOp.Flags = 0; + Req.SetAddressOp.LengthInBytes = 0; + Req.SetAddressOp.Buffer = &RtcRegAddr; + + Req.GetSetDateTimeOp.Flags = I2C_FLAG_READ; + Req.GetSetDateTimeOp.LengthInBytes = sizeof (Buffer); + Req.GetSetDateTimeOp.Buffer = Buffer; + + Status = mI2cMaster->StartRequest ( + mI2cMaster, + FixedPcdGet8 (PcdI2cSlaveAddress), + (VOID *)&Req, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RTC read error at Addr:0x%x\n", RtcRegAddr)); + } + + if (Buffer[PCF2129_CTRL3_REG_ADDR] & PCF2129_CTRL3_BIT_BLF) { + DEBUG((DEBUG_INFO, "### Warning: RTC battery status low, check/replace RTC battery.\n")); + } + + EpochBase = BcdToDecimal8 (Buffer[PCF2129_YR_REG_ADDR]) >= 98 ? EPOCH_BASE_1990 : EPOCH_BASE_2000; + + Time->Nanosecond = 0; + Time->Second = BcdToDecimal8 (Buffer[PCF2129_SEC_REG_ADDR] & PCF2129_SECONDS_MASK); + Time->Minute = BcdToDecimal8 (Buffer[PCF2129_MIN_REG_ADDR] & PCF2129_MINUTES_MASK); + Time->Hour = BcdToDecimal8 (Buffer[PCF2129_HR_REG_ADDR] & PCF2129_HOURS_MASK); + Time->Day = BcdToDecimal8 (Buffer[PCF2129_DAY_REG_ADDR] & PCF2129_DAYS_MASK); + Time->Month = BcdToDecimal8 (Buffer[PCF2129_MON_REG_ADDR] & PCF2129_MONTHS_MASK); + Time->Year = BcdToDecimal8 (Buffer[PCF2129_YR_REG_ADDR]) + EpochBase; + + return Status; +} + +/** + 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 hardware error. + +**/ + +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + UINT8 Buffer[8]; + UINT8 Index; + EFI_STATUS Status; + RTC_I2C_REQUEST Req; + UINT8 RtcRegAddr; + + Index = 0; + Status = EFI_SUCCESS; + RtcRegAddr = PCF2129_CTRL1_REG_ADDR; + + if (mI2cMaster == NULL) { + return EFI_DEVICE_ERROR; + } + + // start register address + Buffer[Index++] = PCF2129_SEC_REG_ADDR; + + // hours, minutes and seconds + Buffer[Index++] = DecimalToBcd8 (Time->Second); + Buffer[Index++] = DecimalToBcd8 (Time->Minute); + Buffer[Index++] = DecimalToBcd8 (Time->Hour); + Buffer[Index++] = DecimalToBcd8 (Time->Day); + Buffer[Index++] = EfiTimeToWday (Time); + Buffer[Index++] = DecimalToBcd8 (Time->Month); + Buffer[Index++] = DecimalToBcd8 (Time->Year % 100); + + Req.OperationCount = 2; + Req.SetAddressOp.Flags = 0; + Req.SetAddressOp.LengthInBytes = 0; + Req.SetAddressOp.Buffer = &RtcRegAddr; + + Req.GetSetDateTimeOp.Flags = 0; + Req.GetSetDateTimeOp.LengthInBytes = sizeof (Buffer); + Req.GetSetDateTimeOp.Buffer = Buffer; + + Status = mI2cMaster->StartRequest ( + mI2cMaster, + FixedPcdGet8 (PcdI2cSlaveAddress), + (VOID *)&Req, + NULL, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RTC write error at Addr:0x%x\n", RtcRegAddr)); + return Status; + } + + return Status; +} + + +/** + Returns the current wakeup alarm clock setting. + + @param Enabled Indicates if the alarm is currently enabled 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 due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +LibGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + 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 wakeup alarm for. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was 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 platform. + +**/ +EFI_STATUS +EFIAPI +LibSetWakeupTime ( + IN BOOLEAN Enabled, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +STATIC +VOID +I2cDriverRegistrationEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_I2C_MASTER_PROTOCOL *I2cMaster; + UINTN BusFrequency; + EFI_HANDLE Handle; + UINTN BufferSize; + + // + // Try to connect the newly registered driver to our handle. + // + do { + BufferSize = sizeof (EFI_HANDLE); + Status = gBS->LocateHandle (ByRegisterNotify, + &gEfiI2cMasterProtocolGuid, + mDriverEventRegistration, + &BufferSize, + &Handle); + if (EFI_ERROR (Status)) { + if (Status != EFI_NOT_FOUND) { + DEBUG ((DEBUG_WARN, "%a: gBS->LocateHandle () returned %r\n", + __FUNCTION__, Status)); + } + break; + } + + if (Handle != mI2cMasterHandle) { + continue; + } + + DEBUG ((DEBUG_INFO, "%a: found I2C master!\n", __FUNCTION__)); + + gBS->CloseEvent (Event); + + Status = gBS->OpenProtocol (mI2cMasterHandle, &gEfiI2cMasterProtocolGuid, + (VOID **)&I2cMaster, gImageHandle, NULL, + EFI_OPEN_PROTOCOL_EXCLUSIVE); + ASSERT_EFI_ERROR (Status); + + Status = I2cMaster->Reset (I2cMaster); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: I2CMaster->Reset () failed - %r\n", + __FUNCTION__, Status)); + break; + } + + BusFrequency = FixedPcdGet16 (PcdI2cBusFrequency); + Status = I2cMaster->SetBusFrequency (I2cMaster, &BusFrequency); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: I2CMaster->SetBusFrequency () failed - %r\n", + __FUNCTION__, Status)); + break; + } + + mI2cMaster = I2cMaster; + break; + } while (TRUE); +} + +/** + This is the declaration of an EFI image entry point. This can be the entry point to an application + written to this specification, an EFI boot service driver, or an EFI runtime driver. + + @param ImageHandle Handle that identifies the loaded image. + @param SystemTable System Table for this image. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_DEVICE_ERROR The operation could not be started. + +**/ +EFI_STATUS +EFIAPI +LibRtcInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + EFI_STATUS Status; + UINTN BufferSize; + + // + // Find the handle that marks the controller + // that will provide the I2C master protocol. + // + BufferSize = sizeof (EFI_HANDLE); + Status = gBS->LocateHandle ( + ByProtocol, + &gPcf2129RealTimeClockLibI2cMasterProtocolGuid, + NULL, + &BufferSize, + &mI2cMasterHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Register a protocol registration notification callback on the driver + // binding protocol so we can attempt to connect our I2C master to it + // as soon as it appears. + // + EfiCreateProtocolNotifyEvent ( + &gEfiI2cMasterProtocolGuid, + TPL_CALLBACK, + I2cDriverRegistrationEvent, + NULL, + &mDriverEventRegistration); + + return EFI_SUCCESS; +} diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec new file mode 100644 index 0000000..ea3fad6 --- /dev/null +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec @@ -0,0 +1,29 @@ +#/** @file +# +# Copyright 2017 NXP +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + DEC_SPECIFICATION = 0x0001001A + PACKAGE_NAME = Pcf2129RtcLib + PACKAGE_GUID = d6c2b7cf-4d3b-4173-8d99-fdcf9ba8403d + PACKAGE_VERSION = 0.1 + +[Guids] + gPcf2129RtcLibTokenSpaceGuid = { 0xb67741d5, 0x0b12, 0x42e1, {0x85, 0xcd, 0x37, 0x1c, 0x5d, 0x59, 0xb7, 0xb0 }} + +[Protocols] + gPcf2129RealTimeClockLibI2cMasterProtocolGuid = { 0x8a1aac5e, 0xdffa, 0x4722, {0xba, 0x75, 0x55, 0x80, 0xda, 0x6a, 0x1b, 0x00 }} + +[PcdsFixedAtBuild] + gPcf2129RtcLibTokenSpaceGuid.PcdI2cSlaveAddress|0|UINT8|0x00000001 + gPcf2129RtcLibTokenSpaceGuid.PcdI2cBusFrequency|0|UINT32|0x00000002 diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf new file mode 100644 index 0000000..fd19b63 --- /dev/null +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf @@ -0,0 +1,47 @@ +#/** @Pcf2129RtcLib.inf +# +# Copyright 2017 NXP +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = Pcf2129RtcLib + FILE_GUID = B661E02D-A90B-42AB-A5F9-CF841AAA43D9 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RealTimeClockLib + + +[Sources.common] + Pcf2129RtcLib.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.dec + +[LibraryClasses] + DebugLib + TimeBaseLib + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiI2cMasterProtocolGuid ## CONSUMES + gPcf2129RealTimeClockLibI2cMasterProtocolGuid ## CONSUMES + +[Pcd] + gPcf2129RtcLibTokenSpaceGuid.PcdI2cSlaveAddress + gPcf2129RtcLibTokenSpaceGuid.PcdI2cBusFrequency + +[Depex] + gPcf2129RealTimeClockLibI2cMasterProtocolGuid ## CONSUMES -- 1.9.1