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