]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
ArmPkg/CompilerIntrinsicsLib: Add uread, uwrite GCC assembly sources
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Pei / PlatformInit / PlatformEarlyInit.c
CommitLineData
b303605e
MK
1/** @file\r
2This PEIM initialize platform for MRC, following action is performed,\r
31. Initizluize GMCH\r
42. Detect boot mode\r
53. Detect video adapter to determine whether we need pre allocated memory\r
64. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.\r
7This file contains the main entrypoint of the PEIM.\r
8\r
406d8575 9Copyright (c) 2013 - 2016 Intel Corporation.\r
b303605e 10\r
0eb3de2e 11SPDX-License-Identifier: BSD-2-Clause-Patent\r
b303605e
MK
12\r
13**/\r
14\r
15\r
16#include "CommonHeader.h"\r
17#include "PlatformEarlyInit.h"\r
18#include "PeiFvSecurity.h"\r
19\r
20EFI_STATUS\r
21EFIAPI\r
22EndOfPeiSignalPpiNotifyCallback (\r
23 IN EFI_PEI_SERVICES **PeiServices,\r
24 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
25 IN VOID *Ppi\r
26 );\r
27\r
28//\r
29// Function prototypes to routines implemented in other source modules\r
30// within this component.\r
31//\r
32\r
33EFI_STATUS\r
34EFIAPI\r
35PlatformErratasPostMrc (\r
36 VOID\r
37 );\r
38\r
39//\r
40// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory\r
41//\r
42BOOLEAN ImageInMemory = FALSE;\r
43\r
44BOARD_LEGACY_GPIO_CONFIG mBoardLegacyGpioConfigTable[] = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION };\r
45UINTN mBoardLegacyGpioConfigTableLen = (sizeof(mBoardLegacyGpioConfigTable) / sizeof(BOARD_LEGACY_GPIO_CONFIG));\r
46BOARD_GPIO_CONTROLLER_CONFIG mBoardGpioControllerConfigTable[] = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION };\r
47UINTN mBoardGpioControllerConfigTableLen = (sizeof(mBoardGpioControllerConfigTable) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG));\r
48UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};\r
49\r
50EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[1] = {\r
51 {\r
52 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
53 &gEfiPeiMasterBootModePpiGuid,\r
54 NULL\r
55 }\r
56};\r
57\r
58EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {\r
59 {\r
60 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
61 &gEfiPeiMemoryDiscoveredPpiGuid,\r
62 MemoryDiscoveredPpiNotifyCallback\r
63 }\r
64};\r
65\r
66EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[1] = {\r
67 {\r
68 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
69 &gEfiEndOfPeiSignalPpiGuid,\r
70 EndOfPeiSignalPpiNotifyCallback\r
71 }\r
72};\r
73\r
74EFI_PEI_STALL_PPI mStallPpi = {\r
75 PEI_STALL_RESOLUTION,\r
76 Stall\r
77};\r
78\r
79EFI_PEI_PPI_DESCRIPTOR mPpiStall[1] = {\r
80 {\r
81 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
82 &gEfiPeiStallPpiGuid,\r
83 &mStallPpi\r
84 }\r
85};\r
86\r
87/**\r
88 Set Mac address on chipset ethernet device.\r
89\r
90 @param Bus PCI Bus number of chipset ethernet device.\r
91 @param Device Device number of chipset ethernet device.\r
92 @param Func PCI Function number of chipset ethernet device.\r
93 @param MacAddr MAC Address to set.\r
94\r
95**/\r
96VOID\r
97EFIAPI\r
98SetLanControllerMacAddr (\r
99 IN CONST UINT8 Bus,\r
100 IN CONST UINT8 Device,\r
101 IN CONST UINT8 Func,\r
102 IN CONST UINT8 *MacAddr,\r
103 IN CONST UINT32 Bar0\r
104 )\r
105{\r
106 UINT32 Data32;\r
107 UINT16 PciVid;\r
108 UINT16 PciDid;\r
109 UINT32 Addr;\r
110 UINT32 MacVer;\r
111 volatile UINT8 *Wrote;\r
112 UINT32 DevPcieAddr;\r
113 UINT16 SaveCmdReg;\r
114 UINT32 SaveBarReg;\r
115\r
116 DevPcieAddr = PCI_LIB_ADDRESS (\r
117 Bus,\r
118 Device,\r
119 Func,\r
120 0\r
121 );\r
122\r
123 //\r
124 // Do nothing if not a supported device.\r
125 //\r
126 PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);\r
127 PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);\r
128 if((PciVid != V_IOH_MAC_VENDOR_ID) || (PciDid != V_IOH_MAC_DEVICE_ID)) {\r
129 return;\r
130 }\r
131\r
132 //\r
133 // Save current settings for PCI CMD/BAR registers\r
134 //\r
135 SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);\r
136 SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR);\r
137\r
138 //\r
65aec008 139 // Use predefined temporary memory resource\r
b303605e
MK
140 //\r
141 PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0);\r
142 PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);\r
143\r
144 Addr = Bar0 + R_IOH_MAC_GMAC_REG_8;\r
145 MacVer = *((volatile UINT32 *) (UINTN)(Addr));\r
146\r
147 DEBUG ((EFI_D_INFO, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",\r
148 (UINTN) Bus,\r
149 (UINTN) Device,\r
150 (UINTN) Func,\r
151 (UINTN) MacVer\r
152 ));\r
153\r
154 //\r
155 // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.\r
156 //\r
157 Addr = Bar0 + R_IOH_MAC_GMAC_REG_17;\r
158 Data32 = *((UINT32 *) (UINTN)(&MacAddr[0]));\r
159 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
160 Wrote = (volatile UINT8 *) (UINTN)(Addr);\r
161 DEBUG ((EFI_D_INFO, "%02x-%02x-%02x-%02x-",\r
162 (UINTN) Wrote[0],\r
163 (UINTN) Wrote[1],\r
164 (UINTN) Wrote[2],\r
165 (UINTN) Wrote[3]\r
166 ));\r
167\r
168 //\r
169 // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits\r
170 // and Address Enable (AE) bit.\r
171 //\r
172 Addr = Bar0 + R_IOH_MAC_GMAC_REG_16;\r
173 Data32 =\r
174 ((UINT32) MacAddr[4]) |\r
175 (((UINT32)MacAddr[5]) << 8) |\r
176 B_IOH_MAC_AE;\r
177 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
178 Wrote = (volatile UINT8 *) (UINTN)(Addr);\r
179\r
180 DEBUG ((EFI_D_INFO, "%02x-%02x\n", (UINTN) Wrote[0], (UINTN) Wrote[1]));\r
181\r
182 //\r
183 // Restore settings for PCI CMD/BAR registers\r
184 //\r
185 PciWrite32 ((DevPcieAddr + R_IOH_MAC_MEMBAR), SaveBarReg);\r
186 PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);\r
187}\r
188\r
406d8575
MK
189/**\r
190 Initialize state of I2C GPIO expanders.\r
191\r
192 @param PlatformType Platform type for GPIO expander init.\r
193\r
194**/\r
195EFI_STATUS\r
196EarlyPlatformConfigGpioExpanders (\r
69a0854b
MK
197 IN CONST EFI_PLATFORM_TYPE PlatformType,\r
198 EFI_BOOT_MODE BootMode\r
406d8575
MK
199 )\r
200{\r
201 EFI_STATUS Status;\r
202 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;\r
203 UINTN Length;\r
204 UINTN ReadLength;\r
205 UINT8 Buffer[2];\r
206\r
207 //\r
208 // Configure GPIO expanders for Galileo Gen 2\r
209 // Route I2C pins to Arduino header\r
210 // Set all GPIO expander pins connected to the Reset Button as inputs\r
211 //\r
212 if (PlatformType == GalileoGen2) {\r
213 //\r
214 // Configure AMUX1_IN (EXP2.P1_4) as an output\r
215 //\r
216 PlatformPcal9555GpioSetDir (\r
217 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.\r
218 12, // P1-4.\r
219 FALSE // Configure as output\r
220 );\r
221\r
222 //\r
223 // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector\r
224 //\r
225 PlatformPcal9555GpioSetLevel (\r
226 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.\r
227 12, // P1-4. \r
228 FALSE // Set pin low\r
229 );\r
230\r
231 //\r
232 // Configure Reset Button(EXP1.P1_7) as an input\r
233 //\r
234 PlatformPcal9555GpioSetDir (\r
235 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.\r
236 15, // P1-7.\r
237 TRUE\r
238 );\r
239\r
240 //\r
241 // Disable pullup on Reset Button(EXP1.P1_7)\r
242 //\r
243 PlatformPcal9555GpioDisablePull (\r
244 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.\r
245 15 // P1-7.\r
246 );\r
247\r
248 //\r
249 // Configure Reset Button(EXP2.P1_7) as an input\r
250 //\r
251 PlatformPcal9555GpioSetDir (\r
252 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.\r
253 15, // P1-7.\r
254 TRUE\r
255 );\r
256\r
257 //\r
258 // Disable pullup on Reset Button(EXP2.P1_7)\r
259 //\r
260 PlatformPcal9555GpioDisablePull (\r
261 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.\r
262 15 // P1-7.\r
263 );\r
69a0854b
MK
264\r
265 if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
266 //\r
267 // Read state of Reset Button - EXP2.P1_7\r
268 // This GPIO is pulled high when the button is not pressed\r
269 // This GPIO reads low when button is pressed\r
270 //\r
271 if (!PlatformPcal9555GpioGetState (\r
272 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2\r
273 15 // P1-7\r
274 )) {\r
275 DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));\r
276\r
277 //\r
278 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
279 //\r
280 QNCAltPortWrite (\r
281 QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
282 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
283 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
284 );\r
285 ResetWarm();\r
286 }\r
287 }\r
406d8575
MK
288 }\r
289\r
290 //\r
291 // Configure GPIO expanders for Galileo Gen 2\r
292 // Set all GPIO expander pins connected to the Reset Button as inputs\r
293 // Route I2C pins to Arduino header\r
294 //\r
295 if (PlatformType == Galileo) {\r
296 //\r
297 // Detect the I2C Slave Address of the GPIO Expander\r
298 //\r
299 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {\r
300 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;\r
301 } else {\r
302 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;\r
303 }\r
304 DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));\r
305\r
306 //\r
307 // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector\r
308 //\r
309\r
310 //\r
311 // Select GPIO Expander GPORT1\r
312 //\r
313 Length = 2;\r
314 Buffer[0] = 0x18; //sub-address\r
315 Buffer[1] = 0x01; //data\r
316 Status = I2cWriteMultipleByte (\r
317 I2CSlaveAddress,\r
318 EfiI2CSevenBitAddrMode,\r
319 &Length,\r
320 &Buffer\r
321 );\r
322 ASSERT_EFI_ERROR (Status);\r
323\r
324 //\r
325 // Read "Pin Direction" of GPIO Expander GPORT1\r
326 //\r
327 Length = 1;\r
328 ReadLength = 1;\r
329 Buffer[1] = 0x1C;\r
330 Status = I2cReadMultipleByte (\r
331 I2CSlaveAddress,\r
332 EfiI2CSevenBitAddrMode,\r
333 &Length,\r
334 &ReadLength,\r
335 &Buffer[1]\r
336 );\r
337 ASSERT_EFI_ERROR (Status);\r
338\r
339 //\r
340 // Configure GPIO Expander GPORT1_BIT5 as an output\r
341 //\r
342 Length = 2;\r
343 Buffer[0] = 0x1C; //sub-address\r
344 Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data\r
345\r
346 Status = I2cWriteMultipleByte (\r
347 I2CSlaveAddress,\r
348 EfiI2CSevenBitAddrMode,\r
349 &Length,\r
350 &Buffer\r
351 );\r
352 ASSERT_EFI_ERROR (Status);\r
353\r
354 //\r
355 // Set GPIO Expander GPORT1_BIT5 low\r
356 //\r
357 Length = 2;\r
358 Buffer[0] = 0x09; //sub-address\r
359 Buffer[1] = (UINT8)(~BIT5); //data\r
360\r
361 Status = I2cWriteMultipleByte (\r
362 I2CSlaveAddress,\r
363 EfiI2CSevenBitAddrMode,\r
364 &Length,\r
365 &Buffer\r
366 );\r
367 ASSERT_EFI_ERROR (Status);\r
368\r
369 //\r
370 // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs\r
371 //\r
372\r
373 //\r
374 // Select GPIO Expander GPORT5\r
375 //\r
376 Length = 2;\r
377 Buffer[0] = 0x18;\r
378 Buffer[1] = 0x05;\r
379 Status = I2cWriteMultipleByte (\r
380 I2CSlaveAddress,\r
381 EfiI2CSevenBitAddrMode,\r
382 &Length,\r
383 &Buffer\r
384 );\r
385 ASSERT_EFI_ERROR (Status);\r
386\r
387 //\r
388 // Read "Pin Direction" of GPIO Expander GPORT5\r
389 //\r
390 Length = 1;\r
391 ReadLength = 1;\r
392 Buffer[1] = 0x1C;\r
393 Status = I2cReadMultipleByte (\r
394 I2CSlaveAddress,\r
395 EfiI2CSevenBitAddrMode,\r
396 &Length,\r
397 &ReadLength,\r
398 &Buffer[1]\r
399 );\r
400 ASSERT_EFI_ERROR (Status);\r
401\r
402 //\r
403 // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs\r
404 //\r
405 Length = 2;\r
406 Buffer[0] = 0x1C;\r
407 Buffer[1] = Buffer[1] | BIT0 | BIT1;\r
408 Status = I2cWriteMultipleByte (\r
409 I2CSlaveAddress,\r
410 EfiI2CSevenBitAddrMode,\r
411 &Length,\r
412 &Buffer\r
413 );\r
414 ASSERT_EFI_ERROR (Status);\r
69a0854b
MK
415\r
416 if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
417 //\r
418 // Read state of RESET_N_SHLD (GPORT5_BIT0)\r
419 //\r
420 Buffer[1] = 5;\r
421 Length = 1;\r
422 ReadLength = 1;\r
423 Status = I2cReadMultipleByte (\r
424 I2CSlaveAddress,\r
425 EfiI2CSevenBitAddrMode,\r
426 &Length,\r
427 &ReadLength,\r
428 &Buffer[1]\r
429 );\r
430 ASSERT_EFI_ERROR (Status);\r
431\r
432 //\r
433 // Return the state of GPORT5_BIT0\r
434 //\r
435 if ((Buffer[1] & BIT0) == 0) {\r
436 DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));\r
437\r
438 //\r
439 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
440 //\r
441 QNCAltPortWrite (\r
442 QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
443 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
444 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
445 );\r
446 ResetWarm();\r
447 }\r
448 }\r
406d8575
MK
449 }\r
450\r
451 return EFI_SUCCESS;\r
452}\r
453\r
b303605e
MK
454/**\r
455 This is the entrypoint of PEIM\r
456\r
457 @param FileHandle Handle of the file being invoked.\r
458 @param PeiServices Describes the list of possible PEI Services.\r
459\r
460 @retval EFI_SUCCESS if it completed successfully.\r
461**/\r
462EFI_STATUS\r
463EFIAPI\r
464PeiInitPlatform (\r
465 IN EFI_PEI_FILE_HANDLE FileHandle,\r
466 IN CONST EFI_PEI_SERVICES **PeiServices\r
467 )\r
468{\r
469 EFI_STATUS Status;\r
470 EFI_BOOT_MODE BootMode;\r
471 EFI_PEI_STALL_PPI *StallPpi;\r
472 EFI_PEI_PPI_DESCRIPTOR *StallPeiPpiDescriptor;\r
473 EFI_FV_FILE_INFO FileInfo;\r
474 EFI_PLATFORM_TYPE PlatformType;\r
475\r
476 PlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);\r
477\r
478 //\r
479 // Initialize Firmware Volume security.\r
480 // This must be done before any firmware volume accesses (excl. BFV)\r
481 //\r
482 Status = PeiInitializeFvSecurity();\r
483 ASSERT_EFI_ERROR (Status);\r
484\r
485 //\r
486 // Do any early platform specific initialization.\r
487 //\r
488 EarlyPlatformInit ();\r
489\r
490 //\r
491 // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based\r
492 // to improve recovery performance.\r
493 //\r
494 Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);\r
495 ASSERT_EFI_ERROR (Status);\r
496 //\r
497 // The follow conditional check only works for memory-mapped FFS,\r
498 // so we ASSERT that the file is really a MM FFS.\r
499 //\r
500 ASSERT (FileInfo.Buffer != NULL);\r
501 if (!(((UINTN) FileInfo.Buffer <= (UINTN) PeiInitPlatform) &&\r
502 ((UINTN) PeiInitPlatform <= (UINTN) FileInfo.Buffer + FileInfo.BufferSize))) {\r
503 //\r
504 // Now that module in memory, update the\r
505 // PPI that describes the Stall to other modules\r
506 //\r
507 Status = PeiServicesLocatePpi (\r
508 &gEfiPeiStallPpiGuid,\r
509 0,\r
510 &StallPeiPpiDescriptor,\r
511 (VOID **) &StallPpi\r
512 );\r
513\r
514 if (!EFI_ERROR (Status)) {\r
515\r
516 Status = PeiServicesReInstallPpi (\r
517 StallPeiPpiDescriptor,\r
518 &mPpiStall[0]\r
519 );\r
520 } else {\r
521\r
522 Status = PeiServicesInstallPpi (&mPpiStall[0]);\r
523 }\r
524 return Status;\r
525 }\r
526\r
527 //\r
528 // Initialize System Phys\r
529 //\r
530\r
531 // Program USB Phy\r
532 InitializeUSBPhy();\r
533\r
534 //\r
535 // Do platform specific logic to create a boot mode\r
536 //\r
537 Status = UpdateBootMode ((EFI_PEI_SERVICES**)PeiServices, &BootMode);\r
538 ASSERT_EFI_ERROR (Status);\r
539\r
540 //\r
541 // Signal possible dependent modules that there has been a\r
542 // final boot mode determination\r
543 //\r
544 if (!EFI_ERROR(Status)) {\r
545 Status = PeiServicesInstallPpi (&mPpiBootMode[0]);\r
546 ASSERT_EFI_ERROR (Status);\r
547 }\r
548\r
549 if (BootMode != BOOT_ON_S3_RESUME) {\r
550 QNCClearSmiAndWake ();\r
551 }\r
552\r
553 DEBUG ((EFI_D_INFO, "MRC Entry\n"));\r
554 MemoryInit ((EFI_PEI_SERVICES**)PeiServices);\r
555\r
556 //\r
557 // Do Early PCIe init.\r
558 //\r
559 DEBUG ((EFI_D_INFO, "Early PCIe controller initialization\n"));\r
560 PlatformPciExpressEarlyInit (PlatformType);\r
561\r
562\r
563 DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n"));\r
564 PlatformErratasPostMrc ();\r
565\r
406d8575
MK
566 //\r
567 //\r
568 //\r
569 DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));\r
69a0854b 570 EarlyPlatformConfigGpioExpanders (PlatformType, BootMode);\r
406d8575 571\r
b303605e
MK
572 //\r
573 // Now that all of the pre-permanent memory activities have\r
574 // been taken care of, post a call-back for the permanent-memory\r
575 // resident services, such as HOB construction.\r
576 // PEI Core will switch stack after this PEIM exit. After that the MTRR\r
577 // can be set.\r
578 //\r
579 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);\r
580 ASSERT_EFI_ERROR (Status);\r
581/*\r
582\r
583 if (BootMode != BOOT_ON_S3_RESUME) {\r
584 Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);\r
585 ASSERT_EFI_ERROR (Status);\r
586 }\r
587*/\r
588 if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
589 PeiServicesRegisterForShadow (FileHandle);\r
590 }\r
591\r
592 return Status;\r
593}\r
594\r
595EFI_STATUS\r
596EFIAPI\r
597EndOfPeiSignalPpiNotifyCallback (\r
598 IN EFI_PEI_SERVICES **PeiServices,\r
599 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
600 IN VOID *Ppi\r
601 )\r
602{\r
603 EFI_STATUS Status;\r
604\r
605 DEBUG ((EFI_D_INFO, "End of PEI Signal Callback\n"));\r
606\r
607 //\r
608 // Restore the flash region to be UC\r
609 // for both normal boot as we build a Resource Hob to\r
610 // describe this region as UC to DXE core.\r
611 //\r
612 WriteBackInvalidateDataCacheRange (\r
613 (VOID *) (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),\r
614 PcdGet32 (PcdFlashAreaSize)\r
615 );\r
616\r
617 Status = MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress), PcdGet32 (PcdFlashAreaSize), CacheUncacheable);\r
618 ASSERT_EFI_ERROR (Status);\r
619\r
620 return EFI_SUCCESS;\r
621}\r
622\r
623/**\r
624 This function will initialize USB Phy registers associated with QuarkSouthCluster.\r
625\r
626 @param VOID No Argument\r
627\r
628 @retval EFI_SUCCESS All registers have been initialized\r
629**/\r
630VOID\r
631EFIAPI\r
632InitializeUSBPhy (\r
633 VOID\r
634 )\r
635{\r
636 UINT32 RegData32;\r
637\r
638 /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock\r
639 * and Port2 as a USB device port, the following sequence must be followed\r
640 *\r
641 **/\r
642\r
643 // Sideband register write to USB AFE (Phy)\r
644 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT);\r
645 RegData32 &= ~(BIT1);\r
646 //\r
647 // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.\r
648 // For port 0 & 1 as host and port 2 as device.\r
649 //\r
650 RegData32 |= (BIT8 | BIT7);\r
651 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT, RegData32);\r
652\r
653 //\r
654 // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.\r
655 //\r
656 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG);\r
657 RegData32 &= ~(BIT10 | BIT9 | BIT8 | BIT7);\r
658 RegData32 |= (BIT10 | BIT7);\r
659 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG, RegData32);\r
660\r
661 // Sideband register write to USB AFE (Phy)\r
662 // (pllbypass) to bypass/Disable PLL before switch\r
663 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);\r
664 RegData32 |= BIT29;\r
665 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);\r
666\r
667 // Sideband register write to USB AFE (Phy)\r
668 // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.\r
669 // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))\r
670 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);\r
671 RegData32 |= BIT1;\r
672 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);\r
673\r
674 // Sideband register write to USB AFE (Phy)\r
675 // (divide by 8) to achieve internal 480MHz clock\r
676 // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)\r
677 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);\r
678 RegData32 &= ~(BIT5 | BIT4 | BIT3);\r
679 RegData32 |= BIT6;\r
680 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);\r
681\r
682 // Sideband register write to USB AFE (Phy)\r
683 // Clear (pllbypass)\r
684 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);\r
685 RegData32 &= ~BIT29;\r
686 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);\r
687\r
688 // Sideband register write to USB AFE (Phy)\r
689 // Set (startlock) to force the PLL FSM to restart the lock\r
690 // sequence due to input clock/freq switch.\r
691 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);\r
692 RegData32 |= BIT24;\r
693 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);\r
694\r
695 // At this point the PLL FSM and COMP FSM will complete\r
696\r
697}\r
698\r
699/**\r
700 This function provides early platform Thermal sensor initialisation.\r
701**/\r
702VOID\r
703EFIAPI\r
704EarlyPlatformThermalSensorInit (\r
705 VOID\r
706 )\r
707{\r
708 DEBUG ((EFI_D_INFO, "Early Platform Thermal Sensor Init\n"));\r
709\r
710 //\r
711 // Set Thermal sensor mode.\r
712 //\r
713 QNCThermalSensorSetRatiometricMode ();\r
714\r
715 //\r
716 // Enable RMU Thermal sensor with a Catastrophic Trip point.\r
717 //\r
718 QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS);\r
719\r
720 //\r
721 // Lock all RMU Thermal sensor control & trip point registers.\r
722 //\r
723 QNCThermalSensorLockAllRegisters ();\r
724}\r
725\r
726/**\r
727 Print early platform info messages includeing the Stage1 module that's\r
728 running, MFH item list and platform data item list.\r
729**/\r
730VOID\r
731EFIAPI\r
732EarlyPlatformInfoMessages (\r
733 VOID\r
734 )\r
735{\r
736 DEBUG_CODE_BEGIN ();\r
737 QUARK_EDKII_STAGE1_HEADER *Edk2ImageHeader;\r
738\r
739 //\r
740 // Find which 'Stage1' image we are running and print the details\r
741 //\r
742 Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);\r
743 DEBUG ((EFI_D_INFO, "\n************************************************************\n"));\r
744\r
745 switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {\r
746 case QUARK_STAGE1_BOOT_IMAGE_TYPE:\r
747 DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));\r
748 break;\r
749\r
750 case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:\r
751 DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));\r
752 break;\r
753\r
754 default:\r
755 DEBUG ((EFI_D_INFO, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n"));\r
756 break;\r
757 }\r
758 DEBUG (\r
759 (EFI_D_INFO,\r
760 "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,\r
761 (UINTN) PcdGet32 (PcdFlashFvMainBase),\r
762 (UINTN) PcdGet32 (PcdFlashFvMainSize)\r
763 ));\r
764\r
765 DEBUG (\r
766 (EFI_D_INFO,\r
767 "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,\r
768 (UINTN) PcdGet32 (PcdFlashFvPayloadBase),\r
769 (UINTN) PcdGet32 (PcdFlashFvPayloadSize)\r
770 ));\r
771\r
772 DEBUG ((EFI_D_INFO, "************************************************************\n\n"));\r
773\r
774 DEBUG_CODE_END ();\r
775}\r
776\r
777/**\r
778 Check if system reset due to error condition.\r
779\r
780 @param ClearErrorBits If TRUE clear error flags and value bits.\r
781\r
782 @retval TRUE if system reset due to error condition.\r
783 @retval FALSE if NO reset error conditions.\r
784**/\r
785BOOLEAN\r
786CheckForResetDueToErrors (\r
787 IN BOOLEAN ClearErrorBits\r
788 )\r
789{\r
790 UINT32 RegValue;\r
791 BOOLEAN ResetDueToError;\r
792\r
793 ResetDueToError = FALSE;\r
794\r
795 //\r
796 // Check if RMU reset system due to access violations.\r
65aec008 797 // RMU updates a SOC Unit register before resetting the system.\r
b303605e
MK
798 //\r
799 RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);\r
800 if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) {\r
801 ResetDueToError = TRUE;\r
802\r
803 DEBUG (\r
804 (EFI_D_ERROR,\r
805 "\nReset due to access violation: %s %s %s %s\n",\r
806 ((RegValue & B_CFG_STICKY_RW_IMR_VIOLATION) != 0) ? L"'IMR'" : L".",\r
807 ((RegValue & B_CFG_STICKY_RW_DECC_VIOLATION) != 0) ? L"'DECC'" : L".",\r
808 ((RegValue & B_CFG_STICKY_RW_SMM_VIOLATION) != 0) ? L"'SMM'" : L".",\r
809 ((RegValue & B_CFG_STICKY_RW_HMB_VIOLATION) != 0) ? L"'HMB'" : L"."\r
810 ));\r
811\r
812 //\r
813 // Clear error bits.\r
814 //\r
815 if (ClearErrorBits) {\r
816 RegValue &= ~(B_CFG_STICKY_RW_VIOLATION);\r
817 QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, RegValue);\r
818 }\r
819 }\r
820\r
821 return ResetDueToError;\r
822}\r
823\r
824/**\r
825 This function provides early platform initialization.\r
826\r
827 @param PlatformInfo Pointer to platform Info structure.\r
828\r
829**/\r
830VOID\r
831EFIAPI\r
832EarlyPlatformInit (\r
833 VOID\r
834 )\r
835{\r
836 EFI_PLATFORM_TYPE PlatformType;\r
837\r
838 PlatformType = (EFI_PLATFORM_TYPE) PcdGet16 (PcdPlatformType);\r
839\r
840 DEBUG ((EFI_D_INFO, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN) PlatformType));\r
841\r
842 //\r
843 // Check if system reset due to error condition.\r
844 //\r
845 if (CheckForResetDueToErrors (TRUE)) {\r
846 if(FeaturePcdGet (WaitIfResetDueToError)) {\r
69a0854b
MK
847 DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n"));\r
848 MicroSecondDelay(10000000);\r
b303605e
MK
849 }\r
850 }\r
851\r
852 //\r
853 // Display platform info messages.\r
854 //\r
855 EarlyPlatformInfoMessages ();\r
856\r
857 //\r
858 // Early Legacy Gpio Init.\r
859 //\r
860 EarlyPlatformLegacyGpioInit (PlatformType);\r
861\r
862 //\r
863 // Early platform Legacy GPIO manipulation depending on GPIOs\r
864 // setup by EarlyPlatformLegacyGpioInit.\r
865 //\r
866 EarlyPlatformLegacyGpioManipulation (PlatformType);\r
867\r
868 //\r
869 // Early platform specific GPIO Controller init & manipulation.\r
870 // Combined for sharing of temp. memory bar.\r
871 //\r
872 EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType);\r
873\r
874 //\r
875 // Early Thermal Sensor Init.\r
876 //\r
877 EarlyPlatformThermalSensorInit ();\r
878\r
879 //\r
880 // Early Lan Ethernet Mac Init.\r
881 //\r
882 EarlyPlatformMacInit (\r
883 PcdGetPtr (PcdIohEthernetMac0),\r
884 PcdGetPtr (PcdIohEthernetMac1)\r
885 );\r
886}\r
887\r
888/**\r
889 This function provides early platform Legacy GPIO initialisation.\r
890\r
891 @param PlatformType Platform type for GPIO init.\r
892\r
893**/\r
894VOID\r
895EFIAPI\r
896EarlyPlatformLegacyGpioInit (\r
897 IN CONST EFI_PLATFORM_TYPE PlatformType\r
898 )\r
899{\r
900 BOARD_LEGACY_GPIO_CONFIG *LegacyGpioConfig;\r
901 UINT32 NewValue;\r
902 UINT32 GpioBaseAddress;\r
903\r
904 //\r
905 // Assert if platform type outside table range.\r
906 //\r
907 ASSERT ((UINTN) PlatformType < mBoardLegacyGpioConfigTableLen);\r
908 LegacyGpioConfig = &mBoardLegacyGpioConfigTable[(UINTN) PlatformType];\r
909\r
910 GpioBaseAddress = (UINT32)PcdGet16 (PcdGbaIoBaseAddress);\r
911\r
912 NewValue = 0x0;\r
913 //\r
914 // Program QNC GPIO Registers.\r
915 //\r
916 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellEnable;\r
917 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL, NewValue );\r
918 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellIoSelect;\r
919 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL, NewValue);\r
920 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellLvlForInputOrOutput;\r
921 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL, NewValue);\r
922 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerPositiveEdge;\r
923 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL, NewValue );\r
924 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerNegativeEdge;\r
925 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL, NewValue);\r
926 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellGPEEnable;\r
927 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL, NewValue);\r
928 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellSMIEnable;\r
929 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL, NewValue );\r
930 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerStatus;\r
931 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL, NewValue);\r
932 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellNMIEnable;\r
933 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL, NewValue);\r
934\r
935 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellEnable;\r
936 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL, NewValue );\r
937 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellIoSelect;\r
938 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL, NewValue) ;\r
939 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellLvlForInputOrOutput;\r
940 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, NewValue);\r
941 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerPositiveEdge;\r
942 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL, NewValue );\r
943 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerNegativeEdge;\r
944 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL, NewValue) ;\r
945 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellGPEEnable;\r
946 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL, NewValue);\r
947 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellSMIEnable;\r
948 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL, NewValue );\r
949 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerStatus;\r
950 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL, NewValue) ;\r
951 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellNMIEnable;\r
952 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL, NewValue);\r
953}\r
954\r
955/**\r
956 Performs any early platform specific Legacy GPIO manipulation.\r
957\r
958 @param PlatformType Platform type GPIO manipulation.\r
959\r
960**/\r
961VOID\r
962EFIAPI\r
963EarlyPlatformLegacyGpioManipulation (\r
964 IN CONST EFI_PLATFORM_TYPE PlatformType\r
965 )\r
966{\r
967 if (PlatformType == CrossHill) {\r
968\r
969 //\r
970 // Pull TPM reset low for 80us (equivalent to cold reset, Table 39\r
971 // Infineon SLB9645 Databook), then pull TPM reset high and wait for\r
972 // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon\r
973 // SLB9645 Databook states TPM is ready to receive command after 30ms\r
974 // but section 4.7 states some TPM commands may take longer to execute\r
975 // upto 150ms after test).\r
976 //\r
977\r
978 PlatformLegacyGpioSetLevel (\r
979 R_QNC_GPIO_RGLVL_RESUME_WELL,\r
980 PLATFORM_RESUMEWELL_TPM_RST_GPIO,\r
981 FALSE\r
982 );\r
983 MicroSecondDelay (80);\r
984\r
985 PlatformLegacyGpioSetLevel (\r
986 R_QNC_GPIO_RGLVL_RESUME_WELL,\r
987 PLATFORM_RESUMEWELL_TPM_RST_GPIO,\r
988 TRUE\r
989 );\r
990 MicroSecondDelay (150000);\r
991 }\r
992\r
993}\r
994\r
995/**\r
996 Performs any early platform specific GPIO Controller init & manipulation.\r
997\r
998 @param PlatformType Platform type for GPIO init & manipulation.\r
999\r
1000**/\r
1001VOID\r
1002EFIAPI\r
1003EarlyPlatformGpioCtrlerInitAndManipulation (\r
1004 IN CONST EFI_PLATFORM_TYPE PlatformType\r
1005 )\r
1006{\r
1007 UINT32 IohGpioBase;\r
1008 UINT32 Data32;\r
1009 UINT32 Addr;\r
1010 BOARD_GPIO_CONTROLLER_CONFIG *GpioConfig;\r
1011 UINT32 DevPcieAddr;\r
1012 UINT16 SaveCmdReg;\r
1013 UINT32 SaveBarReg;\r
1014 UINT16 PciVid;\r
1015 UINT16 PciDid;\r
1016\r
1017 ASSERT ((UINTN) PlatformType < mBoardGpioControllerConfigTableLen);\r
1018 GpioConfig = &mBoardGpioControllerConfigTable[(UINTN) PlatformType];\r
1019\r
1020 IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);\r
1021\r
1022 DevPcieAddr = PCI_LIB_ADDRESS (\r
1023 PcdGet8 (PcdIohGpioBusNumber),\r
1024 PcdGet8 (PcdIohGpioDevNumber),\r
1025 PcdGet8 (PcdIohGpioFunctionNumber),\r
1026 0\r
1027 );\r
1028\r
1029 //\r
1030 // Do nothing if not a supported device.\r
1031 //\r
1032 PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);\r
1033 PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);\r
1034 if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {\r
1035 return;\r
1036 }\r
1037\r
1038 //\r
1039 // Save current settings for PCI CMD/BAR registers.\r
1040 //\r
1041 SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);\r
1042 SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));\r
1043\r
1044 //\r
65aec008 1045 // Use predefined temporary memory resource.\r
b303605e
MK
1046 //\r
1047 PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);\r
1048 PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);\r
1049\r
1050 //\r
1051 // Gpio Controller Init Tasks.\r
1052 //\r
1053\r
1054 //\r
1055 // IEN- Interrupt Enable Register\r
1056 //\r
1057 Addr = IohGpioBase + GPIO_INTEN;\r
1058 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1059 Data32 |= (GpioConfig->IntEn & 0x000FFFFF);\r
1060 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1061\r
1062 //\r
1063 // ISTATUS- Interrupt Status Register\r
1064 //\r
1065 Addr = IohGpioBase + GPIO_INTSTATUS;\r
1066 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1067 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1068\r
1069 //\r
1070 // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR\r
1071 //\r
1072 Addr = IohGpioBase + GPIO_SWPORTA_DR;\r
1073 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1074 Data32 |= (GpioConfig->PortADR & 0x000FFFFF);\r
1075 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1076\r
1077 //\r
1078 // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input\r
1079 //\r
1080 Addr = IohGpioBase + GPIO_SWPORTA_DDR;\r
1081 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1082 Data32 |= (GpioConfig->PortADir & 0x000FFFFF);\r
1083 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1084\r
1085 //\r
1086 // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked\r
1087 //\r
1088 Addr = IohGpioBase + GPIO_INTMASK;\r
1089 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1090 Data32 |= (GpioConfig->IntMask & 0x000FFFFF);\r
1091 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1092\r
1093 //\r
1094 // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive\r
1095 //\r
1096 Addr = IohGpioBase + GPIO_INTTYPE_LEVEL;\r
1097 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1098 Data32 |= (GpioConfig->IntType & 0x000FFFFF);\r
1099 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1100\r
1101 //\r
1102 // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low\r
1103 //\r
1104 Addr = IohGpioBase + GPIO_INT_POLARITY;\r
1105 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1106 Data32 |= (GpioConfig->IntPolarity & 0x000FFFFF);\r
1107 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1108\r
1109 //\r
1110 // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce\r
1111 //\r
1112 Addr = IohGpioBase + GPIO_DEBOUNCE;\r
1113 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1114 Data32 |= (GpioConfig->Debounce & 0x000FFFFF);\r
1115 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1116\r
1117 //\r
1118 // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)\r
1119 //\r
1120 Addr = IohGpioBase + GPIO_LS_SYNC;\r
1121 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]\r
1122 Data32 |= (GpioConfig->LsSync & 0x000FFFFF);\r
1123 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1124\r
1125 //\r
1126 // Gpio Controller Manipulation Tasks.\r
1127 //\r
1128\r
1129 if (PlatformType == (EFI_PLATFORM_TYPE) Galileo) {\r
1130 //\r
1131 // Reset Cypress Expander on Galileo Platform\r
1132 //\r
1133 Addr = IohGpioBase + GPIO_SWPORTA_DR;\r
1134 Data32 = *((volatile UINT32 *) (UINTN)(Addr));\r
1135 Data32 |= BIT4; // Cypress Reset line controlled by GPIO<4>\r
1136 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1137\r
1138 Data32 = *((volatile UINT32 *) (UINTN)(Addr));\r
1139 Data32 &= ~BIT4; // Cypress Reset line controlled by GPIO<4>\r
1140 *((volatile UINT32 *) (UINTN)(Addr)) = Data32;\r
1141\r
1142 }\r
1143\r
1144 //\r
1145 // Restore settings for PCI CMD/BAR registers\r
1146 //\r
1147 PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);\r
1148 PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);\r
1149}\r
1150\r
1151/**\r
1152 Performs any early platform init of SoC Ethernet Mac devices.\r
1153\r
1154 @param IohMac0Address Mac address to program into Mac0 device.\r
1155 @param IohMac1Address Mac address to program into Mac1 device.\r
1156\r
1157**/\r
1158VOID\r
1159EFIAPI\r
1160EarlyPlatformMacInit (\r
1161 IN CONST UINT8 *IohMac0Address,\r
1162 IN CONST UINT8 *IohMac1Address\r
1163 )\r
1164{\r
1165 BOOLEAN SetMacAddr;\r
1166\r
1167 //\r
1168 // Set chipset MAC0 address if configured.\r
1169 //\r
1170 SetMacAddr =\r
1171 (CompareMem (ChipsetDefaultMac, IohMac0Address, sizeof (ChipsetDefaultMac))) != 0;\r
1172 if (SetMacAddr) {\r
1173 if ((*(IohMac0Address) & BIT0) != 0) {\r
1174 DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",\r
1175 (UINTN) IOH_MAC0_BUS_NUMBER,\r
1176 (UINTN) IOH_MAC0_DEVICE_NUMBER,\r
1177 (UINTN) IOH_MAC0_FUNCTION_NUMBER\r
1178 ));\r
1179 ASSERT (FALSE);\r
1180 } else {\r
1181 SetLanControllerMacAddr (\r
1182 IOH_MAC0_BUS_NUMBER,\r
1183 IOH_MAC0_DEVICE_NUMBER,\r
1184 IOH_MAC0_FUNCTION_NUMBER,\r
1185 IohMac0Address,\r
1186 (UINT32) PcdGet64(PcdIohMac0MmioBase)\r
1187 );\r
1188 }\r
1189 } else {\r
1190 DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",\r
1191 (UINTN) IOH_MAC0_BUS_NUMBER,\r
1192 (UINTN) IOH_MAC0_DEVICE_NUMBER,\r
1193 (UINTN) IOH_MAC0_FUNCTION_NUMBER\r
1194 ));\r
1195 }\r
1196\r
1197 //\r
1198 // Set chipset MAC1 address if configured.\r
1199 //\r
1200 SetMacAddr =\r
1201 (CompareMem (ChipsetDefaultMac, IohMac1Address, sizeof (ChipsetDefaultMac))) != 0;\r
1202 if (SetMacAddr) {\r
1203 if ((*(IohMac1Address) & BIT0) != 0) {\r
1204 DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",\r
1205 (UINTN) IOH_MAC1_BUS_NUMBER,\r
1206 (UINTN) IOH_MAC1_DEVICE_NUMBER,\r
1207 (UINTN) IOH_MAC1_FUNCTION_NUMBER\r
1208 ));\r
1209 ASSERT (FALSE);\r
1210 } else {\r
1211 SetLanControllerMacAddr (\r
1212 IOH_MAC1_BUS_NUMBER,\r
1213 IOH_MAC1_DEVICE_NUMBER,\r
1214 IOH_MAC1_FUNCTION_NUMBER,\r
1215 IohMac1Address,\r
1216 (UINT32) PcdGet64(PcdIohMac1MmioBase)\r
1217 );\r
1218 }\r
1219 } else {\r
1220 DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",\r
1221 (UINTN) IOH_MAC1_BUS_NUMBER,\r
1222 (UINTN) IOH_MAC1_DEVICE_NUMBER,\r
1223 (UINTN) IOH_MAC1_FUNCTION_NUMBER\r
1224 ));\r
1225 }\r
1226}\r
1227\r