BoardGpios.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /** @file
  2. Gpio setting for multiplatform..
  3. Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <BoardGpios.h>
  7. #include <Guid/SetupVariable.h>
  8. //
  9. //AlpineValley platform ocde begin
  10. //
  11. #define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
  12. #define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
  13. #define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
  14. #define AV_SC_REG_GPIOS_MUXES_EN0 0x54
  15. #define AV_SC_REG_GPIOS_MUXES_EN1 0x58
  16. #define AV_SC_REG_GPIOS_MUXES_EN2 0x5C
  17. //
  18. //AlpineValley platform code end
  19. //
  20. /**
  21. @param None
  22. @retval EFI_SUCCESS The function completed successfully.
  23. **/
  24. EFI_STATUS
  25. ConfigurePlatformSysCtrlGpio (
  26. IN EFI_PEI_SERVICES **PeiServices,
  27. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  28. IN VOID *SmbusPpi
  29. )
  30. {
  31. //
  32. //AlpineValley platform code begin
  33. //
  34. // Initialize GPIO Settings:
  35. //
  36. UINT32 Status;
  37. EFI_PLATFORM_INFO_HOB *PlatformInfoHob;
  38. DEBUG ((EFI_D_INFO, "ConfigurePlatformSysCtrlGpio()...\n"));
  39. //
  40. // Obtain Platform Info from HOB.
  41. //
  42. Status = GetPlatformInfoHob ((const EFI_PEI_SERVICES **)PeiServices, &PlatformInfoHob);
  43. ASSERT_EFI_ERROR (Status);
  44. //
  45. // The GPIO settings are dependent upon the platform. Obtain the Board ID through
  46. // the EC to determine the current platform.
  47. //
  48. DEBUG ((EFI_D_INFO, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob->PlatformFlavor, PlatformInfoHob->BoardId));
  49. Status = (**PeiServices).LocatePpi (
  50. (const EFI_PEI_SERVICES **)PeiServices,
  51. &gEfiPeiSmbus2PpiGuid,
  52. 0,
  53. NULL,
  54. (void **)&SmbusPpi
  55. );
  56. ASSERT_EFI_ERROR (Status);
  57. //
  58. // Select/modify the GPIO initialization data based on the Board ID.
  59. //
  60. switch (PlatformInfoHob->BoardId)
  61. {
  62. default:
  63. Status = EFI_SUCCESS;
  64. //
  65. // Do nothing for other RVP boards.
  66. //
  67. break;
  68. }
  69. return Status;
  70. }
  71. static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
  72. {
  73. EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  74. &gEfiPeiSmbus2PpiGuid,
  75. ConfigurePlatformSysCtrlGpio
  76. }
  77. };
  78. EFI_STATUS
  79. InstallPlatformSysCtrlGPIONotify (
  80. IN CONST EFI_PEI_SERVICES **PeiServices
  81. )
  82. {
  83. EFI_STATUS Status;
  84. DEBUG ((EFI_D_INFO, "InstallPlatformSysCtrlGPIONotify()...\n"));
  85. Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
  86. ASSERT_EFI_ERROR (Status);
  87. return EFI_SUCCESS;
  88. }
  89. #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
  90. /**
  91. Returns the Correct GPIO table for Mobile/Desktop respectively.
  92. Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
  93. @param PeiServices General purpose services available to every PEIM.
  94. @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
  95. @param BoardId BoardId ID as determined through the EC.
  96. @retval EFI_SUCCESS The function completed successfully.
  97. @retval EFI_DEVICE_ERROR KSC fails to respond.
  98. **/
  99. EFI_STATUS
  100. MultiPlatformGpioTableInit (
  101. IN CONST EFI_PEI_SERVICES **PeiServices,
  102. IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob
  103. )
  104. {
  105. EFI_STATUS Status;
  106. EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
  107. UINTN VarSize;
  108. SYSTEM_CONFIGURATION SystemConfiguration;
  109. DEBUG ((EFI_D_INFO, "MultiPlatformGpioTableInit()...\n"));
  110. //
  111. // Select/modify the GPIO initialization data based on the Board ID.
  112. //
  113. switch (PlatformInfoHob->BoardId) {
  114. case BOARD_ID_MINNOW2: // Minnow2
  115. case BOARD_ID_MINNOW2_TURBOT:
  116. Status = (**PeiServices).LocatePpi (
  117. PeiServices,
  118. &gEfiPeiReadOnlyVariable2PpiGuid,
  119. 0,
  120. NULL,
  121. (void **)&PeiReadOnlyVarPpi
  122. );
  123. ASSERT_EFI_ERROR (Status);
  124. VarSize = sizeof (SYSTEM_CONFIGURATION);
  125. Status = PeiReadOnlyVarPpi->GetVariable (
  126. PeiReadOnlyVarPpi,
  127. PLATFORM_SETUP_VARIABLE_NAME,
  128. &gEfiSetupVariableGuid,
  129. NULL,
  130. &VarSize,
  131. &SystemConfiguration
  132. );
  133. if (SystemConfiguration.GpioWakeCapability == 1) {
  134. PlatformInfoHob->PlatformCfioData = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData2;
  135. }
  136. else {
  137. PlatformInfoHob->PlatformCfioData = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData;
  138. }
  139. PlatformInfoHob->PlatformGpioData_NC = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_NC[0];
  140. PlatformInfoHob->PlatformGpioData_SC = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SC[0];
  141. PlatformInfoHob->PlatformGpioData_SUS = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SUS[0];
  142. break;
  143. }
  144. return EFI_SUCCESS;
  145. }
  146. UINT32
  147. GPIORead32 (
  148. IN UINT32 mmio_conf
  149. )
  150. {
  151. UINT32 conf_val;
  152. UINT32 i;
  153. conf_val = MmioRead32(mmio_conf);
  154. for(i=0;i<5;i++){
  155. if(conf_val == 0xffffffff)
  156. conf_val = MmioRead32(mmio_conf);
  157. else
  158. break;
  159. }
  160. return conf_val;
  161. }
  162. /**
  163. Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
  164. @param Gpio_Mmio_Offset GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
  165. @param Gpio_Pin_Num Pin numbers to config for each GPIO clusters.
  166. @param Gpio_Conf_Data GPIO_CONF_PAD_INIT data array for each GPIO clusters.
  167. **/
  168. VOID
  169. InternalGpioConfig (
  170. IN UINT32 Gpio_Mmio_Offset,
  171. IN UINT32 Gpio_Pin_Num,
  172. GPIO_CONF_PAD_INIT* Gpio_Conf_Data
  173. )
  174. {
  175. UINT32 index;
  176. UINT32 mmio_conf0;
  177. UINT32 mmio_padval;
  178. PAD_CONF0 conf0_val;
  179. PAD_VAL pad_val;
  180. //
  181. // GPIO WELL -- Memory base registers
  182. //
  183. // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
  184. // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
  185. //
  186. for(index=0; index < Gpio_Pin_Num; index++)
  187. {
  188. //
  189. // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
  190. //
  191. mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
  192. mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_VAL + Gpio_Conf_Data[index].offset * 16;
  193. #ifdef EFI_DEBUG
  194. DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
  195. #endif
  196. DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
  197. Gpio_Conf_Data[index].usage,
  198. Gpio_Conf_Data[index].func,
  199. Gpio_Conf_Data[index].int_type,
  200. Gpio_Conf_Data[index].pull,
  201. mmio_conf0));
  202. //
  203. // Step 1: PadVal Programming.
  204. //
  205. pad_val.dw = GPIORead32(mmio_padval);
  206. //
  207. // Config PAD_VAL only for GPIO (Non-Native) Pin
  208. //
  209. if(Native != Gpio_Conf_Data[index].usage)
  210. {
  211. pad_val.dw &= ~0x6; // Clear bits 1:2
  212. pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6); // Set bits 1:2 according to PadVal
  213. //
  214. // set GPO default value
  215. //
  216. if(Gpio_Conf_Data[index].usage == GPO && Gpio_Conf_Data[index].gpod4 != NA)
  217. {
  218. pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
  219. }
  220. }
  221. DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
  222. MmioWrite32(mmio_padval, pad_val.dw);
  223. //
  224. // Step 2: CONF0 Programming
  225. // Read GPIO default CONF0 value, which is assumed to be default value after reset.
  226. //
  227. conf0_val.dw = GPIORead32(mmio_conf0);
  228. //
  229. // Set Function #
  230. //
  231. conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
  232. if(GPO == Gpio_Conf_Data[index].usage)
  233. {
  234. //
  235. // If used as GPO, then internal pull need to be disabled.
  236. //
  237. conf0_val.r.Pull_assign = 0; // Non-pull
  238. }
  239. else
  240. {
  241. //
  242. // Set PullUp / PullDown
  243. //
  244. if(P_20K_H == Gpio_Conf_Data[index].pull)
  245. {
  246. conf0_val.r.Pull_assign = 0x1; // PullUp
  247. conf0_val.r.Pull_strength = 0x2;// 20K
  248. }
  249. else if(P_20K_L == Gpio_Conf_Data[index].pull)
  250. {
  251. conf0_val.r.Pull_assign = 0x2; // PullDown
  252. conf0_val.r.Pull_strength = 0x2;// 20K
  253. }
  254. else if(P_10K_H == Gpio_Conf_Data[index].pull)
  255. {
  256. conf0_val.r.Pull_assign = 0x1; // PullUp
  257. conf0_val.r.Pull_strength = 0x1;// 10K
  258. }
  259. else if(P_10K_L == Gpio_Conf_Data[index].pull)
  260. {
  261. conf0_val.r.Pull_assign = 0x2; // PullDown
  262. conf0_val.r.Pull_strength = 0x1;// 10K
  263. }
  264. else if(P_2K_H == Gpio_Conf_Data[index].pull)
  265. {
  266. conf0_val.r.Pull_assign = 0x1; // PullUp
  267. conf0_val.r.Pull_strength = 0x0;// 2K
  268. }
  269. else if(P_2K_L == Gpio_Conf_Data[index].pull)
  270. {
  271. conf0_val.r.Pull_assign = 0x2; // PullDown
  272. conf0_val.r.Pull_strength = 0x0;// 2K
  273. }
  274. else if(P_NONE == Gpio_Conf_Data[index].pull)
  275. {
  276. conf0_val.r.Pull_assign = 0; // Non-pull
  277. }
  278. else
  279. {
  280. ASSERT(FALSE); // Invalid value
  281. }
  282. }
  283. //
  284. // Set INT Trigger Type
  285. //
  286. conf0_val.dw &= ~0x0f000000; // Clear bits 27:24
  287. //
  288. // Set INT Trigger Type
  289. //
  290. if(TRIG_ == Gpio_Conf_Data[index].int_type)
  291. {
  292. //
  293. // Interrupt not capable, clear bits 27:24
  294. //
  295. }
  296. else
  297. {
  298. conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
  299. }
  300. DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
  301. //
  302. // Write back the targeted GPIO config value according to platform (board) GPIO setting.
  303. //
  304. MmioWrite32 (mmio_conf0, conf0_val.dw);
  305. }
  306. //
  307. // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
  308. // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
  309. //
  310. }
  311. /**
  312. Returns the Correct GPIO table for Mobile/Desktop respectively.
  313. Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
  314. @param PeiServices General purpose services available to every PEIM.
  315. @param PlatformInfoHob PlatformInfoHob pointer with PlatformFlavor specified.
  316. @param BoardId BoardId ID as determined through the EC.
  317. @retval EFI_SUCCESS The function completed successfully.
  318. @retval EFI_DEVICE_ERROR KSC fails to respond.
  319. **/
  320. EFI_STATUS
  321. MultiPlatformGpioProgram (
  322. IN CONST EFI_PEI_SERVICES **PeiServices,
  323. IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob
  324. )
  325. {
  326. #if !_SIMIC_
  327. CFIO_INIT_STRUCT* PlatformCfioDataPtr;
  328. PlatformCfioDataPtr = (CFIO_INIT_STRUCT *) (UINTN) PlatformInfoHob->PlatformCfioData;
  329. DEBUG ((EFI_D_INFO, "MultiPlatformGpioProgram()...\n"));
  330. //
  331. // SCORE GPIO WELL -- IO base registers
  332. //
  333. //
  334. // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
  335. //
  336. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL, PlatformCfioDataPtr->Use_Sel_SC0);
  337. //
  338. // Set GP_LVL Register
  339. //
  340. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL , PlatformCfioDataPtr->GP_Lvl_SC0);
  341. //
  342. // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care
  343. //
  344. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL, PlatformCfioDataPtr->Io_Sel_SC0);
  345. //
  346. // GPIO Triger Positive Edge Enable Register
  347. //
  348. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TPE, PlatformCfioDataPtr->TPE_SC0);
  349. //
  350. // GPIO Trigger Negative Edge Enable Register
  351. //
  352. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TNE, PlatformCfioDataPtr->TNE_SC0);
  353. //
  354. // GPIO Trigger Status
  355. //
  356. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TS, PlatformCfioDataPtr->TS_SC0);
  357. //
  358. // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
  359. //
  360. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL2, PlatformCfioDataPtr->Use_Sel_SC1);
  361. //
  362. // Set GP_LVL2 Register
  363. //
  364. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2, PlatformCfioDataPtr->GP_Lvl_SC1);
  365. //
  366. // GP_IO_SEL2 Register -> 1 = Input 0 = Output. If Native Mode don't care
  367. //
  368. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL2, PlatformCfioDataPtr->Io_Sel_SC1);
  369. //
  370. // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
  371. //
  372. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL3, PlatformCfioDataPtr->Use_Sel_SC2);
  373. //
  374. // Set GP_LVL3 Register
  375. //
  376. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL3, PlatformCfioDataPtr->GP_Lvl_SC2);
  377. //
  378. // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
  379. //
  380. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL3, PlatformCfioDataPtr->Io_Sel_SC2);
  381. //
  382. // SUS GPIO WELL -- IO base registers
  383. //
  384. //
  385. // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
  386. //
  387. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_USE_SEL, PlatformCfioDataPtr->Use_Sel_SS);
  388. //
  389. // Set GP_LVL Register
  390. //
  391. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_LVL , PlatformCfioDataPtr->GP_Lvl_SS);
  392. //
  393. // GP_IO_SEL Register -> 1 = Input 0 = Output. If Native Mode don't care.
  394. //
  395. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_IO_SEL, PlatformCfioDataPtr->Io_Sel_SS);
  396. //
  397. // GPIO Triger Positive Edge Enable Register.
  398. //
  399. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TPE, PlatformCfioDataPtr->TPE_SS);
  400. //
  401. // GPIO Trigger Negative Edge Enable Register.
  402. //
  403. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TNE, PlatformCfioDataPtr->TNE_SS);
  404. //
  405. // GPIO Trigger Status.
  406. //
  407. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TS, PlatformCfioDataPtr->TS_SS);
  408. //
  409. // GPIO Wake Enable.
  410. //
  411. IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_WAKE_EN, PlatformCfioDataPtr->WE_SS);
  412. //
  413. // Config SC/NC/SUS GPIO Pins
  414. //
  415. switch (PlatformInfoHob->BoardId) {
  416. case BOARD_ID_MINNOW2:
  417. case BOARD_ID_MINNOW2_TURBOT:
  418. DEBUG ((EFI_D_INFO, "Start to config Minnow2 GPIO pins\n"));
  419. InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mMinnow2_GpioInitData_SC)/sizeof(mMinnow2_GpioInitData_SC[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SC);
  420. InternalGpioConfig(GPIO_NCORE_OFFSET, sizeof(mMinnow2_GpioInitData_NC)/sizeof(mMinnow2_GpioInitData_NC[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_NC);
  421. InternalGpioConfig(GPIO_SSUS_OFFSET, sizeof(mMinnow2_GpioInitData_SUS)/sizeof(mMinnow2_GpioInitData_SUS[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SUS);
  422. break;
  423. default:
  424. break;
  425. }
  426. //
  427. // configure the CFIO Pnp settings
  428. //
  429. if (PlatformInfoHob->CfioEnabled) {
  430. if (PlatformInfoHob->BoardId == BOARD_ID_MINNOW2 || PlatformInfoHob->BoardId == BOARD_ID_MINNOW2_TURBOT){
  431. 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);
  432. }
  433. }
  434. #else
  435. DEBUG ((EFI_D_INFO, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));
  436. #endif
  437. return EFI_SUCCESS;
  438. }