From 321e633fa4b8e858a4bbe9b4de35074a818f99da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 1 Jan 2009 14:58:10 +0000 Subject: [PATCH] Patch from tqh, modified by myself: enable PCIe snooping through vendor specific registers (ATI and nVidia). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28838 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../drivers/audio/hda/hda_controller.cpp | 37 +++++++++++++++---- .../drivers/audio/hda/hda_controller_defs.h | 9 +++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp index 97539e84bb..4e06050a71 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp @@ -48,6 +48,17 @@ static const struct { }; +static inline void +update_pci_register(hda_controller* controller, uint8 reg, uint8 mask, uint8 value) +{ + uint8 tmp = (gPci->read_pci_config)(controller->pci_info.bus, + controller->pci_info.device, controller->pci_info.function, reg, 1); + (gPci->write_pci_config)(controller->pci_info.bus, + controller->pci_info.device, controller->pci_info.function, + reg, 1, (tmp & mask) | value); +} + + static inline rirb_t& current_rirb(hda_controller *controller) { @@ -700,8 +711,7 @@ hda_hw_init(hda_controller* controller) { uint16 capabilities, stateStatus, cmd; status_t status; - uint8 tcsel; - + /* Map MMIO registers */ controller->regs_area = map_physical_memory("hda_hw_regs", (void*)controller->pci_info.u.h0.base_registers[0], @@ -729,11 +739,22 @@ hda_hw_init(hda_controller* controller) goto no_irq; /* TCSEL is reset to TC0 (clear 0-2 bits) */ - tcsel = (gPci->read_pci_config)(controller->pci_info.bus, - controller->pci_info.device, controller->pci_info.function, PCI_HDA_TCSEL, 1); - (gPci->write_pci_config)(controller->pci_info.bus, - controller->pci_info.device, controller->pci_info.function, - PCI_HDA_TCSEL, 1, tcsel & 0xf8); + update_pci_register(controller, PCI_HDA_TCSEL, PCI_HDA_TCSEL_MASK, 0); + + /* Enable snooping for ATI and Nvidia, right now for all their hda-devices, + but only based on guessing. */ + switch (controller->pci_info.vendor_id) { + /* NVIDIA */ + case 0x10de: + update_pci_register(controller, NVIDIA_HDA_TRANSREG, + NVIDIA_HDA_TRANSREG_MASK, NVIDIA_HDA_ENABLE_COHBITS); + break; + /* ATI */ + case 0x1002: + update_pci_register(controller, ATI_HDA_MISC_CNTR2, + ATI_HDA_MISC_CNTR2_MASK, ATI_HDA_ENABLE_SNOOP); + break; + } capabilities = controller->Read16(HDAC_GLOBAL_CAP); controller->num_input_streams = GLOBAL_CAP_INPUT_STREAMS(capabilities); @@ -762,7 +783,7 @@ hda_hw_init(hda_controller* controller) dprintf("hda: init_corb_rirb_pos failed\n"); goto corb_rirb_failed; } - + controller->Write16(HDAC_WAKE_ENABLE, 0x7fff); /* Enable controller interrupts */ diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller_defs.h b/src/add-ons/kernel/drivers/audio/hda/hda_controller_defs.h index 357cb2f679..84da5e397c 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller_defs.h +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller_defs.h @@ -133,6 +133,15 @@ /* PCI space register definitions */ #define PCI_HDA_TCSEL 0x44 +#define PCI_HDA_TCSEL_MASK 0xf8 + +#define ATI_HDA_MISC_CNTR2 0x42 +#define ATI_HDA_MISC_CNTR2_MASK 0xf8 +#define ATI_HDA_ENABLE_SNOOP 0x02 +#define NVIDIA_HDA_TRANSREG 0x4e +#define NVIDIA_HDA_TRANSREG_MASK 0xf0 +#define NVIDIA_HDA_ENABLE_COHBITS 0x0f + typedef uint32 corb_t; typedef struct {