1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter 2. DRM Internals</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Linux DRM Developer's Guide"><link rel="up" href="drmCore.html" title="Part I. DRM Core"><link rel="prev" href="drmIntroduction.html" title="Chapter 1. Introduction"><link rel="next" href="API-drm-pci-alloc.html" title="drm_pci_alloc"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 2. DRM Internals</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="drmIntroduction.html">Prev</a> </td><th width="60%" align="center">Part I. DRM Core</th><td width="20%" align="right"> <a accesskey="n" href="API-drm-pci-alloc.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="drmInternals"></a>Chapter 2. DRM Internals</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="drmInternals.html#idp1119831828">Driver Initialization</a></span></dt><dd><dl><dt><span class="sect2"><a href="drmInternals.html#idp1119636188">Driver Information</a></span></dt><dt><span class="sect2"><a href="drmInternals.html#idp1119509092">Device Registration</a></span></dt><dt><span class="sect2"><a href="drmInternals.html#idp1122528940">Driver Load</a></span></dt></dl></dd><dt><span class="sect1"><a href="drm-memory-management.html">Memory management</a></span></dt><dd><dl><dt><span class="sect2"><a href="drm-memory-management.html#idp1122551924">The Translation Table Manager (TTM)</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#drm-gem">The Graphics Execution Manager (GEM)</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#idp1122718668">VMA Offset Manager</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#drm-prime-support">PRIME Buffer Sharing</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#idp1122911796">PRIME Function References</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#idp1122987828">DRM MM Range Allocator</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#idp1119448692">DRM MM Range Allocator Function References</a></span></dt><dt><span class="sect2"><a href="drm-memory-management.html#idp1123226860">CMA Helper Functions Reference</a></span></dt></dl></dd><dt><span class="sect1"><a href="drm-mode-setting.html">Mode Setting</a></span></dt><dd><dl><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123353068">Display Modes Function Reference</a></span></dt><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123612996">Atomic Mode Setting Function Reference</a></span></dt><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123785660">Frame Buffer Creation</a></span></dt><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123799668">Dumb Buffer Objects</a></span></dt><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123808604">Output Polling</a></span></dt><dt><span class="sect2"><a href="drm-mode-setting.html#idp1123810164">Locking</a></span></dt></dl></dd><dt><span class="sect1"><a href="drm-kms-init.html">KMS Initialization and Cleanup</a></span></dt><dd><dl><dt><span class="sect2"><a href="drm-kms-init.html#idp1123813300">CRTCs (struct <span class="structname">drm_crtc</span>)</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123834892">Planes (struct <span class="structname">drm_plane</span>)</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123849172">Encoders (struct <span class="structname">drm_encoder</span>)</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123859012">Connectors (struct <span class="structname">drm_connector</span>)</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123892868">Cleanup</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123897460">Output discovery and initialization example</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1123898740">KMS API Functions</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1124538092">KMS Data Structures</a></span></dt><dt><span class="sect2"><a href="drm-kms-init.html#idp1124843020">KMS Locking</a></span></dt></dl></dd><dt><span class="sect1"><a href="ch02s05.html">Mode Setting Helper Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="ch02s05.html#idp1124995876">Helper Functions</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125008132">CRTC Helper Operations</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125018460">Encoder Helper Operations</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125024140">Connector Helper Operations</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125061196">Atomic Modeset Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125415036">Modeset Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125575852">Output Probing Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125647748">fbdev Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125808116">Display Port Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1125934820">Display Port MST Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126139892">MIPI DSI Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126417260">EDID Helper Functions Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126612844">Rectangle Utilities Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126805892">Flip-work Helper Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126875156">HDMI Infoframes Helper Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1126989620">Plane Helper Reference</a></span></dt><dt><span class="sect2"><a href="ch02s05.html#idp1127103124">Tile group</a></span></dt></dl></dd><dt><span class="sect1"><a href="drm-kms-properties.html">KMS Properties</a></span></dt><dd><dl><dt><span class="sect2"><a href="drm-kms-properties.html#idp1127119396">Existing KMS Properties</a></span></dt></dl></dd><dt><span class="sect1"><a href="drm-vertical-blank.html">Vertical Blanking</a></span></dt><dd><dl><dt><span class="sect2"><a href="drm-vertical-blank.html#idp1127382092">Vertical Blanking and Interrupt Handling Functions Reference</a></span></dt></dl></dd><dt><span class="sect1"><a href="ch02s08.html">Open/Close, File Operations and IOCTLs</a></span></dt><dd><dl><dt><span class="sect2"><a href="ch02s08.html#idp1127640468">Open and Close</a></span></dt><dt><span class="sect2"><a href="ch02s08.html#idp1127648684">File Operations</a></span></dt><dt><span class="sect2"><a href="ch02s08.html#idp1127655516">IOCTLs</a></span></dt></dl></dd><dt><span class="sect1"><a href="ch02s09.html">Legacy Support Code</a></span></dt><dd><dl><dt><span class="sect2"><a href="ch02s09.html#idp1127663228">Legacy Suspend/Resume</a></span></dt><dt><span class="sect2"><a href="ch02s09.html#idp1127665524">Legacy DMA Services</a></span></dt></dl></dd></dl></div><p> 2 This chapter documents DRM internals relevant to driver authors 3 and developers working to add support for the latest features to 4 existing drivers. 5 </p><p> 6 First, we go over some typical driver initialization 7 requirements, like setting up command buffers, creating an 8 initial output configuration, and initializing core services. 9 Subsequent sections cover core internals in more detail, 10 providing implementation notes and examples. 11 </p><p> 12 The DRM layer provides several services to graphics drivers, 13 many of them driven by the application interfaces it provides 14 through libdrm, the library that wraps most of the DRM ioctls. 15 These include vblank event handling, memory 16 management, output management, framebuffer management, command 17 submission & fencing, suspend/resume support, and DMA 18 services. 19 </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp1119831828"></a>Driver Initialization</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="drmInternals.html#idp1119636188">Driver Information</a></span></dt><dt><span class="sect2"><a href="drmInternals.html#idp1119509092">Device Registration</a></span></dt><dt><span class="sect2"><a href="drmInternals.html#idp1122528940">Driver Load</a></span></dt></dl></div><p> 20 At the core of every DRM driver is a <span class="structname">drm_driver</span> 21 structure. Drivers typically statically initialize a drm_driver structure, 22 and then pass it to one of the <code class="function">drm_*_init()</code> functions 23 to register it with the DRM subsystem. 24 </p><p> 25 Newer drivers that no longer require a <span class="structname">drm_bus</span> 26 structure can alternatively use the low-level device initialization and 27 registration functions such as <code class="function">drm_dev_alloc()</code> and 28 <code class="function">drm_dev_register()</code> directly. 29 </p><p> 30 The <span class="structname">drm_driver</span> structure contains static 31 information that describes the driver and features it supports, and 32 pointers to methods that the DRM core will call to implement the DRM API. 33 We will first go through the <span class="structname">drm_driver</span> static 34 information fields, and will then describe individual operations in 35 details as they get used in later sections. 36 </p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="idp1119636188"></a>Driver Information</h3></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect3"><a href="drmInternals.html#idp1119636532">Driver Features</a></span></dt><dt><span class="sect3"><a href="drmInternals.html#idp1119850908">Major, Minor and Patchlevel</a></span></dt><dt><span class="sect3"><a href="drmInternals.html#idp1119852892">Name, Description and Date</a></span></dt></dl></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1119636532"></a>Driver Features</h4></div></div></div><p> 37 Drivers inform the DRM core about their requirements and supported 38 features by setting appropriate flags in the 39 <em class="structfield"><code>driver_features</code></em> field. Since those flags 40 influence the DRM core behaviour since registration time, most of them 41 must be set to registering the <span class="structname">drm_driver</span> 42 instance. 43 </p><pre class="synopsis">u32 driver_features;</pre><div class="variablelist"><p class="title"><b>Driver Feature Flags</b></p><dl class="variablelist"><dt><span class="term">DRIVER_USE_AGP</span></dt><dd><p> 44 Driver uses AGP interface, the DRM core will manage AGP resources. 45 </p></dd><dt><span class="term">DRIVER_REQUIRE_AGP</span></dt><dd><p> 46 Driver needs AGP interface to function. AGP initialization failure 47 will become a fatal error. 48 </p></dd><dt><span class="term">DRIVER_PCI_DMA</span></dt><dd><p> 49 Driver is capable of PCI DMA, mapping of PCI DMA buffers to 50 userspace will be enabled. Deprecated. 51 </p></dd><dt><span class="term">DRIVER_SG</span></dt><dd><p> 52 Driver can perform scatter/gather DMA, allocation and mapping of 53 scatter/gather buffers will be enabled. Deprecated. 54 </p></dd><dt><span class="term">DRIVER_HAVE_DMA</span></dt><dd><p> 55 Driver supports DMA, the userspace DMA API will be supported. 56 Deprecated. 57 </p></dd><dt><span class="term">DRIVER_HAVE_IRQ, </span><span class="term">DRIVER_IRQ_SHARED</span></dt><dd><p> 58 DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler 59 managed by the DRM Core. The core will support simple IRQ handler 60 installation when the flag is set. The installation process is 61 described in <a class="xref" href="drmInternals.html#drm-irq-registration" title="IRQ Registration">the section called “IRQ Registration”</a>.</p><p>DRIVER_IRQ_SHARED indicates whether the device & handler 62 support shared IRQs (note that this is required of PCI drivers). 63 </p></dd><dt><span class="term">DRIVER_GEM</span></dt><dd><p> 64 Driver use the GEM memory manager. 65 </p></dd><dt><span class="term">DRIVER_MODESET</span></dt><dd><p> 66 Driver supports mode setting interfaces (KMS). 67 </p></dd><dt><span class="term">DRIVER_PRIME</span></dt><dd><p> 68 Driver implements DRM PRIME buffer sharing. 69 </p></dd><dt><span class="term">DRIVER_RENDER</span></dt><dd><p> 70 Driver supports dedicated render nodes. 71 </p></dd><dt><span class="term">DRIVER_ATOMIC</span></dt><dd><p> 72 Driver supports atomic properties. In this case the driver 73 must implement appropriate obj->atomic_get_property() vfuncs 74 for any modeset objects with driver specific properties. 75 </p></dd></dl></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1119850908"></a>Major, Minor and Patchlevel</h4></div></div></div><pre class="synopsis">int major; 76int minor; 77int patchlevel;</pre><p> 78 The DRM core identifies driver versions by a major, minor and patch 79 level triplet. The information is printed to the kernel log at 80 initialization time and passed to userspace through the 81 DRM_IOCTL_VERSION ioctl. 82 </p><p> 83 The major and minor numbers are also used to verify the requested driver 84 API version passed to DRM_IOCTL_SET_VERSION. When the driver API changes 85 between minor versions, applications can call DRM_IOCTL_SET_VERSION to 86 select a specific version of the API. If the requested major isn't equal 87 to the driver major, or the requested minor is larger than the driver 88 minor, the DRM_IOCTL_SET_VERSION call will return an error. Otherwise 89 the driver's set_version() method will be called with the requested 90 version. 91 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1119852892"></a>Name, Description and Date</h4></div></div></div><pre class="synopsis">char *name; 92char *desc; 93char *date;</pre><p> 94 The driver name is printed to the kernel log at initialization time, 95 used for IRQ registration and passed to userspace through 96 DRM_IOCTL_VERSION. 97 </p><p> 98 The driver description is a purely informative string passed to 99 userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by 100 the kernel. 101 </p><p> 102 The driver date, formatted as YYYYMMDD, is meant to identify the date of 103 the latest modification to the driver. However, as most drivers fail to 104 update it, its value is mostly useless. The DRM core prints it to the 105 kernel log at initialization time and passes it to userspace through the 106 DRM_IOCTL_VERSION ioctl. 107 </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="idp1119509092"></a>Device Registration</h3></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="API-drm-pci-alloc.html"><span class="phrase">drm_pci_alloc</span></a></span><span class="refpurpose"> — 108 Allocate a PCI consistent memory block, for DMA. 109 </span></dt><dt><span class="refentrytitle"><a href="API-drm-pci-free.html"><span class="phrase">drm_pci_free</span></a></span><span class="refpurpose"> — 110 Free a PCI consistent memory block 111 </span></dt><dt><span class="refentrytitle"><a href="API-drm-get-pci-dev.html"><span class="phrase">drm_get_pci_dev</span></a></span><span class="refpurpose"> — 112 Register a PCI device with the DRM subsystem 113 </span></dt><dt><span class="refentrytitle"><a href="API-drm-pci-init.html"><span class="phrase">drm_pci_init</span></a></span><span class="refpurpose"> — 114 Register matching PCI devices with the DRM subsystem 115 </span></dt><dt><span class="refentrytitle"><a href="API-drm-pci-exit.html"><span class="phrase">drm_pci_exit</span></a></span><span class="refpurpose"> — 116 Unregister matching PCI devices from the DRM subsystem 117 </span></dt><dt><span class="refentrytitle"><a href="API-drm-platform-init.html"><span class="phrase">drm_platform_init</span></a></span><span class="refpurpose"> — 118 Register a platform device with the DRM subsystem 119 </span></dt><dt><span class="refentrytitle"><a href="API-drm-put-dev.html"><span class="phrase">drm_put_dev</span></a></span><span class="refpurpose"> — 120 Unregister and release a DRM device 121 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-alloc.html"><span class="phrase">drm_dev_alloc</span></a></span><span class="refpurpose"> — 122 Allocate new DRM device 123 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-ref.html"><span class="phrase">drm_dev_ref</span></a></span><span class="refpurpose"> — 124 Take reference of a DRM device 125 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-unref.html"><span class="phrase">drm_dev_unref</span></a></span><span class="refpurpose"> — 126 Drop reference of a DRM device 127 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-register.html"><span class="phrase">drm_dev_register</span></a></span><span class="refpurpose"> — 128 Register DRM device 129 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-unregister.html"><span class="phrase">drm_dev_unregister</span></a></span><span class="refpurpose"> — 130 Unregister DRM device 131 </span></dt><dt><span class="refentrytitle"><a href="API-drm-dev-set-unique.html"><span class="phrase">drm_dev_set_unique</span></a></span><span class="refpurpose"> — 132 Set the unique name of a DRM device 133 </span></dt></dl></div><p> 134 A number of functions are provided to help with device registration. 135 The functions deal with PCI and platform devices, respectively. 136 </p><p> 137 New drivers that no longer rely on the services provided by the 138 <span class="structname">drm_bus</span> structure can call the low-level 139 device registration functions directly. The 140 <code class="function">drm_dev_alloc()</code> function can be used to allocate 141 and initialize a new <span class="structname">drm_device</span> structure. 142 Drivers will typically want to perform some additional setup on this 143 structure, such as allocating driver-specific data and storing a 144 pointer to it in the DRM device's <em class="structfield"><code>dev_private</code></em> 145 field. Drivers should also set the device's unique name using the 146 <code class="function">drm_dev_set_unique()</code> function. After it has been 147 set up a device can be registered with the DRM subsystem by calling 148 <code class="function">drm_dev_register()</code>. This will cause the device to 149 be exposed to userspace and will call the driver's 150 <em class="structfield"><code>.load()</code></em> implementation. When a device is 151 removed, the DRM device can safely be unregistered and freed by calling 152 <code class="function">drm_dev_unregister()</code> followed by a call to 153 <code class="function">drm_dev_unref()</code>. 154 </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="idp1122528940"></a>Driver Load</h3></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect3"><a href="drmInternals.html#idp1122534228">Driver Private Data</a></span></dt><dt><span class="sect3"><a href="drmInternals.html#drm-irq-registration">IRQ Registration</a></span></dt><dt><span class="sect3"><a href="drmInternals.html#idp1122545436">Memory Manager Initialization</a></span></dt><dt><span class="sect3"><a href="drmInternals.html#idp1122546636">Miscellaneous Device Configuration</a></span></dt></dl></div><p> 155 The <code class="methodname">load</code> method is the driver and device 156 initialization entry point. The method is responsible for allocating and 157 initializing driver private data, performing resource allocation and 158 mapping (e.g. acquiring 159 clocks, mapping registers or allocating command buffers), initializing 160 the memory manager (<a class="xref" href="drm-memory-management.html" title="Memory management">the section called “Memory management”</a>), installing 161 the IRQ handler (<a class="xref" href="drmInternals.html#drm-irq-registration" title="IRQ Registration">the section called “IRQ Registration”</a>), setting up 162 vertical blanking handling (<a class="xref" href="drm-vertical-blank.html" title="Vertical Blanking">the section called “Vertical Blanking”</a>), mode 163 setting (<a class="xref" href="drm-mode-setting.html" title="Mode Setting">the section called “Mode Setting”</a>) and initial output 164 configuration (<a class="xref" href="drm-kms-init.html" title="KMS Initialization and Cleanup">the section called “KMS Initialization and Cleanup”</a>). 165 </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p> 166 If compatibility is a concern (e.g. with drivers converted over from 167 User Mode Setting to Kernel Mode Setting), care must be taken to prevent 168 device initialization and control that is incompatible with currently 169 active userspace drivers. For instance, if user level mode setting 170 drivers are in use, it would be problematic to perform output discovery 171 & configuration at load time. Likewise, if user-level drivers 172 unaware of memory management are in use, memory management and command 173 buffer setup may need to be omitted. These requirements are 174 driver-specific, and care needs to be taken to keep both old and new 175 applications and libraries working. 176 </p></div><pre class="synopsis">int (*load) (struct drm_device *, unsigned long flags);</pre><p> 177 The method takes two arguments, a pointer to the newly created 178 <span class="structname">drm_device</span> and flags. The flags are used to 179 pass the <em class="structfield"><code>driver_data</code></em> field of the device id 180 corresponding to the device passed to <code class="function">drm_*_init()</code>. 181 Only PCI devices currently use this, USB and platform DRM drivers have 182 their <code class="methodname">load</code> method called with flags to 0. 183 </p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1122534228"></a>Driver Private Data</h4></div></div></div><p> 184 The driver private hangs off the main 185 <span class="structname">drm_device</span> structure and can be used for 186 tracking various device-specific bits of information, like register 187 offsets, command buffer status, register state for suspend/resume, etc. 188 At load time, a driver may simply allocate one and set 189 <span class="structname">drm_device</span>.<em class="structfield"><code>dev_priv</code></em> 190 appropriately; it should be freed and 191 <span class="structname">drm_device</span>.<em class="structfield"><code>dev_priv</code></em> 192 set to NULL when the driver is unloaded. 193 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="drm-irq-registration"></a>IRQ Registration</h4></div></div></div><p> 194 The DRM core tries to facilitate IRQ handler registration and 195 unregistration by providing <code class="function">drm_irq_install</code> and 196 <code class="function">drm_irq_uninstall</code> functions. Those functions only 197 support a single interrupt per device, devices that use more than one 198 IRQs need to be handled manually. 199 </p><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a name="idp1122537788"></a>Managed IRQ Registration</h5></div></div></div><p> 200 <code class="function">drm_irq_install</code> starts by calling the 201 <code class="methodname">irq_preinstall</code> driver operation. The operation 202 is optional and must make sure that the interrupt will not get fired by 203 clearing all pending interrupt flags or disabling the interrupt. 204 </p><p> 205 The passed-in IRQ will then be requested by a call to 206 <code class="function">request_irq</code>. If the DRIVER_IRQ_SHARED driver 207 feature flag is set, a shared (IRQF_SHARED) IRQ handler will be 208 requested. 209 </p><p> 210 The IRQ handler function must be provided as the mandatory irq_handler 211 driver operation. It will get passed directly to 212 <code class="function">request_irq</code> and thus has the same prototype as all 213 IRQ handlers. It will get called with a pointer to the DRM device as the 214 second argument. 215 </p><p> 216 Finally the function calls the optional 217 <code class="methodname">irq_postinstall</code> driver operation. The operation 218 usually enables interrupts (excluding the vblank interrupt, which is 219 enabled separately), but drivers may choose to enable/disable interrupts 220 at a different time. 221 </p><p> 222 <code class="function">drm_irq_uninstall</code> is similarly used to uninstall an 223 IRQ handler. It starts by waking up all processes waiting on a vblank 224 interrupt to make sure they don't hang, and then calls the optional 225 <code class="methodname">irq_uninstall</code> driver operation. The operation 226 must disable all hardware interrupts. Finally the function frees the IRQ 227 by calling <code class="function">free_irq</code>. 228 </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a name="idp1122542796"></a>Manual IRQ Registration</h5></div></div></div><p> 229 Drivers that require multiple interrupt handlers can't use the managed 230 IRQ registration functions. In that case IRQs must be registered and 231 unregistered manually (usually with the <code class="function">request_irq</code> 232 and <code class="function">free_irq</code> functions, or their devm_* equivalent). 233 </p><p> 234 When manually registering IRQs, drivers must not set the DRIVER_HAVE_IRQ 235 driver feature flag, and must not provide the 236 <code class="methodname">irq_handler</code> driver operation. They must set the 237 <span class="structname">drm_device</span> <em class="structfield"><code>irq_enabled</code></em> 238 field to 1 upon registration of the IRQs, and clear it to 0 after 239 unregistering the IRQs. 240 </p></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1122545436"></a>Memory Manager Initialization</h4></div></div></div><p> 241 Every DRM driver requires a memory manager which must be initialized at 242 load time. DRM currently contains two memory managers, the Translation 243 Table Manager (TTM) and the Graphics Execution Manager (GEM). 244 This document describes the use of the GEM memory manager only. See 245 <a class="xref" href="drm-memory-management.html" title="Memory management">the section called “Memory management”</a> for details. 246 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp1122546636"></a>Miscellaneous Device Configuration</h4></div></div></div><p> 247 Another task that may be necessary for PCI devices during configuration 248 is mapping the video BIOS. On many devices, the VBIOS describes device 249 configuration, LCD panel timings (if any), and contains flags indicating 250 device state. Mapping the BIOS can be done using the pci_map_rom() call, 251 a convenience function that takes care of mapping the actual ROM, 252 whether it has been shadowed into memory (typically at address 0xc0000) 253 or exists on the PCI device in the ROM BAR. Note that after the ROM has 254 been mapped and any necessary information has been extracted, it should 255 be unmapped; on many devices, the ROM address decoder is shared with 256 other BARs, so leaving it mapped could cause undesired behaviour like 257 hangs or memory corruption. 258 259 </p></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="drmIntroduction.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="drmCore.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="API-drm-pci-alloc.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> <span class="phrase">drm_pci_alloc</span></td></tr></table></div></body></html> 260