Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" |
| 3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> |
| 4 | |
| 5 | <book id="drmDevelopersGuide"> |
| 6 | <bookinfo> |
| 7 | <title>Linux DRM Developer's Guide</title> |
| 8 | |
| 9 | <copyright> |
| 10 | <year>2008-2009</year> |
| 11 | <holder> |
| 12 | Intel Corporation (Jesse Barnes <jesse.barnes@intel.com>) |
| 13 | </holder> |
| 14 | </copyright> |
| 15 | |
| 16 | <legalnotice> |
| 17 | <para> |
| 18 | The contents of this file may be used under the terms of the GNU |
| 19 | General Public License version 2 (the "GPL") as distributed in |
| 20 | the kernel source COPYING file. |
| 21 | </para> |
| 22 | </legalnotice> |
| 23 | </bookinfo> |
| 24 | |
| 25 | <toc></toc> |
| 26 | |
| 27 | <!-- Introduction --> |
| 28 | |
| 29 | <chapter id="drmIntroduction"> |
| 30 | <title>Introduction</title> |
| 31 | <para> |
| 32 | The Linux DRM layer contains code intended to support the needs |
| 33 | of complex graphics devices, usually containing programmable |
| 34 | pipelines well suited to 3D graphics acceleration. Graphics |
| 35 | drivers in the kernel can make use of DRM functions to make |
| 36 | tasks like memory management, interrupt handling and DMA easier, |
| 37 | and provide a uniform interface to applications. |
| 38 | </para> |
| 39 | <para> |
| 40 | A note on versions: this guide covers features found in the DRM |
| 41 | tree, including the TTM memory manager, output configuration and |
| 42 | mode setting, and the new vblank internals, in addition to all |
| 43 | the regular features found in current kernels. |
| 44 | </para> |
| 45 | <para> |
| 46 | [Insert diagram of typical DRM stack here] |
| 47 | </para> |
| 48 | </chapter> |
| 49 | |
| 50 | <!-- Internals --> |
| 51 | |
| 52 | <chapter id="drmInternals"> |
| 53 | <title>DRM Internals</title> |
| 54 | <para> |
| 55 | This chapter documents DRM internals relevant to driver authors |
| 56 | and developers working to add support for the latest features to |
| 57 | existing drivers. |
| 58 | </para> |
| 59 | <para> |
| 60 | First, we'll go over some typical driver initialization |
| 61 | requirements, like setting up command buffers, creating an |
| 62 | initial output configuration, and initializing core services. |
| 63 | Subsequent sections will cover core internals in more detail, |
| 64 | providing implementation notes and examples. |
| 65 | </para> |
| 66 | <para> |
| 67 | The DRM layer provides several services to graphics drivers, |
| 68 | many of them driven by the application interfaces it provides |
| 69 | through libdrm, the library that wraps most of the DRM ioctls. |
| 70 | These include vblank event handling, memory |
| 71 | management, output management, framebuffer management, command |
| 72 | submission & fencing, suspend/resume support, and DMA |
| 73 | services. |
| 74 | </para> |
| 75 | <para> |
| 76 | The core of every DRM driver is struct drm_device. Drivers |
| 77 | will typically statically initialize a drm_device structure, |
| 78 | then pass it to drm_init() at load time. |
| 79 | </para> |
| 80 | |
| 81 | <!-- Internals: driver init --> |
| 82 | |
| 83 | <sect1> |
| 84 | <title>Driver initialization</title> |
| 85 | <para> |
| 86 | Before calling the DRM initialization routines, the driver must |
| 87 | first create and fill out a struct drm_device structure. |
| 88 | </para> |
| 89 | <programlisting> |
| 90 | static struct drm_driver driver = { |
| 91 | /* don't use mtrr's here, the Xserver or user space app should |
| 92 | * deal with them for intel hardware. |
| 93 | */ |
| 94 | .driver_features = |
| 95 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | |
| 96 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET, |
| 97 | .load = i915_driver_load, |
| 98 | .unload = i915_driver_unload, |
| 99 | .firstopen = i915_driver_firstopen, |
| 100 | .lastclose = i915_driver_lastclose, |
| 101 | .preclose = i915_driver_preclose, |
| 102 | .save = i915_save, |
| 103 | .restore = i915_restore, |
| 104 | .device_is_agp = i915_driver_device_is_agp, |
| 105 | .get_vblank_counter = i915_get_vblank_counter, |
| 106 | .enable_vblank = i915_enable_vblank, |
| 107 | .disable_vblank = i915_disable_vblank, |
| 108 | .irq_preinstall = i915_driver_irq_preinstall, |
| 109 | .irq_postinstall = i915_driver_irq_postinstall, |
| 110 | .irq_uninstall = i915_driver_irq_uninstall, |
| 111 | .irq_handler = i915_driver_irq_handler, |
| 112 | .reclaim_buffers = drm_core_reclaim_buffers, |
| 113 | .get_map_ofs = drm_core_get_map_ofs, |
| 114 | .get_reg_ofs = drm_core_get_reg_ofs, |
| 115 | .fb_probe = intelfb_probe, |
| 116 | .fb_remove = intelfb_remove, |
| 117 | .fb_resize = intelfb_resize, |
| 118 | .master_create = i915_master_create, |
| 119 | .master_destroy = i915_master_destroy, |
| 120 | #if defined(CONFIG_DEBUG_FS) |
| 121 | .debugfs_init = i915_debugfs_init, |
| 122 | .debugfs_cleanup = i915_debugfs_cleanup, |
| 123 | #endif |
| 124 | .gem_init_object = i915_gem_init_object, |
| 125 | .gem_free_object = i915_gem_free_object, |
| 126 | .gem_vm_ops = &i915_gem_vm_ops, |
| 127 | .ioctls = i915_ioctls, |
| 128 | .fops = { |
| 129 | .owner = THIS_MODULE, |
| 130 | .open = drm_open, |
| 131 | .release = drm_release, |
| 132 | .ioctl = drm_ioctl, |
| 133 | .mmap = drm_mmap, |
| 134 | .poll = drm_poll, |
| 135 | .fasync = drm_fasync, |
| 136 | #ifdef CONFIG_COMPAT |
| 137 | .compat_ioctl = i915_compat_ioctl, |
| 138 | #endif |
| 139 | }, |
| 140 | .pci_driver = { |
| 141 | .name = DRIVER_NAME, |
| 142 | .id_table = pciidlist, |
| 143 | .probe = probe, |
| 144 | .remove = __devexit_p(drm_cleanup_pci), |
| 145 | }, |
| 146 | .name = DRIVER_NAME, |
| 147 | .desc = DRIVER_DESC, |
| 148 | .date = DRIVER_DATE, |
| 149 | .major = DRIVER_MAJOR, |
| 150 | .minor = DRIVER_MINOR, |
| 151 | .patchlevel = DRIVER_PATCHLEVEL, |
| 152 | }; |
| 153 | </programlisting> |
| 154 | <para> |
| 155 | In the example above, taken from the i915 DRM driver, the driver |
| 156 | sets several flags indicating what core features it supports. |
| 157 | We'll go over the individual callbacks in later sections. Since |
| 158 | flags indicate which features your driver supports to the DRM |
| 159 | core, you need to set most of them prior to calling drm_init(). Some, |
| 160 | like DRIVER_MODESET can be set later based on user supplied parameters, |
| 161 | but that's the exception rather than the rule. |
| 162 | </para> |
| 163 | <variablelist> |
| 164 | <title>Driver flags</title> |
| 165 | <varlistentry> |
| 166 | <term>DRIVER_USE_AGP</term> |
| 167 | <listitem><para> |
| 168 | Driver uses AGP interface |
| 169 | </para></listitem> |
| 170 | </varlistentry> |
| 171 | <varlistentry> |
| 172 | <term>DRIVER_REQUIRE_AGP</term> |
| 173 | <listitem><para> |
| 174 | Driver needs AGP interface to function. |
| 175 | </para></listitem> |
| 176 | </varlistentry> |
| 177 | <varlistentry> |
| 178 | <term>DRIVER_USE_MTRR</term> |
| 179 | <listitem> |
| 180 | <para> |
| 181 | Driver uses MTRR interface for mapping memory. Deprecated. |
| 182 | </para> |
| 183 | </listitem> |
| 184 | </varlistentry> |
| 185 | <varlistentry> |
| 186 | <term>DRIVER_PCI_DMA</term> |
| 187 | <listitem><para> |
| 188 | Driver is capable of PCI DMA. Deprecated. |
| 189 | </para></listitem> |
| 190 | </varlistentry> |
| 191 | <varlistentry> |
| 192 | <term>DRIVER_SG</term> |
| 193 | <listitem><para> |
| 194 | Driver can perform scatter/gather DMA. Deprecated. |
| 195 | </para></listitem> |
| 196 | </varlistentry> |
| 197 | <varlistentry> |
| 198 | <term>DRIVER_HAVE_DMA</term> |
| 199 | <listitem><para>Driver supports DMA. Deprecated.</para></listitem> |
| 200 | </varlistentry> |
| 201 | <varlistentry> |
| 202 | <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term> |
| 203 | <listitem> |
| 204 | <para> |
| 205 | DRIVER_HAVE_IRQ indicates whether the driver has a IRQ |
| 206 | handler, DRIVER_IRQ_SHARED indicates whether the device & |
| 207 | handler support shared IRQs (note that this is required of |
| 208 | PCI drivers). |
| 209 | </para> |
| 210 | </listitem> |
| 211 | </varlistentry> |
| 212 | <varlistentry> |
| 213 | <term>DRIVER_DMA_QUEUE</term> |
| 214 | <listitem> |
| 215 | <para> |
| 216 | If the driver queues DMA requests and completes them |
| 217 | asynchronously, this flag should be set. Deprecated. |
| 218 | </para> |
| 219 | </listitem> |
| 220 | </varlistentry> |
| 221 | <varlistentry> |
| 222 | <term>DRIVER_FB_DMA</term> |
| 223 | <listitem> |
| 224 | <para> |
| 225 | Driver supports DMA to/from the framebuffer. Deprecated. |
| 226 | </para> |
| 227 | </listitem> |
| 228 | </varlistentry> |
| 229 | <varlistentry> |
| 230 | <term>DRIVER_MODESET</term> |
| 231 | <listitem> |
| 232 | <para> |
| 233 | Driver supports mode setting interfaces. |
| 234 | </para> |
| 235 | </listitem> |
| 236 | </varlistentry> |
| 237 | </variablelist> |
| 238 | <para> |
| 239 | In this specific case, the driver requires AGP and supports |
| 240 | IRQs. DMA, as we'll see, is handled by device specific ioctls |
| 241 | in this case. It also supports the kernel mode setting APIs, though |
| 242 | unlike in the actual i915 driver source, this example unconditionally |
| 243 | exports KMS capability. |
| 244 | </para> |
| 245 | </sect1> |
| 246 | |
| 247 | <!-- Internals: driver load --> |
| 248 | |
| 249 | <sect1> |
| 250 | <title>Driver load</title> |
| 251 | <para> |
| 252 | In the previous section, we saw what a typical drm_driver |
| 253 | structure might look like. One of the more important fields in |
| 254 | the structure is the hook for the load function. |
| 255 | </para> |
| 256 | <programlisting> |
| 257 | static struct drm_driver driver = { |
| 258 | ... |
| 259 | .load = i915_driver_load, |
| 260 | ... |
| 261 | }; |
| 262 | </programlisting> |
| 263 | <para> |
| 264 | The load function has many responsibilities: allocating a driver |
| 265 | private structure, specifying supported performance counters, |
| 266 | configuring the device (e.g. mapping registers & command |
| 267 | buffers), initializing the memory manager, and setting up the |
| 268 | initial output configuration. |
| 269 | </para> |
| 270 | <para> |
| 271 | Note that the tasks performed at driver load time must not |
| 272 | conflict with DRM client requirements. For instance, if user |
| 273 | level mode setting drivers are in use, it would be problematic |
| 274 | to perform output discovery & configuration at load time. |
| 275 | Likewise, if pre-memory management aware user level drivers are |
| 276 | in use, memory management and command buffer setup may need to |
| 277 | be omitted. These requirements are driver specific, and care |
| 278 | needs to be taken to keep both old and new applications and |
| 279 | libraries working. The i915 driver supports the "modeset" |
| 280 | module parameter to control whether advanced features are |
| 281 | enabled at load time or in legacy fashion. If compatibility is |
| 282 | a concern (e.g. with drivers converted over to the new interfaces |
| 283 | from the old ones), care must be taken to prevent incompatible |
| 284 | device initialization and control with the currently active |
| 285 | userspace drivers. |
| 286 | </para> |
| 287 | |
| 288 | <sect2> |
| 289 | <title>Driver private & performance counters</title> |
| 290 | <para> |
| 291 | The driver private hangs off the main drm_device structure and |
| 292 | can be used for tracking various device specific bits of |
| 293 | information, like register offsets, command buffer status, |
| 294 | register state for suspend/resume, etc. At load time, a |
| 295 | driver can simply allocate one and set drm_device.dev_priv |
| 296 | appropriately; at unload the driver can free it and set |
| 297 | drm_device.dev_priv to NULL. |
| 298 | </para> |
| 299 | <para> |
| 300 | The DRM supports several counters which can be used for rough |
| 301 | performance characterization. Note that the DRM stat counter |
| 302 | system is not often used by applications, and supporting |
| 303 | additional counters is completely optional. |
| 304 | </para> |
| 305 | <para> |
| 306 | These interfaces are deprecated and should not be used. If performance |
| 307 | monitoring is desired, the developer should investigate and |
| 308 | potentially enhance the kernel perf and tracing infrastructure to export |
| 309 | GPU related performance information to performance monitoring |
| 310 | tools and applications. |
| 311 | </para> |
| 312 | </sect2> |
| 313 | |
| 314 | <sect2> |
| 315 | <title>Configuring the device</title> |
| 316 | <para> |
| 317 | Obviously, device configuration will be device specific. |
| 318 | However, there are several common operations: finding a |
| 319 | device's PCI resources, mapping them, and potentially setting |
| 320 | up an IRQ handler. |
| 321 | </para> |
| 322 | <para> |
| 323 | Finding & mapping resources is fairly straightforward. The |
| 324 | DRM wrapper functions, drm_get_resource_start() and |
| 325 | drm_get_resource_len() can be used to find BARs on the given |
| 326 | drm_device struct. Once those values have been retrieved, the |
| 327 | driver load function can call drm_addmap() to create a new |
| 328 | mapping for the BAR in question. Note you'll probably want a |
| 329 | drm_local_map_t in your driver private structure to track any |
| 330 | mappings you create. |
| 331 | <!-- !Fdrivers/gpu/drm/drm_bufs.c drm_get_resource_* --> |
| 332 | <!-- !Finclude/drm/drmP.h drm_local_map_t --> |
| 333 | </para> |
| 334 | <para> |
| 335 | if compatibility with other operating systems isn't a concern |
| 336 | (DRM drivers can run under various BSD variants and OpenSolaris), |
| 337 | native Linux calls can be used for the above, e.g. pci_resource_* |
| 338 | and iomap*/iounmap. See the Linux device driver book for more |
| 339 | info. |
| 340 | </para> |
| 341 | <para> |
| 342 | Once you have a register map, you can use the DRM_READn() and |
| 343 | DRM_WRITEn() macros to access the registers on your device, or |
| 344 | use driver specific versions to offset into your MMIO space |
| 345 | relative to a driver specific base pointer (see I915_READ for |
| 346 | example). |
| 347 | </para> |
| 348 | <para> |
| 349 | If your device supports interrupt generation, you may want to |
| 350 | setup an interrupt handler at driver load time as well. This |
| 351 | is done using the drm_irq_install() function. If your device |
| 352 | supports vertical blank interrupts, it should call |
| 353 | drm_vblank_init() to initialize the core vblank handling code before |
| 354 | enabling interrupts on your device. This ensures the vblank related |
| 355 | structures are allocated and allows the core to handle vblank events. |
| 356 | </para> |
| 357 | <!--!Fdrivers/char/drm/drm_irq.c drm_irq_install--> |
| 358 | <para> |
| 359 | Once your interrupt handler is registered (it'll use your |
| 360 | drm_driver.irq_handler as the actual interrupt handling |
| 361 | function), you can safely enable interrupts on your device, |
| 362 | assuming any other state your interrupt handler uses is also |
| 363 | initialized. |
| 364 | </para> |
| 365 | <para> |
| 366 | Another task that may be necessary during configuration is |
| 367 | mapping the video BIOS. On many devices, the VBIOS describes |
| 368 | device configuration, LCD panel timings (if any), and contains |
| 369 | flags indicating device state. Mapping the BIOS can be done |
| 370 | using the pci_map_rom() call, a convenience function that |
| 371 | takes care of mapping the actual ROM, whether it has been |
| 372 | shadowed into memory (typically at address 0xc0000) or exists |
| 373 | on the PCI device in the ROM BAR. Note that once you've |
| 374 | mapped the ROM and extracted any necessary information, be |
| 375 | sure to unmap it; on many devices the ROM address decoder is |
| 376 | shared with other BARs, so leaving it mapped can cause |
| 377 | undesired behavior like hangs or memory corruption. |
| 378 | <!--!Fdrivers/pci/rom.c pci_map_rom--> |
| 379 | </para> |
| 380 | </sect2> |
| 381 | |
| 382 | <sect2> |
| 383 | <title>Memory manager initialization</title> |
| 384 | <para> |
| 385 | In order to allocate command buffers, cursor memory, scanout |
| 386 | buffers, etc., as well as support the latest features provided |
| 387 | by packages like Mesa and the X.Org X server, your driver |
| 388 | should support a memory manager. |
| 389 | </para> |
| 390 | <para> |
| 391 | If your driver supports memory management (it should!), you'll |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 392 | need to set that up at load time as well. How you initialize |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 393 | it depends on which memory manager you're using, TTM or GEM. |
| 394 | </para> |
| 395 | <sect3> |
| 396 | <title>TTM initialization</title> |
| 397 | <para> |
| 398 | TTM (for Translation Table Manager) manages video memory and |
| 399 | aperture space for graphics devices. TTM supports both UMA devices |
| 400 | and devices with dedicated video RAM (VRAM), i.e. most discrete |
| 401 | graphics devices. If your device has dedicated RAM, supporting |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 402 | TTM is desirable. TTM also integrates tightly with your |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 403 | driver specific buffer execution function. See the radeon |
| 404 | driver for examples. |
| 405 | </para> |
| 406 | <para> |
| 407 | The core TTM structure is the ttm_bo_driver struct. It contains |
| 408 | several fields with function pointers for initializing the TTM, |
| 409 | allocating and freeing memory, waiting for command completion |
| 410 | and fence synchronization, and memory migration. See the |
| 411 | radeon_ttm.c file for an example of usage. |
| 412 | </para> |
| 413 | <para> |
| 414 | The ttm_global_reference structure is made up of several fields: |
| 415 | </para> |
| 416 | <programlisting> |
| 417 | struct ttm_global_reference { |
| 418 | enum ttm_global_types global_type; |
| 419 | size_t size; |
| 420 | void *object; |
| 421 | int (*init) (struct ttm_global_reference *); |
| 422 | void (*release) (struct ttm_global_reference *); |
| 423 | }; |
| 424 | </programlisting> |
| 425 | <para> |
| 426 | There should be one global reference structure for your memory |
| 427 | manager as a whole, and there will be others for each object |
| 428 | created by the memory manager at runtime. Your global TTM should |
| 429 | have a type of TTM_GLOBAL_TTM_MEM. The size field for the global |
| 430 | object should be sizeof(struct ttm_mem_global), and the init and |
| 431 | release hooks should point at your driver specific init and |
| 432 | release routines, which will probably eventually call |
| 433 | ttm_mem_global_init and ttm_mem_global_release respectively. |
| 434 | </para> |
| 435 | <para> |
| 436 | Once your global TTM accounting structure is set up and initialized |
| 437 | (done by calling ttm_global_item_ref on the global object you |
| 438 | just created), you'll need to create a buffer object TTM to |
| 439 | provide a pool for buffer object allocation by clients and the |
| 440 | kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, |
| 441 | and its size should be sizeof(struct ttm_bo_global). Again, |
| 442 | driver specific init and release functions can be provided, |
| 443 | likely eventually calling ttm_bo_global_init and |
| 444 | ttm_bo_global_release, respectively. Also like the previous |
| 445 | object, ttm_global_item_ref is used to create an initial reference |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 446 | count for the TTM, which will call your initialization function. |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 447 | </para> |
| 448 | </sect3> |
| 449 | <sect3> |
| 450 | <title>GEM initialization</title> |
| 451 | <para> |
| 452 | GEM is an alternative to TTM, designed specifically for UMA |
| 453 | devices. It has simpler initialization and execution requirements |
| 454 | than TTM, but has no VRAM management capability. Core GEM |
| 455 | initialization is comprised of a basic drm_mm_init call to create |
| 456 | a GTT DRM MM object, which provides an address space pool for |
| 457 | object allocation. In a KMS configuration, the driver will |
| 458 | need to allocate and initialize a command ring buffer following |
| 459 | basic GEM initialization. Most UMA devices have a so-called |
| 460 | "stolen" memory region, which provides space for the initial |
| 461 | framebuffer and large, contiguous memory regions required by the |
| 462 | device. This space is not typically managed by GEM, and must |
| 463 | be initialized separately into its own DRM MM object. |
| 464 | </para> |
| 465 | <para> |
| 466 | Initialization will be driver specific, and will depend on |
| 467 | the architecture of the device. In the case of Intel |
| 468 | integrated graphics chips like 965GM, GEM initialization can |
| 469 | be done by calling the internal GEM init function, |
| 470 | i915_gem_do_init(). Since the 965GM is a UMA device |
| 471 | (i.e. it doesn't have dedicated VRAM), GEM will manage |
| 472 | making regular RAM available for GPU operations. Memory set |
| 473 | aside by the BIOS (called "stolen" memory by the i915 |
| 474 | driver) will be managed by the DRM memrange allocator; the |
| 475 | rest of the aperture will be managed by GEM. |
| 476 | <programlisting> |
| 477 | /* Basic memrange allocator for stolen space (aka vram) */ |
| 478 | drm_memrange_init(&dev_priv->vram, 0, prealloc_size); |
| 479 | /* Let GEM Manage from end of prealloc space to end of aperture */ |
| 480 | i915_gem_do_init(dev, prealloc_size, agp_size); |
| 481 | </programlisting> |
| 482 | <!--!Edrivers/char/drm/drm_memrange.c--> |
| 483 | </para> |
| 484 | <para> |
| 485 | Once the memory manager has been set up, we can allocate the |
| 486 | command buffer. In the i915 case, this is also done with a |
| 487 | GEM function, i915_gem_init_ringbuffer(). |
| 488 | </para> |
| 489 | </sect3> |
| 490 | </sect2> |
| 491 | |
| 492 | <sect2> |
| 493 | <title>Output configuration</title> |
| 494 | <para> |
| 495 | The final initialization task is output configuration. This involves |
| 496 | finding and initializing the CRTCs, encoders and connectors |
| 497 | for your device, creating an initial configuration and |
| 498 | registering a framebuffer console driver. |
| 499 | </para> |
| 500 | <sect3> |
| 501 | <title>Output discovery and initialization</title> |
| 502 | <para> |
| 503 | Several core functions exist to create CRTCs, encoders and |
| 504 | connectors, namely drm_crtc_init(), drm_connector_init() and |
| 505 | drm_encoder_init(), along with several "helper" functions to |
| 506 | perform common tasks. |
| 507 | </para> |
| 508 | <para> |
| 509 | Connectors should be registered with sysfs once they've been |
| 510 | detected and initialized, using the |
| 511 | drm_sysfs_connector_add() function. Likewise, when they're |
| 512 | removed from the system, they should be destroyed with |
| 513 | drm_sysfs_connector_remove(). |
| 514 | </para> |
| 515 | <programlisting> |
| 516 | <![CDATA[ |
| 517 | void intel_crt_init(struct drm_device *dev) |
| 518 | { |
| 519 | struct drm_connector *connector; |
| 520 | struct intel_output *intel_output; |
| 521 | |
| 522 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); |
| 523 | if (!intel_output) |
| 524 | return; |
| 525 | |
| 526 | connector = &intel_output->base; |
| 527 | drm_connector_init(dev, &intel_output->base, |
| 528 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
| 529 | |
| 530 | drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, |
| 531 | DRM_MODE_ENCODER_DAC); |
| 532 | |
| 533 | drm_mode_connector_attach_encoder(&intel_output->base, |
| 534 | &intel_output->enc); |
| 535 | |
| 536 | /* Set up the DDC bus. */ |
| 537 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); |
| 538 | if (!intel_output->ddc_bus) { |
| 539 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
| 540 | "failed.\n"); |
| 541 | return; |
| 542 | } |
| 543 | |
| 544 | intel_output->type = INTEL_OUTPUT_ANALOG; |
| 545 | connector->interlace_allowed = 0; |
| 546 | connector->doublescan_allowed = 0; |
| 547 | |
| 548 | drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); |
| 549 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
| 550 | |
| 551 | drm_sysfs_connector_add(connector); |
| 552 | } |
| 553 | ]]> |
| 554 | </programlisting> |
| 555 | <para> |
| 556 | In the example above (again, taken from the i915 driver), a |
| 557 | CRT connector and encoder combination is created. A device |
| 558 | specific i2c bus is also created, for fetching EDID data and |
| 559 | performing monitor detection. Once the process is complete, |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 560 | the new connector is registered with sysfs, to make its |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 561 | properties available to applications. |
| 562 | </para> |
| 563 | <sect4> |
| 564 | <title>Helper functions and core functions</title> |
| 565 | <para> |
| 566 | Since many PC-class graphics devices have similar display output |
| 567 | designs, the DRM provides a set of helper functions to make |
| 568 | output management easier. The core helper routines handle |
| 569 | encoder re-routing and disabling of unused functions following |
| 570 | mode set. Using the helpers is optional, but recommended for |
| 571 | devices with PC-style architectures (i.e. a set of display planes |
| 572 | for feeding pixels to encoders which are in turn routed to |
| 573 | connectors). Devices with more complex requirements needing |
| 574 | finer grained management can opt to use the core callbacks |
| 575 | directly. |
| 576 | </para> |
| 577 | <para> |
| 578 | [Insert typical diagram here.] [Insert OMAP style config here.] |
| 579 | </para> |
| 580 | </sect4> |
| 581 | <para> |
| 582 | For each encoder, CRTC and connector, several functions must |
| 583 | be provided, depending on the object type. Encoder objects |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 584 | need to provide a DPMS (basically on/off) function, mode fixup |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 585 | (for converting requested modes into native hardware timings), |
| 586 | and prepare, set and commit functions for use by the core DRM |
| 587 | helper functions. Connector helpers need to provide mode fetch and |
| 588 | validity functions as well as an encoder matching function for |
Nicolas Kaiser | ce04cc0 | 2010-05-28 07:33:49 +0200 | [diff] [blame] | 589 | returning an ideal encoder for a given connector. The core |
Jesse Barnes | 2d2ef82 | 2009-10-26 13:06:31 -0700 | [diff] [blame] | 590 | connector functions include a DPMS callback, (deprecated) |
| 591 | save/restore routines, detection, mode probing, property handling, |
| 592 | and cleanup functions. |
| 593 | </para> |
| 594 | <!--!Edrivers/char/drm/drm_crtc.h--> |
| 595 | <!--!Edrivers/char/drm/drm_crtc.c--> |
| 596 | <!--!Edrivers/char/drm/drm_crtc_helper.c--> |
| 597 | </sect3> |
| 598 | </sect2> |
| 599 | </sect1> |
| 600 | |
| 601 | <!-- Internals: vblank handling --> |
| 602 | |
| 603 | <sect1> |
| 604 | <title>VBlank event handling</title> |
| 605 | <para> |
| 606 | The DRM core exposes two vertical blank related ioctls: |
| 607 | DRM_IOCTL_WAIT_VBLANK and DRM_IOCTL_MODESET_CTL. |
| 608 | <!--!Edrivers/char/drm/drm_irq.c--> |
| 609 | </para> |
| 610 | <para> |
| 611 | DRM_IOCTL_WAIT_VBLANK takes a struct drm_wait_vblank structure |
| 612 | as its argument, and is used to block or request a signal when a |
| 613 | specified vblank event occurs. |
| 614 | </para> |
| 615 | <para> |
| 616 | DRM_IOCTL_MODESET_CTL should be called by application level |
| 617 | drivers before and after mode setting, since on many devices the |
| 618 | vertical blank counter will be reset at that time. Internally, |
| 619 | the DRM snapshots the last vblank count when the ioctl is called |
| 620 | with the _DRM_PRE_MODESET command so that the counter won't go |
| 621 | backwards (which is dealt with when _DRM_POST_MODESET is used). |
| 622 | </para> |
| 623 | <para> |
| 624 | To support the functions above, the DRM core provides several |
| 625 | helper functions for tracking vertical blank counters, and |
| 626 | requires drivers to provide several callbacks: |
| 627 | get_vblank_counter(), enable_vblank() and disable_vblank(). The |
| 628 | core uses get_vblank_counter() to keep the counter accurate |
| 629 | across interrupt disable periods. It should return the current |
| 630 | vertical blank event count, which is often tracked in a device |
| 631 | register. The enable and disable vblank callbacks should enable |
| 632 | and disable vertical blank interrupts, respectively. In the |
| 633 | absence of DRM clients waiting on vblank events, the core DRM |
| 634 | code will use the disable_vblank() function to disable |
| 635 | interrupts, which saves power. They'll be re-enabled again when |
| 636 | a client calls the vblank wait ioctl above. |
| 637 | </para> |
| 638 | <para> |
| 639 | Devices that don't provide a count register can simply use an |
| 640 | internal atomic counter incremented on every vertical blank |
| 641 | interrupt, and can make their enable and disable vblank |
| 642 | functions into no-ops. |
| 643 | </para> |
| 644 | </sect1> |
| 645 | |
| 646 | <sect1> |
| 647 | <title>Memory management</title> |
| 648 | <para> |
| 649 | The memory manager lies at the heart of many DRM operations, and |
| 650 | is also required to support advanced client features like OpenGL |
| 651 | pbuffers. The DRM currently contains two memory managers, TTM |
| 652 | and GEM. |
| 653 | </para> |
| 654 | |
| 655 | <sect2> |
| 656 | <title>The Translation Table Manager (TTM)</title> |
| 657 | <para> |
| 658 | TTM was developed by Tungsten Graphics, primarily by Thomas |
| 659 | Hellström, and is intended to be a flexible, high performance |
| 660 | graphics memory manager. |
| 661 | </para> |
| 662 | <para> |
| 663 | Drivers wishing to support TTM must fill out a drm_bo_driver |
| 664 | structure. |
| 665 | </para> |
| 666 | <para> |
| 667 | TTM design background and information belongs here. |
| 668 | </para> |
| 669 | </sect2> |
| 670 | |
| 671 | <sect2> |
| 672 | <title>The Graphics Execution Manager (GEM)</title> |
| 673 | <para> |
| 674 | GEM is an Intel project, authored by Eric Anholt and Keith |
| 675 | Packard. It provides simpler interfaces than TTM, and is well |
| 676 | suited for UMA devices. |
| 677 | </para> |
| 678 | <para> |
| 679 | GEM-enabled drivers must provide gem_init_object() and |
| 680 | gem_free_object() callbacks to support the core memory |
| 681 | allocation routines. They should also provide several driver |
| 682 | specific ioctls to support command execution, pinning, buffer |
| 683 | read & write, mapping, and domain ownership transfers. |
| 684 | </para> |
| 685 | <para> |
| 686 | On a fundamental level, GEM involves several operations: memory |
| 687 | allocation and freeing, command execution, and aperture management |
| 688 | at command execution time. Buffer object allocation is relatively |
| 689 | straightforward and largely provided by Linux's shmem layer, which |
| 690 | provides memory to back each object. When mapped into the GTT |
| 691 | or used in a command buffer, the backing pages for an object are |
| 692 | flushed to memory and marked write combined so as to be coherent |
| 693 | with the GPU. Likewise, when the GPU finishes rendering to an object, |
| 694 | if the CPU accesses it, it must be made coherent with the CPU's view |
| 695 | of memory, usually involving GPU cache flushing of various kinds. |
| 696 | This core CPU<->GPU coherency management is provided by the GEM |
| 697 | set domain function, which evaluates an object's current domain and |
| 698 | performs any necessary flushing or synchronization to put the object |
| 699 | into the desired coherency domain (note that the object may be busy, |
| 700 | i.e. an active render target; in that case the set domain function |
| 701 | will block the client and wait for rendering to complete before |
| 702 | performing any necessary flushing operations). |
| 703 | </para> |
| 704 | <para> |
| 705 | Perhaps the most important GEM function is providing a command |
| 706 | execution interface to clients. Client programs construct command |
| 707 | buffers containing references to previously allocated memory objects |
| 708 | and submit them to GEM. At that point, GEM will take care to bind |
| 709 | all the objects into the GTT, execute the buffer, and provide |
| 710 | necessary synchronization between clients accessing the same buffers. |
| 711 | This often involves evicting some objects from the GTT and re-binding |
| 712 | others (a fairly expensive operation), and providing relocation |
| 713 | support which hides fixed GTT offsets from clients. Clients must |
| 714 | take care not to submit command buffers that reference more objects |
| 715 | than can fit in the GTT or GEM will reject them and no rendering |
| 716 | will occur. Similarly, if several objects in the buffer require |
| 717 | fence registers to be allocated for correct rendering (e.g. 2D blits |
| 718 | on pre-965 chips), care must be taken not to require more fence |
| 719 | registers than are available to the client. Such resource management |
| 720 | should be abstracted from the client in libdrm. |
| 721 | </para> |
| 722 | </sect2> |
| 723 | |
| 724 | </sect1> |
| 725 | |
| 726 | <!-- Output management --> |
| 727 | <sect1> |
| 728 | <title>Output management</title> |
| 729 | <para> |
| 730 | At the core of the DRM output management code is a set of |
| 731 | structures representing CRTCs, encoders and connectors. |
| 732 | </para> |
| 733 | <para> |
| 734 | A CRTC is an abstraction representing a part of the chip that |
| 735 | contains a pointer to a scanout buffer. Therefore, the number |
| 736 | of CRTCs available determines how many independent scanout |
| 737 | buffers can be active at any given time. The CRTC structure |
| 738 | contains several fields to support this: a pointer to some video |
| 739 | memory, a display mode, and an (x, y) offset into the video |
| 740 | memory to support panning or configurations where one piece of |
| 741 | video memory spans multiple CRTCs. |
| 742 | </para> |
| 743 | <para> |
| 744 | An encoder takes pixel data from a CRTC and converts it to a |
| 745 | format suitable for any attached connectors. On some devices, |
| 746 | it may be possible to have a CRTC send data to more than one |
| 747 | encoder. In that case, both encoders would receive data from |
| 748 | the same scanout buffer, resulting in a "cloned" display |
| 749 | configuration across the connectors attached to each encoder. |
| 750 | </para> |
| 751 | <para> |
| 752 | A connector is the final destination for pixel data on a device, |
| 753 | and usually connects directly to an external display device like |
| 754 | a monitor or laptop panel. A connector can only be attached to |
| 755 | one encoder at a time. The connector is also the structure |
| 756 | where information about the attached display is kept, so it |
| 757 | contains fields for display data, EDID data, DPMS & |
| 758 | connection status, and information about modes supported on the |
| 759 | attached displays. |
| 760 | </para> |
| 761 | <!--!Edrivers/char/drm/drm_crtc.c--> |
| 762 | </sect1> |
| 763 | |
| 764 | <sect1> |
| 765 | <title>Framebuffer management</title> |
| 766 | <para> |
| 767 | In order to set a mode on a given CRTC, encoder and connector |
| 768 | configuration, clients need to provide a framebuffer object which |
| 769 | will provide a source of pixels for the CRTC to deliver to the encoder(s) |
| 770 | and ultimately the connector(s) in the configuration. A framebuffer |
| 771 | is fundamentally a driver specific memory object, made into an opaque |
| 772 | handle by the DRM addfb function. Once an fb has been created this |
| 773 | way it can be passed to the KMS mode setting routines for use in |
| 774 | a configuration. |
| 775 | </para> |
| 776 | </sect1> |
| 777 | |
| 778 | <sect1> |
| 779 | <title>Command submission & fencing</title> |
| 780 | <para> |
| 781 | This should cover a few device specific command submission |
| 782 | implementations. |
| 783 | </para> |
| 784 | </sect1> |
| 785 | |
| 786 | <sect1> |
| 787 | <title>Suspend/resume</title> |
| 788 | <para> |
| 789 | The DRM core provides some suspend/resume code, but drivers |
| 790 | wanting full suspend/resume support should provide save() and |
| 791 | restore() functions. These will be called at suspend, |
| 792 | hibernate, or resume time, and should perform any state save or |
| 793 | restore required by your device across suspend or hibernate |
| 794 | states. |
| 795 | </para> |
| 796 | </sect1> |
| 797 | |
| 798 | <sect1> |
| 799 | <title>DMA services</title> |
| 800 | <para> |
| 801 | This should cover how DMA mapping etc. is supported by the core. |
| 802 | These functions are deprecated and should not be used. |
| 803 | </para> |
| 804 | </sect1> |
| 805 | </chapter> |
| 806 | |
| 807 | <!-- External interfaces --> |
| 808 | |
| 809 | <chapter id="drmExternals"> |
| 810 | <title>Userland interfaces</title> |
| 811 | <para> |
| 812 | The DRM core exports several interfaces to applications, |
| 813 | generally intended to be used through corresponding libdrm |
| 814 | wrapper functions. In addition, drivers export device specific |
| 815 | interfaces for use by userspace drivers & device aware |
| 816 | applications through ioctls and sysfs files. |
| 817 | </para> |
| 818 | <para> |
| 819 | External interfaces include: memory mapping, context management, |
| 820 | DMA operations, AGP management, vblank control, fence |
| 821 | management, memory management, and output management. |
| 822 | </para> |
| 823 | <para> |
| 824 | Cover generic ioctls and sysfs layout here. Only need high |
| 825 | level info, since man pages will cover the rest. |
| 826 | </para> |
| 827 | </chapter> |
| 828 | |
| 829 | <!-- API reference --> |
| 830 | |
| 831 | <appendix id="drmDriverApi"> |
| 832 | <title>DRM Driver API</title> |
| 833 | <para> |
| 834 | Include auto-generated API reference here (need to reference it |
| 835 | from paragraphs above too). |
| 836 | </para> |
| 837 | </appendix> |
| 838 | |
| 839 | </book> |