diff options
Diffstat (limited to 'Board/EM/SwitchableGraphics/SgTpv/AcpiTables/SgTpvAcpiTables.c')
-rw-r--r-- | Board/EM/SwitchableGraphics/SgTpv/AcpiTables/SgTpvAcpiTables.c | 988 |
1 files changed, 988 insertions, 0 deletions
diff --git a/Board/EM/SwitchableGraphics/SgTpv/AcpiTables/SgTpvAcpiTables.c b/Board/EM/SwitchableGraphics/SgTpv/AcpiTables/SgTpvAcpiTables.c new file mode 100644 index 0000000..8359da3 --- /dev/null +++ b/Board/EM/SwitchableGraphics/SgTpv/AcpiTables/SgTpvAcpiTables.c @@ -0,0 +1,988 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/SwitchableGraphics/Sg TPV/Sg Acpi Tables/SgTpvAcpiTables.c 7 3/21/13 3:48a Joshchou $ +// +// $Revision: 7 $ +// +// $Date: 3/21/13 3:48a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/SwitchableGraphics/Sg TPV/Sg Acpi Tables/SgTpvAcpiTables.c $ +// +// 7 3/21/13 3:48a Joshchou +// [TAG] EIPEIP116106 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] ACPI error in Win8 event viewer on ULT platform +// [RootCause] We use the PCI_config to save/restore registers,and the +// value of EBAS is wrong. +// [Solution] Save the correct value of EBAS in "SgTpvAcpiTables.c" +// Use the MMIO to save/restore registers +// +// 6 1/15/13 6:06a Joshchou +// [TAG] EIP107237 +// [Category] Improvement +// [Description] Modify for support SG on ULT platform. +// +// 5 12/22/12 2:38a Joshchou +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Did not get the correct Endpoint Link Contol Register Value +// [RootCause] Give the wrong address. +// [Solution] Fix the address. +// +// 4 12/18/12 6:21a Joshchou +// [TAG] None +// [Category] Improvement +// [Description] Update for SA RC 081 +// +// 3 10/16/12 4:41a Joshchou +// [TAG] None +// [Category] Improvement +// [Description] Update for SA and ACPI RC 0.7.1 +// [Files] SgTpvAcpiTables.c +// +// 2 9/09/12 10:57p Joshchou +// +// 3 12/12/11 9:17p Alanlin +// [TAG] EIP74169 +// [Category] Improvement +// [Description] Add OEMSSDT module part. Token "SGOEMSSDT_SUPPORT" to +// create OEM SSDT +// for discrete VGA card.When Primarydisplay = Auto or PEG, it can report +// OEM SSDT +// talbes for AMD or nVidia dGPU VGA card. +// [Files] SgTpvAcpiTables.c +// SgTpvAcpiTables.cif +// +// 2 12/02/11 5:38a Alanlin +// [TAG] EIP75211 +// [Category] Improvement +// [Description] Changeing VBIOS size to 128k for _ROM method for nVidia +// chip. +// +// 1 6/27/11 5:26a Alanlin +// [TAG] EIP61848 +// [Category] New Feature +// [Description] Initial check-in.Integrated SwitchableGraphics Intel +// Reference code 0.6.0 +// [Files] SgTpvAcpiTables.cif +// SgTpvAcpiTables.sdl +// SgTpvAcpiTables.mak +// SgTpvAcpiTables.c +// +// +// 10 3/17/11 6:15p Alexp +// Optimus:Add code to preserve HD AudioCodec enable flag in CMOS +// +// 9 1/03/11 12:35p Alexp +// [TAG] EIP50104 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Nvidia GPU device disappears after S3 resume +// [RootCause] PEG bridge controller was not restoring secondary and +// subiordinate bus numbers on S3 resume +// [Solution] add code to save/restore PCI context using S3_resume +// Scripts +// [Files] SgTpvAcpiTables.c +// +// 8 11/12/10 1:19p Alexp +// rearrange the code for Amd and Nvidia tables. +// Add WiDi DID number if WiDi support is selected in GlobalAcpiNvs flags +// +// 7 11/11/10 3:09p Alexp +// Add debug messages +// +// 6 10/06/10 4:17p Alexp +// comments chnage for NvidiaOpRegion header +// +// 5 10/05/10 7:08p Alexp +// added new field in NVH OpRegion to pass MXM3 data block. +// +// 4 9/29/10 1:23p Alexp +// [TAG] EIP43103 --->change code to update dGPU SVID registers +// +// 3 9/23/10 1:12p Alexp +// BUG fix in disable logic for Func1 on PEG endpoint (HDA) for Optimus +// +// 2 9/21/10 5:09p Alexp +// [TAG] EIP43103 --->fix debug messages +// +// 1 9/17/10 1:18p Alexp +// [TAG] EIP43103 +// [Category] Function Request +// [Severity] Normal +// [Symptom] Initial check-in of SgTPV module +// [RootCause] Request to implement SG reference code . +// [Solution] Initial check-in. +// [Files] +// SgTpvAcpiTables.cif;*.sdl;*.mak;*.c +// +//********************************************************************** +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: SgTpvAcpiTables.c +// +// Description: This file contains the routine LoadTpvAcpiTables which installs +// Acpi Tables for Tpv's Switchable Graphics. +// File is linked with Intel's SwitchableGraphicsDxe module +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "SgTpvAcpitables.h" +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Procedure: NvidiaOpRegion & AmdOpRegion +// +// Description: Gfx Vendor specific OperationRegion data structures. +// Must match ones defined in Asl code +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +NVIDIA_OPREGION NvidiaOpRegion; +AMD_OPREGION AmdOpRegion; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LoadTpvAcpiTables +// +// Description: Load Third part graphics vendor support SSDT Tables +// +// Input: VOID +// +// Output: +// EFI_SUCCESS - SSDT Table load successful. +// EFI_UNSUPPORTED - Supported SSDT not found. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +LoadTpvAcpiTables ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + BOOLEAN LoadTable; + INTN Instance; + UINTN NumberOfHandles; + UINTN Index; + UINTN Size; + UINTN TableHandle; +//UINT16 Data16; +//UINT32 Data32; + UINT32 FvStatus; +#if (PI_SPECIFICATION_VERSION < 0x00010000) + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; +#else + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; +#endif + EFI_FV_FILETYPE FileType; + EFI_FV_FILE_ATTRIBUTES Attributes; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + EFI_ACPI_TABLE_VERSION Version; +// EFI_GUID SGTPV_AcpiTableGuid= SGTPV_ACPI_SSDT_GUID; + EFI_GUID SGTPV_AcpiTableGuid; + EFI_GUID gSgtpvAcpiSsdtGuid= SGTPV_ACPI_SSDT_GUID; + EFI_GUID gSgtpvAcpiPchSsdtGuid= SGTPV_ACPIPCH_SSDT_GUID; + +#if SGOEMSSDT_SUPPORT + EFI_GUID SGOEM_AcpiTableGuid = SGOEM_ACPI_SSDT_GUID; +#endif + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; + EFI_ACPI_COMMON_HEADER *Table; + + UINT16 VendorId; + + + FwVol = NULL; + Table = NULL; + + DEBUG ((EFI_D_ERROR, "CpuFamilyId ==0x%X\n", CpuFamilyId)); + SGTPV_AcpiTableGuid = gSgtpvAcpiSsdtGuid; + if (CpuFamilyId == EnumCpuHswUlt) { + SGTPV_AcpiTableGuid = gSgtpvAcpiPchSsdtGuid; + } + + + + VendorId = McDevFunPciCfg16 (EndpointBus, 0, 0, PCI_VID); // DEBUG + DEBUG ((EFI_D_ERROR, "SG TPV Vendor ID %X\n", VendorId)); + + switch(VendorId){ + case NVIDIA_VID: + // + // Set VendorId if PEG is NVIDIA and supports HG + // + VendorId = NVIDIA_VID; + break; + case AMD_VID: + // + // Set VendorId if PEG is AMD and supports HG + // + VendorId = AMD_VID; + break; + default: + // + // either means the Device ID is not on the list of devices we know - we return from this function + // + DEBUG ((EFI_D_ERROR, "SG TPV Unsupported Vendor ID\n")); + return EFI_UNSUPPORTED; + } + + + /// + /// Locate the SA Global NVS Protocol. + /// + Status = gBS->LocateProtocol ( + &gSaGlobalNvsAreaProtocolGuid, + NULL, + (VOID **) &SaGlobalNvsArea + ); + if (EFI_ERROR (Status)) { + return Status; + } + SaGlobalNvsArea->Area->EndpointBaseAddress = (UINT32) (MmPciAddress (0, EndpointBus, 0, 0, 0x0)); + + // + // Locate FV protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + #if (PI_SPECIFICATION_VERSION < 0x00010000) + &gEfiFirmwareVolumeProtocolGuid, + #else + &gEfiFirmwareVolume2ProtocolGuid, + #endif + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + // + // Look for FV with ACPI storage file + // + for (Index = 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + #if (PI_SPECIFICATION_VERSION < 0x00010000) + &gEfiFirmwareVolumeProtocolGuid, + #else + &gEfiFirmwareVolume2ProtocolGuid, + #endif + &FwVol + ); + ASSERT_EFI_ERROR (Status); + + // + // See if it has the ACPI storage file + // + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &SGTPV_AcpiTableGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (!EFI_ERROR (Status)) { + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + // + // Free any allocated buffers + // + (gBS->FreePool) (HandleBuffer); + + // + // Sanity check that we found our data file + // + ASSERT (FwVol); + + // + // By default, a table belongs in all ACPI table versions published. + // + Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; + + // + // Locate ACPI tables + // + Status = gBS->LocateProtocol ( + &gEfiAcpiSupportGuid, + NULL, + &AcpiSupport + ); + + + ASSERT_EFI_ERROR (Status); + + // + // Read tables from the storage file. + // + Instance = 0; + + while (Status == EFI_SUCCESS) { + // + // Read the ACPI tables + // + Status = FwVol->ReadSection ( + FwVol, + &SGTPV_AcpiTableGuid, + EFI_SECTION_RAW, + Instance, + &Table, + &Size, + &FvStatus + ); + if (!EFI_ERROR (Status)) { + // + // check for SwitchableGraphics tables and decide which SSDT should be loaded + // + LoadTable = FALSE; + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + DEBUG ((EFI_D_ERROR, "SG TPV SSDT TblID %X\n", TableHeader->OemTableId)); + + switch (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId) { + + case EFI_SIGNATURE_64 ('N', 'v', 'd', 'T', 'a', 'b', 'l', 0): + if(VendorId != NVIDIA_VID || + SaGlobalNvsArea->Area->SgMode != SgModeMuxed) + break; + + DEBUG ((EFI_D_ERROR, "SG TPV Nvidia SG Table\n")); + // + // This is Nvidia SSDT + // + LoadTable = TRUE; + Status = InstallNvidiaOpRegion (); + if (EFI_ERROR (Status)) { + return Status; + } + + break; + + case EFI_SIGNATURE_64 ('O', 'p', 't', 'T', 'a', 'b', 'l', 0): + if(VendorId != NVIDIA_VID || + SaGlobalNvsArea->Area->SgMode != SgModeMuxless) + break; + + DEBUG ((EFI_D_ERROR, "SG TPV Nvidia Optimus Table\n")); + // + // This is nVidia Optimus SSDT + // + LoadTable = TRUE; + Status = InstallNvidiaOpRegion(); + if (EFI_ERROR(Status)) { + return Status; + } + + break; + + case EFI_SIGNATURE_64 ('A', 'm', 'd', 'T', 'a', 'b', 'l', 0): + if(VendorId != AMD_VID) + break; + // + // This is Amd SSDT + // + LoadTable = TRUE; + Status = InstallAmdOpRegion (); + if (EFI_ERROR (Status)) { + return Status; + } + + break; + + default: + DEBUG ((EFI_D_ERROR, "WARNING: SG TPV Unsupported SSDT Signature...\n")); + break; + } + + // + // Add the table + // + if (LoadTable) { + TableHandle = 0; + Status = AcpiSupport->SetAcpiTable ( + AcpiSupport, + TableHeader, + TRUE, + Version, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + Status = AcpiSupport->PublishTables ( + AcpiSupport, + Version + ); + ASSERT_EFI_ERROR (Status); +// if (EFI_ERROR(Status)) break; + break; // only one ACPI SG/Optimus table should be loaded + } + // + // Increment the instance + // + Instance++; + Table = NULL; + } + } + +#if SGOEMSSDT_SUPPORT + // + // Locate ACPI tables + // + Status = gBS->LocateProtocol ( + &gEfiAcpiSupportGuid, + NULL, + &AcpiSupport + ); + ASSERT_EFI_ERROR (Status); + + // + // Read tables from the storage file. + // + Instance = 0; + + while (Status == EFI_SUCCESS) { + // + // Read the ACPI tables + // + Status = FwVol->ReadSection ( + FwVol, + &SGOEM_AcpiTableGuid, + EFI_SECTION_RAW, + Instance, + &Table, + &Size, + &FvStatus + ); + if (!EFI_ERROR (Status)) { + // + // check for SwitchableGraphics tables and decide which SSDT should be loaded + // + LoadTable = FALSE; + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + DEBUG ((EFI_D_ERROR, "SG TPV SSDT TblID %X\n", TableHeader->OemTableId)); + + switch (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId) { + + // + // Set OEM SSDT + // + + case SGOEM_ACPI_SSDT_TABLE: + if(SaGlobalNvsArea->Area->SgMode != SgModeDgpu) + break; + + DEBUG ((EFI_D_ERROR, "OEM SSDT Table\n")); + // + // This is OEM SSDT + // + LoadTable = TRUE; + if(VendorId == NVIDIA_VID) + Status = InstallNvidiaOpRegion (); + else + Status = InstallAmdOpRegion(); + + if (EFI_ERROR (Status)) { + return Status; + } + + break; + + default: + DEBUG ((EFI_D_ERROR, "WARNING: SG OEM Unsupported SSDT Signature...\n")); + break; + } + + // + // Add the table + // + if (LoadTable) { + TableHandle = 0; + Status = AcpiSupport->SetAcpiTable ( + AcpiSupport, + TableHeader, + TRUE, + Version, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + Status = AcpiSupport->PublishTables ( + AcpiSupport, + Version + ); + ASSERT_EFI_ERROR (Status); +// if (EFI_ERROR(Status)) break; + break; // only one ACPI SG/Optimus table should be loaded + } + // + // Increment the instance + // + Instance++; + Table = NULL; + } + } +#endif + + DEBUG ((EFI_D_ERROR, "SGtpv:: NDID:0x%x\n", SaGlobalNvsArea->Area->NumberOfValidDeviceId)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID1:0x%x\n", SaGlobalNvsArea->Area->DeviceId1)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID2:0x%x\n", SaGlobalNvsArea->Area->DeviceId2)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID3:0x%x\n", SaGlobalNvsArea->Area->DeviceId3)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID4:0x%x\n", SaGlobalNvsArea->Area->DeviceId4)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID5:0x%x\n", SaGlobalNvsArea->Area->DeviceId5)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID6:0x%x\n", SaGlobalNvsArea->Area->DeviceId6)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID7:0x%x\n", SaGlobalNvsArea->Area->DeviceId7)); + DEBUG ((EFI_D_ERROR, "SGtpv:: DID8:0x%x\n", SaGlobalNvsArea->Area->DeviceId8)); + + DEBUG ((EFI_D_ERROR, "SG TPV Gfx acpi UPDATE - COMPLETED\n")); + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +//Procedure: InstallNvidiaOpRegion +// +//Description: Nvidia SG specific Asl OpRegion installation function. +// +//Input: +// +// ImageHandle Handle for this drivers loaded image protocol. +// SystemTable EFI system table. +// +//Output: +// +// EFI_SUCCESS The driver installed without error. +// EFI_ABORTED The driver encountered an error and could not complete +// installation of the ACPI tables. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallNvidiaOpRegion ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; +// Locate MXM3 protocol and get Mxm data pointer from function->MxmReturnStructure + EFI_GUID EfiMxm3ProtocolGuid = MXM3_EFI_GUID; +#if MXM30_SUPPORT == 1 + MXM3_EFI_PROTOCOL *Mxm30Protocol; + VOID *MxmLegMemAddr = NULL; + UINT32 MxmLegMemSize = 0; +#endif + // + // Allocate an ACPI NVS memory buffer as the Nvidia NVIG OpRegion, zero initialize + // the entire 1K, and set the Nvidia NVIG OpRegion pointer in the Global NVS + // area structure. + // + Size = sizeof (NVIG_OPREGION); + Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, Size, &NvidiaOpRegion.NvIgOpRegion); + if (EFI_ERROR (Status)) { + return Status; + } + + (gBS->SetMem) (NvidiaOpRegion.NvIgOpRegion, Size, 0); + + // + // Set up DeviceID values for _DOD. + // Note that Display Subtype bits[15-12] and Port index bits[7:4] are set as per NV Switchable 3.0 spec. + // Not used by Intel driver. + // + // + // Display Type - CRT + // + SaGlobalNvsArea->Area->DeviceId1 = 0x80010100; + + if (SaGlobalNvsArea->Area->ActiveLFP == 3) { + // + // If Active LFP = EDP_A + // + // Display type - LFP Device Sub Type - eDP + // + SaGlobalNvsArea->Area->DeviceId2 = 0x8001A420; + } else { + // + // Display Type - LFP Device Sub Type - LVDS + // + SaGlobalNvsArea->Area->DeviceId2 = 0x80010410; + } + // + // Display type - EFP Device Sub type - DisplayPort 1.1 + // + SaGlobalNvsArea->Area->DeviceId3 = 0x80016330 | ((SaGlobalNvsArea->Area->SgMuxDid3 & 0xFF00) << 10); + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + SaGlobalNvsArea->Area->DeviceId4 = 0x80017331 | ((SaGlobalNvsArea->Area->SgMuxDid4 & 0xFF00) << 10); + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + SaGlobalNvsArea->Area->DeviceId5 = 0x80017342 | ((SaGlobalNvsArea->Area->SgMuxDid5 & 0xFF00) << 10); + + // + // Display type - EFP Device Sub type - DisplayPort 1.1 + // + SaGlobalNvsArea->Area->DeviceId6 = 0x80016353 | ((SaGlobalNvsArea->Area->SgMuxDid6 & 0xFF00) << 10); + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + SaGlobalNvsArea->Area->DeviceId7 = 0x80017354 | ((SaGlobalNvsArea->Area->SgMuxDid7 & 0xFF00) << 10); + + // + // DeviceId8 is not being used on HuronRiver SG + // + SaGlobalNvsArea->Area->DeviceId8 = 0x0; + + // + // NDID + // + SaGlobalNvsArea->Area->NumberOfValidDeviceId = VALIDDIDS;//0x7; + + // + // NVIG + // + SaGlobalNvsArea->Area->NvIgOpRegionAddress = (UINT32)(UINTN)(NvidiaOpRegion.NvIgOpRegion); + + // + // NVIG Header + // + (gBS->CopyMem) (NvidiaOpRegion.NvIgOpRegion->NISG, NVIG_HEADER_SIGNATURE, sizeof (NVIG_HEADER_SIGNATURE)); + NvidiaOpRegion.NvIgOpRegion->NISZ = NVIG_OPREGION_SIZE; + NvidiaOpRegion.NvIgOpRegion->NIVR = NVIG_OPREGION_VER; + + // + // Panel Scaling Preference + // + NvidiaOpRegion.NvIgOpRegion->GPSP = SaGlobalNvsArea->Area->IgdPanelScaling; + + + // Save Link Control register + NvidiaOpRegion.NvIgOpRegion->ELCL= MemoryRead16((UINTN)SaGlobalNvsArea->Area->EndpointPcieCapOffset + 0x10); + + + // + // Allocate an ACPI NVS memory buffer as the Nvidia NVHM OpRegion, zero initialize + // the entire 62K, and set the Nvidia NVHM OpRegion pointer in the Global NVS + // area structure. + // + Size = sizeof (NVHM_OPREGION); + Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, Size, &NvidiaOpRegion.NvHmOpRegion); + + if (EFI_ERROR (Status)) { + (gBS->FreePool) (NvidiaOpRegion.NvIgOpRegion); + return Status; + } + + (gBS->SetMem) (NvidiaOpRegion.NvHmOpRegion, Size, 0); + + // + // NVHM + // + SaGlobalNvsArea->Area->NvHmOpRegionAddress = (UINT32) (UINTN) (NvidiaOpRegion.NvHmOpRegion); + + // + // NVHM Header Signature, Size, Version + // + (gBS->CopyMem) (NvidiaOpRegion.NvHmOpRegion->NVSG, NVHM_HEADER_SIGNATURE, sizeof (NVHM_HEADER_SIGNATURE)); + NvidiaOpRegion.NvHmOpRegion->NVSZ = NVHM_OPREGION_SIZE; + NvidiaOpRegion.NvHmOpRegion->NVVR = NVHM_OPREGION_VER; + + // + // NVHM opregion address + // + NvidiaOpRegion.NvHmOpRegion->NVHO = (UINT32) (UINTN) (NvidiaOpRegion.NvHmOpRegion); + + // + // Copy Oprom to allocated space in NV Opregion + // + NvidiaOpRegion.NvHmOpRegion->RVBS = VbiosSize; + (gBS->CopyMem) ((VOID *) (UINTN) NvidiaOpRegion.NvHmOpRegion->RBUF, VbiosAddress, NvidiaOpRegion.NvHmOpRegion->RVBS); + + // + // Locate the MXM3 Protocol and update Mxm struct pointers + // +#if MXM30_SUPPORT == 1 + Status = gBS->LocateProtocol ( + &EfiMxm3ProtocolGuid, + NULL, + &Mxm30Protocol + ); + if (!EFI_ERROR(Status)) + { + Status = Mxm30Protocol->MxmReturnStructure( + Mxm30Protocol, + NULL, + (CHAR16*)&MxmLegMemSize, + (CHAR16)EFI30_DataBlockID, + (CHAR8**)&MxmLegMemAddr + ); + ASSERT_EFI_ERROR (Status); + // + // Copy MXM3 data structure to allocated space in NV Opregion + // + NvidiaOpRegion.NvHmOpRegion->MXML = MxmLegMemSize; + (gBS->CopyMem) ((VOID *) (UINTN) NvidiaOpRegion.NvHmOpRegion->MXM3, MxmLegMemAddr, MxmLegMemSize); + } +#endif + if (Status != EFI_SUCCESS) { + (gBS->FreePool) (NvidiaOpRegion.NvIgOpRegion); + (gBS->FreePool) (NvidiaOpRegion.NvHmOpRegion); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +//Procedure: InstallAmdOpRegion +// +//Description: Amd(ATI) SG specific Asl Graphics OpRegion installation function. +// +//Input: +// +// ImageHandle Handle for this drivers loaded image protocol. +// SystemTable EFI system table. +// +//Output: +// +// EFI_SUCCESS The driver installed without error. +// EFI_ABORTED The driver encountered an error and could not complete +// installation of the ACPI tables. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallAmdOpRegion ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + + // + // Allocate an ACPI NVS memory buffer as the Amd APXM OpRegion, zero initialize + // the entire 1K, and set the Amd APXM OpRegion pointer in the Global NVS + // area structure. + // + Size = sizeof (APXM_OPREGION); + Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, Size, &AmdOpRegion.ApXmOpRegion); + if (EFI_ERROR (Status)) { + return Status; + } + + (gBS->SetMem) (AmdOpRegion.ApXmOpRegion, Size, 0); + + // + // APXM address + // + SaGlobalNvsArea->Area->ApXmOpRegionAddress = (UINT32) (UINTN) (AmdOpRegion.ApXmOpRegion); + AmdOpRegion.ApXmOpRegion->APXA = (UINT32) (UINTN) (AmdOpRegion.ApXmOpRegion); + + // + // Note. All fields in Amd OpRegion will be initialized with Zeroes. + // Only update those that differ from 0. + + // Set up DIDx values for _DOD + // + // Device ID - CRT on IGPU + // + SaGlobalNvsArea->Area->DeviceId1 = 0x80010100; + + // + // Device ID - LFP (LVDS or eDP) + // + SaGlobalNvsArea->Area->DeviceId2 = 0x80010400; + + // + // Display type - EFP Device Sub type - DisplayPort 1.1 + // + SaGlobalNvsArea->Area->DeviceId3 = 0x80010300; + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + SaGlobalNvsArea->Area->DeviceId4 = 0x80010301; + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + SaGlobalNvsArea->Area->DeviceId5 = 0x80010302; + + // + // Display type - EFP Device Sub type - DisplayPort 1.1 + // + SaGlobalNvsArea->Area->DeviceId6 = 0x80010303; + + // + // Display type - EFP Device Sub type - HDMI 1.2 or 1.3a + // + + // + // SG Feature List for ASL usage + // + if(SaGlobalNvsArea->Area->SgFeatureList & 1) // WIRELESSDISPLAY + SaGlobalNvsArea->Area->DeviceId7 = 0x80010306; + else + SaGlobalNvsArea->Area->DeviceId7 = 0x80010304; + // + // DeviceId8 is not being used on HuronRiver SG + // + SaGlobalNvsArea->Area->DeviceId8 = 0x0; + + // + // NDID + // + SaGlobalNvsArea->Area->NumberOfValidDeviceId = VALIDDIDS;//0x7; + + // + // APXM Header + // + (gBS->CopyMem) (AmdOpRegion.ApXmOpRegion->APSG, APXM_HEADER_SIGNATURE, sizeof (APXM_HEADER_SIGNATURE)); + AmdOpRegion.ApXmOpRegion->APSZ = APXM_OPREGION_SIZE; + AmdOpRegion.ApXmOpRegion->APVR = APXM_OPREGION_VER; + + // + // Total number of toggle list entries + // + AmdOpRegion.ApXmOpRegion->NTLE = 15; + + // + // The display combinations in the list... + // + // + // CRT + // + AmdOpRegion.ApXmOpRegion->TLEX[0] = 0x0002; + // + // LFP + // + AmdOpRegion.ApXmOpRegion->TLEX[1] = 0x0001; + // + // DP_B + // + AmdOpRegion.ApXmOpRegion->TLEX[2] = 0x0008; + // + // HDMI_B + // + AmdOpRegion.ApXmOpRegion->TLEX[3] = 0x0080; + // + // HDMI_C + // + AmdOpRegion.ApXmOpRegion->TLEX[4] = 0x0200; + // + // DP_D + // + AmdOpRegion.ApXmOpRegion->TLEX[5] = 0x0400; + // + // HDMI_D + // + AmdOpRegion.ApXmOpRegion->TLEX[6] = 0x0800; + // + // LFP+CRT + // + AmdOpRegion.ApXmOpRegion->TLEX[7] = 0x0003; + // + // LFP+DP_B + // + AmdOpRegion.ApXmOpRegion->TLEX[8] = 0x0009; + // + // LFP+HDMI_B + // + AmdOpRegion.ApXmOpRegion->TLEX[9] = 0x0081; + // + // LFP+HDMI_C + // + AmdOpRegion.ApXmOpRegion->TLEX[10] = 0x0201; + // + // LFP+DP_D + // + AmdOpRegion.ApXmOpRegion->TLEX[11] = 0x0401; + // + // LFP+HDMI_D + // + AmdOpRegion.ApXmOpRegion->TLEX[12] = 0x0801; + // + // Dummy 1 + // + AmdOpRegion.ApXmOpRegion->TLEX[13] = 0x0; + // + // Dummy 2 + // + AmdOpRegion.ApXmOpRegion->TLEX[14] = 0x0; + + // + // Panel Scaling Preference + // + AmdOpRegion.ApXmOpRegion->EXPM = SaGlobalNvsArea->Area->IgdPanelScaling; + + + // Save Link Control register + AmdOpRegion.ApXmOpRegion->ELCL= MemoryRead16((UINTN)SaGlobalNvsArea->Area->EndpointPcieCapOffset + 0x10); + + + // + // Copy Oprom to allocated space in ATI Opregion + // + AmdOpRegion.ApXmOpRegion->RVBS = VbiosSize; + (gBS->CopyMem) ((VOID *) (UINTN) AmdOpRegion.ApXmOpRegion->RBUF, VbiosAddress, AmdOpRegion.ApXmOpRegion->RVBS); + + if (Status != EFI_SUCCESS) { + (gBS->FreePool) (AmdOpRegion.ApXmOpRegion); + } + + return Status; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |