2 Gpio setting for multiplatform..
4 Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <BoardGpios.h>
18 #include <Guid/SetupVariable.h>
21 //AlpineValley platform ocde begin
23 #define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
24 #define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
25 #define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
26 #define AV_SC_REG_GPIOS_MUXES_EN0 0x54
27 #define AV_SC_REG_GPIOS_MUXES_EN1 0x58
28 #define AV_SC_REG_GPIOS_MUXES_EN2 0x5C
30 //AlpineValley platform code end
33 EFI_GUID gPeiSmbusPpiGuid
= EFI_PEI_SMBUS_PPI_GUID
;
38 @retval EFI_SUCCESS The function completed successfully.
42 ConfigurePlatformSysCtrlGpio (
43 IN EFI_PEI_SERVICES
**PeiServices
,
44 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
49 //AlpineValley platform code begin
51 // Initialize GPIO Settings:
54 EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
;
56 DEBUG ((EFI_D_INFO
, "ConfigurePlatformSysCtrlGpio()...\n"));
59 // Obtain Platform Info from HOB.
61 Status
= GetPlatformInfoHob ((const EFI_PEI_SERVICES
**)PeiServices
, &PlatformInfoHob
);
62 ASSERT_EFI_ERROR (Status
);
65 // The GPIO settings are dependent upon the platform. Obtain the Board ID through
66 // the EC to determine the current platform.
68 DEBUG ((EFI_D_INFO
, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob
->PlatformFlavor
, PlatformInfoHob
->BoardId
));
72 Status
= (**PeiServices
).LocatePpi (
73 (const EFI_PEI_SERVICES
**)PeiServices
,
79 ASSERT_EFI_ERROR (Status
);
82 // Select/modify the GPIO initialization data based on the Board ID.
84 switch (PlatformInfoHob
->BoardId
)
90 // Do nothing for other RVP boards.
97 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
99 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
100 &gEfiPeiSmbusPpiGuid
,
101 ConfigurePlatformSysCtrlGpio
106 InstallPlatformSysCtrlGPIONotify (
107 IN CONST EFI_PEI_SERVICES
**PeiServices
112 DEBUG ((EFI_D_INFO
, "InstallPlatformSysCtrlGPIONotify()...\n"));
114 Status
= (*PeiServices
)->NotifyPpi(PeiServices
, &mNotifyList
[0]);
115 ASSERT_EFI_ERROR (Status
);
120 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
123 Returns the Correct GPIO table for Mobile/Desktop respectively.
124 Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
126 @param PeiServices General purpose services available to every PEIM.
127 @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
128 @param BoardId BoardId ID as determined through the EC.
130 @retval EFI_SUCCESS The function completed successfully.
131 @retval EFI_DEVICE_ERROR KSC fails to respond.
135 MultiPlatformGpioTableInit (
136 IN CONST EFI_PEI_SERVICES
**PeiServices
,
137 IN EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
141 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiReadOnlyVarPpi
;
143 SYSTEM_CONFIGURATION SystemConfiguration
;
145 DEBUG ((EFI_D_INFO
, "MultiPlatformGpioTableInit()...\n"));
148 // Select/modify the GPIO initialization data based on the Board ID.
150 switch (PlatformInfoHob
->BoardId
) {
152 case BOARD_ID_MINNOW2
: // Minnow2
154 Status
= (**PeiServices
).LocatePpi (
156 &gEfiPeiReadOnlyVariable2PpiGuid
,
159 (void **)&PeiReadOnlyVarPpi
161 ASSERT_EFI_ERROR (Status
);
163 VarSize
= sizeof (SYSTEM_CONFIGURATION
);
164 Status
= PeiReadOnlyVarPpi
->GetVariable (
166 PLATFORM_SETUP_VARIABLE_NAME
,
167 &gEfiSetupVariableGuid
,
173 if (SystemConfiguration
.GpioWakeCapability
== 1) {
174 PlatformInfoHob
->PlatformCfioData
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2CfioInitData2
;
177 PlatformInfoHob
->PlatformCfioData
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2CfioInitData
;
180 PlatformInfoHob
->PlatformGpioData_NC
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_NC
[0];
181 PlatformInfoHob
->PlatformGpioData_SC
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_SC
[0];
182 PlatformInfoHob
->PlatformGpioData_SUS
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) &mMinnow2_GpioInitData_SUS
[0];
197 conf_val
= MmioRead32(mmio_conf
);
199 if(conf_val
== 0xffffffff)
200 conf_val
= MmioRead32(mmio_conf
);
210 Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
212 @param Gpio_Mmio_Offset GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
213 @param Gpio_Pin_Num Pin numbers to config for each GPIO clusters.
214 @param Gpio_Conf_Data GPIO_CONF_PAD_INIT data array for each GPIO clusters.
219 IN UINT32 Gpio_Mmio_Offset
,
220 IN UINT32 Gpio_Pin_Num
,
221 GPIO_CONF_PAD_INIT
* Gpio_Conf_Data
231 // GPIO WELL -- Memory base registers
234 // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
235 // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
237 for(index
=0; index
< Gpio_Pin_Num
; index
++)
240 // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
242 mmio_conf0
= IO_BASE_ADDRESS
+ Gpio_Mmio_Offset
+ R_PCH_CFIO_PAD_CONF0
+ Gpio_Conf_Data
[index
].offset
* 16;
243 mmio_padval
= IO_BASE_ADDRESS
+ Gpio_Mmio_Offset
+ R_PCH_CFIO_PAD_VAL
+ Gpio_Conf_Data
[index
].offset
* 16;
246 DEBUG ((EFI_D_INFO
, "%s, ", Gpio_Conf_Data
[index
].pad_name
));
249 DEBUG ((EFI_D_INFO
, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
250 Gpio_Conf_Data
[index
].usage
,
251 Gpio_Conf_Data
[index
].func
,
252 Gpio_Conf_Data
[index
].int_type
,
253 Gpio_Conf_Data
[index
].pull
,
257 // Step 1: PadVal Programming.
259 pad_val
.dw
= GPIORead32(mmio_padval
);
262 // Config PAD_VAL only for GPIO (Non-Native) Pin
264 if(Native
!= Gpio_Conf_Data
[index
].usage
)
266 pad_val
.dw
&= ~0x6; // Clear bits 1:2
267 pad_val
.dw
|= (Gpio_Conf_Data
[index
].usage
& 0x6); // Set bits 1:2 according to PadVal
270 // set GPO default value
272 if(Gpio_Conf_Data
[index
].usage
== GPO
&& Gpio_Conf_Data
[index
].gpod4
!= NA
)
274 pad_val
.r
.pad_val
= Gpio_Conf_Data
[index
].gpod4
;
279 DEBUG ((EFI_D_INFO
, "Set PAD_VAL = 0x%08x, ", pad_val
.dw
));
281 MmioWrite32(mmio_padval
, pad_val
.dw
);
284 // Step 2: CONF0 Programming
285 // Read GPIO default CONF0 value, which is assumed to be default value after reset.
287 conf0_val
.dw
= GPIORead32(mmio_conf0
);
292 conf0_val
.r
.Func_Pin_Mux
= Gpio_Conf_Data
[index
].func
;
294 if(GPO
== Gpio_Conf_Data
[index
].usage
)
297 // If used as GPO, then internal pull need to be disabled.
299 conf0_val
.r
.Pull_assign
= 0; // Non-pull
304 // Set PullUp / PullDown
306 if(P_20K_H
== Gpio_Conf_Data
[index
].pull
)
308 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
309 conf0_val
.r
.Pull_strength
= 0x2;// 20K
311 else if(P_20K_L
== Gpio_Conf_Data
[index
].pull
)
313 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
314 conf0_val
.r
.Pull_strength
= 0x2;// 20K
316 else if(P_10K_H
== Gpio_Conf_Data
[index
].pull
)
318 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
319 conf0_val
.r
.Pull_strength
= 0x1;// 10K
321 else if(P_10K_L
== Gpio_Conf_Data
[index
].pull
)
323 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
324 conf0_val
.r
.Pull_strength
= 0x1;// 10K
326 else if(P_2K_H
== Gpio_Conf_Data
[index
].pull
)
328 conf0_val
.r
.Pull_assign
= 0x1; // PullUp
329 conf0_val
.r
.Pull_strength
= 0x0;// 2K
331 else if(P_2K_L
== Gpio_Conf_Data
[index
].pull
)
333 conf0_val
.r
.Pull_assign
= 0x2; // PullDown
334 conf0_val
.r
.Pull_strength
= 0x0;// 2K
336 else if(P_NONE
== Gpio_Conf_Data
[index
].pull
)
338 conf0_val
.r
.Pull_assign
= 0; // Non-pull
342 ASSERT(FALSE
); // Invalid value
348 // Set INT Trigger Type
350 conf0_val
.dw
&= ~0x0f000000; // Clear bits 27:24
353 // Set INT Trigger Type
355 if(TRIG_
== Gpio_Conf_Data
[index
].int_type
)
358 // Interrupt not capable, clear bits 27:24
363 conf0_val
.dw
|= (Gpio_Conf_Data
[index
].int_type
& 0x0f)<<24;
366 DEBUG ((EFI_D_INFO
, "Set CONF0 = 0x%08x\n", conf0_val
.dw
));
369 // Write back the targeted GPIO config value according to platform (board) GPIO setting.
371 MmioWrite32 (mmio_conf0
, conf0_val
.dw
);
375 // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
376 // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
381 Returns the Correct GPIO table for Mobile/Desktop respectively.
382 Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
384 @param PeiServices General purpose services available to every PEIM.
385 @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
386 @param BoardId BoardId ID as determined through the EC.
388 @retval EFI_SUCCESS The function completed successfully.
389 @retval EFI_DEVICE_ERROR KSC fails to respond.
393 MultiPlatformGpioProgram (
394 IN CONST EFI_PEI_SERVICES
**PeiServices
,
395 IN EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
399 CFIO_INIT_STRUCT
* PlatformCfioDataPtr
;
401 PlatformCfioDataPtr
= (CFIO_INIT_STRUCT
*) (UINTN
) PlatformInfoHob
->PlatformCfioData
;
402 DEBUG ((EFI_D_INFO
, "MultiPlatformGpioProgram()...\n"));
405 // SCORE GPIO WELL -- IO base registers
409 // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
411 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL
, PlatformCfioDataPtr
->Use_Sel_SC0
);
414 // Set GP_LVL Register
416 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL
, PlatformCfioDataPtr
->GP_Lvl_SC0
);
419 // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care
421 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL
, PlatformCfioDataPtr
->Io_Sel_SC0
);
424 // GPIO Triger Positive Edge Enable Register
426 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TPE
, PlatformCfioDataPtr
->TPE_SC0
);
429 // GPIO Trigger Negative Edge Enable Register
431 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TNE
, PlatformCfioDataPtr
->TNE_SC0
);
434 // GPIO Trigger Status
436 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_TS
, PlatformCfioDataPtr
->TS_SC0
);
439 // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
441 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL2
, PlatformCfioDataPtr
->Use_Sel_SC1
);
444 // Set GP_LVL2 Register
446 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL2
, PlatformCfioDataPtr
->GP_Lvl_SC1
);
449 // GP_IO_SEL2 Register -> 1 = Input 0 = Output. If Native Mode don't care
451 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL2
, PlatformCfioDataPtr
->Io_Sel_SC1
);
454 // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
456 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_USE_SEL3
, PlatformCfioDataPtr
->Use_Sel_SC2
);
459 // Set GP_LVL3 Register
461 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_LVL3
, PlatformCfioDataPtr
->GP_Lvl_SC2
);
464 // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
466 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SC_IO_SEL3
, PlatformCfioDataPtr
->Io_Sel_SC2
);
469 // SUS GPIO WELL -- IO base registers
473 // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
475 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_USE_SEL
, PlatformCfioDataPtr
->Use_Sel_SS
);
478 // Set GP_LVL Register
480 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_LVL
, PlatformCfioDataPtr
->GP_Lvl_SS
);
483 // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care.
485 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_IO_SEL
, PlatformCfioDataPtr
->Io_Sel_SS
);
488 // GPIO Triger Positive Edge Enable Register.
490 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TPE
, PlatformCfioDataPtr
->TPE_SS
);
493 // GPIO Trigger Negative Edge Enable Register.
495 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TNE
, PlatformCfioDataPtr
->TNE_SS
);
498 // GPIO Trigger Status.
500 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_TS
, PlatformCfioDataPtr
->TS_SS
);
505 IoWrite32 (GPIO_BASE_ADDRESS
+ R_PCH_GPIO_SUS_WAKE_EN
, PlatformCfioDataPtr
->WE_SS
);
508 // Config SC/NC/SUS GPIO Pins
510 switch (PlatformInfoHob
->BoardId
) {
511 case BOARD_ID_MINNOW2
:
512 DEBUG ((EFI_D_INFO
, "Start to config Minnow2 GPIO pins\n"));
513 InternalGpioConfig(GPIO_SCORE_OFFSET
, sizeof(mMinnow2_GpioInitData_SC
)/sizeof(mMinnow2_GpioInitData_SC
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_SC
);
514 InternalGpioConfig(GPIO_NCORE_OFFSET
, sizeof(mMinnow2_GpioInitData_NC
)/sizeof(mMinnow2_GpioInitData_NC
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_NC
);
515 InternalGpioConfig(GPIO_SSUS_OFFSET
, sizeof(mMinnow2_GpioInitData_SUS
)/sizeof(mMinnow2_GpioInitData_SUS
[0]), (GPIO_CONF_PAD_INIT
*) (UINTN
) PlatformInfoHob
->PlatformGpioData_SUS
);
523 // configure the CFIO Pnp settings
525 if (PlatformInfoHob
->CfioEnabled
) {
526 if (PlatformInfoHob
->BoardId
== BOARD_ID_MINNOW2
){
527 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
);
531 DEBUG ((EFI_D_INFO
, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));