audk/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c

288 lines
7.4 KiB
C

/*++
Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
SPDX-License-Identifier: BSD-2-Clause-Patent
Module Name:
VlvPlatformInit.c
Abstract:
This is the driver that initializes the Intel ValleyView.
--*/
#include "VlvPlatformInit.h"
#include <Protocol/VlvPlatformPolicy.h>
extern DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy;
UINT64 GTTMMADR;
DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy;
/**
"Poll Status" for GT Readiness
@param Base Base address of MMIO
@param Offset MMIO Offset
@param Mask Mask
@param Result Value to wait for
@retval None
**/
VOID
PollGtReady_hang (
UINT64 Base,
UINT32 Offset,
UINT32 Mask,
UINT32 Result
)
{
UINT32 GtStatus;
//
// Register read
//
GtStatus = MmioRead32 ((UINTN)Base+ Offset);
while (((GtStatus & Mask) != Result)) {
GtStatus = MmioRead32 ((UINTN)Base + Offset);
}
}
/**
Do Post GT PM Init Steps after VBIOS Initialization.
@param Event A pointer to the Event that triggered the callback.
@param Context A pointer to private data registered with the callback function.
@retval EFI_SUCCESS GC_TODO
**/
EFI_STATUS
EFIAPI
PostPmInitCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
UINT64 OriginalGTTMMADR;
UINT32 LoGTBaseAddress;
UINT32 HiGTBaseAddress;
//
// Enable Bus Master, I/O and Memory access on 0:2:0
//
PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));
//
// only 32bit read/write is legal for device 0:2:0
//
OriginalGTTMMADR = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR));
OriginalGTTMMADR = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);
//
// 64bit GTTMADR does not work for S3 save script table since it is executed in PEIM phase
// Program temporarily 32bits GTTMMADR for POST and S3 resume
//
LoGTBaseAddress = (UINT32) (GTTMMADR & 0xFFFFFFFF);
HiGTBaseAddress = (UINT32) RShiftU64 ((GTTMMADR & 0xFFFFFFFF00000000), 32);
S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
//
// Restore original GTTMMADR
//
LoGTBaseAddress = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
HiGTBaseAddress = (UINT32) RShiftU64 ((OriginalGTTMMADR & 0xFFFFFFFF00000000), 32);
S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
//
// Lock the following registers, GGC, BDSM, BGSM
//
PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);
gBS->CloseEvent (Event);
//
// Return final status
//
return EFI_SUCCESS;
}
/**
Routine Description:
Initialize GT Post Routines.
@param ImageHandle Handle for the image of this driver
@param DxePlatformSaPolicy SA DxePlatformPolicy protocol
@retval EFI_SUCCESS GT POST initialization complete
**/
EFI_STATUS
IgdPmHook (
IN EFI_HANDLE ImageHandle,
IN DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicyParam
)
{
EFI_EVENT mConOutEvent;
VOID *gConOutNotifyReg;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MemBaseAddress;
UINT32 LoGTBaseAddress;
UINT32 HiGTBaseAddress;
GTTMMADR = 0;
Status = EFI_SUCCESS;
//
// If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program GTTMMADR,
//
if (PciRead16(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_VID)) != 0xFFFF) {
ASSERT (gDS!=NULL);
//
// Enable Bus Master, I/O and Memory access on 0:2:0
//
PciOr8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD), (BIT2 | BIT1 | BIT0));
//
// Means Allocate 4MB for GTTMADDR
//
MemBaseAddress = 0x0ffffffff;
Status = gDS->AllocateMemorySpace (
EfiGcdAllocateMaxAddressSearchBottomUp,
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);
PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR), LoGTBaseAddress);
PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR+4), HiGTBaseAddress);
S3PciRead32(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR));
S3MmioRead32(IGD_R_GTTMMADR + 4);
S3PciRead8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD));
//
// Do POST GT PM Init Steps after VBIOS Initialization in DoPostPmInitCallBack
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
(EFI_EVENT_NOTIFY)PostPmInitCallBack,
NULL,
&mConOutEvent
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->RegisterProtocolNotify (
&gEfiGraphicsOutputProtocolGuid,
mConOutEvent,
&gConOutNotifyReg
);
MmioWrite64 (IGD_R_GTTMMADR, 0);
//
// Free allocated resources
//
gDS->FreeMemorySpace (
MemBaseAddress,
GTTMMADR_SIZE_4MB
);
}
return EFI_SUCCESS;
}
/**
This is the standard EFI driver point that detects
whether there is an ICH southbridge in the system
and if so, initializes the chip.
@param ImageHandle Handle for the image of this driver
@param SystemTable Pointer to the EFI System Table
@retval EFI_SUCCESS The function completed successfully
**/
EFI_STATUS
EFIAPI
VlvPlatformInitEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = gBS->LocateProtocol (&gDxeVlvPlatformPolicyGuid, NULL, (void **)&DxePlatformSaPolicy);
ASSERT_EFI_ERROR (Status);
//
// GtPostInit Initialization
//
DEBUG ((EFI_D_ERROR, "Initializing GT PowerManagement and other GT POST related\n"));
IgdPmHook (ImageHandle, DxePlatformSaPolicy);
//
// IgdOpRegion Install Initialization
//
DEBUG ((EFI_D_ERROR, "Initializing IGD OpRegion\n"));
IgdOpRegionInit ();
return EFI_SUCCESS;
}