/** @file Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PeiAspireVn7Dash572GInitLib.h" #include #include #ifndef STALL_ONE_MILLI_SECOND #define STALL_ONE_MILLI_SECOND 1000 #endif // // Reference RCOMP resistors on motherboard - for Aspire VN7-572G // GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorAspireVn7Dash572G[SA_MRC_MAX_RCOMP] = { 121, 80, 100 }; // // RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for Aspire VN7-572G // GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetAspireVn7Dash572G[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 }; // // dGPU power GPIO definitions #define DGPU_PRESENT GPIO_SKL_LP_GPP_A20 /* Active low */ #define DGPU_HOLD_RST GPIO_SKL_LP_GPP_B4 /* Active low */ #define DGPU_PWR_EN GPIO_SKL_LP_GPP_B21 /* Active low */ EFI_STATUS EFIAPI AspireVn7Dash572GBoardDetect ( VOID ); /** Aspire VN7-572G board configuration init function for PEI pre-memory phase. **/ VOID AspireVn7Dash572GInitPreMem ( VOID ) { // // HSIO PTSS Table // PcdSet32S (PcdSpecificLpHsioPtssTable1, (UINTN) PchLpHsioPtss_AspireVn7Dash572G); PcdSet16S (PcdSpecificLpHsioPtssTable1Size, (UINTN) PchLpHsioPtss_AspireVn7Dash572G_Size); PcdSet32S (PcdSpecificLpHsioPtssTable2, (UINTN) PchLpHsioPtss_AspireVn7Dash572G); PcdSet16S (PcdSpecificLpHsioPtssTable2Size, (UINTN) PchLpHsioPtss_AspireVn7Dash572G_Size); // // DRAM related definition // PcdSet8S (PcdSaMiscUserBd, 5); // ULT/ULX/Mobile Halo PcdSet8S (PcdMrcCaVrefConfig, 2); // DDR4: "VREF_CA to CH_A and VREF_DQ_B to CH_B" // TODO: Clear Dq/Dqs? PcdSetBoolS (PcdMrcDqPinsInterleaved, TRUE); PcdSet32S (PcdMrcRcompResistor, (UINTN) RcompResistorAspireVn7Dash572G); PcdSet32S (PcdMrcRcompTarget, (UINTN) RcompTargetAspireVn7Dash572G); // // Example policy for DIMM slots implementation boards: // 1. Assign Smbus address of DIMMs and SpdData will be updated later // by reading from DIMM SPD. // 2. No need to apply hardcoded SpdData buffers here for such board. // Example: // PcdMrcSpdAddressTable0 = 0xA0 // PcdMrcSpdAddressTable1 = 0xA2 // PcdMrcSpdAddressTable2 = 0xA4 // PcdMrcSpdAddressTable3 = 0xA6 // PcdMrcSpdData = 0 // PcdMrcSpdDataSize = 0 // PcdSet8S (PcdMrcSpdAddressTable0, 0xA0); PcdSet8S (PcdMrcSpdAddressTable1, 0); PcdSet8S (PcdMrcSpdAddressTable2, 0xA4); PcdSet8S (PcdMrcSpdAddressTable3, 0); PcdSet32S (PcdMrcSpdData, 0); PcdSet16S (PcdMrcSpdDataSize, 0); } /** Configures GPIO before memory is ready. **/ EFI_STATUS EFIAPI GpioInitPreMem ( VOID ) { EFI_STATUS Status; DEBUG ((DEBUG_INFO, "GpioInitPreMem() Start\n")); Status = GpioConfigurePads (mGpioTableAspireVn7Dash572G_earlySize, mGpioTableAspireVn7Dash572G_early); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to configure early GPIOs!\n")); return EFI_DEVICE_ERROR; } DEBUG ((DEBUG_INFO, "GpioInitPreMem() End\n")); return EFI_SUCCESS; } /** Initialises the dGPU. **/ VOID DgpuPowerOn ( VOID ) { UINT32 OutputVal; DEBUG ((DEBUG_INFO, "DgpuPowerOn() Start\n")); GpioGetOutputValue (DGPU_PRESENT, &OutputVal); if (!OutputVal) { DEBUG ((DEBUG_INFO, "dGPU present, enable power...\n")); GpioSetOutputValue (DGPU_HOLD_RST, 0); // Assert dGPU_HOLD_RST# MicroSecondDelay (2 * STALL_ONE_MILLI_SECOND); GpioSetOutputValue (DGPU_PWR_EN, 0); // Assert dGPU_PWR_EN# MicroSecondDelay (7 * STALL_ONE_MILLI_SECOND); GpioSetOutputValue (DGPU_HOLD_RST, 1); // Deassert dGPU_HOLD_RST# MicroSecondDelay (30 * STALL_ONE_MILLI_SECOND); } else { DEBUG ((DEBUG_INFO, "dGPU not present, disable power...\n")); GpioSetOutputValue (DGPU_HOLD_RST, 0); // Assert dGPU_HOLD_RST# GpioSetOutputValue (DGPU_PWR_EN, 1); // Deassert dGPU_PWR_EN# } DEBUG ((DEBUG_INFO, "DgpuPowerOn() End\n")); } /** Configure LPC. **/ VOID LpcInit ( VOID ) { // // Program and Enable EC (sideband) Port Addresses and range // PchLpcGenIoRangeSet (0x68, 0x08); // // Program and Enable EC (index) Port Addresses and range // PchLpcGenIoRangeSet (0x1200, 0x10); } /** Configure GPIO and SIO before memory ready. @retval EFI_SUCCESS Operation success. **/ EFI_STATUS EFIAPI AspireVn7Dash572GBoardInitBeforeMemoryInit ( VOID ) { EFI_STATUS Status; Status = GpioInitPreMem (); if (!EFI_ERROR (Status)) { DgpuPowerOn (); } AspireVn7Dash572GInitPreMem (); /// /// Do basic PCH init /// SiliconInit (); // // Fix-up LPC configuration // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh, 4Eh/4Fh, 60h/64h and 62h/66h. // PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange)); PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding)); // // Install PCH RESET PPI and EFI RESET2 PeiService // Status = PchInitializeReset (); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; } /** Configure GPIO and SIO before memory ready. @retval EFI_SUCCESS Operation success. **/ EFI_STATUS EFIAPI AspireVn7Dash572GBoardInitAfterMemoryInit ( VOID ) { EFI_STATUS Status; // BUGBUG: Workaround for a misbehaving system firmware not setting goIdle // - Based on prior investigation for coreboot, I suspect FSP if ((MmioRead32 (0xFED40044) & PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE) == 0) { DEBUG ((DEBUG_WARN, "TPM no-IdleBypass bug: workaround enabled\n")); MmioWrite32 (0xFED40040, PTP_CRB_CONTROL_AREA_REQUEST_GO_IDLE); } // Program the same 64K range of EC memory as vendor FW Status = PchLpcMemRangeSet (0xFE800000); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "Failed to enable LGMR. Were ACPI tables built for LGMR memory map?\n")); } return EFI_SUCCESS; } EFI_STATUS EFIAPI AspireVn7Dash572GBoardDebugInit ( VOID ) { /// /// Do Early PCH init /// EarlySiliconInit (); LpcInit (); // NB: MinPlatform specification defines platform initialisation flow. // Therefore, we defer board detection until we can program LPC. // - Alternatively, move the preceding calls to BoardDetect() AspireVn7Dash572GBoardDetect (); return EFI_SUCCESS; } EFI_BOOT_MODE EFIAPI AspireVn7Dash572GBoardBootModeDetect ( VOID ) { UINT16 ABase; UINT32 SleepType; DEBUG ((DEBUG_INFO, "Performing boot mode detection\n")); // TODO: Perform advanced detection (recovery/capsule) // FIXME: This violates PI specification? But BOOT_WITH* would always take precedence // over BOOT_ON_S{4,5}... PchAcpiBaseGet (&ABase); SleepType = IoRead32 (ABase + R_PCH_ACPI_PM1_CNT) & B_PCH_ACPI_PM1_CNT_SLP_TYP; switch (SleepType) { case V_PCH_ACPI_PM1_CNT_S3: return BOOT_ON_S3_RESUME; case V_PCH_ACPI_PM1_CNT_S4: return BOOT_ON_S4_RESUME; // case V_PCH_ACPI_PM1_CNT_S5: // return BOOT_ON_S5_RESUME; default: return BOOT_WITH_FULL_CONFIGURATION; } }