123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- /** @file
- Gpio setting for multiplatform..
- Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <BoardGpios.h>
- #include <Guid/SetupVariable.h>
- //
- //AlpineValley platform ocde begin
- //
- #define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
- #define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
- #define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
- #define AV_SC_REG_GPIOS_MUXES_EN0 0x54
- #define AV_SC_REG_GPIOS_MUXES_EN1 0x58
- #define AV_SC_REG_GPIOS_MUXES_EN2 0x5C
- //
- //AlpineValley platform code end
- //
- /**
- @param None
- @retval EFI_SUCCESS The function completed successfully.
- **/
- EFI_STATUS
- ConfigurePlatformSysCtrlGpio (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *SmbusPpi
- )
- {
- //
- //AlpineValley platform code begin
- //
- // Initialize GPIO Settings:
- //
- UINT32 Status;
- EFI_PLATFORM_INFO_HOB *PlatformInfoHob;
- DEBUG ((EFI_D_INFO, "ConfigurePlatformSysCtrlGpio()...\n"));
- //
- // Obtain Platform Info from HOB.
- //
- Status = GetPlatformInfoHob ((const EFI_PEI_SERVICES **)PeiServices, &PlatformInfoHob);
- ASSERT_EFI_ERROR (Status);
- //
- // The GPIO settings are dependent upon the platform. Obtain the Board ID through
- // the EC to determine the current platform.
- //
- DEBUG ((EFI_D_INFO, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob->PlatformFlavor, PlatformInfoHob->BoardId));
- Status = (**PeiServices).LocatePpi (
- (const EFI_PEI_SERVICES **)PeiServices,
- &gEfiPeiSmbus2PpiGuid,
- 0,
- NULL,
- (void **)&SmbusPpi
- );
- ASSERT_EFI_ERROR (Status);
- //
- // Select/modify the GPIO initialization data based on the Board ID.
- //
- switch (PlatformInfoHob->BoardId)
- {
- default:
- Status = EFI_SUCCESS;
- //
- // Do nothing for other RVP boards.
- //
- break;
- }
- return Status;
- }
- static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
- {
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gEfiPeiSmbus2PpiGuid,
- ConfigurePlatformSysCtrlGpio
- }
- };
- EFI_STATUS
- InstallPlatformSysCtrlGPIONotify (
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- DEBUG ((EFI_D_INFO, "InstallPlatformSysCtrlGPIONotify()...\n"));
- Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
- ASSERT_EFI_ERROR (Status);
- return EFI_SUCCESS;
- }
- #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
- /**
- Returns the Correct GPIO table for Mobile/Desktop respectively.
- Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
- @param PeiServices General purpose services available to every PEIM.
- @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
- @param BoardId BoardId ID as determined through the EC.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_DEVICE_ERROR KSC fails to respond.
- **/
- EFI_STATUS
- MultiPlatformGpioTableInit (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob
- )
- {
- EFI_STATUS Status;
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
- UINTN VarSize;
- SYSTEM_CONFIGURATION SystemConfiguration;
- DEBUG ((EFI_D_INFO, "MultiPlatformGpioTableInit()...\n"));
- //
- // Select/modify the GPIO initialization data based on the Board ID.
- //
- switch (PlatformInfoHob->BoardId) {
- case BOARD_ID_MINNOW2: // Minnow2
- case BOARD_ID_MINNOW2_TURBOT:
- Status = (**PeiServices).LocatePpi (
- PeiServices,
- &gEfiPeiReadOnlyVariable2PpiGuid,
- 0,
- NULL,
- (void **)&PeiReadOnlyVarPpi
- );
- ASSERT_EFI_ERROR (Status);
-
- VarSize = sizeof (SYSTEM_CONFIGURATION);
- Status = PeiReadOnlyVarPpi->GetVariable (
- PeiReadOnlyVarPpi,
- PLATFORM_SETUP_VARIABLE_NAME,
- &gEfiSetupVariableGuid,
- NULL,
- &VarSize,
- &SystemConfiguration
- );
-
- if (SystemConfiguration.GpioWakeCapability == 1) {
- PlatformInfoHob->PlatformCfioData = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData2;
- }
- else {
- PlatformInfoHob->PlatformCfioData = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData;
- }
-
- PlatformInfoHob->PlatformGpioData_NC = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_NC[0];
- PlatformInfoHob->PlatformGpioData_SC = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SC[0];
- PlatformInfoHob->PlatformGpioData_SUS = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SUS[0];
- break;
- }
- return EFI_SUCCESS;
- }
- UINT32
- GPIORead32 (
- IN UINT32 mmio_conf
- )
- {
- UINT32 conf_val;
- UINT32 i;
- conf_val = MmioRead32(mmio_conf);
- for(i=0;i<5;i++){
- if(conf_val == 0xffffffff)
- conf_val = MmioRead32(mmio_conf);
- else
- break;
- }
- return conf_val;
- }
- /**
- Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
- @param Gpio_Mmio_Offset GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
- @param Gpio_Pin_Num Pin numbers to config for each GPIO clusters.
- @param Gpio_Conf_Data GPIO_CONF_PAD_INIT data array for each GPIO clusters.
- **/
- VOID
- InternalGpioConfig (
- IN UINT32 Gpio_Mmio_Offset,
- IN UINT32 Gpio_Pin_Num,
- GPIO_CONF_PAD_INIT* Gpio_Conf_Data
- )
- {
- UINT32 index;
- UINT32 mmio_conf0;
- UINT32 mmio_padval;
- PAD_CONF0 conf0_val;
- PAD_VAL pad_val;
- //
- // GPIO WELL -- Memory base registers
- //
- // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
- // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
- //
- for(index=0; index < Gpio_Pin_Num; index++)
- {
- //
- // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
- //
- mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
- mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_VAL + Gpio_Conf_Data[index].offset * 16;
- #ifdef EFI_DEBUG
- DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
- #endif
- DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
- Gpio_Conf_Data[index].usage,
- Gpio_Conf_Data[index].func,
- Gpio_Conf_Data[index].int_type,
- Gpio_Conf_Data[index].pull,
- mmio_conf0));
- //
- // Step 1: PadVal Programming.
- //
- pad_val.dw = GPIORead32(mmio_padval);
- //
- // Config PAD_VAL only for GPIO (Non-Native) Pin
- //
- if(Native != Gpio_Conf_Data[index].usage)
- {
- pad_val.dw &= ~0x6; // Clear bits 1:2
- pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6); // Set bits 1:2 according to PadVal
- //
- // set GPO default value
- //
- if(Gpio_Conf_Data[index].usage == GPO && Gpio_Conf_Data[index].gpod4 != NA)
- {
- pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
- }
- }
- DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
- MmioWrite32(mmio_padval, pad_val.dw);
- //
- // Step 2: CONF0 Programming
- // Read GPIO default CONF0 value, which is assumed to be default value after reset.
- //
- conf0_val.dw = GPIORead32(mmio_conf0);
- //
- // Set Function #
- //
- conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
- if(GPO == Gpio_Conf_Data[index].usage)
- {
- //
- // If used as GPO, then internal pull need to be disabled.
- //
- conf0_val.r.Pull_assign = 0; // Non-pull
- }
- else
- {
- //
- // Set PullUp / PullDown
- //
- if(P_20K_H == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x1; // PullUp
- conf0_val.r.Pull_strength = 0x2;// 20K
- }
- else if(P_20K_L == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x2; // PullDown
- conf0_val.r.Pull_strength = 0x2;// 20K
- }
- else if(P_10K_H == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x1; // PullUp
- conf0_val.r.Pull_strength = 0x1;// 10K
- }
- else if(P_10K_L == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x2; // PullDown
- conf0_val.r.Pull_strength = 0x1;// 10K
- }
- else if(P_2K_H == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x1; // PullUp
- conf0_val.r.Pull_strength = 0x0;// 2K
- }
- else if(P_2K_L == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0x2; // PullDown
- conf0_val.r.Pull_strength = 0x0;// 2K
- }
- else if(P_NONE == Gpio_Conf_Data[index].pull)
- {
- conf0_val.r.Pull_assign = 0; // Non-pull
- }
- else
- {
- ASSERT(FALSE); // Invalid value
- }
- }
- //
- // Set INT Trigger Type
- //
- conf0_val.dw &= ~0x0f000000; // Clear bits 27:24
- //
- // Set INT Trigger Type
- //
- if(TRIG_ == Gpio_Conf_Data[index].int_type)
- {
- //
- // Interrupt not capable, clear bits 27:24
- //
- }
- else
- {
- conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
- }
- DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
- //
- // Write back the targeted GPIO config value according to platform (board) GPIO setting.
- //
- MmioWrite32 (mmio_conf0, conf0_val.dw);
- }
- //
- // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
- // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
- //
- }
- /**
- Returns the Correct GPIO table for Mobile/Desktop respectively.
- Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
- @param PeiServices General purpose services available to every PEIM.
- @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
- @param BoardId BoardId ID as determined through the EC.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_DEVICE_ERROR KSC fails to respond.
- **/
- EFI_STATUS
- MultiPlatformGpioProgram (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob
- )
- {
- #if !_SIMIC_
- CFIO_INIT_STRUCT* PlatformCfioDataPtr;
- PlatformCfioDataPtr = (CFIO_INIT_STRUCT *) (UINTN) PlatformInfoHob->PlatformCfioData;
- DEBUG ((EFI_D_INFO, "MultiPlatformGpioProgram()...\n"));
- //
- // SCORE GPIO WELL -- IO base registers
- //
- //
- // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL, PlatformCfioDataPtr->Use_Sel_SC0);
- //
- // Set GP_LVL Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL , PlatformCfioDataPtr->GP_Lvl_SC0);
- //
- // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL, PlatformCfioDataPtr->Io_Sel_SC0);
- //
- // GPIO Triger Positive Edge Enable Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TPE, PlatformCfioDataPtr->TPE_SC0);
- //
- // GPIO Trigger Negative Edge Enable Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TNE, PlatformCfioDataPtr->TNE_SC0);
- //
- // GPIO Trigger Status
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TS, PlatformCfioDataPtr->TS_SC0);
- //
- // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL2, PlatformCfioDataPtr->Use_Sel_SC1);
- //
- // Set GP_LVL2 Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2, PlatformCfioDataPtr->GP_Lvl_SC1);
- //
- // GP_IO_SEL2 Register -> 1 = Input 0 = Output. If Native Mode don't care
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL2, PlatformCfioDataPtr->Io_Sel_SC1);
- //
- // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL3, PlatformCfioDataPtr->Use_Sel_SC2);
- //
- // Set GP_LVL3 Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL3, PlatformCfioDataPtr->GP_Lvl_SC2);
- //
- // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL3, PlatformCfioDataPtr->Io_Sel_SC2);
- //
- // SUS GPIO WELL -- IO base registers
- //
- //
- // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_USE_SEL, PlatformCfioDataPtr->Use_Sel_SS);
- //
- // Set GP_LVL Register
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_LVL , PlatformCfioDataPtr->GP_Lvl_SS);
- //
- // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care.
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_IO_SEL, PlatformCfioDataPtr->Io_Sel_SS);
- //
- // GPIO Triger Positive Edge Enable Register.
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TPE, PlatformCfioDataPtr->TPE_SS);
- //
- // GPIO Trigger Negative Edge Enable Register.
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TNE, PlatformCfioDataPtr->TNE_SS);
- //
- // GPIO Trigger Status.
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TS, PlatformCfioDataPtr->TS_SS);
- //
- // GPIO Wake Enable.
- //
- IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_WAKE_EN, PlatformCfioDataPtr->WE_SS);
- //
- // Config SC/NC/SUS GPIO Pins
- //
- switch (PlatformInfoHob->BoardId) {
- case BOARD_ID_MINNOW2:
- case BOARD_ID_MINNOW2_TURBOT:
- DEBUG ((EFI_D_INFO, "Start to config Minnow2 GPIO pins\n"));
- InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mMinnow2_GpioInitData_SC)/sizeof(mMinnow2_GpioInitData_SC[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SC);
- InternalGpioConfig(GPIO_NCORE_OFFSET, sizeof(mMinnow2_GpioInitData_NC)/sizeof(mMinnow2_GpioInitData_NC[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_NC);
- InternalGpioConfig(GPIO_SSUS_OFFSET, sizeof(mMinnow2_GpioInitData_SUS)/sizeof(mMinnow2_GpioInitData_SUS[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SUS);
- break;
- default:
- break;
- }
- //
- // configure the CFIO Pnp settings
- //
- if (PlatformInfoHob->CfioEnabled) {
- if (PlatformInfoHob->BoardId == BOARD_ID_MINNOW2 || PlatformInfoHob->BoardId == BOARD_ID_MINNOW2_TURBOT){
- InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI)/sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI[0]), (GPIO_CONF_PAD_INIT *) (UINTN)PlatformInfoHob->PlatformGpioData_SC_TRI);
- }
- }
- #else
- DEBUG ((EFI_D_INFO, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));
- #endif
- return EFI_SUCCESS;
- }
|