intel_extreme: add MSI support
This commit is contained in:
parent
83ea4af492
commit
c2cfbd70fe
@ -103,6 +103,7 @@ int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
char* gDeviceNames[MAX_CARDS + 1];
|
||||
intel_info* gDeviceInfo[MAX_CARDS];
|
||||
pci_module_info* gPCI;
|
||||
pci_x86_module_info* gPCIx86Module = NULL;
|
||||
agp_gart_module_info* gGART;
|
||||
mutex gLock;
|
||||
|
||||
@ -185,6 +186,14 @@ init_driver(void)
|
||||
|
||||
mutex_init(&gLock, "intel extreme ksync");
|
||||
|
||||
// Try to get the PCI x86 module as well so we can enable possible MSIs.
|
||||
if (get_module(B_PCI_X86_MODULE_NAME,
|
||||
(module_info **)&gPCIx86Module) != B_OK) {
|
||||
ERROR("failed to get pci x86 module\n");
|
||||
gPCIx86Module = NULL;
|
||||
}
|
||||
|
||||
|
||||
// find devices
|
||||
|
||||
int32 found = 0;
|
||||
@ -240,6 +249,10 @@ init_driver(void)
|
||||
mutex_destroy(&gLock);
|
||||
put_module(B_AGP_GART_MODULE_NAME);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
if (gPCIx86Module != NULL) {
|
||||
gPCIx86Module = NULL;
|
||||
put_module(B_PCI_X86_MODULE_NAME);
|
||||
}
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
@ -263,6 +276,10 @@ uninit_driver(void)
|
||||
|
||||
put_module(B_AGP_GART_MODULE_NAME);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
if (gPCIx86Module != NULL) {
|
||||
gPCIx86Module = NULL;
|
||||
put_module(B_PCI_X86_MODULE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
extern char* gDeviceNames[];
|
||||
extern intel_info* gDeviceInfo[];
|
||||
extern pci_module_info* gPCI;
|
||||
extern pci_x86_module_info* gPCIx86Module;
|
||||
extern agp_gart_module_info* gGART;
|
||||
extern mutex gLock;
|
||||
|
||||
|
@ -131,13 +131,30 @@ init_interrupt_handler(intel_info &info)
|
||||
status = B_ERROR;
|
||||
}
|
||||
|
||||
if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00
|
||||
&& info.pci->u.h0.interrupt_line != 0xff) {
|
||||
// Find the right interrupt vector, using MSIs if available.
|
||||
info.irq = 0xff;
|
||||
info.use_msi = false;
|
||||
if (info.pci->u.h0.interrupt_pin != 0x00)
|
||||
info.irq = info.pci->u.h0.interrupt_line;
|
||||
if (gPCIx86Module != NULL && gPCIx86Module->get_msi_count(info.pci->bus,
|
||||
info.pci->device, info.pci->function) >= 1) {
|
||||
uint8 msiVector = 0;
|
||||
if (gPCIx86Module->configure_msi(info.pci->bus, info.pci->device,
|
||||
info.pci->function, 1, &msiVector) == B_OK
|
||||
&& gPCIx86Module->enable_msi(info.pci->bus, info.pci->device,
|
||||
info.pci->function) == B_OK) {
|
||||
ERROR("using message signaled interrupts\n");
|
||||
info.irq = msiVector;
|
||||
info.use_msi = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == B_OK && info.irq != 0xff) {
|
||||
// we've gotten an interrupt line for us to use
|
||||
|
||||
info.fake_interrupts = false;
|
||||
|
||||
status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line,
|
||||
status = install_io_interrupt_handler(info.irq,
|
||||
&intel_interrupt_handler, (void*)&info, 0);
|
||||
if (status == B_OK) {
|
||||
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
|
||||
@ -384,8 +401,14 @@ intel_extreme_uninit(intel_info &info)
|
||||
write16(info, find_reg(info, INTEL_INTERRUPT_ENABLED), 0);
|
||||
write16(info, find_reg(info, INTEL_INTERRUPT_MASK), ~0);
|
||||
|
||||
remove_io_interrupt_handler(info.pci->u.h0.interrupt_line,
|
||||
intel_interrupt_handler, &info);
|
||||
remove_io_interrupt_handler(info.irq, intel_interrupt_handler, &info);
|
||||
|
||||
if (info.use_msi && gPCIx86Module != NULL) {
|
||||
gPCIx86Module->disable_msi(info.pci->bus,
|
||||
info.pci->device, info.pci->function);
|
||||
gPCIx86Module->unconfigure_msi(info.pci->bus,
|
||||
info.pci->device, info.pci->function);
|
||||
}
|
||||
}
|
||||
|
||||
gGART->unmap_aperture(info.aperture);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <AGP.h>
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
#include <PCI_x86.h>
|
||||
|
||||
#include "intel_extreme.h"
|
||||
#include "lock.h"
|
||||
@ -34,6 +35,8 @@ struct intel_info {
|
||||
struct overlay_registers* overlay_registers;
|
||||
|
||||
bool fake_interrupts;
|
||||
uint8 irq;
|
||||
bool use_msi;
|
||||
|
||||
const char* device_identifier;
|
||||
DeviceType device_type;
|
||||
|
Loading…
Reference in New Issue
Block a user