Drivers must initialize the mode setting core by calling
drm_mode_config_init on the DRM device. The function
initializes the drm_device
mode_config field and never fails. Once done,
mode configuration must be setup by initializing the following fields.
int min_width, min_height; int max_width, max_height;
Minimum and maximum width and height of the frame buffers in pixel units.
struct drm_mode_config_funcs *funcs;
Mode setting functions.
Frame buffers are abstract memory objects that provide a source of pixels to scanout to a CRTC. Applications explicitly request the creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and receive an opaque handle that can be passed to the KMS CRTC control, plane configuration and page flip functions.
Frame buffers rely on the underneath memory manager for low-level memory
operations. When creating a frame buffer applications pass a memory
handle (or a list of memory handles for multi-planar formats) through
drm_mode_fb_cmd2 argument. For drivers using
GEM as their userspace buffer management interface this would be a GEM
handle. Drivers are however free to use their own backing storage object
handles, e.g. vmwgfx directly exposes special TTM handles to userspace
and so expects TTM handles in the create ioctl and not GEM handles.
The lifetime of a drm framebuffer is controlled with a reference count,
drivers can grab additional references with
drm_framebuffer_referenceand drop them
driver-private framebuffers for which the last reference is never
dropped (e.g. for the fbdev framebuffer when the struct
drm_framebuffer is embedded into the fbdev
helper struct) drivers can manually clean up a framebuffer at module
unload time with
The KMS API doesn't standardize backing storage object creation and leaves it to driver-specific ioctls. Furthermore actually creating a buffer object even for GEM-based drivers is done through a driver-specific ioctl - GEM only has a common userspace interface for sharing and destroying objects. While not an issue for full-fledged graphics stacks that include device-specific userspace components (in libdrm for instance), this limit makes DRM-based early boot graphics unnecessarily complex.
Dumb objects partly alleviate the problem by providing a standard API to create dumb buffers suitable for scanout, which can then be used to create KMS frame buffers.
To support dumb objects drivers must implement the
int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args);
dumb_create operation creates a driver
object (GEM or TTM handle) suitable for scanout based on the
width, height and depth from the struct
drm_mode_create_dumb argument. It fills the
fields with a handle for the newly created object and its line
pitch and size in bytes.
int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle);
dumb_destroy operation destroys a dumb
object created by
int (*dumb_map_offset)(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset);
dumb_map_offset operation associates an
mmap fake offset with the object given by the handle and returns
it. Drivers must use the
drm_gem_create_mmap_offset function to
associate the fake offset as described in
the section called “GEM Objects Mapping”.
Note that dumb objects may not be used for gpu acceleration, as has been attempted on some ARM embedded platforms. Such drivers really must have a hardware-specific ioctl to allocate suitable buffer objects.
void (*output_poll_changed)(struct drm_device *dev);
This operation notifies the driver that the status of one or more
connectors has changed. Drivers that use the fb helper can just call the
drm_fb_helper_hotplug_event function to handle this