Added HDA quirks for enabling snoop.
* Enabled snoop for all Intel hardware as found in the Linux driver. * This fixes #8949.
This commit is contained in:
parent
0ea775505e
commit
1979b64856
@ -35,6 +35,33 @@
|
||||
#define PAGE_ALIGN(size) (((size) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1))
|
||||
|
||||
|
||||
#define PCI_VENDOR_AMD 0x1002
|
||||
#define PCI_VENDOR_INTEL 0x8086
|
||||
#define PCI_VENDOR_NVIDIA 0x10de
|
||||
#define PCI_ALL_DEVICES 0xffffffff
|
||||
#define HDA_QUIRK_SNOOP 0x0001
|
||||
|
||||
|
||||
static const struct {
|
||||
uint32 vendor_id, device_id;
|
||||
uint32 quirks;
|
||||
} kControllerQuirks[] = {
|
||||
{ PCI_VENDOR_INTEL, 0x1c20, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x1d20, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x1e20, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x8c20, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x9c20, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x9c21, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x0c0c, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x811b, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_INTEL, 0x080a, HDA_QUIRK_SNOOP },
|
||||
// Enable snooping for ATI and Nvidia, right now for all their hda-devices,
|
||||
// but only based on guessing.
|
||||
{ PCI_VENDOR_AMD, PCI_ALL_DEVICES, HDA_QUIRK_SNOOP },
|
||||
{ PCI_VENDOR_NVIDIA, PCI_ALL_DEVICES, HDA_QUIRK_SNOOP },
|
||||
};
|
||||
|
||||
|
||||
static const struct {
|
||||
uint32 multi_rate;
|
||||
uint32 hw_rate;
|
||||
@ -59,6 +86,20 @@ static const struct {
|
||||
static pci_x86_module_info* sPCIx86Module;
|
||||
|
||||
|
||||
static uint32
|
||||
get_controller_quirks(pci_info& info)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < sizeof(kControllerQuirks) / sizeof(kControllerQuirks[0]); i++) {
|
||||
if (info.vendor_id == kControllerQuirks[i].vendor_id
|
||||
&& (kControllerQuirks[i].device_id == PCI_ALL_DEVICES
|
||||
|| kControllerQuirks[i].device_id == info.device_id))
|
||||
return kControllerQuirks[i].quirks;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
update_pci_register(hda_controller* controller, uint8 reg, uint32 mask, uint32 value, uint8 size)
|
||||
{
|
||||
@ -800,8 +841,11 @@ hda_verb_read(hda_codec* codec, uint32 nid, uint32 vid, uint32 *response)
|
||||
status_t
|
||||
hda_hw_init(hda_controller* controller)
|
||||
{
|
||||
uint16 capabilities, stateStatus, cmd;
|
||||
uint16 capabilities;
|
||||
uint16 stateStatus;
|
||||
uint16 cmd;
|
||||
status_t status;
|
||||
uint32 quirks;
|
||||
|
||||
// Map MMIO registers
|
||||
controller->regs_area = map_physical_memory("hda_hw_regs",
|
||||
@ -861,27 +905,26 @@ hda_hw_init(hda_controller* controller)
|
||||
// TCSEL is reset to TC0 (clear 0-2 bits)
|
||||
update_pci_register(controller, PCI_HDA_TCSEL, PCI_HDA_TCSEL_MASK, 0, 1);
|
||||
|
||||
// Enable snooping for ATI and Nvidia, right now for all their hda-devices,
|
||||
// but only based on guessing.
|
||||
switch (controller->pci_info.vendor_id) {
|
||||
case NVIDIA_VENDORID:
|
||||
update_pci_register(controller, NVIDIA_HDA_TRANSREG,
|
||||
NVIDIA_HDA_TRANSREG_MASK, NVIDIA_HDA_ENABLE_COHBITS, 1);
|
||||
update_pci_register(controller, NVIDIA_HDA_ISTRM_COH,
|
||||
~NVIDIA_HDA_ENABLE_COHBIT, NVIDIA_HDA_ENABLE_COHBIT, 1);
|
||||
update_pci_register(controller, NVIDIA_HDA_OSTRM_COH,
|
||||
~NVIDIA_HDA_ENABLE_COHBIT, NVIDIA_HDA_ENABLE_COHBIT, 1);
|
||||
break;
|
||||
case ATI_VENDORID:
|
||||
update_pci_register(controller, ATI_HDA_MISC_CNTR2,
|
||||
ATI_HDA_MISC_CNTR2_MASK, ATI_HDA_ENABLE_SNOOP, 1);
|
||||
break;
|
||||
case INTEL_VENDORID:
|
||||
if (controller->pci_info.device_id == INTEL_SCH_DEVICEID) {
|
||||
quirks = get_controller_quirks(controller->pci_info);
|
||||
if ((quirks & HDA_QUIRK_SNOOP) != 0) {
|
||||
switch (controller->pci_info.vendor_id) {
|
||||
case PCI_VENDOR_NVIDIA:
|
||||
update_pci_register(controller, NVIDIA_HDA_TRANSREG,
|
||||
NVIDIA_HDA_TRANSREG_MASK, NVIDIA_HDA_ENABLE_COHBITS, 1);
|
||||
update_pci_register(controller, NVIDIA_HDA_ISTRM_COH,
|
||||
~NVIDIA_HDA_ENABLE_COHBIT, NVIDIA_HDA_ENABLE_COHBIT, 1);
|
||||
update_pci_register(controller, NVIDIA_HDA_OSTRM_COH,
|
||||
~NVIDIA_HDA_ENABLE_COHBIT, NVIDIA_HDA_ENABLE_COHBIT, 1);
|
||||
break;
|
||||
case PCI_VENDOR_AMD:
|
||||
update_pci_register(controller, ATI_HDA_MISC_CNTR2,
|
||||
ATI_HDA_MISC_CNTR2_MASK, ATI_HDA_ENABLE_SNOOP, 1);
|
||||
break;
|
||||
case PCI_VENDOR_INTEL:
|
||||
update_pci_register(controller, INTEL_SCH_HDA_DEVC,
|
||||
~INTEL_SCH_HDA_DEVC_SNOOP, 0, 2);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
capabilities = controller->Read16(HDAC_GLOBAL_CAP);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -135,24 +135,18 @@
|
||||
#define PCI_HDA_TCSEL 0x44
|
||||
#define PCI_HDA_TCSEL_MASK 0xf8
|
||||
|
||||
#define ATI_HDA_MISC_CNTR2 0x42
|
||||
#define ATI_HDA_MISC_CNTR2 0x42
|
||||
#define ATI_HDA_MISC_CNTR2_MASK 0xf8
|
||||
#define ATI_HDA_ENABLE_SNOOP 0x02
|
||||
#define NVIDIA_HDA_OSTRM_COH 0x4c
|
||||
#define NVIDIA_HDA_ISTRM_COH 0x4d
|
||||
#define NVIDIA_HDA_ENABLE_COHBIT 0x01
|
||||
#define NVIDIA_HDA_TRANSREG 0x4e
|
||||
#define NVIDIA_HDA_TRANSREG 0x4e
|
||||
#define NVIDIA_HDA_TRANSREG_MASK 0xf0
|
||||
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
|
||||
#define INTEL_SCH_HDA_DEVC 0x78
|
||||
#define INTEL_SCH_HDA_DEVC 0x78
|
||||
#define INTEL_SCH_HDA_DEVC_SNOOP 0x800
|
||||
|
||||
#define ATI_VENDORID 0x1002
|
||||
#define INTEL_VENDORID 0x8086
|
||||
#define INTEL_SCH_DEVICEID 0x811b
|
||||
#define NVIDIA_VENDORID 0x10de
|
||||
|
||||
|
||||
|
||||
typedef uint32 corb_t;
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user