From: "Leif Lindholm" <leif@nuviainc.com>
To: Nhi Pham <nhi@os.amperecomputing.com>
Cc: devel@edk2.groups.io, Vu Nguyen <vunguyen@os.amperecomputing.com>,
Thang Nguyen <thang@os.amperecomputing.com>,
Chuong Tran <chuong@os.amperecomputing.com>,
Phong Vo <phong@os.amperecomputing.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: Re: [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library
Date: Sat, 5 Jun 2021 00:21:41 +0100 [thread overview]
Message-ID: <20210604232141.asjuirz52gxvis7a@leviathan> (raw)
In-Reply-To: <20210526100724.5359-7-nhi@os.amperecomputing.com>
On Wed, May 26, 2021 at 17:06:57 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>
> The DwI2cLib library provides basic functions to control the I2C
> controller on Ampere Altra processor.
>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
(but I think this was one of the ones that have issues that should be
addressed - please ensure build with CLANG38 before v3)
/
Leif
> ---
> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 +
> Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf | 38 +
> Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h | 100 +++
> Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c | 883 ++++++++++++++++++++
> 4 files changed, 1024 insertions(+)
>
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 73097afaf841..8be6a329bb26 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -28,6 +28,9 @@ [LibraryClasses]
> ## @libraryclass Defines a set of methods to communicate with SCP.
> SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
>
> + ## @libraryclass Defines a set of methods to read/write to I2C devices.
> + I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> +
> ## @libraryclass Defines a set of methods to communicate with secure parition over MM interface.
> MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> new file mode 100644
> index 000000000000..091f5f9b310c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Component description for DwI2cLib library for the Designware I2C controller.
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001B
> + BASE_NAME = DwI2cLib
> + FILE_GUID = 222609E2-C181-11E6-A4A6-CEC0C932CE01
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = I2cLib
> + CONSTRUCTOR = I2cLibConstructor
> +
> +[Sources]
> + DwI2cLib.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + ArmPlatformPkg/ArmPlatformPkg.dec
> + MdePkg/MdePkg.dec
> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + HobLib
> + IoLib
> + TimerLib
> +
> +[Guids]
> + gEfiEventVirtualAddressChangeGuid
> + gPlatformHobGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> new file mode 100644
> index 000000000000..f13794171029
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> @@ -0,0 +1,100 @@
> +/** @file
> + Library implementation for the Designware I2C controller.
> +
> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef I2C_LIB_H_
> +#define I2C_LIB_H_
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +/**
> + Write to I2C bus.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] SlaveAddr The address of slave device on the bus.
> + @param[in,out] Buf Buffer that holds data to write.
> + @param[in,out] WriteLength Pointer to length of buffer.
> +
> + @return EFI_SUCCESS Write successfully.
> + @return EFI_INVALID_PARAMETER A parameter is invalid.
> + @return EFI_UNSUPPORTED The bus is not supported.
> + @return EFI_NOT_READY The device/bus is not ready.
> + @return EFI_TIMEOUT Timeout why transferring data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWrite (
> + IN UINT32 Bus,
> + IN UINT32 SlaveAddr,
> + IN OUT UINT8 *Buf,
> + IN OUT UINT32 *WriteLength
> + );
> +
> +/**
> + Read data from I2C bus.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] SlaveAddr The address of slave device on the bus.
> + @param[in] BufCmd Buffer where to send the command.
> + @param[in] CmdLength Pointer to length of BufCmd.
> + @param[in,out] Buf Buffer where to put the read data to.
> + @param[in,out] ReadLength Pointer to length of buffer.
> +
> + @return EFI_SUCCESS Read successfully.
> + @return EFI_INVALID_PARAMETER A parameter is invalid.
> + @return EFI_UNSUPPORTED The bus is not supported.
> + @return EFI_NOT_READY The device/bus is not ready.
> + @return EFI_TIMEOUT Timeout why transferring data.
> + @return EFI_CRC_ERROR There are errors on receiving data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cRead (
> + IN UINT32 Bus,
> + IN UINT32 SlaveAddr,
> + IN UINT8 *BufCmd,
> + IN UINT32 CmdLength,
> + IN OUT UINT8 *Buf,
> + IN OUT UINT32 *ReadLength
> + );
> +
> +/**
> + Setup new transaction with I2C slave device.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] BusSpeed I2C bus speed in Hz.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cProbe (
> + IN UINT32 Bus,
> + IN UINTN BusSpeed
> + );
> +
> +/**
> + Setup a bus that to be used in runtime service.
> +
> + @param[in] Bus I2C bus Id.
> +
> + @retval EFI_SUCCESS Success.
> + @retval Otherwise Error code.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cSetupRuntime (
> + IN UINT32 Bus
> + );
> +
> +#endif /* I2C_LIB_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
> new file mode 100644
> index 000000000000..5e7cd020223c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
> @@ -0,0 +1,883 @@
> +/** @file
> +
> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/I2cLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <PlatformInfoHob.h>
> +
> +#define I2cSync() { asm volatile ("dmb ish" : : : "memory"); }
> +
> +//
> +// Runtime needs to be 64K alignment
> +//
> +#define RUNTIME_ADDRESS_MASK (~(SIZE_64KB - 1))
> +#define RUNTIME_ADDRESS_LENGTH SIZE_64KB
> +
> +//
> +// Private I2C bus data
> +//
> +typedef struct {
> + UINTN Base;
> + UINT32 BusSpeed;
> + UINT32 RxFifo;
> + UINT32 TxFifo;
> + UINT32 PollingTime;
> + UINT32 Enabled;
> +} DW_I2C_CONTEXT_T;
> +
> +//
> +// I2C SCL counter macros
> +//
> +typedef enum {
> + I2cSpeedModeStandard = 0,
> + I2cSpeedModeFast,
> +} I2C_SPEED_MODE;
> +
> +#define DW_I2C_MAXIMUM_SPEED_HZ 400000
> +
> +typedef enum {
> + I2cSclSpkLen = 0,
> + I2cSclHcnt,
> + I2cSclLcnt,
> +} I2C_SCL_PARAM;
> +
> +STATIC UINT32 I2cSclParam[][3] = {
> + /* SPK_LEN, HCNT, LCNT */
> + [I2cSpeedModeStandard] = { 10, 0x3E2, 0x47D }, // SS (Standard Speed)
> + [I2cSpeedModeFast] = { 10, 0xA4, 0x13F }, // FS (Fast Speed)
> +};
> +
> +STATIC BOOLEAN mI2cRuntimeEnableArray[MAX_PLATFORM_I2C_BUS_NUM] = {FALSE};
> +STATIC UINTN mI2cBaseArray[MAX_PLATFORM_I2C_BUS_NUM] = {PLATFORM_I2C_REGISTER_BASE};
> +STATIC DW_I2C_CONTEXT_T mI2cBusList[MAX_PLATFORM_I2C_BUS_NUM];
> +STATIC UINTN mI2cClock = 0;
> +STATIC EFI_EVENT mVirtualAddressChangeEvent = NULL;
> +
> +//
> +// Registers
> +//
> +#define DW_IC_CON 0x0
> +#define DW_IC_CON_MASTER BIT0
> +#define DW_IC_CON_SPEED_STD BIT1
> +#define DW_IC_CON_SPEED_FAST BIT2
> +#define DW_IC_CON_10BITADDR_MASTER BIT4
> +#define DW_IC_CON_RESTART_EN BIT5
> +#define DW_IC_CON_SLAVE_DISABLE BIT6
> +#define DW_IC_TAR 0x4
> +#define DW_IC_TAR_10BITS BIT12
> +#define DW_IC_SAR 0x8
> +#define DW_IC_DATA_CMD 0x10
> +#define DW_IC_DATA_CMD_RESTART BIT10
> +#define DW_IC_DATA_CMD_STOP BIT9
> +#define DW_IC_DATA_CMD_CMD BIT8
> +#define DW_IC_DATA_CMD_DAT_MASK 0xFF
> +#define DW_IC_SS_SCL_HCNT 0x14
> +#define DW_IC_SS_SCL_LCNT 0x18
> +#define DW_IC_FS_SCL_HCNT 0x1c
> +#define DW_IC_FS_SCL_LCNT 0x20
> +#define DW_IC_HS_SCL_HCNT 0x24
> +#define DW_IC_HS_SCL_LCNT 0x28
> +#define DW_IC_INTR_STAT 0x2c
> +#define DW_IC_INTR_MASK 0x30
> +#define DW_IC_INTR_RX_UNDER BIT0
> +#define DW_IC_INTR_RX_OVER BIT1
> +#define DW_IC_INTR_RX_FULL BIT2
> +#define DW_IC_INTR_TX_EMPTY BIT4
> +#define DW_IC_INTR_TX_ABRT BIT6
> +#define DW_IC_INTR_ACTIVITY BIT8
> +#define DW_IC_INTR_STOP_DET BIT9
> +#define DW_IC_INTR_START_DET BIT10
> +#define DW_IC_ERR_CONDITION \
> + (DW_IC_INTR_RX_UNDER | DW_IC_INTR_RX_OVER | DW_IC_INTR_TX_ABRT)
> +#define DW_IC_RAW_INTR_STAT 0x34
> +#define DW_IC_CLR_INTR 0x40
> +#define DW_IC_CLR_RX_UNDER 0x44
> +#define DW_IC_CLR_RX_OVER 0x48
> +#define DW_IC_CLR_TX_ABRT 0x54
> +#define DW_IC_CLR_ACTIVITY 0x5c
> +#define DW_IC_CLR_STOP_DET 0x60
> +#define DW_IC_CLR_START_DET 0x64
> +#define DW_IC_ENABLE 0x6c
> +#define DW_IC_STATUS 0x70
> +#define DW_IC_STATUS_ACTIVITY BIT0
> +#define DW_IC_STATUS_TFE BIT2
> +#define DW_IC_STATUS_RFNE BIT3
> +#define DW_IC_STATUS_MST_ACTIVITY BIT5
> +#define DW_IC_TXFLR 0x74
> +#define DW_IC_RXFLR 0x78
> +#define DW_IC_SDA_HOLD 0x7c
> +#define DW_IC_TX_ABRT_SOURCE 0x80
> +#define DW_IC_ENABLE_STATUS 0x9c
> +#define DW_IC_COMP_PARAM_1 0xf4
> +#define DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) \
> + ((((x) >> 8) & 0xFF) + 1)
> +#define DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) \
> + ((((x) >> 16) & 0xFF) + 1)
> +#define DW_IC_COMP_TYPE 0xfc
> +#define SB_DW_IC_CON 0xa8
> +#define SB_DW_IC_SCL_TMO_CNT 0xac
> +#define SB_DW_IC_RX_PEC 0xb0
> +#define SB_DW_IC_ACK 0xb4
> +#define SB_DW_IC_FLG 0xb8
> +#define SB_DW_IC_FLG_CLR 0xbc
> +#define SB_DW_IC_INTR_STAT 0xc0
> +#define SB_DW_IC_INTR_STAT_MASK 0xc4
> +#define SB_DW_IC_DEBUG_SEL 0xec
> +#define SB_DW_IC_ACK_DEBUG 0xf0
> +#define DW_IC_FS_SPKLEN 0xa0
> +#define DW_IC_HS_SPKLEN 0xa4
> +
> +//
> +// Timeout interval
> +//
> +// The interval is equal to the 10 times the signaling period
> +// for the highest I2C transfer speed used in the system.
> +//
> +#define DW_POLL_INTERVAL_US(x) (10 * (1000000 / (x)))
> +
> +//
> +// Maximum timeout count
> +//
> +#define DW_MAX_TRANSFER_POLL_COUNT 100000 // Maximum timeout: 10s
> +#define DW_MAX_STATUS_POLL_COUNT 100
> +
> +#define DW_POLL_MST_ACTIVITY_INTERVAL_US 1000 // 1ms
> +#define DW_MAX_MST_ACTIVITY_POLL_COUNT 20
> +
> +/**
> + Initialize I2C Bus
> + **/
> +VOID
> +I2cHWInit (
> + UINT32 Bus
> + )
> +{
> + UINT32 Param;
> +
> + mI2cBusList[Bus].Base = mI2cBaseArray[Bus];
> +
> + Param = MmioRead32 (mI2cBusList[Bus].Base + DW_IC_COMP_PARAM_1);
> +
> + mI2cBusList[Bus].PollingTime = DW_POLL_INTERVAL_US (mI2cBusList[Bus].BusSpeed);
> + mI2cBusList[Bus].RxFifo = DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH (Param);
> + mI2cBusList[Bus].TxFifo = DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH (Param);
> + mI2cBusList[Bus].Enabled = 0;
> +
> + DEBUG ((DEBUG_VERBOSE, "%a: Bus %d, Rx_Buffer %d, Tx_Buffer %d\n",
> + __FUNCTION__,
> + Bus,
> + mI2cBusList[Bus].RxFifo,
> + mI2cBusList[Bus].TxFifo
> + ));
> +}
> +
> +/**
> + Enable or disable I2C Bus
> + */
> +VOID
> +I2cEnable (
> + UINT32 Bus,
> + UINT32 Enable
> + )
> +{
> + UINT32 I2cStatusCnt;
> + UINTN Base;
> +
> + Base = mI2cBusList[Bus].Base;
> + I2cStatusCnt = DW_MAX_STATUS_POLL_COUNT;
> + mI2cBusList[Bus].Enabled = Enable;
> +
> + MmioWrite32 (Base + DW_IC_ENABLE, Enable);
> +
> + do {
> + if ((MmioRead32 (Base + DW_IC_ENABLE_STATUS) & 0x01) == Enable) {
> + break;
> + }
> + MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> + } while (I2cStatusCnt-- != 0);
> +
> + if (I2cStatusCnt == 0) {
> + DEBUG ((DEBUG_ERROR, "%a: Enable/disable timeout\n", __FUNCTION__));
> + }
> +
> + if ((Enable == 0) || (I2cStatusCnt == 0)) {
> + /* Unset the target adddress */
> + MmioWrite32 (Base + DW_IC_TAR, 0);
> + mI2cBusList[Bus].Enabled = 0;
> + }
> +}
> +
> +/**
> + Setup Slave address
> + **/
> +VOID
> +I2cSetSlaveAddr (
> + UINT32 Bus,
> + UINT32 SlaveAddr
> + )
> +{
> + UINTN Base;
> + UINT32 OldEnableStatus;
> +
> + Base = mI2cBusList[Bus].Base;
> + OldEnableStatus = mI2cBusList[Bus].Enabled;
> +
> + I2cEnable (Bus, 0);
> + MmioWrite32 (Base + DW_IC_TAR, SlaveAddr);
> + if (OldEnableStatus != 0) {
> + I2cEnable (Bus, 1);
> + }
> +}
> +
> +/**
> + Check for errors on I2C Bus
> + **/
> +UINT32
> +I2cCheckErrors (
> + UINT32 Bus
> + )
> +{
> + UINTN Base;
> + UINT32 ErrorStatus;
> +
> + Base = mI2cBusList[Bus].Base;
> +
> + ErrorStatus = MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_ERR_CONDITION;
> +
> + if ((ErrorStatus & DW_IC_INTR_RX_UNDER) != 0) {
> + DEBUG ((DEBUG_ERROR, "%a: RX_UNDER error on i2c bus %d error status %08x\n",
> + __FUNCTION__,
> + Bus,
> + ErrorStatus
> + ));
> + MmioRead32 (Base + DW_IC_CLR_RX_UNDER);
> + }
> +
> + if ((ErrorStatus & DW_IC_INTR_RX_OVER) != 0) {
> + DEBUG ((DEBUG_ERROR, "%a: RX_OVER error on i2c bus %d error status %08x\n",
> + __FUNCTION__,
> + Bus,
> + ErrorStatus
> + ));
> + MmioRead32 (Base + DW_IC_CLR_RX_OVER);
> + }
> +
> + if ((ErrorStatus & DW_IC_INTR_TX_ABRT) != 0) {
> + DEBUG ((DEBUG_VERBOSE, "%a: TX_ABORT at source %08x\n",
> + __FUNCTION__,
> + MmioRead32 (Base + DW_IC_TX_ABRT_SOURCE)
> + ));
> + MmioRead32 (Base + DW_IC_CLR_TX_ABRT);
> + }
> +
> + return ErrorStatus;
> +}
> +
> +/**
> + Waiting for bus to not be busy
> + **/
> +BOOLEAN
> +I2cWaitBusNotBusy (
> + UINT32 Bus
> + )
> +{
> + UINTN Base;
> + UINTN PollCount;
> +
> + Base = mI2cBusList[Bus].Base;
> + PollCount = DW_MAX_MST_ACTIVITY_POLL_COUNT;
> +
> + while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_MST_ACTIVITY) != 0) {
> + if (PollCount == 0) {
> + DEBUG ((DEBUG_VERBOSE, "%a: Timeout while waiting for bus ready\n", __FUNCTION__));
> + return FALSE;
> + }
> + PollCount--;
> + /*
> + * A delay isn't absolutely necessary.
> + * But to ensure that we don't hammer the bus constantly,
> + * delay for DW_POLL_MST_ACTIVITY_INTERVAL_US as with other implementation.
> + */
> + MicroSecondDelay (DW_POLL_MST_ACTIVITY_INTERVAL_US);
> + }
> +
> + return TRUE;
> +}
> +
> +/**
> + Waiting for TX FIFO buffer available
> + **/
> +EFI_STATUS
> +I2cWaitTxData (
> + UINT32 Bus
> + )
> +{
> + UINTN Base;
> + UINTN PollCount;
> +
> + Base = mI2cBusList[Bus].Base;
> + PollCount = 0;
> +
> + while (MmioRead32 (Base + DW_IC_TXFLR) == mI2cBusList[Bus].TxFifo) {
> + if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
> + DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX buffer available\n", __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> + MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Waiting for RX FIFO buffer available
> + **/
> +EFI_STATUS
> +I2cWaitRxData (
> + UINT32 Bus
> + )
> +{
> + UINTN Base;
> + UINTN PollCount;
> +
> + Base = mI2cBusList[Bus].Base;
> + PollCount = 0;
> +
> + while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_RFNE) == 0) {
> + if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
> + DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for RX buffer available\n", __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> +
> + if ((I2cCheckErrors (Bus) & DW_IC_INTR_TX_ABRT) != 0) {
> + return EFI_ABORTED;
> + }
> +
> + MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Initialize the Designware I2C SCL Counts
> +
> + This functions configures SCL clock Count for Standard Speed (SS) and Fast Speed (FS) mode.
> + **/
> +VOID
> +I2cSclInit (
> + UINT32 Bus,
> + UINT32 I2cClkFreq,
> + UINT32 I2cSpeed
> + )
> +{
> + UINT16 IcCon;
> + UINTN Base;
> + UINT32 I2cSpeedKhz;
> +
> + Base = mI2cBusList[Bus].Base;
> + I2cSpeedKhz = I2cSpeed / 1000;
> +
> + DEBUG ((DEBUG_VERBOSE, "%a: Bus %d I2cClkFreq %d I2cSpeed %d\n",
> + __FUNCTION__,
> + Bus,
> + I2cClkFreq,
> + I2cSpeed
> + ));
> +
> + IcCon = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN;
> +
> + if (I2cSpeedKhz <= 100) {
> + IcCon |= DW_IC_CON_SPEED_STD;
> + // Standard speed mode
> + MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeStandard][I2cSclSpkLen]);
> + MmioWrite32 (Base + DW_IC_SS_SCL_HCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclHcnt]);
> + MmioWrite32 (Base + DW_IC_SS_SCL_LCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclLcnt]);
> + } else if (I2cSpeedKhz > 100 && I2cSpeedKhz <= 400) {
> + IcCon |= DW_IC_CON_SPEED_FAST;
> + // Fast speed mode
> + MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeFast][I2cSclSpkLen]);
> + MmioWrite32 (Base + DW_IC_FS_SCL_HCNT, I2cSclParam[I2cSpeedModeFast][I2cSclHcnt]);
> + MmioWrite32 (Base + DW_IC_FS_SCL_LCNT, I2cSclParam[I2cSpeedModeFast][I2cSclLcnt]);
> + }
> + MmioWrite32 (Base + DW_IC_CON, IcCon);
> +}
> +
> +/**
> + Initialize the designware i2c master hardware
> + **/
> +EFI_STATUS
> +I2cInit (
> + UINT32 Bus,
> + UINTN BusSpeed
> + )
> +{
> + UINTN Base;
> +
> + ASSERT (mI2cClock != 0);
> +
> + mI2cBusList[Bus].BusSpeed = BusSpeed;
> + I2cHWInit (Bus);
> +
> + Base = mI2cBusList[Bus].Base;
> +
> + /* Disable the adapter and interrupt */
> + I2cEnable (Bus, 0);
> + MmioWrite32 (Base + DW_IC_INTR_MASK, 0);
> +
> + /* Set standard and fast speed divider for high/low periods */
> + I2cSclInit (Bus, mI2cClock, BusSpeed);
> + MmioWrite32 (Base + DW_IC_SDA_HOLD, 0x4b);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Wait the transaction finished
> + **/
> +EFI_STATUS
> +I2cFinish (
> + UINT32 Bus
> + )
> +{
> + UINTN Base;
> + UINTN PollCount;
> +
> + Base = mI2cBusList[Bus].Base;
> + PollCount = 0;
> +
> + /* Wait for TX FIFO empty */
> + do {
> + if ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_TFE) != 0) {
> + break;
> + }
> + MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> + } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
> +
> + if (PollCount >= DW_MAX_TRANSFER_POLL_COUNT) {
> + DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX FIFO empty\n", __FUNCTION__));
> + return EFI_TIMEOUT;
> + }
> +
> + /* Wait for STOP signal detected on the bus */
> + PollCount = 0;
> + do {
> + if ((MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_INTR_STOP_DET) != 0) {
> + MmioRead32 (Base + DW_IC_CLR_STOP_DET);
> + return EFI_SUCCESS;
> + }
> + MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> + } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
> +
> + DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for transaction finished\n", __FUNCTION__));
> + return EFI_TIMEOUT;
> +}
> +
> +EFI_STATUS
> +InternalI2cWrite (
> + UINT32 Bus,
> + UINT8 *Buf,
> + UINT32 *Length
> + )
> +{
> + EFI_STATUS Status;
> + UINTN WriteCount;
> + UINTN Base;
> +
> + Status = EFI_SUCCESS;
> + Base = mI2cBusList[Bus].Base;
> +
> + DEBUG ((DEBUG_VERBOSE, "%a: Write Bus %d Buf %p Length %d\n",
> + __FUNCTION__,
> + Bus,
> + Buf,
> + *Length
> + ));
> + I2cEnable (Bus, 1);
> +
> + WriteCount = 0;
> + while ((*Length - WriteCount) != 0) {
> + Status = I2cWaitTxData (Bus);
> + if (EFI_ERROR (Status)) {
> + MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> + I2cSync ();
> + goto Exit;
> + }
> +
> + if (WriteCount == *Length - 1) {
> + MmioWrite32 (
> + Base + DW_IC_DATA_CMD,
> + (Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK) | DW_IC_DATA_CMD_STOP
> + );
> + } else {
> + MmioWrite32 (
> + Base + DW_IC_DATA_CMD,
> + Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK
> + );
> + }
> + I2cSync ();
> + WriteCount++;
> + }
> +
> +Exit:
> + *Length = WriteCount;
> + I2cFinish (Bus);
> + I2cWaitBusNotBusy (Bus);
> + I2cEnable (Bus, 0);
> +
> + return Status;
> +}
> +
> +EFI_STATUS
> +InternalI2cRead (
> + UINT32 Bus,
> + UINT8 *BufCmd,
> + UINT32 CmdLength,
> + UINT8 *Buf,
> + UINT32 *Length
> + )
> +{
> + EFI_STATUS Status;
> + UINTN Base;
> + UINT32 CmdSend;
> + UINT32 TxLimit, RxLimit;
> + UINTN Idx;
> + UINTN Count;
> + UINTN ReadCount;
> + UINTN WriteCount;
> +
> + Status = EFI_SUCCESS;
> + Base = mI2cBusList[Bus].Base;
> + Count = 0;
> +
> + DEBUG ((DEBUG_VERBOSE, "%a: Read Bus %d Buf %p Length:%d\n",
> + __FUNCTION__,
> + Bus,
> + Buf,
> + *Length
> + ));
> +
> + I2cEnable (Bus, 1);
> +
> + /* Write command data */
> + WriteCount = 0;
> + while (CmdLength != 0) {
> + TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
> + Count = CmdLength > TxLimit ? TxLimit : CmdLength;
> +
> + for (Idx = 0; Idx < Count; Idx++ ) {
> + CmdSend = BufCmd[WriteCount++] & DW_IC_DATA_CMD_DAT_MASK;
> + MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
> + I2cSync ();
> +
> + if (I2cCheckErrors (Bus) != 0) {
> + Status = EFI_CRC_ERROR;
> + goto Exit;
> + }
> + CmdLength--;
> + }
> +
> + Status = I2cWaitTxData (Bus);
> + if (EFI_ERROR (Status)) {
> + MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> + I2cSync ();
> + goto Exit;
> + }
> + }
> +
> + ReadCount = 0;
> + WriteCount = 0;
> + while ((*Length - ReadCount) != 0) {
> + TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
> + RxLimit = mI2cBusList[Bus].RxFifo - MmioRead32 (Base + DW_IC_RXFLR);
> + Count = *Length - ReadCount;
> + Count = Count > RxLimit ? RxLimit : Count;
> + Count = Count > TxLimit ? TxLimit : Count;
> +
> + for (Idx = 0; Idx < Count; Idx++ ) {
> + CmdSend = DW_IC_DATA_CMD_CMD;
> + if (WriteCount == *Length - 1) {
> + CmdSend |= DW_IC_DATA_CMD_STOP;
> + }
> + MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
> + I2cSync ();
> + WriteCount++;
> +
> + if (I2cCheckErrors (Bus) != 0) {
> + DEBUG ((DEBUG_VERBOSE,
> + "%a: Sending reading command remaining length %d CRC error\n",
> + __FUNCTION__,
> + *Length
> + ));
> + Status = EFI_CRC_ERROR;
> + goto Exit;
> + }
> + }
> +
> + for (Idx = 0; Idx < Count; Idx++ ) {
> + Status = I2cWaitRxData (Bus);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_VERBOSE,
> + "%a: Reading remaining length %d failed to wait data\n",
> + __FUNCTION__,
> + *Length
> + ));
> +
> + if (Status != EFI_ABORTED) {
> + MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> + I2cSync ();
> + }
> +
> + goto Exit;
> + }
> +
> + Buf[ReadCount++] = MmioRead32 (Base + DW_IC_DATA_CMD) & DW_IC_DATA_CMD_DAT_MASK;
> + I2cSync ();
> +
> + if (I2cCheckErrors (Bus) != 0) {
> + DEBUG ((DEBUG_VERBOSE, "%a: Reading remaining length %d CRC error\n",
> + __FUNCTION__,
> + *Length
> + ));
> + Status = EFI_CRC_ERROR;
> + goto Exit;
> + }
> + }
> + }
> +
> +Exit:
> + *Length = ReadCount;
> + I2cFinish (Bus);
> + I2cWaitBusNotBusy (Bus);
> + I2cEnable (Bus, 0);
> +
> + return Status;
> +}
> +
> +/**
> + Write to I2C bus.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] SlaveAddr The address of slave device on the bus.
> + @param[in,out] Buf Buffer that holds data to write.
> + @param[in,out] WriteLength Pointer to length of buffer.
> +
> + @return EFI_SUCCESS Write successfully.
> + @return EFI_INVALID_PARAMETER A parameter is invalid.
> + @return EFI_UNSUPPORTED The bus is not supported.
> + @return EFI_NOT_READY The device/bus is not ready.
> + @return EFI_TIMEOUT Timeout why transferring data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWrite (
> + IN UINT32 Bus,
> + IN UINT32 SlaveAddr,
> + IN OUT UINT8 *Buf,
> + IN OUT UINT32 *WriteLength
> + )
> +{
> + if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> + || Buf == NULL
> + || WriteLength == NULL)
> + {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + I2cSetSlaveAddr (Bus, SlaveAddr);
> +
> + return InternalI2cWrite (Bus, Buf, WriteLength);
> +}
> +
> +/**
> + Read data from I2C bus.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] SlaveAddr The address of slave device on the bus.
> + @param[in] BufCmd Buffer where to send the command.
> + @param[in] CmdLength Pointer to length of BufCmd.
> + @param[in,out] Buf Buffer where to put the read data to.
> + @param[in,out] ReadLength Pointer to length of buffer.
> +
> + @return EFI_SUCCESS Read successfully.
> + @return EFI_INVALID_PARAMETER A parameter is invalid.
> + @return EFI_UNSUPPORTED The bus is not supported.
> + @return EFI_NOT_READY The device/bus is not ready.
> + @return EFI_TIMEOUT Timeout why transferring data.
> + @return EFI_CRC_ERROR There are errors on receiving data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cRead (
> + IN UINT32 Bus,
> + IN UINT32 SlaveAddr,
> + IN UINT8 *BufCmd,
> + IN UINT32 CmdLength,
> + IN OUT UINT8 *Buf,
> + IN OUT UINT32 *ReadLength
> + )
> +{
> + if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> + || Buf == NULL
> + || ReadLength == NULL)
> + {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + I2cSetSlaveAddr (Bus, SlaveAddr);
> +
> + return InternalI2cRead (Bus, BufCmd, CmdLength, Buf, ReadLength);
> +}
> +
> +/**
> + Setup new transaction with I2C slave device.
> +
> + @param[in] Bus I2C bus Id.
> + @param[in] BusSpeed I2C bus speed in Hz.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cProbe (
> + IN UINT32 Bus,
> + IN UINTN BusSpeed
> + )
> +{
> + if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> + || BusSpeed > DW_I2C_MAXIMUM_SPEED_HZ)
> + {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return I2cInit (Bus, BusSpeed);
> +}
> +
> +/**
> + * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
> + *
> + * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
> + * It convers pointer to new virtual address.
> + *
> + * @param Event Event whose notification function is being invoked.
> + * @param Context Pointer to the notification function's context.
> + */
> +VOID
> +EFIAPI
> +I2cVirtualAddressChangeEvent (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + UINTN Count;
> +
> + EfiConvertPointer (0x0, (VOID **)&mI2cBusList);
> + EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray);
> + EfiConvertPointer (0x0, (VOID **)&mI2cClock);
> + for (Count = 0; Count < MAX_PLATFORM_I2C_BUS_NUM; Count++) {
> + if (!mI2cRuntimeEnableArray[Count]) {
> + continue;
> + }
> + EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray[Count]);
> + EfiConvertPointer (0x0, (VOID **)&mI2cBusList[Count].Base);
> + }
> +}
> +
> +/**
> + Setup a bus that to be used in runtime service.
> +
> + @param[in] Bus I2C bus Id.
> +
> + @retval EFI_SUCCESS Success.
> + @retval Otherwise Error code.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cSetupRuntime (
> + IN UINT32 Bus
> + )
> +{
> + EFI_STATUS Status;
> + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
> +
> + if (Bus >= MAX_PLATFORM_I2C_BUS_NUM) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (mVirtualAddressChangeEvent == NULL) {
> + /*
> + * Register for the virtual address change event
> + */
> + Status = gBS->CreateEventEx (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + I2cVirtualAddressChangeEvent,
> + NULL,
> + &gEfiEventVirtualAddressChangeGuid,
> + &mVirtualAddressChangeEvent
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + Status = gDS->GetMemorySpaceDescriptor (
> + mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
> + &Descriptor
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = gDS->SetMemorySpaceAttributes (
> + mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
> + RUNTIME_ADDRESS_LENGTH,
> + Descriptor.Attributes | EFI_MEMORY_RUNTIME
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + mI2cRuntimeEnableArray[Bus] = TRUE;
> +
> + return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +I2cLibConstructor (
> + VOID
> + )
> +{
> + VOID *Hob;
> + PLATFORM_INFO_HOB *PlatformHob;
> +
> + /* Get I2C Clock from the Platform HOB */
> + Hob = GetFirstGuidHob (&gPlatformHobGuid);
> + if (Hob == NULL) {
> + return EFI_NOT_FOUND;
> + }
> + PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> + mI2cClock = PlatformHob->AhbClk;
> + ASSERT (mI2cClock != 0);
> +
> + return EFI_SUCCESS;
> +}
> --
> 2.17.1
>
next prev parent reply other threads:[~2021-06-04 23:21 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-06-04 23:04 ` Leif Lindholm
2021-06-09 4:50 ` Nhi Pham
2021-06-09 12:40 ` Leif Lindholm
2021-06-15 16:46 ` Nhi Pham
2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
2021-05-26 10:23 ` [edk2-devel] " Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
2021-06-04 23:05 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
2021-06-04 23:07 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
2021-06-04 23:12 ` Leif Lindholm
2021-06-15 16:47 ` Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
2021-06-04 23:21 ` Leif Lindholm [this message]
2021-06-15 16:47 ` Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
2021-06-04 23:22 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-06-04 23:26 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-06-04 23:27 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
2021-06-04 23:36 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-06-04 23:37 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
2021-06-04 23:44 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
2021-06-04 23:47 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-06-04 23:50 ` Leif Lindholm
2021-06-15 16:49 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
2021-06-05 0:05 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
2021-06-07 22:45 ` Leif Lindholm
2021-06-15 16:50 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
2021-06-08 22:26 ` Leif Lindholm
2021-06-09 5:29 ` Ard Biesheuvel
2021-06-15 15:54 ` Nhi Pham
2021-06-16 14:20 ` Ard Biesheuvel
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
2021-06-07 22:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-06-07 22:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-06-08 11:13 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
2021-06-07 23:00 ` Leif Lindholm
2021-06-15 16:51 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-06-07 23:08 ` Leif Lindholm
2021-06-15 16:51 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-06-07 23:10 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
2021-06-07 23:14 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-06-07 23:15 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-06-07 23:20 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-06-07 23:22 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-06-07 23:24 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
2021-06-07 23:34 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
2021-06-07 23:46 ` Leif Lindholm
2021-06-15 16:52 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
2021-06-07 23:50 ` Leif Lindholm
2021-06-09 15:21 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
2021-06-07 23:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
2021-06-07 23:58 ` Leif Lindholm
2021-06-09 15:20 ` Nhi Pham
2021-05-27 12:56 ` [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. " Leif Lindholm
2021-06-04 13:54 ` Leif Lindholm
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=20210604232141.asjuirz52gxvis7a@leviathan \
--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