Refresh redox-drm and AMD GPU driver
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -44,8 +44,11 @@ unsafe extern "C" {
|
||||
fn ffi_redox_pci_set_device_info(
|
||||
vendor: u16,
|
||||
device: u16,
|
||||
bus_number: u8,
|
||||
dev_number: u8,
|
||||
func_number: u8,
|
||||
revision: u8,
|
||||
irq: u8,
|
||||
irq: u32,
|
||||
bar0_addr: u64,
|
||||
bar0_size: u64,
|
||||
bar2_addr: u64,
|
||||
@@ -105,6 +108,9 @@ fn amdgpu_dc_cleanup() {
|
||||
pub fn set_pci_device_info(
|
||||
vendor: u16,
|
||||
device: u16,
|
||||
bus_number: u8,
|
||||
dev_number: u8,
|
||||
func_number: u8,
|
||||
revision: u8,
|
||||
irq: u32,
|
||||
bar0_addr: u64,
|
||||
@@ -115,11 +121,31 @@ pub fn set_pci_device_info(
|
||||
#[cfg(not(no_amdgpu_c))]
|
||||
unsafe {
|
||||
ffi_redox_pci_set_device_info(
|
||||
vendor, device, revision, irq as u8, bar0_addr, bar0_size, bar2_addr, bar2_size,
|
||||
vendor,
|
||||
device,
|
||||
bus_number,
|
||||
dev_number,
|
||||
func_number,
|
||||
revision,
|
||||
irq,
|
||||
bar0_addr,
|
||||
bar0_size,
|
||||
bar2_addr,
|
||||
bar2_size,
|
||||
);
|
||||
}
|
||||
let _ = (
|
||||
vendor, device, revision, irq, bar0_addr, bar0_size, bar2_addr, bar2_size,
|
||||
vendor,
|
||||
device,
|
||||
bus_number,
|
||||
dev_number,
|
||||
func_number,
|
||||
revision,
|
||||
irq,
|
||||
bar0_addr,
|
||||
bar0_size,
|
||||
bar2_addr,
|
||||
bar2_size,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,9 @@ impl AmdDriver {
|
||||
display::set_pci_device_info(
|
||||
info.vendor_id,
|
||||
info.device_id,
|
||||
info.location.bus,
|
||||
info.location.device,
|
||||
info.location.function,
|
||||
info.revision,
|
||||
info.irq.unwrap_or(0),
|
||||
bar0.addr,
|
||||
@@ -522,22 +525,6 @@ impl GpuDriver for AmdDriver {
|
||||
Ok(gem.object(handle)?.size)
|
||||
}
|
||||
|
||||
fn gem_export_dmafd(&self, handle: GemHandle) -> Result<i32> {
|
||||
let mut gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("GEM manager poisoned".to_string()))?;
|
||||
gem.export_dmafd(handle)
|
||||
}
|
||||
|
||||
fn gem_import_dmafd(&self, fd: i32) -> Result<GemHandle> {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("GEM manager poisoned".to_string()))?;
|
||||
gem.import_dmafd(fd)
|
||||
}
|
||||
|
||||
fn get_edid(&self, connector_id: u32) -> Vec<u8> {
|
||||
match self.connectors.lock() {
|
||||
Ok(connectors) => connectors
|
||||
|
||||
@@ -443,27 +443,6 @@ impl GpuDriver for IntelDriver {
|
||||
Ok(gem.object(handle)?.size)
|
||||
}
|
||||
|
||||
fn gem_export_dmafd(&self, handle: GemHandle) -> Result<i32> {
|
||||
let mut gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
gem.export_dmafd(handle)
|
||||
}
|
||||
|
||||
fn gem_import_dmafd(&self, fd: i32) -> Result<GemHandle> {
|
||||
let handle = {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
gem.import_dmafd(fd)?
|
||||
};
|
||||
|
||||
let _ = self.ensure_gem_gpu_mapping(handle)?;
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
fn get_edid(&self, connector_id: u32) -> Vec<u8> {
|
||||
match self.connectors.lock() {
|
||||
Ok(connectors) => connectors
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::io::{Read, Write};
|
||||
|
||||
use log::{info, warn};
|
||||
use redox_driver_sys::irq::{IrqHandle, MsixTable, MsixVector};
|
||||
use redox_driver_sys::pci::{PciDevice, PciDeviceInfo, PCI_CAP_ID_MSIX};
|
||||
use redox_driver_sys::pci::{PciDevice, PciDeviceInfo, PCI_CAP_ID_MSI, PCI_CAP_ID_MSIX};
|
||||
use redox_driver_sys::quirks::PciQuirkFlags;
|
||||
|
||||
use crate::driver::{DriverError, Result};
|
||||
|
||||
@@ -12,6 +13,10 @@ pub enum InterruptHandle {
|
||||
table: MsixTable,
|
||||
cap_offset: u8,
|
||||
},
|
||||
Msi {
|
||||
handle: IrqHandle,
|
||||
irq: u32,
|
||||
},
|
||||
Legacy {
|
||||
handle: IrqHandle,
|
||||
irq: u32,
|
||||
@@ -20,8 +25,35 @@ pub enum InterruptHandle {
|
||||
|
||||
impl InterruptHandle {
|
||||
pub fn setup(device_info: &PciDeviceInfo, pci_device: &mut PciDevice) -> Result<Self> {
|
||||
if let Ok(Some(handle)) = Self::try_msix(device_info, pci_device) {
|
||||
return Ok(handle);
|
||||
let quirks = device_info.quirks();
|
||||
|
||||
if !quirks.contains(PciQuirkFlags::NO_MSIX) {
|
||||
if let Ok(Some(handle)) = Self::try_msix(device_info, pci_device) {
|
||||
return Ok(handle);
|
||||
}
|
||||
} else {
|
||||
info!(
|
||||
"redox-drm: skipping MSI-X for {} (NO_MSIX quirk)",
|
||||
device_info.location
|
||||
);
|
||||
}
|
||||
|
||||
if !quirks.contains(PciQuirkFlags::NO_MSI) {
|
||||
if let Ok(Some(handle)) = Self::try_msi(device_info, pci_device) {
|
||||
return Ok(handle);
|
||||
}
|
||||
} else {
|
||||
info!(
|
||||
"redox-drm: skipping MSI for {} (NO_MSI quirk)",
|
||||
device_info.location
|
||||
);
|
||||
}
|
||||
|
||||
if quirks.contains(PciQuirkFlags::FORCE_LEGACY_IRQ) {
|
||||
info!(
|
||||
"redox-drm: forcing legacy IRQ for {} (FORCE_LEGACY_IRQ quirk)",
|
||||
device_info.location
|
||||
);
|
||||
}
|
||||
|
||||
Self::try_legacy(device_info)
|
||||
@@ -89,6 +121,35 @@ impl InterruptHandle {
|
||||
}))
|
||||
}
|
||||
|
||||
fn try_msi(device_info: &PciDeviceInfo, _pci_device: &mut PciDevice) -> Result<Option<Self>> {
|
||||
let msi_cap = match device_info.find_capability(PCI_CAP_ID_MSI) {
|
||||
Some(cap) => cap,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let irq = device_info.irq.ok_or_else(|| {
|
||||
DriverError::Io(format!("no IRQ for MSI on {}", device_info.location))
|
||||
})?;
|
||||
|
||||
let handle = match IrqHandle::request(irq) {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"redox-drm: MSI IRQ request failed for {}: {e}",
|
||||
device_info.location
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
info!(
|
||||
"redox-drm: MSI enabled for {} cap_offset={:#x} irq {}",
|
||||
device_info.location, msi_cap.offset, irq
|
||||
);
|
||||
|
||||
Ok(Some(InterruptHandle::Msi { handle, irq }))
|
||||
}
|
||||
|
||||
fn try_legacy(device_info: &PciDeviceInfo) -> Result<Self> {
|
||||
let irq = device_info
|
||||
.irq
|
||||
@@ -114,7 +175,7 @@ impl InterruptHandle {
|
||||
Err(e) => Err(DriverError::Io(e.to_string())),
|
||||
}
|
||||
}
|
||||
InterruptHandle::Legacy { handle, .. } => handle
|
||||
InterruptHandle::Msi { handle, .. } | InterruptHandle::Legacy { handle, .. } => handle
|
||||
.try_wait()
|
||||
.map(|ev| ev.is_some())
|
||||
.map_err(|e| DriverError::Io(e.to_string())),
|
||||
@@ -134,7 +195,7 @@ impl InterruptHandle {
|
||||
.write_all(&buf)
|
||||
.map_err(|e| DriverError::Io(e.to_string()))
|
||||
}
|
||||
InterruptHandle::Legacy { handle, .. } => {
|
||||
InterruptHandle::Msi { handle, .. } | InterruptHandle::Legacy { handle, .. } => {
|
||||
let mut buf = [0u8; 8];
|
||||
let _ = handle.wait().map_err(|e| DriverError::Io(e.to_string()))?;
|
||||
Ok(())
|
||||
@@ -145,7 +206,7 @@ impl InterruptHandle {
|
||||
pub fn irq(&self) -> u32 {
|
||||
match self {
|
||||
InterruptHandle::Msix { vector, .. } => vector.irq,
|
||||
InterruptHandle::Legacy { irq, .. } => *irq,
|
||||
InterruptHandle::Msi { irq, .. } | InterruptHandle::Legacy { irq, .. } => *irq,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ pub mod interrupt;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::info;
|
||||
use redox_driver_sys::pci::{PciDevice, PciDeviceInfo, PCI_VENDOR_ID_AMD, PCI_VENDOR_ID_INTEL};
|
||||
use redox_driver_sys::quirks::PciQuirkFlags;
|
||||
|
||||
use crate::driver::{DriverError, GpuDriver, Result};
|
||||
|
||||
@@ -26,6 +28,21 @@ impl DriverRegistry {
|
||||
info
|
||||
};
|
||||
|
||||
let quirks = full.quirks();
|
||||
if !quirks.is_empty() {
|
||||
info!(
|
||||
"redox-drm: quirks for {:#06x}:{:#06x}: {:?}",
|
||||
full.vendor_id, full.device_id, quirks
|
||||
);
|
||||
}
|
||||
|
||||
if quirks.contains(PciQuirkFlags::DISABLE_ACCEL) {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {:#06x}:{:#06x} at {} has DISABLE_ACCEL quirk — skipping probe",
|
||||
full.vendor_id, full.device_id, full.location
|
||||
)));
|
||||
}
|
||||
|
||||
match full.vendor_id {
|
||||
PCI_VENDOR_ID_AMD => {
|
||||
let driver = amd::AmdDriver::new(full, firmware)?;
|
||||
|
||||
Reference in New Issue
Block a user