alder_lake_bios/Intel/AlderLake/AlderLakeBoardPkg/Library/PeiBoardConfigLib/PeiBoardConfigLib.c

763 lines
26 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2020, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
/** @file
Implementation of PeiBoardConfigLib.
@copyright
INTEL CONFIDENTIAL
Copyright 2015 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <PiPei.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/PostCodeLib.h>
#include <Library/TimerLib.h>
#include <Library/EcMiscLib.h>
#include <Library/PeiDxeBoardIdsLib.h>
#include <Library/GpioLib.h>
#include <PlatformBoardType.h>
#include <PlatformBoardId.h>
#include <PlatformBoardConfig.h>
#include <OemSetup.h>
#include <SetupVariable.h>
#include <Ppi/ReadOnlyVariable2.h>
#include <Library/PeiServicesLib.h>
#include <Library/SiliconInitLib.h>
#include <Library/PmcLib.h>
#include <Guid/BootStateCapsule.h>
#include <Library/BoardConfigLib.h>
#include <BootStateLib.h>
#define STALL_TIME 1000000 // 1,000,000 microseconds = 1 second
//[-start-200910-IB17040158-add]//
typedef struct{
UINT16 BoardId;
UINT16 MaxGpioPins;
} BOARD_ID_TO_GPIO_MAX_PIN_MAP;
BOARD_ID_TO_GPIO_MAX_PIN_MAP mAdlBoardIdToGpioMaxPinMap[] = {
{ AdlSSkuType, 255 }, // According Document number: 618659
{ AdlPSkuType, 169 }, // According Document number: 627075
{ AdlMSkuType, 162 }, // According Document number: 627075
};
UINT8 mAdlBoardIdToGpioMaxPinMapSize = ARRAY_SIZE (mAdlBoardIdToGpioMaxPinMap);
//[-end-200910-IB17040158-add]//
/**
Returns the BoardId ID of the platform from the EC for Mobile.
@param[in] BoardId BoardId ID as determined through the EC.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR EC fails to respond.
**/
EFI_STATUS
EFIAPI
InternalGetBoardId (
OUT UINT16 *BoardId
)
{
EFI_STATUS Status;
BOARD_ID_INFO EcBoardInfo;
Status = EFI_SUCCESS;
//
// Return BoardIdUnknown1 in case of error.
//
*BoardId = BoardIdUnknown1;
EcBoardInfo.Raw = 0;
Status = GetBoardInfo ((UINT16 *)&EcBoardInfo);
DEBUG ((DEBUG_INFO, "Raw Board ID from EC is 0x%x\n", EcBoardInfo.Raw));
if (Status == EFI_SUCCESS) {
*BoardId = (UINT16)EcBoardInfo.TglRvpFields.BoardId;
*BoardId &= 0x03F;
PcdSet16S (PcdBoardId, (UINT16) (EcBoardInfo.TglRvpFields.BoardId));
PcdSet16S (PcdBoardBomId, (UINT16) (EcBoardInfo.TglRvpFields.BomId));
PcdSet16S (PcdBoardRev, (UINT16) (EcBoardInfo.TglRvpFields.FabId));
PcdSetBoolS (PcdSpdPresent, (BOOLEAN) (EcBoardInfo.TglRvpFields.SpdPresent));
PcdSet16S (PcdDisplayId, (UINT16) ((EcBoardInfo.TglRvpFields.DdiAConfig) | (EcBoardInfo.TglRvpFields.DdiBConfig << BIT0) | (EcBoardInfo.TglRvpFields.DdiBDisplay << BIT1)));
DEBUG ((DEBUG_INFO, "Fields.BoardId from EC is 0x%x\n", PcdGet16 (PcdBoardId)));
DEBUG ((DEBUG_INFO, "Fields.BomId from EC is 0x%x\n", PcdGet16 (PcdBoardBomId)));
DEBUG ((DEBUG_INFO, "Fields.FabId from EC is 0x%x\n", PcdGet16 (PcdBoardRev)));
DEBUG ((DEBUG_INFO, "Fields.SpdPresent from EC = %x\n", PcdGetBool (PcdSpdPresent)));
DEBUG ((DEBUG_INFO, "Fields.Display ID from EC = %x\n", PcdGet16 (PcdDisplayId)));
} else {
DEBUG ((DEBUG_ERROR, "Failed to get Board ID from EC\n"));
}
return Status;
}
VOID
EFIAPI
InternalUpdateRvpBoardConfig (
IN OUT UINT16 BoardId
)
{
UINTN Size;
UINT8 BoardType;
UINT8 PlatformType;
UINT8 PlatformFlavor;
if (BoardId < mSizeOfmBoardIndex) {
Size = StrSize (mBoardIdIndex[BoardId]);
PcdSetPtrS (PcdBoardName, &Size, mBoardIdIndex[BoardId]);
}
//
// Update Board Type/Platform Type/Platform Flavor
//
switch (BoardId) {
case BoardIdAdlPSimics:
BoardType = BoardTypeRvp;
PlatformType = TypeUltUlx;
PlatformFlavor = FlavorMobile;
if(PcdSet64S(PcdAcpiDefaultOemTableId, ACPI_OEM_TABLE_ID_TGL_ULT) != EFI_SUCCESS)
{
DEBUG ((DEBUG_INFO, "Set PcdAcpiDefaultOemTableId error!!!\n"));
}
break;
case BoardIdAdlSTgpHDdr4SODimm1DCrb:
BoardType = BoardTypeRvp;
PlatformType = TypeTrad;
PlatformFlavor = FlavorMobile;
if(PcdSet64S(PcdAcpiDefaultOemTableId, ACPI_OEM_TABLE_ID_TGL_ULT) != EFI_SUCCESS)
{
DEBUG ((DEBUG_INFO, "Set PcdAcpiDefaultOemTableId error!!!\n"));
}
break;
case BoardIdAdlSAdpSDdr4UDimm2DCrb:
case BoardIdAdlSAdpSDdr4UDimm2DCrbEv:
case BoardIdAdlSAdpSDdr4UDimm2DCrbCpv:
case BoardIdAdlSAdpSDdr5UDimm1DCrb:
case BoardIdAdlSAdpSDdr5UDimm1DCrbPpv:
case BoardIdAdlSAdpSDdr5UDimm2DCrb:
case BoardIdAdlSAdpSDdr5SODimmCrb:
case BoardIdAdlSAdpSDdr4SODimmCrb:
case BoardIdAdlSAdpSDdr5UDimm1DAep:
case BoardIdAdlSAdpSDdr5UDimm1DOc:
case BoardIdAdlSAdpSDdr5UDimm1DSr:
case BoardIdAdlSAdpSSbgaDdr4SODimmCrb:
BoardType = BoardTypeRvp;
PlatformType = TypeTrad;
PlatformFlavor = FlavorDesktop;
if(PcdSet64S (PcdAcpiDefaultOemTableId, ACPI_OEM_TABLE_ID_ADL) != EFI_SUCCESS)
{
DEBUG ((DEBUG_INFO, "Set PcdAcpiDefaultOemTableId error!!!\n"));
}
break;
case BoardIdAdlSAdpSSbgaDdr5SODimmErb:
case BoardIdAdlSAdpSSbgaDdr5SODimmCrb:
case BoardIdAdlSAdpSSbgaDdr5SODimmAep:
BoardType = BoardTypeRvp;
PlatformType = TypeTrad;
PlatformFlavor = FlavorMobileWorkstation;
if(PcdSet64S(PcdAcpiDefaultOemTableId, ACPI_OEM_TABLE_ID_ADL) != EFI_SUCCESS)
{
DEBUG ((DEBUG_INFO, "Set PcdAcpiDefaultOemTableId error!!!\n"));
}
break;
case BoardIdAdlPLp4Rvp:
case BoardIdAdlPLp5Rvp:
case BoardIdAdlPT3Lp5Rvp:
case BoardIdAdlPDdr5Rvp:
case BoardIdAdlPDdr4Rvp:
case BoardIdAdlPDdr5MRRvp:
case BoardIdAdlPLp4Bep:
case BoardIdAdlPLp5Aep:
case BoardIdAdlPLp5Dg128Aep:
case BoardIdAdlPDdr5Dg384Aep:
case BoardIdAdlPLp5MbAep:
case BoardIdAdlMLp4Rvp:
case BoardIdAdlMLp5Rvp:
case BoardIdAdlMLp5Rvp2a:
case BoardIdAdlMLp5PmicRvp:
case BoardIdAdlMLp5Aep:
case BoardIdAdlPMMAep:
case BoardIdAdlPLp5Gcs:
BoardType = BoardTypeRvp;
PlatformType = TypeUltUlx;
PlatformFlavor = FlavorMobile;
if(PcdSet64S (PcdAcpiDefaultOemTableId, ACPI_OEM_TABLE_ID_ADL_P_M) != EFI_SUCCESS)
{
DEBUG ((DEBUG_INFO, "Set PcdAcpiDefaultOemTableId error!!!\n"));
}
break;
default:
BoardType = BoardTypeRvp;
PlatformType = TypeUnknown;
PlatformFlavor = FlavorUnknown;
break;
}
PcdSet8S (PcdBoardType, BoardType);
PcdSet8S (PcdPlatformType, PlatformType);
PcdSet8S (PcdPlatformFlavor, PlatformFlavor);
DEBUG ((DEBUG_INFO, "PcdAcpiDefaultOemTableId is 0x%llX\n", PcdGet64 (PcdAcpiDefaultOemTableId)));
}
/**
This function call checks if valid Board information is available in the stored region
on the previous boot and restores them.
@retval TRUE Valid Board information is available and restored successfully.
@retval FALSE No valid Board information found.
**/
BOOLEAN
IsValidBoardInformationStored (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
UINTN Size;
BOARD_INFO_SETUP BoardInfoSetup;
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&VariablePpi
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : Read Only Variable PPI is not found.\n"));
return FALSE;
}
//
// 1. Check if Board information variables are available in NV storage.
// @todo decouple Board information variables from BOARD_INFO_SETUP.
Size = sizeof (BOARD_INFO_SETUP);
Status = VariablePpi->GetVariable (
VariablePpi,
L"BoardInfoSetup",
&gBoardInfoVariableGuid,
NULL,
&Size,
&BoardInfoSetup
);
if (!EFI_ERROR (Status) && (BoardInfoSetup.BoardId != BoardIdUnknown1) && (BoardInfoSetup.BoardId != 0)) {
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : Found Board information variables in NV storage.\n"));
} else {
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : Board information variables are not stored in NV storage.\n"));
return FALSE;
}
//
// 2. Check if this is NOT the first boot after BIOS/EC update by Capsule update.
//
#if FixedPcdGetBool(PcdCapsuleEnable) == 1
UINT8 BootStateAfterCapsule;
BootStateAfterCapsule = TRUE;
Status = GetBootStateAfterCapsule(&BootStateAfterCapsule);
if (EFI_ERROR (Status) || BootStateAfterCapsule) {
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : BootStateAfterCapsule variable is not present or TRUE.\n"));
DEBUG ((DEBUG_INFO, "This is the very first boot after BIOS flash or Capsule update for EC/BIOS.\n"));
return FALSE;
}
#endif
//
// 3. Check if this is NOT the first boot after RTC clear.
// Technically Board information variables are not impacted by RTC clear, but check for fail safe to force to read EC.
if (!PmcIsRtcBatteryGood ()) {
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : This is the very first boot after RTC clear.\n"));
return FALSE;
}
/*
Note : The check logic #1-#3 do not capture the following scenario. Recommendation is to do RTC clear to support those.
- EC is updated by flash programming tool.
- HW rework is performed on the board for BomId, FabId or BoardID update.
*/
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : Valid Board information is available.\n"));
//
// Restore the valid Board information to PCDs
//
DEBUG ((DEBUG_INFO, "IsValidBoardInformationStored : Restoring Board information.\n"));
PcdSetBoolS (PcdEcPresent, BoardInfoSetup.EcPresent);
PcdSet8S (PcdEcEspiFlashSharingMode, BoardInfoSetup.EcEspiFlashSharingMode);
PcdSet8S (PcdEcPeciMode, BoardInfoSetup.EcPeciMode);
PcdSet8S (PcdEcMajorRevision, BoardInfoSetup.EcMajorRevision);
PcdSet8S (PcdEcMinorRevision, BoardInfoSetup.EcMinorRevision);
DEBUG ((DEBUG_INFO, " +==============================================+\n"));
DEBUG ((DEBUG_INFO, " | EC Major Revision: %02X EC Minor Revision: %02X |\n", BoardInfoSetup.EcMajorRevision, BoardInfoSetup.EcMinorRevision));
DEBUG ((DEBUG_INFO, " +==============================================+\n"));
PcdSet16S (PcdBoardId, BoardInfoSetup.BoardId);
PcdSet16S (PcdBoardBomId, BoardInfoSetup.BoardBomId);
PcdSet16S (PcdBoardRev, BoardInfoSetup.FabId);
PcdSetBoolS (PcdSpdPresent, BoardInfoSetup.SpdPresent);
PcdSet8S (PcdPlatformGeneration, BoardInfoSetup.PlatformGeneration);
PcdSet16S (PcdDisplayId, BoardInfoSetup.DisplayId);
DEBUG ((DEBUG_INFO, " BoardId is 0x%x\n", PcdGet16 (PcdBoardId)));
DEBUG ((DEBUG_INFO, " BomId is 0x%x\n" , PcdGet16 (PcdBoardBomId)));
DEBUG ((DEBUG_INFO, " FabId is 0x%x\n" , PcdGet16 (PcdBoardRev)));
DEBUG ((DEBUG_INFO, " SpdPresent = %x\n", PcdGetBool (PcdSpdPresent)));
DEBUG ((DEBUG_INFO, " DisplayId = %x\n" , PcdGet16 (PcdDisplayId)));
return TRUE;
}
/**
Procedure to detect current board HW configuration.
**/
VOID
GetBoardConfig (
VOID
)
{
UINT16 BoardId;
RETURN_STATUS Status;
UINT8 DataBuffer[4];
UINT8 Retry;
UINT8 EcData;
//[-start-200220-IB14630326-add]//
//
// PcdUseCrbEcFlag = FALSE will remove this EC Lib instance.
// Add check here also to avoid run CRB related code
// Project will go to OemProjectReferenceIntelCrb()
//
if (!FeaturePcdGet(PcdCrbBoard)) {
DEBUG ((DEBUG_INFO, "[GetBoardConfig] PcdCrbBoard: %x \n", FeaturePcdGet(PcdCrbBoard)));
return;
}
//[-end-200220-IB14630326-add]//
//
// Get Platform Info and fill the PCD
//
Retry = 0;
BoardId = BoardIdUnknown1;
PcdSet8S (PcdBoardType, BoardTypeMax);
PcdSetBoolS (PcdEcPresent, FALSE);
EarlyLpcIoDecode();
Status = WakeUpEc ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Wake Up Ec Fail. Status = %r \n", Status));
}
if (!IsValidBoardInformationStored ()) {
//
// Detect EC Revision
//
DEBUG((DEBUG_INFO, "Reading EC to set Board information to PCDs \n"));
Retry = 5;
do {
Status = DetectEcSupport ((UINT8 *)DataBuffer);
Retry--;
if ((RETURN_ERROR (Status)) && (Retry != 0)) {
MicroSecondDelay (STALL_TIME);
}
} while ((RETURN_ERROR (Status)) && (Retry != 0));
if (RETURN_ERROR (Status)) {
PcdSetBoolS (PcdEcPresent, FALSE);
} else {
// Byte3[4:3] 0 = G3
// 1 = SAF
// 2 = MAF
PcdSet8S (PcdEcEspiFlashSharingMode, (DataBuffer[3]>>3)&0x3);
// Byte3[1] 0 = Legacy PECI mode // default
// 1 = PECI over eSPI mode
PcdSet8S (PcdEcPeciMode, (DataBuffer[3]>>1)&0x1);
PcdSetBoolS (PcdEcPresent, TRUE);
Status = DetectEcRevision ((UINT8 *)DataBuffer);
PcdSet8S (PcdEcMajorRevision, DataBuffer[0]);
PcdSet8S (PcdEcMinorRevision, DataBuffer[1]);
DEBUG ((DEBUG_INFO, "+==============================================+\n"));
DEBUG ((DEBUG_INFO, "| EC Major Revision: %02X EC Minor Revision: %02X |\n", DataBuffer[0], DataBuffer[1]));
DEBUG ((DEBUG_INFO, "+==============================================+\n"));
}
//
// get RVP board ID
//
if (PcdGetBool (PcdEcPresent)) {
// get board ID from EC
DEBUG ((DEBUG_INFO, "Reading Board ID from EC ...\n"));
do {
Status = InternalGetBoardId (&BoardId);
} while (Status != EFI_SUCCESS);
DEBUG ((DEBUG_INFO, "Got Board ID from EC: 0x%x \n", BoardId));
} else {
// todo: get board ID on an EC less board. hard code BoardIdUnknown1 for temp use
PcdSet16S (PcdBoardId, BoardIdUnknown1);
}
}
BoardId = PcdGet16 (PcdBoardId);
//
// update RVP board config
//
InternalUpdateRvpBoardConfig (BoardId);
if ((PcdGetBool (PcdEcPresent)) && ((PcdGet8 (PcdPlatformFlavor) == FlavorMobile) || (PcdGet8 (PcdPlatformFlavor) == FlavorMobileWorkstation))) {
//
// check dock status if support
//
Status = GetPcieDockStatus (&EcData);
if ((Status == EFI_SUCCESS) && (EcData & EC_B_DOCK_STATUS_ATTACH)) {
PcdSetBoolS (PcdDockAttached, TRUE);
}
//
// Notify EC to set PECI mode
//
SendEcCommand (EC_C_SET_PECI_MODE);
if (SendEcData (PcdGet8 (PcdEcPeciMode)) != EFI_SUCCESS){
DEBUG ((DEBUG_INFO, "Fail to set PECI mode with EC Data %02X\n", PcdGet8 (PcdEcPeciMode)));
}
}
DEBUG ((DEBUG_INFO, "Platform Information:\n"));
DEBUG ((DEBUG_INFO, "PlatformType: %x\n", PcdGet8 (PcdPlatformType)));
DEBUG ((DEBUG_INFO, "BoardName: %s\n", PcdGetPtr (PcdBoardName)));
DEBUG ((DEBUG_INFO, "PlatformFlavor: %x\n", PcdGet8 (PcdPlatformFlavor)));
DEBUG ((DEBUG_INFO, "BoardID: 0x%x\n", BoardId));
DEBUG ((DEBUG_INFO, "BoardRev: %x\n", PcdGet16 (PcdBoardRev)));
DEBUG ((DEBUG_INFO, "BoardBomId: %x\n", PcdGet16 (PcdBoardBomId)));
DEBUG ((DEBUG_INFO, "BoardType: %x\n", PcdGet8 (PcdBoardType)));
DEBUG ((DEBUG_INFO, "PlatformGeneration: %x\n", PcdGet8 (PcdPlatformGeneration)));
DEBUG ((DEBUG_INFO, "EcPresent: %d\n", PcdGetBool (PcdEcPresent)));
DEBUG ((DEBUG_INFO, "SpdPresent: %d\n", PcdGetBool (PcdSpdPresent)));
DEBUG ((DEBUG_INFO, "DisplayId %x\n", PcdGet16 (PcdDisplayId)));
//
// Halt the system if BoardID unknown
//
if (BoardId == BoardIdUnknown1) {
UINT32 code = 0;
switch (PcdGet8 (PcdBoardType)) {
case BoardTypeRvp:
code = 0xBD10;
break;
case BoardTypeSv:
code = 0xBD20;
break;
default:
code = 0xBD30;
break;
}
DEBUG ((DEBUG_ERROR, "Platform BoardID unknown, set PostCode=0x%x and halt the system !\n", code));
PostCode (code);
CpuDeadLoop ();
}
}
/**
Count the number of GPIO settings in the Table.
@param[in] GpioTable The pointer of GPIO config table
@param[out] GpioCount The number of GPIO config entries
**/
//[-start-200910-IB17040158-modify]//
VOID
GetGpioTableSize (
GPIO_INIT_CONFIG *GpioTable,
OUT UINT16 *GpioCount
)
{
UINT16 MaxGpioPin;
MaxGpioPin = PcdGet16 (PcdMaxGpioPins);
*GpioCount = 0;
if(GpioTable != NULL) {
while (GpioTable[*GpioCount].GpioPad != 0 && *GpioCount < MaxGpioPin) {
DEBUG ((DEBUG_INFO, "GpioTable[%d]->GpioPad = %x \n", *GpioCount, GpioTable[*GpioCount].GpioPad));
(*GpioCount) ++;
}
} else {
DEBUG ((DEBUG_INFO, "GpioTable is NULL\n"));
}
DEBUG ((DEBUG_INFO, "GetGpioTableSize() GpioCount = %d\n", *GpioCount));
}
//[-end-200910-IB17040158-modify]//
/**
Configure GPIO Table setting to PcdBoardGpioTablePreMem && PcdBoardGpioTable
@param[in] GpioTable The pointer of GPIO config table
@param[in] IsPostMem Is call from PostMem/PreMem
True - PostMem, False - PreMem
**/
//[-start-200910-IB17040158-modify]//
VOID
ConfigureGpioTabletoPCD(
IN GPIO_INIT_CONFIG *GpioTable,
IN UINT16 IsPostMem
)
{
UINT16 GpioCount = 0;
UINTN Size = 0;
EFI_STATUS Status = EFI_SUCCESS;
BOOLEAN DisableVpdGpioTable = FALSE;
UINT8 Index;
UINT16 CrbSku;
UINT16 MaxGpioPin;
DEBUG ((DEBUG_INFO, "ConfigureGpioTabletoPCD() Start\n"));
MaxGpioPin = PcdGet16 (PcdMaxGpioPins);
//
// If user set PcdMaxGpioPins to non-zero value, just keep user's configuration.
// If PcdMaxGpioPins is zero, process the auto update flow based on CRB SKU.
//
if (MaxGpioPin == 0) {
CrbSku = PcdGet16 (PcdCrbSkuId);
for (Index = 0; Index < mAdlBoardIdToGpioMaxPinMapSize; Index++) {
if (mAdlBoardIdToGpioMaxPinMap[Index].BoardId == CrbSku) {
DEBUG((DEBUG_INFO, "CRB SKU = %d\n", CrbSku));
DEBUG((DEBUG_INFO, "Index = %d, BoardId = %d\n", Index, mAdlBoardIdToGpioMaxPinMap[Index].BoardId));
MaxGpioPin = mAdlBoardIdToGpioMaxPinMap[Index].MaxGpioPins;
break;
}
}
//
// If MaxGpioPin is still zero, set it to MAX_GPIO_PINS.
//
if (MaxGpioPin == 0) {
MaxGpioPin = MAX_GPIO_PINS;
}
Status = PcdSet16S (PcdMaxGpioPins, MaxGpioPin);
ASSERT_EFI_ERROR (Status);
}
DEBUG((DEBUG_INFO, "Max GPIO Pins = %d\n", MaxGpioPin));
DisableVpdGpioTable = (BOOLEAN) PcdGetBool (PcdDisableVpdGpioTable);
DEBUG((DEBUG_INFO, "PcdDisableVpdGpioTable = %d\n", DisableVpdGpioTable));
if (!DisableVpdGpioTable) {
if (GpioTable != NULL) {
GetGpioTableSize (GpioTable, &GpioCount);
if (GpioCount) {
if (IsPostMem == POST_MEM) { // Post Mem GPIO Configuration
if (GpioCount >= MaxGpioPin) {
DEBUG ((DEBUG_ERROR, "GpioTable entries exceeds limit, Configure only MAX_GPIO_PINS Pins.\n"));
GpioCount = MaxGpioPin;
}
DEBUG ((DEBUG_INFO, "GpioTable Count = %d\n", GpioCount));
Size = (UINTN) (GpioCount * sizeof (GPIO_INIT_CONFIG));
Status = PcdSetPtrS (PcdBoardGpioTable, &Size, GpioTable);
} else if (IsPostMem == PRE_MEM) { // Pre Mem GPIO Configuration
if (GpioCount >= MAX_PRE_MEM_GPIO_PINS) {
DEBUG ((DEBUG_ERROR, "PreMem GpioTable entries exceeds limit, Configure only MAX_PRE_MEM_GPIO_PINS Pins.\n"));
GpioCount = MAX_PRE_MEM_GPIO_PINS;
}
DEBUG ((DEBUG_INFO, "GpioTable Count = %d\n", GpioCount));
Size = (UINTN) (GpioCount * sizeof (GPIO_INIT_CONFIG));
Status = PcdSetPtrS (PcdBoardGpioTablePreMem, &Size, GpioTable);
} else if (IsPostMem == EARLY_PRE_MEM) { // Pre Mem GPIO Configuration
if (GpioCount >= MAX_PRE_MEM_GPIO_PINS) {
DEBUG((DEBUG_ERROR, "EarlyPreMem GpioTable entries exceeds limit, Configure only MAX_PRE_MEM_GPIO_PINS Pins.\n"));
GpioCount = MAX_PRE_MEM_GPIO_PINS;
}
DEBUG((DEBUG_INFO, "EarlyPreMem GpioTable Count = %d\n", GpioCount));
Size = (UINTN)(GpioCount * sizeof(GPIO_INIT_CONFIG));
Status = PcdSetPtrS(PcdBoardGpioTableEarlyPreMem, &Size, GpioTable);
}
ASSERT_EFI_ERROR (Status);
} else {
DEBUG ((DEBUG_INFO, "GpioTable is Empty\n"));
}
} else {
DEBUG ((DEBUG_INFO, "GpioTable is NULL\n"));
}
} else {
DEBUG ((DEBUG_INFO, "PcdDisableVpdGpioTable is TRUE, GPIO Tables will be updated by PCT PEIM \n"));
}
DEBUG ((DEBUG_INFO, "ConfigureGpioTabletoPCD() End\n"));
}
//[-end-200910-IB17040158-modify]//
/**
Configures GPIO
@param[in] GpioTable Point to Platform Gpio table
@param[in] GpioTableCount Number of Gpio table entries
**/
STATIC
VOID
ConfigureGpio (
IN GPIO_INIT_CONFIG *GpioTable,
IN UINT16 GpioTableCount
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n"));
Status = GpioConfigurePads (GpioTableCount, GpioTable);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n"));
}
/**
Configure GPIO Before Memory is initialized.
@param[in] GpioTable Pointer to Gpio table
**/
VOID
GpioInit (
IN GPIO_INIT_CONFIG *GpioTable
)
{
UINT16 GpioCount;
if (GpioTable != 0) {
GpioCount = 0;
GetGpioTableSize (GpioTable, &GpioCount);
if (GpioCount != 0) {
ConfigureGpio ((VOID *) GpioTable, (UINTN) GpioCount);
}
}
}
/**
Configure GPIO group GPE tier.
**/
VOID
GpioGroupTierInit (
VOID
)
{
DEBUG ((DEBUG_INFO, "GpioGroupTierInit Start\n"));
if (PcdGet32 (PcdGpioGroupToGpeDw0)) {
GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0),
PcdGet32 (PcdGpioGroupToGpeDw1),
PcdGet32 (PcdGpioGroupToGpeDw2));
}
DEBUG ((DEBUG_INFO, "GpioGroupTierInit End\n"));
}
/**
Update Cpu Xhci Port Enable Map PCD from SaSetup data.
**/
VOID
EFIAPI
TcssUpdateCpuXhciPortEnableMapPcd (
VOID
)
{
EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
EFI_STATUS Status;
SA_SETUP SaSetup;
UINTN DataSize;
UINT8 PortEnableMask;
UINT8 PortEnableMap;
UINT8 Index;
DEBUG ((DEBUG_INFO, "[TCSS] TcssUpdateCpuXhciPortEnableMapPcd: Start\n"));
PortEnableMask = 0x0F; // Enable Mask for All 4 CPU USB Port.
PortEnableMap = PcdGet8 (PcdCpuXhciPortSupportMap); // Get Board Capability Map set Cpu Xhci Port.
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **) &VariableServices
);
if (Status == EFI_SUCCESS) {
DataSize = sizeof (SA_SETUP);
Status = VariableServices->GetVariable (
VariableServices,
L"SaSetup",
&gSaSetupVariableGuid,
NULL,
&DataSize,
&SaSetup
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "[TCSS] TcssUpdateCpuXhciPortEnableMapPcd: GetVariable SaSetup failed with Status= %r\n", Status));
return;
}
if (SaSetup.TcssXhciEn == TRUE) {
if ((SaSetup.CpuUsbPortDisable == FALSE) || (SaSetup.CpuUsbPdoProgramming == FALSE)) {
DEBUG ((DEBUG_INFO, "[TCSS] CpuUsbPortDisable Programming is Disable. So Enabling Mask for All Ports.\n"));
PortEnableMask = 0x0F;
} else {
PortEnableMask = 0x0; // Clearing the Default value.
DEBUG ((DEBUG_INFO, "[TCSS] CpuUsbPortDisable is Enable. So Enabling Mask As per Port Enable.\n"));
for (Index = 0; Index < MAX_TCSS_USB3_PORTS; Index++) {
PortEnableMask |= ((SaSetup.CpuUsbSsPort[Index] & BIT0) << Index);
}
}
} else {
DEBUG ((DEBUG_INFO, "[TCSS] TcssXhciEn is Disable. So Disabling Mask for All Ports.\n"));
PortEnableMask = 0x0;
}
}
DEBUG ((DEBUG_INFO, "[TCSS] Cpu Usb Port Enable Mask is = 0x%x\n", PortEnableMask));
PortEnableMap &= PortEnableMask; // Apply the Mask calculated from SaSetup Data.
DEBUG ((DEBUG_INFO, "[TCSS] Cpu Usb Port Enable Map in Post-Mem is = 0x%x\n", PortEnableMap));
PcdSet8S (PcdCpuUsb30PortEnable, PortEnableMap);
DEBUG ((DEBUG_INFO, "[TCSS] TcssUpdateCpuXhciPortEnableMapPcd: End\n"));
}