intel: P0 — DP retrain at modeset, sync_file fd export/import
display.rs: DP link retraining at set_mode time Before enabling DDI_BUF_CTL, retrain DP link for the active port Uses display's own dp_aux vector for DPCD communication Fixes link recovery after mode changes syncobj.rs: sync_file fd infrastructure export_sync_file(): generate fd token, map syncobj → fd import_sync_file(): resolve fd token → syncobj handle close_sync_file(): remove fd from table driver.rs: GpuDriver trait methods for sync_file syncobj_export_fd() / syncobj_import_fd() with default Unsupported mod.rs: IntelDriver implementation delegates to SyncobjManager scheme.rs: DRM_IOCTL_REDOX_SYNCOBJ_HANDLE_TO_FD (0x73) DRM_IOCTL_REDOX_SYNCOBJ_FD_TO_HANDLE (0x74) Wire types with proper #[repr(C)] Copy+Clone attributes
This commit is contained in:
@@ -186,6 +186,14 @@ pub trait GpuDriver: Send + Sync {
|
||||
Err(DriverError::Unsupported("syncobj not supported by this backend"))
|
||||
}
|
||||
|
||||
fn syncobj_export_fd(&self, _handle: SyncobjHandle) -> Result<i32> {
|
||||
Err(DriverError::Unsupported("syncobj fd export not supported"))
|
||||
}
|
||||
|
||||
fn syncobj_import_fd(&self, _fd: i32) -> Result<SyncobjHandle> {
|
||||
Err(DriverError::Unsupported("syncobj fd import not supported"))
|
||||
}
|
||||
|
||||
fn redox_private_cs_submit(
|
||||
&self,
|
||||
_submit: &RedoxPrivateCsSubmit,
|
||||
|
||||
@@ -226,6 +226,14 @@ impl IntelDisplay {
|
||||
|
||||
pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo) -> Result<()> {
|
||||
let index = usize::from(pipe.index);
|
||||
|
||||
if let Some(port) = pipe.port {
|
||||
if (port as usize) < self.dp_aux.len() {
|
||||
debug!("redox-drm-intel: retraining DP link port {} for {}x{}@{}",
|
||||
port, mode.hdisplay, mode.vdisplay, mode.vrefresh);
|
||||
let _ = super::dp_link::train_dp_link(&self.mmio, &self.dp_aux[port as usize], port);
|
||||
}
|
||||
}
|
||||
self.write32(
|
||||
self.regs.htotal(index as u8),
|
||||
pack_pair(mode.htotal, mode.hdisplay),
|
||||
|
||||
@@ -1193,6 +1193,18 @@ impl GpuDriver for IntelDriver {
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn syncobj_export_fd(&self, handle: SyncobjHandle) -> Result<i32> {
|
||||
let mut mgr = self.syncobj_mgr.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel syncobj state poisoned".into()))?;
|
||||
mgr.export_sync_file(handle)
|
||||
}
|
||||
|
||||
fn syncobj_import_fd(&self, fd: i32) -> Result<SyncobjHandle> {
|
||||
let mgr = self.syncobj_mgr.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel syncobj state poisoned".into()))?;
|
||||
mgr.import_sync_file(fd)
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_display_topology(display: &IntelDisplay) -> Result<(Vec<Connector>, Vec<Encoder>)> {
|
||||
|
||||
@@ -163,4 +163,26 @@ impl SyncobjManager {
|
||||
pub fn is_handle_valid(&self, handle: SyncobjHandle) -> bool {
|
||||
self.objects.contains_key(&handle)
|
||||
}
|
||||
|
||||
pub fn export_sync_file(&mut self, handle: SyncobjHandle) -> Result<i32> {
|
||||
if !self.objects.contains_key(&handle) {
|
||||
return Err(DriverError::NotFound(format!("syncobj handle {} not found", handle)));
|
||||
}
|
||||
let fd = self.next_fd;
|
||||
self.next_fd = self.next_fd.wrapping_add(1);
|
||||
self.fd_table.insert(fd, handle);
|
||||
debug!("redox-drm-intel: sync_file fd {} exported for syncobj {}", fd, handle);
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
pub fn import_sync_file(&self, fd: i32) -> Result<SyncobjHandle> {
|
||||
self.fd_table.get(&fd).copied().ok_or_else(|| {
|
||||
DriverError::NotFound(format!("sync_file fd {} not found", fd))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn close_sync_file(&mut self, fd: i32) {
|
||||
self.fd_table.remove(&fd);
|
||||
debug!("redox-drm-intel: sync_file fd {} closed", fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ const DRM_IOCTL_MODE_ATOMIC: usize = DRM_IOCTL_BASE + 0x3C;
|
||||
const DRM_IOCTL_REDOX_SYNCOBJ_CREATE: usize = DRM_IOCTL_BASE + 0x70;
|
||||
const DRM_IOCTL_REDOX_SYNCOBJ_DESTROY: usize = DRM_IOCTL_BASE + 0x71;
|
||||
const DRM_IOCTL_REDOX_SYNCOBJ_WAIT: usize = DRM_IOCTL_BASE + 0x72;
|
||||
const DRM_IOCTL_REDOX_SYNCOBJ_HANDLE_TO_FD: usize = DRM_IOCTL_BASE + 0x73;
|
||||
const DRM_IOCTL_REDOX_SYNCOBJ_FD_TO_HANDLE: usize = DRM_IOCTL_BASE + 0x74;
|
||||
const DRM_MODE_ATOMIC_TEST_ONLY: u32 = 0x0100;
|
||||
const DRM_MODE_ATOMIC_NONBLOCK: u32 = 0x0200;
|
||||
const DRM_MODE_PAGE_FLIP_EVENT: u32 = 0x01;
|
||||
@@ -598,8 +600,27 @@ struct RedoxSyncobjWaitWire {
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
struct RedoxSyncobjWaitResultWire {
|
||||
completed: u32,
|
||||
_pad: [u8; 4],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
struct RedoxSyncobjHandleToFdWire {
|
||||
handle: u32,
|
||||
flags: u32,
|
||||
fd: i32,
|
||||
_pad: [u8; 4],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
struct RedoxSyncobjFdToHandleWire {
|
||||
fd: i32,
|
||||
handle: u32,
|
||||
_pad: [u8; 4],
|
||||
}
|
||||
|
||||
|
||||
// ---- Internal handle types ----
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -1471,6 +1492,8 @@ impl DrmScheme {
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_CREATE => "SYNCOBJ_CREATE",
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_DESTROY => "SYNCOBJ_DESTROY",
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_WAIT => "SYNCOBJ_WAIT",
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_HANDLE_TO_FD => "SYNCOBJ_HANDLE_TO_FD",
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_FD_TO_HANDLE => "SYNCOBJ_FD_TO_HANDLE",
|
||||
_ => "UNKNOWN",
|
||||
};
|
||||
log::info!(
|
||||
@@ -1656,10 +1679,29 @@ impl DrmScheme {
|
||||
.map_err(driver_to_syscall)?;
|
||||
let resp = RedoxSyncobjWaitResultWire {
|
||||
completed: if completed { 1 } else { 0 },
|
||||
_pad: [0u8; 4],
|
||||
};
|
||||
bytes_of(&resp)
|
||||
}
|
||||
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_HANDLE_TO_FD => {
|
||||
let req = decode_wire::<RedoxSyncobjHandleToFdWire>(payload)?;
|
||||
let fd = self.driver.syncobj_export_fd(req.handle)
|
||||
.map_err(driver_to_syscall)?;
|
||||
let mut resp = req;
|
||||
resp.fd = fd;
|
||||
bytes_of(&resp)
|
||||
}
|
||||
|
||||
DRM_IOCTL_REDOX_SYNCOBJ_FD_TO_HANDLE => {
|
||||
let req = decode_wire::<RedoxSyncobjFdToHandleWire>(payload)?;
|
||||
let handle = self.driver.syncobj_import_fd(req.fd)
|
||||
.map_err(driver_to_syscall)?;
|
||||
let mut resp = req;
|
||||
resp.handle = handle;
|
||||
bytes_of(&resp)
|
||||
}
|
||||
|
||||
DRM_IOCTL_MODE_CREATE_DUMB => {
|
||||
let mut req = decode_wire::<DrmCreateDumbWire>(payload)?;
|
||||
info!(
|
||||
|
||||
Reference in New Issue
Block a user