From patchwork Wed Dec 7 11:49:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gary guo X-Patchwork-Id: 87074 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp281618qgi; Wed, 7 Dec 2016 04:14:31 -0800 (PST) X-Received: by 10.200.47.119 with SMTP id k52mr66021434qta.180.1481112871071; Wed, 07 Dec 2016 04:14:31 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id m186si14287487qkc.45.2016.12.07.04.14.30; Wed, 07 Dec 2016 04:14:31 -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 D184D60899; Wed, 7 Dec 2016 12:14:07 +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_H2 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 B22A860750; Wed, 7 Dec 2016 11:59:00 +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 2236560E94; Wed, 7 Dec 2016 11:58:35 +0000 (UTC) Received: from mail-pg0-f43.google.com (mail-pg0-f43.google.com [74.125.83.43]) by lists.linaro.org (Postfix) with ESMTPS id 0BF8C60E6A for ; Wed, 7 Dec 2016 11:52:51 +0000 (UTC) Received: by mail-pg0-f43.google.com with SMTP id x23so161419530pgx.1 for ; Wed, 07 Dec 2016 03:52:51 -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=EyEBzxNrZ+R1qERq6mCIsfOivlrzP3WYWa+Zqpa2gcQ=; b=UXHwwWrd9D3LLtvUgJN62s6WvkLRTCLa9QqGeZhhF3O0UOKDavUQ79gdtlHXlcisE3 ujcwEaO0P0ECumVDpnHEwh9YnrDlbNMk3Obs+nFobsK51lwGlMt0pK1R4JUxcuJeH1Wc ziLbZlIBPUHfujDyH1Ll1ak5ppBu5Vk3InOE13Gg0hC5nSrpw+p+xbHOTSxK3Kfp2je4 HqoRu57mNONoRzL1dppVPfatLDTADKdMclb4k68lzvoLAGtluY6YJlr2Uqceu8WDqxaj MrtnIlM8mquG8depvHlgHFXF2VkPKTrI1/4HnaoCkXiv8TyufTMwkhiOpU69FNByuCbS nvyg== X-Gm-Message-State: AKaTC01ad5HVYVDm3OVhNd8NeK4O+DxE1Inngja3j7YYIZrO4L0e7JI2t3fauxIOTlrZ0EE7EHE= X-Received: by 10.84.142.1 with SMTP id 1mr143485600plw.87.1481111570113; Wed, 07 Dec 2016 03:52:50 -0800 (PST) Received: from localhost.localdomain ([119.145.15.121]) by smtp.gmail.com with ESMTPSA id y20sm42169141pfj.26.2016.12.07.03.52.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 07 Dec 2016 03:52:49 -0800 (PST) From: Heyi Guo To: linaro-uefi@lists.linaro.org Date: Wed, 7 Dec 2016 19:49:33 +0800 Message-Id: <1481111375-71058-37-git-send-email-heyi.guo@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1481111375-71058-1-git-send-email-heyi.guo@linaro.org> References: <1481111375-71058-1-git-send-email-heyi.guo@linaro.org> Cc: Peicong Li , sunchenhui@huawei.com, wanghuiqiang@huawei.com Subject: [Linaro-uefi] [linaro-uefi v7 36/38] 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 Reviewed-by: Leif Lindholm --- Platforms/Hisilicon/D03/Include/Library/CpldD03.h | 4 + .../DS3231RealTimeClockLib.c | 89 +++++++++++++++++----- .../DS3231RealTimeClockLib.inf | 2 + 3 files changed, 76 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..91d7de1 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,54 @@ 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, + //Check if BMC has taken ownership of I2C. + //If so, wait 30ms, then try again. + //If not, start using I2C. + //And the CPLD_I2C_SWITCH_FLAG will be set to CPU_GET_I2C_CONTROL + //BMC will check this flag to decide to use I2C or not. + 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 +185,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 +222,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 +244,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 +286,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 +362,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]