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