From patchwork Tue Dec 6 10:57:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gary guo X-Patchwork-Id: 86781 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp1961513qgi; Tue, 6 Dec 2016 03:19:53 -0800 (PST) X-Received: by 10.55.176.131 with SMTP id z125mr50617906qke.286.1481023193667; Tue, 06 Dec 2016 03:19:53 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id u63si11432804qkb.79.2016.12.06.03.19.53; Tue, 06 Dec 2016 03:19:53 -0800 (PST) Received-SPF: pass (google.com: domain of linaro-uefi-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linaro-uefi-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=linaro-uefi-bounces@lists.linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 39A5260C20; Tue, 6 Dec 2016 11:19:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 52FF46369F; Tue, 6 Dec 2016 11:05:12 +0000 (UTC) X-Original-To: linaro-uefi@lists.linaro.org Delivered-To: linaro-uefi@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id F33CB60C7E; Tue, 6 Dec 2016 11:04:33 +0000 (UTC) Received: from mail-pg0-f41.google.com (mail-pg0-f41.google.com [74.125.83.41]) by lists.linaro.org (Postfix) with ESMTPS id 7CF6F607EE for ; Tue, 6 Dec 2016 11:00:17 +0000 (UTC) Received: by mail-pg0-f41.google.com with SMTP id x23so148348152pgx.1 for ; Tue, 06 Dec 2016 03:00:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=j65LaYLYmj8sqnkRFeygKI0mbGT5Y4e7HDH4X9JZYfM=; b=WZzCEEKo1zDfV+Ycg+2lI5uHZgmNgIALv1B+a5WtwYwdCjuqAQ9EfWNoJHyrfpbwt4 WHyW6GU/V+GPGAbKiUXh8sVLdAf7qN6DahWzIQ4Gd+rWjYGAiq8azdpq1ybbB+wdWmz/ G6P7S8nb4g/ri8k6bxTUvTHfSZeeY3GLtwgr5KTwHIqmjNXqypsJjNRpZGaozY8Ofm5H a7wobF1rSEBzmdZw5PM+Se015u9xD0vEumko9MQNgOv7A32dtmQCPhYTyQbw65QpVADS a4Qf3Z63w0bLFaxsyaPIgLDPhMy5VgubMkSPwxBtlqcfOOIAmnFMio+smtV2KdCRQutX av6g== X-Gm-Message-State: AKaTC03P6VhiFaPDMp5GP/4Qyvqg+J1K+cgpstQH4vvn2uHrH968D1oCrSaCpINLanHMnRjw6p4= X-Received: by 10.84.141.1 with SMTP id 1mr134507068plu.133.1481022016628; Tue, 06 Dec 2016 03:00:16 -0800 (PST) Received: from localhost.localdomain ([119.145.15.121]) by smtp.gmail.com with ESMTPSA id x26sm6980952pge.24.2016.12.06.03.00.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Dec 2016 03:00:16 -0800 (PST) From: Heyi Guo To: linaro-uefi@lists.linaro.org Date: Tue, 6 Dec 2016 18:57:06 +0800 Message-Id: <1481021828-59826-36-git-send-email-heyi.guo@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1481021828-59826-1-git-send-email-heyi.guo@linaro.org> References: <1481021828-59826-1-git-send-email-heyi.guo@linaro.org> Cc: Peicong Li , sunchenhui@huawei.com, wanghuiqiang@huawei.com Subject: [Linaro-uefi] [linaro-uefi v6 35/37] D03: enhance RTC lock acquiring X-BeenThere: linaro-uefi@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linaro-uefi-bounces@lists.linaro.org Sender: "Linaro-uefi" We would acquire I2C lock only when I2C status in CPLD shows idle, however, acquiring lock will still fail for BMC might acquire the lock at exactly the same time. So we add additional check to see if we really get the lock. Timeout process is also added to avoid system hang due to possible deadlock or device error. Code style is improved as well. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Peicong Li Signed-off-by: Heyi Guo --- Platforms/Hisilicon/D03/Include/Library/CpldD03.h | 4 ++ .../DS3231RealTimeClockLib.c | 83 +++++++++++++++++----- .../DS3231RealTimeClockLib.inf | 2 + 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/Platforms/Hisilicon/D03/Include/Library/CpldD03.h b/Platforms/Hisilicon/D03/Include/Library/CpldD03.h index 78aec2f..456bf4b 100644 --- a/Platforms/Hisilicon/D03/Include/Library/CpldD03.h +++ b/Platforms/Hisilicon/D03/Include/Library/CpldD03.h @@ -17,5 +17,9 @@ #define __CPLD_D03_H__ #define CPLD_BIOSINDICATE_FLAG 0x09 +#define CPLD_I2C_SWITCH_FLAG 0x17 +#define CPU_GET_I2C_CONTROL BIT2 +#define BMC_I2C_STATUS BIT3 + #endif diff --git a/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c b/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c index fa63027..3d4a624 100644 --- a/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c +++ b/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c @@ -38,6 +38,7 @@ #include #include #include "DS3231RealTimeClock.h" +#include #include extern I2C_DEVICE gDS3231RtcDevice; @@ -56,6 +57,48 @@ IdentifyDS3231 ( } EFI_STATUS +SwitchRtcI2cChannelAndLock(VOID) +{ + UINT8 Temp; + UINT8 Count; + + for (Count = 0; Count < 20; Count++){ + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + + if ((Temp & BMC_I2C_STATUS) != 0){ + //The I2C channel is shared with BMC, + //and we need some time to get the idle status, + //we only switch I2C channel to RTC when it is not busy + MicroSecondDelay(30000); + + continue; + } + + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + Temp = Temp | CPU_GET_I2C_CONTROL; + WriteCpldReg(CPLD_I2C_SWITCH_FLAG, Temp); + //This is empirical value,give cpld some time to make sure the + //value is wrote in + MicroSecondDelay(2); + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + + if ((Temp & CPU_GET_I2C_CONTROL) == CPU_GET_I2C_CONTROL){ + return EFI_SUCCESS; + } + //There need 30ms to keep consistent with the previous loops if the CPU failed + //to get control of I2C + MicroSecondDelay(30000); + } + + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + Temp = Temp & ~CPU_GET_I2C_CONTROL; + WriteCpldReg(CPLD_I2C_SWITCH_FLAG, Temp); + + return EFI_NOT_READY; +} + + +EFI_STATUS InitializeDS3231 ( VOID ) @@ -136,19 +179,17 @@ LibGetTime ( return EFI_INVALID_PARAMETER; } - - - Temp = ReadCpldReg(0x17); - while( (Temp & BIT3) != 0) - { - Temp = ReadCpldReg(0x17); + Status = SwitchRtcI2cChannelAndLock(); + if(EFI_ERROR (Status)) { + return Status; } - WriteCpldReg(0x17,0x4); + // Initialize the hardware if not already done if (!mDS3231Initialized) { Status = InitializeDS3231 (); if (EFI_ERROR (Status)) { - return EFI_NOT_READY; + Status = EFI_NOT_READY; + goto GExit; } } @@ -175,7 +216,8 @@ LibGetTime ( BaseHour = 0; if((Temp&0x30) == 0x30){ - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto GExit; }else if(Temp&0x20){ BaseHour = 20; }else if(Temp&0x10){ @@ -196,11 +238,15 @@ LibGetTime ( Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; if((EFI_ERROR(Status)) || (!IsTimeValid(Time)) || ((Time->Year - BaseYear) > 99)) { - return EFI_DEVICE_ERROR; + Status = EFI_UNSUPPORTED; } - WriteCpldReg(0x17,0x0); - return EFI_SUCCESS; +GExit: + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + Temp = Temp & ~CPU_GET_I2C_CONTROL; + WriteCpldReg(CPLD_I2C_SWITCH_FLAG, Temp); + + return Status; } @@ -234,13 +280,10 @@ LibSetTime ( return EFI_INVALID_PARAMETER; } - - Temp = ReadCpldReg(0x17); - while( (Temp & BIT3) != 0) - { - Temp = ReadCpldReg(0x17); + Status = SwitchRtcI2cChannelAndLock(); + if(EFI_ERROR (Status)) { + return Status; } - WriteCpldReg(0x17,0x4); // Initialize the hardware if not already done if (!mDS3231Initialized) { @@ -313,7 +356,9 @@ LibSetTime ( EXIT: - WriteCpldReg(0x17,0x0); + Temp = ReadCpldReg(CPLD_I2C_SWITCH_FLAG); + Temp = Temp & ~CPU_GET_I2C_CONTROL; + WriteCpldReg(CPLD_I2C_SWITCH_FLAG, Temp); return Status; } diff --git a/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf b/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf index 8121f37..ae1b9b8 100644 --- a/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf +++ b/Platforms/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf @@ -30,6 +30,7 @@ MdePkg/MdePkg.dec EmbeddedPkg/EmbeddedPkg.dec OpenPlatformPkg/OpenPlatformPkg.dec + OpenPlatformPkg/Platforms/Hisilicon/D03/D03.dec OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec [LibraryClasses] @@ -41,6 +42,7 @@ TimerLib # Use EFiAtRuntime to check stage UefiRuntimeLib + CpldIoLib EfiTimeBaseLib [Pcd]