From: "Nhi Pham via groups.io" <nhi=os.amperecomputing.com@groups.io>
To: devel@edk2.groups.io
Cc: quic_llindhol@quicinc.com, chuong@os.amperecomputing.com,
rebecca@os.amperecomputing.com, nhi@os.amperecomputing.com
Subject: [edk2-devel] [edk2-platforms][PATCH v2 1/5] AmpereAltraPkg/DwI2cLib: Add support for SMBUS+PEC operation
Date: Wed, 7 Aug 2024 13:47:27 +0700 [thread overview]
Message-ID: <20240807064731.4049764-2-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20240807064731.4049764-1-nhi@os.amperecomputing.com>
This introduces two input parameters to the I2cProbe() and updates the
InternalI2cRead() for the support of the SMBUS operation with optional
PEC check, which will be used by the IPMI SSIF driver.
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h | 11 +-
Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c | 6 +-
Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c | 129 ++++++++++++++++++--
3 files changed, 131 insertions(+), 15 deletions(-)
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
index f13794171029..3a312f7b6aed 100644
--- a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
@@ -1,7 +1,7 @@
/** @file
Library implementation for the Designware I2C controller.
- Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+ Copyright (c) 2020 - 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -70,6 +70,9 @@ I2cRead (
@param[in] Bus I2C bus Id.
@param[in] BusSpeed I2C bus speed in Hz.
+ @param[in] IsSmbus Flag to indicate if the bus is used to execute an SMBus operation.
+ @param[in] PecCheck If Packet Error Code (PEC) checking is required for the SMBUS operation
+ and is ignored when present in other operations.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@@ -78,8 +81,10 @@ I2cRead (
EFI_STATUS
EFIAPI
I2cProbe (
- IN UINT32 Bus,
- IN UINTN BusSpeed
+ IN UINT32 Bus,
+ IN UINTN BusSpeed,
+ IN BOOLEAN IsSmbus,
+ IN BOOLEAN PecCheck
);
/**
diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
index bc886b530f3c..a9e7328381e6 100644
--- a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
+++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+ Copyright (c) 2020 - 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -104,7 +104,7 @@ RtcI2cRead (
return EFI_DEVICE_ERROR;
}
- Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
+ Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED, FALSE, FALSE);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -148,7 +148,7 @@ RtcI2cWrite (
return EFI_INVALID_PARAMETER;
}
- Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
+ Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED, FALSE, FALSE);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
index 669ba2ea98a4..a6631ea17d69 100644
--- a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+ Copyright (c) 2020 - 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -31,12 +31,14 @@
// Private I2C bus data
//
typedef struct {
- UINTN Base;
- UINT32 BusSpeed;
- UINT32 RxFifo;
- UINT32 TxFifo;
- UINT32 PollingTime;
- UINT32 Enabled;
+ UINTN Base;
+ UINT32 BusSpeed;
+ UINT32 RxFifo;
+ UINT32 TxFifo;
+ UINT32 PollingTime;
+ UINT32 Enabled;
+ BOOLEAN IsSmbus;
+ BOOLEAN PecCheck;
} DW_I2C_CONTEXT_T;
//
@@ -337,6 +339,11 @@ I2cWaitTxData (
DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX buffer available\n", __FUNCTION__));
return EFI_TIMEOUT;
}
+
+ if ((I2cCheckErrors (Bus) & DW_IC_INTR_TX_ABRT) != 0) {
+ return EFI_ABORTED;
+ }
+
MicroSecondDelay (mI2cBusList[Bus].PollingTime);
}
@@ -542,6 +549,72 @@ InternalI2cWrite (
return Status;
}
+/**
+ This extracts the data length from the initial byte of the SMBUS transaction. This allows
+ the driver to accurately read the SMBUS response with the exact length, rather than
+ consistently reading 32-byte block of data.
+
+ @param[in] Bus I2C bus Id.
+ @param[out] BusSpeed Pointer to the buffer to store the read length.
+
+ @retval EFI_SUCCESS The operation is successful.
+ @retval Others An error occurred.
+
+**/
+EFI_STATUS
+InternalSmbusReadDataLength (
+ UINT32 Bus,
+ UINT32 *Length
+ )
+{
+ EFI_STATUS Status;
+ UINTN Base;
+ UINT32 CmdSend;
+
+ Base = mI2cBusList[Bus].Base;
+
+ CmdSend = DW_IC_DATA_CMD_CMD;
+ MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
+ I2cSync ();
+
+ if (I2cCheckErrors (Bus) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a: Sending reading command error\n", __func__));
+ return EFI_CRC_ERROR;
+ }
+
+ Status = I2cWaitRxData (Bus);
+ if (EFI_ERROR (Status)) {
+ //
+ // If the SMBUS target is not ready to handle the request
+ // or is busy with preparing the response data, it will response
+ // NACK, and the error status TX_ABRT is triggered to indicate that
+ // the RX FIFO is not ready for reading. Thus, the following message
+ // serves more as verbose alert rather than an error.
+ //
+ DEBUG ((DEBUG_VERBOSE,
+ "%a: Reading Smbus data length failed to wait data\n",
+ __func__
+ ));
+
+ if (Status != EFI_ABORTED) {
+ MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
+ I2cSync ();
+ }
+
+ return Status;
+ }
+
+ *Length = MmioRead32 (Base + DW_IC_DATA_CMD) & DW_IC_DATA_CMD_DAT_MASK;
+ I2cSync ();
+
+ if (I2cCheckErrors (Bus) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a: Sending reading command error\n", __func__));
+ return EFI_CRC_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
EFI_STATUS
InternalI2cRead (
UINT32 Bus,
@@ -559,6 +632,7 @@ InternalI2cRead (
UINTN Count;
UINTN ReadCount;
UINTN WriteCount;
+ UINT32 ResponseLen;
Status = EFI_SUCCESS;
Base = mI2cBusList[Bus].Base;
@@ -601,6 +675,35 @@ InternalI2cRead (
}
WriteCount = 0;
+ if (mI2cBusList[Bus].IsSmbus) {
+ //
+ // Read Smbus Data Length, first byte of the Smbus response data.
+ //
+ Status = InternalSmbusReadDataLength (Bus, &ResponseLen);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ WriteCount++;
+ Buf[ReadCount++] = ResponseLen;
+
+ //
+ // Abort the transaction when the requested length is shorter than the actual response data
+ // or if there is no response data when PEC disabled.
+ //
+ if ((*Length < (ResponseLen + 2)) || (!mI2cBusList[Bus].PecCheck && ResponseLen == 0)) {
+ MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_CMD | DW_IC_DATA_CMD_STOP);
+ I2cSync ();
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ *Length = ResponseLen + 1; // Response Data Length + 8-bit Byte Count field
+ if (mI2cBusList[Bus].PecCheck) {
+ *Length += 1; // ++ 8-bit PEC field
+ }
+ }
+
while ((*Length - ReadCount) != 0) {
TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
RxLimit = mI2cBusList[Bus].RxFifo - MmioRead32 (Base + DW_IC_RXFLR);
@@ -750,6 +853,9 @@ I2cRead (
@param[in] Bus I2C bus Id.
@param[in] BusSpeed I2C bus speed in Hz.
+ @param[in] IsSmbus Flag to indicate if the bus is used to execute an SMBus operation.
+ @param[in] PecCheck If Packet Error Code (PEC) checking is required for the SMBUS operation
+ and is ignored when present in other operations.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@@ -758,8 +864,10 @@ I2cRead (
EFI_STATUS
EFIAPI
I2cProbe (
- IN UINT32 Bus,
- IN UINTN BusSpeed
+ IN UINT32 Bus,
+ IN UINTN BusSpeed,
+ IN BOOLEAN IsSmbus,
+ IN BOOLEAN PecCheck
)
{
if (Bus >= AC01_I2C_MAX_BUS_NUM
@@ -768,6 +876,9 @@ I2cProbe (
return EFI_INVALID_PARAMETER;
}
+ mI2cBusList[Bus].IsSmbus = IsSmbus;
+ mI2cBusList[Bus].PecCheck = PecCheck;
+
return I2cInit (Bus, BusSpeed);
}
--
2.25.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#120262): https://edk2.groups.io/g/devel/message/120262
Mute This Topic: https://groups.io/mt/107765353/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-08-07 6:50 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-07 6:47 [edk2-devel] [edk2-platforms][PATCH v2 0/5] Add IPMI SSIF support Nhi Pham via groups.io
2024-08-07 6:47 ` Nhi Pham via groups.io [this message]
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 2/5] AmpereSiliconPkg: Define PCDs for SMBUS and BMC Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 3/5] AmpereAltraPkg: Add SmbusHc PEI and DXE drivers Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 4/5] JadePkg: Add PlatformBmcReadyLib to support BMC ready check Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 5/5] Ampere/Jade: Enable IPMI SSIF Nhi Pham via groups.io
2024-08-07 7:16 ` [edk2-devel] [edk2-platforms][PATCH v2 0/5] Add IPMI SSIF support Chang, Abner via groups.io
2024-08-07 7:35 ` Nhi Pham via groups.io
2024-08-09 2:44 ` Chang, Abner via groups.io
2024-08-09 3:05 ` Nhi Pham via groups.io
2024-08-09 4:34 ` Chang, Abner via groups.io
2024-08-07 10:23 ` Leif Lindholm
2024-08-07 10:45 ` Chang, Abner via groups.io
2024-08-07 10:56 ` Leif Lindholm
2024-08-07 10:59 ` Chang, Abner via groups.io
2024-08-08 3:06 ` Nhi Pham via groups.io
[not found] ` <17E9A1ED2D454E7A.19172@groups.io>
2024-08-13 4:16 ` Nhi Pham via groups.io
2024-08-29 5:55 ` Chuong Tran
2024-08-29 7:11 ` Nhi Pham via groups.io
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240807064731.4049764-2-nhi@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox