[EHL] GpioLock update
Issue seen in Yocto RT kernel that PSE GBE0 Transmission. Found out that GPPC_A_5.pmode=0 (RGMII0_TXCTL) which expected to be 0x1. override become 0x0. After investigation these PADCFGLOCK_GPP_A_0 and PADCFGLOCKTX_GPP_A_0 registers should be 0xFFFFFF to lock the GPIO GPPC_A_x to prevent modificaiton to the GPIO. Implemented GpioLock function in GpioLib.c to fix this issue. Signed-off-by: Ong Kok Tong <kok.tong.ong@intel.com>
This commit is contained in:
parent
126a2c5f03
commit
f94decd222
|
@ -751,6 +751,7 @@ BoardInit (
|
|||
if (GetBootMode() != BOOT_ON_FLASH_UPDATE) {
|
||||
UpdatePayloadId ();
|
||||
}
|
||||
GpioLockPads();
|
||||
break;
|
||||
case PostSiliconInit:
|
||||
// Set TSEG base/size PCD
|
||||
|
|
|
@ -25,6 +25,8 @@ typedef struct {
|
|||
//
|
||||
UINT32 OutputState;
|
||||
} GPIO_UNLOCK_HOB_DATA;
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED GPIO_UNLOCK_HOB_DATA *mGpioUnlockData = NULL;
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mGpioUnlockDataRecords = 0;
|
||||
|
||||
/**
|
||||
This procedure will get index of GPIO Unlock HOB structure for selected GroupIndex and DwNum.
|
||||
|
@ -126,6 +128,29 @@ GpioGetUnlockData (
|
|||
return HobDataLength;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This procedure will get pointer to GPIO Unlock data structure.
|
||||
|
||||
@param[out] GpioUnlockData pointer to GPIO Unlock data structure
|
||||
|
||||
@retval Length number of GPIO unlock data records
|
||||
**/
|
||||
STATIC
|
||||
UINT32
|
||||
GpioLocateUnlockData (
|
||||
GPIO_UNLOCK_HOB_DATA **GpioUnlockData
|
||||
)
|
||||
{
|
||||
if (mGpioUnlockData == NULL) {
|
||||
*GpioUnlockData = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*GpioUnlockData = (GPIO_UNLOCK_HOB_DATA *) mGpioUnlockData;
|
||||
return mGpioUnlockDataRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
This procedure stores GPIO group data about pads which PadConfig needs to be unlocked.
|
||||
|
||||
|
@ -213,3 +238,102 @@ GpioStoreGroupDwUnlockOutputData (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This procedure will get GPIO group data with pads, which PadConfig is supposed to be left unlock
|
||||
|
||||
@param[in] GroupIndex GPIO group index
|
||||
@param[in] DwNum DWORD index for a group.
|
||||
For group which has less then 32 pads per group DwNum must be 0.
|
||||
@retval UnlockedPads DWORD bitmask for pads which are going to be left unlocked
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: to be locked, 1: Leave unlocked
|
||||
**/
|
||||
UINT32
|
||||
GpioGetGroupDwUnlockPadConfigMask (
|
||||
IN UINT32 GroupIndex,
|
||||
IN UINT32 DwNum
|
||||
)
|
||||
{
|
||||
GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
|
||||
UINT32 Length;
|
||||
UINT32 Index;
|
||||
|
||||
Length = GpioLocateUnlockData (&GpioUnlockData);
|
||||
if (Length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Index = GpioUnlockDataIndex (GroupIndex, DwNum);
|
||||
if (Index >= Length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GpioUnlockData[Index].PadConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
This procedure will get GPIO group data with pads, which Output is supposed to be left unlock
|
||||
|
||||
@param[in] GroupIndex GPIO group index
|
||||
@param[in] DwNum DWORD index for a group.
|
||||
For group which has less then 32 pads per group DwNum must be 0.
|
||||
@retval UnlockedPads DWORD bitmask for pads which are going to be left unlocked
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: to be locked, 1: Leave unlocked
|
||||
**/
|
||||
UINT32
|
||||
GpioGetGroupDwUnlockOutputMask (
|
||||
IN UINT32 GroupIndex,
|
||||
IN UINT32 DwNum
|
||||
)
|
||||
{
|
||||
GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
|
||||
UINT32 Length;
|
||||
UINT32 Index;
|
||||
|
||||
Length = GpioLocateUnlockData (&GpioUnlockData);
|
||||
if (Length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Index = GpioUnlockDataIndex (GroupIndex, DwNum);
|
||||
if (Index >= Length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GpioUnlockData[Index].OutputState;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is to be used In GpioLockPads() to override a lock request by SOC code.
|
||||
|
||||
@param[in] Group GPIO group
|
||||
@param[in] DwNum Register number for current group (parameter applicable in accessing whole register).
|
||||
For group which has less then 32 pads per group DwNum must be 0.
|
||||
@param[out] *UnlockCfgPad DWORD bitmask for pads which are going to be left unlocked
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: to be locked, 1: Leave unlocked
|
||||
@param[out] *UnlockTxPad DWORD bitmask for pads which are going to be left unlocked
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: to be locked, 1: Leave unlocked
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid input parameter
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioUnlockOverride (
|
||||
IN GPIO_GROUP Group,
|
||||
IN UINT32 DwNum,
|
||||
OUT UINT32 *UnlockCfgPad,
|
||||
OUT UINT32 *UnlockTxPad
|
||||
)
|
||||
{
|
||||
|
||||
if ((UnlockCfgPad == NULL) || (UnlockTxPad == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*UnlockCfgPad = 0;
|
||||
*UnlockTxPad = 0;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -531,6 +531,64 @@ GpioUnlockPadCfgForGroupDw (
|
|||
DwNum,
|
||||
~PadsToUnlock,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This procedure will set PadCfgLock for selected pads within one group
|
||||
|
||||
@param[in] Group GPIO group
|
||||
@param[in] DwNum PadCfgLock register number for current group.
|
||||
For group which has less then 32 pads per group DwNum must be 0.
|
||||
@param[in] PadsToLock Bitmask for pads which are going to be locked
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: DoNotLock, 1: Lock
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioLockPadCfgForGroupDw (
|
||||
IN GPIO_GROUP Group,
|
||||
IN UINT32 DwNum,
|
||||
IN UINT32 PadsToLock
|
||||
)
|
||||
{
|
||||
if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return GpioWriteLockReg (
|
||||
GpioPadConfigLockRegister,
|
||||
Group,
|
||||
DwNum,
|
||||
~0u,
|
||||
PadsToLock
|
||||
);
|
||||
}
|
||||
/**
|
||||
This procedure will set PadCfgLock for selected pad
|
||||
|
||||
@param[in] GpioPad GPIO pad
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid group or pad number
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioLockPadCfg (
|
||||
IN GPIO_PAD GpioPad
|
||||
)
|
||||
{
|
||||
GPIO_GROUP Group;
|
||||
UINT32 PadNumber;
|
||||
|
||||
Group = GpioGetGroupFromGpioPad (GpioPad);
|
||||
PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
|
||||
|
||||
return GpioLockPadCfgForGroupDw (
|
||||
Group,
|
||||
GPIO_GET_DW_NUM (PadNumber),
|
||||
1 << GPIO_GET_PAD_POSITION (PadNumber)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -568,6 +626,64 @@ GpioUnlockPadCfgTxForGroupDw (
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This procedure will set PadCfgLockTx for selected pads within one group
|
||||
|
||||
@param[in] Group GPIO group
|
||||
@param[in] DwNum PadCfgLock register number for current group.
|
||||
For group which has less then 32 pads per group DwNum must be 0.
|
||||
@param[in] PadsToLockTx Bitmask for pads which are going to be locked,
|
||||
Bit position - PadNumber
|
||||
Bit value - 0: DoNotLockTx, 1: LockTx
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioLockPadCfgTxForGroupDw (
|
||||
IN GPIO_GROUP Group,
|
||||
IN UINT32 DwNum,
|
||||
IN UINT32 PadsToLockTx
|
||||
)
|
||||
{
|
||||
if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return GpioWriteLockReg (
|
||||
GpioPadLockOutputRegister,
|
||||
Group,
|
||||
DwNum,
|
||||
~0u,
|
||||
PadsToLockTx
|
||||
);
|
||||
}
|
||||
/**
|
||||
This procedure will set PadCfgLockTx for selected pad
|
||||
|
||||
@param[in] GpioPad GPIO pad
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid group or pad number
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioLockPadCfgTx (
|
||||
IN GPIO_PAD GpioPad
|
||||
)
|
||||
{
|
||||
GPIO_GROUP Group;
|
||||
UINT32 PadNumber;
|
||||
|
||||
Group = GpioGetGroupFromGpioPad (GpioPad);
|
||||
PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
|
||||
|
||||
return GpioLockPadCfgTxForGroupDw (
|
||||
Group,
|
||||
GPIO_GET_DW_NUM (PadNumber),
|
||||
1 << GPIO_GET_PAD_POSITION (PadNumber)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This function gets Group to GPE0 configuration
|
||||
|
||||
|
@ -657,3 +773,59 @@ GpioGetGroupDwToGpeDwX (
|
|||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
/**
|
||||
This procedure is used to lock all GPIO pads except the ones
|
||||
which were requested during their configuration to be left unlocked.
|
||||
This function must be called before BIOS_DONE - before POSTBOOT_SAI is enabled.
|
||||
FSP - call this function from wrapper before transition to FSP-S
|
||||
UEFI/EDK - call this function before EndOfPei event
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully
|
||||
@retval EFI_INVALID_PARAMETER Invalid group or pad number
|
||||
**/
|
||||
EFI_STATUS
|
||||
GpioLockPads (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 DwNum;
|
||||
GPIO_GROUP Group;
|
||||
GPIO_GROUP GroupMin;
|
||||
GPIO_GROUP GroupMax;
|
||||
UINT32 UnlockedPads;
|
||||
UINT32 OverrideCfgPads;
|
||||
UINT32 OverrideTxPads;
|
||||
EFI_STATUS Status;
|
||||
|
||||
GroupMin = GpioGetLowestGroup ();
|
||||
GroupMax = GpioGetHighestGroup ();
|
||||
|
||||
for (Group = GroupMin; Group <= GroupMax; Group++) {
|
||||
for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
|
||||
OverrideCfgPads = 0;
|
||||
OverrideTxPads = 0;
|
||||
Status = GpioUnlockOverride (Group, DwNum, &OverrideCfgPads, &OverrideTxPads);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UnlockedPads = GpioGetGroupDwUnlockPadConfigMask (GpioGetGroupIndexFromGroup (Group), DwNum);
|
||||
|
||||
Status = GpioLockPadCfgForGroupDw (Group, DwNum, (UINT32)~(UnlockedPads | OverrideCfgPads));
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UnlockedPads = GpioGetGroupDwUnlockOutputMask (GpioGetGroupIndexFromGroup (Group), DwNum);
|
||||
|
||||
Status = GpioLockPadCfgTxForGroupDw (Group, DwNum, (UINT32)~(UnlockedPads | OverrideTxPads));
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue