diff options
Diffstat (limited to 'ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/graphicsinit.c')
-rw-r--r-- | ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/graphicsinit.c | 1094 |
1 files changed, 1094 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/graphicsinit.c b/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/graphicsinit.c new file mode 100644 index 0000000..2b1af13 --- /dev/null +++ b/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/graphicsinit.c @@ -0,0 +1,1094 @@ +/** @file + DXE driver for Initializing SystemAgent Graphics initialization. + +@copyright + Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "GraphicsInit.h" +#include EFI_PROTOCOL_DEFINITION (LegacyBios) +#include EFI_PROTOCOL_DEFINITION (GopComponentName2) +#ifndef AMI_OVERRIDE_FOR_INTEL_GOP_SUPPORT +#if (defined(IntelSaGopDriver_SUPPORT) && (IntelSaGopDriver_SUPPORT == 1)) +#include "Include\Protocol\IntelSaGopDriver.h" +#endif +#endif +UINT64 GTTMMADR; +UINTN MCHBAR_BASE; +UINT8 rP1GraphicsFreq; +EFI_EVENT mExitPmAuthEvent; + +DXE_PLATFORM_SA_POLICY_PROTOCOL *mDxePlatformSaPolicy; +GOP_COMPONENT_NAME2_PROTOCOL *GopComponentName2Protocol = NULL; + +/// +/// RC6 Settings +/// +BOOT_SCRIPT_REGISTER_SETTING gSaGtRC6Registers[] = { + 0x0, + 0xA090, + 0xFFFFFFFF, + 0x0, + /// + /// RC1e - RC6/6p - RC6pp Wake Rate Limits + /// + 0x0, + 0xA098, + 0xFFFFFFFF, + 0x3E80000, + 0x0, + 0xA09C, + 0xFFFFFFFF, + 0x00280000, + 0x0, + 0xA0A8, + 0xFFFFFFFF, + 0x1E848, + 0x0, + 0xA0AC, + 0xFFFFFFFF, + 0x19, + /// + /// Render/Video/Blitter Idle Max Count + /// + 0x0, + 0x2054, + 0x0, + 0xA, + 0x0, + 0x12054, + 0x0, + 0xA, + 0x0, + 0x22054, + 0x0, + 0xA, + 0x0, + 0x1a054, + 0x0, + 0xA, + /// + /// RC Sleep / RCx Thresholds + /// + 0x0, + 0xA0B0, + 0xFFFFFFFF, + 0, + 0x0, + 0xA0B4, + 0xFFFFFFFF, + 0x3E8, + 0x0, + 0xA0B8, + 0xFFFFFFFF, + 0xC350, + /// + /// RP Settings + /// + 0x0, + 0xA010, + 0xFFFFFFFF, + 0xF4240, + 0x0, + 0xA014, + 0xFFFFFFFF, + 0x12060000, + 0x0, + 0xA02C, + 0xFFFFFFFF, + 0x0000E808, + 0x0, + 0xA030, + 0xFFFFFFFF, + 0x0003BD08, + 0x0, + 0xA068, + 0xFFFFFFFF, + 0x000101D0, + 0x0, + 0xA06C, + 0xFFFFFFFF, + 0x00055730, + 0x0, + 0xA070, + 0xFFFFFFFF, + 0xA +}; + +/// +/// PM Lock Settings +/// +BOOT_SCRIPT_REGISTER_SETTING gSaGtPmLockBits[] = { + 0x0, + 0xA248, + 0xFFFFFFFF, + BIT31, + 0x0, + 0xA004, + 0xFFFFFFFF, + BIT4, + 0x0, + 0xA080, + 0xFFFFFFFF, + BIT2, + 0x0, + 0xA180, + 0xFFFFFFFF, + BIT31 +}; + +EFI_STATUS +PmInit ( + IN EFI_HANDLE ImageHandle, + IN DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy + ) +/** + Initialize GT PowerManagement of SystemAgent. + + @param[in] ImageHandle - Handle for the image of this driver + @param[in] DxePlatformSaPolicy - SA DxePlatformPolicy protocol + + @retval EFI_SUCCESS - GT Power Management initialization complete +**/ +{ + UINT8 i; + UINT32 RegOffset; + UINT32 Data32; + UINT32 Data32And; + UINT32 Data32Or; + UINT32 Data32Mask; + UINT32 Result; + CPU_STEPPING CpuSteppingId; + CPU_FAMILY CpuFamilyId; + + CpuFamilyId = GetCpuFamily(); + CpuSteppingId = GetCpuStepping(); + + /// + /// Multi Threaded Force Wake + /// + RegOffset = 0xA180; + Data32 = BIT5; + Mmio32 (GTTMMADR, RegOffset) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + 1, + &Data32 + ); + + RegOffset = 0xA188; + Data32 = 0x00010001; + Mmio32 (GTTMMADR, RegOffset) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + 1, + &Data32 + ); + /// + /// Force Wake Acknowledge Bit + /// + RegOffset = 0x130044; + Data32Mask = BIT0; + Result = 1; + PollGtReady (GTTMMADR, RegOffset, Data32Mask, Result); + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + &Data32Mask, + &Result, + 50, + 200000 + ); + + /// + /// Enable counters except Power Meter + /// + Data32And = 0xFFFFFFFF; + Data32Or = 0x16; + Mmio32AndThenOr (GTTMMADR, 0xA248, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA248), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + + /// + /// GFXPAUSE Settings + /// + Data32 = 0x70020; + + + if (((CpuFamilyId == EnumCpuHsw) && (CpuSteppingId < EnumHswC0) ) || + ((CpuFamilyId == EnumCpuHswUlt) && (CpuSteppingId < EnumHswUltC0)) || + ((CpuFamilyId == EnumCpuCrw) && (CpuSteppingId < EnumCrwC0) )) { + Data32 |= 0xFFFF; + } + + Mmio32 (GTTMMADR, 0xA000) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA000), + 1, + &Data32 + ); + + + /// + /// ECO Settings + /// BIT28 = 1 GFX will be blocked from accessing memory (go=0) during CPD enter + /// BIT26 = 1 indicates to PCU that we are doing a fifo block due to RC6 and not CPD + /// BIT[24:22] = 100 RC6 Control + /// + RegOffset = 0xA180; + Data32And = 0xFFFFFFFF; + Data32Or = BIT28 + BIT26; + if (DxePlatformSaPolicy->IgdConfig->RenderStandby) { + Data32And = (UINT32)~(BIT23 + BIT22); + Data32Or |= BIT24; + } + + /// + /// Force CPD Non-IA. for steppings less than C0 for HSW/CRW + /// + if (((CpuFamilyId == EnumCpuHsw) && (CpuSteppingId < EnumHswC0)) || + ((CpuFamilyId == EnumCpuCrw) && (CpuSteppingId < EnumCrwC0))) { + Data32Or |= BIT30; + } + /// + /// Force CPD Block memory bits. for stepping less than C0 for HSW/ULT/CRW + /// + if (((CpuFamilyId == EnumCpuHsw) && (CpuSteppingId < EnumHswC0) ) || + ((CpuFamilyId == EnumCpuHswUlt) && (CpuSteppingId < EnumHswUltC0)) || + ((CpuFamilyId == EnumCpuCrw) && (CpuSteppingId < EnumCrwC0) )) { + Data32And &= (UINT32)~(BIT28); + Data32Or &= (UINT32)~(BIT28); + } + + Mmio32AndThenOr (GTTMMADR, RegOffset, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + + /// + /// Clock Gating Settings + /// + Data32 = 0x3FD; + Mmio32 (GTTMMADR, 0x9424) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x9424), + 1, + &Data32 + ); + + /// + /// Enable Unit Level Clock Gates + /// + Data32 = 0x80; + Mmio32 (GTTMMADR, 0x9400) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x9400), + 1, + &Data32 + ); + + Data32 = 0x40401000; + Mmio32 (GTTMMADR, 0x9404) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x9404), + 1, + &Data32 + ); + + Data32 = 0; + Mmio32 (GTTMMADR, 0x9408) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x9408), + 1, + &Data32 + ); + + Data32 = 0x02000001; + Mmio32 (GTTMMADR, 0x940c) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x940c), + 1, + &Data32 + ); + + Data32 = 0x08000000; + Mmio32 (GTTMMADR, 0xA008) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA008), + 1, + &Data32 + ); + /// + /// RC6 Settings + /// + for (i = 0; i < sizeof (gSaGtRC6Registers) / sizeof (BOOT_SCRIPT_REGISTER_SETTING); ++i) { + RegOffset = gSaGtRC6Registers[i].Offset; + Data32And = gSaGtRC6Registers[i].AndMask; + Data32Or = gSaGtRC6Registers[i].OrMask; + + Mmio32AndThenOr (GTTMMADR, RegOffset, Data32And, Data32Or); + + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + } + + /// + /// RP Control + /// + Data32 = 0xB92; + Mmio32 (GTTMMADR, 0xA024) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA024), + 1, + &Data32 + ); + + /// + /// HW RC6 Control Settings + /// + Data32 = 0; + + if (DxePlatformSaPolicy->IgdConfig->RenderStandby) { + Data32 = 0x88040000; + } + + Mmio32 (GTTMMADR, 0xA090) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA090), + 1, + &Data32 + ); + + /// + /// Video frequency request + /// + Data32 = 0x08000000; + Mmio32 (GTTMMADR, 0xA00C) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0xA00C), + 1, + &Data32 + ); + + /// + /// RC6 Settings + /// + /// + /// Wait for Mailbox ready + /// + Data32Mask = BIT31; + Result = 0; + + PollGtReady (GTTMMADR, 0x138124, Data32Mask, Result); + + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138124), + &Data32Mask, + &Result, + 50, + 200000 + ); + + /// + /// Mailbox Data - RC6 VIDS + /// + Data32 = 0x0; + Mmio32 (GTTMMADR, 0x138128) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138128), + 1, + &Data32 + ); + + /// + /// Mailbox Command + /// + Data32 = 0x80000004; + Mmio32 (GTTMMADR, 0x138124) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138124), + 1, + &Data32 + ); + + /// + /// Wait for Mailbox ready + /// + Data32Mask = BIT31; + Result = 0; + + PollGtReady (GTTMMADR, 0x138124, Data32Mask, Result); + + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138124), + &Data32Mask, + &Result, + 50, + 200000 + ); + + /// + /// Enable PM Interrupts + /// + Data32 = 0x3000076; + Mmio32 (GTTMMADR, 0x4402C) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x4402C), + 1, + &Data32 + ); + + /// + /// RC6 setting + /// + if (mDxePlatformSaPolicy->IgdConfig->RenderStandby) { + /// + /// Software RC state - RC6 + /// + Data32 = 0x40000; + Mmio32 (GTTMMADR, 0xA094) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (GTTMMADR + 0xA094), + 1, + &Data32 + ); + } + + /// + /// PM Lock Settings + /// + for (i = 0; i < sizeof (gSaGtPmLockBits) / sizeof (BOOT_SCRIPT_REGISTER_SETTING); ++i) { + RegOffset = gSaGtPmLockBits[i].Offset; + Data32And = gSaGtPmLockBits[i].AndMask; + Data32Or = gSaGtPmLockBits[i].OrMask; + + Mmio32AndThenOr (GTTMMADR, RegOffset, Data32And, Data32Or); + + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + } + return EFI_SUCCESS; +} + +EFI_STATUS +PavpInit ( + IN EFI_HANDLE ImageHandle, + IN DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy + ) +/** + Initialize PAVP feature of SystemAgent. + + @param[in] ImageHandle - Handle for the image of this driver + @param[in] DxePlatformSaPolicy - SA DxePlatformPolicy protocol + + @retval EFI_SUCCESS - PAVP initialization complete +**/ +{ + + UINT32 DwordData; + UINT32 PcmBase; + CPU_STEPPING CpuSteppingId; + CPU_FAMILY CpuFamilyId; + + CpuFamilyId = GetCpuFamily(); + CpuSteppingId = GetCpuStepping(); + + McD0PciCfg32And (R_SA_PAVPC, ~(B_SA_PAVPC_HVYMODSEL_MASK | B_SA_PAVPC_PCMBASE_MASK | B_SA_PAVPC_PAVPE_MASK | B_SA_PAVPC_PCME_MASK)); + McD0PciCfg16Or (R_SA_PAVPC, B_SA_PAVPC_PCME_MASK | B_SA_PAVPC_PAVPE_MASK); + PcmBase = ((UINT32) RShiftU64 ((McD0PciCfg32 (R_SA_TOLUD)), 20)) - PAVP_PCM_SIZE_1_MB; + McD0PciCfg32Or (R_SA_PAVPC, (UINT32) LShiftU64 (PcmBase, 20)); + + if ((CpuFamilyId == EnumCpuHsw) || + (CpuFamilyId == EnumCpuHswUlt) || + (CpuFamilyId == EnumCpuCrw) + ){ + McD0PciCfg32Or (R_SA_PAVPC, (BIT4)); + } + + DwordData = McD0PciCfg32 (R_SA_PAVPC); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 0, + 0, + R_SA_PAVPC)), + 1, + &DwordData + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +PostPmInitExitPmAuth ( + VOID + ) +/** + Do Post GT PM Init Steps after VBIOS Initialization. + + @retval EFI_SUCCESS Succeed. +**/ +{ + UINT32 RegOffset; + UINT32 Data32; + EFI_STATUS Status; + UINT32 Data32Mask; + UINT32 Result; + UINT16 Data16; + CHAR16 *DriverVersion; + UINTN Index; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL; + + /// + /// Get the platform setup policy. + /// + Status = gBS->LocateProtocol (&gDxePlatformSaPolicyGuid, NULL, (VOID **) &mDxePlatformSaPolicy); + ASSERT_EFI_ERROR (Status); + + /// + /// only 32bit read/write is legal for device 0:2:0 + /// + GTTMMADR = (UINT64) (McD2PciCfg32 (R_SA_IGD_GTTMMADR)); + GTTMMADR = LShiftU64 ((UINT64) McD2PciCfg32 (R_SA_IGD_GTTMMADR + 4), 32) | (GTTMMADR); + + /// + /// Save the current GTMMADR value into S3 resume script before other S3 resume items in this function. + /// GTTMMADR may have been modified by the PCI enumeration code at this point, + /// but not saved into the S3 resume script yet. + /// + /// + /// only 32bit read/write is legal for device 0:2:0 + /// + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 2, + 0, + R_SA_IGD_GTTMMADR)), + 1, + >TMMADR + ); + + /// + /// only 32bit read/write is legal for device 0:2:0 + /// + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 2, + 0, + R_SA_IGD_GTTMMADR + 4)), + 1, + (&(UINT32) GTTMMADR) + 1 + ); + + GTTMMADR = GTTMMADR &~(BIT2 | BIT1); + + /// + /// Enable Bus Master, I/O and Memory access on 0:2:0 + /// + McD2PciCfg16Or (R_SA_IGD_CMD, (BIT2 | BIT1)); + Data16 = McD2PciCfg16(R_SA_IGD_CMD); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (MmPciAddress (0, 0, 2, 0, R_SA_IGD_CMD)), + 1, + &Data16 + ); + + /// + /// Deassert Force Wake + RegOffset = 0xA188; + Data32 = 0x00010000; + Mmio32 (GTTMMADR, RegOffset) = Data32; + + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + 1, + &Data32 + ); + + RegOffset = 0x130044; + Data32Mask = BIT0; + Result = 0; + PollGtReady (GTTMMADR, RegOffset, Data32Mask, Result); + + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + &Data32Mask, + &Result, + 50, + 200000 + ); + + RegOffset = 0xA188; + Data32 = 0x00000001; + Mmio32 (GTTMMADR, RegOffset) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + RegOffset), + 1, + &Data32 + ); + + + Status = gBS->LocateProtocol ( + &gEfiLegacyBiosProtocolGuid, + NULL, + (VOID **) &LegacyBios + ); + + +#ifndef AMI_OVERRIDE_FOR_INTEL_GOP_SUPPORT +#if (defined(IntelSaGopDriver_SUPPORT) && (IntelSaGopDriver_SUPPORT == 1)) +{ + EFI_PHYSICAL_ADDRESS VbtAddress; + UINT32 VbtSize; + PLATFORM_GOP_POLICY_PROTOCOL *PlatformGOPPolicy; + EFI_GUID PlatformGOPPolicyGuid = EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID; + EFI_STATUS Status2 = EFI_SUCCESS; + // + // Locate Platform GOP policy protocol + // + Status = gBS->LocateProtocol (&PlatformGOPPolicyGuid, NULL, &PlatformGOPPolicy); + if (!EFI_ERROR(Status)) { + Status2 = PlatformGOPPolicy->GetVbtData(&VbtAddress, &VbtSize); + if (!EFI_ERROR(Status2)) LegacyBios = NULL; + } +} +#endif +#endif // AMI_OVERRIDE_FOR_INTEL_GOP_SUPPORT + + if (!LegacyBios) { + Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid, NULL, (VOID **)&GopComponentName2Protocol); + if (!EFI_ERROR (Status)) { + Status = GopComponentName2Protocol->GetDriverVersion ( + GopComponentName2Protocol, + "en-US", + &DriverVersion + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; (DriverVersion[Index] != '\0'); Index++) { + } + Index = (Index+1)*2; + CopyMem(mDxePlatformSaPolicy->IgdConfig->GopVersion, DriverVersion, Index); + } + } + } + + /// + /// Return final status + /// + return EFI_SUCCESS; +} + +EFI_STATUS +GraphicsInit ( + IN EFI_HANDLE ImageHandle, + IN DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy + ) +/** +Initialize GT Post Routines. + + @param[in] ImageHandle - Handle for the image of this driver + @param[in] DxePlatformSaPolicy - SA DxePlatformPolicy protocol + + @retval EFI_SUCCESS - GT POST initialization complete + @retval EFI_NOT_FOUND - Dxe System Table not found. +**/ +{ + EFI_PHYSICAL_ADDRESS MemBaseAddress; + UINT32 LoGTBaseAddress; + UINT32 HiGTBaseAddress; + UINT32 Data32And; + UINT32 Data32Or; + EFI_STATUS Status; + UINTN DwordData; + UINT32 Data32Mask; + UINT32 Result; + UINT16 Data16; + CPU_FAMILY CpuFamilyId; + UINT8 CpuSteppingId; + UINT32 Data32; + UINT16 IsUlx; + + CpuFamilyId = GetCpuFamily(); + CpuSteppingId = GetCpuStepping(); + + GTTMMADR = 0; + Status = EFI_SUCCESS; + MCHBAR_BASE = McD0PciCfg64 (0x48) &~BIT0; + + /// + /// Read the RP1 Graphics Frequency + /// + rP1GraphicsFreq = (UINT8) ((Mmio32 (MCHBAR_BASE, 0x5998) >> 8) & 0xFF); + + /// + /// If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program GTTMMADR, + /// + if (McD2PciCfg16 (R_SA_IGD_VID) != 0xFFFF) { + gDS = NULL; + Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS); + ASSERT_EFI_ERROR (Status); + ASSERT(gDS != NULL); + if (gDS == NULL) { + return EFI_NOT_FOUND; + } + + /// + /// Means Allocate 4MB for GTTMADDR + /// + MemBaseAddress = 0x0ffffffffffffffff; + + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAnySearchBottomUp, + EfiGcdMemoryTypeMemoryMappedIo, + GTT_MEM_ALIGN, + GTTMMADR_SIZE_4MB, + &MemBaseAddress, + ImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Program GT PM Settings if GTTMMADR allocation is Successful + /// + GTTMMADR = (UINTN) MemBaseAddress; + + LoGTBaseAddress = (UINT32) (MemBaseAddress & 0xFFFFFFFF); + HiGTBaseAddress = (UINT32) RShiftU64 ((MemBaseAddress & 0xFFFFFFFF00000000), 32); + McD2PciCfg32 (R_SA_IGD_GTTMMADR) = LoGTBaseAddress | BIT2; + McD2PciCfg32 (R_SA_IGD_GTTMMADR + 4) = HiGTBaseAddress; + + DwordData = McD2PciCfg32 (R_SA_IGD_GTTMMADR); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 2, + 0, + R_SA_IGD_GTTMMADR)), + 1, + &DwordData + ); + + DwordData = McD2PciCfg32 (R_SA_IGD_GTTMMADR + 4); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 2, + 0, + R_SA_IGD_GTTMMADR + 4)), + 1, + &DwordData + ); + + /// + /// Enable Bus Master, I/O and Memory access on 0:2:0 + /// + McD2PciCfg16Or (R_SA_IGD_CMD, (BIT2 | BIT1)); + Data16 = McD2PciCfg16 (R_SA_IGD_CMD); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (MmPciAddress (0, 0, 2, 0, R_SA_IGD_CMD)), + 1, + &Data16 + ); + + /// + /// PAVP Initialization + /// + DEBUG ((EFI_D_INFO, "Initializing PAVP\n")); + PavpInit (ImageHandle, DxePlatformSaPolicy); + /// + /// PmInit Initialization + /// + DEBUG ((EFI_D_INFO, "Initializing GT PowerManagement\n")); + PmInit (ImageHandle, DxePlatformSaPolicy); + + /// + /// Enable PowerWell for DP and Audio: set Dev2 mmio 45400 bit 31 and poll bit30 (1 means enabled) + /// + Data32And = 0xFFFFFFFF; + Data32Or = (UINT32) (BIT31); + Mmio32Or (GTTMMADR, 0x45400, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x45400), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + + Data32Mask = BIT30; + Result = BIT30; + PollGtReady (GTTMMADR, 0x45400, Data32Mask, Result); + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x45400), + &Data32Mask, + &Result, + 50, + 200000 + ); + + if (DxePlatformSaPolicy->Revision >=4) { + IsUlx = 0; + Data16 = McD2PciCfg16 (0x2); + if ((Data16 == 0xA0E) || (Data16 == 0xA1E)) { + IsUlx = 1; + } + /// + /// BIOS to get supported CD frequency + /// + if (((MmioRead32 (GTTMMADR + 0x42014) & 0x1000000) != 0) || (IsUlx == 1) || (CpuFamilyId == EnumCpuHswUlt)) { + ///fixed frequency + mDxePlatformSaPolicy->IgdConfig->CdClkVar = 0; + } else { + ///choice of varying frequency + mDxePlatformSaPolicy->IgdConfig->CdClkVar = 2; + } + + if (IsUlx == 1) { + Data32And = 0xF7FFFFFF; + Data32Or = 0x4000000; + } else { + if ((mDxePlatformSaPolicy->IgdConfig->CdClk) != 1) { + if ((mDxePlatformSaPolicy->IgdConfig->CdClkVar != 0)) { + ///540 or 337.5Mhz + Data32And = 0xF7FFFFFF; + Data32Or = 0x4000000; + } + } else { + ///450 Mhz + Data32And = 0xF3FFFFFF; + Data32Or = 0; + } + } + Mmio32AndThenOr (GTTMMADR, 0x130040, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x130040), + &Data32Or, /// Data to be ORed + &Data32And /// Data to be ANDed + ); + + if ((CpuFamilyId == EnumCpuHswUlt)||(IsUlx == 1)) { + Data32 = 1; + if (((mDxePlatformSaPolicy->IgdConfig->CdClk) == 1) && (IsUlx == 0)) { + Data32 = 0; + } + + Mmio32 (GTTMMADR, 0x138128) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138128), + 1, + &Data32 + ); + + Data32 = 0x0; + Mmio32 (GTTMMADR, 0x13812c) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x13812c), + 1, + &Data32 + ); + + Data32 = 0x80000017; + Mmio32 (GTTMMADR, 0x138124) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (GTTMMADR + 0x138124), + 1, + &Data32 + ); + } + } + + McD2PciCfg16And (R_SA_IGD_CMD, ~(BIT2 | BIT1)); + Data16 = McD2PciCfg16(R_SA_IGD_CMD); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (MmPciAddress (0, 0, 2, 0, R_SA_IGD_CMD)), + 1, + &Data16 + ); + + McD2PciCfg64 (R_SA_IGD_GTTMMADR) = 0; + DwordData = McD2PciCfg64(R_SA_IGD_GTTMMADR); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, 0, 2, 0, R_SA_IGD_GTTMMADR)), + 1, + &DwordData + ); + + /// + /// Free allocated resources + /// + gDS->FreeMemorySpace (MemBaseAddress, GTTMMADR_SIZE_4MB); + } + + /// + /// Lock PAVPC Register + /// + McD0PciCfg32Or (R_SA_PAVPC, B_SA_PAVPC_PAVPLCK_MASK); + + DwordData = McD0PciCfg32 (R_SA_PAVPC); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (MmPciAddress (0, + 0, + 0, + 0, + R_SA_PAVPC)), + 1, + &DwordData + ); + + return EFI_SUCCESS; +} + +VOID +PollGtReady ( + UINT64 Base, + UINT32 Offset, + UINT32 Mask, + UINT32 Result + ) +/** + "Poll Status" for GT Readiness + + @param[in] Base - Base address of MMIO + @param[in] Offset - MMIO Offset + @param[in] Mask - Mask + @param[in] Result - Value to wait for +**/ +{ + UINT32 GtStatus; + UINT16 StallCount; + + StallCount = 0; + + /// + /// Register read + /// + GtStatus = Mmio32 (Base, Offset); + + while (((GtStatus & Mask) != Result) && (StallCount < GT_WAIT_TIMEOUT)) { + + GtStatus = Mmio32 (Base, Offset); + /// + /// 1mSec wait + /// + gBS->Stall (1000); + StallCount = StallCount + 1; + } + + ASSERT ((StallCount != GT_WAIT_TIMEOUT)); +} |