2 Gpio setting for multiplatform..
4 Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <BoardGpios.h>
13 #include <Guid/SetupVariable.h>
16 //AlpineValley platform ocde begin
18 #define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
19 #define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
20 #define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
21 #define AV_SC_REG_GPIOS_MUXES_EN0 0x54
22 #define AV_SC_REG_GPIOS_MUXES_EN1 0x58
23 #define AV_SC_REG_GPIOS_MUXES_EN2 0x5C
25 //AlpineValley platform code end
28 EFI_GUID gPeiSmbusPpiGuid
= EFI_PEI_SMBUS_PPI_GUID
;
33 @retval EFI_SUCCESS The function completed successfully.
37 ConfigurePlatformSysCtrlGpio (
38 IN EFI_PEI_SERVICES
**PeiServices
,
39 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
44 //AlpineValley platform code begin
46 // Initialize GPIO Settings:
49 EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
;
51 DEBUG ((EFI_D_INFO
, "ConfigurePlatformSysCtrlGpio()...\n"));
54 // Obtain Platform Info from HOB.
56 Status
= GetPlatformInfoHob ((const EFI_PEI_SERVICES
**)PeiServices
, &PlatformInfoHob
);
57 ASSERT_EFI_ERROR (Status
);
60 // The GPIO settings are dependent upon the platform. Obtain the Board ID through
61 // the EC to determine the current platform.
63 DEBUG ((EFI_D_INFO
, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob
->PlatformFlavor
, PlatformInfoHob
->BoardId
));
67 Status
= (**PeiServices
).LocatePpi (
68 (const EFI_PEI_SERVICES
**)PeiServices
,
74 ASSERT_EFI_ERROR (Status
);
77 // Select/modify the GPIO initialization data based on the Board ID.
79 switch (PlatformInfoHob
->BoardId
)
85 // Do nothing for other RVP boards.
92 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
94 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
96 ConfigurePlatformSysCtrlGpio
101 InstallPlatformSysCtrlGPIONotify (
102 IN CONST EFI_PEI_SERVICES
**PeiServices
107 DEBUG ((EFI_D_INFO
, "InstallPlatformSysCtrlGPIONotify()...\n"));
109 Status
= (*PeiServices
)->NotifyPpi(PeiServices
, &mNotifyList
[0]);
110 ASSERT_EFI_ERROR (Status
);
115 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
118 Returns the Correct GPIO table for Mobile/Desktop respectively.
119 Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
121 @param PeiServices General purpose services available to every PEIM.
122 @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
123 @param BoardId BoardId ID as determined through the EC.
125 @retval EFI_SUCCESS The function completed successfully.
126 @retval EFI_DEVICE_ERROR KSC fails to respond.
130 MultiPlatformGpioTableInit (
131 IN CONST EFI_PEI_SERVICES
**PeiServices
,
132 IN EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
136 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiReadOnlyVarPpi
;
138 SYSTEM_CONFIGURATION SystemConfiguration
;
140 DEBUG ((EFI_D_INFO
, "MultiPlatformGpioTableInit()...\n"));
143 // Select/modify the GPIO initialization data based on the Board ID.
145 switch (PlatformInfoHob
->BoardId
) {
147 case BOARD_ID_MINNOW2
: // Minnow2
148 case BOARD_ID_MINNOW2_TURBOT
:
149 Status
= (**PeiServices
).LocatePpi (
151 &gEfiPeiReadOnlyVariable2PpiGuid
,
154 (void **)&PeiReadOnlyVarPpi
156 ASSERT_EFI_ERROR (Status
);
158 VarSize
= sizeof (SYSTEM_CONFIGURATION
);
159 Status
= PeiReadOnlyVarPpi
->GetVariable (
161 PLATFORM_SETUP_VARIABLE_NAME
,
162 &gEfiSetupVariableGuid
,
168 if (SystemConfiguration
.GpioWakeCapability
== 1) {
169 PlatformInfoHob
->PlatformCfioData
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2CfioInitData2
;
172 PlatformInfoHob
->PlatformCfioData
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2CfioInitData
;
175 PlatformInfoHob
->PlatformGpioData_NC
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_NC
[0];
176 PlatformInfoHob
->PlatformGpioData_SC
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_SC
[0];
177 PlatformInfoHob
->PlatformGpioData_SUS
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_SUS
[0];
192 conf_val
= MmioRead32(mmio_conf
);
194 if(conf_val
== 0xffffffff)
195 conf_val
= MmioRead32(mmio_conf
);
205 Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
207 @param Gpio_Mmio_Offset GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
208 @param Gpio_Pin_Num Pin numbers to config for each GPIO clusters.
209 @param Gpio_Conf_Data GPIO_CONF_PAD_INIT data array for each GPIO clusters.
214 IN UINT32 Gpio_Mmio_Offset
,
215 IN UINT32 Gpio_Pin_Num
,
216 GPIO_CONF_PAD_INIT
* Gpio_Conf_Data
226 // GPIO WELL -- Memory base registers
229 // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
230 // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
232 for(index
=0; index
< Gpio_Pin_Num
; index
++)
235 // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
237 mmio_conf0
= IO_BASE_ADDRESS
+ Gpio_Mmio_Offset
+ R_PCH_CFIO_PAD_CONF0
+ Gpio_Conf_Data
[index
].offset
* 16;
238 mmio_padval
= IO_BASE_ADDRESS
+ Gpio_Mmio_Offset
+ R_PCH_CFIO_PAD_VAL
+ Gpio_Conf_Data
[index
].offset
* 16;
241 DEBUG ((EFI_D_INFO
, "%s, ", Gpio_Conf_Data
[index
].pad_name
));
244 DEBUG ((EFI_D_INFO
, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
245 Gpio_Conf_Data
[index
].usage
,
246 Gpio_Conf_Data
[index
].func
,
247 Gpio_Conf_Data
[index
].int_type
,
248 Gpio_Conf_Data
[index
].pull
,
252 // Step 1: PadVal Programming.
254 pad_val
.dw
= GPIORead32(mmio_padval
);
257 // Config PAD_VAL only for GPIO (Non-Native) Pin
259 if(Native
!= Gpio_Conf_Data
[index
].usage
)
261 pad_val
.dw
&= ~0x6; // Clear bits 1:2
262 pad_val
.dw
|= (Gpio_Conf_Data
[index
].usage
& 0x6); // Set bits 1:2 according to PadVal
265 // set GPO default value
267 if(Gpio_Conf_Data
[index
].usage
== GPO
&& Gpio_Conf_Data
[index
].gpod4
!= NA
)
269 pad_val
.r
.pad_val
= Gpio_Conf_Data
[index
].gpod4
;
274 DEBUG ((EFI_D_INFO
, "Set PAD_VAL = 0x%08x, ", pad_val
.dw
));
276 MmioWrite32(mmio_padval
, pad_val
.dw
);
279 // Step 2: CONF0 Programming
280 // Read GPIO default CONF0 value, which is assumed to be default value after reset.
282 conf0_val
.dw
= GPIORead32(mmio_conf0
);
287 conf0_val
.r
.Func_Pin_Mux
= Gpio_Conf_Data
[index
].func
;
289 if(GPO
== Gpio_Conf_Data
[index
].usage
)
292 // If used as GPO, then internal pull need to be disabled.
294 conf0_val
.r
.Pull_assign
= 0; // Non-pull
299 // Set PullUp / PullDown
301 if(P_20K_H
== Gpio_Conf_Data
[index
].pull
)
303 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
304 conf0_val
.r
.Pull_strength
= 0x2;// 20K
306 else if(P_20K_L
== Gpio_Conf_Data
[index
].pull
)
308 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
309 conf0_val
.r
.Pull_strength
= 0x2;// 20K
311 else if(P_10K_H
== Gpio_Conf_Data
[index
].pull
)
313 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
314 conf0_val
.r
.Pull_strength
= 0x1;// 10K
316 else if(P_10K_L
== Gpio_Conf_Data
[index
].pull
)
318 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
319 conf0_val
.r
.Pull_strength
= 0x1;// 10K
321 else if(P_2K_H
== Gpio_Conf_Data
[index
].pull
)
323 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
324 conf0_val
.r
.Pull_strength
= 0x0;// 2K
326 else if(P_2K_L
== Gpio_Conf_Data
[index
].pull
)
328 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
329 conf0_val
.r
.Pull_strength
= 0x0;// 2K
331 else if(P_NONE
== Gpio_Conf_Data
[index
].pull
)
333 conf0_val
.r
.Pull_assign
= 0; // Non-pull
337 ASSERT(FALSE
); // Invalid value
343 // Set INT Trigger Type
345 conf0_val
.dw
&= ~0x0f000000; // Clear bits 27:24
348 // Set INT Trigger Type
350 if(TRIG_
== Gpio_Conf_Data
[index
].int_type
)
353 // Interrupt not capable, clear bits 27:24
358 conf0_val
.dw
|= (Gpio_Conf_Data
[index
].int_type
& 0x0f)<<24;
361 DEBUG ((EFI_D_INFO
, "Set CONF0 = 0x%08x\n", conf0_val
.dw
));
364 // Write back the targeted GPIO config value according to platform (board) GPIO setting.
366 MmioWrite32 (mmio_conf0
, conf0_val
.dw
);
370 // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
371 // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
376 Returns the Correct GPIO table for Mobile/Desktop respectively.
377 Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
379 @param PeiServices General purpose services available to every PEIM.
380 @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
381 @param BoardId BoardId ID as determined through the EC.
383 @retval EFI_SUCCESS The function completed successfully.
384 @retval EFI_DEVICE_ERROR KSC fails to respond.
388 MultiPlatformGpioProgram (
389 IN CONST EFI_PEI_SERVICES
**PeiServices
,
390 IN EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
394 CFIO_INIT_STRUCT
* PlatformCfioDataPtr
;
396 PlatformCfioDataPtr
= (CFIO_INIT_STRUCT
*) (UINTN
) PlatformInfoHob
->PlatformCfioData
;
397 DEBUG ((EFI_D_INFO
, "MultiPlatformGpioProgram()...\n"));
400 // SCORE GPIO WELL -- IO base registers
404 // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
406 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL
, PlatformCfioDataPtr
->Use_Sel_SC0
);
409 // Set GP_LVL Register
411 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL
, PlatformCfioDataPtr
->GP_Lvl_SC0
);
414 // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care
416 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL
, PlatformCfioDataPtr
->Io_Sel_SC0
);
419 // GPIO Triger Positive Edge Enable Register
421 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TPE
, PlatformCfioDataPtr
->TPE_SC0
);
424 // GPIO Trigger Negative Edge Enable Register
426 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TNE
, PlatformCfioDataPtr
->TNE_SC0
);
429 // GPIO Trigger Status
431 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TS
, PlatformCfioDataPtr
->TS_SC0
);
434 // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
436 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL2
, PlatformCfioDataPtr
->Use_Sel_SC1
);
439 // Set GP_LVL2 Register
441 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL2
, PlatformCfioDataPtr
->GP_Lvl_SC1
);
444 // GP_IO_SEL2 Register -> 1 = Input 0 = Output. If Native Mode don't care
446 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL2
, PlatformCfioDataPtr
->Io_Sel_SC1
);
449 // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
451 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL3
, PlatformCfioDataPtr
->Use_Sel_SC2
);
454 // Set GP_LVL3 Register
456 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL3
, PlatformCfioDataPtr
->GP_Lvl_SC2
);
459 // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
461 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL3
, PlatformCfioDataPtr
->Io_Sel_SC2
);
464 // SUS GPIO WELL -- IO base registers
468 // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
470 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_USE_SEL
, PlatformCfioDataPtr
->Use_Sel_SS
);
473 // Set GP_LVL Register
475 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_LVL
, PlatformCfioDataPtr
->GP_Lvl_SS
);
478 // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care.
480 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_IO_SEL
, PlatformCfioDataPtr
->Io_Sel_SS
);
483 // GPIO Triger Positive Edge Enable Register.
485 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TPE
, PlatformCfioDataPtr
->TPE_SS
);
488 // GPIO Trigger Negative Edge Enable Register.
490 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TNE
, PlatformCfioDataPtr
->TNE_SS
);
493 // GPIO Trigger Status.
495 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TS
, PlatformCfioDataPtr
->TS_SS
);
500 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_WAKE_EN
, PlatformCfioDataPtr
->WE_SS
);
503 // Config SC/NC/SUS GPIO Pins
505 switch (PlatformInfoHob
->BoardId
) {
506 case BOARD_ID_MINNOW2
:
507 case BOARD_ID_MINNOW2_TURBOT
:
508 DEBUG ((EFI_D_INFO
, "Start to config Minnow2 GPIO pins\n"));
509 InternalGpioConfig(GPIO_SCORE_OFFSET
, sizeof(mMinnow2_GpioInitData_SC
)/sizeof(mMinnow2_GpioInitData_SC
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_SC
);
510 InternalGpioConfig(GPIO_NCORE_OFFSET
, sizeof(mMinnow2_GpioInitData_NC
)/sizeof(mMinnow2_GpioInitData_NC
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_NC
);
511 InternalGpioConfig(GPIO_SSUS_OFFSET
, sizeof(mMinnow2_GpioInitData_SUS
)/sizeof(mMinnow2_GpioInitData_SUS
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_SUS
);
519 // configure the CFIO Pnp settings
521 if (PlatformInfoHob
->CfioEnabled
) {
522 if (PlatformInfoHob
->BoardId
== BOARD_ID_MINNOW2
|| PlatformInfoHob
->BoardId
== BOARD_ID_MINNOW2_TURBOT
){
523 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
);
527 DEBUG ((EFI_D_INFO
, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));