]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
670fefc1c36901f5351e73fd4910f99ca6f52f37
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformInitPei / PchInitPeim.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14
15 Module Name:
16
17 PchInitPeim.c
18
19 Abstract:
20
21 Do Early PCH platform initialization.
22
23
24 --*/
25
26 #include "PlatformEarlyInit.h"
27 #include "Ppi/PchPlatformPolicy.h"
28 #include "PchRegs.h"
29 #include <Ppi/PchUsbPolicy.h>
30 #include "Ppi/PchInit.h"
31 #include <Library/PcdLib.h>
32
33 EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID;
34
35 #define MC_PMSTS_OFFSET 0xC
36
37 #define DEFAULT_BUS_INFO 0x2020
38
39
40 #define PCI_LPC_BASE (0x8000F800)
41 #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))
42 #define PCIEX_BASE_ADDRESS 0xE0000000
43 #define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
44
45 VOID
46 PchPolicySetupInit (
47 IN CONST EFI_PEI_SERVICES **PeiServices,
48 IN SYSTEM_CONFIGURATION *SystemConfiguration
49 );
50
51 VOID
52 PchInitInterrupt (
53 IN SYSTEM_CONFIGURATION *SystemConfiguration
54 );
55
56 EFI_STATUS
57 InstallPeiPchUsbPolicy (
58 IN CONST EFI_PEI_SERVICES **PeiServices
59 );
60
61 #ifndef __GNUC__
62 #pragma warning (push)
63 #pragma warning (disable : 4245)
64 #pragma warning (pop)
65 #endif
66
67 UINT8
68 ReadCmosBank1Byte (
69 IN UINT8 Address
70 )
71 {
72 UINT8 Data;
73
74 IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
75 Data = IoRead8 (R_PCH_RTC_EXT_TARGET);
76 return Data;
77 }
78
79 VOID
80 WriteCmosBank1Byte (
81 IN UINT8 Address,
82 IN UINT8 Data
83 )
84 {
85 IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
86 IoWrite8(R_PCH_RTC_EXT_TARGET, Data);
87 }
88
89 /**
90 Turn off system if needed.
91
92 @param PeiServices Pointer to PEI Services
93 @param CpuIo Pointer to CPU I/O Protocol
94
95 @retval None.
96
97 **/
98 VOID
99 CheckPowerOffNow (
100 VOID
101 )
102 {
103 UINT16 Pm1Sts;
104
105 //
106 // Read and check the ACPI registers
107 //
108 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
109 if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) == B_PCH_ACPI_PM1_STS_PWRBTN) {
110 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
111 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
112 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN);
113
114 //
115 // Should not return
116 //
117 CpuDeadLoop();
118 }
119 }
120
121 VOID
122 ClearPowerState (
123 IN SYSTEM_CONFIGURATION *SystemConfiguration
124 )
125 {
126 UINT8 Data8;
127 UINT16 Data16;
128 UINT32 Data32;
129
130 //
131 // Check for PowerState option for AC power loss and program the chipset
132 //
133
134 //
135 // Clear PWROK (Set to Clear)
136 //
137 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_PWROK_FLR);
138
139 //
140 // Clear Power Failure Bit (Set to Clear)
141 //
142 // TODO: Check if it is OK to clear here
143 //
144
145 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR);
146
147 //
148 // Clear the GPE and PM enable
149 //
150 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00);
151 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32) 0x00);
152
153 //
154 // Halt the TCO timer
155 //
156 Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT);
157 Data16 |= B_PCH_TCO_CNT_TMR_HLT;
158 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16);
159
160 //
161 // if NMI_NOW_STS is set
162 // NMI NOW bit is "Write '1' to clear"
163 //
164 Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI);
165 if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) {
166 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI, B_PCH_ILB_GNMI_NMIN);
167 }
168
169 //
170 // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use.
171 //
172 Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
173 if ((Data32 & B_PCH_TCO_STS_SECOND_TO) == B_PCH_TCO_STS_SECOND_TO)
174 {
175 #if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0))
176 WriteCmosBank1Byte (
177 EFI_CMOS_PERFORMANCE_FLAGS,
178 ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET
179 );
180 #endif
181 }
182 }
183
184 /*++
185
186 Clear any SMI status or wake status left over from boot.
187
188 **/
189 VOID
190 ClearSmiAndWake (
191 VOID
192 )
193 {
194 UINT16 Pm1Sts;
195 UINT32 Gpe0Sts;
196 UINT32 SmiSts;
197
198 //
199 // Read the ACPI registers
200 //
201 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
202 Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
203 SmiSts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS);
204
205 //
206 // Register Wake up reason for S4. This information is used to notify
207 // WinXp of wake up reason because S4 wake up path doesn't keep SCI.
208 // This is important for Viiv(Quick resume) platform.
209 //
210
211 //
212 // First Clear CMOS S4 Wake up flag.
213 //
214 WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0);
215
216 //
217 // Check wake up reason and set CMOS accordingly. Currently checks
218 // Power button, USB, PS/2.
219 // Note : PS/2 wake up is using GPI13 (IO_PME). This must be changed depending
220 // on board design.
221 //
222 if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) {
223 WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);
224 }
225
226 //
227 // Clear any SMI or wake state from the boot
228 //
229 Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR | B_PCH_ACPI_PM1_STS_PWRBTN);
230
231 Gpe0Sts |=
232 (
233 B_PCH_ACPI_GPE0a_STS_CORE_GPIO |
234 B_PCH_ACPI_GPE0a_STS_SUS_GPIO |
235 B_PCH_ACPI_GPE0a_STS_PME_B0 |
236 B_PCH_ACPI_GPE0a_STS_BATLOW |
237 B_PCH_ACPI_GPE0a_STS_PCI_EXP |
238 B_PCH_ACPI_GPE0a_STS_GUNIT_SCI |
239 B_PCH_ACPI_GPE0a_STS_PUNIT_SCI |
240 B_PCH_ACPI_GPE0a_STS_SWGPE |
241 B_PCH_ACPI_GPE0a_STS_HOT_PLUG
242 );
243
244 SmiSts |=
245 (
246 B_PCH_SMI_STS_SMBUS |
247 B_PCH_SMI_STS_PERIODIC |
248 B_PCH_SMI_STS_TCO |
249 B_PCH_SMI_STS_SWSMI_TMR |
250 B_PCH_SMI_STS_APM |
251 B_PCH_SMI_STS_ON_SLP_EN |
252 B_PCH_SMI_STS_BIOS
253 );
254
255 //
256 // Write them back
257 //
258 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts);
259 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts);
260 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts);
261 }
262
263 /**
264 Issue PCI-E Secondary Bus Reset
265
266 @param Bus Bus number of the bridge
267 @param Dev Devices number of the bridge
268 @param Fun Function number of the bridge
269
270 @retval EFI_SUCCESS
271
272 **/
273 EFI_STATUS
274 PcieSecondaryBusReset (
275 IN CONST EFI_PEI_SERVICES **PeiServices,
276 IN UINT8 Bus,
277 IN UINT8 Dev,
278 IN UINT8 Fun
279 )
280 {
281 EFI_PEI_STALL_PPI *PeiStall;
282 EFI_STATUS Status;
283
284 Status = (**PeiServices).LocatePpi (
285 PeiServices,
286 &gEfiPeiStallPpiGuid,
287 0,
288 NULL,
289 (void **)&PeiStall
290 );
291 ASSERT_EFI_ERROR (Status);
292
293 //
294 // Issue secondary bus reset
295 //
296 MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS);
297
298 //
299 // Wait 1ms
300 //
301 PeiStall->Stall (PeiServices, PeiStall, 1000);
302
303
304 //
305 // Clear the reset bit
306 // Note: The PCIe spec suggests 100ms delay between clearing this bit and accessing
307 // the device's config space. Since we will not access the config space until we enter DXE
308 // we don't put delay expressly here.
309 //
310 MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS));
311
312 return EFI_SUCCESS;
313 }
314
315 /**
316 Provide hard reset PPI service.
317 To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9).
318
319 @param PeiServices General purpose services available to every PEIM.
320
321 @retval Not return System reset occured.
322 @retval EFI_DEVICE_ERROR Device error, could not reset the system.
323
324 **/
325 EFI_STATUS
326 EFIAPI
327 IchReset (
328 IN CONST EFI_PEI_SERVICES **PeiServices
329 )
330 {
331 IoWrite8 (
332 R_PCH_RST_CNT,
333 V_PCH_RST_CNT_HARDSTARTSTATE
334 );
335
336 IoWrite8 (
337 R_PCH_RST_CNT,
338 V_PCH_RST_CNT_HARDRESET
339 );
340
341 //
342 // System reset occured, should never reach at this line.
343 //
344 ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
345 CpuDeadLoop();
346
347 return EFI_DEVICE_ERROR;
348 }
349
350 VOID
351 PchPlatformLpcInit (
352 IN CONST EFI_PEI_SERVICES **PeiServices,
353 IN SYSTEM_CONFIGURATION *SystemConfiguration
354 )
355 {
356 EFI_BOOT_MODE BootMode;
357 UINT8 Data8;
358 UINT16 Data16;
359
360 (*PeiServices)->GetBootMode(PeiServices, &BootMode);
361
362 if ((BootMode != BOOT_ON_S3_RESUME)) {
363
364 //
365 // Clear all pending SMI. On S3 clear power button enable so it wll not generate an SMI
366 //
367 ClearSmiAndWake ();
368 }
369
370 ClearPowerState (SystemConfiguration);
371
372 //
373 // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH EDS
374 // early in POST after each power up directly after coin-cell battery insertion.
375 // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1".
376 // The UIP bit status may be polled by software (i.e ME FW) during POST.
377 //
378 if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
379 //
380 // Set and clear SET bit in RTC_REGB
381 //
382 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
383 Data8 = IoRead8(R_PCH_RTC_TARGET);
384 Data8 |= B_PCH_RTC_REGISTERB_SET;
385 IoWrite8(R_PCH_RTC_TARGET, Data8);
386
387 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
388 Data8 &= (~B_PCH_RTC_REGISTERB_SET);
389 IoWrite8(R_PCH_RTC_TARGET, Data8);
390
391 //
392 // Clear the UIP bit in RTC_REGA
393 //
394 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA);
395 IoWrite8(R_PCH_RTC_TARGET, 0x00);
396 }
397
398 //
399 // Disable SERR NMI and IOCHK# NMI in port 61
400 //
401 Data8 = IoRead8 (R_PCH_NMI_SC);
402 IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 | B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN));
403
404 //
405 // Enable Bus Master, I/O, Mem, and SERR on LPC bridge
406 //
407 Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND);
408 MmioWrite16 (
409 MmPciAddress (0,
410 DEFAULT_PCI_BUS_NUMBER_PCH,
411 PCI_DEVICE_NUMBER_PCH_LPC,
412 PCI_FUNCTION_NUMBER_PCH_LPC,
413 R_PCH_LPC_COMMAND
414 ),
415 (Data16 |
416 B_PCH_LPC_COMMAND_IOSE |
417 B_PCH_LPC_COMMAND_MSE |
418 B_PCH_LPC_COMMAND_BME |
419 B_PCH_LPC_COMMAND_SERR_EN)
420 );
421
422 //
423 // Set Stretch S4 to 1-2s per marketing request.
424 // Note: This register is powered by RTC well.
425 //
426 MmioAndThenOr8 (
427 PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ,
428 (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW),
429 (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE | V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S)
430 );
431
432 }
433
434 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
435
436 VOID
437 UARTInit (
438 IN SYSTEM_CONFIGURATION *SystemConfiguration
439 )
440 {
441 if (0) { // for fix cr4 issue
442 //
443 // Program and enable PMC Base.
444 //
445 IoWrite32 (0xCF8, PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
446 IoWrite32 (0xCFC, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
447
448 if( (SystemConfiguration->PcuUart1 == 1) &&
449 (SystemConfiguration->LpssHsuart0Enabled == 0)){
450 //
451 // Enable COM1 for debug message output.
452 //
453 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, BIT24);
454
455 //
456 //Enable internal UART3 port(COM1)
457 //
458 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
459 MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L
460 MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0
461 MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);
462 } else {
463 //
464 //Disable UART3(COM1)
465 //
466 MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
467 MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07);
468 MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07);
469 MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
470
471
472 if (SystemConfiguration->LpssHsuart0Enabled == 1){
473 //
474 //Valleyview BIOS Specification Vol2,17.2
475 //LPSS_UART1 ¨C set each pad PAD_CONF0.Func_Pin_Mux to function 1:
476 //
477 MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
478 MmioOr8 (IO_BASE_ADDRESS + 0x0090, 0x01);
479 MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
480 MmioOr8 (IO_BASE_ADDRESS + 0x00D0, 0x01);
481
482 }
483 }
484
485
486 DEBUG ((EFI_D_ERROR, "EnableInternalUart\n"));
487 } else {
488 //
489 // If SIO UART interface selected
490 //Disable internal UART port(COM1)
491 //
492 if (0) {; // For fix CR4 issue
493 MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
494 MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
495 MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
496 MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
497
498 }
499 }
500 }
501
502 VOID
503 IchRcrbInit (
504 IN CONST EFI_PEI_SERVICES **PeiServices,
505 IN SYSTEM_CONFIGURATION *SystemConfiguration
506 )
507 {
508 EFI_BOOT_MODE BootMode;
509
510 (*PeiServices)->GetBootMode(PeiServices, &BootMode);
511
512 //
513 // If not recovery or flash update boot path. set the BIOS interface lock down bit.
514 // It locks the top swap bit and BIOS boot strap bits from being changed.
515 //
516 if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
517 MmioOr8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_BILD);
518 }
519
520 //
521 // Disable the Watchdog timer expiration from causing a system reset
522 //
523 MmioOr8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, B_PCH_PMC_PM_CFG_NO_REBOOT);
524
525 //
526 // Initial RCBA according to the PeiRCBA table
527 //
528 if ((BootMode == BOOT_ON_S3_RESUME)) {
529 //
530 // We are resuming from S3
531 // Enable HPET if enabled in Setup
532 // ICH Config register Offset 0x3404 bit 7 (Enable) = 1,
533 // Bit 1:0 (Mem I/O address) = 0 (0xFED00000)
534 //
535 MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
536
537 }
538
539 }
540
541
542 EFI_STATUS
543 PlatformPchInit (
544 IN SYSTEM_CONFIGURATION *SystemConfiguration,
545 IN CONST EFI_PEI_SERVICES **PeiServices,
546 IN UINT16 PlatformType
547 )
548 {
549 EFI_STATUS Status;
550 EFI_BOOT_MODE BootMode;
551
552 Status = PeiServicesGetBootMode (&BootMode);
553 ASSERT_EFI_ERROR (Status);
554
555 IchRcrbInit (PeiServices, SystemConfiguration);
556
557 if (BootMode == BOOT_IN_RECOVERY_MODE) {
558 InstallPeiPchUsbPolicy(PeiServices);
559 }
560
561 //
562 // PCH Policy Initialization based on Setup variable.
563 //
564 PchPolicySetupInit (PeiServices, SystemConfiguration);
565
566 UARTInit(SystemConfiguration);
567
568 PchPlatformLpcInit (PeiServices, SystemConfiguration);
569
570 return EFI_SUCCESS;
571 }
572
573 /**
574
575 Returns the state of A16 inversion
576
577 @retval TRUE A16 is inverted
578 @retval FALSE A16 is not inverted
579
580 **/
581 BOOLEAN
582 IsA16Inverted (
583 )
584 {
585 UINT8 Data;
586 Data = MmioRead8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS);
587 return (Data & B_PCH_RCRB_GCS_TS) ? TRUE : FALSE;
588 }
589
590 VOID
591 PchPolicySetupInit (
592 IN CONST EFI_PEI_SERVICES **PeiServices,
593 IN SYSTEM_CONFIGURATION *SystemConfiguration
594 )
595 {
596 EFI_STATUS Status;
597 EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc;
598 PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi;
599 PCH_HPET_CONFIG *HpetConfig;
600 PCH_PCIE_CONFIG *PcieConfig;
601 UINT8 Index;
602 PCH_IOAPIC_CONFIG *IoApicConfig;
603 PCH_LPSS_CONFIG *LpssConfig;
604 UINT32 SpiHsfsReg;
605 UINT32 SpiFdodReg;
606
607 //
608 // Disable codec ALC-262
609 //
610 UINT32 IoBase;
611
612 //
613 // Install Pch Platform Policy PPI. As we depend on Pch Init PPI so we are executed after
614 // PchInit PEIM. Thus we can insure PCH Initialization is performed when we install the Pch Platform Policy PPI,
615 // as PchInit PEIM registered a notification function on our policy PPI.
616 //
617 // --cr-- For better code structure / modularity, we should use a notification function on Pch Init PPI to perform
618 // actions that depend on PchInit PEIM's initialization.
619 //
620 //Todo: confirm if we need update to PCH_PLATFORM_POLICY_PPI_REVISION_5
621 //
622 DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - Start\n"));
623
624 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PchPlatformPolicyPpiDesc);
625 ASSERT_EFI_ERROR (Status);
626
627 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), (void **)&PchPlatformPolicyPpi);
628 ASSERT_EFI_ERROR (Status);
629
630 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), (void **)&HpetConfig);
631 ASSERT_EFI_ERROR (Status);
632
633 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), (void **)&PcieConfig);
634 ASSERT_EFI_ERROR (Status);
635
636 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), (void **)&IoApicConfig);
637 ASSERT_EFI_ERROR (Status);
638
639 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_LPSS_CONFIG), (void **)&LpssConfig);
640 ASSERT_EFI_ERROR (Status);
641
642 PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_1;
643 PchPlatformPolicyPpi->BusNumber = DEFAULT_PCI_BUS_NUMBER_PCH;
644 PchPlatformPolicyPpi->SpiBase = SPI_BASE_ADDRESS;
645 PchPlatformPolicyPpi->PmcBase = PMC_BASE_ADDRESS;
646 PchPlatformPolicyPpi->IoBase = IO_BASE_ADDRESS;
647 PchPlatformPolicyPpi->IlbBase = ILB_BASE_ADDRESS;
648 PchPlatformPolicyPpi->PUnitBase = PUNIT_BASE_ADDRESS;
649 PchPlatformPolicyPpi->MphyBase = MPHY_BASE_ADDRESS;
650 PchPlatformPolicyPpi->Rcba = RCBA_BASE_ADDRESS;
651 PchPlatformPolicyPpi->AcpiBase = ACPI_BASE_ADDRESS;
652 PchPlatformPolicyPpi->GpioBase = GPIO_BASE_ADDRESS;
653 PchPlatformPolicyPpi->SataMode = SystemConfiguration->SataType;
654 PchPlatformPolicyPpi->EnableRmh = SystemConfiguration->PchUsbRmh;
655
656 PchPlatformPolicyPpi->EhciPllCfgEnable = SystemConfiguration->EhciPllCfgEnable;
657
658
659 PchPlatformPolicyPpi->HpetConfig = HpetConfig;
660 PchPlatformPolicyPpi->PcieConfig = PcieConfig;
661 PchPlatformPolicyPpi->IoApicConfig = IoApicConfig;
662
663 PchPlatformPolicyPpi->HpetConfig->Enable = SystemConfiguration->Hpet;
664 PchPlatformPolicyPpi->HpetConfig->Base = HPET_BASE_ADDRESS;
665 PchPlatformPolicyPpi->IoApicConfig->IoApicId = 0x01;
666
667 //
668 // Set LPSS configuration according to setup value.
669 //
670 PchPlatformPolicyPpi->LpssConfig->LpssPciModeEnabled = SystemConfiguration->LpssPciModeEnabled;
671
672 PchPlatformPolicyPpi->LpssConfig->Dma1Enabled = SystemConfiguration->LpssDma1Enabled;
673 PchPlatformPolicyPpi->LpssConfig->I2C0Enabled = SystemConfiguration->LpssI2C0Enabled;
674 PchPlatformPolicyPpi->LpssConfig->I2C1Enabled = SystemConfiguration->LpssI2C1Enabled;
675 PchPlatformPolicyPpi->LpssConfig->I2C2Enabled = SystemConfiguration->LpssI2C2Enabled;
676 PchPlatformPolicyPpi->LpssConfig->I2C3Enabled = SystemConfiguration->LpssI2C3Enabled;
677 PchPlatformPolicyPpi->LpssConfig->I2C4Enabled = SystemConfiguration->LpssI2C4Enabled;
678 PchPlatformPolicyPpi->LpssConfig->I2C5Enabled = SystemConfiguration->LpssI2C5Enabled;
679 PchPlatformPolicyPpi->LpssConfig->I2C6Enabled = SystemConfiguration->LpssI2C6Enabled;
680
681 PchPlatformPolicyPpi->LpssConfig->Dma0Enabled = SystemConfiguration->LpssDma0Enabled;;
682 PchPlatformPolicyPpi->LpssConfig->Pwm0Enabled = SystemConfiguration->LpssPwm0Enabled;
683 PchPlatformPolicyPpi->LpssConfig->Pwm1Enabled = SystemConfiguration->LpssPwm1Enabled;
684 PchPlatformPolicyPpi->LpssConfig->Hsuart0Enabled = SystemConfiguration->LpssHsuart0Enabled;
685 PchPlatformPolicyPpi->LpssConfig->Hsuart1Enabled = SystemConfiguration->LpssHsuart1Enabled;
686 PchPlatformPolicyPpi->LpssConfig->SpiEnabled = SystemConfiguration->LpssSpiEnabled;
687
688
689 for (Index = 0; Index < PCH_PCIE_MAX_ROOT_PORTS; Index++) {
690 PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] = SystemConfiguration->PcieRootPortSpeed[Index];
691 }
692
693 SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_HSFS);
694 if ((SpiHsfsReg & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
695 MmioWrite32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOC, V_PCH_SPI_FDOC_FDSS_FSDM);
696 SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOD);
697 if (SpiFdodReg == V_PCH_SPI_FDBAR_FLVALSIG) {
698 }
699 //
700 // Disable codec ALC-262
701 //
702 if (SystemConfiguration->DisableCodec262 == 1) {
703 IoBase = MmioRead32 (MmPciAddress (0,
704 PchPlatformPolicyPpi->BusNumber,
705 PCI_DEVICE_NUMBER_PCH_LPC,
706 PCI_FUNCTION_NUMBER_PCH_LPC,
707 0
708 ) + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
709 MmioAnd32 ((UINTN) (IoBase + 0x270), (UINT32) (~0x07));
710 }
711 }
712
713 PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
714 PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid;
715 PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi;
716
717 //
718 // Install PCH Platform Policy PPI
719 //
720 Status = (**PeiServices).InstallPpi (
721 PeiServices,
722 PchPlatformPolicyPpiDesc
723 );
724 ASSERT_EFI_ERROR (Status);
725
726 DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - End\n"));
727 }
728
729 EFI_STATUS
730 InstallPeiPchUsbPolicy (
731 IN CONST EFI_PEI_SERVICES **PeiServices
732 )
733 {
734 EFI_STATUS Status = EFI_SUCCESS;
735
736 EFI_PEI_PPI_DESCRIPTOR *PeiPchUsbPolicyPpiDesc;
737 PCH_USB_POLICY_PPI *PeiPchUsbPolicyPpi;
738 PCH_USB_CONFIG *UsbConfig;
739
740 DEBUG ((EFI_D_INFO, "InstallPeiPchUsbPolicy...\n"));
741
742 //
743 // Allocate descriptor and PPI structures. Since these are dynamically updated
744 // we cannot do a global variable PPI.
745 //
746 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PeiPchUsbPolicyPpiDesc);
747
748
749 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_POLICY_PPI), (void **)&PeiPchUsbPolicyPpi);
750
751
752
753 Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), (void **)&UsbConfig);
754
755
756 //
757 // Initiate PCH USB policy.
758 //
759 PeiPchUsbPolicyPpi->Revision = PCH_USB_POLICY_PPI_REVISION_1;
760 UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE;
761 UsbConfig->UsbPerPortCtl = PCH_DEVICE_DISABLE;
762 UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE;
763
764 UsbConfig->Usb20OverCurrentPins[0] = PchUsbOverCurrentPin0;
765
766 UsbConfig->Usb20OverCurrentPins[1] = PchUsbOverCurrentPin0;
767
768 UsbConfig->Usb20OverCurrentPins[2] = PchUsbOverCurrentPin1;
769
770 UsbConfig->Usb20OverCurrentPins[3] = PchUsbOverCurrentPin1;
771
772
773 //
774 // Enable USB Topology control and program the topology setting for every USB port
775 // See Platform Design Guide for description of topologies
776 //
777 //
778 // Port 0: ~10.9", Port 1: ~10.1", Port 2: ~11.2", Port 3: ~11.5", Port 4: ~3.7", Port 5: ~2.7", Port 6: ~4.1"
779 // Port 7: ~4.5", Port 8: ~10.7", Port 9: ~10.5", Port 10: ~4.2", Port 11: ~4.3", Port 12: ~3.1", Port 13: ~2.9"
780 //
781
782 //
783 // Port 0: ~3.5", Port 1: ~4.1", Port 2: ~4.6", Port 3: ~4.6", Port 4: ~12.5", Port 5: ~12", Port 6: ~5.1"
784 // Port 7: ~5.1", Port 8: ~4.1", Port 9: ~4.1", Port 10: ~14.5", Port 11: ~12.8", Port 12: ~12.9", Port 13: ~14.6"
785 //
786 UsbConfig->Usb20PortLength[0] = 0x53;
787 UsbConfig->Usb20PortLength[1] = 0x49;
788 UsbConfig->Usb20PortLength[2] = 0x47;
789 UsbConfig->Usb20PortLength[3] = 0x80;
790
791 PeiPchUsbPolicyPpi->Mode = EHCI_MODE;
792
793 PeiPchUsbPolicyPpi->EhciMemBaseAddr = PcdGet32(PcdPeiIchEhciControllerMemoryBaseAddress);
794
795 PeiPchUsbPolicyPpi->EhciMemLength = (UINT32) 0x400 * PchEhciControllerMax;
796
797 PeiPchUsbPolicyPpi->XhciMemBaseAddr = 0;
798
799 PeiPchUsbPolicyPpi->UsbConfig = UsbConfig;
800
801 PeiPchUsbPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
802
803 PeiPchUsbPolicyPpiDesc->Guid = &gPchUsbPolicyPpiGuid;
804
805 PeiPchUsbPolicyPpiDesc->Ppi = PeiPchUsbPolicyPpi;
806
807 //
808 // Install PCH USB Policy PPI
809 //
810 Status = (**PeiServices).InstallPpi (PeiServices, PeiPchUsbPolicyPpiDesc);
811
812 return Status;
813 }