123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912 |
- /** @file
- Install Iio Port Bifurcation Init Data.
- @copyright
- Copyright 2017 - 2021 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiPei.h>
- #include <Upi/KtiHost.h>
- #include <Guid/SetupVariable.h>
- #include <Guid/PlatformInfo.h>
- #include <Ppi/Smbus2.h>
- #include <GpioInitData.h>
- #include <Library/PeiServicesTablePointerLib.h>
- #include <Library/GpioLib.h>
- #include <Library/UbaIioConfigLib.h>
- #include <Library/UbaPlatLib.h>
- #include <Library/HobLib.h>
- #include <Library/UbaIioPortBifurcationInitLib.h>
- #include <Library/PchMultiPchBase.h>
- #include <CpuAndRevisionDefines.h>
- #include <Ppi/DynamicSiLibraryPpi.h>
- #include "PeiCommonBoardInitLib.h"
- #include "IioBifurcationSlotTable.h"
- #define IIO_D_UBALOG(...) { DEBUG((DEBUG_ERROR, "[IIO](UBA) " __VA_ARGS__)); } // Important log always printed
- #define IIO_D_UBADBG(...) { DEBUG((DEBUG_INFO, "[IIO](UBA) " __VA_ARGS__)); } // Debug log, printed with BIOS debug jumper
- #define IIO_D_UBAWARN(...) { DEBUG((DEBUG_ERROR, "[IIO](UBA) WARNING: " __VA_ARGS__)); } // Warning log, not necessary error
- #define IIO_D_UBAERR(...) { DEBUG((DEBUG_ERROR, "[IIO](UBA) ERROR: " __VA_ARGS__)); } // Errorneous situation, probably bug or hw problem
- EFI_PLATFORM_INFO*
- GetPlatformInfoFromHob (
- VOID
- )
- {
- EFI_HOB_GUID_TYPE *GuidHob;
- GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
- if (GuidHob == NULL) {
- ASSERT (FALSE);
- return NULL;
- }
- return GET_GUID_HOB_DATA (GuidHob);
- }
- /**
- Check if QAT-UPLINK override is needed
- @param[in] Socket Socket index
- @param[in] Iou IOU index
- @param[out] Bifurcation Buffer for bifurcation needed to support QAT
- @return TRUE if custom bifurcation is necessary
- */
- BOOLEAN
- IsQatUplinkOverrideNeeded (
- IN UINT8 Socket,
- IN UINT8 Iou,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi,
- OUT UINT8 *Bifurcation
- )
- {
- EFI_PLATFORM_INFO *PlatformInfo;
- UINT32 Gpio;
- EFI_STATUS Status;
- PlatformInfo = GetPlatformInfoFromHob ();
- if (PlatformInfo == NULL) {
- return FALSE;
- }
- switch (PlatformInfo->BoardId) {
- case TypeWilsonCityRP:
- case TypeWilsonCityModular:
- case TypeWilsonCitySMT:
- case TypeWilsonCityPPV:
- case TypeWilsonPointRP:
- case TypeWilsonPointModular:
- case TypeCooperCityRP:
- if (Socket %2 == 0 && Iou == 3) {
- //
- // It is possible that special bifurcation for QAT-UPLINK if needed
- // It can be recognized by GPIO D8: 0 means that there is no UPLINK
- //
- Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_D8, &Gpio);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- if (Gpio != 0) {
- *Bifurcation = IIO_BIFURCATE_xxx8xxx8;
- return TRUE;
- } else {
- return FALSE;
- }
- }
- break;
- }
- //
- // By default there is no QAT-UPLINK support
- //
- return FALSE;
- }
- /**
- Check if QAT-CABLE override is needed
- @param[in] Socket Socket index
- @param[in] Iou IOU index
- @param[out] Bifurcation Buffer for bifurcation needed to support QAT
- @return TRUE if custom bifurcation is necessary
- */
- BOOLEAN
- IsQatCableOverrideNeeded (
- IN UINT8 Socket,
- IN UINT8 Iou,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi,
- OUT UINT8 *Bifurcation
- )
- {
- EFI_PLATFORM_INFO *PlatformInfo;
- UINT32 Gpio;
- EFI_STATUS Status;
- PlatformInfo = GetPlatformInfoFromHob ();
- if (PlatformInfo == NULL) {
- return FALSE;
- }
- switch (PlatformInfo->BoardId) {
- case TypeWilsonCityRP:
- case TypeWilsonCityModular:
- case TypeWilsonCitySMT:
- case TypeWilsonCityPPV:
- case TypeWilsonPointRP:
- case TypeWilsonPointModular:
- if (Iou == 4) {
- //
- // It is possible that special bifurcation for Oculink QAT cable is needed
- // Then cable is used to connect oculinks ports with QAT
- // To determine it if cable is needed GPIO-B3 needs to be examined
- // GPIO-B3 == 0 means that cable is present
- //
- Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B3, &Gpio);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- if (Gpio != 0) {
- //
- // There is no cable
- //
- return FALSE;
- }
- //
- // Cable is present to check which MEZZ IOU is used GPIO B4 needs to be examined
- // GPIO-B4 == 1: MEZZ IOU from Socket0 is used;
- // GPIO-B4 == 0: MEZZ IOU from Socket1 is used;
- //
- Status = DynamicSiLibraryPpi->GpioGetInputValueByPchId (PCH_LEGACY_ID, GPIO_SKL_H_GPP_B4, &Gpio);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- if ((Socket == 0 && Gpio == 1) || (Socket == 1 && Gpio == 0)) {
- *Bifurcation = IIO_BIFURCATE_xxx8x4x4;
- return TRUE;
- }
- }
- } //switch: Board-Id
- //
- // By default there is no QAT-cable support
- //
- return FALSE;
- }
- /**
- Check if QAT override is needed.
- There are two possible QAT variants:
- - QAT uplink
- - QAT cable
- If LBG with QAT is detected (by GPIO read) custom bifurcation should be set.
- @param[in] IioGlobalData Pointer to IioGlobalData
- */
- VOID
- CheckQatBifurcationOverrides (
- IN IIO_GLOBALS *IioGlobalData,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi
- )
- {
- UINT8 Socket;
- UINT8 Iou;
- UINT8 Bifurcation;
- UINT8 StackIndex;
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- for (Iou = 0; Iou < MAX_IOU_PER_SOCKET; Iou++) {
- StackIndex = Iou+1;
- if (!DynamicSiLibraryPpi->IioIsSocketPresent (Socket)) {
- //
- // Skip sockets which are not present on the platform
- //
- continue;
- }
- if (!DynamicSiLibraryPpi->IioIsStackPresent (Socket, StackIndex)) {
- //
- // Skips stacks which are not present on the platform
- //
- continue;
- }
- //
- // Override if QAT is enabled
- //
- if (IsQatUplinkOverrideNeeded (Socket, Iou, DynamicSiLibraryPpi, &Bifurcation)) {
- if (IioGlobalData->SetupData.ConfigIOU[Socket][Iou] == IIO_BIFURCATE_AUTO) {
- IioGlobalData->SetupData.ConfigIOU[Socket][Iou] = Bifurcation;
- IIO_D_UBALOG ("[%d.%d] QAT-uplink detected; bif=%d\n", Socket, StackIndex, Bifurcation);
- }
- } else if (IsQatCableOverrideNeeded (Socket, Iou, DynamicSiLibraryPpi, &Bifurcation)) {
- if (IioGlobalData->SetupData.ConfigIOU[Socket][Iou] == IIO_BIFURCATE_AUTO) {
- IioGlobalData->SetupData.ConfigIOU[Socket][Iou] = Bifurcation;
- IIO_D_UBALOG ("[%d.%d] QAT-cable detected; bif=%d\n", Socket, StackIndex, Bifurcation);
- }
- }
- } // for each Iou
- } // for each Socket
- }
- /**
- Check if MRL sensor is present for given port.
- It depends on board architecture.
- Sometimes slot doesn't support it in contrast to Ext.Card.
- @param[in] TotalPortIndex Index of the port (across all ports on platform)
- @param[in] ExtCardPresent TRUE if Ext. card presence was detected
- @return TRUE if MRL sensor presence is expected
- */
- BOOLEAN
- IsMrlSensorPresent (
- IN UINT16 TotalPortIndex,
- IN BOOLEAN ExtCardPresent
- )
- {
- EFI_HOB_GUID_TYPE *GuidHob;
- EFI_PLATFORM_INFO *PlatformInfo;
- //
- // This data should be read from platform specific config (slot table IIO_BIFURCATION_DATA_ENTRY_EX)
- // but for now there is no such information
- // Let this be a temp. workaround until the update of UBA slot configs
- //
- if (ExtCardPresent) {
- //
- // MRL sensor is always present for Ext. Cards
- //
- return TRUE;
- }
- GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
- if (GuidHob == NULL) {
- ASSERT (FALSE);
- return FALSE;
- }
- PlatformInfo = GET_GUID_HOB_DATA (GuidHob);
- switch (PlatformInfo->BoardId) {
- case TypeWilsonCityRP:
- //
- // This is version for ICX
- //
- switch (TotalPortIndex) {
- case SOCKET_1_INDEX + PORT_1A_INDEX:
- case SOCKET_1_INDEX + PORT_1B_INDEX:
- case SOCKET_1_INDEX + PORT_1C_INDEX:
- case SOCKET_1_INDEX + PORT_1D_INDEX:
- //
- // only one slot on WilsonCity supports MRL
- //
- return TRUE;
- default:
- return FALSE;
- }
- break;
- case TypeCooperCityRP:
- //
- // Let's assume that MRL is supported by all slots on CooperCity - where HP is enabled!
- //
- return TRUE;
- default:
- //
- // For the rest of platforms the situation is unknown for now
- //
- return FALSE;
- }
- }
- /**
- Verify if VMD is enabled and override Slot configuration
- based on the VMD settings
- @param[in] IioGlobalData Pointer to Iio Globals.
- @param[in] Slot Slot configuration settings
- @param[in] SlotEntries Number of slot entries
- @param[in] ExtCardPresent Table with results of Ext. Card detection
- **/
- #define SLOT_NUM_OFFSET_FOR_EXT_CARD_SLOT 0x50
- VOID
- ConfigureSlots (
- IN OUT IIO_GLOBALS *IioGlobalData,
- IN IIO_SLOT_CONFIG_DATA_ENTRY_EX *Slot,
- IN UINT8 SlotEntries,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi,
- IN BOOLEAN ExtCardPresent[MAX_SOCKET][MAX_IOU_PER_SOCKET]
- )
- {
- UINT8 Index;
- UINT16 TotalPortIndex;
- UINT8 IioIndex = 0;
- UINT8 Stack;
- UINT8 PortIndex = 0;
- UINT8 Iou;
- BOOLEAN IsHpSupportedBySlot;
- BOOLEAN IsVmdEnabledForSlot = TRUE;
- BOOLEAN IsExtCardInSlot = TRUE;
- BOOLEAN AreLanesAssignedToPort = TRUE;
- for (Index = 0; Index < SlotEntries; Index ++) {
- TotalPortIndex = Slot[Index].PortIndex;
- if (DynamicSiLibraryPpi->GetMaxPortNumPerSocket() == 0 || DynamicSiLibraryPpi->GetMaxPortNumPerSocket() == 0) {
- return;
- }
- IioIndex = (UINT8) (TotalPortIndex / DynamicSiLibraryPpi->GetMaxPortNumPerSocket ());
- PortIndex = (UINT8) (TotalPortIndex - (IioIndex * DynamicSiLibraryPpi->GetMaxPortNumPerSocket ()));
- Stack = IioGlobalData->IioVar.IioVData.StackPerPort[IioIndex][PortIndex];
- Iou = Stack - 1;
- IsHpSupportedBySlot = FALSE;
- IsVmdEnabledForSlot = DynamicSiLibraryPpi->IsVMDEnabledForPort (IioIndex, PortIndex);
- IsExtCardInSlot = (Slot[Index].ExtensionCardSupport && ExtCardPresent[IioIndex][Iou]);
- AreLanesAssignedToPort = DynamicSiLibraryPpi->IioAreLanesAssignedToPort (IioGlobalData, IioIndex, PortIndex);
- if (Slot[Index].Hidden || !AreLanesAssignedToPort) {
- //
- // Hide rootports which are hidden in slots table or don't have any lanes assigned
- //
- IioGlobalData->SetupData.HidePEXPMenu[TotalPortIndex] = HIDE;
- IioGlobalData->SetupData.PEXPHIDE[TotalPortIndex] = HIDE;
- } else {
- //
- // Unhide active rootports (hided by default)
- //
- IioGlobalData->SetupData.HidePEXPMenu[TotalPortIndex] = NOT_HIDE;
- IioGlobalData->SetupData.PEXPHIDE[TotalPortIndex] = NOT_HIDE;
- }
- if (Slot[Index].SlotPowerLimitScale != PWR_SCL_MAX) {
- IioGlobalData->SetupData.SLOTSPLS[TotalPortIndex] = Slot[Index].SlotPowerLimitScale;
- IioGlobalData->SetupData.SLOTSPLV[TotalPortIndex] = Slot[Index].SlotPowerLimitValue;
- }
- if (Slot[Index].SlotNumber != NO_SLT_IMP) {
- IioGlobalData->SetupData.SLOTIMP[TotalPortIndex] = SLT_IMP;
- IioGlobalData->SetupData.SLOTPSP[TotalPortIndex] = Slot[Index].SlotNumber;
- } else if (AreLanesAssignedToPort) {
- //
- // If slot is not marked as implemented yet, but is exposed in current bifurcation
- // assume that there will be a slot
- //
- IioGlobalData->SetupData.SLOTIMP[TotalPortIndex] = 1;
- IioGlobalData->SetupData.SLOTPSP[TotalPortIndex] = SLOT_NUM_OFFSET_FOR_EXT_CARD_SLOT + TotalPortIndex;
- }
- if (IsVmdEnabledForSlot) {
- //
- // Disable Electromechanical Interlock presence for VMD
- //
- IioGlobalData->SetupData.SLOTEIP[TotalPortIndex] = DISABLE;
- } else {
- IioGlobalData->SetupData.SLOTEIP[TotalPortIndex] = Slot[Index].InterLockPresent;
- }
- //
- // HotPlug related settings:
- // - first check the presence of Ext. Card in the slot and apply specific setting
- // - next apply common settings for HotPlug
- //
- if (IsExtCardInSlot && Slot[Index].ExtnCardHotPlugCapable) {
- IsHpSupportedBySlot = TRUE;
- //
- // Apply specific overrides for HP with Ext. Card
- //
- if (Slot[Index].ExtnCardHPVppPort != VPP_PORT_MAX) {
- IioGlobalData->SetupData.VppEnabled[TotalPortIndex] = TRUE;
- IioGlobalData->SetupData.VppPort[TotalPortIndex] = Slot[Index].ExtnCardHPVppPort;
- IioGlobalData->SetupData.VppAddress[TotalPortIndex] = Slot[Index].ExtnCardHPVppAddress;
- }
- } else if (Slot[Index].HotPlugCapable) {
- //
- // HP settings when there is no Ext. Card
- //
- IsHpSupportedBySlot = TRUE;
- if (Slot[Index].VppPort != VPP_PORT_MAX) {
- IioGlobalData->SetupData.VppEnabled[TotalPortIndex] = TRUE;
- IioGlobalData->SetupData.VppPort[TotalPortIndex] = Slot[Index].VppPort;
- IioGlobalData->SetupData.VppAddress[TotalPortIndex] = Slot[Index].VppAddress;
- }
- }
- if (IsHpSupportedBySlot) {
- //
- // There are common setting for HP
- //
- IioGlobalData->SetupData.SLOTHPCAP[TotalPortIndex] = ENABLE;
- IioGlobalData->SetupData.SLOTAIP[TotalPortIndex] = ENABLE; // Attention Indicator Present
- IioGlobalData->SetupData.SLOTPIP[TotalPortIndex] = ENABLE; // Power Indicator Present
- if (IsVmdEnabledForSlot) {
- IioGlobalData->SetupData.SLOTHPSUP[TotalPortIndex] = ENABLE; // HotPlug Surprise is always enabled for VMD
- }
- if (!IsVmdEnabledForSlot && IsMrlSensorPresent (TotalPortIndex, IsExtCardInSlot)) {
- //
- // Let's assume that if MRL sensor is present Attention button and Power Controller is also present
- //
- IioGlobalData->SetupData.SLOTMRLSP[TotalPortIndex] = ENABLE;
- IioGlobalData->SetupData.SLOTABP[TotalPortIndex] = ENABLE;
- IioGlobalData->SetupData.SLOTPCP[TotalPortIndex] = ENABLE;
- } else {
- IioGlobalData->SetupData.SLOTMRLSP[TotalPortIndex] = DISABLE;
- IioGlobalData->SetupData.SLOTABP[TotalPortIndex] = DISABLE;
- IioGlobalData->SetupData.SLOTPCP[TotalPortIndex] = DISABLE;
- }
- }
- } // for each slot entry
- }
- /**
- Check if lanes are reversed for given IOU - this is important when non-symetrical
- bifurcation is requested.
- @param[in] BifurcationTable record from bifurcation table
- @return TRUE if lanes are in reversed order
- */
- BOOLEAN
- IsLaneReversed (
- IN IIO_BIFURCATION_DATA_ENTRY_EX *BifurcationTable
- )
- {
- EFI_HOB_GUID_TYPE *GuidHob;
- EFI_PLATFORM_INFO *PlatformInfo;
- //
- // This data should be read from platform specific config - but for now we don't have this information there
- // Let this be a temp. workaround until the update of biffurcation config.
- //
- GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
- if (GuidHob == NULL) {
- ASSERT (FALSE);
- return FALSE;
- }
- PlatformInfo = GET_GUID_HOB_DATA (GuidHob);
- switch (PlatformInfo->BoardId) {
- case TypeCooperCityRP:
- //
- // For CooperCityRP lane reversed are:
- // - on even sockets: on IOU4
- // - on odd sockets: on IOU1
- //
- return ((BifurcationTable->Socket&1) == 1 && BifurcationTable->IouNumber == Iio_Iou1);
- default:
- //
- // Let's assume that WilsonCity config is a default one.
- //
- //
- // This is version for ICX (default)
- //
- return (BifurcationTable->Socket == 1 &&
- (BifurcationTable->IouNumber == Iio_Iou0 || BifurcationTable->IouNumber == Iio_Iou4));
- }
- }
- /**
- Read the bifurcation info stored at I/O Expander (PCA9554) which BIOS
- can get through Smbus.
- To communicate with IO Expander first MUX PCA9545 needs to be configured.
- The bifurcation encoding is [3:0]:
- BW5_BIFURCATE_x4x4x4x4 1 0 0 0
- BW5_BIFURCATE_x4x4xxx8 1 0 0 1 Lanes to port ACD on board
- BW5_BIFURCATE_xxx8x4x4 1 0 1 0 Lanes to port ABC on board
- BW5_BIFURCATE_xxx8xxx8 1 0 1 1 Lanes to port AC on board
- No BW5 1 1 x x
- @param IioGlobalData - Pointer to IioGlobals
- @param BroadwayTablePtr - Pointer to BroadwayTable
- @retval IIO_BIFURCATE_xxxxxxxx BW communication failure
- @retval IIO_BIFURCATE_x4x4x4x4 Requested bifurcation x4x4x4x4
- @retval IIO_BIFURCATE_x4x4xxx8 Requested bifurcation x4x4xxx8
- @retval IIO_BIFURCATE_xxx8x4x4 Requested bifurcation xxx8x4x4
- @retval IIO_BIFURCATE_xxx8xxx8 Requested bifurcation xxx8xxx8
- **/
- UINT8
- GetBw5Bifurcation (
- IN IIO_BIFURCATION_DATA_ENTRY_EX *BifurcationTable,
- IN IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi
- )
- {
- EFI_STATUS Status;
- EFI_SMBUS_DEVICE_ADDRESS SmbDevAddr;
- EFI_PEI_SMBUS2_PPI *SmbPpi = NULL;
- UINT16 SmbData = 0;
- UINT8 SmbByteData = 0;
- UINT8 RetryCount;
- UINTN SmbLen = 2;
- UINTN SmbByteLen = 1;
- if (BifurcationTable->ExtnCardSMBusAddress == SMB_ADDR_MAX ) {
- return IIO_BIFURCATE_xxxxxxxx;
- }
- Status = PeiServicesLocatePpi (&gEfiPeiSmbus2PpiGuid, 0, NULL, (VOID **) &SmbPpi);
- // Initialize Bw5Id to not present
- if (Status != EFI_SUCCESS || SmbPpi == NULL) {
- DEBUG ((DEBUG_ERROR, "[Iio] Get SMBus protocol error %x\n", Status));
- return IIO_BIFURCATE_xxxxxxxx;
- }
- for (RetryCount = 0; RetryCount < NUM_OF_RETRIES; RetryCount++) {
- //
- // Configure through the smbus MUX PCA9545 to start communicate to GPIO expander
- //
- SmbDevAddr.SmbusDeviceAddress = BifurcationTable->MuxSMBusAddress >> 1;
- SmbByteData = BifurcationTable->MuxSMBusChannel;
- Status = SmbPpi->Execute (SmbPpi, SmbDevAddr, 0, EfiSmbusSendByte, FALSE, &SmbByteLen, &SmbByteData);
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // Read the current I/O pins configuration for Port0
- //
- SmbDevAddr.SmbusDeviceAddress = BifurcationTable->ExtnCardSMBusAddress >> 1;
- Status = SmbPpi->Execute (SmbPpi, SmbDevAddr, BW4_CONFIG_OFFSET, EfiSmbusReadWord, FALSE, &SmbLen, &SmbData);
- if (!EFI_ERROR (Status)) {
- //
- // Configure the direction of I/O pins for Port0/Port1 as Input.
- //
- SmbData = SmbData | BW5_CONFIG_REG_MASK;
- Status = SmbPpi->Execute (SmbPpi, SmbDevAddr, BW4_CONFIG_OFFSET, EfiSmbusWriteWord, FALSE, &SmbLen, &SmbData);
- if (!EFI_ERROR (Status)) {
- //
- // Read Input Port0/Port1 register to identify BW5 Id
- //
- Status = SmbPpi->Execute (SmbPpi, SmbDevAddr, BW4_DATA_OFFSET, EfiSmbusReadWord, FALSE, &SmbLen, &SmbData);
- if (!EFI_ERROR (Status)){
- //
- // Mask the Input Port0/1 register data [15:0] to get BW5 ID [3:0].
- //
- // The bifurcation encoding is [3:0]:
- // BW5_BIFURCATE_x4x4x4x4 1 0 0 0
- // BW5_BIFURCATE_x4x4xxx8 1 0 0 1 Lanes to port ACD on board
- // BW5_BIFURCATE_xxx8x4x4 1 0 1 0 Lanes to port ABC on board
- // BW5_BIFURCATE_xxx8xxx8 1 0 1 1 Lanes to port AC on board
- // No BW5 1 1 x x
- //
- switch (SmbData & 0xF) {
- case 0x8:
- return IIO_BIFURCATE_x4x4x4x4;
- break;
- case 0x9:
- if (IsLaneReversed (BifurcationTable)) {
- return IIO_BIFURCATE_xxx8x4x4;
- } else {
- return IIO_BIFURCATE_x4x4xxx8;
- }
- break;
- case 0xA:
- if (IsLaneReversed (BifurcationTable)) {
- return IIO_BIFURCATE_x4x4xxx8;
- } else {
- return IIO_BIFURCATE_xxx8x4x4;
- }
- break;
- case 0xB:
- return IIO_BIFURCATE_xxx8xxx8;
- break;
- default:
- return IIO_BIFURCATE_xxxxxxxx;
- break;
- }
- } // Read Port0
- } // Configure Port0
- } // Read Port0 Config
- //
- // Configure through the smbus MUX PCA9545 to end communicate to GPIO expander
- //
- SmbDevAddr.SmbusDeviceAddress = BifurcationTable->MuxSMBusAddress >> 1;
- SmbByteData &= ~BifurcationTable->MuxSMBusChannel;
- Status = SmbPpi->Execute (SmbPpi, SmbDevAddr, 0, EfiSmbusSendByte, FALSE, &SmbByteLen, &SmbByteData);
- if (EFI_ERROR (Status)) {
- continue;
- }
- } //RetryCount
- return IIO_BIFURCATE_xxxxxxxx;
- }
- /**
- Set bifurcation base of default settings and Ext. Card presence
- (detected by BW)
- @param[in] IioGlobalData Pointer to Iio Globals.
- @param[in] BifurcationTable Bifurcation configuration settings
- @param[in] BifurcationEntries Number of bif. table entries
- @param[in] ExtCardPresent Table with results of Ext. Card detection
- **/
- VOID
- DetectExtCards (
- IN IIO_GLOBALS *IioGlobalData,
- IN IIO_BIFURCATION_DATA_ENTRY_EX *BifurcationTable,
- IN UINT8 BifurcationEntries,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi,
- OUT BOOLEAN ExtCardPresent[MAX_SOCKET][MAX_IOU_PER_SOCKET]
- )
- {
- UINT8 Index;
- UINT8 BwBifurcation;
- UINT8 Socket;
- UINT8 Iou;
- //
- // Try to communicate with Ext.Card which can request custom bifurcation on the stack
- //
- for (Index = 0; Index < BifurcationEntries; Index++){
- Socket = BifurcationTable[Index].Socket;
- Iou = BifurcationTable[Index].IouNumber;
- ExtCardPresent[Socket][Iou] = FALSE; // by default
- if (BifurcationTable[Index].ExtnCardSMBusAddress != SMB_ADDR_MAX) {
- //
- // ExtCard can be supported at this stack - try to detect it
- //
- BwBifurcation = GetBw5Bifurcation (&BifurcationTable[Index], DynamicSiLibraryPpi);
- if (BwBifurcation != IIO_BIFURCATE_xxxxxxxx) {
- //
- // Ext. Card is detected on this IOU
- //
- IIO_D_UBALOG ("[%d.%d] Ext. Card detected; bif=%d\n", Socket, Iou+1, BwBifurcation);
- ExtCardPresent[Socket][Iou] = TRUE;
- }
- }
- //
- // Set custom bifurcation requested by Ext. Card
- //
- if (IioGlobalData->SetupData.ConfigIOU[Socket][Iou] == IIO_BIFURCATE_AUTO) {
- //
- // There are no overrides for this IOU
- //
- if (ExtCardPresent[Socket][Iou]) {
- //
- // Set bifurcation requested by Ext. Card
- //
- IioGlobalData->SetupData.ConfigIOU[Socket][Iou] = BwBifurcation;
- } else {
- //
- // Set the default bifurcation for this IOU
- //
- IioGlobalData->SetupData.ConfigIOU[Socket][Iou] = BifurcationTable[Index].Bifurcation;
- }
- }
- IIO_D_UBADBG ("[%d.%d] final bifurcation = %X\n", Socket, Iou+1, IioGlobalData->SetupData.ConfigIOU[Socket][Iou]);
- } // for bifurcation table entry
- }
- /**
- Dump prepared configuration to log.
- @param[in] SetupData Pointer to SetupData structure
- **/
- VOID
- DumpConfiguration (
- IN IIO_CONFIG *SetupData,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi
- )
- {
- UINT8 IioIndex;
- UINT8 StackIndex = 0;
- UINT8 Iou;
- UINT8 PortIndex = 0;
- UINT8 PortInStackIndex = 0;
- UINT16 TotalPortIndex =0;
- for (IioIndex = 0; IioIndex < MAX_SOCKET ; IioIndex++) {
- if (!DynamicSiLibraryPpi->IioIsSocketPresent (IioIndex)) {
- //
- // Skips sockets which are not present on the platform
- //
- continue;
- }
- for (StackIndex = 0; StackIndex < DynamicSiLibraryPpi->GetMaxStackNumPerSocket (); StackIndex++) {
- if (DynamicSiLibraryPpi->IsDmiStack (StackIndex)) {
- //
- // Skip DMI stacks in dump
- //
- continue;
- }
- if (!DynamicSiLibraryPpi->IioIsStackPresent (IioIndex, StackIndex)) {
- //
- // Skips stacks which are not present on the platform
- //
- continue;
- }
- if (StackIndex >= MAX_IIO_STACK) {
- break;
- }
- Iou = StackIndex - 1;
- IIO_D_UBALOG("[%d.%d] Bifurcation = %X\n", IioIndex, StackIndex, SetupData->ConfigIOU[IioIndex][Iou]);
- IIO_D_UBALOG (" [ IDX ], PortHide, SlotImpl, SlotNumber, HotPlug, Vpp, Interlock\n");
- for (PortInStackIndex = 0; PortInStackIndex < DynamicSiLibraryPpi->GetMaxPortNumPerStack (StackIndex); PortInStackIndex++) {
- PortIndex = DynamicSiLibraryPpi->GetPortIndexbyStack (StackIndex, PortInStackIndex);
- TotalPortIndex = (IioIndex * DynamicSiLibraryPpi->GetMaxPortNumPerSocket ()) + PortIndex;
- IIO_D_UBALOG (" [%d p%02d] %2d | %2d | %3d | %3d | 0x%02x | %2d \n",
- IioIndex, PortIndex,
- SetupData->PEXPHIDE[TotalPortIndex],
- SetupData->SLOTIMP[TotalPortIndex],
- SetupData->SLOTPSP[TotalPortIndex],
- SetupData->SLOTHPCAP[TotalPortIndex],
- SetupData->VppAddress[TotalPortIndex] | SetupData->VppPort[TotalPortIndex],
- SetupData->SLOTEIP[TotalPortIndex]);
- } // foreach PortInStack
- } //foreach StackIndex
- } // foreach IioIndex
- }
- /**
- This function prepare the data for silicon initialization based on
- bifurcations and slots table
- This function is for tables in version PLATFORM_IIO_CONFIG_UPDATE_VERSION = 2
- @param[in] IioGlobalData IIO Global data structure
- @param[in] IioConfigTable
- */
- VOID
- IioPortBifurcationInitVer2 (
- IN IIO_GLOBALS *IioGlobalData,
- IN PLATFORM_IIO_CONFIG_UPDATE_TABLE_EX IioConfigTable,
- IN DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi
- )
- {
- IIO_BIFURCATION_DATA_ENTRY_EX *BifurcationTableEx;
- UINT8 BifurcationEntries;
- IIO_SLOT_CONFIG_DATA_ENTRY_EX *SlotTableEx;
- UINT8 SlotEntries;
- BOOLEAN ExtCardDetected[MAX_SOCKET][MAX_IOU_PER_SOCKET];
- //
- // Init bifurcation and slots tables
- //
- BifurcationTableEx = IioConfigTable.IioBifurcationTablePtr;
- BifurcationEntries = (UINT8) (IioConfigTable.IioBifurcationTableSize / sizeof (IIO_BIFURCATION_DATA_ENTRY_EX));
- SlotTableEx = IioConfigTable.IioSlotTablePtr;
- SlotEntries = (UINT8) (IioConfigTable.IioSlotTableSize / sizeof (IIO_SLOT_CONFIG_DATA_ENTRY_EX));
- //
- // Set the bifurcations for each IOU:
- // - if any override is set in setup menu - stay bifurcation not changed
- // - next check if QAT is detected (this is LBG specific) - QAT requires special bifurcation
- // - next try to detect ext. cards with BW bifurcation
- // - at the end set default bifurcation if no other options wer applied before
- if (DynamicSiLibraryPpi->IsCpuAndRevision (CPU_ICXSP, REV_ALL) ||
- DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CPX, REV_ALL) ||
- DynamicSiLibraryPpi->IsCpuAndRevision (CPU_SKX, REV_ALL) ||
- DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CLX, REV_ALL)
- ) {
- //
- // This is important only for programs with LBG PCH
- //
- CheckQatBifurcationOverrides (IioGlobalData, DynamicSiLibraryPpi);
- }
- DetectExtCards (IioGlobalData, BifurcationTableEx, BifurcationEntries, DynamicSiLibraryPpi, ExtCardDetected);
- //
- // Set each rootport settings based on slots table
- //
- ConfigureSlots (IioGlobalData, SlotTableEx, SlotEntries, DynamicSiLibraryPpi, ExtCardDetected);
- //
- // Configuration is ready - dump the config to log
- //
- DumpConfiguration (&IioGlobalData->SetupData, DynamicSiLibraryPpi);
- }
- /**
- Program the IIO_GLOBALS data structure with OEM IIO init values for SLOTs and Bifurcation.
- @param mSB - pointer to this protocol
- @param IioUds - Pointer to the IIO UDS data structure.
- @retval EFI_SUCCESS
- **/
- VOID
- IioPortBifurcationInitCallback (
- IN IIO_GLOBALS *IioGlobalData
- )
- {
- EFI_STATUS Status;
- UBA_CONFIG_DATABASE_PPI *UbaConfigPpi = NULL;
- DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL;
- PLATFORM_IIO_CONFIG_UPDATE_TABLE_EX IioConfigTable;
- UINTN TableSize;
- //
- // Locate PLATFORM_IIO_CONFIG_UPDATE_TABLE_EX
- //
- Status = PeiServicesLocatePpi (&gUbaConfigDatabasePpiGuid, 0, NULL, (VOID **) &UbaConfigPpi);
- if (EFI_ERROR (Status)) {
- ASSERT (FALSE);
- return;
- }
- Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, (VOID **) &DynamicSiLibraryPpi);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- TableSize = sizeof (IioConfigTable);
- Status = UbaConfigPpi->GetData (UbaConfigPpi, &gPlatformIioConfigDataGuid, &IioConfigTable, &TableSize);
- if (EFI_ERROR (Status)) {
- ASSERT (FALSE);
- return;
- }
- ASSERT (IioConfigTable.Signature == PLATFORM_IIO_CONFIG_UPDATE_SIGNATURE);
- //
- // Call the right version of bifurcation init procedure
- //
- switch (IioConfigTable.Version) {
- case PLATFORM_IIO_CONFIG_UPDATE_VERSION_2:
- IioPortBifurcationInitVer2 (IioGlobalData, IioConfigTable, DynamicSiLibraryPpi);
- break;
- case PLATFORM_IIO_CONFIG_UPDATE_VERSION:
- IioPortBifurcationInitVer1 (IioGlobalData);
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
- IIO_PORT_BIFURCATION_INIT_TABLE IioPortBifurcationInitTable =
- {
- IIO_PORT_BIFURCATION_INIT_SIGNATURE,
- IIO_PORT_BIFURCATION_INIT_VERSION,
- IioPortBifurcationInitCallback
- };
- EFI_STATUS
- InstallIioPortBifurcationInitData (
- IN UBA_CONFIG_DATABASE_PPI *UbaConfigPpi
- )
- {
- return UbaConfigPpi->AddData (
- UbaConfigPpi,
- &gIioPortBifurcationInitDataGuid,
- &IioPortBifurcationInitTable,
- sizeof (IioPortBifurcationInitTable)
- );
- }
|