Added TrueType base and HDA driver
This commit is contained in:
parent
aa3f734406
commit
42cc0d9f40
30 changed files with 7120 additions and 35 deletions
571
boot/platform/uefi/drivers/intel-hda/hda.c
Normal file
571
boot/platform/uefi/drivers/intel-hda/hda.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/*********************************************************************************/
|
||||
/* Module Name: hda.c */
|
||||
/* Project: AurixOS */
|
||||
/* */
|
||||
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
|
||||
/* All rights reserved. */
|
||||
/* This program and the accompanying materials are licensed and made available */
|
||||
/* under the terms and conditions of the BSD License which accompanies */
|
||||
/* this distribution. The full text of the license may be found at */
|
||||
/* http://opensource.org/licenses/bsd-license. */
|
||||
/* */
|
||||
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
|
||||
/*********************************************************************************/
|
||||
|
||||
#include <lib/string.h>
|
||||
#include <mm/mman.h>
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <print.h>
|
||||
|
||||
#include <hda.h>
|
||||
#include <pciconf.h>
|
||||
|
||||
// Number of rows that are updated by the timer event for debug purposes
|
||||
#define REFRESH_ROWS 9
|
||||
#define Bar0 0
|
||||
|
||||
static uint64_t CorbCommandCount = 0;
|
||||
|
||||
PCI_HDA_REGION *PcieDeviceConfigSpace;
|
||||
uint64_t *DmaPositionBuffer = NULL;
|
||||
uint64_t *AddressBSL = NULL;
|
||||
int16_t *AudioBuffer = NULL;
|
||||
|
||||
uint64_t CorbAddress;
|
||||
void *CorbMapping = NULL;
|
||||
uint8_t CorbLastAddedCommandIndex = 0;
|
||||
|
||||
uint64_t RirbAddress;
|
||||
void *RirbMapping = NULL;
|
||||
uint8_t RirbLastProcessedResponseIndex = 0;
|
||||
|
||||
EFI_STATUS AddCommandToCorb(uint32_t VerbToSend)
|
||||
{
|
||||
CorbLastAddedCommandIndex += 1;
|
||||
if (CorbLastAddedCommandIndex >= 256) {
|
||||
CorbLastAddedCommandIndex = 0;
|
||||
}
|
||||
|
||||
WritePciMemory(CorbAddress + (CorbLastAddedCommandIndex * sizeof(uint32_t)), (void *)&VerbToSend, 1, EfiPciWidthUint32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBWP, (void *)&CorbLastAddedCommandIndex, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
CorbCommandCount += 1;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS ReadResponseFromRirb(uint64_t *VerbResponse)
|
||||
{
|
||||
RirbLastProcessedResponseIndex += 1;
|
||||
if (RirbLastProcessedResponseIndex >= 256) {
|
||||
RirbLastProcessedResponseIndex = 0;
|
||||
}
|
||||
|
||||
return ReadPciMemory(RirbAddress + (RirbLastProcessedResponseIndex * sizeof(uint64_t)), VerbResponse, 1, EfiPciWidthUint64);
|
||||
}
|
||||
|
||||
EFI_STATUS InitHda()
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
Status = GetHdaPciIoHandler();
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
|
||||
Status = GetRootBridgeIoHandler();
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS DisposeHdaLib()
|
||||
{
|
||||
// TODO: Release CORB and RIRB
|
||||
// Close protocols
|
||||
// Free Variables
|
||||
// Close events
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS AllocateCORBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace)
|
||||
{
|
||||
uint8_t *CorbAddressPointer = NULL;
|
||||
uint32_t ReadValue32 = 0;
|
||||
uint32_t WriteValue = 0;
|
||||
uint8_t WriteValue8 = 0;
|
||||
|
||||
SetupCommonBuffer(&CorbAddressPointer, 1024, &CorbMapping, 16);
|
||||
CorbAddress = (uint64_t)CorbAddressPointer;
|
||||
|
||||
WriteValue = (CorbAddress & 0xFFFFFFFF);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBLBASE,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = (CorbAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBUBASE,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = 0;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBWP,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = 0x8000;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
ReadControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
||||
(void *)&ReadValue32, 1, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = 0;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue8 = 0x3;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBCTL,
|
||||
(void *)&WriteValue8, 1, Bar0, EfiPciWidthUint8);
|
||||
|
||||
//debug("AllocateCORBBuffer(): CorbAddress=0x%llx\n", CorbAddress);
|
||||
//debug("AllocateCORBBuffer(): CorbMapping=0x%llx\n", CorbMapping);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS AllocateRIRBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace)
|
||||
{
|
||||
uint8_t *RirbAddressPointer = NULL;
|
||||
|
||||
uint32_t WriteValue = 0;
|
||||
uint8_t WriteValue8 = 0;
|
||||
|
||||
SetupCommonBuffer(&RirbAddressPointer, 2048, &RirbMapping, 16);
|
||||
RirbAddress = (uint64_t)RirbAddressPointer;
|
||||
|
||||
WriteValue = (RirbAddress & 0xFFFFFFFF);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBLBASE,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = (RirbAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBUBASE,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue = 0;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBWP,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
WriteValue8 = 0x2;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBCTL,
|
||||
(void *)&WriteValue8, 1, Bar0, EfiPciWidthUint8);
|
||||
|
||||
//debug("AllocateRIRBBuffer(): RirbAddress=0x%llx\n", RirbAddress);
|
||||
//debug("AllocateRIRBBuffer(): RirbMapping=0x%llx\n", RirbMapping);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS FillCodecNode(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
uint32_t CurrentNodeId,
|
||||
HDA_NODE_TYPE NodeType,
|
||||
struct Node *CurrentNode)
|
||||
{
|
||||
uint32_t CurrentSubordinateNodeCount = 0;
|
||||
struct Node TempNode;
|
||||
|
||||
TempNode.NodeId = CurrentNodeId;
|
||||
TempNode.NodeType = NodeType;
|
||||
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_VENDOR_ID, &TempNode.VendorId);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_REVISION_ID, &TempNode.RevisionId);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SUBORDINATE_NODE_COUNT, &CurrentSubordinateNodeCount);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_FUNCTION_GROUP_TYPE, &TempNode.FunctionGroupType);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_AUDIO_FUNC_CAP, &TempNode.FuncCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_AUDIO_WIDGET_CAP, &TempNode.WidgetCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SAMPLE_SIZE_RATE_CAP, &TempNode.SampleSizeRateCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_STREAM_FORMATS, &TempNode.StreamFormat);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_PIN_CAP, &TempNode.PinCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_INPUT_AMP_CAP, &TempNode.InputAmpCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_OUTPUT_AMP_CAP, &TempNode.OutputAmpCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_CONNECTION_LIST_LENGTH, &TempNode.ConnectionListLength);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SUPPORTED_POWER_STATES, &TempNode.SupportedPowerStates);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_PROCESSING_CAP, &TempNode.ProcessingCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_GPIO_COUNT, &TempNode.GPIOCount);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_VOLUME_KNOB_CAP, &TempNode.VolKnobCap);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_POWER_STATE, 0, &TempNode.PowerState);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_CHANNEL_STREAM_ID, 0, &TempNode.ChannelStreamId);
|
||||
|
||||
TempNode.StartingChildNodeAddess = HDA_SUB_NODE_COUNT_START_NODE(CurrentSubordinateNodeCount);
|
||||
TempNode.SubordinateNodeCount = HDA_SUB_NODE_COUNT_TOTAL_NODE(CurrentSubordinateNodeCount);
|
||||
TempNode.WidgetType = HDA_WIDGET_TYPE(TempNode.WidgetCap);
|
||||
TempNode.RightGain = GetAmplifierGain(PcieDeviceConfigSpace, TempNode.NodeId, true, false);
|
||||
TempNode.LeftGain = GetAmplifierGain(PcieDeviceConfigSpace, TempNode.NodeId, true, true);
|
||||
|
||||
memcpy(CurrentNode, &TempNode, sizeof(struct Node));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetNodeById(struct Node *RootNode,
|
||||
uint32_t NodeIdToSearch,
|
||||
struct Node *NodeDetected)
|
||||
{
|
||||
struct Node *CurrentFunctionGroupNode = NULL;
|
||||
struct Node *CurrentWidgetNode = NULL;
|
||||
|
||||
uint32_t CurrentFunctionGroupId = 0;
|
||||
uint32_t CurrentFgArrayIndexer = 0;
|
||||
|
||||
uint32_t CurrentWidgetId = 0;
|
||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
||||
|
||||
if (CurrentFunctionGroupNode->NodeId == NodeIdToSearch) {
|
||||
memcpy(NodeDetected, CurrentFunctionGroupNode, sizeof(struct Node));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
CurrentWidgetArrayIndexer = 0;
|
||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
||||
|
||||
if (CurrentWidgetNode->NodeId == NodeIdToSearch) {
|
||||
memcpy(NodeDetected, CurrentWidgetNode,sizeof(struct Node));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
struct Node *RootNode)
|
||||
{
|
||||
struct Node *CurrentFunctionGroupNode = NULL;
|
||||
struct Node *CurrentWidgetNode = NULL;
|
||||
|
||||
uint32_t CurrentFunctionGroupId = 0;
|
||||
uint32_t CurrentFgArrayIndexer = 0;
|
||||
|
||||
uint32_t CurrentWidgetId = 0;
|
||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
FillCodecNode(PcieDeviceConfigSpace, 0, HDA_NODE_ROOT, RootNode);
|
||||
RootNode->ChildNodes = mem_alloc(sizeof(struct Node) * (RootNode->SubordinateNodeCount - RootNode->StartingChildNodeAddess));
|
||||
memset(RootNode->ChildNodes, 0, sizeof(struct Node) * (RootNode->SubordinateNodeCount - RootNode->StartingChildNodeAddess));
|
||||
|
||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
||||
FillCodecNode(PcieDeviceConfigSpace, CurrentFunctionGroupId, HDA_NODE_FUNCTION_GROUP, CurrentFunctionGroupNode);
|
||||
CurrentFunctionGroupNode->ChildNodes = mem_alloc(sizeof(struct Node) * CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount);
|
||||
memset(CurrentFunctionGroupNode->ChildNodes, 0, sizeof(struct Node) * CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount);
|
||||
|
||||
CurrentWidgetArrayIndexer = 0;
|
||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
||||
FillCodecNode(PcieDeviceConfigSpace, CurrentWidgetId, HDA_NODE_WIDGET, CurrentWidgetNode);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS ReleaseCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
struct Node *RootNode)
|
||||
{
|
||||
struct Node *CurrentFunctionGroupNode = NULL;
|
||||
uint32_t CurrentFunctionGroupId = 0;
|
||||
uint32_t CurrentFgArrayIndexer = 0;
|
||||
|
||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount - 1; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
||||
mem_free(CurrentFunctionGroupNode->ChildNodes);
|
||||
}
|
||||
|
||||
mem_free(RootNode->ChildNodes);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetCodecData8BitPayload(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
uint8_t CodecAddress, uint8_t NodeId,
|
||||
HDA_VERB Verb, uint8_t VerbPayload,
|
||||
uint32_t *Response)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetCodecData8BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
uint8_t CodecAddress, uint8_t NodeId,
|
||||
HDA_VERB Verb, uint8_t VerbPayload,
|
||||
uint32_t *Response)
|
||||
{
|
||||
HDA_COMMAND_FIELD_8BIT_PAYLOAD Command;
|
||||
HDA_RESPONSE_FIELD *RawResponse;
|
||||
|
||||
uint32_t VerbToSend = 0;
|
||||
uint64_t TempResponse = 0;
|
||||
|
||||
Command.CAd = CodecAddress;
|
||||
Command.NID = NodeId;
|
||||
Command.VerbIdent = Verb;
|
||||
Command.VerbPayload = VerbPayload;
|
||||
|
||||
memcpy(&VerbToSend, &Command, sizeof(uint32_t));
|
||||
AddCommandToCorb(VerbToSend);
|
||||
|
||||
gBootServices->Stall(200);
|
||||
|
||||
ReadResponseFromRirb(&TempResponse);
|
||||
|
||||
RawResponse = (HDA_RESPONSE_FIELD *)&TempResponse;
|
||||
memcpy(Response, &RawResponse->Response, sizeof(uint32_t));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetCodecData16BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
uint8_t CodecAddress, uint8_t NodeId,
|
||||
HDA_VERB Verb, uint16_t VerbPayload,
|
||||
uint32_t *Response)
|
||||
{
|
||||
HDA_COMMAND_FIELD_16BIT_PAYLOAD Command;
|
||||
HDA_RESPONSE_FIELD *RawResponse;
|
||||
|
||||
uint32_t VerbToSend = 0;
|
||||
uint64_t TempResponse = 0;
|
||||
|
||||
Command.CAd = CodecAddress;
|
||||
Command.NID = NodeId;
|
||||
Command.VerbIdent = Verb;
|
||||
Command.VerbPayload = VerbPayload;
|
||||
|
||||
memcpy(&VerbToSend, &Command, sizeof(uint32_t));
|
||||
AddCommandToCorb(VerbToSend);
|
||||
|
||||
gBootServices->Stall(200);
|
||||
|
||||
ReadResponseFromRirb(&TempResponse);
|
||||
|
||||
RawResponse = (HDA_RESPONSE_FIELD *)&TempResponse;
|
||||
memcpy(Response, &RawResponse->Response, sizeof(uint32_t));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS SendCommandToAllWidgets8BitPayload (
|
||||
PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
HDA_VERB Verb, uint8_t VerbPayload)
|
||||
{
|
||||
struct Node RootNode;
|
||||
uint32_t Response;
|
||||
|
||||
GetCodecTree(PcieDeviceConfigSpace, &RootNode);
|
||||
|
||||
struct Node *CurrentFunctionGroupNode = NULL;
|
||||
struct Node *CurrentWidgetNode = NULL;
|
||||
|
||||
uint32_t CurrentFunctionGroupId = 0;
|
||||
uint32_t CurrentFgArrayIndexer = 0;
|
||||
|
||||
uint32_t CurrentWidgetId = 0;
|
||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, 0, Verb, VerbPayload, &Response);
|
||||
|
||||
debug("Verb 0x%llx with payload 0x%llx sent to node 0x0\n", Verb, VerbPayload);
|
||||
for (CurrentFunctionGroupId = RootNode.StartingChildNodeAddess; CurrentFunctionGroupId < RootNode.StartingChildNodeAddess + RootNode.SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentFunctionGroupId, Verb, VerbPayload, &Response);
|
||||
CurrentFunctionGroupNode = &(RootNode.ChildNodes[CurrentFgArrayIndexer]);
|
||||
CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentWidgetId, Verb, VerbPayload, &Response);
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseCodecTree(PcieDeviceConfigSpace, &RootNode);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS SendCommandToAllWidgets16BitPayload (
|
||||
PCI_HDA_REGION* PcieDeviceConfigSpace,
|
||||
HDA_VERB Verb, uint16_t VerbPayload)
|
||||
{
|
||||
struct Node RootNode;
|
||||
uint32_t Response;
|
||||
|
||||
GetCodecTree(PcieDeviceConfigSpace, &RootNode);
|
||||
|
||||
struct Node *CurrentFunctionGroupNode = NULL;
|
||||
struct Node *CurrentWidgetNode = NULL;
|
||||
|
||||
uint32_t CurrentFunctionGroupId = 0;
|
||||
uint32_t CurrentFgArrayIndexer = 0;
|
||||
|
||||
uint32_t CurrentWidgetId = 0;
|
||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, 0, Verb, VerbPayload, &Response);
|
||||
|
||||
for (CurrentFunctionGroupId = RootNode.StartingChildNodeAddess; CurrentFunctionGroupId < RootNode.StartingChildNodeAddess + RootNode.SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentFunctionGroupId, Verb, VerbPayload, &Response);
|
||||
CurrentFunctionGroupNode = &(RootNode.ChildNodes[CurrentFgArrayIndexer]);
|
||||
CurrentWidgetArrayIndexer = 0;
|
||||
|
||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentWidgetId, Verb, VerbPayload, &Response);
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseCodecTree(PcieDeviceConfigSpace, &RootNode);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS GetCodecData16BitPayload(PCI_HDA_REGION* PcieDeviceConfigSpace,
|
||||
uint8_t CodecAddress, uint8_t NodeId,
|
||||
HDA_VERB Verb, uint16_t VerbPayload,
|
||||
uint32_t *Response)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t GetAmplifierGain(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
uint8_t NodeId, bool InputOutput,
|
||||
bool LeftRight)
|
||||
{
|
||||
uint32_t Response = 0;
|
||||
uint16_t PayloadToSend = 0;
|
||||
|
||||
PayloadToSend = NodeId;
|
||||
PayloadToSend |= (InputOutput << 15);
|
||||
PayloadToSend |= (LeftRight << 13);
|
||||
|
||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0x0, NodeId, HDA_VRB_GET_AMPLIFIER_GAIN_MUTE, 0x0, &Response);
|
||||
return Response;
|
||||
}
|
||||
|
||||
EFI_STATUS DisablePcieInterrupts(PCI_HDA_REGION *PcieDeviceConfigSpace)
|
||||
{
|
||||
uint16_t CommandRegister = 0;
|
||||
|
||||
ReadControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_PCICMD, &CommandRegister, 1, EfiPciWidthUint16);
|
||||
CommandRegister += (1 << 10);
|
||||
WriteControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_PCICMD, (void *)&CommandRegister, 1, EfiPciWidthUint16);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EnablePcieNoSnoop(PCI_HDA_REGION *PcieDeviceConfigSpace)
|
||||
{
|
||||
uint16_t DeviceControlRegister = 0;
|
||||
|
||||
ReadControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_DEVCTL, (void *)&DeviceControlRegister, 1, EfiPciWidthUint16);
|
||||
DeviceControlRegister += (1 << 11);
|
||||
WriteControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_DEVCTL, (void *)&DeviceControlRegister, 1, EfiPciWidthUint16);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS AddDescriptorListEntryOss0(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet,
|
||||
uint64_t DataAddress,
|
||||
uint32_t DataLength,
|
||||
uint8_t BdlEntryIndex,
|
||||
uint32_t SdxLastValidIndex)
|
||||
{
|
||||
EFI_UINT64 BdlAddress;
|
||||
EFI_UINT32 BdlLower;
|
||||
EFI_UINT64 BdlUpper;
|
||||
|
||||
HDA_BUFFER_DESCRIPTOR_LIST *DescriptorList = NULL;
|
||||
|
||||
ReadControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
||||
(void *)&BdlLower, 1, EfiPciWidthUint32);
|
||||
ReadControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
||||
(void *)&BdlUpper, 1, EfiPciWidthUint32);
|
||||
|
||||
BdlAddress = BdlLower | (BdlUpper << 32);
|
||||
|
||||
DescriptorList = (HDA_BUFFER_DESCRIPTOR_LIST *)BdlAddress;
|
||||
DescriptorList->BDLEntry[BdlEntryIndex].Address = DataAddress;
|
||||
DescriptorList->BDLEntry[BdlEntryIndex].Length = DataLength;
|
||||
|
||||
// TODO: Enable this after Corb/Rirb start to process unsolicited responses
|
||||
DescriptorList->BDLEntry[BdlEntryIndex].IntrptOnComp = 1;
|
||||
|
||||
return WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXLVI,
|
||||
(void *)&SdxLastValidIndex, 1, Bar0, EfiPciWidthUint32);
|
||||
}
|
||||
|
||||
EFI_STATUS AllocateStreamsPages(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet)
|
||||
{
|
||||
uint8_t *BdlAddressPointer = NULL;
|
||||
void *BdlMapping = NULL;
|
||||
uint64_t BdlAddress;
|
||||
|
||||
// DMAPositionBuffer
|
||||
uint8_t *DmaAddressPointer = NULL;
|
||||
void *DmaMapping = NULL;
|
||||
uint64_t DmaAddress;
|
||||
|
||||
uint32_t WriteValue = 0;
|
||||
|
||||
uint64_t IssCount = (ControllerRegisterSet->GCAP >> 8) & 0xF;
|
||||
uint64_t OssCount = (ControllerRegisterSet->GCAP >> 12) & 0xF;
|
||||
uint64_t BssCount = (ControllerRegisterSet->GCAP >> 3) & 0x1F;
|
||||
uint64_t Count = 0;
|
||||
|
||||
for (Count = 0; Count < IssCount; Count++) {
|
||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
||||
|
||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
||||
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_ISSN_OFFSET(Count) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
WriteValue = (BdlAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_ISSN_OFFSET(Count) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
}
|
||||
|
||||
for (Count = 0; Count < OssCount; Count++) {
|
||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
||||
|
||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
||||
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
WriteValue = (BdlAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
}
|
||||
|
||||
for (Count = 0; Count < BssCount; Count++) {
|
||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
||||
|
||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
||||
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_BSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
WriteValue = (BdlAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_BSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
}
|
||||
|
||||
SetupCommonBuffer(&DmaAddressPointer, (IssCount + OssCount + BssCount) * sizeof(uint64_t), &DmaMapping, 16);
|
||||
DmaAddress = (uint64_t)DmaAddressPointer;
|
||||
|
||||
WriteValue = (DmaAddress & 0xFFFFFFFF);
|
||||
WriteValue |= 0x01;
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_DPIBLBASE, (void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
WriteValue = (DmaAddress >> 32);
|
||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_DPIBUBASE, (void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue