diff options
Diffstat (limited to 'Documentation/DocBook')
| -rw-r--r-- | Documentation/DocBook/Makefile | 2 | ||||
| -rw-r--r-- | Documentation/DocBook/drm.tmpl | 839 |
2 files changed, 840 insertions, 1 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 325cfd1d6d99..c7e5dc7e8cb3 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
| @@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ | |||
| 14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ | 14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ |
| 15 | mac80211.xml debugobjects.xml sh.xml regulator.xml \ | 15 | mac80211.xml debugobjects.xml sh.xml regulator.xml \ |
| 16 | alsa-driver-api.xml writing-an-alsa-driver.xml \ | 16 | alsa-driver-api.xml writing-an-alsa-driver.xml \ |
| 17 | tracepoint.xml media.xml | 17 | tracepoint.xml media.xml drm.xml |
| 18 | 18 | ||
| 19 | ### | 19 | ### |
| 20 | # The build process is as follows (targets): | 20 | # The build process is as follows (targets): |
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl new file mode 100644 index 000000000000..7583dc7cf64d --- /dev/null +++ b/Documentation/DocBook/drm.tmpl | |||
| @@ -0,0 +1,839 @@ | |||
| 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 | ||
| 392 | need to set that up at load time as well. How you intialize | ||
| 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 | ||
| 402 | TTM is desireable. TTM also integrates tightly with your | ||
| 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 | ||
| 446 | count for the TTM, which will call your initalization function. | ||
| 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, | ||
| 560 | the new connector is regsitered with sysfs, to make its | ||
| 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 | ||
| 584 | need should provide a DPMS (basically on/off) function, mode fixup | ||
| 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 | ||
| 589 | returing an ideal encoder for a given connector. The core | ||
| 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> | ||
