123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- /** @file
- Initializes the PCH HD Audio ACPI Tables.
- Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/DebugLib.h>
- #include <Library/IoLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/PciSegmentLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/UefiLib.h>
- #include <Protocol/AcpiTable.h>
- #include <Library/ConfigBlockLib.h>
- #include "PchInit.h"
- #include <Protocol/PchPolicy.h>
- #include <ConfigBlock/HdAudioConfig.h>
- #include <Private/PchConfigHob.h>
- #include <Library/PchInfoLib.h>
- #include <Private/Library/PchHdaLib.h>
- #include <IndustryStandard/Pci30.h>
- #include <Register/PchRegs.h>
- #include <Register/PchRegsHda.h>
- PCH_HDA_NHLT_ENDPOINTS mPchHdaNhltEndpoints[HdaEndpointMax] =
- {
- {HdaDmicX1, B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT, 0, FALSE},
- {HdaDmicX2, (B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT), 0, FALSE},
- {HdaDmicX4, (B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT), 0, FALSE},
- {HdaBtRender, (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT | B_HDA_BT_A2DP_FORMAT), 0, FALSE},
- {HdaBtCapture, (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT), 0, FALSE},
- {HdaI2sRender1, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO, FALSE},
- {HdaI2sRender2, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO, FALSE},
- {HdaI2sCapture, B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_CAPTURE_DEVICE_INFO, FALSE}
- };
- #define DSP_FW_STOLEN_MEMORY_SIZE 0x400000 //4MB
- /**
- Allocates 4MB of memory for DSP FW usage.
- @retval EFI_PHYSICAL_ADDRESS Allocated memory address
- **/
- EFI_PHYSICAL_ADDRESS
- AllocateAudioDspStolenMemory (
- )
- {
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS DspStolenMemBaseAddress;
- DspStolenMemBaseAddress = 0;
- DEBUG ((DEBUG_INFO, "AllocateAudioDspStolenMemory()\n"));
- //
- // Reserve memory to store Acpi Debug data.
- //
- DspStolenMemBaseAddress = 0xFFFFFFFF;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (DSP_FW_STOLEN_MEMORY_SIZE),
- &DspStolenMemBaseAddress
- );
- ASSERT_EFI_ERROR(Status);
- ZeroMem ((VOID *) (UINTN) DspStolenMemBaseAddress, DSP_FW_STOLEN_MEMORY_SIZE);
- mPchNvsAreaProtocol.Area->DSPM = (UINT32) DspStolenMemBaseAddress;
- DEBUG ((DEBUG_INFO, "mPchNvsAreaProtocol.Area->DSPM = 0x%016x\n", mPchNvsAreaProtocol.Area->DSPM));
- return DspStolenMemBaseAddress;
- }
- /**
- Retrieves address of NHLT table from XSDT/RSDT.
- @retval NHLT_ACPI_TABLE* Pointer to NHLT table if found
- @retval NULL NHLT could not be found
- **/
- NHLT_ACPI_TABLE *
- LocateNhltAcpiTable (
- VOID
- )
- {
- EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
- NHLT_ACPI_TABLE *Nhlt;
- UINTN Index;
- UINT64 Data64;
- EFI_STATUS Status;
- Rsdp = NULL;
- Xsdt = NULL;
- Nhlt = NULL;
- ///
- /// Find the AcpiSupport protocol returns RSDP (or RSD PTR) address.
- ///
- DEBUG ((DEBUG_INFO, "LocateNhltAcpiTable() Start\n"));
- Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID *) &Rsdp);
- if (EFI_ERROR (Status) || (Rsdp == NULL)) {
- DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));
- return NULL;
- }
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;
- if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
- // If XSDT has not been found, check RSDT
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
- if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
- DEBUG ((DEBUG_ERROR, "XSDT/RSDT == NULL or wrong signature\n"));
- return NULL;
- }
- }
- for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Xsdt->Length; Index = Index + sizeof (UINT64)) {
- Data64 = *(UINT64 *) ((UINT8 *) Xsdt + Index);
- Nhlt = (NHLT_ACPI_TABLE *) (UINTN) Data64;
- if (Nhlt->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
- break;
- }
- }
- if (Nhlt == NULL || Nhlt->Header.Signature != NHLT_ACPI_TABLE_SIGNATURE) {
- DEBUG ((DEBUG_ERROR, "Nhlt == NULL or wrong signature\n"));
- return NULL;
- }
- DEBUG ((DEBUG_INFO, "Found NhltTable, Address = 0x%016x\n", Nhlt));
- return Nhlt;
- }
- /**
- Constructs and installs NHLT table.
- @retval EFI_SUCCESS ACPI Table installed successfully
- @retval EFI_UNSUPPORTED ACPI Table protocol not found
- **/
- EFI_STATUS
- PublishNhltAcpiTable (
- VOID
- )
- {
- UINTN AcpiTableKey;
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
- NHLT_ACPI_TABLE *NhltTable;
- UINT32 TableLength;
- EFI_STATUS Status;
- AcpiTable = NULL;
- NhltTable = NULL;
- AcpiTableKey = 0;
- DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));
- //
- // Locate ACPI support protocol
- //
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
- if ( EFI_ERROR (Status) || AcpiTable == NULL) {
- return EFI_UNSUPPORTED;
- }
- NhltConstructor (mPchHdaNhltEndpoints, &NhltTable, &TableLength);
- NhltAcpiHeaderConstructor (NhltTable, TableLength);
- Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable, NhltTable->Header.Length, &AcpiTableKey);
- DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
- return Status;
- }
- /**
- Sets NVS ACPI variables for HDAS._DSM and SNDW._DSD accordingly to policy.
- @param[in] NhltAcpiTableAddress
- @param[in] NhltAcpiTableLength
- @param[in] *HdAudioConfigHob
- @param[in] *HdAudioDxeConfig
- **/
- VOID
- UpdateHdaAcpiData (
- IN UINT64 NhltAcpiTableAddress,
- IN UINT32 NhltAcpiTableLength,
- IN CONST HDAUDIO_HOB *HdAudioConfigHob,
- IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
- )
- {
- DEBUG ((DEBUG_INFO, "UpdateHdaAcpiData():\n NHLT Address = 0x%016x, Length = 0x%08x\n", NhltAcpiTableAddress, NhltAcpiTableLength));
- DEBUG ((DEBUG_INFO, " FeatureMask = 0x%08x\n", HdAudioDxeConfig->DspFeatureMask));
- mPchNvsAreaProtocol.Area->NHLA = NhltAcpiTableAddress;
- mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
- mPchNvsAreaProtocol.Area->ADFM = HdAudioDxeConfig->DspFeatureMask;
- mPchNvsAreaProtocol.Area->SWQ0 = HdAudioConfigHob->AudioLinkSndw1 ? 0 : BIT1;
- mPchNvsAreaProtocol.Area->SWQ1 = HdAudioConfigHob->AudioLinkSndw2 ? 0 : BIT1;
- mPchNvsAreaProtocol.Area->SWQ2 = HdAudioConfigHob->AudioLinkSndw3 ? 0 : BIT1;
- mPchNvsAreaProtocol.Area->SWQ3 = HdAudioConfigHob->AudioLinkSndw4 ? 0 : BIT1;
- }
- /**
- Initialize and publish NHLT (Non-HDA Link Table), update NVS variables.
- @param[in] *HdAudioConfigHob
- @param[in] *HdAudioDxeConfig
- @retval EFI_SUCCESS The function completed successfully
- **/
- EFI_STATUS
- SetHdaAcpiTable (
- IN CONST HDAUDIO_HOB *HdAudioConfigHob,
- IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
- )
- {
- NHLT_ACPI_TABLE *NhltTable;
- EFI_STATUS Status;
- NhltTable = NULL;
- Status = EFI_SUCCESS;
- if (HdAudioDxeConfig->NhltDefaultFlow == TRUE) {
- switch (HdAudioDxeConfig->DspEndpointDmic) {
- case PchHdaDmic1chArray:
- mPchHdaNhltEndpoints[HdaDmicX1].Enable = TRUE;
- break;
- case PchHdaDmic2chArray:
- mPchHdaNhltEndpoints[HdaDmicX2].Enable = TRUE;
- break;
- case PchHdaDmic4chArray:
- mPchHdaNhltEndpoints[HdaDmicX4].Enable = TRUE;
- break;
- case PchHdaDmicDisabled:
- default:
- mPchHdaNhltEndpoints[HdaDmicX2].Enable = FALSE;
- mPchHdaNhltEndpoints[HdaDmicX4].Enable = FALSE;
- }
- if (HdAudioDxeConfig->DspEndpointBluetooth) {
- mPchHdaNhltEndpoints[HdaBtRender].Enable = TRUE;
- mPchHdaNhltEndpoints[HdaBtCapture].Enable = TRUE;
- }
- if (HdAudioDxeConfig->DspEndpointI2s) {
- mPchHdaNhltEndpoints[HdaI2sRender1].Enable = TRUE;
- mPchHdaNhltEndpoints[HdaI2sRender2].Enable = TRUE;
- mPchHdaNhltEndpoints[HdaI2sCapture].Enable = TRUE;
- }
- Status = PublishNhltAcpiTable ();
- }
- NhltTable = LocateNhltAcpiTable ();
- if (NhltTable == NULL) {
- return EFI_LOAD_ERROR;
- }
- UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
- if (IsPchLp () && (PchStepping () < PCH_B0)) {
- AllocateAudioDspStolenMemory ();
- }
- DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
- return Status;
- }
- /**
- Initialize Intel High Definition Audio ACPI Tables
- @retval EFI_SUCCESS The function completed successfully
- @retval EFI_LOAD_ERROR ACPI table cannot be installed
- @retval EFI_UNSUPPORTED ACPI table not set because DSP is disabled
- **/
- EFI_STATUS
- PchHdAudioAcpiInit (
- VOID
- )
- {
- EFI_STATUS Status;
- UINT64 HdaPciBase;
- CONST HDAUDIO_HOB *HdAudioConfigHob;
- PCH_POLICY_PROTOCOL *PchPolicy;
- PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig;
- DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() Start\n"));
- HdAudioConfigHob = &mPchConfigHob->HdAudio;
- ///
- /// Get PCH Policy Protocol
- ///
- Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **)&PchPolicy);
- ASSERT_EFI_ERROR (Status);
- ///
- /// Get HD Audio DXE Config Block
- ///
- Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdAudioDxeConfig);
- ASSERT_EFI_ERROR (Status);
- HdaPciBase = PCI_SEGMENT_LIB_ADDRESS (
- DEFAULT_PCI_SEGMENT_NUMBER_PCH,
- DEFAULT_PCI_BUS_NUMBER_PCH,
- PCI_DEVICE_NUMBER_PCH_HDA,
- PCI_FUNCTION_NUMBER_PCH_HDA,
- 0
- );
- if ((PciSegmentRead16 (HdaPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) || (HdAudioConfigHob->DspEnable == FALSE)) {
- // Do not set ACPI tables if HDAudio is Function disabled or DSP is disabled
- DEBUG ((DEBUG_INFO, "AudioDSP: Non-HDAudio ACPI Table (NHLT) not set!\n"));
- return EFI_UNSUPPORTED;
- }
- Status = SetHdaAcpiTable (HdAudioConfigHob, HdAudioDxeConfig);
- DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
- return Status;
- }
|