/** @file PEI Library Functions. Initialize GPIOs Copyright (c) 2020, 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 #include #include #include #include #include #include #include #include #include #include #include #include #define SIO_RUNTIME_REG_BASE_ADDRESS 0x0680 #define RECOVERY_MODE_GPIO_PIN 0 // Platform specific @todo use PCD #define MANUFACTURE_MODE_GPIO_PIN 0 // Platform specific @todo use PCD /** Configures GPIO @param[in] GpioTable Point to Platform Gpio table @param[in] GpioTableCount Number of Gpio table entries **/ VOID ConfigureGpio ( IN GPIO_INIT_CONFIG *GpioDefinition, IN UINT16 GpioTableCount ) { DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n")); CreateGpioCheckConflictHob (GpioDefinition, GpioTableCount); GpioConfigurePads (GpioTableCount, GpioDefinition); DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n")); } /** Configure GPIO group GPE tier. @retval none. **/ VOID GpioGroupTierInitHook( VOID ) { DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook Start\n")); if (PcdGet32 (PcdGpioGroupToGpeDw0)) { GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0), PcdGet32 (PcdGpioGroupToGpeDw1), PcdGet32 (PcdGpioGroupToGpeDw2)); } DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook End\n")); } /** Configure single GPIO pad for touchpanel interrupt **/ VOID TouchpanelGpioInit ( VOID ) { GPIO_INIT_CONFIG* TouchpanelPad; GPIO_PAD_OWN PadOwnVal; PadOwnVal = 0; TouchpanelPad = (VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableTouchPanel); if (TouchpanelPad != NULL) { GpioGetPadOwnership (TouchpanelPad->GpioPad, &PadOwnVal); if (PadOwnVal == GpioPadOwnHost) { GpioConfigurePads (1, TouchpanelPad); } } } /** Configure GPIO Before Memory is not ready. **/ VOID GpioInitPreMem ( VOID ) { if (PcdGet32 (PcdBoardGpioTablePreMem) != 0 && PcdGet16 (PcdBoardGpioTablePreMemSize) != 0) { ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTablePreMem), (UINTN) PcdGet16 (PcdBoardGpioTablePreMemSize)); } } /** Basic GPIO configuration before memory is ready **/ VOID GpioInitEarlyPreMem ( VOID ) { GPIO_CONFIG BbrstConfig; UINT32 WwanBbrstGpio; WwanBbrstGpio = PcdGet32 (PcdWwanBbrstGpio); if (WwanBbrstGpio) { // // BIOS needs to put modem in OFF state for the two scenarios below. // 1. Modem RESET# is not asserted via PLTRST# in the previous sleep state // 2. Modem is disabled via setup option // GpioGetPadConfig (WwanBbrstGpio, &BbrstConfig); if ((PcdGetBool (PcdPcieWwanEnable) == FALSE) || (PcdGetBool (PcdWwanResetWorkaround) == TRUE && BbrstConfig.Direction == GpioDirOut && BbrstConfig.OutputState == GpioOutHigh)) { // // Assert FULL_CARD_POWER_OFF#, RESET# and PERST# GPIOs // if (PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize) != 0) { ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize)); } if (PcdGetBool (PcdPcieWwanEnable) == TRUE && PcdGetBool (PcdWwanResetWorkaround) == TRUE) { MicroSecondDelay (1 * 1000); // Delay by 1ms } } // // Turn ON modem power and de-assert RESET# and PERST# GPIOs // if (PcdGetBool (PcdPcieWwanEnable) == TRUE) { if (PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize) != 0) { ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize)); } } } } /** Configure GPIO **/ VOID GpioInit ( VOID ) { ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable), (UINTN) PcdGet16 (PcdBoardGpioTableSize)); if (PcdGet32 (PcdBoardGpioTable2)) { ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable2), (UINTN) PcdGet16 (PcdBoardGpioTable2Size)); } TouchpanelGpioInit (); // // Lock pads after initializing platform GPIO. // Pads which were requested to be unlocked during configuration // will not be locked. // GpioLockPads (); return; } /** Configure Super IO **/ VOID SioInit ( VOID ) { // // Program and Enable Default Super IO Configuration Port Addresses and range // PchLpcGenIoRangeSet (PcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF), 0x10); PchLpcGenIoRangeSet (SIO_RUNTIME_REG_BASE_ADDRESS & (~0x7F), 0x10); return; } /** Configure GPIO and SIO before memory ready @retval EFI_SUCCESS Operation success. **/ EFI_STATUS BoardInitPreMem ( VOID ) { // // Obtain Platform Info from HOB. // GpioInitPreMem (); GpioGroupTierInitHook (); SioInit (); return EFI_SUCCESS; } /** Configure GPIO and SIO @retval EFI_SUCCESS Operation success. **/ EFI_STATUS BoardInit ( VOID ) { GpioInit (); return EFI_SUCCESS; } /** Do platform specific programming post-memory. @retval EFI_SUCCESS The function completed successfully. **/ EFI_STATUS PlatformSpecificInit ( VOID ) { GPIO_CONFIG GpioConfig; if (IsCnlPch ()) { // // Tristate unused pins by audio link mode. // ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG)); GpioConfig.PadMode = GpioPadModeGpio; GpioConfig.HostSoftPadOwn = GpioHostOwnGpio; GpioConfig.Direction = GpioDirNone; GpioConfig.OutputState = GpioOutDefault; GpioConfig.InterruptConfig = GpioIntDis; GpioConfig.PowerConfig = GpioPlatformReset; GpioConfig.ElectricalConfig = GpioTermNone; GpioSetPadConfig (GPIO_CNL_LP_SSP1_SFRM, &GpioConfig); GpioSetPadConfig (GPIO_CNL_LP_SSP1_TXD, &GpioConfig); } return EFI_SUCCESS; } /** Early Board Configuration before memory is ready @retval EFI_SUCCESS Operation success. **/ EFI_STATUS BoardInitEarlyPreMem ( VOID ) { GpioInitEarlyPreMem (); return EFI_SUCCESS; }