From 0eb96178dbf9fc2acc5dda6a050cd0fd40e51e9a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 15 Dec 2025 23:37:16 +0100 Subject: [PATCH] Port remaining drm ioctls to the new infrastructure --- drivers/graphics/driver-graphics/src/lib.rs | 131 ++++++++++++++++++++ drivers/graphics/graphics-ipc/src/v2.rs | 112 ++++++++++++++++- 2 files changed, 241 insertions(+), 2 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index db6f2669ef..39a11e461b 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -432,6 +432,36 @@ impl SchemeSync for GraphicsScheme { ) -> Result { use graphics_ipc::v2::ipc; + const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888 + + fn id_index(id: u32) -> u32 { + id & 0xFF + } + + fn conn_id(i: u32) -> u32 { + id_index(i) | (1 << 8) + } + + fn crtc_id(i: u32) -> u32 { + id_index(i) | (1 << 9) + } + + fn enc_id(i: u32) -> u32 { + id_index(i) | (1 << 10) + } + + fn fb_id(i: u32) -> u32 { + id_index(i) | (1 << 11) + } + + fn fb_handle_id(i: u32) -> u32 { + id_index(i) | (1 << 12) + } + + fn plane_id(i: u32) -> u32 { + id_index(i) | (1 << 13) + } + match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::V1Screen { .. } => { return Err(Error::new(EOPNOTSUPP)); @@ -467,6 +497,107 @@ impl SchemeSync for GraphicsScheme { )?; Ok(0) }), + ipc::MODE_CARD_RES => ipc::DrmModeCardRes::with(payload, |mut data| { + let count = self.adapter.display_count(); + let mut conn_ids = Vec::with_capacity(count); + let mut crtc_ids = Vec::with_capacity(count); + let mut enc_ids = Vec::with_capacity(count); + let mut fb_ids = Vec::with_capacity(count); + for i in 0..(count as u32) { + conn_ids.push(conn_id(i)); + crtc_ids.push(crtc_id(i)); + enc_ids.push(enc_id(i)); + fb_ids.push(fb_id(i)); + } + data.set_fb_id_ptr(&fb_ids); + data.set_crtc_id_ptr(&crtc_ids); + data.set_connector_id_ptr(&conn_ids); + data.set_encoder_id_ptr(&enc_ids); + data.set_min_width(0); + data.set_max_width(16384); + data.set_min_height(0); + data.set_max_height(16384); + Ok(0) + }), + ipc::MODE_GET_CRTC => ipc::DrmModeCrtc::with(payload, |mut data| { + let i = id_index(data.crtc_id()); + let (width, height) = self.adapter.display_size(i as usize); + //TOOD: connectors + data.set_fb_id(fb_id(i)); + data.set_x(0); + data.set_y(0); + data.set_gamma_size(0); + data.set_mode_valid(0); + //TODO: mode + data.set_mode(Default::default()); + Ok(0) + }), + ipc::MODE_GET_ENCODER => ipc::DrmModeGetEncoder::with(payload, |mut data| { + let i = id_index(data.encoder_id()); + let (width, height) = self.adapter.display_size(i as usize); + data.set_crtc_id(crtc_id(i)); + data.set_possible_crtcs(1 << i); + data.set_possible_clones(1 << i); + Ok(0) + }), + ipc::MODE_GET_CONNECTOR => ipc::DrmModeGetConnector::with(payload, |mut data| { + let i = id_index(data.connector_id()); + let (width, height) = self.adapter.display_size(i as usize); + data.set_modes_ptr(&[]); + data.set_props_ptr(&[]); + data.set_prop_values_ptr(&[]); + data.set_encoders_ptr(&[enc_id(i)]); + Ok(0) + }), + ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| { + let i = id_index(data.fb_id()); + let (width, height) = self.adapter.display_size(i as usize); + data.set_width(width); + data.set_height(height); + data.set_pitch(width * 4); //TODO: stride + data.set_bpp(32); + data.set_depth(24); + data.set_handle(fb_handle_id(i)); + Ok(0) + }), + ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| { + let count = self.adapter.display_count(); + let mut ids = Vec::with_capacity(count); + for i in 0..(count as u32) { + ids.push(plane_id(i)); + } + data.set_plane_id_ptr(&ids); + Ok(0) + }), + ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { + let i = id_index(data.plane_id()); + let (width, height) = self.adapter.display_size(i as usize); + data.set_crtc_id(crtc_id(i)); + data.set_fb_id(fb_id(i)); + data.set_possible_crtcs(1 << i); + data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]); + Ok(0) + }), + ipc::MODE_OBJ_GET_PROPERTIES => { + ipc::DrmModeObjGetProperties::with(payload, |mut data| { + // TODO + data.set_props_ptr(&[]); + data.set_prop_values_ptr(&[]); + Ok(0) + }) + } + ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { + let i = id_index(data.fb_id()); + let (width, height) = self.adapter.display_size(i as usize); + data.set_width(width); + data.set_height(height); + data.set_pixel_format(DRM_FORMAT_ARGB8888); + data.set_handles([fb_handle_id(i), 0, 0, 0]); + data.set_pitches([width * 4, 0, 0, 0]); + data.set_offsets([0; 4]); + data.set_modifier([0; 4]); + Ok(0) + }), ipc::DISPLAY_COUNT => { if payload.len() < size_of::() { return Err(Error::new(EINVAL)); diff --git a/drivers/graphics/graphics-ipc/src/v2.rs b/drivers/graphics/graphics-ipc/src/v2.rs index 1b671458d3..d95cd49924 100644 --- a/drivers/graphics/graphics-ipc/src/v2.rs +++ b/drivers/graphics/graphics-ipc/src/v2.rs @@ -188,7 +188,7 @@ pub mod ipc { ); }; (struct $ioctl_ty:ident, $mem_ty:ident { - $field:ident: $ty:ty [array<$el:ident, $counted_by:ident>], + $field:ident: $ty:ty [array<$el:ty, $counted_by:ident>], $($rest:tt)* } => ($($ioctl_fields:tt)*), @@ -204,7 +204,7 @@ pub mod ipc { }; (struct $ioctl_ty:ident, $mem_ty:ident {} => ($($ioctl_field:ident: $ioctl_field_ty:ty,)*), - ($($counted_field:ident: $counted_ty:ty [array<$el:ident, $counted_by:ident>],)*), + ($($counted_field:ident: $counted_ty:ty [array<$el:ty, $counted_by:ident>],)*), ($($noncounted_field:ident: $noncounted_ty:ty,)*) ) => { pub use drm_sys::$ioctl_ty; @@ -380,6 +380,114 @@ pub mod ipc { } } + pub const MODE_GET_CRTC: u64 = 0xA1; + define_ioctl_data! { + struct drm_mode_crtc, DrmModeCrtc { + set_connectors_ptr: u64, + count_connectors: u32, + crtc_id: u32, + fb_id: u32, + x: u32, + y: u32, + gamma_size: u32, + mode_valid: u32, + mode: drm_sys::drm_mode_modeinfo, + } + } + + pub const MODE_GET_ENCODER: u64 = 0xA6; + define_ioctl_data! { + struct drm_mode_get_encoder, DrmModeGetEncoder { + encoder_id: u32, + encoder_type: u32, + crtc_id: u32, + possible_crtcs: u32, + possible_clones: u32, + } + } + + pub const MODE_GET_CONNECTOR: u64 = 0xA7; + define_ioctl_data! { + struct drm_mode_get_connector, DrmModeGetConnector { + encoders_ptr: u64 [array], + modes_ptr: u64 [array], + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_modes: u32, + count_props: u32, + count_encoders: u32, + encoder_id: u32, + connector_id: u32, + connector_type: u32, + connector_type_id: u32, + connection: u32, + mm_width: u32, + mm_height: u32, + subpixel: u32, + pad: u32, + } + } + + pub const MODE_GET_FB: u64 = 0xAD; + define_ioctl_data! { + struct drm_mode_fb_cmd, DrmModeFbCmd { + fb_id: u32, + width: u32, + height: u32, + pitch: u32, + bpp: u32, + depth: u32, + handle: u32, + } + } + + pub const MODE_GET_PLANE_RES: u64 = 0xB5; + define_ioctl_data! { + struct drm_mode_get_plane_res, DrmModeGetPlaneRes { + plane_id_ptr: u64 [array], + count_planes: u32, + } + } + + pub const MODE_GET_PLANE: u64 = 0xB6; + define_ioctl_data! { + struct drm_mode_get_plane, DrmModeGetPlane { + plane_id: u32, + crtc_id: u32, + fb_id: u32, + possible_crtcs: u32, + gamma_size: u32, + count_format_types: u32, + format_type_ptr: u64 [array], + } + } + + pub const MODE_OBJ_GET_PROPERTIES: u64 = 0xB9; + define_ioctl_data! { + struct drm_mode_obj_get_properties, DrmModeObjGetProperties { + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_props: u32, + obj_id: u32, + obj_type: u32, + } + } + + pub const MODE_GET_FB2: u64 = 0xCE; + define_ioctl_data! { + struct drm_mode_fb_cmd2, DrmModeFbCmd2 { + fb_id: u32, + width: u32, + height: u32, + pixel_format: u32, + flags: u32, + handles: [u32; 4], + pitches: [u32; 4], + offsets: [u32; 4], + modifier: [u64; 4], + } + } + // FIXME replace these with proper drm interfaces pub const DISPLAY_COUNT: u64 = 1; #[repr(C, packed)]