294 lines
11 KiB
C
294 lines
11 KiB
C
//*****************************************************************************
|
|
//
|
|
//
|
|
// Copyright (c) 2012 - 2015, Hefei LCFC Information Technology Co.Ltd.
|
|
// And/or its affiliates. All rights reserved.
|
|
// Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL.
|
|
// Use is subject to license terms.
|
|
//
|
|
//******************************************************************************
|
|
/*
|
|
History:
|
|
Date Name Version Change Notes
|
|
*/
|
|
#include <PiPei.h>
|
|
#include <Pi/PiBootMode.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/PeiServicesLib.h>
|
|
#include <Library/OemSvcLfcCardReaderCfg.h>
|
|
#include <Library/OemSvcLfcBayHubCardReaderCfg.h>
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
#include <Library/GpioLib.h>
|
|
#define GPIO_VER2_LP_GPP_R6 0x09030006 //Board ID5
|
|
#define GPIO_VER2_LP_GPP_R7 0x09030007 //Board ID6
|
|
static GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG YogaC770_GPIO_Table_early_initBay[] =
|
|
{
|
|
{GPIO_VER2_LP_GPP_R6, {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntDis, GpioHostDeepReset, GpioTermNone, GpioLockDefault}},//Board ID5
|
|
{GPIO_VER2_LP_GPP_R7, {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntDis, GpioHostDeepReset, GpioTermNone, GpioLockDefault}},//Board ID6
|
|
};
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
|
|
PCI_REG_TABLE OZ621PciRegTable[] = {
|
|
{ 0xD0, 0x7FFFFFFF, 0x00000000 }, // Unlock write protect.
|
|
//
|
|
// Program O2SD Subsystem Vendor/Device ID
|
|
//
|
|
{ 0x2C, 0x00000000, LENOVO_OZ711LV2_SSVID_SSID }, // Programing SSID/SVID.
|
|
//
|
|
// Disable O2SD function if it is necessary - If L1 Substate function is supported by the platform
|
|
//
|
|
{ 0xE0, 0x0FFFFFFF, 0x30000000 }, // Set the PCI PM L1 Entrance timer to 16us.
|
|
//[-start-211110-YUNLEI0153-modify]//
|
|
{ 0x3E4, 0xFEF7FFFF, 0x01080000 }, // Set the IDDQ function.
|
|
//[-end-211110-YUNLEI0153-modify]//
|
|
{ 0x248, 0x00000000, L12ThresholdValueScale }, // 110us - L1.2 Threshold scale register set to 010b, L1.2 Threshold value set to 00 0110 1110b, Enable PCI-PM L1 Sub state and ASPM L1 Sub state enable
|
|
{ 0x90, 0xFFFFFFFC, 0x00000003 }, // Enable L0s=bit0, L1=bit1.
|
|
{ 0x90, 0xFFFFFEFF, 0x00000100 }, // Enable using CLK_REQ# to save power.
|
|
//
|
|
// Reverse CD# and WP polarity if it is necessary - Skip now
|
|
//
|
|
//
|
|
// Disable RTD3 (Run Time D3) function if it is necessary - Skip now, default is Enable
|
|
//
|
|
//{ 0x3E0, 0xDFFFFFFF, 0x00000000 }, // Enable RTD3 function.
|
|
//
|
|
// Enable LTR (Latency Tolerant Reporting) feature if it is necessary
|
|
//
|
|
{ 0xA8, 0xFFFFFBFF, 0x00000400 }, // LTR Mechanism Enable; if the application does not support LTR Bit[10] set to 0b.
|
|
{ 0x234, 0x00000000, LTRMaxLatencyValueScale }, // Set max no-snoop latency and max snoop latency -> 3ms, Thinkpad Intel not use this
|
|
//
|
|
// L1 Substate function related
|
|
//
|
|
{ 0x248, 0x00000000, L12ThresholdValueScale }, // 110us - L1.2 Threshold scale register set to 010b, L1.2 Threshold value set to 00 0110 1110b, Enable PCI-PM L1 Sub state and ASPM L1 Sub state enable
|
|
//
|
|
// Enable Power saving mode if it is necessary. (PCI Express Capability Register, Link Control register.)
|
|
//
|
|
{ 0x90, 0xFFFFFFFC, 0x00000003 }, // Enable L0s=bit0, L1=bit1.
|
|
{ 0x90, 0xFFFFFEFF, 0x00000100 }, // Enable using CLK_REQ# to save power.
|
|
//
|
|
// PART B
|
|
//
|
|
//
|
|
// Set the L1 Entrance Timer
|
|
//
|
|
{ 0xE0, 0x0FFFFFFF, 0x30000000 }, // Set the PCI PM L1 Entrance timer to 16us.
|
|
{ 0xFC, 0xFFF0FFFF, 0x00080000 }, // Set the ASPM L1 Entrance timer to 512us.
|
|
//
|
|
// Set the IDDQ function for more power saving
|
|
//
|
|
//[-start-211110-YUNLEI0153-modify]//
|
|
{ 0x3E4, 0xFEF7FFFF, 0x01080000 }, // Set the IDDQ function.
|
|
//[-end-211110-YUNLEI0153-modify]//
|
|
//
|
|
// Set the tuning pass window threshold
|
|
//
|
|
{ 0x300, 0xFFFFFF00, 0x00000055 }, // Set the tuning pass window threshold for SDR104 and SDR50 to 5.
|
|
//
|
|
// Set DLL default sample clock phase of SDR50 if all phases tuning pass
|
|
//
|
|
{ 0x300, 0xFFFF0FFF, 0x00006000 }, // Set DLL default sample clock phase of SDR50 if all phases tuning pass. -> Thinkpad Intel not use this
|
|
//
|
|
// Set drive strength for 1.8V&3.3V signal
|
|
//
|
|
{ 0x304, 0xFFFFFF81, 0x00000044 }, // Set Card Reader driving strength. For EMC request.
|
|
{ 0xD0, 0xFFFFFFFF, 0x80000000 }, // Lock write protect.
|
|
};
|
|
|
|
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
PCI_REG_TABLE OZ621PciRegTable_size14[] = {
|
|
{ 0xD0, 0x7FFFFFFF, 0x00000000 }, // Unlock write protect.
|
|
//
|
|
// Program O2SD Subsystem Vendor/Device ID
|
|
//
|
|
{ 0x2C, 0x00000000, LENOVO_OZ711LV2_SSVID_SSID }, // Programing SSID/SVID.
|
|
//
|
|
// Disable O2SD function if it is necessary - If L1 Substate function is supported by the platform
|
|
//
|
|
{ 0xE0, 0x0FFFFFFF, 0x30000000 }, // Set the PCI PM L1 Entrance timer to 16us.
|
|
{ 0x3E4, 0xFFF7FFFF, 0x00080000 }, // Set the IDDQ function.
|
|
{ 0x248, 0x00000000, L12ThresholdValueScale }, // 110us - L1.2 Threshold scale register set to 010b, L1.2 Threshold value set to 00 0110 1110b, Enable PCI-PM L1 Sub state and ASPM L1 Sub state enable
|
|
{ 0x90, 0xFFFFFFFC, 0x00000003 }, // Enable L0s=bit0, L1=bit1.
|
|
{ 0x90, 0xFFFFFEFF, 0x00000100 }, // Enable using CLK_REQ# to save power.
|
|
//
|
|
// Reverse CD# and WP polarity if it is necessary - Skip now
|
|
//
|
|
//
|
|
// Disable RTD3 (Run Time D3) function if it is necessary - Skip now, default is Enable
|
|
//
|
|
//{ 0x3E0, 0xDFFFFFFF, 0x00000000 }, // Enable RTD3 function.
|
|
//
|
|
// Enable LTR (Latency Tolerant Reporting) feature if it is necessary
|
|
//
|
|
{ 0xA8, 0xFFFFFBFF, 0x00000400 }, // LTR Mechanism Enable; if the application does not support LTR Bit[10] set to 0b.
|
|
{ 0x234, 0x00000000, LTRMaxLatencyValueScale }, // Set max no-snoop latency and max snoop latency -> 3ms, Thinkpad Intel not use this
|
|
//
|
|
// L1 Substate function related
|
|
//
|
|
{ 0x248, 0x00000000, L12ThresholdValueScale }, // 110us - L1.2 Threshold scale register set to 010b, L1.2 Threshold value set to 00 0110 1110b, Enable PCI-PM L1 Sub state and ASPM L1 Sub state enable
|
|
//
|
|
// Enable Power saving mode if it is necessary. (PCI Express Capability Register, Link Control register.)
|
|
//
|
|
{ 0x90, 0xFFFFFFFC, 0x00000003 }, // Enable L0s=bit0, L1=bit1.
|
|
{ 0x90, 0xFFFFFEFF, 0x00000100 }, // Enable using CLK_REQ# to save power.
|
|
//
|
|
// PART B
|
|
//
|
|
//
|
|
// Set the L1 Entrance Timer
|
|
//
|
|
{ 0xE0, 0x0FFFFFFF, 0x30000000 }, // Set the PCI PM L1 Entrance timer to 16us.
|
|
{ 0xFC, 0xFFF0FFFF, 0x00080000 }, // Set the ASPM L1 Entrance timer to 512us.
|
|
//
|
|
// Set the IDDQ function for more power saving
|
|
//
|
|
{ 0x3E4, 0xFFF7FFFF, 0x00080000 }, // Set the IDDQ function.
|
|
//
|
|
// Set the tuning pass window threshold
|
|
//
|
|
{ 0x300, 0xFFFFFF00, 0x00000055 }, // Set the tuning pass window threshold for SDR104 and SDR50 to 5.
|
|
//
|
|
// Set DLL default sample clock phase of SDR50 if all phases tuning pass
|
|
//
|
|
{ 0x300, 0xFFFF0FFF, 0x00006000 }, // Set DLL default sample clock phase of SDR50 if all phases tuning pass. -> Thinkpad Intel not use this
|
|
//
|
|
// Set drive strength for 1.8V&3.3V signal
|
|
//
|
|
{ 0x304, 0xFFFFFF81, 0x00000044 }, // Set Card Reader driving strength. For EMC request.
|
|
{ 0xD0, 0xFFFFFFFF, 0x80000000 }, // Lock write protect.
|
|
};
|
|
|
|
|
|
EFI_STATUS
|
|
LcfcGpioGetMachineSizeBay(
|
|
OUT UINT8 *MachineSize
|
|
)
|
|
|
|
{
|
|
UINT32 BoardID5, BoardID6;
|
|
UINT8 Data8 = 0;
|
|
GpioGetInputValue(GPIO_VER2_LP_GPP_R6,&BoardID5);
|
|
GpioGetInputValue(GPIO_VER2_LP_GPP_R7,&BoardID6);
|
|
|
|
Data8 |= (UINT8)(BoardID6 << 0);
|
|
Data8 |= (UINT8)(BoardID5 << 1);
|
|
|
|
DEBUG ((DEBUG_INFO, "KEBIN dbg Machine Size = 0x%x\n",Data8));
|
|
*MachineSize = Data8;
|
|
DEBUG ((DEBUG_INFO, "KEBIN dbg2 MachineSize = 0x%x\n",*MachineSize));
|
|
return EFI_SUCCESS;
|
|
}
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
|
|
// this function will be executed right after end of pei (project speific code here)
|
|
EFI_STATUS
|
|
EFIAPI
|
|
CheckAndProgramBayHubCardReader (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
UINT8 BrgBusNum,
|
|
UINT8 BrgDevNum,
|
|
UINT8 BrgFunNum,
|
|
UINT8 BusNum,
|
|
UINTN MemBaseAddr,
|
|
UINT16 VendorId,
|
|
UINT16 DeviceId
|
|
)
|
|
{
|
|
UINT32 Temp32;
|
|
UINT8 Index;
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
UINT8 MachineSize = 0;
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
|
|
DEBUG((DEBUG_INFO, __FUNCTION__" Entry\n"));
|
|
//
|
|
// Determine device by Vendor ID and Device ID.
|
|
//
|
|
if ((VendorId != BayHub_Card_Reader_VID) || (DeviceId != BayHub_Card_Reader_DID)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
DEBUG ((DEBUG_INFO, "Find Bayhub Card Reader(B:%d/D:%d:/F:%d)\n", BusNum, 0, 0));
|
|
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
GpioConfigurePads (2, YogaC770_GPIO_Table_early_initBay);
|
|
LcfcGpioGetMachineSizeBay (&MachineSize);
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
|
|
//
|
|
// Write Value To Crc Register
|
|
//
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
if(2 == MachineSize) {
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
for(Index = 0 ; Index < sizeof(OZ621PciRegTable)/sizeof(PCI_REG_TABLE) ; Index ++) {
|
|
if(OZ621PciRegTable[Index].Offset == 0xFFFFFFFF) break;
|
|
|
|
//
|
|
// Get Current setting.
|
|
//
|
|
Temp32 = MmioRead32((UINTN) (MemBaseAddr+ OZ621PciRegTable[Index].Offset));
|
|
DEBUG ((DEBUG_INFO, "Read Bayhub Card Reader Register Offset %.4X: %.8X\n", OZ621PciRegTable[Index].Offset, Temp32));
|
|
//
|
|
// Prepare OEM Setting.
|
|
//
|
|
Temp32 = (Temp32 & OZ621PciRegTable[Index].AndMask) | OZ621PciRegTable[Index].OrValue;
|
|
|
|
//
|
|
// Write OEM Setting.
|
|
//
|
|
MmioWrite32((UINTN) (MemBaseAddr + OZ621PciRegTable[Index].Offset), Temp32);
|
|
DEBUG ((DEBUG_INFO, "Write Bayhub Card Reader Register Offset %.4X: %.8X\n", OZ621PciRegTable[Index].Offset, Temp32));
|
|
}
|
|
//[start-211211-STORM1119-modify]
|
|
#if defined(C770_SUPPORT)
|
|
}else {
|
|
for(Index = 0 ; Index < sizeof(OZ621PciRegTable_size14)/sizeof(PCI_REG_TABLE) ; Index ++) {
|
|
if(OZ621PciRegTable_size14[Index].Offset == 0xFFFFFFFF) break;
|
|
|
|
//
|
|
// Get Current setting.
|
|
//
|
|
Temp32 = MmioRead32((UINTN) (MemBaseAddr+ OZ621PciRegTable_size14[Index].Offset));
|
|
DEBUG ((DEBUG_INFO, "Read Bayhub Card Reader Register Offset %.4X: %.8X\n", OZ621PciRegTable_size14[Index].Offset, Temp32));
|
|
//
|
|
// Prepare OEM Setting.
|
|
//
|
|
Temp32 = (Temp32 & OZ621PciRegTable_size14[Index].AndMask) | OZ621PciRegTable_size14[Index].OrValue;
|
|
|
|
//
|
|
// Write OEM Setting.
|
|
//
|
|
MmioWrite32((UINTN) (MemBaseAddr + OZ621PciRegTable_size14[Index].Offset), Temp32);
|
|
DEBUG ((DEBUG_INFO, "Write Bayhub Card Reader Register Offset %.4X: %.8X\n", OZ621PciRegTable_size14[Index].Offset, Temp32));
|
|
}
|
|
|
|
}
|
|
#endif
|
|
//[end-211211-STORM1119-modify]
|
|
// Bayhub PCI Bridge
|
|
MemBaseAddr = PCI_EXPRESS_LIB_ADDRESS (BrgBusNum, BrgDevNum, BrgFunNum, 0);
|
|
|
|
//
|
|
// Card Reader Pcie root Port L1 Sub-States Control 1 (L1SCTL1) Offset 208h
|
|
//
|
|
// Program root port Threshold scale & Threshold value same as Device (L12ThresholdValueScale)
|
|
// Program root port PCI-PM L1 Substate and ASPM L1 Substate
|
|
//
|
|
Temp32 = L12ThresholdValueScale;
|
|
PciExpressWrite32((UINTN) (MemBaseAddr + 0x208), Temp32);
|
|
|
|
DEBUG((DEBUG_INFO, __FUNCTION__" End\n"));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|