Table of Contents
This chapter documents DRM internals relevant to driver authors and developers working to add support for the latest features to existing drivers.
First, we'll go over some typical driver initialization requirements, like setting up command buffers, creating an initial output configuration, and initializing core services. Subsequent sections will cover core internals in more detail, providing implementation notes and examples.
The DRM layer provides several services to graphics drivers, many of them driven by the application interfaces it provides through libdrm, the library that wraps most of the DRM ioctls. These include vblank event handling, memory management, output management, framebuffer management, command submission & fencing, suspend/resume support, and DMA services.
The core of every DRM driver is struct drm_driver. Drivers will typically statically initialize a drm_driver structure, then pass it to drm_init() at load time.
Before calling the DRM initialization routines, the driver must first create and fill out a struct drm_driver structure.
static struct drm_driver driver = { /* don't use mtrr's here, the Xserver or user space app should * deal with them for intel hardware. */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET, .load = i915_driver_load, .unload = i915_driver_unload, .firstopen = i915_driver_firstopen, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .save = i915_save, .restore = i915_restore, .device_is_agp = i915_driver_device_is_agp, .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, .irq_handler = i915_driver_irq_handler, .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, .fb_probe = intelfb_probe, .fb_remove = intelfb_remove, .fb_resize = intelfb_resize, .master_create = i915_master_create, .master_destroy = i915_master_destroy, #if defined(CONFIG_DEBUG_FS) .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, #endif .gem_init_object = i915_gem_init_object, .gem_free_object = i915_gem_free_object, .gem_vm_ops = &i915_gem_vm_ops, .ioctls = i915_ioctls, .fops = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, .ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, #ifdef CONFIG_COMPAT .compat_ioctl = i915_compat_ioctl, #endif .llseek = noop_llseek, }, .pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, .probe = probe, .remove = __devexit_p(drm_cleanup_pci), }, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, };
In the example above, taken from the i915 DRM driver, the driver sets several flags indicating what core features it supports. We'll go over the individual callbacks in later sections. Since flags indicate which features your driver supports to the DRM core, you need to set most of them prior to calling drm_init(). Some, like DRIVER_MODESET can be set later based on user supplied parameters, but that's the exception rather than the rule.
Driver flags
Driver uses AGP interface
Driver needs AGP interface to function.
Driver uses MTRR interface for mapping memory. Deprecated.
Driver is capable of PCI DMA. Deprecated.
Driver can perform scatter/gather DMA. Deprecated.
Driver supports DMA. Deprecated.
DRIVER_HAVE_IRQ indicates whether the driver has a IRQ handler, DRIVER_IRQ_SHARED indicates whether the device & handler support shared IRQs (note that this is required of PCI drivers).
If the driver queues DMA requests and completes them asynchronously, this flag should be set. Deprecated.
Driver supports DMA to/from the framebuffer. Deprecated.
Driver supports mode setting interfaces.
In this specific case, the driver requires AGP and supports IRQs. DMA, as we'll see, is handled by device specific ioctls in this case. It also supports the kernel mode setting APIs, though unlike in the actual i915 driver source, this example unconditionally exports KMS capability.