Commits on Source (79)
-
Many drivers abuse the platform driver/bus system as it provides a simple way to create and bind a device to a driver-specific set of probe/release functions. Instead of doing that, and wasting all of the memory associated with a platform device, here is a "faux" bus that can be used instead. Reviewed-by:
Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by:
Danilo Krummrich <dakr@kernel.org> Reviewed-by:
Lyude Paul <lyude@redhat.com> Reviewed-by:
Thomas Weißschuh <thomas.weissschuh@linutronix.de> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Lyude Paul authored
This introduces a module for working with faux devices in rust, along with adding sample code to show how the API is used. Unlike other types of devices, we don't provide any hooks for device probe/removal - since these are optional for the faux API and are unnecessary in rust. Signed-off-by:
Lyude Paul <lyude@redhat.com> Cc: Maíra Canal <mairacanal@riseup.net> Cc: Danilo Krummrich <dakr@kernel.org> Cc: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Lyude Paul authored
There's not that many bindings in here right now, but we're about to add quite a lot more - which means it's probably worth it to further split out the current helpers we have in helpers/drm.c into their own folder. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
This is just for basic usage in the DRM shmem abstractions for implied locking, not intended as a full DMA Reservation abstraction yet. Signed-off-by:
Asahi Lina <lina@asahilina.net>
-
There doesn't seem to be a way for the Rust bindings to get a compile-time constant reference to drm_gem_shmem_vm_ops, so we need to duplicate that structure in Rust... this isn't nice... Signed-off-by:
Asahi Lina <lina@asahilina.net>
-
The DRM shmem helper includes common code useful for drivers which allocate GEM objects as anonymous shmem. Add a Rust abstraction for this. Drivers can choose the raw GEM implementation or the shmem layer, depending on their needs. Lyude changelog: * Rebase * Squash "rust: drm: device: Convert Device to AlwaysRefCounted" as this commit doesn't compile without it anyway Signed-off-by:
Asahi Lina <lina@asahilina.net>
-
This is just for basic usage in the DRM shmem abstractions for implied locking, not intended as a full DMA Reservation abstraction yet. Signed-off-by:
Asahi Lina <lina@asahilina.net>
-
Lyude Paul authored
This adds some very basic rust bindings for fourcc. We only have a single format code added for the moment, but this is enough to get a driver registered. TODO: * Write up something to automatically generate constants from the fourcc headers Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Drop FormatList and ModifierList These aren't actually needed as pointed out by Louis Chauvet * Add a constant for FORMAT_MOD_INVALID I realized that we actually need this because the format list isn't terminated with a 0 like I thought, and we can't pick this up automatically through bindgen
-
Lyude Paul authored
This commit adds some traits for registering DRM devices with KMS support, implemented through the kernel::drm::kms::Kms trait. Devices which don't have KMS support can simply use PhantomData<Self>. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Generate feature flags automatically, these shouldn't need to be specified by the user * Fix typo on KmsImpl documentation V3: * Get rid of Kms, long live KmsDriver After Daniel pointed out that we should just make KmsDriver a supertrait of Driver, it immediately occurred to me that there's no actual need for Kms to be a separate trait at all. So, drop Kms entirely and move its requirements over to KmsDriver. * Drop fbdev module entirely and move setup_fbdev() into AllocImpl (Daniel)
-
Lyude Paul authored
The KMS API has a very consistent idea of a "mode config object", which includes any object with a drm_mode_object struct embedded in it. These objects have their own object IDs which DRM exposes to userspace, and we introduce the ModeConfigObject trait to represent any object matching these characteristics. One slightly less consistent trait of these objects however: some mode objects have a reference count, while others don't. Since rust requires that we are able to define the lifetime of an object up-front, we introduce two other super-traits of ModeConfigObject for this: * StaticModeObject - this trait represents any mode object which does not have a reference count of its own. Such objects can be considered to share the lifetime of their parent KMS device * RcModeObject - this trait represents any mode object which does have its own reference count. Objects implementing this trait get a free blanket implementation of AlwaysRefCounted, and as such can be used with the ARef container without us having to implement AlwaysRefCounted for each individual mode object. This will be able to handle most lifetimes we'll need with one exception: it's entirely possible a driver may want to hold a "owned" reference to a static mode object. We allow for this by introducing the KmsRef container, which grabs an owned refcount to the parent KMS device of a StaticModeObject and holds a pointer to said object - essentially allowing it to act identically to an owned refcount by preventing the device's lifetime from ending until the KmsRef is dropped. I choose not to use AlwaysRefCounted for this as holding a refcount to the device has its own set of implications since if you forget to drop the KmsRef the device will never be destroyed. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Document why modesetting objects require Send + Sync * Make `ModeObject` an unsafe trait I was prompted to make this change in response to one of Daniel's comments, as it occurred to me that we need something that ensures that implementers are only returning valid `drm_mode_object` pointers so we have something to put down for the various related safety comments in RcModeObject. Also, update the safety comments there.
-
Lyude Paul authored
We start off by introducing wrappers for the first important type of mode object: a DRM display connector. This introduces Connector<T: DriverConnector> and ConnectorState<T: DriverConnectorState>. Both DriverConnector and DriverConnectorState must be implemented by KMS drivers, and a driver may have as many implementations of these two traits as it needs. This also introduces the general data pattern we'll be using for all of the core mode objects that can be used in atomic commits. It's important to note that both Connector<T> and ConnectorState<T> are intended to be "subclassable". To explain what this means, we need to look at how a DRM driver normally uses objects like DRM connectors. Typically, a driver in C will define its connectors like so: struct foo_connector { struct drm_connector base; int bar; } Note that we have a drm_connector struct embedded in foo_connector, but we have data which comes after it which is defined by the driver. This is important for a number of reasons: connectors can have their own mutexes and various other hardware-specific information that a driver may want access to at any time. The same goes for drm_connector_state, where drivers will subclass this struct in the same way. It's worth noting as well that it isn't uncommon for a driver to have multiple types of connectors, but we'll handle in a later commit. As a result, we've designed Connector<T> and ConnectorState<T> so that for both types: a DRM driver can add custom data into the T. As well, there's some basic limitations on how this data may be accessed: * Data within the `DriverConnector` struct is pinned in order to allow mutexes and other structs which need pinning to be stored within it. As well, it is impossible to get a direct mutable reference to the data within DriverConnector - as there's no locks for doing so which would cause a race condition. * Data within the `DriverConnectorState` struct is currently not pinned. While it's not unheard of for a driver to put something like a mutex in its atomic states, (VKMS actually does this in some spots) this quickly complicates things especially with nonblocking modesets - and doesn't really fit into the philosophy of an atomic state anyway. We may add support for this in the future later if this does end up being needed, but for now we hold back in order to make it much easier for drivers to access private data within the atomic state. As well, the functions we provide for converting to/from raw connector state pointers are notably different from many other rust types in the kernel. Instead of converting raw state pointers to raw ConnectorState<T> pointers, we allow for direct immutable and mutable references. The reason for this is that it makes accessing private driver data in the state much easier, and unlike Connector<T> - we can actually uphold all of the required data aliasing rules thanks to states only being mutable by a single thread before they've been swapped in. Note that currently, we don't provide a way to access said private data for ConnectorState<T> since allowing direct access to a &mut ConnectorState<T> could allow a caller to modify portions of drm_connector_state which are meant to be invariant throughout the lifetime of the connector state. We'll address this in the next few commits when we introduce the global atomic state type. And finally - we introduce the following internal traits for the crate side of things: * AsRawConnector - any type which can spit out a *mut bindings::drm_connector or be recovered from one * AsRawConnectorState - any type which can return a reference to a bindings::drm_connector_state * private::AsRawConnectorState - just methods for AsRawConnectorState that we don't want to be accessible to our users (since they could be used to introduce UB) * FromRawConnectorState - any type which can be recovered from a raw pointer to a bindings::drm_connector_state The reason for having AsRawConnectorState and FromRawConnectorState as separate traits unlike AsRawConnector is due to the fact that we'll introduce objects later on which can be used as DRM connector states, but cannot be directly derived from a *mut bindings::drm_connector_state because they hold additional state or have additional side-effects. Likewise, we'll also have other objects which can be used as raw DRM connectors - hence AsRawConnector. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Add safety comment to implementation of ModeObject * Make AsRawConnector an unsafe trait, we need a guarantee that as_raw() always returns a valid pointer. * Improve safety comments in atomic_duplicate_state_callback * Improve safety comments in Connector::new() * Switch to requiring a UnregisteredKmsDevice instead of a Device This is in preparation for the static/dynamic connector split, which we may as well prepare for since we don't have any use for dynamic connectors yet. * Drop redundant Connector associated type in AsRawConnector trait * Improve safety comments in FromRawConnectorState * Introduce UnregisteredConnector type * Don't have AsRawConnector be a supertrait of StaticModeObject. We don't want Unregistered mode object variants to be able to return a pointer to the DRM device since that would break the UnregisteredKmsDevice pattern.
-
Lyude Paul authored
The next step is adding a set of basic bindings to create a plane, which has to happen before we can create a CRTC (since we need to be able to at least specify a primary plane for a CRTC upon creation). This mostly follows the same general pattern as connectors (AsRawPlane, AsRawPlaneState, etc.). There is one major difference with planes vs. other types of atomic mode objects: drm_plane_state isn't the only base plane struct used in DRM drivers, as some drivers will use helpers like drm_shadow_plane_state which have a drm_plane_state embedded within them. Since we'll eventually be adding bindings for shadow planes, we introduce a PlaneStateHelper trait - which represents any data type which can be used as the main wrapping structure around a drm_plane_state - and we implement this trait for PlaneState<T>. This trait can be used in our C callbacks to allow for drivers to use different wrapping structures without needing to implement a separate set of FFI callbacks for each type. Currently planes are the only type I'm aware of which do this. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V2: * Start using Gerry Guo's updated #[vtable] function so that our driver operations table has a static location in memory V3: * Add safety comment for implementation of ModeObject * Make AsRawPlane unsafe, since we need a guarantee that `as_raw()` always returns a valid pointer to an initialized drm_plane. * Add comments to __drm_atomic_helper_duplicate_state() * Switch `PlaneType` to camel casing * Improve safety comment in `Plane::<T>::new()` * Fix parameter types for `formats` and `format_modifiers`, as pointed out by Louis Chauvet DRM will copy all of these into its own storage. * Improve safety comments in FromRawPlaneState * Introduce UnregisteredPlane type * Don't have AsRawPlane be a supertrait of StaticModeObject. We don't want Unregistered mode object variants to be able to return a pointer to the DRM device since that would break the UnregisteredKmsDevice pattern.
-
Lyude Paul authored
This introduces basic bindings for DRM CRTCs which follow the same general pattern as connectors and planes (e.g. AsRawCrtc, AsRawCrtcState, etc.). There is one big difference though - drm_crtc_state appears to be the one atomic state that actually has data which can be mutated from outside of the atomic commit phase - which means we can't keep rust referencs to it, and instead need to use the Opaque type and implement things through pointers instead. This should be the last mode object we're introducing for the time being with its own atomic state. Note that we've not added bindings for private modesetting objects yet, but I don't think those will be needed for rvkms - and the same general patterns we're using here should work for adding private modesetting objects. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Add commit data in the future V3: * Add safety comments for ModeObject implementation * Make AsRawCrtc unsafe, as we need a guarantee that `as_raw()` will always return a pointer to a valid `drm_crtc`. * Update safety comments in atomic_duplicate_state_callback * Rename generics in Crtc::new to PrimaryData and CursorData * Add missing safety comment in Crtc::new() * Improve safety comments in AsRawCrtc * Break up the conversion from Pin<Box<Crtc>> to &Crtc a bit * Document why there's an UnsafeCell in CrtcState, because even I forgot the reason for this :). * Introduce UnregisteredCrtc type * Don't have AsRawCrtc be a supertrait of StaticModeObject. We don't want Unregistered mode object variants to be able to return a pointer to the DRM device since that would break the UnregisteredKmsDevice pattern.
-
Lyude Paul authored
The last thing we need to be able to register a KMS driver is the ability to create DRM encoders, so let's add bindings for that. Again, these bindings follow the same general pattern as CRTCs, planes, and connector with one difference: encoders don't have an atomic state. Note that not having an atomic state doesn't mean there aren't plenty of valid usecases for a driver to stick private data within a DRM encoder, hence why we reuse the aforementioned pattern. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Add safety comments for ModeObject implementation * Make AsRawEncoder unsafe so that we have a guarantee that `as_raw()` always returns a valid pointer. * Introduce UnregisteredEncoder type * Don't have AsRawEncoder be a supertrait of StaticModeObject. We don't want Unregistered mode object variants to be able to return a pointer to the DRM device since that would break the UnregisteredKmsDevice pattern.
-
Lyude Paul authored
This adds a simple binding for completing the last step of creating a DRM connector - attaching its encoder. This function should only be called before the connector is registered, and DRM should enforce this itself by returning an error if a driver tries to add an encoder to an already-registered DRM connector. Note that unlike most of the methods we'll be adding to DRM mode objects, this is directly implemented on the Connector<T> type since I don't really think it would make sense for us to allow this operation on an OpaqueConnector (a DRM connector without a known DriverConnector implementation, something we'll be adding in the next few commits). Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Move to UnregisteredConnector interface
-
Lyude Paul authored
Next up is filling out some of the basic connector hotplugging callbacks - which we'll need for setting up the fbdev helpers for KMS devices. Note that connector hotplugging in DRM follows a BFL scheme: pretty much all probing is protected under the mighty drm_device->mode_config.lock, which of course is a bit counter-intuitive to rust's locking schemes where data is always associated with its lock. Since that lock is embedded in an FFI type and not a rust type, we need to introduce our own wrapper type that acts as a lock acquisition for this. This brings us to introducing a few new types: * ModeConfigGuard - the most basic lock guard, as long as this object is alive we are guaranteed to be holding drm_device->mode_config.lock. This object doesn't do much else on its own currently. * ConnectorGuard - an object which corresponds to a specific typed DRM connector. This can only be acquired with a ModeConfigGuard, and will be used to allow calling methods that are only safe to call with drm_device->mode_config.lock held. Since it implements Deref<Target=Connector<T>> as well, it can also be used for any other operations that would normally be available on a DRM connector. And finally, we add the DriverConnector::get_modes() trait method which drivers can use to implement the drm_connector_helper_funcs.get_modes callback. Note that while we make this trait method mandatory, we only do so for the time being since VKMS doesn't do very much with DRM connectors - and as such we have no need yet to implement alternative connector probing schemes outside of get_modes(). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
A simple binding for drm_add_modes_noedid() using the ConnectorGuard type we just added. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Add a wrapper for `drm_set_preferred_mode()` for our new `ConnectorGuard` type so we can set the preferred mode for RVKMS connectors. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Now that we have more then one way to refer to connectors, we also want to ensure that any methods which are common to any kind of connector type can be used on all connector representations. This is where RawConnector and RawConnectorState come in: we implement these traits for any type which implements AsRawConnector or AsRawConnectorState respectively. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Same thing as RawConnector and RawConnectorState, just for CRTCs now. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Same thing as RawCrtc and RawCrtcState, but for DRM planes now Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Limit unsafe scope in RawPlane::index() * Improve safety comments
-
Lyude Paul authored
Since we allow drivers to have multiple implementations of DriverConnector and DriverConnectorState (in C, the equivalent of this is having multiple structs which embed drm_connector) - there are some situations we will run into where it's not possible for us to know the corresponding DriverConnector or DriverConnectorState for a given connector. The most obvious one is iterating through all connectors on a KMS device. So, take advantage of the various connector traits we added to introduce OpaqueConnector<> and OpaqueConnectorState<> which both can be used as a DRM connector and connector state respectively without needing to know the corresponding traits. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Add upcast functions for these types V3: * Add safety comment to implementation of ModeObject * Add safety comments to AsRawConnector implementation * Implement try_from_opaque() and from_opaque() using a macro * Ensure all Opaque types have the ability to "upcast" LYUDE NOTE: * We need to move the AsRaw* work before this now that we're actually using macros for generating all of the upcast functions, since we now rely on crtc(), plane(), etc. for the state functions to get their respective mode objects so we can check their vtables. * Start using a macro for implementing the conversions here, and introduce the ModesetObjectVtable function for using the macro
-
Lyude Paul authored
This is the same thing as OpaqueConnector and OpaqueConnectorState, but for CRTCs now. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Add upcast functions V3: * Add safety comment for implementation of ModeObject * Add safety comments to AsRawCrtc implementation * Implement try_from_opaque() and from_opaque() using a macro
-
Lyude Paul authored
Same thing as OpaqueCrtc and OpaqueCrtcState, but for plane states now. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Finish adding upcast functions. V3: * Add safety comment to implementation of ModeObject * Add safety comments to implementation of AsRawPlane * Implement try_from_opaque() and from_opaque() using a macro * Add missing upcasts
-
Lyude Paul authored
Same thing as OpaquePlane, but for encoders now. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Add upcast functions for this V3: * Add safety comment to ModeObject implementation * Add safety comments for AsRawEncoder * Implement try_from_opaque() and from_opaque() using a macro
-
Lyude Paul authored
Next up is introducing bindings that we can use to represent the global DRM atomic state, along with all of the various object states contained within. We do this by introducing a few new concepts: borrowed states, atomic state mutators, and atomic state composers. To understand these, we need to quickly touch upon the general life of an atomic commit. Assuming a driver does its own internal atomic commit, the procedure looks something like this: * Allocate a new atomic state * Duplicate the atomic state of each mode object we want to mutate, and add the duplicated state to the new atomic state * Check (possibly more then once) the atomic state, possibly modifying it along the way * Commit the atomic state to software (we'll call this commit time). At this point no new objects can be added to the state * Finish committing the atomic state to hardware asynchronously With this in mind, we introduce AtomicStateMutator and AtomicStateComposer (along with leaky variants intended for uses in FFI calls). An AtomicStateMutator allows mutating an atomic state but does not allow for adding new objects to the state. Subsequently, an AtomicStateComposer allows for both mutating an atomic state and adding new mode objects. We control when we expose each of these types in order to implement the limitations required by the aforementioned example. Note as well that AtomicStateComposer is intended to eventually be usable directly by drivers. In this scenario, a driver will be able to create an AtomicStateComposer (the equivalent of allocating an atomic state in C) and then commit it by passing it to our DRM bindings by-value, insuring that once the commit process begins it is impossible to keep using the AtomicStateComposer. The next part of this is allowing users to modify the atomic states of all of the objects contained within an atomic state. Since it's an extremely common usecase for objects to mutate the atomic state of multiple objects at once in an unpredictable order, we need a mechanism that will allow us to hand out &mut references to each state while ensuring at runtime that we do not break rust's data aliasing rules (which disallow us from ever having more then one &mut reference to the same piece of data). We do this by introducing the concept of a "borrowed" state. This is a very similar concept to RefCell, where it is ensured during runtime that when a &mut reference is taken out another one cannot be created until the corresponding Ref object has been dropped. Our equivalent Ref types are BorrowedConnectorState, BorrowedCrtcState, and BorrowedPlaneState. Each one of these types can be used in the same manner as a Ref - no additional borrows for an atomic state may be taken until the existing one has been dropped. Subsequently, all of these types implement their respective AsRaw* and FromRaw* counter-parts - and allow dereferencing to each driver-private data structure for fully qualified borrows (like BorrowedCrtcState<'a, CrtcState<T>>. This allows a pretty clean way of mutating multiple states at once without ever breaking rust's mutability rules. We'll use all of these types over the next few commits to begin introducing various atomic modeset callbacks to each mode object type. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Drop the TODO about printing a kernel error in BorrowedConnectorState I thought this was something we'd want early on in designing this, but since then I'm pretty sure we just want to return None - there are valid cases where we'd get None while doing connector iteration through an atomic state * Improve safety comments in BorrowedConnectorState::new() * Rename Borrowed*State to *StateMutator I think this makes things a lot clearer, as well - cleanup the documentation regarding this. * Drop plane state iterator for now. It's not that we don't need this, it's just that I haven't actually finished writing these up for all types so I'd rather focus on that later now that we've demonstrated it's a thing that is possible. And it at least shouldn't be needed for getting these bindings/rvkms upstream.
-
Lyude Paul authored
We should submit these seperately since I'm trying to get rid of all of the WIPs here.
-
Lyude Paul authored
* Drop num_plane() for the time being Without the plane state iterator in this patch series there's no current usecase for this, so just drop the function for the time being and we'll reintroduce it when it's ready.
-
Lyude Paul authored
-
Lyude Paul authored
An optional trait method for implementing a CRTC's atomic state check. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Document uses of ManuallyDrop
-
Lyude Paul authored
A mandatory trait method used for implementing DRM's atomic plane update callback. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Optional trait method for implementing a plane's atomic_check(). Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Document ManuallyDrop uses better
-
Lyude Paul authored
A binding for checking drm_crtc_state.active. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Add a binding for checking drm_plane_state.crtc. Note that we don't have a way of knowing what DriverCrtc implementation would be used here (and want to make this function also available on OpaquePlaneState types), so we return an OpaqueCrtc. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Add a binding for drm_atomic_helper_check_plane_state(). Since we want to make sure that the user is passing in the new state for a Crtc instead of an old state, we explicitly ask for a reference to a BorrowedCrtcState. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Add support for scaling options
-
Lyude Paul authored
This adds some very simple bindings for drm_framebuffer. We don't use them much yet, but we'll eventually be using them when rvkms eventually gets CRC and writeback support. Just like Connector objects, these use RcModeObject. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Replace Framebuffer struct with tuple * Add safety comments for ModeObject implementation * Add comment for why we're using Sealed
-
Lyude Paul authored
Returns the Framebuffer currently assigned in an atomic plane state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Optional trait methods for implementing the atomic_begin and atomic_flush callbacks for a CRTC. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Optional trait methods for implementing the atomic_enable and atomic_disable callbacks of a CRTC. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This is just a crate-private helper to use Lock::from_raw() to provide an immutable reference to the DRM event_lock, so that it can be used like a normal rust spinlock. We'll need this for adding vblank related bindings. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
A binding for checking drm_device.num_crtcs. We'll need this in a moment for vblank support, since setting it up requires knowing the number of CRTCs that a driver has initialized. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This commit adds bindings for implementing vblank support for a driver's CRTCs. These bindings are optional, to account for the fact that not all drivers have dedicated hardware vblanks. In order to accomplish this, we introduce the VblankSupport trait which can be implemented on DriverCrtc by drivers which support vblanks. This works in the same way as the main Kms trait - drivers which don't support hardware vblanks can simply pass PhantomData<Self> to the associated type on DriverCrtc. If a driver chooses to implement VblankSupport, VblankImpl will be implemented by DRM automatically - and can be passed to the VblankImpl associated type on DriverCrtc. Additionally, we gate methods which only apply to vblank-supporting drivers by introducing a VblankDriverCrtc trait that is automatically implemented by DRM for CRTC drivers implementing VblankSupport. This works basically in the same way as Kms and KmsDriver, but for CRTCs. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- Notes: * One thing to keep in mind: this trait is implemented on the CRTC as opposed to the KMS driver due to the possibility that a driver may have multiple different types of CRTCs. As a result, it's not impossible that there could potentially be differences in each type's vblank hardware implementation. In theory this could lead to a driver mistakenly only implementing VblankSupport for some CRTCs and not others, which isn't really defined behavior in DRM. As such, one of the dependencies in the branch for this patch series preview is a fix to ensure that DRM disallows registering drivers that make this mistake. V3: * Update to the latest SpinlockIrq changes * Fix typo on get_vblank_timestamp() * Break statements in vblank_crtc() up a bit * Add comments around all uses of ManuallyDrop * Improve SAFETY comments * Make some unsafe scopes smaller
-
Lyude Paul authored
A quick note: this is one of my favorite bindings so far :). It sounds way overly complicated, but so far actually writing implementations of this in rust has been a breeze. Anyway: RVKMS has a slightly different atomic_commit_tail than normal, which means we need to write up some bindings for atomic_commit_tail. This is a lot more interesting then it might seem on the surface as implementing atomic_commit_tail incorrectly could result in UB. And in general, DRM has up until now relied entirely on the programmer to do this correctly through implicit ordering requirements. In the universe of rust though, we want no UB at all! To ensure this, we need to make sure that all atomic commit callbacks follow all of these requirements: * Disable/enable modeset commits must happen exactly once * A disable modeset must be committed for a resource before an enable modeset may be committed for a resource * Plane updates must happen exactly once * drm_atomic_commit_hw_done() must be called exactly once, and only after all commits have been completed. * The state may not be mutated after drm_atomic_commit_hw_done() is called * Access to the prior atomic states are revoked after drm_atomic_commit_hw_done() is called (and our "new" states become "old" states) To handle this, we introduce a number of new objects and types: tokens: * AtomicCommitTail Main object for controlling the commit_tail process * ModesetsReadyToken A single use token indicating that no modesets have been committed with the AtomicCommitTail yet * commit_modeset_disables() -> DisablesCommittedToken This function consumes the ModesetsReadyToken, commits modeset disables, and then returns a DisablesCommittedToken * commit_modeset_enables() -> EnablesCommittedToken This function consumes a DisablesCommittedToken, commits modeset enables, and then returns a EnablesCommittedToken EnablesCommittedToken - enforcing the disables -> enables order. * commit_planes() -> PlaneUpdatesCommittedToken Consumes a PlaneUpdatesReadyToken and returns a PlaneUpdatesCommittedToken. * commit_hw_done() -> CommittedAtomicState Revokes access to the AtomicCommitTailObject, and consumes both the EnablesCommittedToken and PlaneUpdatesCommitted tokens. This ensures that all modesets and plane updates have occurred exactly once. * CommittedAtomicState - main object for controlling the atomic_commit_tail after the state has been swapped in. This must be returned from the atomic_commit_tail function to prove that all of the required commits have occurred. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- TODO: * Currently this solution wouldn't be sufficient for drivers that need precise control over the order of each individual modeset or plane update. However, this should be very easy to add. * Figure out something better for enforcing the plane cleanup then what we have right now (e.g. cleaning up planes in the destructor for CommittedAtomicState). * Add iterator functions that take mutable references to the atomic state objects here. This will prevent functions like commit_modeset_disables() from being called while a state borrow is taken out, while still allowing easy access to the contents of the atomic state at any portion of the atomic commit tail. * Actually add some macros for generating bitmasks like we do with PlaneCommitFlags - right now we just do this by hand.
-
Lyude Paul authored
Now that we've added all of the bits that we need for the KMS API, it's time to introduce rvkms! This is a port of the VKMS driver to rust, with the intent of acting as an example usecase of the KMS bindings that we've come up with so far in preparation for writing a display driver for nova. Currently RVKMS is an extremely bear bones driver - it only registers a device and emulates vblanking, but it exercises a good portion of the API that we've introduced so far! Eventually I hope to introduce CRC generation and maybe writeback connectors like. Signed-off-by:
Lyude Paul <lyude@redhat.com> --- V3: * Replace platform device usage with faux device
-
Lyude Paul authored
A simple helper alias for code that needs to deal with Guard types returned from Mutexes. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
A simple helper alias for code that needs to deal with Guard types returned from SpinLocks. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
same for irq spinlocks. This will get dropped in the future since it's no longer the solution that we're going to be going for upstream, but it is taking forever for simple patches to be merged :(. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
gotta poke andreas about this one! looks like we forgot to actually expose this type
-
Lyude Paul authored
We're going to be calling some methods from AllocImpl directly in Registration::new() - which means that the rust compiler needs to know that our associated AllocImpl trait uses us as a Driver trait. Otherwise, it'll complain about a missing trait bound. The simplest way to do this is to just add this as a trait bound for the associated Driver::Object trait. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
In order to add rust bindings for the various DRM_MODE_CONNECTOR_* type IDs, we need a way to know the range of defined connector types - since each type corresponds to an actual array entry in drm_connector_enum_list. So, let's make this easy to figure out by adding a new _DRM_MODE_CONNECTOR_COUNT macro that always matches the number of available connector type IDs. Also, use that macro to define the size of drm_connector_enum_list to ensure that builds fail if someone attempts to add a new entry to drm_connector_enum_list without updating this macro. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
* Introduce an actual enum for connector types I realized we actually could do this fairly easy by using #[non_exhaustive], which should future-proof us against new connector types being added someday (if that ever happens).
-
Lyude Paul authored
-
Lyude Paul authored
* Turn all of the encoder type IDs into an enum using a new macro
-
Lyude Paul authored
* Improve safety comments
-
Lyude Paul authored
* Document uses of ManuallyDrop
-
Lyude Paul authored
-
Lyude Paul authored
* Use addr_of_mut! for accessing fields we were using &mut for. I think this is correct after going through some other rfl work?
-
Lyude Paul authored
* Change name of PlaneType to Type (for consistency with the other type IDs we've adde)
-
Lyude Paul authored
-
Lyude Paul authored
* Use addr_of_mut! in more places instead of &mut
-
Lyude Paul authored
* Use addr_of_mut!() instead of &mut
-
Lyude Paul authored
* Use addr_of_mut!() instead of &mut
-
Lyude Paul authored
* Add some missing invariant comments
-
Lyude Paul authored
-
Lyude Paul authored
* Use addr_of_mut!() instead of &mut for accessing C struct fields
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
-
Lyude Paul authored
Showing
- Documentation/driver-api/infrastructure.rst 6 additions, 0 deletionsDocumentation/driver-api/infrastructure.rst
- MAINTAINERS 2 additions, 0 deletionsMAINTAINERS
- drivers/base/Makefile 1 addition, 1 deletiondrivers/base/Makefile
- drivers/base/base.h 1 addition, 0 deletionsdrivers/base/base.h
- drivers/base/faux.c 232 additions, 0 deletionsdrivers/base/faux.c
- drivers/base/init.c 1 addition, 0 deletionsdrivers/base/init.c
- drivers/gpu/drm/Kconfig 2 additions, 0 deletionsdrivers/gpu/drm/Kconfig
- drivers/gpu/drm/Makefile 1 addition, 0 deletionsdrivers/gpu/drm/Makefile
- drivers/gpu/drm/drm_connector.c 1 addition, 1 deletiondrivers/gpu/drm/drm_connector.c
- drivers/gpu/drm/drm_gem_shmem_helper.c 6 additions, 3 deletionsdrivers/gpu/drm/drm_gem_shmem_helper.c
- drivers/gpu/drm/rvkms/Kconfig 3 additions, 0 deletionsdrivers/gpu/drm/rvkms/Kconfig
- drivers/gpu/drm/rvkms/Makefile 1 addition, 0 deletionsdrivers/gpu/drm/rvkms/Makefile
- drivers/gpu/drm/rvkms/connector.rs 54 additions, 0 deletionsdrivers/gpu/drm/rvkms/connector.rs
- drivers/gpu/drm/rvkms/crtc.rs 249 additions, 0 deletionsdrivers/gpu/drm/rvkms/crtc.rs
- drivers/gpu/drm/rvkms/encoder.rs 29 additions, 0 deletionsdrivers/gpu/drm/rvkms/encoder.rs
- drivers/gpu/drm/rvkms/file.rs 23 additions, 0 deletionsdrivers/gpu/drm/rvkms/file.rs
- drivers/gpu/drm/rvkms/gem.rs 30 additions, 0 deletionsdrivers/gpu/drm/rvkms/gem.rs
- drivers/gpu/drm/rvkms/output.rs 53 additions, 0 deletionsdrivers/gpu/drm/rvkms/output.rs
- drivers/gpu/drm/rvkms/plane.rs 82 additions, 0 deletionsdrivers/gpu/drm/rvkms/plane.rs
- drivers/gpu/drm/rvkms/rvkms.rs 146 additions, 0 deletionsdrivers/gpu/drm/rvkms/rvkms.rs
drivers/base/faux.c
0 → 100644
drivers/gpu/drm/rvkms/Kconfig
0 → 100644
drivers/gpu/drm/rvkms/Makefile
0 → 100644
drivers/gpu/drm/rvkms/connector.rs
0 → 100644
drivers/gpu/drm/rvkms/crtc.rs
0 → 100644
drivers/gpu/drm/rvkms/encoder.rs
0 → 100644
drivers/gpu/drm/rvkms/file.rs
0 → 100644
drivers/gpu/drm/rvkms/gem.rs
0 → 100644
drivers/gpu/drm/rvkms/output.rs
0 → 100644
drivers/gpu/drm/rvkms/plane.rs
0 → 100644
drivers/gpu/drm/rvkms/rvkms.rs
0 → 100644