/** @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;
}