<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>drm/i915 Intel GFX Driver — The Linux Kernel documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=3918102e" />
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="drm/imagination PowerVR Graphics Driver" href="imagination/index.html" />
<link rel="prev" title="AMDGPU Glossary" href="amdgpu/amdgpu-glossary.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.svg" alt="Logo of The Linux Kernel"/>
</a></p>
<h1 class="logo"><a href="../index.html">The Linux Kernel</a></h1>
<p class="blurb">6.18.50</p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>
<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#core-subsystems">Core subsystems</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../subsystem-apis.html#human-interfaces">Human interfaces</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../input/index.html">Input Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../hid/index.html">Human Interface Devices (HID)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../sound/index.html">Sound Subsystem Documentation</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="index.html">GPU Driver Developer’s Guide</a></li>
<li class="toctree-l3"><a class="reference internal" href="../fb/index.html">Frame Buffer</a></li>
<li class="toctree-l3"><a class="reference internal" href="../leds/index.html">LEDs</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#networking-interfaces">Networking interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#other-subsystems">Other subsystems</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../translations/index.html">Translations</a></li>
</ul>
</div>
<script type="text/javascript"> <!--
var sbar = document.getElementsByClassName("sphinxsidebar")[0];
let currents = document.getElementsByClassName("current")
if (currents.length) {
sbar.scrollTop = currents[currents.length - 1].offsetTop;
}
--> </script>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/gpu/i915.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
</div>
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="drm-i915-intel-gfx-driver">
<h1>drm/i915 Intel GFX Driver<a class="headerlink" href="#drm-i915-intel-gfx-driver" title="Link to this heading">¶</a></h1>
<p>The drm/i915 driver supports all (with the exception of some very early
models) integrated GFX chipsets with both Intel display and rendering
blocks. This excludes a set of SoC platforms with an SGX rendering unit,
those have basic support through the gma500 drm driver.</p>
<section id="core-driver-infrastructure">
<h2>Core Driver Infrastructure<a class="headerlink" href="#core-driver-infrastructure" title="Link to this heading">¶</a></h2>
<p>This section covers core driver infrastructure used by both the display
and the GEM parts of the driver.</p>
<section id="runtime-power-management">
<h3>Runtime Power Management<a class="headerlink" href="#runtime-power-management" title="Link to this heading">¶</a></h3>
<p>The i915 driver supports dynamic enabling and disabling of entire hardware
blocks at runtime. This is especially important on the display side where
software is supposed to control many power gates manually on recent hardware,
since on the GT side a lot of the power management is done by the hardware.
But even there some manual control at the device level is required.</p>
<p>Since i915 supports a diverse set of platforms with a unified codebase and
hardware engineers just love to shuffle functionality around between power
domains there’s a sizeable amount of indirection required. This file provides
generic functions to the driver for grabbing and releasing references for
abstract power domains. It then maps those to the actual power wells
present for a given platform.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_get_raw">
<span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_get_raw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_get_raw" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab a raw runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is the unlocked version of <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_display_power_is_enabled()</span></code> and should
only be used from error capture and recovery code where deadlocks are
possible.
This function grabs a device-level runtime pm reference (mostly used for
asynchronous PM management from display code) and ensures that it is powered
up. Raw references are not considered during wakelock assert checks.</p>
<p>Any runtime pm reference obtained by this function must have a symmetric
call to <a class="reference internal" href="#c.intel_runtime_pm_put_raw" title="intel_runtime_pm_put_raw"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put_raw()</span></code></a> to release the reference again.</p>
<p><strong>Return</strong></p>
<p>the wakeref cookie to pass to <a class="reference internal" href="#c.intel_runtime_pm_put_raw" title="intel_runtime_pm_put_raw"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put_raw()</span></code></a>, evaluates
as True if the wakeref was acquired, or False otherwise.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_get">
<span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_get</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_get" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab a runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function grabs a device-level runtime pm reference (mostly used for GEM
code to ensure the GTT or GT is on) and ensures that it is powered up.</p>
<p>Any runtime pm reference obtained by this function must have a symmetric
call to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a> to release the reference again.</p>
<p><strong>Return</strong></p>
<p>the wakeref cookie to pass to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a></p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.__intel_runtime_pm_get_if_active">
<span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">__intel_runtime_pm_get_if_active</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">ignore_usecount</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.__intel_runtime_pm_get_if_active" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab a runtime pm reference if device is active</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">ignore_usecount</span></code></dt><dd><p>get a ref even if dev->power.usage_count is 0</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function grabs a device-level runtime pm reference if the device is
already active and ensures that it is powered up. It is illegal to try
and access the HW should <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_runtime_pm_get_if_active()</span></code> report failure.</p>
<p>If <strong>ignore_usecount</strong> is true, a reference will be acquired even if there is no
user requiring the device to be powered up (dev->power.usage_count == 0).
If the function returns false in this case then it’s guaranteed that the
device’s runtime suspend hook has been called already or that it will be
called (and hence it’s also guaranteed that the device’s runtime resume
hook will be called eventually).</p>
<p>Any runtime pm reference obtained by this function must have a symmetric
call to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a> to release the reference again.</p>
<p><strong>Return</strong></p>
<p>the wakeref cookie to pass to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a>, evaluates
as True if the wakeref was acquired, or False otherwise.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_get_noresume">
<span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_get_noresume</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_get_noresume" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab a runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function grabs a device-level runtime pm reference.</p>
<p>It will _not_ resume the device but instead only get an extra wakeref.
Therefore it is only valid to call this functions from contexts where
the device is known to be active and with another wakeref previously hold.</p>
<p>Any runtime pm reference obtained by this function must have a symmetric
call to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a> to release the reference again.</p>
<p><strong>Return</strong></p>
<p>the wakeref cookie to pass to <a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a></p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_put_raw">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_put_raw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span>, <span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="n"><span class="pre">wref</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_put_raw" title="Link to this definition">¶</a><br /></dt>
<dd><p>release a raw runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">intel_wakeref_t</span> <span class="pre">wref</span></code></dt><dd><p>wakeref acquired for the reference that is being released</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function drops the device-level runtime pm reference obtained by
<a class="reference internal" href="#c.intel_runtime_pm_get_raw" title="intel_runtime_pm_get_raw"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_get_raw()</span></code></a> and might power down the corresponding
hardware block right away if this is the last reference.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_put_unchecked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_put_unchecked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_put_unchecked" title="Link to this definition">¶</a><br /></dt>
<dd><p>release an unchecked runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function drops the device-level runtime pm reference obtained by
<a class="reference internal" href="#c.intel_runtime_pm_get" title="intel_runtime_pm_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_get()</span></code></a> and might power down the corresponding
hardware block right away if this is the last reference.</p>
<p>This function exists only for historical reasons and should be avoided in
new code, as the correctness of its use cannot be checked. Always use
<a class="reference internal" href="#c.intel_runtime_pm_put" title="intel_runtime_pm_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_put()</span></code></a> instead.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_put">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_put</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span>, <span class="n"><span class="pre">intel_wakeref_t</span></span><span class="w"> </span><span class="n"><span class="pre">wref</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_put" title="Link to this definition">¶</a><br /></dt>
<dd><p>release a runtime pm reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">intel_wakeref_t</span> <span class="pre">wref</span></code></dt><dd><p>wakeref acquired for the reference that is being released</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function drops the device-level runtime pm reference obtained by
<a class="reference internal" href="#c.intel_runtime_pm_get" title="intel_runtime_pm_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_runtime_pm_get()</span></code></a> and might power down the corresponding
hardware block right away if this is the last reference.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_runtime_pm_enable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_runtime_pm_enable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_runtime_pm</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">rpm</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_runtime_pm_enable" title="Link to this definition">¶</a><br /></dt>
<dd><p>enable runtime pm</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_runtime_pm</span> <span class="pre">*rpm</span></code></dt><dd><p>the intel_runtime_pm structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function enables runtime pm at the end of the driver load sequence.</p>
<p>Note that this function does currently not enable runtime pm for the
subordinate display power domains. That is done by
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_power_domains_enable()</span></code>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_get">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_get</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="n"><span class="pre">fw_domains</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_get" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab forcewake domain references</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">forcewake_domains</span> <span class="pre">fw_domains</span></code></dt><dd><p>forcewake domains to get reference on</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function can be used get GT’s forcewake domain references.
Normal register access will handle the forcewake domains automatically.
However if some sequence requires the GT to not power down a particular
forcewake domains this function should be called at the beginning of the
sequence. And subsequently the reference should be dropped by symmetric
call to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_unforce_forcewake_put()</span></code>. Usually caller wants all the domains
to be kept awake so the <strong>fw_domains</strong> would be then FORCEWAKE_ALL.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_user_get">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_user_get</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_user_get" title="Link to this definition">¶</a><br /></dt>
<dd><p>claim forcewake on behalf of userspace</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is a wrapper around <a class="reference internal" href="#c.intel_uncore_forcewake_get" title="intel_uncore_forcewake_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_uncore_forcewake_get()</span></code></a> to acquire
the GT powerwell and in the process disable our debugging for the
duration of userspace’s bypass.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_user_put">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_user_put</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_user_put" title="Link to this definition">¶</a><br /></dt>
<dd><p>release forcewake on behalf of userspace</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function complements <a class="reference internal" href="#c.intel_uncore_forcewake_user_get" title="intel_uncore_forcewake_user_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_uncore_forcewake_user_get()</span></code></a> and releases
the GT powerwell taken on behalf of the userspace bypass.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_get__locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_get__locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="n"><span class="pre">fw_domains</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_get__locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab forcewake domain references</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">forcewake_domains</span> <span class="pre">fw_domains</span></code></dt><dd><p>forcewake domains to get reference on</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>See <a class="reference internal" href="#c.intel_uncore_forcewake_get" title="intel_uncore_forcewake_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_uncore_forcewake_get()</span></code></a>. This variant places the onus
on the caller to explicitly handle the dev_priv->uncore.lock spinlock.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_put">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_put</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="n"><span class="pre">fw_domains</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_put" title="Link to this definition">¶</a><br /></dt>
<dd><p>release a forcewake domain reference</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">forcewake_domains</span> <span class="pre">fw_domains</span></code></dt><dd><p>forcewake domains to put references</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function drops the device-level forcewakes for specified
domains obtained by <a class="reference internal" href="#c.intel_uncore_forcewake_get" title="intel_uncore_forcewake_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_uncore_forcewake_get()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="n"><span class="pre">fw_domains</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>flush the delayed release</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">forcewake_domains</span> <span class="pre">fw_domains</span></code></dt><dd><p>forcewake domains to flush</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_put__locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_put__locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="n"><span class="pre">fw_domains</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_put__locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>release forcewake domain references</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the intel_uncore structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">forcewake_domains</span> <span class="pre">fw_domains</span></code></dt><dd><p>forcewake domains to put references</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>See <a class="reference internal" href="#c.intel_uncore_forcewake_put" title="intel_uncore_forcewake_put"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_uncore_forcewake_put()</span></code></a>. This variant places the onus
on the caller to explicitly handle the dev_priv->uncore.lock spinlock.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.__intel_wait_for_register_fw">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">__intel_wait_for_register_fw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="n"><span class="pre">i915_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">mask</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">fast_timeout_us</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">slow_timeout_ms</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">out_value</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.__intel_wait_for_register_fw" title="Link to this definition">¶</a><br /></dt>
<dd><p>wait until register matches expected state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the register to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">mask</span></code></dt><dd><p>mask to apply to register value</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>expected value</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">fast_timeout_us</span></code></dt><dd><p>fast timeout in microsecond for atomic/tight wait</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">slow_timeout_ms</span></code></dt><dd><p>slow timeout in millisecond</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">*out_value</span></code></dt><dd><p>optional placeholder to hold registry value</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This routine waits until the target register <strong>reg</strong> contains the expected
<strong>value</strong> after applying the <strong>mask</strong>, i.e. it waits until</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>(intel_uncore_read_fw(uncore, reg) & mask) == value
</pre></div>
</div>
<p>Otherwise, the wait will timeout after <strong>slow_timeout_ms</strong> milliseconds.
For atomic context <strong>slow_timeout_ms</strong> must be zero and <strong>fast_timeout_us</strong>
must be not larger than 20,0000 microseconds.</p>
<p>Note that this routine assumes the caller holds forcewake asserted, it is
not suitable for very long waits. See <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_wait_for_register()</span></code> if you
wish to wait without holding forcewake for the duration (i.e. you expect
the wait to be slow).</p>
<p><strong>Return</strong></p>
<p>0 if the register matches the desired condition, or -ETIMEDOUT.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.__intel_wait_for_register">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">__intel_wait_for_register</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="n"><span class="pre">i915_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">mask</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">fast_timeout_us</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">slow_timeout_ms</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">out_value</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.__intel_wait_for_register" title="Link to this definition">¶</a><br /></dt>
<dd><p>wait until register matches expected state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>the <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the register to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">mask</span></code></dt><dd><p>mask to apply to register value</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>expected value</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">fast_timeout_us</span></code></dt><dd><p>fast timeout in microsecond for atomic/tight wait</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">slow_timeout_ms</span></code></dt><dd><p>slow timeout in millisecond</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">*out_value</span></code></dt><dd><p>optional placeholder to hold registry value</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This routine waits until the target register <strong>reg</strong> contains the expected
<strong>value</strong> after applying the <strong>mask</strong>, i.e. it waits until</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>(intel_uncore_read(uncore, reg) & mask) == value
</pre></div>
</div>
<p>Otherwise, the wait will timeout after <strong>timeout_ms</strong> milliseconds.</p>
<p><strong>Return</strong></p>
<p>0 if the register matches the desired condition, or -ETIMEDOUT.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_uncore_forcewake_for_reg">
<span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">forcewake_domains</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_uncore_forcewake_for_reg</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_uncore</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uncore</span></span>, <span class="n"><span class="pre">i915_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">op</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_uncore_forcewake_for_reg" title="Link to this definition">¶</a><br /></dt>
<dd><p>which forcewake domains are needed to access a register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span> <span class="pre">*uncore</span></code></dt><dd><p>pointer to <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_uncore</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>register in question</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">op</span></code></dt><dd><p>operation bitmask of FW_REG_READ and/or FW_REG_WRITE</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Returns a set of forcewake domains required to be taken with for example
intel_uncore_forcewake_get for the specified register to be accessible in the
specified mode (read, write or read/write) with raw mmio accessors.</p>
<p><strong>NOTE</strong></p>
<p>On Gen6 and Gen7 write forcewake domain (FORCEWAKE_RENDER) requires the
callers to do FIFO management on their own or risk losing writes.</p>
</div>
</section>
<section id="interrupt-handling">
<h3>Interrupt Handling<a class="headerlink" href="#interrupt-handling" title="Link to this heading">¶</a></h3>
<p>These functions provide the basic support for enabling and disabling the
interrupt handling support. There’s a lot more functionality in i915_irq.c
and related files, but that will be described in separate chapters.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_irq_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_irq_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_irq_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initializes irq support</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function initializes all the irq support including work items, timers
and all the vtables. It does not setup the interrupt itself though.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_irq_suspend">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_irq_suspend</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_irq_suspend" title="Link to this definition">¶</a><br /></dt>
<dd><p>Suspend interrupts</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is used to disable interrupts at runtime.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_irq_resume">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_irq_resume</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_irq_resume" title="Link to this definition">¶</a><br /></dt>
<dd><p>Resume interrupts</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is used to enable interrupts at runtime.</p>
</div>
</section>
<section id="intel-gvt-g-guest-support-vgpu">
<h3>Intel GVT-g Guest Support(vGPU)<a class="headerlink" href="#intel-gvt-g-guest-support-vgpu" title="Link to this heading">¶</a></h3>
<p>Intel GVT-g is a graphics virtualization technology which shares the
GPU among multiple virtual machines on a time-sharing basis. Each
virtual machine is presented a virtual GPU (vGPU), which has equivalent
features as the underlying physical GPU (pGPU), so i915 driver can run
seamlessly in a virtual machine. This file provides vGPU specific
optimizations when running in a virtual machine, to reduce the complexity
of vGPU emulation and to improve the overall performance.</p>
<p>A primary function introduced here is so-called “address space ballooning”
technique. Intel GVT-g partitions global graphics memory among multiple VMs,
so each VM can directly access a portion of the memory without hypervisor’s
intervention, e.g. filling textures or queuing commands. However with the
partitioning an unmodified i915 driver would assume a smaller graphics
memory starting from address ZERO, then requires vGPU emulation module to
translate the graphics address between ‘guest view’ and ‘host view’, for
all registers and command opcodes which contain a graphics memory address.
To reduce the complexity, Intel GVT-g introduces “address space ballooning”,
by telling the exact partitioning knowledge to each guest i915 driver, which
then reserves and prevents non-allocated portions from allocation. Thus vGPU
emulation module only needs to scan and validate graphics addresses without
complexity of address translation.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_vgpu_detect">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_vgpu_detect</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_vgpu_detect" title="Link to this definition">¶</a><br /></dt>
<dd><p>detect virtual GPU</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>i915 device private</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the initialization stage, to detect whether
running on a vGPU.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_vgt_deballoon">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_vgt_deballoon</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_ggtt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ggtt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_vgt_deballoon" title="Link to this definition">¶</a><br /></dt>
<dd><p>deballoon reserved graphics address trunks</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_ggtt</span> <span class="pre">*ggtt</span></code></dt><dd><p>the global GGTT from which we reserved earlier</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called to deallocate the ballooned-out graphic memory, when
driver is unloaded or when ballooning fails.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_vgt_balloon">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_vgt_balloon</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_ggtt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ggtt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_vgt_balloon" title="Link to this definition">¶</a><br /></dt>
<dd><p>balloon out reserved graphics address trunks</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_ggtt</span> <span class="pre">*ggtt</span></code></dt><dd><p>the global GGTT from which to reserve</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the initialization stage, to balloon out the
graphic address space allocated to other vGPUs, by marking these spaces as
reserved. The ballooning related knowledge(starting address and size of
the mappable/unmappable graphic memory) is described in the vgt_if structure
in a reserved mmio range.</p>
<p>To give an example, the drawing below depicts one typical scenario after
ballooning. Here the vGPU1 has 2 pieces of graphic address spaces ballooned
out each for the mappable and the non-mappable part. From the vGPU1 point of
view, the total size is the same as the physical one, with the start address
of its graphic space being zero. Yet there are some portions ballooned out(
the shadow part, which are marked as reserved by drm allocator). From the
host point of view, the graphic address space is partitioned by multiple
vGPUs in different VMs.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> vGPU1 view Host view
0 ------> +-----------+ +-----------+
^ |###########| | vGPU3 |
| |###########| +-----------+
| |###########| | vGPU2 |
| +-----------+ +-----------+
mappable GM | available | ==> | vGPU1 |
| +-----------+ +-----------+
| |###########| | |
v |###########| | Host |
+=======+===========+ +===========+
^ |###########| | vGPU3 |
| |###########| +-----------+
| |###########| | vGPU2 |
| +-----------+ +-----------+
unmappable GM | available | ==> | vGPU1 |
| +-----------+ +-----------+
| |###########| | |
| |###########| | Host |
v |###########| | |
total GM size ------> +-----------+ +-----------+
</pre></div>
</div>
<p><strong>Return</strong></p>
<p>zero on success, non-zero if configuration invalid or ballooning failed</p>
</div>
</section>
<section id="intel-gvt-g-host-support-vgpu-device-model">
<h3>Intel GVT-g Host Support(vGPU device model)<a class="headerlink" href="#intel-gvt-g-host-support-vgpu-device-model" title="Link to this heading">¶</a></h3>
<p>Intel GVT-g is a graphics virtualization technology which shares the
GPU among multiple virtual machines on a time-sharing basis. Each
virtual machine is presented a virtual GPU (vGPU), which has equivalent
features as the underlying physical GPU (pGPU), so i915 driver can run
seamlessly in a virtual machine.</p>
<p>To virtualize GPU resources GVT-g driver depends on hypervisor technology
e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping capability
and be virtualized within GVT-g device module. More architectural design
doc is available on <a class="reference external" href="https://github.com/intel/gvt-linux/wiki">https://github.com/intel/gvt-linux/wiki</a>.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gvt_init">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gvt_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gvt_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initialize GVT components</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>drm i915 private data</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the initialization stage to create a GVT device.</p>
<p><strong>Return</strong></p>
<p>Zero on success, negative error code if failed.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gvt_driver_remove">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gvt_driver_remove</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gvt_driver_remove" title="Link to this definition">¶</a><br /></dt>
<dd><p>cleanup GVT components when i915 driver is unbinding</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>drm i915 private *</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the i915 driver unloading stage, to shutdown
GVT components and release the related resources.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gvt_resume">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gvt_resume</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gvt_resume" title="Link to this definition">¶</a><br /></dt>
<dd><p>GVT resume routine wrapper</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>drm i915 private *</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the i915 driver resume stage to restore required
HW status for GVT so that vGPU can continue running after resumed.</p>
</div>
</section>
<section id="workarounds">
<h3>Workarounds<a class="headerlink" href="#workarounds" title="Link to this heading">¶</a></h3>
<p>Hardware workarounds are register programming documented to be executed in
the driver that fall outside of the normal programming sequences for a
platform. There are some basic categories of workarounds, depending on
how/when they are applied:</p>
<ul>
<li><p>Context workarounds: workarounds that touch registers that are
saved/restored to/from the HW context image. The list is emitted (via Load
Register Immediate commands) once when initializing the device and saved in
the default context. That default context is then used on every context
creation to have a “primed golden context”, i.e. a context image that
already contains the changes needed to all the registers.</p>
<p>Context workarounds should be implemented in the *<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_ctx_workarounds_init()</span></code>
variants respective to the targeted platforms.</p>
</li>
<li><p>Engine workarounds: the list of these WAs is applied whenever the specific
engine is reset. It’s also possible that a set of engine classes share a
common power domain and they are reset together. This happens on some
platforms with render and compute engines. In this case (at least) one of
them need to keeep the workaround programming: the approach taken in the
driver is to tie those workarounds to the first compute/render engine that
is registered. When executing with GuC submission, engine resets are
outside of kernel driver control, hence the list of registers involved in
written once, on engine initialization, and then passed to GuC, that
saves/restores their values before/after the reset takes place. See
<code class="docutils literal notranslate"><span class="pre">drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c</span></code> for reference.</p>
<p>Workarounds for registers specific to RCS and CCS should be implemented in
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rcs_engine_wa_init()</span></code> and <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">ccs_engine_wa_init()</span></code>, respectively; those for
registers belonging to BCS, VCS or VECS should be implemented in
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">xcs_engine_wa_init()</span></code>. Workarounds for registers not belonging to a specific
engine’s MMIO range but that are part of of the common RCS/CCS reset domain
should be implemented in <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">general_render_compute_wa_init()</span></code>. The settings
about the CCS load balancing should be added in <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">ccs_engine_wa_mode()</span></code>.</p>
</li>
<li><p>GT workarounds: the list of these WAs is applied whenever these registers
revert to their default values: on GPU reset, suspend/resume <a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>, etc.</p>
<p>GT workarounds should be implemented in the *<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_gt_workarounds_init()</span></code>
variants respective to the targeted platforms.</p>
</li>
<li><p>Register whitelist: some workarounds need to be implemented in userspace,
but need to touch privileged registers. The whitelist in the kernel
instructs the hardware to allow the access to happen. From the kernel side,
this is just a special case of a MMIO workaround (as we write the list of
these to/be-whitelisted registers to some special HW registers).</p>
<p>Register whitelisting should be done in the *<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_whitelist_build()</span></code> variants
respective to the targeted platforms.</p>
</li>
<li><p>Workaround batchbuffers: buffers that get executed automatically by the
hardware on every HW context restore. These buffers are created and
programmed in the default context so the hardware always go through those
programming sequences when switching contexts. The support for workaround
batchbuffers is enabled these hardware mechanisms:</p>
<ol class="arabic simple">
<li><p>INDIRECT_CTX: A batchbuffer and an offset are provided in the default
context, pointing the hardware to jump to that location when that offset
is reached in the context restore. Workaround batchbuffer in the driver
currently uses this mechanism for all platforms.</p></li>
<li><p>BB_PER_CTX_PTR: A batchbuffer is provided in the default context,
pointing the hardware to a buffer to continue executing after the
engine registers are restored in a context restore sequence. This is
currently not used in the driver.</p></li>
</ol>
</li>
<li><p>Other: There are WAs that, due to their nature, cannot be applied from a
central place. Those are peppered around the rest of the code, as needed.
Workarounds related to the display IP are the main example.</p></li>
</ul>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id2" role="doc-footnote">
<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id1">1</a><span class="fn-bracket">]</span></span>
<p>Technically, some registers are powercontext saved & restored, so they
survive a suspend/resume. In practice, writing them again is not too
costly and simplifies things, so it’s the approach taken in the driver.</p>
</aside>
</aside>
</section>
</section>
<section id="display-hardware-handling">
<h2>Display Hardware Handling<a class="headerlink" href="#display-hardware-handling" title="Link to this heading">¶</a></h2>
<p>This section covers everything related to the display hardware including
the mode setting infrastructure, plane, sprite and cursor handling and
display, output probing and related topics.</p>
<section id="mode-setting-infrastructure">
<h3>Mode Setting Infrastructure<a class="headerlink" href="#mode-setting-infrastructure" title="Link to this heading">¶</a></h3>
<p>The i915 driver is thus far the only DRM driver which doesn’t use the
common DRM helper code to implement mode setting sequences. Thus it has
its own tailor-made infrastructure for executing a display configuration
change.</p>
</section>
<section id="frontbuffer-tracking">
<h3>Frontbuffer Tracking<a class="headerlink" href="#frontbuffer-tracking" title="Link to this heading">¶</a></h3>
<p>Many features require us to track changes to the currently active
frontbuffer, especially rendering targeted at the frontbuffer.</p>
<p>To be able to do so we track frontbuffers using a bitmask for all possible
frontbuffer slots through <a class="reference internal" href="#c.intel_frontbuffer_track" title="intel_frontbuffer_track"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_frontbuffer_track()</span></code></a>. The functions in this
file are then called when the contents of the frontbuffer are invalidated,
when frontbuffer rendering has stopped again to flush out all the changes
and when the frontbuffer is exchanged with a flip. Subsystems interested in
frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks
into the relevant places and filter for the frontbuffer slots that they are
interested int.</p>
<p>On a high level there are two types of powersaving features. The first one
work like a special cache (FBC and PSR) and are interested when they should
stop caching and when to restart caching. This is done by placing callbacks
into the invalidate and the flush functions: At invalidate the caching must
be stopped and at flush time it can be restarted. And maybe they need to know
when the frontbuffer changes (e.g. when the hw doesn’t initiate an invalidate
and flush on its own) which can be achieved with placing callbacks into the
flip functions.</p>
<p>The other type of display power saving feature only cares about busyness
(e.g. DRRS). In that case all three (invalidate, flush and flip) indicate
busyness. There is no direct way to detect idleness. Instead an idle timer
work delayed work should be started from the flush and flip functions and
cancelled as soon as busyness is detected.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_invalidate">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_invalidate</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_frontbuffer</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">front</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">fb_op_origin</span></span><span class="w"> </span><span class="n"><span class="pre">origin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_invalidate" title="Link to this definition">¶</a><br /></dt>
<dd><p>invalidate frontbuffer object</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_frontbuffer</span> <span class="pre">*front</span></code></dt><dd><p>GEM object to invalidate</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">fb_op_origin</span> <span class="pre">origin</span></code></dt><dd><p>which operation caused the invalidation</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called every time rendering on the given object starts and
frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed
until the rendering completes or a flip on this frontbuffer plane is
scheduled.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_frontbuffer</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">front</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">fb_op_origin</span></span><span class="w"> </span><span class="n"><span class="pre">origin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>flush frontbuffer object</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_frontbuffer</span> <span class="pre">*front</span></code></dt><dd><p>GEM object to flush</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">fb_op_origin</span> <span class="pre">origin</span></code></dt><dd><p>which operation caused the flush</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called every time rendering on the given object has
completed and frontbuffer caching can be started again.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.frontbuffer_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">frontbuffer_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">fb_op_origin</span></span><span class="w"> </span><span class="n"><span class="pre">origin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.frontbuffer_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>flush frontbuffer</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">fb_op_origin</span> <span class="pre">origin</span></code></dt><dd><p>which operation caused the flush</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called every time rendering on the given planes has
completed and frontbuffer caching can be started again. Flushes will get
delayed if they’re blocked by some outstanding asynchronous rendering.</p>
<p>Can be called without any locks held.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_flip_prepare">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_flip_prepare</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_flip_prepare" title="Link to this definition">¶</a><br /></dt>
<dd><p>prepare asynchronous frontbuffer flip</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called after scheduling a flip on <strong>obj</strong>. The actual
frontbuffer flushing will be delayed until completion is signalled with
intel_frontbuffer_flip_complete. If an invalidate happens in between this
flush will be cancelled.</p>
<p>Can be called without any locks held.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_flip_complete">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_flip_complete</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_flip_complete" title="Link to this definition">¶</a><br /></dt>
<dd><p>complete asynchronous frontbuffer flip</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called after the flip has been latched and will complete
on the next vblank. It will execute the flush if it hasn’t been cancelled yet.</p>
<p>Can be called without any locks held.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_flip">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_flip</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_flip" title="Link to this definition">¶</a><br /></dt>
<dd><p>synchronous frontbuffer flip</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called after scheduling a flip on <strong>obj</strong>. This is for
synchronous plane updates which will happen on the next vblank and which will
not get delayed by pending gpu rendering.</p>
<p>Can be called without any locks held.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_queue_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_queue_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_frontbuffer</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">front</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_queue_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>queue flushing frontbuffer object</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_frontbuffer</span> <span class="pre">*front</span></code></dt><dd><p>GEM object to flush</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is targeted for our dirty callback for queueing flush when
dma fence is signals</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_frontbuffer_track">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_frontbuffer_track</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_frontbuffer</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">old</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_frontbuffer</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">new</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_frontbuffer_track" title="Link to this definition">¶</a><br /></dt>
<dd><p>update frontbuffer tracking</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_frontbuffer</span> <span class="pre">*old</span></code></dt><dd><p>current buffer for the frontbuffer slots</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_frontbuffer</span> <span class="pre">*new</span></code></dt><dd><p>new buffer for the frontbuffer slots</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>bitmask of frontbuffer slots</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This updates the frontbuffer tracking bits <strong>frontbuffer_bits</strong> by clearing them
from <strong>old</strong> and setting them in <strong>new</strong>. Both <strong>old</strong> and <strong>new</strong> can be NULL.</p>
</div>
</section>
<section id="display-fifo-underrun-reporting">
<h3>Display FIFO Underrun Reporting<a class="headerlink" href="#display-fifo-underrun-reporting" title="Link to this heading">¶</a></h3>
<p>The i915 driver checks for display fifo underruns using the interrupt signals
provided by the hardware. This is enabled by default and fairly useful to
debug display issues, especially watermark settings.</p>
<p>If an underrun is detected this is logged into dmesg. To avoid flooding logs
and occupying the cpu underrun interrupts are disabled after the first
occurrence until the next modeset on a given pipe.</p>
<p>Note that underrun detection on gmch platforms is a bit more ugly since there
is no interrupt (despite that the signalling bit is in the PIPESTAT pipe
interrupt register). Also on some other platforms underrun interrupts are
shared, which means that if we detect an underrun we need to disable underrun
reporting on all pipes.</p>
<p>The code also supports underrun detection on the PCH transcoder.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_set_cpu_fifo_underrun_reporting">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_set_cpu_fifo_underrun_reporting</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_set_cpu_fifo_underrun_reporting" title="pipe"><span class="n"><span class="pre">pipe</span></span></a><span class="w"> </span><span class="n"><span class="pre">pipe</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">enable</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_set_cpu_fifo_underrun_reporting" title="Link to this definition">¶</a><br /></dt>
<dd><p>set cpu fifo underrun reporting state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pipe</span></code></dt><dd><p>(CPU) pipe to set state for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">enable</span></code></dt><dd><p>whether underruns should be reported or not</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function sets the fifo underrun state for <strong>pipe</strong>. It is used in the
modeset code to avoid false positives since on many platforms underruns are
expected when disabling or enabling the pipe.</p>
<p>Notice that on some platforms disabling underrun reports for one pipe
disables for all due to shared interrupts. Actual reporting is still per-pipe
though.</p>
<p>Returns the previous state of underrun reporting.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_set_pch_fifo_underrun_reporting">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_set_pch_fifo_underrun_reporting</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">pipe</span></span><span class="w"> </span><span class="n"><span class="pre">pch_transcoder</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">enable</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_set_pch_fifo_underrun_reporting" title="Link to this definition">¶</a><br /></dt>
<dd><p>set PCH fifo underrun reporting state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pch_transcoder</span></code></dt><dd><p>the PCH transcoder (same as pipe on IVB and older)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">enable</span></code></dt><dd><p>whether underruns should be reported or not</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function makes us disable or enable PCH fifo underruns for a specific
PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO
underrun reporting for one transcoder may also disable all the other PCH
error interruts for the other transcoders, due to the fact that there’s just
one interrupt mask/enable bit for all the transcoders.</p>
<p>Returns the previous state of underrun reporting.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cpu_fifo_underrun_irq_handler">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cpu_fifo_underrun_irq_handler</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_cpu_fifo_underrun_irq_handler" title="pipe"><span class="n"><span class="pre">pipe</span></span></a><span class="w"> </span><span class="n"><span class="pre">pipe</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cpu_fifo_underrun_irq_handler" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle CPU fifo underrun interrupt</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pipe</span></code></dt><dd><p>(CPU) pipe to set state for</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This handles a CPU fifo underrun interrupt, generating an underrun warning
into dmesg if underrun reporting is enabled and then disables the underrun
interrupt to avoid an irq storm.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_pch_fifo_underrun_irq_handler">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_pch_fifo_underrun_irq_handler</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">pipe</span></span><span class="w"> </span><span class="n"><span class="pre">pch_transcoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_pch_fifo_underrun_irq_handler" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle PCH fifo underrun interrupt</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pch_transcoder</span></code></dt><dd><p>the PCH transcoder (same as pipe on IVB and older)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This handles a PCH fifo underrun interrupt, generating an underrun warning
into dmesg if underrun reporting is enabled and then disables the underrun
interrupt to avoid an irq storm.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_check_cpu_fifo_underruns">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_check_cpu_fifo_underruns</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_check_cpu_fifo_underruns" title="Link to this definition">¶</a><br /></dt>
<dd><p>check for CPU fifo underruns immediately</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared
error interrupt may have been disabled, and so CPU fifo underruns won’t
necessarily raise an interrupt, and on GMCH platforms where underruns never
raise an interrupt.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_check_pch_fifo_underruns">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_check_pch_fifo_underruns</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_check_pch_fifo_underruns" title="Link to this definition">¶</a><br /></dt>
<dd><p>check for PCH fifo underruns immediately</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared
error interrupt may have been disabled, and so PCH fifo underruns won’t
necessarily raise an interrupt.</p>
</div>
</section>
<section id="plane-configuration">
<h3>Plane Configuration<a class="headerlink" href="#plane-configuration" title="Link to this heading">¶</a></h3>
<p>This section covers plane configuration and composition with the primary
plane, sprites, cursors and overlays. This includes the infrastructure
to do atomic vsync’ed updates of all this state and also tightly coupled
topics like watermark setup and computation, framebuffer compression and
panel self refresh.</p>
</section>
<section id="atomic-plane-helpers">
<h3>Atomic Plane Helpers<a class="headerlink" href="#atomic-plane-helpers" title="Link to this heading">¶</a></h3>
<p>The functions here are used by the atomic plane helper functions to
implement legacy plane updates (i.e., drm_plane-><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">update_plane()</span></code> and
drm_plane-><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">disable_plane()</span></code>). This allows plane updates to use the
atomic state infrastructure and perform plane updates as separate
prepare/check/commit/cleanup steps.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_plane_destroy">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_plane_destroy</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane" title="drm_plane"><span class="n"><span class="pre">drm_plane</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plane</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_plane_destroy" title="Link to this definition">¶</a><br /></dt>
<dd><p>destroy a plane</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane</span> <span class="pre">*plane</span></code></dt><dd><p>plane to destroy</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Common destruction function for all types of planes (primary, cursor,
sprite).</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_plane_duplicate_state">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane_state" title="drm_plane_state"><span class="n"><span class="pre">drm_plane_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">intel_plane_duplicate_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane" title="drm_plane"><span class="n"><span class="pre">drm_plane</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plane</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_plane_duplicate_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>duplicate plane state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane</span> <span class="pre">*plane</span></code></dt><dd><p>drm plane</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Allocates and returns a copy of the plane state (both common and
Intel-specific) for the specified plane.</p>
<p><strong>Return</strong></p>
<p>The newly allocated plane state, or NULL on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_plane_destroy_state">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_plane_destroy_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane" title="drm_plane"><span class="n"><span class="pre">drm_plane</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plane</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane_state" title="drm_plane_state"><span class="n"><span class="pre">drm_plane_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_plane_destroy_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>destroy plane state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane</span> <span class="pre">*plane</span></code></dt><dd><p>drm plane</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane_state</span> <span class="pre">*state</span></code></dt><dd><p>state object to destroy</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Destroys the plane state (both common and Intel-specific) for the
specified plane.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_prepare_plane_fb">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_prepare_plane_fb</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane" title="drm_plane"><span class="n"><span class="pre">drm_plane</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">_plane</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane_state" title="drm_plane_state"><span class="n"><span class="pre">drm_plane_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">_new_plane_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_prepare_plane_fb" title="Link to this definition">¶</a><br /></dt>
<dd><p>Prepare fb for usage on plane</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane</span> <span class="pre">*_plane</span></code></dt><dd><p>drm plane to prepare for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane_state</span> <span class="pre">*_new_plane_state</span></code></dt><dd><p>the plane state being prepared</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Prepares a framebuffer for usage on a display plane. Generally this
involves pinning the underlying object and updating the frontbuffer tracking
bits. Some older platforms need special physical address handling for
cursor planes.</p>
<p>Returns 0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cleanup_plane_fb">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cleanup_plane_fb</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane" title="drm_plane"><span class="n"><span class="pre">drm_plane</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plane</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_plane_state" title="drm_plane_state"><span class="n"><span class="pre">drm_plane_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">_old_plane_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cleanup_plane_fb" title="Link to this definition">¶</a><br /></dt>
<dd><p>Cleans up an fb after plane use</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane</span> <span class="pre">*plane</span></code></dt><dd><p>drm plane to clean up for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_plane_state</span> <span class="pre">*_old_plane_state</span></code></dt><dd><p>the state from the previous modeset</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Cleans up a framebuffer that has just been removed from a plane.</p>
</div>
</section>
<section id="asynchronous-page-flip">
<h3>Asynchronous Page Flip<a class="headerlink" href="#asynchronous-page-flip" title="Link to this heading">¶</a></h3>
<p>Asynchronous page flip is the implementation for the DRM_MODE_PAGE_FLIP_ASYNC
flag. Currently async flip is only supported via the drmModePageFlip IOCTL.
Correspondingly, support is currently added for primary plane only.</p>
<p>Async flip can only change the plane surface address, so anything else
changing is rejected from the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_async_flip_check_hw()</span></code> function.
Once this check is cleared, flip done interrupt is enabled using
the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_crtc_enable_flip_done()</span></code> function.</p>
<p>As soon as the surface address register is written, flip done interrupt is
generated and the requested events are sent to the userspace in the interrupt
handler itself. The timestamp and sequence sent during the flip done event
correspond to the last vblank and have no relation to the actual time when
the flip done event was sent.</p>
</section>
<section id="output-probing">
<h3>Output Probing<a class="headerlink" href="#output-probing" title="Link to this heading">¶</a></h3>
<p>This section covers output probing and related infrastructure like the
hotplug interrupt storm detection and mitigation code. Note that the
i915 driver still uses most of the common DRM helper code for output
probing, so those sections fully apply.</p>
</section>
<section id="hotplug">
<h3>Hotplug<a class="headerlink" href="#hotplug" title="Link to this heading">¶</a></h3>
<p>Simply put, hotplug occurs when a display is connected to or disconnected
from the system. However, there may be adapters and docking stations and
Display Port short pulses and MST devices involved, complicating matters.</p>
<p>Hotplug in i915 is handled in many different levels of abstraction.</p>
<p>The platform dependent interrupt handling code in i915_irq.c enables,
disables, and does preliminary handling of the interrupts. The interrupt
handlers gather the hotplug detect (HPD) information from relevant registers
into a platform independent mask of hotplug pins that have fired.</p>
<p>The platform independent interrupt handler <a class="reference internal" href="#c.intel_hpd_irq_handler" title="intel_hpd_irq_handler"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_irq_handler()</span></code></a> in
intel_hotplug.c does hotplug irq storm detection and mitigation, and passes
further processing to appropriate bottom halves (Display Port specific and
regular hotplug).</p>
<p>The Display Port work function <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_digport_work_func()</span></code> calls into
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_dp_hpd_pulse()</span></code> via hooks, which handles DP short pulses and DP MST long
pulses, with failures and non-MST long pulses triggering regular hotplug
processing on the connector.</p>
<p>The regular hotplug work function <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_hotplug_work_func()</span></code> calls connector
detect hooks, and, if connector status changes, triggers sending of hotplug
uevent to userspace via <a class="reference internal" href="drm-kms-helpers.html#c.drm_kms_helper_hotplug_event" title="drm_kms_helper_hotplug_event"><code class="xref c c-func docutils literal notranslate"><span class="pre">drm_kms_helper_hotplug_event()</span></code></a>.</p>
<p>Finally, the userspace is responsible for triggering a modeset upon receiving
the hotplug uevent, disabling or enabling the crtc as needed.</p>
<p>The hotplug interrupt storm detection and mitigation code keeps track of the
number of interrupts per hotplug pin per a period of time, and if the number
of interrupts exceeds a certain threshold, the interrupt is disabled for a
while before being re-enabled. The intention is to mitigate issues raising
from broken hardware triggering massive amounts of interrupts and grinding
the system to a halt.</p>
<p>Current implementation expects that hotplug interrupt storm will not be
seen when display port sink is connected, hence on platforms whose DP
callback is handled by i915_digport_work_func reenabling of hpd is not
performed (it was never expected to be disabled in the first place ;) )
this is specific to DP sinks handled by this routine and any other display
such as HDMI or DVI enabled on the same port will have proper logic since
it will use i915_hotplug_work_func where this logic is handled.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_pin_default">
<span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">hpd_pin</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_pin_default</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_hpd_pin_default" title="port"><span class="n"><span class="pre">port</span></span></a><span class="w"> </span><span class="n"><span class="pre">port</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_pin_default" title="Link to this definition">¶</a><br /></dt>
<dd><p>return default pin associated with certain port.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">port</span> <span class="pre">port</span></code></dt><dd><p>the hpd port to get associated pin</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>It is only valid and used by digital port encoder.</p>
<p>Return pin that is associatade with <strong>port</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_irq_storm_detect">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_irq_storm_detect</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">hpd_pin</span></span><span class="w"> </span><span class="n"><span class="pre">pin</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">long_hpd</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_irq_storm_detect" title="Link to this definition">¶</a><br /></dt>
<dd><p>gather stats and detect HPD IRQ storm on a pin</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">hpd_pin</span> <span class="pre">pin</span></code></dt><dd><p>the pin to gather stats on</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">long_hpd</span></code></dt><dd><p>whether the HPD IRQ was long or short</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Gather stats about HPD IRQs from the specified <strong>pin</strong>, and detect IRQ
storms. Only the pin specific stats and state are changed, the caller is
responsible for further action.</p>
<p>The number of IRQs that are allowed within <strong>HPD_STORM_DETECT_PERIOD</strong> is
stored in <strong>display->hotplug.hpd_storm_threshold</strong> which defaults to
<strong>HPD_STORM_DEFAULT_THRESHOLD</strong>. Long IRQs count as +10 to this threshold, and
short IRQs count as +1. If this threshold is exceeded, it’s considered an
IRQ storm and the IRQ state is set to <strong>HPD_MARK_DISABLED</strong>.</p>
<p>By default, most systems will only count long IRQs towards
<code class="xref c c-type docutils literal notranslate"><span class="pre">display->hotplug</span></code>.hpd_storm_threshold. However, some older systems also
suffer from short IRQ storms and must also track these. Because short IRQ
storms are naturally caused by sideband interactions with DP MST devices,
short IRQ detection is only enabled for systems without DP MST support.
Systems which are new enough to support DP MST are far less likely to
suffer from IRQ storms at all, so this is fine.</p>
<p>The HPD threshold can be controlled through i915_hpd_storm_ctl in debugfs,
and should only be adjusted for automated hotplug testing.</p>
<p>Return true if an IRQ storm was detected on <strong>pin</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_trigger_irq">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_trigger_irq</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_digital_port</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dig_port</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_trigger_irq" title="Link to this definition">¶</a><br /></dt>
<dd><p>trigger an hpd irq event for a port</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_digital_port</span> <span class="pre">*dig_port</span></code></dt><dd><p>digital port</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Trigger an HPD interrupt event for the given port, emulating a short pulse
generated by the sink, and schedule the dig port work to handle it.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_irq_handler">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_irq_handler</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">pin_mask</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">long_mask</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_irq_handler" title="Link to this definition">¶</a><br /></dt>
<dd><p>main hotplug irq handler</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">pin_mask</span></code></dt><dd><p>a mask of hpd pins that have triggered the irq</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">long_mask</span></code></dt><dd><p>a mask of hpd pins that may be long hpd pulses</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is the main hotplug irq handler for all platforms. The platform specific
irq handlers call the platform specific hotplug irq handlers, which read and
decode the appropriate registers into bitmasks about hpd pins that have
triggered (<strong>pin_mask</strong>), and which of those pins may be long pulses
(<strong>long_mask</strong>). The <strong>long_mask</strong> is ignored if the port corresponding to the pin
is not a digital port.</p>
<p>Here, we do hotplug irq storm detection and mitigation, and pass further
processing to appropriate bottom halves.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initializes and enables hpd support</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function enables the hotplug support. It requires that interrupts have
already been enabled with <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_irq_init_hw()</span></code>. From this point on hotplug and
poll request can run concurrently to other code, so locking rules must be
obeyed.</p>
<p>This is a separate step from interrupt enabling to simplify the locking rules
in the driver load and resume code.</p>
<p>Also see: <a class="reference internal" href="#c.intel_hpd_poll_enable" title="intel_hpd_poll_enable"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_poll_enable()</span></code></a> and <a class="reference internal" href="#c.intel_hpd_poll_disable" title="intel_hpd_poll_disable"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_poll_disable()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_poll_enable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_poll_enable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_poll_enable" title="Link to this definition">¶</a><br /></dt>
<dd><p>enable polling for connectors with hpd</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function enables polling for all connectors which support HPD.
Under certain conditions HPD may not be functional. On most Intel GPUs,
this happens when we enter runtime suspend.
On Valleyview and Cherryview systems, this also happens when we shut off all
of the powerwells.</p>
<p>Since this function can get called in contexts where we’re already holding
dev->mode_config.mutex, we do the actual hotplug enabling in a separate
worker.</p>
<p>Also see: <a class="reference internal" href="#c.intel_hpd_init" title="intel_hpd_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_init()</span></code></a> and <a class="reference internal" href="#c.intel_hpd_poll_disable" title="intel_hpd_poll_disable"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_poll_disable()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_poll_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_poll_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_poll_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>disable polling for connectors with hpd</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function disables polling for all connectors which support HPD.
Under certain conditions HPD may not be functional. On most Intel GPUs,
this happens when we enter runtime suspend.
On Valleyview and Cherryview systems, this also happens when we shut off all
of the powerwells.</p>
<p>Since this function can get called in contexts where we’re already holding
dev->mode_config.mutex, we do the actual hotplug enabling in a separate
worker.</p>
<p>Also used during driver init to initialize connector->polled
appropriately for all connectors.</p>
<p>Also see: <a class="reference internal" href="#c.intel_hpd_init" title="intel_hpd_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_init()</span></code></a> and <a class="reference internal" href="#c.intel_hpd_poll_enable" title="intel_hpd_poll_enable"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_poll_enable()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_block">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_block</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_block" title="Link to this definition">¶</a><br /></dt>
<dd><p>Block handling of HPD IRQs on an HPD pin</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>Encoder to block the HPD handling for</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Blocks the handling of HPD IRQs on the HPD pin of <strong>encoder</strong>.</p>
<p>On return:</p>
<ul class="simple">
<li><p>It’s guaranteed that the blocked encoders’ HPD pulse handler
(via intel_digital_port::<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">hpd_pulse()</span></code>) is not running.</p></li>
<li><p>The hotplug event handling (via intel_encoder::<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">hotplug()</span></code>) of an
HPD IRQ pending at the time this function is called may be still
running.</p></li>
<li><p>Detection on the encoder’s connector (via
drm_connector_helper_funcs::<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">detect_ctx()</span></code>,
drm_connector_funcs::<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">detect()</span></code>) remains allowed, for instance as part of
userspace connector probing, or DRM core’s connector polling.</p></li>
</ul>
<p>The call must be followed by calling <a class="reference internal" href="#c.intel_hpd_unblock" title="intel_hpd_unblock"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_unblock()</span></code></a>, or
<a class="reference internal" href="#c.intel_hpd_clear_and_unblock" title="intel_hpd_clear_and_unblock"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_clear_and_unblock()</span></code></a>.</p>
<p>Note that the handling of HPD IRQs for another encoder using the same HPD
pin as that of <strong>encoder</strong> will be also blocked.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_unblock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_unblock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_unblock" title="Link to this definition">¶</a><br /></dt>
<dd><p>Unblock handling of HPD IRQs on an HPD pin</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>Encoder to unblock the HPD handling for</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Unblock the handling of HPD IRQs on the HPD pin of <strong>encoder</strong>, which was
previously blocked by <a class="reference internal" href="#c.intel_hpd_block" title="intel_hpd_block"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_block()</span></code></a>. Any HPD IRQ raised on the
HPD pin while it was blocked will be handled for <strong>encoder</strong> and for any
other encoder sharing the same HPD pin.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_hpd_clear_and_unblock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_hpd_clear_and_unblock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_hpd_clear_and_unblock" title="Link to this definition">¶</a><br /></dt>
<dd><p>Unblock handling of new HPD IRQs on an HPD pin</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>Encoder to unblock the HPD handling for</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Unblock the handling of HPD IRQs on the HPD pin of <strong>encoder</strong>, which was
previously blocked by <a class="reference internal" href="#c.intel_hpd_block" title="intel_hpd_block"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_hpd_block()</span></code></a>. Any HPD IRQ raised on the
HPD pin while it was blocked will be cleared, handling only new IRQs.</p>
</div>
</section>
<section id="high-definition-audio">
<h3>High Definition Audio<a class="headerlink" href="#high-definition-audio" title="Link to this heading">¶</a></h3>
<p>The graphics and audio drivers together support High Definition Audio over
HDMI and Display Port. The audio programming sequences are divided into audio
codec and controller enable and disable sequences. The graphics driver
handles the audio codec sequences, while the audio driver handles the audio
controller sequences.</p>
<p>The disable sequences must be performed before disabling the transcoder or
port. The enable sequences may only be performed after enabling the
transcoder and port, and after completed link training. Therefore the audio
enable/disable sequences are part of the modeset sequence.</p>
<p>The codec and controller sequences could be done either parallel or serial,
but generally the ELDV/PD change in the codec sequence indicates to the audio
driver that the controller sequence should start. Indeed, most of the
co-operation between the graphics and audio drivers is handled via audio
related registers. (The notable exception is the power management, not
covered here.)</p>
<p>The struct <a class="reference internal" href="#c.i915_audio_component" title="i915_audio_component"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_audio_component</span></code></a> is used to interact between the graphics
and audio drivers. The struct <code class="xref c c-type docutils literal notranslate"><span class="pre">i915_audio_component_ops</span></code> <strong>ops</strong> in it is
defined in graphics driver and called in audio driver. The
struct <code class="xref c c-type docutils literal notranslate"><span class="pre">i915_audio_component_audio_ops</span></code> <strong>audio_ops</strong> is called from i915 driver.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_codec_enable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_codec_enable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_connector_state" title="drm_connector_state"><span class="n"><span class="pre">drm_connector_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">conn_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_codec_enable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Enable the audio codec for HD audio</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>encoder on which to enable audio</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>pointer to the current crtc state.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">drm_connector_state</span> <span class="pre">*conn_state</span></code></dt><dd><p>pointer to the current connector state.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>The enable sequences may only be performed after enabling the transcoder and
port, and after completed link training.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_codec_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_codec_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">old_crtc_state</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-kms.html#c.drm_connector_state" title="drm_connector_state"><span class="n"><span class="pre">drm_connector_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">old_conn_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_codec_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Disable the audio codec for HD audio</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>encoder on which to disable audio</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*old_crtc_state</span></code></dt><dd><p>pointer to the old crtc state.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">drm_connector_state</span> <span class="pre">*old_conn_state</span></code></dt><dd><p>pointer to the old connector state.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>The disable sequences must be performed before disabling the transcoder or
port.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_hooks_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_hooks_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_hooks_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Set up chip specific audio hooks</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_component_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_component_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_component_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initialize and register the audio component</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This will register with the component framework a child component which
will bind dynamically to the snd_hda_intel driver’s corresponding master
component when the latter is registered. During binding the child
initializes an instance of <a class="reference internal" href="#c.i915_audio_component" title="i915_audio_component"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_audio_component</span></code></a> which it receives
from the master. The master can then start to use the interface defined by
this struct. Each side can break the binding at any point by deregistering
its own component after which each side’s component unbind callback is
called.</p>
<p>We ignore any error during registration and continue with reduced
functionality (i.e. without HDMI audio).</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_component_cleanup">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_component_cleanup</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_component_cleanup" title="Link to this definition">¶</a><br /></dt>
<dd><p>deregister the audio component</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Deregisters the audio component, breaking any existing binding to the
corresponding snd_hda_intel driver’s master component.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Initialize the audio driver either using component framework or using lpe audio bridge</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_audio_deinit">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_audio_deinit</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_audio_deinit" title="Link to this definition">¶</a><br /></dt>
<dd><p>deinitialize the audio driver</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_audio_component">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_audio_component</span></span></span><a class="headerlink" href="#c.i915_audio_component" title="Link to this definition">¶</a><br /></dt>
<dd><p>Used for direct communication between i915 and hda drivers</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_audio_component {
struct drm_audio_component base;
int aud_sample_rate[MAX_PORTS];
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">base</span></code></dt><dd><p>the drm_audio_component base class</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">aud_sample_rate</span></code></dt><dd><p>the array of audio sample rate per port</p>
</dd>
</dl>
</div>
</section>
<section id="intel-hdmi-lpe-audio-support">
<h3>Intel HDMI LPE Audio Support<a class="headerlink" href="#intel-hdmi-lpe-audio-support" title="Link to this heading">¶</a></h3>
<p>Motivation:
Atom platforms (e.g. valleyview and cherryTrail) integrates a DMA-based
interface as an alternative to the traditional HDaudio path. While this
mode is unrelated to the LPE aka SST audio engine, the documentation refers
to this mode as LPE so we keep this notation for the sake of consistency.</p>
<p>The interface is handled by a separate standalone driver maintained in the
ALSA subsystem for simplicity. To minimize the interaction between the two
subsystems, a bridge is setup between the hdmi-lpe-audio and i915:
1. Create a platform device to share MMIO/IRQ resources
2. Make the platform device child of i915 device for runtime PM.
3. Create IRQ chip to forward the LPE audio irqs.
the hdmi-lpe-audio driver probes the lpe audio device and creates a new
sound card</p>
<p>Threats:
Due to the restriction in Linux platform device model, user need manually
uninstall the hdmi-lpe-audio driver before uninstalling i915 module,
otherwise we might run into use-after-free issues after i915 removes the
platform device: even though hdmi-lpe-audio driver is released, the modules
is still in “installed” status.</p>
<p>Implementation:
The MMIO/REG platform resources are created according to the registers
specification.
When forwarding LPE audio irqs, the flow control handler selection depends
on the platform, for example on valleyview handle_simple_irq is enough.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_lpe_audio_irq_handler">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_lpe_audio_irq_handler</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_lpe_audio_irq_handler" title="Link to this definition">¶</a><br /></dt>
<dd><p>forwards the LPE audio irq</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>the LPE Audio irq is forwarded to the irq handler registered by LPE audio
driver.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_lpe_audio_init">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_lpe_audio_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_lpe_audio_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>detect and setup the bridge between HDMI LPE Audio driver and i915</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>0 if successful. non-zero if detection or
llocation/initialization fails</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_lpe_audio_teardown">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_lpe_audio_teardown</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_lpe_audio_teardown" title="Link to this definition">¶</a><br /></dt>
<dd><p>destroy the bridge between HDMI LPE audio driver and i915</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>release all the resources for LPE audio <-> i915 bridge.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_lpe_audio_notify">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_lpe_audio_notify</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">transcoder</span></span><span class="w"> </span><span class="n"><span class="pre">cpu_transcoder</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_lpe_audio_notify" title="port"><span class="n"><span class="pre">port</span></span></a><span class="w"> </span><span class="n"><span class="pre">port</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">eld</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ls_clock</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">dp_output</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_lpe_audio_notify" title="Link to this definition">¶</a><br /></dt>
<dd><p>notify lpe audio event audio driver and i915</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">transcoder</span> <span class="pre">cpu_transcoder</span></code></dt><dd><p>CPU transcoder</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">port</span> <span class="pre">port</span></code></dt><dd><p>port</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">void</span> <span class="pre">*eld</span></code></dt><dd><p>ELD data</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">ls_clock</span></code></dt><dd><p>Link symbol clock in kHz</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">dp_output</span></code></dt><dd><p>Driving a DP output?</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Notify lpe audio driver of eld change.</p>
</div>
</section>
<section id="panel-self-refresh-psr-psr-srd">
<h3>Panel Self Refresh PSR (PSR/SRD)<a class="headerlink" href="#panel-self-refresh-psr-psr-srd" title="Link to this heading">¶</a></h3>
<p>Since Haswell Display controller supports Panel Self-Refresh on display
panels witch have a remote frame buffer (RFB) implemented according to PSR
spec in eDP1.3. PSR feature allows the display to go to lower standby states
when system is idle but display is on as it eliminates display refresh
request to DDR memory completely as long as the frame buffer for that
display is unchanged.</p>
<p>Panel Self Refresh must be supported by both Hardware (source) and
Panel (sink).</p>
<p>PSR saves power by caching the framebuffer in the panel RFB, which allows us
to power down the link and memory controller. For DSI panels the same idea
is called “manual mode”.</p>
<p>The implementation uses the hardware-based PSR support which automatically
enters/exits self-refresh mode. The hardware takes care of sending the
required DP aux message and could even retrain the link (that part isn’t
enabled yet though). The hardware also keeps track of any frontbuffer
changes to know when to exit self-refresh mode again. Unfortunately that
part doesn’t work too well, hence why the i915 PSR support uses the
software frontbuffer tracking to make sure it doesn’t miss a screen
update. For this integration <a class="reference internal" href="#c.intel_psr_invalidate" title="intel_psr_invalidate"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_psr_invalidate()</span></code></a> and <a class="reference internal" href="#c.intel_psr_flush" title="intel_psr_flush"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_psr_flush()</span></code></a>
get called by the frontbuffer tracking code. Note that because of locking
issues the self-refresh re-enable code is done from a work queue, which
must be correctly synchronized/cancelled when shutting down the pipe.”</p>
<p>DC3CO (DC3 clock off)</p>
<p>On top of PSR2, GEN12 adds a intermediate power savings state that turns
clock off automatically during PSR2 idle state.
The smaller overhead of DC3co entry/exit vs. the overhead of PSR2 deep sleep
entry/exit allows the HW to enter a low-power state even when page flipping
periodically (for instance a 30fps video playback scenario).</p>
<p>Every time a flips occurs PSR2 will get out of deep sleep state(if it was),
so DC3CO is enabled and tgl_dc3co_disable_work is schedule to run after 6
frames, if no other flip occurs and the function above is executed, DC3CO is
disabled and PSR2 is configured to enter deep sleep, resetting again in case
of another flip.
Front buffer modifications do not trigger DC3CO activation on purpose as it
would bring a lot of complexity and most of the moderns systems will only
use page flips.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_psr_disable" title="intel_dp"><span class="n"><span class="pre">intel_dp</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">intel_dp</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">old_crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Disable PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span> <span class="pre">*intel_dp</span></code></dt><dd><p>Intel DP</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*old_crtc_state</span></code></dt><dd><p>old CRTC state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function needs to be called before disabling pipe.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_pause">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_pause</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_psr_pause" title="intel_dp"><span class="n"><span class="pre">intel_dp</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">intel_dp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_pause" title="Link to this definition">¶</a><br /></dt>
<dd><p>Pause PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span> <span class="pre">*intel_dp</span></code></dt><dd><p>Intel DP</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function need to be called after enabling psr.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_resume">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_resume</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_psr_resume" title="intel_dp"><span class="n"><span class="pre">intel_dp</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">intel_dp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_resume" title="Link to this definition">¶</a><br /></dt>
<dd><p>Resume PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span> <span class="pre">*intel_dp</span></code></dt><dd><p>Intel DP</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function need to be called after pausing psr.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_needs_vblank_notification">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_needs_vblank_notification</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_needs_vblank_notification" title="Link to this definition">¶</a><br /></dt>
<dd><p>Check if PSR need vblank enable/disable notification.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>CRTC status</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>We need to block DC6 entry in case of Panel Replay as enabling VBI doesn’t
prevent it in case of Panel Replay. Panel Replay switches main link off on
DC entry. This means vblank interrupts are not fired and is a problem if
user-space is polling for vblank events. Also Wa_16025596647 needs
information when vblank is enabled/disabled.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_trigger_frame_change_event">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_trigger_frame_change_event</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dsb</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_trigger_frame_change_event" title="Link to this definition">¶</a><br /></dt>
<dd><p>Trigger “Frame Change” event</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dsb</span> <span class="pre">*dsb</span></code></dt><dd><p>DSB context</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>the atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>the CRTC</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Generate PSR “Frame Change” event.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_min_vblank_delay">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_min_vblank_delay</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_min_vblank_delay" title="Link to this definition">¶</a><br /></dt>
<dd><p>Minimum vblank delay needed by PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>the crtc state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return minimum vblank delay needed by PSR.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_wait_for_idle_locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_wait_for_idle_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">new_crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_wait_for_idle_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>wait for PSR be ready for a pipe update</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*new_crtc_state</span></code></dt><dd><p>new CRTC state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is expected to be called from <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">pipe_update_start()</span></code> where it is
not expected to race with PSR enable or disable.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_invalidate">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_invalidate</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">fb_op_origin</span></span><span class="w"> </span><span class="n"><span class="pre">origin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_invalidate" title="Link to this definition">¶</a><br /></dt>
<dd><p>Invalidate PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">fb_op_origin</span> <span class="pre">origin</span></code></dt><dd><p>which operation caused the invalidate</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Since the hardware frontbuffer tracking has gaps we need to integrate
with the software frontbuffer tracking. This function gets called every
time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
disabled if the frontbuffer mask contains a buffer relevant to PSR.</p>
<p>Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.”</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">fb_op_origin</span></span><span class="w"> </span><span class="n"><span class="pre">origin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>Flush PSR</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">fb_op_origin</span> <span class="pre">origin</span></code></dt><dd><p>which operation caused the flush</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Since the hardware frontbuffer tracking has gaps we need to integrate
with the software frontbuffer tracking. This function gets called every
time frontbuffer rendering has completed and flushed out to memory. PSR
can be enabled again if no other frontbuffer relevant to PSR is dirty.</p>
<p>Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_psr_init" title="intel_dp"><span class="n"><span class="pre">intel_dp</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">intel_dp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Init basic PSR work and mutex.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span> <span class="pre">*intel_dp</span></code></dt><dd><p>Intel DP</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called after the initializing connector.
(the initializing of connector treats the handling of connector capabilities)
And it initializes basic PSR stuff for each DP Encoder.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_link_ok">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_link_ok</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_psr_link_ok" title="intel_dp"><span class="n"><span class="pre">intel_dp</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">intel_dp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_link_ok" title="Link to this definition">¶</a><br /></dt>
<dd><p>return psr->link_ok</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span> <span class="pre">*intel_dp</span></code></dt><dd><p><code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dp</span></code></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>We are seeing unexpected link re-trainings with some panels. This is caused
by panel stating bad link status after PSR is enabled. Code checking link
status can call this to ensure it can ignore bad link status stated by the
panel I.e. if panel is stating bad link and intel_psr_link_ok is stating link
is ok caller should rely on latter.</p>
<p>Return value of link_ok</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_lock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_lock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_lock" title="Link to this definition">¶</a><br /></dt>
<dd><p>grab PSR lock</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>the crtc state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is initially meant to be used by around CRTC update, when
vblank sensitive registers are updated and we need grab the lock
before it to avoid vblank evasion.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_unlock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_unlock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_unlock" title="Link to this definition">¶</a><br /></dt>
<dd><p>release PSR lock</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>the crtc state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Release the PSR lock that was held during pipe update.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_notify_dc5_dc6">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_notify_dc5_dc6</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_notify_dc5_dc6" title="Link to this definition">¶</a><br /></dt>
<dd><p>Notify PSR about enable/disable dc5/dc6</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel atomic state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to schedule
psr_dc5_dc6_wa_work used for applying/removing the workaround.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_dc5_dc6_wa_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_dc5_dc6_wa_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_dc5_dc6_wa_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Init work for underrun on idle PSR HW bug wa</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel atomic state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to init
psr_dc5_dc6_wa_work used for applying the workaround.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_notify_pipe_change">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_notify_pipe_change</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">enable</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_notify_pipe_change" title="Link to this definition">¶</a><br /></dt>
<dd><p>Notify PSR about enable/disable of a pipe</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>intel atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>intel crtc</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">enable</span></code></dt><dd><p>enable/disable</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
remove the workaround when pipe is getting enabled/disabled</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_psr_notify_vblank_enable_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_psr_notify_vblank_enable_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">enable</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_psr_notify_vblank_enable_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Notify PSR about enable/disable of vblank</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel display struct</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">enable</span></code></dt><dd><p>enable/disable</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
remove the workaround when vblank is getting enabled/disabled</p>
</div>
</section>
<section id="frame-buffer-compression-fbc">
<h3>Frame Buffer Compression (FBC)<a class="headerlink" href="#frame-buffer-compression-fbc" title="Link to this heading">¶</a></h3>
<p>FBC tries to save memory bandwidth (and so power consumption) by
compressing the amount of memory used by the display. It is total
transparent to user space and completely handled in the kernel.</p>
<p>The benefits of FBC are mostly visible with solid backgrounds and
variation-less patterns. It comes from keeping the memory footprint small
and having fewer memory pages opened and accessed for refreshing the display.</p>
<p>i915 is responsible to reserve stolen memory for FBC and configure its
offset on proper registers. The hardware takes care of all
compress/decompress. However there are many known cases where we have to
forcibly disable it to allow proper screen updates.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_fbc_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_fbc_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_fbc_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>disable FBC if it’s associated with crtc</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>the CRTC</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function disables FBC if it’s associated with the provided CRTC.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_fbc_handle_fifo_underrun_irq">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_fbc_handle_fifo_underrun_irq</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_fbc_handle_fifo_underrun_irq" title="Link to this definition">¶</a><br /></dt>
<dd><p>disable FBC when we get a FIFO underrun</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Without FBC, most underruns are harmless and don’t really cause too many
problems, except for an annoying message on dmesg. With FBC, underruns can
become black screens or even worse, especially when paired with bad
watermarks. So in order for us to be on the safe side, completely disable FBC
in case we ever detect a FIFO underrun on any pipe. An underrun on any pipe
already suggests that watermarks may be bad, so try to be as safe as
possible.</p>
<p>This function is called from the IRQ handler.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_fbc_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_fbc_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_fbc_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Initialize FBC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function might be called during PM init process.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_fbc_sanitize">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_fbc_sanitize</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_fbc_sanitize" title="Link to this definition">¶</a><br /></dt>
<dd><p>Sanitize FBC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Make sure FBC is initially disabled since we have no
idea eg. into which parts of stolen it might be scribbling
into.</p>
</div>
</section>
<section id="display-refresh-rate-switching-drrs">
<h3>Display Refresh Rate Switching (DRRS)<a class="headerlink" href="#display-refresh-rate-switching-drrs" title="Link to this heading">¶</a></h3>
<p>Display Refresh Rate Switching (DRRS) is a power conservation feature
which enables swtching between low and high refresh rates,
dynamically, based on the usage scenario. This feature is applicable
for internal panels.</p>
<p>Indication that the panel supports DRRS is given by the panel EDID, which
would list multiple refresh rates for one resolution.</p>
<p>DRRS is of 2 types - static and seamless.
Static DRRS involves changing refresh rate (RR) by doing a full modeset
(may appear as a blink on screen) and is used in dock-undock scenario.
Seamless DRRS involves changing RR without any visual effect to the user
and can be used during normal system usage. This is done by programming
certain registers.</p>
<p>Support for static/seamless DRRS may be indicated in the VBT based on
inputs from the panel spec.</p>
<p>DRRS saves power by switching to low RR based on usage scenarios.</p>
<p>The implementation is based on frontbuffer tracking implementation. When
there is a disturbance on the screen triggered by user activity or a periodic
system activity, DRRS is disabled (RR is changed to high RR). When there is
no movement on screen, after a timeout of 1 second, a switch to low RR is
made.</p>
<p>For integration with frontbuffer tracking code, <a class="reference internal" href="#c.intel_drrs_invalidate" title="intel_drrs_invalidate"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_drrs_invalidate()</span></code></a>
and <a class="reference internal" href="#c.intel_drrs_flush" title="intel_drrs_flush"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_drrs_flush()</span></code></a> are called.</p>
<p>DRRS can be further extended to support other internal panels and also
the scenario of video playback wherein RR is set based on the rate
requested by userspace.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_drrs_activate">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_drrs_activate</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_drrs_activate" title="Link to this definition">¶</a><br /></dt>
<dd><p>activate DRRS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>the crtc state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Activates DRRS on the crtc.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_drrs_deactivate">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_drrs_deactivate</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">old_crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_drrs_deactivate" title="Link to this definition">¶</a><br /></dt>
<dd><p>deactivate DRRS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*old_crtc_state</span></code></dt><dd><p>the old crtc state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Deactivates DRRS on the crtc.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_drrs_invalidate">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_drrs_invalidate</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_drrs_invalidate" title="Link to this definition">¶</a><br /></dt>
<dd><p>Disable Idleness DRRS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called everytime rendering on the given planes start.
Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).</p>
<p>Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_drrs_flush">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_drrs_flush</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">frontbuffer_bits</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_drrs_flush" title="Link to this definition">¶</a><br /></dt>
<dd><p>Restart Idleness DRRS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">frontbuffer_bits</span></code></dt><dd><p>frontbuffer plane tracking bits</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function gets called every time rendering on the given planes has
completed or flip on a crtc is completed. So DRRS should be upclocked
(LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
if no other planes are dirty.</p>
<p>Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_drrs_crtc_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_drrs_crtc_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_drrs_crtc_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Init DRRS for CRTC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>crtc</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called only once at driver load to initialize basic
DRRS stuff.</p>
</div>
</section>
<section id="dpio">
<h3>DPIO<a class="headerlink" href="#dpio" title="Link to this heading">¶</a></h3>
<p>VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI
ports. DPIO is the name given to such a display PHY. These PHYs
don’t follow the standard programming model using direct MMIO
registers, and instead their registers must be accessed through IOSF
sideband. VLV has one such PHY for driving ports B and C, and CHV
adds another PHY for driving port D. Each PHY responds to specific
IOSF-SB port.</p>
<p>Each display PHY is made up of one or two channels. Each channel
houses a common lane part which contains the PLL and other common
logic. CH0 common lane also contains the IOSF-SB logic for the
Common Register Interface (CRI) ie. the DPIO registers. CRI clock
must be running when any DPIO registers are accessed.</p>
<p>In addition to having their own registers, the PHYs are also
controlled through some dedicated signals from the display
controller. These include PLL reference clock enable, PLL enable,
and CRI clock selection, for example.</p>
<p>Eeach channel also has two splines (also called data lanes), and
each spline is made up of one Physical Access Coding Sub-Layer
(PCS) block and two TX lanes. So each channel has two PCS blocks
and four TX lanes. The TX lanes are used as DP lanes or TMDS
data/clock pairs depending on the output type.</p>
<p>Additionally the PHY also contains an AUX lane with AUX blocks
for each channel. This is used for DP AUX communication, but
this fact isn’t really relevant for the driver since AUX is
controlled from the display controller side. No DPIO registers
need to be accessed during AUX communication,</p>
<p>Generally on VLV/CHV the common lane corresponds to the pipe and
the spline (PCS/TX) corresponds to the port.</p>
<p>For dual channel PHY (VLV/CHV):</p>
<blockquote>
<div><p>pipe A == CMN/PLL/REF CH0</p>
<p>pipe B == CMN/PLL/REF CH1</p>
<p>port B == PCS/TX CH0</p>
<p>port C == PCS/TX CH1</p>
</div></blockquote>
<p>This is especially important when we cross the streams
ie. drive port B with pipe B, or port C with pipe A.</p>
<p>For single channel PHY (CHV):</p>
<blockquote>
<div><p>pipe C == CMN/PLL/REF CH0</p>
<p>port D == PCS/TX CH0</p>
</div></blockquote>
<p>On BXT the entire PHY channel corresponds to the port. That means
the PLL is also now associated with the port rather than the pipe,
and so the clock needs to be routed to the appropriate transcoder.
Port A PLL is directly connected to transcoder EDP and port B/C
PLLs can be routed to any transcoder A/B/C.</p>
<p>Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
digital port D (CHV) or port A (BXT).</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Dual channel PHY (VLV/CHV/BXT)
---------------------------------
| CH0 | CH1 |
| CMN/PLL/REF | CMN/PLL/REF |
|---------------|---------------| Display PHY
| PCS01 | PCS23 | PCS01 | PCS23 |
|-------|-------|-------|-------|
|TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3|
---------------------------------
| DDI0 | DDI1 | DP/HDMI ports
---------------------------------
Single channel PHY (CHV/BXT)
-----------------
| CH0 |
| CMN/PLL/REF |
|---------------| Display PHY
| PCS01 | PCS23 |
|-------|-------|
|TX0|TX1|TX2|TX3|
-----------------
| DDI2 | DP/HDMI port
-----------------
</pre></div>
</div>
</section>
<section id="dmc-firmware-support">
<h3>DMC Firmware Support<a class="headerlink" href="#dmc-firmware-support" title="Link to this heading">¶</a></h3>
<p>From gen9 onwards we have newly added DMC (Display microcontroller) in display
engine to save and restore the state of display engine when it enter into
low-power state and comes back to normal.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_block_pkgc">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_block_pkgc</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dmc_block_pkgc" title="pipe"><span class="n"><span class="pre">pipe</span></span></a><span class="w"> </span><span class="n"><span class="pre">pipe</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">block</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_block_pkgc" title="Link to this definition">¶</a><br /></dt>
<dd><p>block PKG C-state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pipe</span></code></dt><dd><p>pipe which register use to block</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">block</span></code></dt><dd><p>block/unblock</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This interface is target for Wa_16025596647 usage. I.e. to set/clear
PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS bit in PIPEDMC_BLOCK_PKGC_SW register.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank" title="pipe"><span class="n"><span class="pre">pipe</span></span></a><span class="w"> </span><span class="n"><span class="pre">pipe</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">enable</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank" title="Link to this definition">¶</a><br /></dt>
<dd><p>start of PKG C-state exit</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">pipe</span> <span class="pre">pipe</span></code></dt><dd><p>pipe which register use to block</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">enable</span></code></dt><dd><p>enable/disable</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This interface is target for Wa_16025596647 usage. I.e. start the package C
exit at the start of the undelayed vblank</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_load_program">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_load_program</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_load_program" title="Link to this definition">¶</a><br /></dt>
<dd><p>write the firmware from memory to register.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>DMC firmware is read from a .bin file and kept in internal memory one time.
Everytime display comes back from low power state this function is called to
copy the firmware from internal memory to registers.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_disable_program">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_disable_program</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_disable_program" title="Link to this definition">¶</a><br /></dt>
<dd><p>disable the firmware</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Disable all event handlers in the firmware, making sure the firmware is
inactive after the display is uninitialized.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initialize the firmware loading.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is called at the time of loading the display driver to read
firmware from a .bin file and copied into a internal memory.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_suspend">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_suspend</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_suspend" title="Link to this definition">¶</a><br /></dt>
<dd><p>prepare DMC firmware before system suspend</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Prepare the DMC firmware before entering system suspend. This includes
flushing pending work items and releasing any resources acquired during
init.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_resume">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_resume</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_resume" title="Link to this definition">¶</a><br /></dt>
<dd><p>init DMC firmware during system resume</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Reinitialize the DMC firmware during system resume, reacquiring any
resources released in <a class="reference internal" href="#c.intel_dmc_suspend" title="intel_dmc_suspend"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dmc_suspend()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dmc_fini">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dmc_fini</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dmc_fini" title="Link to this definition">¶</a><br /></dt>
<dd><p>unload the DMC firmware.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Firmmware unloading includes freeing the internal memory and reset the
firmware loading status.</p>
</div>
</section>
<section id="dmc-flip-queue">
<h3>DMC Flip Queue<a class="headerlink" href="#dmc-flip-queue" title="Link to this heading">¶</a></h3>
<p>A flip queue is a ring buffer implemented by the pipe DMC firmware.
The driver inserts entries into the queues to be executed by the
pipe DMC at a specified presentation timestamp (PTS).</p>
<p>Each pipe DMC provides several queues:</p>
<ul class="simple">
<li><p>1 general queue (two DSB buffers executed per entry)</p></li>
<li><p>3 plane queues (one DSB buffer executed per entry)</p></li>
<li><p>1 fast queue (deprecated)</p></li>
</ul>
</section>
<section id="dmc-wakelock-support">
<h3>DMC wakelock support<a class="headerlink" href="#dmc-wakelock-support" title="Link to this heading">¶</a></h3>
<p>Wake lock is the mechanism to cause display engine to exit DC
states to allow programming to registers that are powered down in
those states. Previous projects exited DC states automatically when
detecting programming. Now software controls the exit by
programming the wake lock. This improves system performance and
system interactions and better fits the flip queue style of
programming. Wake lock is only required when DC5, DC6, or DC6v have
been enabled in DC_STATE_EN and the wake lock mode of operation has
been enabled.</p>
<p>The wakelock mechanism in DMC allows the display engine to exit DC
states explicitly before programming registers that may be powered
down. In earlier hardware, this was done automatically and
implicitly when the display engine accessed a register. With the
wakelock implementation, the driver asserts a wakelock in DMC,
which forces it to exit the DC state until the wakelock is
deasserted.</p>
<p>The mechanism can be enabled and disabled by writing to the
DMC_WAKELOCK_CFG register. There are also 13 control registers
that can be used to hold and release different wakelocks. In the
current implementation, we only need one wakelock, so only
DMC_WAKELOCK1_CTL is used. The other definitions are here for
potential future use.</p>
</section>
<section id="video-bios-table-vbt">
<h3>Video BIOS Table (VBT)<a class="headerlink" href="#video-bios-table-vbt" title="Link to this heading">¶</a></h3>
<p>The Video BIOS Table, or VBT, provides platform and board specific
configuration information to the driver that is not discoverable or available
through other means. The configuration is mostly related to display
hardware. The VBT is available via the ACPI OpRegion or, on older systems, in
the PCI ROM.</p>
<p>The VBT consists of a VBT Header (defined as <a class="reference internal" href="#c.vbt_header" title="vbt_header"><code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">vbt_header</span></code></a>), a BDB
Header (<a class="reference internal" href="#c.bdb_header" title="bdb_header"><code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">bdb_header</span></code></a>), and a number of BIOS Data Blocks (BDB) that
contain the actual configuration information. The VBT Header, and thus the
VBT, begins with “$VBT” signature. The VBT Header contains the offset of the
BDB Header. The data blocks are concatenated after the BDB Header. The data
blocks have a 1-byte Block ID, 2-byte Block Size, and Block Size bytes of
data. (Block 53, the MIPI Sequence Block is an exception.)</p>
<p>The driver parses the VBT during load. The relevant information is stored in
driver private data for ease of use, and the actual VBT is not read after
that.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_is_valid_vbt">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_is_valid_vbt</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_is_valid_vbt" title="Link to this definition">¶</a><br /></dt>
<dd><p>does the given buffer contain a valid VBT</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">void</span> <span class="pre">*buf</span></code></dt><dd><p>pointer to a buffer to validate</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">size</span></code></dt><dd><p>size of the buffer</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Returns true on valid VBT.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>find VBT and initialize settings from the BIOS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Parse and initialize settings from the Video BIOS Tables (VBT). If the VBT
was not found in ACPI OpRegion, try to find it in PCI ROM first. Also
initialize some defaults if the VBT is not present at all.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_driver_remove">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_driver_remove</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_driver_remove" title="Link to this definition">¶</a><br /></dt>
<dd><p>Free any resources allocated by <a class="reference internal" href="#c.intel_bios_init" title="intel_bios_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_bios_init()</span></code></a></p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_is_tv_present">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_is_tv_present</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_is_tv_present" title="Link to this definition">¶</a><br /></dt>
<dd><p>is integrated TV present in VBT</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return true if TV is present. If no child devices were parsed from VBT,
assume TV is present.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_is_lvds_present">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_is_lvds_present</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="n"><span class="pre">u8</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i2c_pin</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_is_lvds_present" title="Link to this definition">¶</a><br /></dt>
<dd><p>is LVDS present in VBT</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u8</span> <span class="pre">*i2c_pin</span></code></dt><dd><p>i2c pin for LVDS if present</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return true if LVDS is present. If no child devices were parsed from VBT,
assume LVDS is present.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_is_port_present">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_is_port_present</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_bios_is_port_present" title="port"><span class="n"><span class="pre">port</span></span></a><span class="w"> </span><span class="n"><span class="pre">port</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_is_port_present" title="Link to this definition">¶</a><br /></dt>
<dd><p>is the specified digital port present</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">port</span> <span class="pre">port</span></code></dt><dd><p>port to check</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return true if the device in <code class="docutils literal notranslate"><span class="pre">port</span></code> is present.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_bios_is_dsi_present">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_bios_is_dsi_present</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_bios_is_dsi_present" title="port"><span class="n"><span class="pre">port</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">port</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_bios_is_dsi_present" title="Link to this definition">¶</a><br /></dt>
<dd><p>is DSI present in VBT</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">port</span> <span class="pre">*port</span></code></dt><dd><p>port for DSI if present</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return true if DSI is present, and return the port in <code class="docutils literal notranslate"><span class="pre">port</span></code>.</p>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.vbt_header">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">vbt_header</span></span></span><a class="headerlink" href="#c.vbt_header" title="Link to this definition">¶</a><br /></dt>
<dd><p>VBT Header structure</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct vbt_header {
u8 signature[20];
u16 version;
u16 header_size;
u16 vbt_size;
u8 vbt_checksum;
u8 reserved0;
u32 bdb_offset;
u32 aim_offset[4];
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">signature</span></code></dt><dd><p>VBT signature, always starts with “$VBT”</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">version</span></code></dt><dd><p>Version of this structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">header_size</span></code></dt><dd><p>Size of this structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">vbt_size</span></code></dt><dd><p>Size of VBT (VBT Header, BDB Header and data blocks)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">vbt_checksum</span></code></dt><dd><p>Checksum</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">reserved0</span></code></dt><dd><p>Reserved</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bdb_offset</span></code></dt><dd><p>Offset of <a class="reference internal" href="#c.bdb_header" title="bdb_header"><code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">bdb_header</span></code></a> from beginning of VBT</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">aim_offset</span></code></dt><dd><p>Offsets of add-in data blocks from beginning of VBT</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.bdb_header">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">bdb_header</span></span></span><a class="headerlink" href="#c.bdb_header" title="Link to this definition">¶</a><br /></dt>
<dd><p>BDB Header structure</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct bdb_header {
u8 signature[16];
u16 version;
u16 header_size;
u16 bdb_size;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">signature</span></code></dt><dd><p>BDB signature “BIOS_DATA_BLOCK”</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">version</span></code></dt><dd><p>Version of the data block definitions</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">header_size</span></code></dt><dd><p>Size of this structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bdb_size</span></code></dt><dd><p>Size of BDB (BDB Header and data blocks)</p>
</dd>
</dl>
</div>
</section>
<section id="display-clocks">
<h3>Display clocks<a class="headerlink" href="#display-clocks" title="Link to this heading">¶</a></h3>
<p>The display engine uses several different clocks to do its work. There
are two main clocks involved that aren’t directly related to the actual
pixel clock or any symbol/bit clock of the actual output port. These
are the core display clock (CDCLK) and RAWCLK.</p>
<p>CDCLK clocks most of the display pipe logic, and thus its frequency
must be high enough to support the rate at which pixels are flowing
through the pipes. Downscaling must also be accounted as that increases
the effective pixel rate.</p>
<p>On several platforms the CDCLK frequency can be changed dynamically
to minimize power consumption for a given display configuration.
Typically changes to the CDCLK frequency require all the display pipes
to be shut down while the frequency is being changed.</p>
<p>On SKL+ the DMC will toggle the CDCLK off/on during DC5/6 entry/exit.
DMC will not change the active CDCLK frequency however, so that part
will still be performed by the driver directly.</p>
<p>There are multiple components involved in the generation of the CDCLK
frequency:</p>
<ul class="simple">
<li><p>We have the CDCLK PLL, which generates an output clock based on a
reference clock and a ratio parameter.</p></li>
<li><p>The CD2X Divider, which divides the output of the PLL based on a
divisor selected from a set of pre-defined choices.</p></li>
<li><p>The CD2X Squasher, which further divides the output based on a
waveform represented as a sequence of bits where each zero
“squashes out” a clock cycle.</p></li>
<li><p>And, finally, a fixed divider that divides the output frequency by 2.</p></li>
</ul>
<p>As such, the resulting CDCLK frequency can be calculated with the
following formula:</p>
<blockquote>
<div><p>cdclk = vco / cd2x_div / (sq_len / sq_div) / 2</p>
</div></blockquote>
<p>, where vco is the frequency generated by the PLL; cd2x_div
represents the CD2X Divider; sq_len and sq_div are the bit length
and the number of high bits for the CD2X Squasher waveform, respectively;
and 2 represents the fixed divider.</p>
<p>Note that some older platforms do not contain the CD2X Divider
and/or CD2X Squasher, in which case we can ignore their respective
factors in the formula above.</p>
<p>Several methods exist to change the CDCLK frequency, which ones are
supported depends on the platform:</p>
<ul class="simple">
<li><p>Full PLL disable + re-enable with new VCO frequency. Pipes must be inactive.</p></li>
<li><p>CD2X divider update. Single pipe can be active as the divider update
can be synchronized with the pipe’s start of vblank.</p></li>
<li><p>Crawl the PLL smoothly to the new VCO frequency. Pipes can be active.</p></li>
<li><p>Squash waveform update. Pipes can be active.</p></li>
<li><p>Crawl and squash can also be done back to back. Pipes can be active.</p></li>
</ul>
<p>RAWCLK is a fixed frequency clock, often used by various auxiliary
blocks such as AUX CH or backlight PWM. Hence the only thing we
really need to know about RAWCLK is its frequency so that various
dividers can be programmed correctly.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cdclk_init_hw">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cdclk_init_hw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cdclk_init_hw" title="Link to this definition">¶</a><br /></dt>
<dd><p>Initialize CDCLK hardware</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Initialize CDCLK. This consists mainly of initializing display->cdclk.hw and
sanitizing the state of the hardware if needed. This is generally done only
during the display core initialization sequence, after which the DMC will
take care of turning CDCLK off/on as needed.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cdclk_uninit_hw">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cdclk_uninit_hw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cdclk_uninit_hw" title="Link to this definition">¶</a><br /></dt>
<dd><p>Uninitialize CDCLK hardware</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Uninitialize CDCLK. This is done only during the display core
uninitialization sequence.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cdclk_clock_changed">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cdclk_clock_changed</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">a</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cdclk_clock_changed" title="Link to this definition">¶</a><br /></dt>
<dd><p>Check whether the clock changed</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*a</span></code></dt><dd><p>first CDCLK configuration</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*b</span></code></dt><dd><p>second CDCLK configuration</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>True if CDCLK changed in a way that requires re-programming and
False otherwise.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cdclk_can_cd2x_update">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cdclk_can_cd2x_update</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">a</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cdclk_can_cd2x_update" title="Link to this definition">¶</a><br /></dt>
<dd><p>Determine if changing between the two CDCLK configurations requires only a cd2x divider update</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*a</span></code></dt><dd><p>first CDCLK configuration</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*b</span></code></dt><dd><p>second CDCLK configuration</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>True if changing between the two CDCLK configurations
can be done with just a cd2x divider update, false if not.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_cdclk_changed">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_cdclk_changed</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">a</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_cdclk_config</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_cdclk_changed" title="Link to this definition">¶</a><br /></dt>
<dd><p>Determine if two CDCLK configurations are different</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*a</span></code></dt><dd><p>first CDCLK configuration</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_cdclk_config</span> <span class="pre">*b</span></code></dt><dd><p>second CDCLK configuration</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>True if the CDCLK configurations don’t match, false if they do.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_set_cdclk_pre_plane_update">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_set_cdclk_pre_plane_update</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_set_cdclk_pre_plane_update" title="Link to this definition">¶</a><br /></dt>
<dd><p>Push the CDCLK state to the hardware</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>intel atomic state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Program the hardware before updating the HW plane state based on the
new CDCLK state, if necessary.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_set_cdclk_post_plane_update">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_set_cdclk_post_plane_update</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_set_cdclk_post_plane_update" title="Link to this definition">¶</a><br /></dt>
<dd><p>Push the CDCLK state to the hardware</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>intel atomic state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Program the hardware after updating the HW plane state based on the
new CDCLK state, if necessary.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_update_max_cdclk">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_update_max_cdclk</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_update_max_cdclk" title="Link to this definition">¶</a><br /></dt>
<dd><p>Determine the maximum support CDCLK frequency</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Determine the maximum CDCLK frequency the platform supports, and also
derive the maximum dot clock frequency the maximum CDCLK frequency
allows.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_update_cdclk">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_update_cdclk</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_update_cdclk" title="Link to this definition">¶</a><br /></dt>
<dd><p>Determine the current CDCLK frequency</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Determine the current CDCLK frequency.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_read_rawclk">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_read_rawclk</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_read_rawclk" title="Link to this definition">¶</a><br /></dt>
<dd><p>Determine the current RAWCLK frequency</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Determine the current RAWCLK frequency. RAWCLK is a fixed
frequency clock so this needs to done only once.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_init_cdclk_hooks">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_init_cdclk_hooks</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_init_cdclk_hooks" title="Link to this definition">¶</a><br /></dt>
<dd><p>Initialize CDCLK related modesetting hooks</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>display instance</p>
</dd>
</dl>
</div>
</section>
<section id="display-plls">
<h3>Display PLLs<a class="headerlink" href="#display-plls" title="Link to this heading">¶</a></h3>
<p>Display PLLs used for driving outputs vary by platform. While some have
per-pipe or per-encoder dedicated PLLs, others allow the use of any PLL
from a pool. In the latter scenario, it is possible that multiple pipes
share a PLL if their configurations match.</p>
<p>This file provides an abstraction over display PLLs. The function
<a class="reference internal" href="#c.intel_dpll_init" title="intel_dpll_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_init()</span></code></a> initializes the PLLs for the given platform. The
users of a PLL are tracked and that tracking is integrated with the atomic
modset interface. During an atomic operation, required PLLs can be reserved
for a given CRTC and encoder configuration by calling
<a class="reference internal" href="#c.intel_dpll_reserve" title="intel_dpll_reserve"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_reserve()</span></code></a> and previously reserved PLLs can be released
with <a class="reference internal" href="#c.intel_dpll_release" title="intel_dpll_release"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_release()</span></code></a>.
Changes to the users are first staged in the atomic state, and then made
effective by calling <a class="reference internal" href="#c.intel_dpll_swap_state" title="intel_dpll_swap_state"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_swap_state()</span></code></a> during the atomic
commit phase.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_get_dpll_by_id">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll" title="intel_dpll"><span class="n"><span class="pre">intel_dpll</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">intel_get_dpll_by_id</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll_id" title="intel_dpll_id"><span class="n"><span class="pre">intel_dpll_id</span></span></a><span class="w"> </span><span class="n"><span class="pre">id</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_get_dpll_by_id" title="Link to this definition">¶</a><br /></dt>
<dd><p>get a DPLL given its id</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">intel_dpll_id</span> <span class="pre">id</span></code></dt><dd><p>pll id</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>A pointer to the DPLL with <strong>id</strong></p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_enable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_enable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_enable" title="Link to this definition">¶</a><br /></dt>
<dd><p>enable a CRTC’s DPLL</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>CRTC, and its state, which has a DPLL</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Enable DPLL used by <strong>crtc</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>disable a CRTC’s shared DPLL</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>CRTC, and its state, which has a shared DPLL</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Disable DPLL used by <strong>crtc</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_crtc_get">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_crtc_get</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll" title="intel_dpll"><span class="n"><span class="pre">intel_dpll</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pll</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll_state" title="intel_dpll_state"><span class="n"><span class="pre">intel_dpll_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dpll_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_crtc_get" title="Link to this definition">¶</a><br /></dt>
<dd><p>Get a DPLL reference for a CRTC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>CRTC on which behalf the reference is taken</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll</span> <span class="pre">*pll</span></code></dt><dd><p>DPLL for which the reference is taken</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dpll_state</span> <span class="pre">*dpll_state</span></code></dt><dd><p>the DPLL atomic state in which the reference is tracked</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Take a reference for <strong>pll</strong> tracking the use of it by <strong>crtc</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_crtc_put">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_crtc_put</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll" title="intel_dpll"><span class="n"><span class="pre">intel_dpll</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pll</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll_state" title="intel_dpll_state"><span class="n"><span class="pre">intel_dpll_state</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dpll_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_crtc_put" title="Link to this definition">¶</a><br /></dt>
<dd><p>Drop a DPLL reference for a CRTC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>CRTC on which behalf the reference is dropped</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll</span> <span class="pre">*pll</span></code></dt><dd><p>DPLL for which the reference is dropped</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dpll_state</span> <span class="pre">*dpll_state</span></code></dt><dd><p>the DPLL atomic state in which the reference is tracked</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Drop a reference for <strong>pll</strong> tracking the end of use of it by <strong>crtc</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_swap_state">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_swap_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_swap_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>make atomic DPLL configuration effective</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>atomic state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is the dpll version of <a class="reference internal" href="drm-kms-helpers.html#c.drm_atomic_helper_swap_state" title="drm_atomic_helper_swap_state"><code class="xref c c-func docutils literal notranslate"><span class="pre">drm_atomic_helper_swap_state()</span></code></a> since the
helper does not handle driver-specific global state.</p>
<p>For consistency with atomic helpers this function does a complete swap,
i.e. it also puts the current state into <strong>state</strong>, even though there is no
need for that at this moment.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.icl_set_active_port_dpll">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">icl_set_active_port_dpll</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc_state</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">icl_port_dpll_id</span></span><span class="w"> </span><span class="n"><span class="pre">port_dpll_id</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.icl_set_active_port_dpll" title="Link to this definition">¶</a><br /></dt>
<dd><p>select the active port DPLL for a given CRTC</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc_state</span> <span class="pre">*crtc_state</span></code></dt><dd><p>state for the CRTC to select the DPLL for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">icl_port_dpll_id</span> <span class="pre">port_dpll_id</span></code></dt><dd><p>the active <strong>port_dpll_id</strong> to select</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Select the given <strong>port_dpll_id</strong> instance from the DPLLs reserved for the
CRTC.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_init">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>Initialize DPLLs</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Initialize DPLLs for <strong>display</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_compute">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_compute</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_compute" title="Link to this definition">¶</a><br /></dt>
<dd><p>compute DPLL state CRTC and encoder combination</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>CRTC to compute DPLLs for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>encoder</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function computes the DPLL state for the given CRTC and encoder.</p>
<p>The new configuration in the atomic commit <strong>state</strong> is made effective by
calling <a class="reference internal" href="#c.intel_dpll_swap_state" title="intel_dpll_swap_state"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_swap_state()</span></code></a>.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_reserve">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_reserve</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_reserve" title="Link to this definition">¶</a><br /></dt>
<dd><p>reserve DPLLs for CRTC and encoder combination</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>CRTC to reserve DPLLs for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>encoder</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function reserves all required DPLLs for the given CRTC and encoder
combination in the current atomic commit <strong>state</strong> and the new <strong>crtc</strong> atomic
state.</p>
<p>The new configuration in the atomic commit <strong>state</strong> is made effective by
calling <a class="reference internal" href="#c.intel_dpll_swap_state" title="intel_dpll_swap_state"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_swap_state()</span></code></a>.</p>
<p>The reserved DPLLs should be released by calling
<a class="reference internal" href="#c.intel_dpll_release" title="intel_dpll_release"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_release()</span></code></a>.</p>
<p><strong>Return</strong></p>
<p>0 if all required DPLLs were successfully reserved,
negative error code otherwise.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_release">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_release</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_release" title="Link to this definition">¶</a><br /></dt>
<dd><p>end use of DPLLs by CRTC in atomic state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>crtc from which the DPLLs are to be released</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function releases all DPLLs reserved by <a class="reference internal" href="#c.intel_dpll_reserve" title="intel_dpll_reserve"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_reserve()</span></code></a>
from the current atomic commit <strong>state</strong> and the old <strong>crtc</strong> atomic state.</p>
<p>The new configuration in the atomic commit <strong>state</strong> is made effective by
calling <a class="reference internal" href="#c.intel_dpll_swap_state" title="intel_dpll_swap_state"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_swap_state()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_update_active">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_update_active</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_encoder</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">encoder</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_update_active" title="Link to this definition">¶</a><br /></dt>
<dd><p>update the active DPLL for a CRTC/encoder</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>the CRTC for which to update the active DPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_encoder</span> <span class="pre">*encoder</span></code></dt><dd><p>encoder determining the type of port DPLL</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Update the active DPLL for the given <strong>crtc</strong>/<strong>encoder</strong> in <strong>crtc</strong>’s atomic state,
from the port DPLLs reserved previously by <a class="reference internal" href="#c.intel_dpll_reserve" title="intel_dpll_reserve"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_dpll_reserve()</span></code></a>. The
DPLL selected will be based on the current mode of the encoder’s port.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_get_freq">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_get_freq</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll" title="intel_dpll"><span class="n"><span class="pre">intel_dpll</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pll</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dpll_hw_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dpll_hw_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_get_freq" title="Link to this definition">¶</a><br /></dt>
<dd><p>calculate the DPLL’s output frequency</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll</span> <span class="pre">*pll</span></code></dt><dd><p>DPLL for which to calculate the output frequency</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll_hw_state</span> <span class="pre">*dpll_hw_state</span></code></dt><dd><p>DPLL state from which to calculate the output frequency</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return the output frequency corresponding to <strong>pll</strong>’s passed in <strong>dpll_hw_state</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_get_hw_state">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_get_hw_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_dpll" title="intel_dpll"><span class="n"><span class="pre">intel_dpll</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pll</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dpll_hw_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dpll_hw_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_get_hw_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>readout the DPLL’s hardware state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display device instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dpll</span> <span class="pre">*pll</span></code></dt><dd><p>DPLL for which to calculate the output frequency</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dpll_hw_state</span> <span class="pre">*dpll_hw_state</span></code></dt><dd><p>DPLL’s hardware state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Read out <strong>pll</strong>’s hardware state into <strong>dpll_hw_state</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_dump_hw_state">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_dump_hw_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_printer" title="drm_printer"><span class="n"><span class="pre">drm_printer</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">p</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dpll_hw_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dpll_hw_state</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_dump_hw_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>dump hw_state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_printer</span> <span class="pre">*p</span></code></dt><dd><p>where to print the state to</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll_hw_state</span> <span class="pre">*dpll_hw_state</span></code></dt><dd><p>hw state to be dumped</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Dumo out the relevant values in <strong>dpll_hw_state</strong>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dpll_compare_hw_state">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_compare_hw_state</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_display</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">display</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dpll_hw_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">a</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dpll_hw_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dpll_compare_hw_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>compare the two states</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_display</span> <span class="pre">*display</span></code></dt><dd><p>intel_display structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll_hw_state</span> <span class="pre">*a</span></code></dt><dd><p>first DPLL hw state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">intel_dpll_hw_state</span> <span class="pre">*b</span></code></dt><dd><p>second DPLL hw state</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Compare DPLL hw states <strong>a</strong> and <strong>b</strong>.</p>
<p><strong>Return</strong></p>
<p>true if the states are equal, false if the differ</p>
</div>
<dl class="c enum">
<dt class="sig sig-object c" id="c.intel_dpll_id">
<span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_id</span></span></span><a class="headerlink" href="#c.intel_dpll_id" title="Link to this definition">¶</a><br /></dt>
<dd><p>possible DPLL ids</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Constants</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_PRIVATE</span></code></dt><dd><p>non-shared dpll in use</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_PCH_PLL_A</span></code></dt><dd><p>DPLL A in ILK, SNB and IVB</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_PCH_PLL_B</span></code></dt><dd><p>DPLL B in ILK, SNB and IVB</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_WRPLL1</span></code></dt><dd><p>HSW and BDW WRPLL1</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_WRPLL2</span></code></dt><dd><p>HSW and BDW WRPLL2</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_SPLL</span></code></dt><dd><p>HSW and BDW SPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_LCPLL_810</span></code></dt><dd><p>HSW and BDW 0.81 GHz LCPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_LCPLL_1350</span></code></dt><dd><p>HSW and BDW 1.35 GHz LCPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_LCPLL_2700</span></code></dt><dd><p>HSW and BDW 2.7 GHz LCPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_SKL_DPLL0</span></code></dt><dd><p>SKL and later DPLL0</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_SKL_DPLL1</span></code></dt><dd><p>SKL and later DPLL1</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_SKL_DPLL2</span></code></dt><dd><p>SKL and later DPLL2</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_SKL_DPLL3</span></code></dt><dd><p>SKL and later DPLL3</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_DPLL0</span></code></dt><dd><p>ICL/TGL combo PHY DPLL0</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_DPLL1</span></code></dt><dd><p>ICL/TGL combo PHY DPLL1</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_EHL_DPLL4</span></code></dt><dd><p>EHL combo PHY DPLL4</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_TBTPLL</span></code></dt><dd><p>ICL/TGL TBT PLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_MGPLL1</span></code></dt><dd><dl class="simple">
<dt>ICL MG PLL 1 port 1 (C),</dt><dd><p>TGL TC PLL 1 port 1 (TC1)</p>
</dd>
</dl>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_MGPLL2</span></code></dt><dd><dl class="simple">
<dt>ICL MG PLL 1 port 2 (D)</dt><dd><p>TGL TC PLL 1 port 2 (TC2)</p>
</dd>
</dl>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_MGPLL3</span></code></dt><dd><dl class="simple">
<dt>ICL MG PLL 1 port 3 (E)</dt><dd><p>TGL TC PLL 1 port 3 (TC3)</p>
</dd>
</dl>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_ICL_MGPLL4</span></code></dt><dd><dl class="simple">
<dt>ICL MG PLL 1 port 4 (F)</dt><dd><p>TGL TC PLL 1 port 4 (TC4)</p>
</dd>
</dl>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_TGL_MGPLL5</span></code></dt><dd><p>TGL TC PLL port 5 (TC5)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_TGL_MGPLL6</span></code></dt><dd><p>TGL TC PLL port 6 (TC6)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_DG1_DPLL0</span></code></dt><dd><p>DG1 combo PHY DPLL0</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_DG1_DPLL1</span></code></dt><dd><p>DG1 combo PHY DPLL1</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_DG1_DPLL2</span></code></dt><dd><p>DG1 combo PHY DPLL2</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">DPLL_ID_DG1_DPLL3</span></code></dt><dd><p>DG1 combo PHY DPLL3</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>Enumeration of possible IDs for a DPLL. Real shared dpll ids must be >= 0.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.intel_dpll_state">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll_state</span></span></span><a class="headerlink" href="#c.intel_dpll_state" title="Link to this definition">¶</a><br /></dt>
<dd><p>hold the DPLL atomic state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct intel_dpll_state {
u8 pipe_mask;
struct intel_dpll_hw_state hw_state;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">pipe_mask</span></code></dt><dd><p>mask of pipes using this DPLL, active or not</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hw_state</span></code></dt><dd><p>hardware configuration for the DPLL stored in
struct <code class="xref c c-type docutils literal notranslate"><span class="pre">intel_dpll_hw_state</span></code>.</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>This structure holds an atomic state for the DPLL, that can represent
either its current state (in struct <code class="xref c c-type docutils literal notranslate"><span class="pre">intel_shared_dpll</span></code>) or a desired
future state which would be applied by an atomic mode set (stored in
a struct <code class="xref c c-type docutils literal notranslate"><span class="pre">intel_atomic_state</span></code>).</p>
<p>See also <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_reserve_shared_dplls()</span></code> and <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_release_shared_dplls()</span></code>.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.dpll_info">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">dpll_info</span></span></span><a class="headerlink" href="#c.dpll_info" title="Link to this definition">¶</a><br /></dt>
<dd><p>display PLL platform specific info</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct dpll_info {
const char *name;
const struct intel_dpll_funcs *funcs;
enum intel_dpll_id id;
enum intel_display_power_domain power_domain;
bool always_on;
bool is_alt_port_dpll;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">name</span></code></dt><dd><p>DPLL name; used for logging</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">funcs</span></code></dt><dd><p>platform specific hooks</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">id</span></code></dt><dd><p>unique identifier for this DPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">power_domain</span></code></dt><dd><p>extra power domain required by the DPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">always_on</span></code></dt><dd><p>Inform the state checker that the DPLL is kept enabled even if
not in use by any CRTC.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">is_alt_port_dpll</span></code></dt><dd><p>Inform the state checker that the DPLL can be used as a fallback
(for TC->TBT fallback).</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.intel_dpll">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dpll</span></span></span><a class="headerlink" href="#c.intel_dpll" title="Link to this definition">¶</a><br /></dt>
<dd><p>display PLL with tracked state and users</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct intel_dpll {
struct intel_dpll_state state;
u8 index;
u8 active_mask;
bool on;
const struct dpll_info *info;
intel_wakeref_t wakeref;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">state</span></code></dt><dd><p>Store the state for the pll, including its hw state
and CRTCs using it.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">index</span></code></dt><dd><p>index for atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">active_mask</span></code></dt><dd><p>mask of active pipes (i.e. DPMS on) using this DPLL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">on</span></code></dt><dd><p>is the PLL actually active? Disabled during modeset</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">info</span></code></dt><dd><p>platform specific info</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">wakeref</span></code></dt><dd><p>In some platforms a device-level runtime pm reference may
need to be grabbed to disable DC states while this DPLL is enabled</p>
</dd>
</dl>
</div>
</section>
<section id="display-state-buffer">
<h3>Display State Buffer<a class="headerlink" href="#display-state-buffer" title="Link to this heading">¶</a></h3>
<p>A DSB (Display State Buffer) is a queue of MMIO instructions in the memory
which can be offloaded to DSB HW in Display Controller. DSB HW is a DMA
engine that can be programmed to download the DSB from memory.
It allows driver to batch submit display HW programming. This helps to
reduce loading time and CPU activity, thereby making the context switch
faster. DSB Support added from Gen12 Intel graphics based platform.</p>
<p>DSB’s can access only the pipe, plane, and transcoder Data Island Packet
registers.</p>
<p>DSB HW can support only register writes (both indexed and direct MMIO
writes). There are no registers reads possible with DSB HW engine.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dsb_reg_write_indexed">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dsb_reg_write_indexed</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dsb</span></span>, <span class="n"><span class="pre">i915_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">val</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dsb_reg_write_indexed" title="Link to this definition">¶</a><br /></dt>
<dd><p>Emit indexed register write to the DSB context</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dsb</span> <span class="pre">*dsb</span></code></dt><dd><p>DSB context</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>register address.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">val</span></code></dt><dd><p>value.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is used for writing register-value pair in command
buffer of DSB.</p>
<p>Note that indexed writes are slower than normal MMIO writes
for a small number (less than 5 or so) of writes to the same
register.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dsb_commit">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dsb_commit</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dsb</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dsb_commit" title="Link to this definition">¶</a><br /></dt>
<dd><p>Trigger workload execution of DSB.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dsb</span> <span class="pre">*dsb</span></code></dt><dd><p>DSB context</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is used to do actual write to hardware using DSB.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dsb_prepare">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">intel_dsb_prepare</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_atomic_state</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">state</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_crtc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">crtc</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb_id</span></span><span class="w"> </span><span class="n"><span class="pre">dsb_id</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">max_cmds</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dsb_prepare" title="Link to this definition">¶</a><br /></dt>
<dd><p>Allocate, pin and map the DSB command buffer.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_atomic_state</span> <span class="pre">*state</span></code></dt><dd><p>the atomic state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_crtc</span> <span class="pre">*crtc</span></code></dt><dd><p>the CRTC</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">intel_dsb_id</span> <span class="pre">dsb_id</span></code></dt><dd><p>the DSB engine to use</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">max_cmds</span></code></dt><dd><p>number of commands we need to fit into command buffer</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function prepare the command buffer which is used to store dsb
instructions with data.</p>
<p><strong>Return</strong></p>
<p>DSB context, NULL on failure</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_dsb_cleanup">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_dsb_cleanup</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_dsb</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dsb</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_dsb_cleanup" title="Link to this definition">¶</a><br /></dt>
<dd><p>To cleanup DSB context.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_dsb</span> <span class="pre">*dsb</span></code></dt><dd><p>DSB context</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function cleanup the DSB context by unpinning and releasing
the VMA object associated with it.</p>
</div>
</section>
</section>
<section id="gt-programming">
<h2>GT Programming<a class="headerlink" href="#gt-programming" title="Link to this heading">¶</a></h2>
<section id="multicast-replicated-mcr-registers">
<h3>Multicast/Replicated (MCR) Registers<a class="headerlink" href="#multicast-replicated-mcr-registers" title="Link to this heading">¶</a></h3>
<p>Some GT registers are designed as “multicast” or “replicated” registers:
multiple instances of the same register share a single MMIO offset. MCR
registers are generally used when the hardware needs to potentially track
independent values of a register per hardware unit (e.g., per-subslice,
per-L3bank, etc.). The specific types of replication that exist vary
per-platform.</p>
<p>MMIO accesses to MCR registers are controlled according to the settings
programmed in the platform’s MCR_SELECTOR register(s). MMIO writes to MCR
registers can be done in either a (i.e., a single write updates all
instances of the register to the same value) or unicast (a write updates only
one specific instance). Reads of MCR registers always operate in a unicast
manner regardless of how the multicast/unicast bit is set in MCR_SELECTOR.
Selection of a specific MCR instance for unicast operations is referred to
as “steering.”</p>
<p>If MCR register operations are steered toward a hardware unit that is
fused off or currently powered down due to power gating, the MMIO operation
is “terminated” by the hardware. Terminated read operations will return a
value of zero and terminated unicast write operations will be silently
ignored.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_lock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_lock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_lock" title="Link to this definition">¶</a><br /></dt>
<dd><p>Acquire MCR steering lock</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">*flags</span></code></dt><dd><p>storage to save IRQ flags to</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Performs locking to protect the steering for the duration of an MCR
operation. On MTL and beyond, a hardware lock will also be taken to
serialize access not only for the driver, but also for external hardware and
firmware agents.</p>
<p><strong>Context</strong></p>
<p>Takes gt->mcr_lock. uncore->lock should <em>not</em> be held when this
function is called, although it may be acquired after this
function call.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_unlock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_unlock</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_unlock" title="Link to this definition">¶</a><br /></dt>
<dd><p>Release MCR steering lock</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">flags</span></code></dt><dd><p>IRQ flags to restore</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Releases the lock acquired by <a class="reference internal" href="#c.intel_gt_mcr_lock" title="intel_gt_mcr_lock"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_gt_mcr_lock()</span></code></a>.</p>
<p><strong>Context</strong></p>
<p>Releases gt->mcr_lock</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_lock_sanitize">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_lock_sanitize</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_lock_sanitize" title="Link to this definition">¶</a><br /></dt>
<dd><p>Sanitize MCR steering lock</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This will be used to sanitize the initial status of the hardware lock
during driver load and resume since there won’t be any concurrent access
from other agents at those times, but it’s possible that boot firmware
may have left the lock in a bad state.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_read">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_read</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">group</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">instance</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_read" title="Link to this definition">¶</a><br /></dt>
<dd><p>read a specific instance of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the MCR register to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">group</span></code></dt><dd><p>the MCR group</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">instance</span></code></dt><dd><p>the MCR instance</p>
</dd>
</dl>
<p><strong>Context</strong></p>
<p>Takes and releases gt->mcr_lock</p>
<p><strong>Description</strong></p>
<p>Returns the value read from an MCR register after steering toward a specific
group/instance.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_unicast_write">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_unicast_write</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">group</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">instance</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_unicast_write" title="Link to this definition">¶</a><br /></dt>
<dd><p>write a specific instance of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the MCR register to write</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>value to write</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">group</span></code></dt><dd><p>the MCR group</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">instance</span></code></dt><dd><p>the MCR instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Write an MCR register in unicast mode after steering toward a specific
group/instance.</p>
<p><strong>Context</strong></p>
<p>Calls a function that takes and releases gt->mcr_lock</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_multicast_write">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_multicast_write</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_multicast_write" title="Link to this definition">¶</a><br /></dt>
<dd><p>write a value to all instances of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the MCR register to write</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>value to write</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Write an MCR register in multicast mode to update all instances.</p>
<p><strong>Context</strong></p>
<p>Takes and releases gt->mcr_lock</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_multicast_write_fw">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_multicast_write_fw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_multicast_write_fw" title="Link to this definition">¶</a><br /></dt>
<dd><p>write a value to all instances of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the MCR register to write</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>value to write</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Write an MCR register in multicast mode to update all instances. This
function assumes the caller is already holding any necessary forcewake
domains; use <a class="reference internal" href="#c.intel_gt_mcr_multicast_write" title="intel_gt_mcr_multicast_write"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_gt_mcr_multicast_write()</span></code></a> in cases where forcewake should
be obtained automatically.</p>
<p><strong>Context</strong></p>
<p>The caller must hold gt->mcr_lock.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_multicast_rmw">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_multicast_rmw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">clear</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">set</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_multicast_rmw" title="Link to this definition">¶</a><br /></dt>
<dd><p>Performs a multicast RMW operations</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the MCR register to read and write</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">clear</span></code></dt><dd><p>bits to clear during RMW</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">set</span></code></dt><dd><p>bits to set during RMW</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Performs a read-modify-write on an MCR register in a multicast manner.
This operation only makes sense on MCR registers where all instances are
expected to have the same value. The read will target any non-terminated
instance and the write will be applied to all instances.</p>
<p>This function assumes the caller is already holding any necessary forcewake
domains; use <a class="reference internal" href="#c.intel_gt_mcr_multicast_rmw" title="intel_gt_mcr_multicast_rmw"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_gt_mcr_multicast_rmw()</span></code></a> in cases where forcewake should
be obtained automatically.</p>
<p>Returns the old (unmodified) value read.</p>
<p><strong>Context</strong></p>
<p>Calls functions that take and release gt->mcr_lock</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_get_nonterminated_steering">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_get_nonterminated_steering</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u8</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">group</span></span>, <span class="n"><span class="pre">u8</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">instance</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_get_nonterminated_steering" title="Link to this definition">¶</a><br /></dt>
<dd><p>find group/instance values that will steer a register to a non-terminated instance</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>register for which the steering is required</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u8</span> <span class="pre">*group</span></code></dt><dd><p>return variable for group steering</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u8</span> <span class="pre">*instance</span></code></dt><dd><p>return variable for instance steering</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function returns a group/instance pair that is guaranteed to work for
read steering of the given register. Note that a value will be returned even
if the register is not replicated and therefore does not actually require
steering.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_read_any_fw">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_read_any_fw</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_read_any_fw" title="Link to this definition">¶</a><br /></dt>
<dd><p>reads one instance of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>register to read</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Reads a GT MCR register. The read will be steered to a non-terminated
instance (i.e., one that isn’t fused off or powered down by power gating).
This function assumes the caller is already holding any necessary forcewake
domains; use <a class="reference internal" href="#c.intel_gt_mcr_read_any" title="intel_gt_mcr_read_any"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_gt_mcr_read_any()</span></code></a> in cases where forcewake should be
obtained automatically.</p>
<p>Returns the value from a non-terminated instance of <strong>reg</strong>.</p>
<p><strong>Context</strong></p>
<p>The caller must hold gt->mcr_lock.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_read_any">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_read_any</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_read_any" title="Link to this definition">¶</a><br /></dt>
<dd><p>reads one instance of an MCR register</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>register to read</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Reads a GT MCR register. The read will be steered to a non-terminated
instance (i.e., one that isn’t fused off or powered down by power gating).</p>
<p>Returns the value from a non-terminated instance of <strong>reg</strong>.</p>
<p><strong>Context</strong></p>
<p>Calls a function that takes and releases gt->mcr_lock.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_get_ss_steering">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_get_ss_steering</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">dss</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">group</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">instance</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_get_ss_steering" title="Link to this definition">¶</a><br /></dt>
<dd><p>returns the group/instance steering for a SS</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">dss</span></code></dt><dd><p>DSS ID to obtain steering for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">*group</span></code></dt><dd><p>pointer to storage for steering group ID</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">*instance</span></code></dt><dd><p>pointer to storage for steering instance ID</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Returns the steering IDs (via the <strong>group</strong> and <strong>instance</strong> parameters) that
correspond to a specific subslice/DSS ID.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_gt_mcr_wait_for_reg">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_gt_mcr_wait_for_reg</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_gt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">gt</span></span>, <span class="n"><span class="pre">i915_mcr_reg_t</span></span><span class="w"> </span><span class="n"><span class="pre">reg</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">mask</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">value</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">fast_timeout_us</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">slow_timeout_ms</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_gt_mcr_wait_for_reg" title="Link to this definition">¶</a><br /></dt>
<dd><p>wait until MCR register matches expected state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_gt</span> <span class="pre">*gt</span></code></dt><dd><p>GT structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">i915_mcr_reg_t</span> <span class="pre">reg</span></code></dt><dd><p>the register to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">mask</span></code></dt><dd><p>mask to apply to register value</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">value</span></code></dt><dd><p>value to wait for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">fast_timeout_us</span></code></dt><dd><p>fast timeout in microsecond for atomic/tight wait</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">slow_timeout_ms</span></code></dt><dd><p>slow timeout in millisecond</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This routine waits until the target register <strong>reg</strong> contains the expected
<strong>value</strong> after applying the <strong>mask</strong>, i.e. it waits until</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>(intel_gt_mcr_read_any_fw(gt, reg) & mask) == value
</pre></div>
</div>
<p>Otherwise, the wait will timeout after <strong>slow_timeout_ms</strong> milliseconds.
For atomic context <strong>slow_timeout_ms</strong> must be zero and <strong>fast_timeout_us</strong>
must be not larger than 20,0000 microseconds.</p>
<p>This function is basically an MCR-friendly version of
<a class="reference internal" href="#c.__intel_wait_for_register_fw" title="__intel_wait_for_register_fw"><code class="xref c c-func docutils literal notranslate"><span class="pre">__intel_wait_for_register_fw()</span></code></a>. Generally this function will only be used
on GAM registers which are a bit special --- although they’re MCR registers,
reads (e.g., waiting for status updates) are always directed to the primary
instance.</p>
<p>Note that this routine assumes the caller holds forcewake asserted, it is
not suitable for very long waits.</p>
<p><strong>Context</strong></p>
<p>Calls a function that takes and releases gt->mcr_lock</p>
<p><strong>Return</strong></p>
<p>0 if the register matches the desired condition, or -ETIMEDOUT.</p>
</div>
</section>
</section>
<section id="memory-management-and-command-submission">
<h2>Memory Management and Command Submission<a class="headerlink" href="#memory-management-and-command-submission" title="Link to this heading">¶</a></h2>
<p>This sections covers all things related to the GEM implementation in the
i915 driver.</p>
<section id="intel-gpu-basics">
<h3>Intel GPU Basics<a class="headerlink" href="#intel-gpu-basics" title="Link to this heading">¶</a></h3>
<p>An Intel GPU has multiple engines. There are several engine types:</p>
<ul class="simple">
<li><p>Render Command Streamer (RCS). An engine for rendering 3D and
performing compute.</p></li>
<li><p>Blitting Command Streamer (BCS). An engine for performing blitting and/or
copying operations.</p></li>
<li><p>Video Command Streamer. An engine used for video encoding and decoding. Also
sometimes called ‘BSD’ in hardware documentation.</p></li>
<li><p>Video Enhancement Command Streamer (VECS). An engine for video enhancement.
Also sometimes called ‘VEBOX’ in hardware documentation.</p></li>
<li><p>Compute Command Streamer (CCS). An engine that has access to the media and
GPGPU pipelines, but not the 3D pipeline.</p></li>
<li><p>Graphics Security Controller (GSCCS). A dedicated engine for internal
communication with GSC controller on security related tasks like
High-bandwidth Digital Content Protection (HDCP), Protected Xe Path (PXP),
and HuC firmware authentication.</p></li>
</ul>
<p>The Intel GPU family is a family of integrated GPU’s using Unified
Memory Access. For having the GPU “do work”, user space will feed the
GPU batch buffers via one of the ioctls <cite>DRM_IOCTL_I915_GEM_EXECBUFFER2</cite>
or <cite>DRM_IOCTL_I915_GEM_EXECBUFFER2_WR</cite>. Most such batchbuffers will
instruct the GPU to perform work (for example rendering) and that work
needs memory from which to read and memory to which to write. All memory
is encapsulated within GEM buffer objects (usually created with the ioctl
<cite>DRM_IOCTL_I915_GEM_CREATE</cite>). An ioctl providing a batchbuffer for the GPU
to create will also list all GEM buffer objects that the batchbuffer reads
and/or writes. For implementation details of memory management see
<a class="reference internal" href="#gem-bo-management-implementation-details">GEM BO Management Implementation Details</a>.</p>
<p>The i915 driver allows user space to create a context via the ioctl
<cite>DRM_IOCTL_I915_GEM_CONTEXT_CREATE</cite> which is identified by a 32-bit
integer. Such a context should be viewed by user-space as -loosely-
analogous to the idea of a CPU process of an operating system. The i915
driver guarantees that commands issued to a fixed context are to be
executed so that writes of a previously issued command are seen by
reads of following commands. Actions issued between different contexts
(even if from the same file descriptor) are NOT given that guarantee
and the only way to synchronize across contexts (even from the same
file descriptor) is through the use of fences. At least as far back as
Gen4, also have that a context carries with it a GPU HW context;
the HW context is essentially (most of at least) the state of a GPU.
In addition to the ordering guarantees, the kernel will restore GPU
state via HW context when commands are issued to a context, this saves
user space the need to restore (most of at least) the GPU state at the
start of each batchbuffer. The non-deprecated ioctls to submit batchbuffer
work can pass that ID (in the lower bits of drm_i915_gem_execbuffer2::rsvd1)
to identify what context to use with the command.</p>
<p>The GPU has its own memory management and address space. The kernel
driver maintains the memory translation table for the GPU. For older
GPUs (i.e. those before Gen8), there is a single global such translation
table, a global Graphics Translation Table (GTT). For newer generation
GPUs each context has its own translation table, called Per-Process
Graphics Translation Table (PPGTT). Of important note, is that although
PPGTT is named per-process it is actually per context. When user space
submits a batchbuffer, the kernel walks the list of GEM buffer objects
used by the batchbuffer and guarantees that not only is the memory of
each such GEM buffer object resident but it is also present in the
(PP)GTT. If the GEM buffer object is not yet placed in the (PP)GTT,
then it is given an address. Two consequences of this are: the kernel
needs to edit the batchbuffer submitted to write the correct value of
the GPU address when a GEM BO is assigned a GPU address and the kernel
might evict a different GEM BO from the (PP)GTT to make address room
for another GEM BO. Consequently, the ioctls submitting a batchbuffer
for execution also include a list of all locations within buffers that
refer to GPU-addresses so that the kernel can edit the buffer correctly.
This process is dubbed relocation.</p>
</section>
<section id="locking-guidelines">
<h3>Locking Guidelines<a class="headerlink" href="#locking-guidelines" title="Link to this heading">¶</a></h3>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This is a description of how the locking should be after
refactoring is done. Does not necessarily reflect what the locking
looks like while WIP.</p>
</div>
<ol class="arabic">
<li><p>All locking rules and interface contracts with cross-driver interfaces
(dma-buf, dma_fence) need to be followed.</p></li>
<li><p>dma_resv will be the outermost lock (when needed) and ww_acquire_ctx
is to be hoisted at highest level and passed down within i915_gem_ctx
in the call chain</p></li>
<li><p>While holding lru/memory manager (buddy, drm_mm, whatever) locks
system memory allocations are not allowed</p></li>
<li><p>Do not nest different lru/memory manager locks within each other.
Take them in turn to update memory allocations, relying on the object’s
dma_resv ww_mutex to serialize against other operations.</p></li>
<li><p>The suggestion for lru/memory managers locks is that they are small
enough to be spinlocks.</p></li>
<li><p>All features need to come with exhaustive kernel selftests and/or
IGT tests when appropriate</p></li>
<li><p>All LMEM uAPI paths need to be fully restartable (<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_interruptible()</span></code>
for all locks/waits/sleeps)</p>
<blockquote>
<div><ul class="simple">
<li><p>Error handling validation through signal injection.
Still the best strategy we have for validating GEM uAPI
corner cases.
Must be excessively used in the IGT, and we need to check
that we really have full path coverage of all error cases.</p></li>
<li><p>-EDEADLK handling with ww_mutex</p></li>
</ul>
</div></blockquote>
</li>
</ol>
</section>
<section id="gem-bo-management-implementation-details">
<h3>GEM BO Management Implementation Details<a class="headerlink" href="#gem-bo-management-implementation-details" title="Link to this heading">¶</a></h3>
<p>A VMA represents a GEM BO that is bound into an address space. Therefore, a
VMA’s presence cannot be guaranteed before binding, or after unbinding the
object into/from the address space.</p>
<p>To make things as simple as possible (ie. no refcounting), a VMA’s lifetime
will always be <= an objects lifetime. So object refcounting should cover us.</p>
</section>
<section id="buffer-object-eviction">
<h3>Buffer Object Eviction<a class="headerlink" href="#buffer-object-eviction" title="Link to this heading">¶</a></h3>
<p>This section documents the interface functions for evicting buffer
objects to make space available in the virtual gpu address spaces. Note
that this is mostly orthogonal to shrinking buffer objects caches, which
has the goal to make main memory (shared with the gpu through the
unified memory architecture) available.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_evict_something">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_evict_something</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_address_space</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vm</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">min_size</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">alignment</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">color</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">start</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">end</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_evict_something" title="Link to this definition">¶</a><br /></dt>
<dd><p>Evict vmas to make room for binding a new one</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span> <span class="pre">*vm</span></code></dt><dd><p>address space to evict from</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>An optional <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">min_size</span></code></dt><dd><p>size of the desired free space</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">alignment</span></code></dt><dd><p>alignment constraint of the desired free space</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">color</span></code></dt><dd><p>color for the desired space</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">start</span></code></dt><dd><p>start (inclusive) of the range from which to evict objects</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">end</span></code></dt><dd><p>end (exclusive) of the range from which to evict objects</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">flags</span></code></dt><dd><p>additional flags to control the eviction algorithm</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function will try to evict vmas until a free space satisfying the
requirements is found. Callers must check first whether any such hole exists
already before calling this function.</p>
<p>This function is used by the object/vma binding code.</p>
<p>Since this function is only used to free up virtual address space it only
ignores pinned vmas, and not object where the backing storage itself is
pinned. Hence obj->pages_pin_count does not protect against eviction.</p>
<p>To clarify: This is for freeing up virtual address space, not for freeing
memory in e.g. the shrinker.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_evict_for_node">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_evict_for_node</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_address_space</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vm</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-mm.html#c.drm_mm_node" title="drm_mm_node"><span class="n"><span class="pre">drm_mm_node</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">target</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_evict_for_node" title="Link to this definition">¶</a><br /></dt>
<dd><p>Evict vmas to make room for binding a new one</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span> <span class="pre">*vm</span></code></dt><dd><p>address space to evict from</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>An optional <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_mm_node</span> <span class="pre">*target</span></code></dt><dd><p>range (and color) to evict for</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">flags</span></code></dt><dd><p>additional flags to control the eviction algorithm</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function will try to evict vmas that overlap the target node.</p>
<p>To clarify: This is for freeing up virtual address space, not for freeing
memory in e.g. the shrinker.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_evict_vm">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_evict_vm</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_address_space</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vm</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">busy_bo</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_evict_vm" title="Link to this definition">¶</a><br /></dt>
<dd><p>Evict all idle vmas from a vm</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span> <span class="pre">*vm</span></code></dt><dd><p>Address space to cleanse</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>An optional <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span></code>. If not NULL, i915_gem_evict_vm
will be able to evict vma’s locked by the ww as well.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">**busy_bo</span></code></dt><dd><p>Optional pointer to <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span></code>. If not NULL, then
in the event <a class="reference internal" href="#c.i915_gem_evict_vm" title="i915_gem_evict_vm"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_evict_vm()</span></code></a> is unable to trylock an object for eviction,
then <strong>busy_bo</strong> will point to it. -EBUSY is also returned. The caller must drop
the vm->mutex, before trying again to acquire the contended lock. The caller
also owns a reference to the object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function evicts all vmas from a vm.</p>
<p>This is used by the execbuf code as a last-ditch effort to defragment the
address space.</p>
<p>To clarify: This is for freeing up virtual address space, not for freeing
memory in e.g. the shrinker.</p>
</div>
</section>
<section id="buffer-object-memory-shrinking">
<h3>Buffer Object Memory Shrinking<a class="headerlink" href="#buffer-object-memory-shrinking" title="Link to this heading">¶</a></h3>
<p>This section documents the interface function for shrinking memory usage
of buffer object caches. Shrinking is used to make main memory
available. Note that this is mostly orthogonal to evicting buffer
objects, which has the goal to make space in gpu virtual address spaces.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_shrink">
<span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_shrink</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">target</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">nr_scanned</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">shrink</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_shrink" title="Link to this definition">¶</a><br /></dt>
<dd><p>Shrink buffer object caches</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>i915 gem ww acquire ctx, or NULL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">target</span></code></dt><dd><p>amount of memory to make available, in pages</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">*nr_scanned</span></code></dt><dd><p>optional output for number of pages scanned (incremental)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">shrink</span></code></dt><dd><p>control flags for selecting cache types</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function is the main interface to the shrinker. It will try to release
up to <strong>target</strong> pages of main memory backing storage from buffer objects.
Selection of the specific caches can be done with <strong>flags</strong>. This is e.g. useful
when purgeable objects should be removed from caches preferentially.</p>
<p>Note that it’s not guaranteed that released amount is actually available as
free system memory - the pages might still be in-used to due to other reasons
(like cpu mmaps) or the mm core has reused them before we could grab them.
Therefore code that needs to explicitly shrink buffer objects caches (e.g. to
avoid deadlocks in memory reclaim) must fall back to <a class="reference internal" href="#c.i915_gem_shrink_all" title="i915_gem_shrink_all"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_shrink_all()</span></code></a>.</p>
<p>Also note that any kind of pinning (both per-vma address space pins and
backing storage pins at the buffer object level) result in the shrinker code
having to skip the object.</p>
<p><strong>Return</strong></p>
<p>The number of pages of backing storage actually released.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_shrink_all">
<span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_shrink_all</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_shrink_all" title="Link to this definition">¶</a><br /></dt>
<dd><p>Shrink buffer object caches completely</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is a simple wrapper around <a class="reference internal" href="#c.i915_gem_shrink" title="i915_gem_shrink"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_shrink()</span></code></a> to aggressively shrink all
caches completely. It also first waits for and retires all outstanding
requests to also be able to release backing storage for active objects.</p>
<p>This should only be used in code to intentionally quiescent the gpu or as a
last-ditch effort when memory seems to have run out.</p>
<p><strong>Return</strong></p>
<p>The number of pages of backing storage actually released.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_object_make_unshrinkable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_object_make_unshrinkable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_object_make_unshrinkable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Hide the object from the shrinker. By default all object types that support shrinking(see IS_SHRINKABLE), will also make the object visible to the shrinker after allocating the system memory pages.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>The GEM object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is typically used for special kernel internal objects that can’t be
easily processed by the shrinker, like if they are perma-pinned.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.__i915_gem_object_make_shrinkable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">__i915_gem_object_make_shrinkable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.__i915_gem_object_make_shrinkable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Move the object to the tail of the shrinkable list. Objects on this list might be swapped out. Used with WILLNEED objects.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>The GEM object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>DO NOT USE. This is intended to be called on very special objects that don’t
yet have mm.pages, but are guaranteed to have potentially reclaimable pages
underneath.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.__i915_gem_object_make_purgeable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">__i915_gem_object_make_purgeable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.__i915_gem_object_make_purgeable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Move the object to the tail of the purgeable list. Objects on this list might be swapped out. Used with DONTNEED objects.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>The GEM object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>DO NOT USE. This is intended to be called on very special objects that don’t
yet have mm.pages, but are guaranteed to have potentially reclaimable pages
underneath.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_object_make_shrinkable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_object_make_shrinkable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_object_make_shrinkable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Move the object to the tail of the shrinkable list. Objects on this list might be swapped out. Used with WILLNEED objects.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>The GEM object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>MUST only be called on objects which have backing pages.</p>
<p>MUST be balanced with previous call to <a class="reference internal" href="#c.i915_gem_object_make_unshrinkable" title="i915_gem_object_make_unshrinkable"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_object_make_unshrinkable()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_object_make_purgeable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_object_make_purgeable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_object_make_purgeable" title="Link to this definition">¶</a><br /></dt>
<dd><p>Move the object to the tail of the purgeable list. Used with DONTNEED objects. Unlike with shrinkable objects, the shrinker will attempt to discard the backing pages, instead of trying to swap them out.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>The GEM object.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>MUST only be called on objects which have backing pages.</p>
<p>MUST be balanced with previous call to <a class="reference internal" href="#c.i915_gem_object_make_unshrinkable" title="i915_gem_object_make_unshrinkable"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_object_make_unshrinkable()</span></code></a>.</p>
</div>
</section>
<section id="batchbuffer-parsing">
<h3>Batchbuffer Parsing<a class="headerlink" href="#batchbuffer-parsing" title="Link to this heading">¶</a></h3>
<p>Motivation:
Certain OpenGL features (e.g. transform feedback, performance monitoring)
require userspace code to submit batches containing commands such as
MI_LOAD_REGISTER_IMM to access various registers. Unfortunately, some
generations of the hardware will noop these commands in “unsecure” batches
(which includes all userspace batches submitted via i915) even though the
commands may be safe and represent the intended programming model of the
device.</p>
<p>The software command parser is similar in operation to the command parsing
done in hardware for unsecure batches. However, the software parser allows
some operations that would be noop’d by hardware, if the parser determines
the operation is safe, and submits the batch as “secure” to prevent hardware
parsing.</p>
<p>Threats:
At a high level, the hardware (and software) checks attempt to prevent
granting userspace undue privileges. There are three categories of privilege.</p>
<p>First, commands which are explicitly defined as privileged or which should
only be used by the kernel driver. The parser rejects such commands</p>
<p>Second, commands which access registers. To support correct/enhanced
userspace functionality, particularly certain OpenGL extensions, the parser
provides a whitelist of registers which userspace may safely access</p>
<p>Third, commands which access privileged memory (i.e. GGTT, HWS page, etc).
The parser always rejects such commands.</p>
<p>The majority of the problematic commands fall in the MI_* range, with only a
few specific commands on each engine (e.g. PIPE_CONTROL and MI_FLUSH_DW).</p>
<p>Implementation:
Each engine maintains tables of commands and registers which the parser
uses in scanning batch buffers submitted to that engine.</p>
<p>Since the set of commands that the parser must check for is significantly
smaller than the number of commands supported, the parser tables contain only
those commands required by the parser. This generally works because command
opcode ranges have standard command length encodings. So for commands that
the parser does not need to check, it can easily skip them. This is
implemented via a per-engine length decoding vfunc.</p>
<p>Unfortunately, there are a number of commands that do not follow the standard
length encoding for their opcode range, primarily amongst the MI_* commands.
To handle this, the parser provides a way to define explicit “skip” entries
in the per-engine command tables.</p>
<p>Other command table entries map fairly directly to high level categories
mentioned above: rejected, register whitelist. The parser implements a number
of checks, including the privileged memory checks, via a general bitmasking
mechanism.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_engine_init_cmd_parser">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_engine_init_cmd_parser</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_engine_cs</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">engine</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_engine_init_cmd_parser" title="Link to this definition">¶</a><br /></dt>
<dd><p>set cmd parser related fields for an engine</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_engine_cs</span> <span class="pre">*engine</span></code></dt><dd><p>the engine to initialize</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Optionally initializes fields related to batch buffer command parsing in the
<code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_engine_cs</span></code> based on whether the platform requires software
command parsing.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_engine_cleanup_cmd_parser">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_engine_cleanup_cmd_parser</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_engine_cs</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">engine</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_engine_cleanup_cmd_parser" title="Link to this definition">¶</a><br /></dt>
<dd><p>clean up cmd parser related fields</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_engine_cs</span> <span class="pre">*engine</span></code></dt><dd><p>the engine to clean up</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Releases any resources related to command parsing that may have been
initialized for the specified engine.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_engine_cmd_parser">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_engine_cmd_parser</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_engine_cs</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">engine</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">batch</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">batch_offset</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">batch_length</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">shadow</span></span>, <span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="n"><span class="pre">trampoline</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_engine_cmd_parser" title="Link to this definition">¶</a><br /></dt>
<dd><p>parse a batch buffer for privilege violations</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_engine_cs</span> <span class="pre">*engine</span></code></dt><dd><p>the engine on which the batch is to execute</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_vma</span> <span class="pre">*batch</span></code></dt><dd><p>the batch buffer in question</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">batch_offset</span></code></dt><dd><p>byte offset in the batch at which execution starts</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">batch_length</span></code></dt><dd><p>length of the commands in batch_obj</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_vma</span> <span class="pre">*shadow</span></code></dt><dd><p>validated copy of the batch buffer in question</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bool</span> <span class="pre">trampoline</span></code></dt><dd><p>true if we need to trampoline into privileged execution</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Parses the specified batch buffer looking for privilege violations as
described in the overview.</p>
<p><strong>Return</strong></p>
<p>non-zero if the parser finds violations or otherwise fails; -EACCES
if the batch appears legal but should use hardware parsing</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_cmd_parser_get_version">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_cmd_parser_get_version</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev_priv</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_cmd_parser_get_version" title="Link to this definition">¶</a><br /></dt>
<dd><p>get the cmd parser version number</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*dev_priv</span></code></dt><dd><p>i915 device private</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>The cmd parser maintains a simple increasing integer version number suitable
for passing to userspace clients to determine what operations are permitted.</p>
<p><strong>Return</strong></p>
<p>the current version number of the cmd parser</p>
</div>
</section>
<section id="user-batchbuffer-execution">
<h3>User Batchbuffer Execution<a class="headerlink" href="#user-batchbuffer-execution" title="Link to this heading">¶</a></h3>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_gem_engines">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_engines</span></span></span><a class="headerlink" href="#c.i915_gem_engines" title="Link to this definition">¶</a><br /></dt>
<dd><p>A set of engines</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_gem_engines {
union {
struct list_head link;
struct rcu_head rcu;
};
struct i915_sw_fence fence;
struct i915_gem_context *ctx;
unsigned int num_engines;
struct intel_context *engines[];
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">{unnamed_union}</span></code></dt><dd><p>anonymous</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">link</span></code></dt><dd><p>Link in i915_gem_context::stale::engines</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">rcu</span></code></dt><dd><p>RCU to use when freeing</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">fence</span></code></dt><dd><p>Fence used for delayed destruction of engines</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ctx</span></code></dt><dd><p>i915_gem_context backpointer</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">num_engines</span></code></dt><dd><p>Number of engines in this set</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engines</span></code></dt><dd><p>Array of engines</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_gem_engines_iter">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_engines_iter</span></span></span><a class="headerlink" href="#c.i915_gem_engines_iter" title="Link to this definition">¶</a><br /></dt>
<dd><p>Iterator for an i915_gem_engines set</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_gem_engines_iter {
unsigned int idx;
const struct i915_gem_engines *engines;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">idx</span></code></dt><dd><p>Index into i915_gem_engines::engines</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engines</span></code></dt><dd><p>Engine set being iterated</p>
</dd>
</dl>
</div>
<dl class="c enum">
<dt class="sig sig-object c" id="c.i915_gem_engine_type">
<span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_engine_type</span></span></span><a class="headerlink" href="#c.i915_gem_engine_type" title="Link to this definition">¶</a><br /></dt>
<dd><p>Describes the type of an i915_gem_proto_engine</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Constants</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">I915_GEM_ENGINE_TYPE_INVALID</span></code></dt><dd><p>An invalid engine</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">I915_GEM_ENGINE_TYPE_PHYSICAL</span></code></dt><dd><p>A single physical engine</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">I915_GEM_ENGINE_TYPE_BALANCED</span></code></dt><dd><p>A load-balanced engine set</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">I915_GEM_ENGINE_TYPE_PARALLEL</span></code></dt><dd><p>A parallel engine set</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_gem_proto_engine">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_proto_engine</span></span></span><a class="headerlink" href="#c.i915_gem_proto_engine" title="Link to this definition">¶</a><br /></dt>
<dd><p>prototype engine</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_gem_proto_engine {
enum i915_gem_engine_type type;
struct intel_engine_cs *engine;
unsigned int num_siblings;
unsigned int width;
struct intel_engine_cs **siblings;
struct intel_sseu sseu;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">type</span></code></dt><dd><p>Type of this engine</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engine</span></code></dt><dd><p>Engine, for physical</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">num_siblings</span></code></dt><dd><p>Number of balanced or parallel siblings</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">width</span></code></dt><dd><p>Width of each sibling</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">siblings</span></code></dt><dd><p>Balanced siblings or num_siblings * width for parallel</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sseu</span></code></dt><dd><p>Client-set SSEU parameters</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>This <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">describes</span></code> an engine that a context may contain. Engines
have four types:</p>
<blockquote>
<div><ul class="simple">
<li><p>I915_GEM_ENGINE_TYPE_INVALID: Invalid engines can be created but they
show up as a NULL in i915_gem_engines::engines[i] and any attempt to
use them by the user results in -EINVAL. They are also useful during
proto-context construction because the client may create invalid
engines and then set them up later as virtual engines.</p></li>
<li><p>I915_GEM_ENGINE_TYPE_PHYSICAL: A single physical engine, described by
i915_gem_proto_engine::engine.</p></li>
<li><p>I915_GEM_ENGINE_TYPE_BALANCED: A load-balanced engine set, described
i915_gem_proto_engine::num_siblings and i915_gem_proto_engine::siblings.</p></li>
<li><p>I915_GEM_ENGINE_TYPE_PARALLEL: A parallel submission engine set, described
i915_gem_proto_engine::width, i915_gem_proto_engine::num_siblings, and
i915_gem_proto_engine::siblings.</p></li>
</ul>
</div></blockquote>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_gem_proto_context">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_proto_context</span></span></span><a class="headerlink" href="#c.i915_gem_proto_context" title="Link to this definition">¶</a><br /></dt>
<dd><p>prototype context</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_gem_proto_context {
struct drm_i915_file_private *fpriv;
struct i915_address_space *vm;
unsigned long user_flags;
struct i915_sched_attr sched;
int num_user_engines;
struct i915_gem_proto_engine *user_engines;
struct intel_sseu legacy_rcs_sseu;
bool single_timeline;
bool uses_protected_content;
intel_wakeref_t pxp_wakeref;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">fpriv</span></code></dt><dd><p>Client which creates the context</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">vm</span></code></dt><dd><p>See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.vm</span></code></a></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">user_flags</span></code></dt><dd><p>See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.user_flags</span></code></a></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sched</span></code></dt><dd><p>See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.sched</span></code></a></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">num_user_engines</span></code></dt><dd><p>Number of user-specified engines or -1</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">user_engines</span></code></dt><dd><p>User-specified engines</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">legacy_rcs_sseu</span></code></dt><dd><p>Client-set SSEU parameters for the legacy RCS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">single_timeline</span></code></dt><dd><p>See See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.syncobj</span></code></a></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">uses_protected_content</span></code></dt><dd><p>See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.uses_protected_content</span></code></a></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pxp_wakeref</span></code></dt><dd><p>See <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_context.pxp_wakeref</span></code></a></p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>The <a class="reference internal" href="#c.i915_gem_proto_context" title="i915_gem_proto_context"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_proto_context</span></code></a> represents the creation parameters for
a <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_context</span></code></a>. This is used to gather parameters provided
either through creation flags or via SET_CONTEXT_PARAM so that, when we
create the final i915_gem_context, those parameters can be immutable.</p>
<p>The context uAPI allows for two methods of setting context parameters:
SET_CONTEXT_PARAM and CONTEXT_CREATE_EXT_SETPARAM. The former is
allowed to be called at any time while the later happens as part of
GEM_CONTEXT_CREATE. When these were initially added, Currently,
everything settable via one is settable via the other. While some
params are fairly simple and setting them on a live context is harmless
such the context priority, others are far trickier such as the VM or the
set of engines. To avoid some truly nasty race conditions, we don’t
allow setting the VM or the set of engines on live contexts.</p>
<p>The way we dealt with this without breaking older userspace that sets
the VM or engine set via SET_CONTEXT_PARAM is to delay the creation of
the actual context until after the client is done configuring it with
SET_CONTEXT_PARAM. From the perspective of the client, it has the same
u32 context ID the whole time. From the perspective of i915, however,
it’s an i915_gem_proto_context right up until the point where we attempt
to do something which the proto-context can’t handle at which point the
real context gets created.</p>
<p>This is accomplished via a little xarray dance. When GEM_CONTEXT_CREATE
is called, we create a proto-context, reserve a slot in context_xa but
leave it NULL, the proto-context in the corresponding slot in
proto_context_xa. Then, whenever we go to look up a context, we first
check context_xa. If it’s there, we return the i915_gem_context and
we’re done. If it’s not, we look in proto_context_xa and, if we find it
there, we create the actual context and kill the proto-context.</p>
<p>At the time we made this change (April, 2021), we did a fairly complete
audit of existing userspace to ensure this wouldn’t break anything:</p>
<blockquote>
<div><ul class="simple">
<li><p>Mesa/i965 didn’t use the engines or VM APIs at all</p></li>
<li><p>Mesa/ANV used the engines API but via CONTEXT_CREATE_EXT_SETPARAM and
didn’t use the VM API.</p></li>
<li><p>Mesa/iris didn’t use the engines or VM APIs at all</p></li>
<li><p>The open-source compute-runtime didn’t yet use the engines API but
did use the VM API via SET_CONTEXT_PARAM. However, CONTEXT_SETPARAM
was always the second ioctl on that context, immediately following
GEM_CONTEXT_CREATE.</p></li>
<li><p>The media driver sets engines and bonding/balancing via
SET_CONTEXT_PARAM. However, CONTEXT_SETPARAM to set the VM was
always the second ioctl on that context, immediately following
GEM_CONTEXT_CREATE and setting engines immediately followed that.</p></li>
</ul>
</div></blockquote>
<p>In order for this dance to work properly, any modification to an
i915_gem_proto_context that is exposed to the client via
drm_i915_file_private::proto_context_xa must be guarded by
drm_i915_file_private::proto_context_lock. The exception is when a
proto-context has not yet been exposed such as when handling
CONTEXT_CREATE_SET_PARAM during GEM_CONTEXT_CREATE.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_gem_context">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_context</span></span></span><a class="headerlink" href="#c.i915_gem_context" title="Link to this definition">¶</a><br /></dt>
<dd><p>client state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_gem_context {
struct drm_i915_private *i915;
struct drm_i915_file_private *file_priv;
struct i915_gem_engines __rcu *engines;
struct mutex engines_mutex;
struct drm_syncobj *syncobj;
struct i915_address_space *vm;
struct pid *pid;
struct list_head link;
struct i915_drm_client *client;
struct list_head client_link;
struct kref ref;
struct work_struct release_work;
struct rcu_head rcu;
unsigned long user_flags;
#define UCONTEXT_NO_ERROR_CAPTURE 1;
#define UCONTEXT_BANNABLE 2;
#define UCONTEXT_RECOVERABLE 3;
#define UCONTEXT_PERSISTENCE 4;
#define UCONTEXT_LOW_LATENCY 5;
unsigned long flags;
#define CONTEXT_CLOSED 0;
#define CONTEXT_USER_ENGINES 1;
bool uses_protected_content;
intel_wakeref_t pxp_wakeref;
struct mutex mutex;
struct i915_sched_attr sched;
atomic_t guilty_count;
atomic_t active_count;
unsigned long hang_timestamp[2];
#define CONTEXT_FAST_HANG_JIFFIES (120 * HZ);
u8 remap_slice;
struct radix_tree_root handles_vma;
struct mutex lut_mutex;
char name[TASK_COMM_LEN + 8];
struct {
spinlock_t lock;
struct list_head engines;
} stale;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">i915</span></code></dt><dd><p>i915 device backpointer</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">file_priv</span></code></dt><dd><p>owning file descriptor</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engines</span></code></dt><dd><p>User defined engines for this context</p>
<p>Various uAPI offer the ability to lookup up an
index from this array to select an engine operate on.</p>
<p>Multiple logically distinct instances of the same engine
may be defined in the array, as well as composite virtual
engines.</p>
<p>Execbuf uses the I915_EXEC_RING_MASK as an index into this
array to select which HW context + engine to execute on. For
the default array, the user_ring_map[] is used to translate
the legacy uABI onto the appropriate index (e.g. both
I915_EXEC_DEFAULT and I915_EXEC_RENDER select the same
context, and I915_EXEC_BSD is weird). For a user defined
array, execbuf uses I915_EXEC_RING_MASK as a plain index.</p>
<p>User defined by I915_CONTEXT_PARAM_ENGINE (when the
CONTEXT_USER_ENGINES flag is set).</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engines_mutex</span></code></dt><dd><p>guards writes to engines</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">syncobj</span></code></dt><dd><p>Shared timeline syncobj</p>
<p>When the SHARED_TIMELINE flag is set on context creation, we
emulate a single timeline across all engines using this syncobj.
For every execbuffer2 call, this syncobj is used as both an in-
and out-fence. Unlike the real intel_timeline, this doesn’t
provide perfect atomic in-order guarantees if the client races
with itself by calling execbuffer2 twice concurrently. However,
if userspace races with itself, that’s not likely to yield well-
defined results anyway so we choose to not care.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">vm</span></code></dt><dd><p>unique address space (GTT)</p>
<p>In full-ppgtt mode, each context has its own address space ensuring
complete separation of one client from all others.</p>
<p>In other modes, this is a NULL pointer with the expectation that
the caller uses the shared global GTT.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pid</span></code></dt><dd><p>process id of creator</p>
<p>Note that who created the context may not be the principle user,
as the context may be shared across a local socket. However,
that should only affect the default context, all contexts created
explicitly by the client are expected to be isolated.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">link</span></code></dt><dd><p>place with <code class="xref c c-type docutils literal notranslate"><span class="pre">drm_i915_private.context_list</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">client</span></code></dt><dd><p><code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_drm_client</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">client_link</span></code></dt><dd><p>for linking onto <code class="xref c c-type docutils literal notranslate"><span class="pre">i915_drm_client.ctx_list</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ref</span></code></dt><dd><p>reference count</p>
<p>A reference to a context is held by both the client who created it
and on each request submitted to the hardware using the request
(to ensure the hardware has access to the state until it has
finished all pending writes). See <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_context_get()</span></code> and
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_context_put()</span></code> for access.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">release_work</span></code></dt><dd><p>Work item for deferred cleanup, since <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_context_put()</span></code> tends to
be called from hardirq context.</p>
<p>FIXME: The only real reason for this is <a class="reference internal" href="#c.i915_gem_engines" title="i915_gem_engines"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_gem_engines.fence</span></code></a>, all
other callers are from process context and need at most some mild
shuffling to pull the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_context_put()</span></code> call out of a spinlock.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">rcu</span></code></dt><dd><p>rcu_head for deferred freeing.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">user_flags</span></code></dt><dd><p>small set of booleans controlled by the user</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">flags</span></code></dt><dd><p>small set of booleans</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">uses_protected_content</span></code></dt><dd><p>context uses PXP-encrypted objects.</p>
<p>This flag can only be set at ctx creation time and it’s immutable for
the lifetime of the context. See I915_CONTEXT_PARAM_PROTECTED_CONTENT
in uapi/drm/i915_drm.h for more info on setting restrictions and
expected behaviour of marked contexts.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pxp_wakeref</span></code></dt><dd><p>wakeref to keep the device awake when PXP is in use</p>
<p>PXP sessions are invalidated when the device is suspended, which in
turns invalidates all contexts and objects using it. To keep the
flow simple, we keep the device awake when contexts using PXP objects
are in use. It is expected that the userspace application only uses
PXP when the display is on, so taking a wakeref here shouldn’t worsen
our power metrics.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">mutex</span></code></dt><dd><p>guards everything that isn’t engines or handles_vma</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sched</span></code></dt><dd><p>scheduler parameters</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">guilty_count</span></code></dt><dd><p>How many times this context has caused a GPU hang.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">active_count</span></code></dt><dd><p>How many times this context was active during a GPU
hang, but did not cause it.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hang_timestamp</span></code></dt><dd><p>The last time(s) this context caused a GPU hang</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">remap_slice</span></code></dt><dd><p>Bitmask of cache lines that need remapping</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">handles_vma</span></code></dt><dd><p>rbtree to look up our context specific obj/vma for
the user handle. (user handles are per fd, but the binding is
per vm, which may be one per context or shared with the global GTT)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">lut_mutex</span></code></dt><dd><p>Locks handles_vma</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">name</span></code></dt><dd><p>arbitrary name, used for user debug</p>
<p>A name is constructed for the context from the creator’s process
name, pid and user handle in order to uniquely identify the
context in messages.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">stale</span></code></dt><dd><p>tracks stale engines to be destroyed</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>The <a class="reference internal" href="#c.i915_gem_context" title="i915_gem_context"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_context</span></code></a> represents the combined view of the driver and
logical hardware state for a particular client.</p>
<p>Userspace submits commands to be executed on the GPU as an instruction
stream within a GEM object we call a batchbuffer. This instructions may
refer to other GEM objects containing auxiliary state such as kernels,
samplers, render targets and even secondary batchbuffers. Userspace does
not know where in the GPU memory these objects reside and so before the
batchbuffer is passed to the GPU for execution, those addresses in the
batchbuffer and auxiliary objects are updated. This is known as relocation,
or patching. To try and avoid having to relocate each object on the next
execution, userspace is told the location of those objects in this pass,
but this remains just a hint as the kernel may choose a new location for
any object in the future.</p>
<p>At the level of talking to the hardware, submitting a batchbuffer for the
GPU to execute is to add content to a buffer from which the HW
command streamer is reading.</p>
<ol class="arabic simple">
<li><p>Add a command to load the HW context. For Logical Ring Contexts, i.e.
Execlists, this command is not placed on the same buffer as the
remaining items.</p></li>
<li><p>Add a command to invalidate caches to the buffer.</p></li>
<li><p>Add a batchbuffer start command to the buffer; the start command is
essentially a token together with the GPU address of the batchbuffer
to be executed.</p></li>
<li><p>Add a pipeline flush to the buffer.</p></li>
<li><p>Add a memory write command to the buffer to record when the GPU
is done executing the batchbuffer. The memory write writes the
global sequence number of the request, <code class="docutils literal notranslate"><span class="pre">i915_request::global_seqno</span></code>;
the i915 driver uses the current value in the register to determine
if the GPU has completed the batchbuffer.</p></li>
<li><p>Add a user interrupt command to the buffer. This command instructs
the GPU to issue an interrupt when the command, pipeline flush and
memory write are completed.</p></li>
<li><p>Inform the hardware of the additional commands added to the buffer
(by updating the tail pointer).</p></li>
</ol>
<p>Processing an execbuf ioctl is conceptually split up into a few phases.</p>
<ol class="arabic simple">
<li><p>Validation - Ensure all the pointers, handles and flags are valid.</p></li>
<li><p>Reservation - Assign GPU address space for every object</p></li>
<li><p>Relocation - Update any addresses to point to the final locations</p></li>
<li><p>Serialisation - Order the request with respect to its dependencies</p></li>
<li><p>Construction - Construct a request to execute the batchbuffer</p></li>
<li><p>Submission (at some point in the future execution)</p></li>
</ol>
<p>Reserving resources for the execbuf is the most complicated phase. We
neither want to have to migrate the object in the address space, nor do
we want to have to update any relocations pointing to this object. Ideally,
we want to leave the object where it is and for all the existing relocations
to match. If the object is given a new address, or if userspace thinks the
object is elsewhere, we have to parse all the relocation entries and update
the addresses. Userspace can set the I915_EXEC_NORELOC flag to hint that
all the target addresses in all of its objects match the value in the
relocation entries and that they all match the presumed offsets given by the
list of execbuffer objects. Using this knowledge, we know that if we haven’t
moved any buffers, all the relocation entries are valid and we can skip
the update. (If userspace is wrong, the likely outcome is an impromptu GPU
hang.) The requirement for using I915_EXEC_NO_RELOC are:</p>
<blockquote>
<div><p>The addresses written in the objects must match the corresponding
reloc.presumed_offset which in turn must match the corresponding
execobject.offset.</p>
<p>Any render targets written to in the batch must be flagged with
EXEC_OBJECT_WRITE.</p>
<p>To avoid stalling, execobject.offset should match the current
address of that object within the active context.</p>
</div></blockquote>
<p>The reservation is done is multiple phases. First we try and keep any
object already bound in its current location - so as long as meets the
constraints imposed by the new execbuffer. Any object left unbound after the
first pass is then fitted into any available idle space. If an object does
not fit, all objects are removed from the reservation and the process rerun
after sorting the objects into a priority order (more difficult to fit
objects are tried first). Failing that, the entire VM is cleared and we try
to fit the execbuf once last time before concluding that it simply will not
fit.</p>
<p>A small complication to all of this is that we allow userspace not only to
specify an alignment and a size for the object in the address space, but
we also allow userspace to specify the exact offset. This objects are
simpler to place (the location is known a priori) all we have to do is make
sure the space is available.</p>
<p>Once all the objects are in place, patching up the buried pointers to point
to the final locations is a fairly simple job of walking over the relocation
entry arrays, looking up the right address and rewriting the value into
the object. Simple! ... The relocation entries are stored in user memory
and so to access them we have to copy them into a local buffer. That copy
has to avoid taking any pagefaults as they may lead back to a GEM object
requiring the vm->mutex (i.e. recursive deadlock). So once again we split
the relocation into multiple passes. First we try to do everything within an
atomic context (avoid the pagefaults) which requires that we never wait. If
we detect that we may wait, or if we need to fault, then we have to fallback
to a slower path. The slowpath has to drop the mutex. (Can you hear alarm
bells yet?) Dropping the mutex means that we lose all the state we have
built up so far for the execbuf and we must reset any global data. However,
we do leave the objects pinned in their final locations - which is a
potential issue for concurrent execbufs. Once we have left the mutex, we can
allocate and copy all the relocation entries into a large array at our
leisure, reacquire the mutex, reclaim all the objects and other state and
then proceed to update any incorrect addresses with the objects.</p>
<p>As we process the relocation entries, we maintain a record of whether the
object is being written to. Using NORELOC, we expect userspace to provide
this information instead. We also check whether we can skip the relocation
by comparing the expected value inside the relocation entry with the target’s
final address. If they differ, we have to map the current object and rewrite
the 4 or 8 byte pointer within.</p>
<p>Serialising an execbuf is quite simple according to the rules of the GEM
ABI. Execution within each context is ordered by the order of submission.
Writes to any GEM object are in order of submission and are exclusive. Reads
from a GEM object are unordered with respect to other reads, but ordered by
writes. A write submitted after a read cannot occur before the read, and
similarly any read submitted after a write cannot occur before the write.
Writes are ordered between engines such that only one write occurs at any
time (completing any reads beforehand) - using semaphores where available
and CPU serialisation otherwise. Other GEM access obey the same rules, any
write (either via mmaps using set-domain, or via pwrite) must flush all GPU
reads before starting, and any read (either using set-domain or pread) must
flush all GPU writes before starting. (Note we only employ a barrier before,
we currently rely on userspace not concurrently starting a new execution
whilst reading or writing to an object. This may be an advantage or not
depending on how much you trust userspace not to shoot themselves in the
foot.) Serialisation may just result in the request being inserted into
a DAG awaiting its turn, but most simple is to wait on the CPU until
all dependencies are resolved.</p>
<p>After all of that, is just a matter of closing the request and handing it to
the hardware (well, leaving it in a queue to be executed). However, we also
offer the ability for batchbuffers to be run with elevated privileges so
that they access otherwise hidden registers. (Used to adjust L3 cache etc.)
Before any batch is given extra privileges we first must check that it
contains no nefarious instructions, we check that each instruction is from
our whitelist and all registers are also from an allowed list. We first
copy the user’s batchbuffer to a shadow (so that the user doesn’t have
access to it, either by the CPU or GPU as we scan it) and then parse each
instruction. If everything is ok, we set a flag telling the hardware to run
the batchbuffer in trusted mode, otherwise the ioctl is rejected.</p>
</section>
<section id="scheduling">
<h3>Scheduling<a class="headerlink" href="#scheduling" title="Link to this heading">¶</a></h3>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_sched_engine">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_sched_engine</span></span></span><a class="headerlink" href="#c.i915_sched_engine" title="Link to this definition">¶</a><br /></dt>
<dd><p>scheduler engine</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_sched_engine {
struct kref ref;
spinlock_t lock;
struct list_head requests;
struct list_head hold;
struct tasklet_struct tasklet;
struct i915_priolist default_priolist;
int queue_priority_hint;
struct rb_root_cached queue;
bool no_priolist;
void *private_data;
void (*destroy)(struct kref *kref);
bool (*disabled)(struct i915_sched_engine *sched_engine);
void (*kick_backend)(const struct i915_request *rq, int prio);
void (*bump_inflight_request_prio)(struct i915_request *rq, int prio);
void (*retire_inflight_request_prio)(struct i915_request *rq);
void (*schedule)(struct i915_request *request, const struct i915_sched_attr *attr);
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">ref</span></code></dt><dd><p>reference count of schedule engine object</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">lock</span></code></dt><dd><p>protects requests in priority lists, requests, hold and
tasklet while running</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">requests</span></code></dt><dd><p>list of requests inflight on this schedule engine</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hold</span></code></dt><dd><p>list of ready requests, but on hold</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">tasklet</span></code></dt><dd><p>softirq tasklet for submission</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">default_priolist</span></code></dt><dd><p>priority list for I915_PRIORITY_NORMAL</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">queue_priority_hint</span></code></dt><dd><p>Highest pending priority.</p>
<p>When we add requests into the queue, or adjust the priority of
executing requests, we compute the maximum priority of those
pending requests. We can then use this value to determine if
we need to preempt the executing requests to service the queue.
However, since the we may have recorded the priority of an inflight
request we wanted to preempt but since completed, at the time of
dequeuing the priority hint may no longer may match the highest
available request priority.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">queue</span></code></dt><dd><p>queue of requests, in priority lists</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">no_priolist</span></code></dt><dd><p>priority lists disabled</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">private_data</span></code></dt><dd><p>private data of the submission backend</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">destroy</span></code></dt><dd><p>destroy schedule engine / cleanup in backend</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">disabled</span></code></dt><dd><p>check if backend has disabled submission</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">kick_backend</span></code></dt><dd><p>kick backend after a request’s priority has changed</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">bump_inflight_request_prio</span></code></dt><dd><p>update priority of an inflight request</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">retire_inflight_request_prio</span></code></dt><dd><p>indicate request is retired to
priority tracking</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">schedule</span></code></dt><dd><p>adjust priority of request</p>
<p>Call when the priority on a request has changed and it and its
dependencies may need rescheduling. Note the request itself may
not be ready to run!</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>A schedule engine represents a submission queue with different priority
bands. It contains all the common state (relative to the backend) to queue,
track, and submit a request.</p>
<p>This object at the moment is quite i915 specific but will transition into a
container for the drm_gpu_scheduler plus a few other variables once the i915
is integrated with the DRM scheduler.</p>
</section>
<section id="logical-rings-logical-ring-contexts-and-execlists">
<h3>Logical Rings, Logical Ring Contexts and Execlists<a class="headerlink" href="#logical-rings-logical-ring-contexts-and-execlists" title="Link to this heading">¶</a></h3>
<p>Motivation:
GEN8 brings an expansion of the HW contexts: “Logical Ring Contexts”.
These expanded contexts enable a number of new abilities, especially
“Execlists” (also implemented in this file).</p>
<p>One of the main differences with the legacy HW contexts is that logical
ring contexts incorporate many more things to the context’s state, like
PDPs or ringbuffer control registers:</p>
<p>The reason why PDPs are included in the context is straightforward: as
PPGTTs (per-process GTTs) are actually per-context, having the PDPs
contained there mean you don’t need to do a ppgtt->switch_mm yourself,
instead, the GPU will do it for you on the context switch.</p>
<p>But, what about the ringbuffer control registers (head, tail, etc..)?
shouldn’t we just need a set of those per engine command streamer? This is
where the name “Logical Rings” starts to make sense: by virtualizing the
rings, the engine cs shifts to a new “ring buffer” with every context
switch. When you want to submit a workload to the GPU you: A) choose your
context, B) find its appropriate virtualized ring, C) write commands to it
and then, finally, D) tell the GPU to switch to that context.</p>
<p>Instead of the legacy MI_SET_CONTEXT, the way you tell the GPU to switch
to a contexts is via a context execution list, ergo “Execlists”.</p>
<p>LRC implementation:
Regarding the creation of contexts, we have:</p>
<ul class="simple">
<li><p>One global default context.</p></li>
<li><p>One local default context for each opened fd.</p></li>
<li><p>One local extra context for each context create ioctl call.</p></li>
</ul>
<p>Now that ringbuffers belong per-context (and not per-engine, like before)
and that contexts are uniquely tied to a given engine (and not reusable,
like before) we need:</p>
<ul class="simple">
<li><p>One ringbuffer per-engine inside each context.</p></li>
<li><p>One backing object per-engine inside each context.</p></li>
</ul>
<p>The global default context starts its life with these new objects fully
allocated and populated. The local default context for each opened fd is
more complex, because we don’t know at creation time which engine is going
to use them. To handle this, we have implemented a deferred creation of LR
contexts:</p>
<p>The local context starts its life as a hollow or blank holder, that only
gets populated for a given engine once we receive an execbuffer. If later
on we receive another execbuffer ioctl for the same context but a different
engine, we allocate/populate a new ringbuffer and context backing object and
so on.</p>
<p>Finally, regarding local contexts created using the ioctl call: as they are
only allowed with the render ring, we can allocate & populate them right
away (no need to defer anything, at least for now).</p>
<p>Execlists implementation:
Execlists are the new method by which, on gen8+ hardware, workloads are
submitted for execution (as opposed to the legacy, ringbuffer-based, method).
This method works as follows:</p>
<p>When a request is committed, its commands (the BB start and any leading or
trailing commands, like the seqno breadcrumbs) are placed in the ringbuffer
for the appropriate context. The tail pointer in the hardware context is not
updated at this time, but instead, kept by the driver in the ringbuffer
structure. A structure representing this request is added to a request queue
for the appropriate engine: this structure contains a copy of the context’s
tail after the request was written to the ring buffer and a pointer to the
context itself.</p>
<p>If the engine’s request queue was empty before the request was added, the
queue is processed immediately. Otherwise the queue will be processed during
a context switch interrupt. In any case, elements on the queue will get sent
(in pairs) to the GPU’s ExecLists Submit Port (ELSP, for short) with a
globally unique 20-bits submission ID.</p>
<p>When execution of a request completes, the GPU updates the context status
buffer with a context complete event and generates a context switch interrupt.
During the interrupt handling, the driver examines the events in the buffer:
for each context complete event, if the announced ID matches that on the head
of the request queue, then that request is retired and removed from the queue.</p>
<p>After processing, if any requests were retired and the queue is not empty
then a new execution list can be submitted. The two requests at the front of
the queue are next to be submitted but since a context may not occur twice in
an execution list, if subsequent requests have the same ID as the first then
the two requests must be combined. This is done simply by discarding requests
at the head of the queue until either only one requests is left (in which case
we use a NULL second context) or the first two requests have unique IDs.</p>
<p>By always executing the first two requests in the queue the driver ensures
that the GPU is kept as busy as possible. In the case where a single context
completes but a second context is still executing, the request for this second
context will be at the head of the queue when we remove the first one. This
request will then be resubmitted along with a new request for a different context,
which will cause the hardware to continue executing the second request and queue
the new request (the GPU detects the condition of a context getting preempted
with the same context and optimizes the context switch flow by not doing
preemption, but just sampling the new tail pointer).</p>
</section>
<section id="global-gtt-views">
<h3>Global GTT views<a class="headerlink" href="#global-gtt-views" title="Link to this heading">¶</a></h3>
<p>Background and previous state</p>
<p>Historically objects could exists (be bound) in global GTT space only as
singular instances with a view representing all of the object’s backing pages
in a linear fashion. This view will be called a normal view.</p>
<p>To support multiple views of the same object, where the number of mapped
pages is not equal to the backing store, or where the layout of the pages
is not linear, concept of a GGTT view was added.</p>
<p>One example of an alternative view is a stereo display driven by a single
image. In this case we would have a framebuffer looking like this
(2x2 pages):</p>
<blockquote>
<div><p>12
34</p>
</div></blockquote>
<p>Above would represent a normal GGTT view as normally mapped for GPU or CPU
rendering. In contrast, fed to the display engine would be an alternative
view which could look something like this:</p>
<blockquote>
<div><p>1212
3434</p>
</div></blockquote>
<p>In this example both the size and layout of pages in the alternative view is
different from the normal view.</p>
<p>Implementation and usage</p>
<p>GGTT views are implemented using VMAs and are distinguished via <code class="xref c c-enum broken_xref docutils literal notranslate"><span class="pre">enum</span>
<span class="pre">i915_gtt_view_type</span></code> and <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gtt_view</span></code>.</p>
<p>A new flavour of core GEM functions which work with GGTT bound objects were
added with the _ggtt_ infix, and sometimes with _view postfix to avoid
renaming in large amounts of code. They take the <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gtt_view</span></code>
parameter encapsulating all metadata required to implement a view.</p>
<p>As a helper for callers which are only interested in the normal view,
globally const i915_gtt_view_normal singleton instance exists. All old core
GEM API functions, the ones not taking the view parameter, are operating on,
or with the normal GGTT view.</p>
<p>Code wanting to add or use a new GGTT view needs to:</p>
<ol class="arabic simple">
<li><p>Add a new <code class="xref c c-enum broken_xref docutils literal notranslate"><span class="pre">enum</span> <span class="pre">with</span></code> a suitable name.</p></li>
<li><p>Extend the metadata in the i915_gtt_view structure if required.</p></li>
<li><p>Add support to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_get_vma_pages()</span></code>.</p></li>
</ol>
<p>New views are required to build a scatter-gather table from within the
i915_get_vma_pages function. This table is stored in the vma.gtt_view and
exists for the lifetime of an VMA.</p>
<p>Core API is designed to have copy semantics which means that passed in
<code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gtt_view</span></code> does not need to be persistent (left around after
calling the core API functions).</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_gtt_reserve">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_gtt_reserve</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_address_space</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vm</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-mm.html#c.drm_mm_node" title="drm_mm_node"><span class="n"><span class="pre">drm_mm_node</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">node</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">offset</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">color</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_gtt_reserve" title="Link to this definition">¶</a><br /></dt>
<dd><p>reserve a node in an address_space (GTT)</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span> <span class="pre">*vm</span></code></dt><dd><p>the <code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>An optional <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_mm_node</span> <span class="pre">*node</span></code></dt><dd><p>the <a class="reference internal" href="drm-mm.html#c.drm_mm_node" title="drm_mm_node"><code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_mm_node</span></code></a> (typically i915_vma.node)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">size</span></code></dt><dd><p>how much space to allocate inside the GTT,
must be #I915_GTT_PAGE_SIZE aligned</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">offset</span></code></dt><dd><p>where to insert inside the GTT,
must be #I915_GTT_MIN_ALIGNMENT aligned, and the node
(<strong>offset</strong> + <strong>size</strong>) must fit within the address space</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">color</span></code></dt><dd><p>color to apply to node, if this node is not from a VMA,
color must be #I915_COLOR_UNEVICTABLE</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">flags</span></code></dt><dd><p>control search and eviction behaviour</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p><a class="reference internal" href="#c.i915_gem_gtt_reserve" title="i915_gem_gtt_reserve"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_gtt_reserve()</span></code></a> tries to insert the <strong>node</strong> at the exact <strong>offset</strong> inside
the address space (using <strong>size</strong> and <strong>color</strong>). If the <strong>node</strong> does not fit, it
tries to evict any overlapping nodes from the GTT, including any
neighbouring nodes if the colors do not match (to ensure guard pages between
differing domains). See <a class="reference internal" href="#c.i915_gem_evict_for_node" title="i915_gem_evict_for_node"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_evict_for_node()</span></code></a> for the gory details
on the eviction algorithm. #PIN_NONBLOCK may used to prevent waiting on
evicting active overlapping objects, and any overlapping node that is pinned
or marked as unevictable will also result in failure.</p>
<p><strong>Return</strong></p>
<p>0 on success, -ENOSPC if no suitable hole is found, -EINTR if
asked to wait for eviction and interrupted.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_gtt_insert">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_gtt_insert</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_address_space</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vm</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_gem_ww_ctx</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ww</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-mm.html#c.drm_mm_node" title="drm_mm_node"><span class="n"><span class="pre">drm_mm_node</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">node</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">alignment</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">color</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">start</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="n"><span class="pre">end</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">flags</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_gtt_insert" title="Link to this definition">¶</a><br /></dt>
<dd><p>insert a node into an address_space (GTT)</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span> <span class="pre">*vm</span></code></dt><dd><p>the <code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_address_space</span></code></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span> <span class="pre">*ww</span></code></dt><dd><p>An optional <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_gem_ww_ctx</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_mm_node</span> <span class="pre">*node</span></code></dt><dd><p>the <a class="reference internal" href="drm-mm.html#c.drm_mm_node" title="drm_mm_node"><code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_mm_node</span></code></a> (typically i915_vma.node)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">size</span></code></dt><dd><p>how much space to allocate inside the GTT,
must be #I915_GTT_PAGE_SIZE aligned</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">alignment</span></code></dt><dd><p>required alignment of starting offset, may be 0 but
if specified, this must be a power-of-two and at least
#I915_GTT_MIN_ALIGNMENT</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">color</span></code></dt><dd><p>color to apply to node</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">start</span></code></dt><dd><p>start of any range restriction inside GTT (0 for all),
must be #I915_GTT_PAGE_SIZE aligned</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">end</span></code></dt><dd><p>end of any range restriction inside GTT (U64_MAX for all),
must be #I915_GTT_PAGE_SIZE aligned if not U64_MAX</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">flags</span></code></dt><dd><p>control search and eviction behaviour</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p><a class="reference internal" href="#c.i915_gem_gtt_insert" title="i915_gem_gtt_insert"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_gtt_insert()</span></code></a> first searches for an available hole into which
is can insert the node. The hole address is aligned to <strong>alignment</strong> and
its <strong>size</strong> must then fit entirely within the [<strong>start</strong>, <strong>end</strong>] bounds. The
nodes on either side of the hole must match <strong>color</strong>, or else a guard page
will be inserted between the two nodes (or the node evicted). If no
suitable hole is found, first a victim is randomly selected and tested
for eviction, otherwise then the LRU list of objects within the GTT
is scanned to find the first set of replacement nodes to create the hole.
Those old overlapping nodes are evicted from the GTT (and so must be
rebound before any future use). Any node that is currently pinned cannot
be evicted (see <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_vma_pin()</span></code>). Similar if the node’s VMA is currently
active and #PIN_NONBLOCK is specified, that node is also skipped when
searching for an eviction candidate. See <a class="reference internal" href="#c.i915_gem_evict_something" title="i915_gem_evict_something"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_evict_something()</span></code></a> for
the gory details on the eviction algorithm.</p>
<p><strong>Return</strong></p>
<p>0 on success, -ENOSPC if no suitable hole is found, -EINTR if
asked to wait for eviction and interrupted.</p>
</div>
</section>
<section id="gtt-fences-and-swizzling">
<h3>GTT Fences and Swizzling<a class="headerlink" href="#gtt-fences-and-swizzling" title="Link to this heading">¶</a></h3>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_vma_revoke_fence">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_vma_revoke_fence</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vma</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_vma_revoke_fence" title="Link to this definition">¶</a><br /></dt>
<dd><p>force-remove fence for a VMA</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_vma</span> <span class="pre">*vma</span></code></dt><dd><p>vma to map linearly (not through a fence reg)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function force-removes any fence from the given object, which is useful
if the kernel wants to do untiled GTT access.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_vma_pin_fence">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_vma_pin_fence</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vma</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_vma_pin_fence" title="Link to this definition">¶</a><br /></dt>
<dd><p>set up fencing for a vma</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_vma</span> <span class="pre">*vma</span></code></dt><dd><p>vma to map through a fence reg</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>When mapping objects through the GTT, userspace wants to be able to write
to them without having to worry about swizzling if the object is tiled.
This function walks the fence regs looking for a free one for <strong>obj</strong>,
stealing one if it can’t find any.</p>
<p>It then sets up the reg based on the object’s properties: address, pitch
and tiling format.</p>
<p>For an untiled surface, this removes any existing fence.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_reserve_fence">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_fence_reg</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">i915_reserve_fence</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_ggtt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ggtt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_reserve_fence" title="Link to this definition">¶</a><br /></dt>
<dd><p>Reserve a fence for vGPU</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_ggtt</span> <span class="pre">*ggtt</span></code></dt><dd><p>Global GTT</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function walks the fence regs looking for a free one and remove
it from the fence_list. It is used to reserve fence for vGPU to use.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_unreserve_fence">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_unreserve_fence</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_fence_reg</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">fence</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_unreserve_fence" title="Link to this definition">¶</a><br /></dt>
<dd><p>Reclaim a reserved fence</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_fence_reg</span> <span class="pre">*fence</span></code></dt><dd><p>the fence reg</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function add a reserved fence register from vGPU to the fence_list.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_ggtt_restore_fences">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_ggtt_restore_fences</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_ggtt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ggtt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_ggtt_restore_fences" title="Link to this definition">¶</a><br /></dt>
<dd><p>restore fence state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_ggtt</span> <span class="pre">*ggtt</span></code></dt><dd><p>Global GTT</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Restore the hw fence state to match the software tracking again, to be called
after a gpu reset and on resume. Note that on runtime suspend we only cancel
the fences, to be reacquired by the user later.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.detect_bit_6_swizzle">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">detect_bit_6_swizzle</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_ggtt</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ggtt</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.detect_bit_6_swizzle" title="Link to this definition">¶</a><br /></dt>
<dd><p>detect bit 6 swizzling pattern</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_ggtt</span> <span class="pre">*ggtt</span></code></dt><dd><p>Global GGTT</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Detects bit 6 swizzling of address lookup between IGD access and CPU
access through main memory.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_object_do_bit_17_swizzle">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_object_do_bit_17_swizzle</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">sg_table</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pages</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_object_do_bit_17_swizzle" title="Link to this definition">¶</a><br /></dt>
<dd><p>fixup bit 17 swizzling</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>i915 GEM buffer object</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sg_table</span> <span class="pre">*pages</span></code></dt><dd><p>the scattergather list of physical pages</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function fixes up the swizzling in case any page frame number for this
object has changed in bit 17 since that state has been saved with
<a class="reference internal" href="#c.i915_gem_object_save_bit_17_swizzle" title="i915_gem_object_save_bit_17_swizzle"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_object_save_bit_17_swizzle()</span></code></a>.</p>
<p>This is called when pinning backing storage again, since the kernel is free
to move unpinned backing storage around (either by directly moving pages or
by swapping them out and back in again).</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_object_save_bit_17_swizzle">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_object_save_bit_17_swizzle</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_gem_object</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">obj</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">sg_table</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">pages</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_object_save_bit_17_swizzle" title="Link to this definition">¶</a><br /></dt>
<dd><p>save bit 17 swizzling</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_gem_object</span> <span class="pre">*obj</span></code></dt><dd><p>i915 GEM buffer object</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sg_table</span> <span class="pre">*pages</span></code></dt><dd><p>the scattergather list of physical pages</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This function saves the bit 17 of each page frame number so that swizzling
can be fixed up later on with <a class="reference internal" href="#c.i915_gem_object_do_bit_17_swizzle" title="i915_gem_object_do_bit_17_swizzle"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_object_do_bit_17_swizzle()</span></code></a>. This must
be called before the backing storage can be unpinned.</p>
</div>
<section id="global-gtt-fence-handling">
<h4>Global GTT Fence Handling<a class="headerlink" href="#global-gtt-fence-handling" title="Link to this heading">¶</a></h4>
<p>Important to avoid confusions: “fences” in the i915 driver are not execution
fences used to track command completion but hardware detiler objects which
wrap a given range of the global GTT. Each platform has only a fairly limited
set of these objects.</p>
<p>Fences are used to detile GTT memory mappings. They’re also connected to the
hardware frontbuffer render tracking and hence interact with frontbuffer
compression. Furthermore on older platforms fences are required for tiled
objects used by the display engine. They can also be used by the render
engine - they’re required for blitter commands and are optional for render
commands. But on gen4+ both display (with the exception of fbc) and rendering
have their own tiling state bits and don’t need fences.</p>
<p>Also note that fences only support X and Y tiling and hence can’t be used for
the fancier new tiling formats like W, Ys and Yf.</p>
<p>Finally note that because fences are such a restricted resource they’re
dynamically associated with objects. Furthermore fence state is committed to
the hardware lazily to avoid unnecessary stalls on gen2/3. Therefore code must
explicitly call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_object_get_fence()</span></code> to synchronize fencing status
for cpu access. Also note that some code wants an unfenced view, for those
cases the fence can be removed forcefully with <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_gem_object_put_fence()</span></code>.</p>
<p>Internally these functions will synchronize with userspace access by removing
CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed.</p>
</section>
<section id="hardware-tiling-and-swizzling-details">
<h4>Hardware Tiling and Swizzling Details<a class="headerlink" href="#hardware-tiling-and-swizzling-details" title="Link to this heading">¶</a></h4>
<p>The idea behind tiling is to increase cache hit rates by rearranging
pixel data so that a group of pixel accesses are in the same cacheline.
Performance improvement from doing this on the back/depth buffer are on
the order of 30%.</p>
<p>Intel architectures make this somewhat more complicated, though, by
adjustments made to addressing of data when the memory is in interleaved
mode (matched pairs of DIMMS) to improve memory bandwidth.
For interleaved memory, the CPU sends every sequential 64 bytes
to an alternate memory channel so it can get the bandwidth from both.</p>
<p>The GPU also rearranges its accesses for increased bandwidth to interleaved
memory, and it matches what the CPU does for non-tiled. However, when tiled
it does it a little differently, since one walks addresses not just in the
X direction but also Y. So, along with alternating channels when bit
6 of the address flips, it also alternates when other bits flip -- Bits 9
(every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
are common to both the 915 and 965-class hardware.</p>
<p>The CPU also sometimes XORs in higher bits as well, to improve
bandwidth doing strided access like we do so frequently in graphics. This
is called “Channel XOR Randomization” in the MCH documentation. The result
is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
decode.</p>
<p>All of this bit 6 XORing has an effect on our memory management,
as we need to make sure that the 3d driver can correctly address object
contents.</p>
<p>If we don’t have interleaved memory, all tiling is safe and no swizzling is
required.</p>
<p>When bit 17 is XORed in, we simply refuse to tile at all. Bit
17 is not just a page offset, so as we page an object out and back in,
individual pages in it will have different bit 17 addresses, resulting in
each 64 bytes being swapped with its neighbor!</p>
<p>Otherwise, if interleaved, we have to tell the 3d driver what the address
swizzling it needs to do is, since it’s writing with the CPU to the pages
(bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
to match what the GPU expects.</p>
</section>
</section>
<section id="object-tiling-ioctls">
<h3>Object Tiling IOCTLs<a class="headerlink" href="#object-tiling-ioctls" title="Link to this heading">¶</a></h3>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_fence_size">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_fence_size</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">tiling</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">stride</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_fence_size" title="Link to this definition">¶</a><br /></dt>
<dd><p>required global GTT size for a fence</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">size</span></code></dt><dd><p>object size</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">tiling</span></code></dt><dd><p>tiling mode</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">stride</span></code></dt><dd><p>tiling stride</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return the required global GTT size for a fence (view of a tiled object),
taking into account potential fence register mapping.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_fence_alignment">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_fence_alignment</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">tiling</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">stride</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_fence_alignment" title="Link to this definition">¶</a><br /></dt>
<dd><p>required global GTT alignment for a fence</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">size</span></code></dt><dd><p>object size</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">tiling</span></code></dt><dd><p>tiling mode</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">stride</span></code></dt><dd><p>tiling stride</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Return the required global GTT alignment for a fence (a view of a tiled
object), taking into account potential fence register mapping.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_set_tiling_ioctl">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_set_tiling_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_device" title="drm_device"><span class="n"><span class="pre">drm_device</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">data</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_set_tiling_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>IOCTL handler to set tiling mode</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_device</span> <span class="pre">*dev</span></code></dt><dd><p>DRM device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*data</span></code></dt><dd><p>data pointer for the ioctl</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>DRM file for the ioctl call</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Sets the tiling mode of an object, returning the required swizzling of
bit 6 of addresses in the object.</p>
<p>Called by the user via ioctl.</p>
<p><strong>Return</strong></p>
<p>Zero on success, negative errno on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_gem_get_tiling_ioctl">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_gem_get_tiling_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_device" title="drm_device"><span class="n"><span class="pre">drm_device</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">data</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_gem_get_tiling_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>IOCTL handler to get tiling mode</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_device</span> <span class="pre">*dev</span></code></dt><dd><p>DRM device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*data</span></code></dt><dd><p>data pointer for the ioctl</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>DRM file for the ioctl call</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Returns the current tiling mode and required bit 6 swizzling for the object.</p>
<p>Called by the user via ioctl.</p>
<p><strong>Return</strong></p>
<p>Zero on success, negative errno on failure.</p>
</div>
<p><a class="reference internal" href="#c.i915_gem_set_tiling_ioctl" title="i915_gem_set_tiling_ioctl"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_set_tiling_ioctl()</span></code></a> and <a class="reference internal" href="#c.i915_gem_get_tiling_ioctl" title="i915_gem_get_tiling_ioctl"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_gem_get_tiling_ioctl()</span></code></a> is the userspace
interface to declare fence register requirements.</p>
<p>In principle GEM doesn’t care at all about the internal data layout of an
object, and hence it also doesn’t care about tiling or swizzling. There’s two
exceptions:</p>
<ul class="simple">
<li><p>For X and Y tiling the hardware provides detilers for CPU access, so called
fences. Since there’s only a limited amount of them the kernel must manage
these, and therefore userspace must tell the kernel the object tiling if it
wants to use fences for detiling.</p></li>
<li><p>On gen3 and gen4 platforms have a swizzling pattern for tiled objects which
depends upon the physical page frame number. When swapping such objects the
page frame number might change and the kernel must be able to fix this up
and hence now the tiling. Note that on a subset of platforms with
asymmetric memory channel population the swizzling pattern changes in an
unknown way, and for those the kernel simply forbids swapping completely.</p></li>
</ul>
<p>Since neither of this applies for new tiling layouts on modern platforms like
W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled.
Anything else can be handled in userspace entirely without the kernel’s
involvement.</p>
</section>
<section id="protected-objects">
<h3>Protected Objects<a class="headerlink" href="#protected-objects" title="Link to this heading">¶</a></h3>
<p>PXP (Protected Xe Path) is a feature available in Gen12 and newer platforms.
It allows execution and flip to display of protected (i.e. encrypted)
objects. The SW support is enabled via the CONFIG_DRM_I915_PXP kconfig.</p>
<p>Objects can opt-in to PXP encryption at creation time via the
I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
correctly protected they must be used in conjunction with a context created
with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
of those two uapi flags for details and restrictions.</p>
<p>Protected objects are tied to a pxp session; currently we only support one
session, which i915 manages and whose index is available in the uapi
(I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
protected objects.
The session is invalidated by the HW when certain events occur (e.g.
suspend/resume). When this happens, all the objects that were used with the
session are marked as invalid and all contexts marked as using protected
content are banned. Any further attempt at using them in an execbuf call is
rejected, while flips are converted to black frames.</p>
<p>Some of the PXP setup operations are performed by the Management Engine,
which is handled by the mei driver; communication between i915 and mei is
performed via the mei_pxp component module.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.intel_pxp">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_pxp</span></span></span><a class="headerlink" href="#c.intel_pxp" title="Link to this definition">¶</a><br /></dt>
<dd><p>pxp state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct intel_pxp {
struct intel_gt *ctrl_gt;
bool platform_cfg_is_bad;
u32 kcr_base;
struct gsccs_session_resources {
u64 host_session_handle;
struct intel_context *ce;
struct i915_vma *pkt_vma;
void *pkt_vaddr;
struct i915_vma *bb_vma;
void *bb_vaddr;
} gsccs_res;
struct i915_pxp_component *pxp_component;
struct device_link *dev_link;
bool pxp_component_added;
struct intel_context *ce;
struct mutex arb_mutex;
bool arb_is_valid;
u32 key_instance;
struct mutex tee_mutex;
struct {
struct drm_i915_gem_object *obj;
void *vaddr;
} stream_cmd;
bool hw_state_invalidated;
bool irq_enabled;
struct completion termination;
struct work_struct session_work;
u32 session_events;
#define PXP_TERMINATION_REQUEST BIT(0);
#define PXP_TERMINATION_COMPLETE BIT(1);
#define PXP_INVAL_REQUIRED BIT(2);
#define PXP_EVENT_TYPE_IRQ BIT(3);
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">ctrl_gt</span></code></dt><dd><p>pointer to the tile that owns the controls for PXP subsystem assets that
the VDBOX, the KCR engine (and GSC CS depending on the platform)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">platform_cfg_is_bad</span></code></dt><dd><p>used to track if any prior arb session creation resulted
in a failure that was caused by a platform configuration issue, meaning that
failure will not get resolved without a change to the platform (not kernel)
such as BIOS configuration, firwmware update, etc. This bool gets reflected when
GET_PARAM:I915_PARAM_PXP_STATUS is called.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">kcr_base</span></code></dt><dd><p>base mmio offset for the KCR engine which is different on legacy platforms
vs newer platforms where the KCR is inside the media-tile.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">gsccs_res</span></code></dt><dd><p>resources for request submission for platforms that have a GSC engine.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pxp_component</span></code></dt><dd><p>i915_pxp_component <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">of</span></code> the bound mei_pxp
module. Only set and cleared inside component bind/unbind functions,
which are protected by <code class="xref c c-type docutils literal notranslate"><span class="pre">tee_mutex</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">dev_link</span></code></dt><dd><p>Enforce module relationship for power management ordering.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pxp_component_added</span></code></dt><dd><p>track if the pxp component has been added.
Set and cleared in tee init and fini functions respectively.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ce</span></code></dt><dd><p>kernel-owned context used for PXP operations</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">arb_mutex</span></code></dt><dd><p>protects arb session start</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">arb_is_valid</span></code></dt><dd><p>tracks arb session status.
After a teardown, the arb session can still be in play on the HW
even if the keys are gone, so we can’t rely on the HW state of the
session to know if it’s valid and need to track the status in SW.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">key_instance</span></code></dt><dd><p>tracks which key instance we’re on, so we can use it
to determine if an object was created using the current key or a
previous one.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">tee_mutex</span></code></dt><dd><p>protects the tee channel binding and messaging.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">stream_cmd</span></code></dt><dd><p>LMEM obj used to send stream PXP commands to the GSC</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hw_state_invalidated</span></code></dt><dd><p>if the HW perceives an attack on the integrity
of the encryption it will invalidate the keys and expect SW to
re-initialize the session. We keep track of this state to make sure
we only re-start the arb session when required.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">irq_enabled</span></code></dt><dd><p>tracks the status of the kcr irqs</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">termination</span></code></dt><dd><p>tracks the status of a pending termination. Only
re-initialized under gt->irq_lock and completed in <code class="xref c c-type docutils literal notranslate"><span class="pre">session_work</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">session_work</span></code></dt><dd><p>worker that manages session events.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">session_events</span></code></dt><dd><p>pending session events, protected with gt->irq_lock.</p>
</dd>
</dl>
</div>
</section>
</section>
<section id="microcontrollers">
<h2>Microcontrollers<a class="headerlink" href="#microcontrollers" title="Link to this heading">¶</a></h2>
<p>Starting from gen9, three microcontrollers are available on the HW: the
graphics microcontroller (GuC), the HEVC/H.265 microcontroller (HuC) and the
display microcontroller (DMC). The driver is responsible for loading the
firmwares on the microcontrollers; the GuC and HuC firmwares are transferred
to WOPCM using the DMA engine, while the DMC firmware is written through MMIO.</p>
<section id="wopcm">
<h3>WOPCM<a class="headerlink" href="#wopcm" title="Link to this heading">¶</a></h3>
<section id="wopcm-layout">
<h4>WOPCM Layout<a class="headerlink" href="#wopcm-layout" title="Link to this heading">¶</a></h4>
<p>The layout of the WOPCM will be fixed after writing to GuC WOPCM size and
offset registers whose values are calculated and determined by HuC/GuC
firmware size and set of hardware requirements/restrictions as shown below:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> +=========> +====================+ <== WOPCM Top
^ | HW contexts RSVD |
| +===> +====================+ <== GuC WOPCM Top
| ^ | |
| | | |
| | | |
| GuC | |
| WOPCM | |
| Size +--------------------+
WOPCM | | GuC FW RSVD |
| | +--------------------+
| | | GuC Stack RSVD |
| | +------------------- +
| v | GuC WOPCM RSVD |
| +===> +====================+ <== GuC WOPCM base
| | WOPCM RSVD |
| +------------------- + <== HuC Firmware Top
v | HuC FW |
+=========> +====================+ <== WOPCM Base
</pre></div>
</div>
<p>GuC accessible WOPCM starts at GuC WOPCM base and ends at GuC WOPCM top.
The top part of the WOPCM is reserved for hardware contexts (e.g. RC6
context).</p>
</section>
</section>
<section id="guc">
<h3>GuC<a class="headerlink" href="#guc" title="Link to this heading">¶</a></h3>
<p>The GuC is a microcontroller inside the GT HW, introduced in gen9. The GuC is
designed to offload some of the functionality usually performed by the host
driver; currently the main operations it can take care of are:</p>
<ul class="simple">
<li><p>Authentication of the HuC, which is required to fully enable HuC usage.</p></li>
<li><p>Low latency graphics context scheduling (a.k.a. GuC submission).</p></li>
<li><p>GT Power management.</p></li>
</ul>
<p>The enable_guc module parameter can be used to select which of those
operations to enable within GuC. Note that not all the operations are
supported on all gen9+ platforms.</p>
<p>Enabling the GuC is not mandatory and therefore the firmware is only loaded
if at least one of the operations is selected. However, not loading the GuC
might result in the loss of some features that do require the GuC (currently
just the HuC, but more are expected to land in the future).</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.intel_guc">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_guc</span></span></span><a class="headerlink" href="#c.intel_guc" title="Link to this definition">¶</a><br /></dt>
<dd><p>Top level structure of GuC.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct intel_guc {
struct intel_uc_fw fw;
struct intel_guc_log log;
struct intel_guc_ct ct;
struct intel_guc_slpc slpc;
struct intel_guc_state_capture *capture;
struct dentry *dbgfs_node;
struct i915_sched_engine *sched_engine;
struct i915_request *stalled_request;
enum {
STALL_NONE,
STALL_REGISTER_CONTEXT,
STALL_MOVE_LRC_TAIL,
STALL_ADD_REQUEST,
} submission_stall_reason;
spinlock_t irq_lock;
unsigned int msg_enabled_mask;
atomic_t outstanding_submission_g2h;
struct xarray tlb_lookup;
u32 serial_slot;
u32 next_seqno;
struct {
bool enabled;
void (*reset)(struct intel_guc *guc);
void (*enable)(struct intel_guc *guc);
void (*disable)(struct intel_guc *guc);
} interrupts;
struct {
spinlock_t lock;
struct ida guc_ids;
int num_guc_ids;
unsigned long *guc_ids_bitmap;
struct list_head guc_id_list;
unsigned int guc_ids_in_use;
struct list_head destroyed_contexts;
struct work_struct destroyed_worker;
struct work_struct reset_fail_worker;
intel_engine_mask_t reset_fail_mask;
unsigned int sched_disable_delay_ms;
unsigned int sched_disable_gucid_threshold;
} submission_state;
bool submission_supported;
bool submission_selected;
bool submission_initialized;
struct intel_uc_fw_ver submission_version;
bool rc_supported;
bool rc_selected;
struct i915_vma *ads_vma;
struct iosys_map ads_map;
u32 ads_regset_size;
u32 ads_regset_count[I915_NUM_ENGINES];
struct guc_mmio_reg *ads_regset;
u32 ads_golden_ctxt_size;
u32 ads_waklv_size;
u32 ads_capture_size;
struct i915_vma *lrc_desc_pool_v69;
void *lrc_desc_pool_vaddr_v69;
struct xarray context_lookup;
u32 params[GUC_CTL_MAX_DWORDS];
struct {
u32 base;
unsigned int count;
enum forcewake_domains fw_domains;
} send_regs;
i915_reg_t notify_reg;
u32 mmio_msg;
struct mutex send_mutex;
struct {
spinlock_t lock;
u64 gt_stamp;
unsigned long ping_delay;
struct delayed_work work;
u32 shift;
unsigned long last_stat_jiffies;
} timestamp;
struct work_struct dead_guc_worker;
unsigned long last_dead_guc_jiffies;
#ifdef CONFIG_DRM_I915_SELFTEST;
int number_guc_id_stolen;
u32 fast_response_selftest;
#endif;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">fw</span></code></dt><dd><p>the GuC firmware</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">log</span></code></dt><dd><p>sub-structure containing GuC log related data and objects</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ct</span></code></dt><dd><p>the command transport communication channel</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">slpc</span></code></dt><dd><p>sub-structure containing SLPC related data and objects</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">capture</span></code></dt><dd><p>the error-state-capture module’s data and objects</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">dbgfs_node</span></code></dt><dd><p>debugfs node</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sched_engine</span></code></dt><dd><p>Global engine used to submit requests to GuC</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">stalled_request</span></code></dt><dd><p>if GuC can’t process a request for any reason, we
save it until GuC restarts processing. No other request can be
submitted until the stalled request is processed.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_stall_reason</span></code></dt><dd><p>reason why submission is stalled</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">irq_lock</span></code></dt><dd><p>protects GuC irq state</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">msg_enabled_mask</span></code></dt><dd><p>mask of events that are processed when receiving
an INTEL_GUC_ACTION_DEFAULT G2H message.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">outstanding_submission_g2h</span></code></dt><dd><p>number of outstanding GuC to Host
responses related to GuC submission, used to determine if the GT is
idle</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">tlb_lookup</span></code></dt><dd><p>xarray to store all pending TLB invalidation requests</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">serial_slot</span></code></dt><dd><p>id to the initial waiter created in tlb_lookup,
which is used only when failed to allocate new waiter.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">next_seqno</span></code></dt><dd><p>the next id (sequence number) to allocate.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">interrupts</span></code></dt><dd><p>pointers to GuC interrupt-managing functions.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state</span></code></dt><dd><p>sub-structure for submission state protected by
single lock</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.lock</span></code></dt><dd><p>protects everything in
submission_state, ce->guc_id.id, and ce->guc_id.ref
when transitioning in and out of zero</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.guc_ids</span></code></dt><dd><p>used to allocate new
guc_ids, single-lrc</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.num_guc_ids</span></code></dt><dd><p>Number of guc_ids, selftest
feature to be able to reduce this number while testing.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.guc_ids_bitmap</span></code></dt><dd><p>used to allocate
new guc_ids, multi-lrc</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.guc_id_list</span></code></dt><dd><p>list of intel_context
with valid guc_ids but no refs</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.guc_ids_in_use</span></code></dt><dd><p>Number single-lrc
guc_ids in use</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.destroyed_contexts</span></code></dt><dd><p>list of contexts
waiting to be destroyed (deregistered with the GuC)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.destroyed_worker</span></code></dt><dd><p>worker to deregister
contexts, need as we need to take a GT PM reference and
can’t from destroy function as it might be in an atomic
context (no sleeping)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.reset_fail_worker</span></code></dt><dd><p>worker to trigger
a GT reset after an engine reset fails</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.reset_fail_mask</span></code></dt><dd><p>mask of engines that
failed to reset</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.sched_disable_delay_ms</span></code></dt><dd><p>schedule
disable delay, in ms, for contexts</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_state.sched_disable_gucid_threshold</span></code></dt><dd><p>threshold of min remaining available guc_ids before
we start bypassing the schedule disable delay</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_supported</span></code></dt><dd><p>tracks whether we support GuC submission on
the current platform</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_selected</span></code></dt><dd><p>tracks whether the user enabled GuC submission</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_initialized</span></code></dt><dd><p>tracks whether GuC submission has been initialised</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">submission_version</span></code></dt><dd><p>Submission API version of the currently loaded firmware</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">rc_supported</span></code></dt><dd><p>tracks whether we support GuC rc on the current platform</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">rc_selected</span></code></dt><dd><p>tracks whether the user enabled GuC rc</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_vma</span></code></dt><dd><p>object allocated to hold the GuC ADS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_map</span></code></dt><dd><p>contents of the GuC ADS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_regset_size</span></code></dt><dd><p>size of the save/restore regsets in the ADS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_regset_count</span></code></dt><dd><p>number of save/restore registers in the ADS for
each engine</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_regset</span></code></dt><dd><p>save/restore regsets in the ADS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_golden_ctxt_size</span></code></dt><dd><p>size of the golden contexts in the ADS</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_waklv_size</span></code></dt><dd><p>size of workaround KLVs</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ads_capture_size</span></code></dt><dd><p>size of register lists in the ADS used for error capture</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">lrc_desc_pool_v69</span></code></dt><dd><p>object allocated to hold the GuC LRC descriptor pool</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">lrc_desc_pool_vaddr_v69</span></code></dt><dd><p>contents of the GuC LRC descriptor pool</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">context_lookup</span></code></dt><dd><p>used to resolve intel_context from guc_id, if a
context is present in this structure it is registered with the GuC</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">params</span></code></dt><dd><p>Control params for fw initialization</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">send_regs</span></code></dt><dd><p>GuC’s FW specific registers used for sending MMIO H2G</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">notify_reg</span></code></dt><dd><p>register used to send interrupts to the GuC FW</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">mmio_msg</span></code></dt><dd><p>notification bitmask that the GuC writes in one of its
registers when the CT channel is disabled, to be processed when the
channel is back up.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">send_mutex</span></code></dt><dd><p>used to serialize the intel_guc_send actions</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp</span></code></dt><dd><p>GT timestamp object that stores a copy of the timestamp
and adjusts it for overflow using a worker.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.lock</span></code></dt><dd><p>Lock protecting the below fields and
the engine stats.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.gt_stamp</span></code></dt><dd><p>64-bit extended value of the GT
timestamp.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.ping_delay</span></code></dt><dd><p>Period for polling the GT
timestamp for overflow.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.work</span></code></dt><dd><p>Periodic work to adjust GT timestamp,
engine and context usage for overflows.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.shift</span></code></dt><dd><p>Right shift value for the gpm timestamp</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">timestamp.last_stat_jiffies</span></code></dt><dd><p>jiffies at last actual
stats collection time. We use this timestamp to ensure
we don’t oversample the stats because runtime power
management events can trigger stats collection at much
higher rates than required.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">dead_guc_worker</span></code></dt><dd><p>Asynchronous worker thread for forcing a GuC reset.
Specifically used when the G2H handler wants to issue a reset. Resets
require flushing the G2H queue. So, the G2H processing itself must not
trigger a reset directly. Instead, go via this worker.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">last_dead_guc_jiffies</span></code></dt><dd><p>timestamp of previous ‘dead guc’ occurrence
used to prevent a fundamentally broken system from continuously
reloading the GuC.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">number_guc_id_stolen</span></code></dt><dd><p>The number of guc_ids that have been stolen</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">fast_response_selftest</span></code></dt><dd><p>Backdoor to CT handler for fast response selftest</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>It handles firmware loading and manages client pool. intel_guc owns an
i915_sched_engine for submission.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_guc_ggtt_offset">
<span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_guc_ggtt_offset</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_guc" title="intel_guc"><span class="n"><span class="pre">intel_guc</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">guc</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">vma</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_guc_ggtt_offset" title="Link to this definition">¶</a><br /></dt>
<dd><p>Get and validate the GGTT offset of <strong>vma</strong></p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_guc</span> <span class="pre">*guc</span></code></dt><dd><p>intel_guc structure.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_vma</span> <span class="pre">*vma</span></code></dt><dd><p>i915 graphics virtual memory area.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>GuC does not allow any gfx GGTT address that falls into range
[0, ggtt.pin_bias), which is reserved for Boot ROM, SRAM and WOPCM.
Currently, in order to exclude [0, ggtt.pin_bias) address space from
GGTT, all gfx objects used by GuC are allocated with <a class="reference internal" href="#c.intel_guc_allocate_vma" title="intel_guc_allocate_vma"><code class="xref c c-func docutils literal notranslate"><span class="pre">intel_guc_allocate_vma()</span></code></a>
and pinned with PIN_OFFSET_BIAS along with the value of ggtt.pin_bias.</p>
<p><strong>Return</strong></p>
<p>GGTT offset of the <strong>vma</strong>.</p>
</div>
<section id="guc-firmware-layout">
<h4>GuC Firmware Layout<a class="headerlink" href="#guc-firmware-layout" title="Link to this heading">¶</a></h4>
<p>The GuC/HuC firmware layout looks like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+======================================================================+
| Firmware blob |
+===============+===============+============+============+============+
| CSS header | uCode | RSA key | modulus | exponent |
+===============+===============+============+============+============+
<-header size-> <---header size continued ----------->
<--- size ----------------------------------------------------------->
<-key size->
<-mod size->
<-exp size->
</pre></div>
</div>
<p>The firmware may or may not have modulus key and exponent data. The header,
uCode and RSA signature are must-have components that will be used by driver.
Length of each components, which is all in dwords, can be found in header.
In the case that modulus and exponent are not present in fw, a.k.a truncated
image, the length value still appears in header.</p>
<p>Driver will do some basic fw size validation based on the following rules:</p>
<ol class="arabic simple">
<li><p>Header, uCode and RSA are must-have components.</p></li>
<li><p>All firmware components, if they present, are in the sequence illustrated
in the layout table above.</p></li>
<li><p>Length info of each component can be found in header, in dwords.</p></li>
<li><p>Modulus and exponent key are not required by driver. They may not appear
in fw. So driver will load a truncated firmware in this case.</p></li>
</ol>
<p>Starting from DG2, the HuC is loaded by the GSC instead of i915. The GSC
firmware performs all the required integrity checks, we just need to check
the version. Note that the header for GSC-managed blobs is different from the
CSS used for dma-loaded firmwares.</p>
</section>
<section id="guc-memory-management">
<h4>GuC Memory Management<a class="headerlink" href="#guc-memory-management" title="Link to this heading">¶</a></h4>
<p>GuC can’t allocate any memory for its own usage, so all the allocations must
be handled by the host driver. GuC accesses the memory via the GGTT, with the
exception of the top and bottom parts of the 4GB address space, which are
instead re-mapped by the GuC HW to memory location of the FW itself (WOPCM)
or other parts of the HW. The driver must take care not to place objects that
the GuC is going to access in these reserved ranges. The layout of the GuC
address space is shown below:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> +===========> +====================+ <== FFFF_FFFF
^ | Reserved |
| +====================+ <== GUC_GGTT_TOP
| | |
| | DRAM |
GuC | |
Address +===> +====================+ <== GuC ggtt_pin_bias
Space ^ | |
| | | |
| GuC | GuC |
| WOPCM | WOPCM |
| Size | |
| | | |
v v | |
+=======+===> +====================+ <== 0000_0000
</pre></div>
</div>
<p>The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to GuC WOPCM
while upper part of GuC Address Space [ggtt_pin_bias, GUC_GGTT_TOP) is mapped
to DRAM. The value of the GuC ggtt_pin_bias is the GuC WOPCM size.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_guc_allocate_vma">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_vma</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">intel_guc_allocate_vma</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_guc" title="intel_guc"><span class="n"><span class="pre">intel_guc</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">guc</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">size</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_guc_allocate_vma" title="Link to this definition">¶</a><br /></dt>
<dd><p>Allocate a GGTT VMA for GuC usage</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_guc</span> <span class="pre">*guc</span></code></dt><dd><p>the guc</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">size</span></code></dt><dd><p>size of area to allocate (both virtual space and memory)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is a wrapper to create an object for use with the GuC. In order to
use it inside the GuC, an object needs to be pinned lifetime, so we allocate
both some backing storage and a range inside the Global GTT. We must pin
it in the GGTT somewhere other than than [0, GUC ggtt_pin_bias) because that
range is reserved inside GuC.</p>
<p><strong>Return</strong></p>
<p>A i915_vma if successful, otherwise an ERR_PTR.</p>
</div>
</section>
<section id="guc-specific-firmware-loader">
<h4>GuC-specific firmware loader<a class="headerlink" href="#guc-specific-firmware-loader" title="Link to this heading">¶</a></h4>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_guc_fw_upload">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_guc_fw_upload</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.intel_guc" title="intel_guc"><span class="n"><span class="pre">intel_guc</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">guc</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_guc_fw_upload" title="Link to this definition">¶</a><br /></dt>
<dd><p>load GuC uCode to device</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_guc</span> <span class="pre">*guc</span></code></dt><dd><p>intel_guc structure</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Called from <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_uc_init_hw()</span></code> during driver load, resume from sleep and
after a GPU reset.</p>
<p>The firmware image should have already been fetched into memory, so only
check that fetch succeeded, and then transfer the image to the h/w.</p>
<p><strong>Return</strong></p>
<p>non-zero code on error</p>
</div>
</section>
<section id="guc-based-command-submission">
<h4>GuC-based command submission<a class="headerlink" href="#guc-based-command-submission" title="Link to this heading">¶</a></h4>
<p>The Scratch registers:
There are 16 MMIO-based registers start from 0xC180. The kernel driver writes
a value to the action register (SOFT_SCRATCH_0) along with any data. It then
triggers an interrupt on the GuC via another register write (0xC4C8).
Firmware writes a success/fail code back to the action register after
processes the request. The kernel driver polls waiting for this update and
then proceeds.</p>
<p>Command Transport buffers (CTBs):
Covered in detail in other sections but CTBs (Host to GuC - H2G, GuC to Host
- G2H) are a message interface between the i915 and GuC.</p>
<p>Context registration:
Before a context can be submitted it must be registered with the GuC via a
H2G. A unique guc_id is associated with each context. The context is either
registered at request creation time (normal operation) or at submission time
(abnormal operation, e.g. after a reset).</p>
<p>Context submission:
The i915 updates the LRC tail value in memory. The i915 must enable the
scheduling of the context within the GuC for the GuC to actually consider it.
Therefore, the first time a disabled context is submitted we use a schedule
enable H2G, while follow up submissions are done via the context submit H2G,
which informs the GuC that a previously enabled context has new work
available.</p>
<p>Context unpin:
To unpin a context a H2G is used to disable scheduling. When the
corresponding G2H returns indicating the scheduling disable operation has
completed it is safe to unpin the context. While a disable is in flight it
isn’t safe to resubmit the context so a fence is used to stall all future
requests of that context until the G2H is returned. Because this interaction
with the GuC takes a non-zero amount of time we delay the disabling of
scheduling after the pin count goes to zero by a configurable period of time
(see SCHED_DISABLE_DELAY_MS). The thought is this gives the user a window of
time to resubmit something on the context before doing this costly operation.
This delay is only done if the context isn’t closed and the guc_id usage is
less than a threshold (see NUM_SCHED_DISABLE_GUC_IDS_THRESHOLD).</p>
<p>Context deregistration:
Before a context can be destroyed or if we steal its guc_id we must
deregister the context with the GuC via H2G. If stealing the guc_id it isn’t
safe to submit anything to this guc_id until the deregister completes so a
fence is used to stall all requests associated with this guc_id until the
corresponding G2H returns indicating the guc_id has been deregistered.</p>
<p>submission_state.guc_ids:
Unique number associated with private GuC context data passed in during
context registration / submission / deregistration. 64k available. Simple ida
is used for allocation.</p>
<p>Stealing guc_ids:
If no guc_ids are available they can be stolen from another context at
request creation time if that context is unpinned. If a guc_id can’t be found
we punt this problem to the user as we believe this is near impossible to hit
during normal use cases.</p>
<p>Locking:
In the GuC submission code we have 3 basic spin locks which protect
everything. Details about each below.</p>
<p>sched_engine->lock
This is the submission lock for all contexts that share an i915 schedule
engine (sched_engine), thus only one of the contexts which share a
sched_engine can be submitting at a time. Currently only one sched_engine is
used for all of GuC submission but that could change in the future.</p>
<p>guc->submission_state.lock
Global lock for GuC submission state. Protects guc_ids and destroyed contexts
list.</p>
<p>ce->guc_state.lock
Protects everything under ce->guc_state. Ensures that a context is in the
correct state before issuing a H2G. e.g. We don’t issue a schedule disable
on a disabled context (bad idea), we don’t issue a schedule enable when a
schedule disable is in flight, etc... Also protects list of inflight requests
on the context and the priority management state. Lock is individual to each
context.</p>
<p>Lock ordering rules:
sched_engine->lock -> ce->guc_state.lock
guc->submission_state.lock -> ce->guc_state.lock</p>
<p>Reset races:
When a full GT reset is triggered it is assumed that some G2H responses to
H2Gs can be lost as the GuC is also reset. Losing these G2H can prove to be
fatal as we do certain operations upon receiving a G2H (e.g. destroy
contexts, release guc_ids, etc...). When this occurs we can scrub the
context state and cleanup appropriately, however this is quite racey.
To avoid races, the reset code must disable submission before scrubbing for
the missing G2H, while the submission code must check for submission being
disabled and skip sending H2Gs and updating context states when it is. Both
sides must also make sure to hold the relevant locks.</p>
</section>
<section id="guc-abi">
<h4>GuC ABI<a class="headerlink" href="#guc-abi" title="Link to this heading">¶</a></h4>
<p id="hxg-message"><strong>HXG Message</strong></p>
<p>All messages exchanged with GuC are defined using 32 bit dwords.
First dword is treated as a message header. Remaining dwords are optional.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><dl class="simple">
<dt><strong>ORIGIN</strong> - originator of the message</dt><dd><ul class="simple">
<li><p><span class="target" id="guc-hxg-origin-host">GUC_HXG_ORIGIN_HOST</span> = 0</p></li>
<li><p><span class="target" id="guc-hxg-origin-guc">GUC_HXG_ORIGIN_GUC</span> = 1</p></li>
</ul>
</dd>
</dl>
</td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><dl class="simple">
<dt><strong>TYPE</strong> - message type</dt><dd><ul class="simple">
<li><p><span class="target" id="guc-hxg-type-request">GUC_HXG_TYPE_REQUEST</span> = 0</p></li>
<li><p><span class="target" id="guc-hxg-type-event">GUC_HXG_TYPE_EVENT</span> = 1</p></li>
<li><p><span class="target" id="guc-hxg-type-fast-request">GUC_HXG_TYPE_FAST_REQUEST</span> = 2</p></li>
<li><p><span class="target" id="guc-hxg-type-no-response-busy">GUC_HXG_TYPE_NO_RESPONSE_BUSY</span> = 3</p></li>
<li><p><span class="target" id="guc-hxg-type-no-response-retry">GUC_HXG_TYPE_NO_RESPONSE_RETRY</span> = 5</p></li>
<li><p><span class="target" id="guc-hxg-type-response-failure">GUC_HXG_TYPE_RESPONSE_FAILURE</span> = 6</p></li>
<li><p><span class="target" id="guc-hxg-type-response-success">GUC_HXG_TYPE_RESPONSE_SUCCESS</span> = 7</p></li>
</ul>
</dd>
</dl>
</td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><p><strong>AUX</strong> - auxiliary data (depends on TYPE)</p></td>
</tr>
<tr class="row-odd"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p><strong>PAYLOAD</strong> - optional payload (depends on TYPE)</p></td>
</tr>
<tr class="row-even"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-request"><strong>HXG Request</strong></p>
<p>The <a class="reference internal" href="#hxg-request">HXG Request</a> message should be used to initiate synchronous activity
for which confirmation or return data is expected.</p>
<p>The recipient of this message shall use <a class="reference internal" href="#hxg-response">HXG Response</a>, <a class="reference internal" href="#hxg-failure">HXG Failure</a>
or <a class="reference internal" href="#hxg-retry">HXG Retry</a> message as a definite reply, and may use <a class="reference internal" href="#hxg-busy">HXG Busy</a>
message as a intermediate reply.</p>
<p>Format of <strong>DATA0</strong> and all <strong>DATAn</strong> fields depends on the <strong>ACTION</strong> code.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-request">GUC_HXG_TYPE_REQUEST</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p><strong>DATA0</strong> - request data (depends on ACTION)</p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p><strong>ACTION</strong> - requested action code</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p><strong>DATAn</strong> - optional data (depends on ACTION)</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-fast-request"><strong>HXG Fast Request</strong></p>
<p>The <a class="reference internal" href="#hxg-request">HXG Request</a> message should be used to initiate asynchronous activity
for which confirmation or return data is not expected.</p>
<p>If confirmation is required then <a class="reference internal" href="#hxg-request">HXG Request</a> shall be used instead.</p>
<p>The recipient of this message may only use <a class="reference internal" href="#hxg-failure">HXG Failure</a> message if it was
unable to accept this request (like invalid data).</p>
<p>Format of <a class="reference internal" href="#hxg-fast-request">HXG Fast Request</a> message is same as <a class="reference internal" href="#hxg-request">HXG Request</a> except <strong>TYPE</strong>.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN - see <a class="reference internal" href="#hxg-message">HXG Message</a></p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-fast-request">GUC_HXG_TYPE_FAST_REQUEST</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p>DATA0 - see <a class="reference internal" href="#hxg-request">HXG Request</a></p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p>ACTION - see <a class="reference internal" href="#hxg-request">HXG Request</a></p></td>
</tr>
<tr class="row-even"><td><p>...</p></td>
<td></td>
<td><p>DATAn - see <a class="reference internal" href="#hxg-request">HXG Request</a></p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-event"><strong>HXG Event</strong></p>
<p>The <a class="reference internal" href="#hxg-event">HXG Event</a> message should be used to initiate asynchronous activity
that does not involves immediate confirmation nor data.</p>
<p>Format of <strong>DATA0</strong> and all <strong>DATAn</strong> fields depends on the <strong>ACTION</strong> code.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-event">GUC_HXG_TYPE_EVENT</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p><strong>DATA0</strong> - event data (depends on ACTION)</p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p><strong>ACTION</strong> - event action code</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p><strong>DATAn</strong> - optional event data (depends on ACTION)</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-busy"><strong>HXG Busy</strong></p>
<p>The <a class="reference internal" href="#hxg-busy">HXG Busy</a> message may be used to acknowledge reception of the <a class="reference internal" href="#hxg-request">HXG Request</a>
message if the recipient expects that it processing will be longer than default
timeout.</p>
<p>The <strong>COUNTER</strong> field may be used as a progress indicator.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-no-response-busy">GUC_HXG_TYPE_NO_RESPONSE_BUSY</a></p></td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><p><strong>COUNTER</strong> - progress indicator</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-retry"><strong>HXG Retry</strong></p>
<p>The <a class="reference internal" href="#hxg-retry">HXG Retry</a> message should be used by recipient to indicate that the
<a class="reference internal" href="#hxg-request">HXG Request</a> message was dropped and it should be resent again.</p>
<p>The <strong>REASON</strong> field may be used to provide additional information.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-no-response-retry">GUC_HXG_TYPE_NO_RESPONSE_RETRY</a></p></td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><dl class="simple">
<dt><strong>REASON</strong> - reason for retry</dt><dd><ul class="simple">
<li><p><span class="target" id="guc-hxg-retry-reason-unspecified">GUC_HXG_RETRY_REASON_UNSPECIFIED</span> = 0</p></li>
</ul>
</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-failure"><strong>HXG Failure</strong></p>
<p>The <a class="reference internal" href="#hxg-failure">HXG Failure</a> message shall be used as a reply to the <a class="reference internal" href="#hxg-request">HXG Request</a>
message that could not be processed due to an error.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-response-failure">GUC_HXG_TYPE_RESPONSE_FAILURE</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p><strong>HINT</strong> - additional error hint</p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p><strong>ERROR</strong> - error/result code</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="hxg-response"><strong>HXG Response</strong></p>
<p>The <a class="reference internal" href="#hxg-response">HXG Response</a> message shall be used as a reply to the <a class="reference internal" href="#hxg-request">HXG Request</a>
message that was successfully processed without an error.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN</p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-response-success">GUC_HXG_TYPE_RESPONSE_SUCCESS</a></p></td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><p><strong>DATA0</strong> - data (depends on ACTION from <a class="reference internal" href="#hxg-request">HXG Request</a>)</p></td>
</tr>
<tr class="row-odd"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p><strong>DATAn</strong> - data (depends on ACTION from <a class="reference internal" href="#hxg-request">HXG Request</a>)</p></td>
</tr>
<tr class="row-even"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="guc-mmio-based-communication"><strong>GuC MMIO based communication</strong></p>
<p>The MMIO based communication between Host and GuC relies on special
hardware registers which format could be defined by the software
(so called scratch registers).</p>
<p>Each MMIO based message, both Host to GuC (H2G) and GuC to Host (G2H)
messages, which maximum length depends on number of available scratch
registers, is directly written into those scratch registers.</p>
<p>For Gen9+, there are 16 software scratch registers 0xC180-0xC1B8,
but no H2G command takes more than 4 parameters and the GuC firmware
itself uses an 4-element array to store the H2G message.</p>
<p>For Gen11+, there are additional 4 registers 0x190240-0x19024C, which
are, regardless on lower count, preferred over legacy ones.</p>
<p>The MMIO based communication is mainly used during driver initialization
phase to setup the <a class="reference internal" href="#ctb-based-communication">CTB based communication</a> that will be used afterwards.</p>
<p id="mmio-hxg-message"><strong>MMIO HXG Message</strong></p>
<p>Format of the MMIO messages follows definitions of <a class="reference internal" href="#hxg-message">HXG Message</a>.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>0</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p>[Embedded <a class="reference internal" href="#hxg-message">HXG Message</a>]</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="ct-buffer"><strong>CT Buffer</strong></p>
<p>Circular buffer used to send <a class="reference internal" href="#ctb-message">CTB Message</a></p>
<p id="ctb-descriptor"><strong>CTB Descriptor</strong></p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>0</p></td>
<td><p>31:0</p></td>
<td><p><strong>HEAD</strong> - offset (in dwords) to the last dword that was
read from the <a class="reference internal" href="#ct-buffer">CT Buffer</a>.
It can only be updated by the receiver.</p></td>
</tr>
<tr class="row-odd"><td><p>1</p></td>
<td><p>31:0</p></td>
<td><p><strong>TAIL</strong> - offset (in dwords) to the last dword that was
written to the <a class="reference internal" href="#ct-buffer">CT Buffer</a>.
It can only be updated by the sender.</p></td>
</tr>
<tr class="row-even"><td><p>2</p></td>
<td><p>31:0</p></td>
<td><p><strong>STATUS</strong> - status of the CTB</p>
<blockquote>
<div><ul class="simple">
<li><p><span class="target" id="guc-ctb-status-no-error">GUC_CTB_STATUS_NO_ERROR</span> = 0 (normal operation)</p></li>
<li><p><span class="target" id="guc-ctb-status-overflow">GUC_CTB_STATUS_OVERFLOW</span> = 1 (head/tail too large)</p></li>
<li><p><span class="target" id="guc-ctb-status-underflow">GUC_CTB_STATUS_UNDERFLOW</span> = 2 (truncated message)</p></li>
<li><p><span class="target" id="guc-ctb-status-mismatch">GUC_CTB_STATUS_MISMATCH</span> = 4 (head/tail modified)</p></li>
<li><p><span class="target" id="guc-ctb-status-unused">GUC_CTB_STATUS_UNUSED</span> = 8 (CTB is not in use)</p></li>
</ul>
</div></blockquote>
</td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
<td><p>RESERVED = MBZ</p></td>
</tr>
<tr class="row-even"><td><p>15</p></td>
<td><p>31:0</p></td>
<td><p>RESERVED = MBZ</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="ctb-message"><strong>CTB Message</strong></p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31:16</p></td>
<td><p><strong>FENCE</strong> - message identifier</p></td>
</tr>
<tr class="row-odd"><td><p>15:12</p></td>
<td><dl class="simple">
<dt><strong>FORMAT</strong> - format of the CTB message</dt><dd><ul class="simple">
<li><p><span class="target" id="guc-ctb-format-hxg">GUC_CTB_FORMAT_HXG</span> = 0 - see <a class="reference internal" href="#ctb-hxg-message">CTB HXG Message</a></p></li>
</ul>
</dd>
</dl>
</td>
</tr>
<tr class="row-even"><td><p>11:8</p></td>
<td><p><strong>RESERVED</strong></p></td>
</tr>
<tr class="row-odd"><td><p>7:0</p></td>
<td><p><strong>NUM_DWORDS</strong> - length of the CTB message (w/o header)</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p>optional (depends on FORMAT)</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="ctb-hxg-message"><strong>CTB HXG Message</strong></p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31:16</p></td>
<td><p>FENCE</p></td>
</tr>
<tr class="row-odd"><td><p>15:12</p></td>
<td><p>FORMAT = <a class="reference internal" href="#guc-ctb-format-hxg">GUC_CTB_FORMAT_HXG</a></p></td>
</tr>
<tr class="row-even"><td><p>11:8</p></td>
<td><p>RESERVED = MBZ</p></td>
</tr>
<tr class="row-odd"><td><p>7:0</p></td>
<td><p>NUM_DWORDS = length (in dwords) of the embedded HXG message</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p>[Embedded <a class="reference internal" href="#hxg-message">HXG Message</a>]</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="ctb-based-communication"><strong>CTB based communication</strong></p>
<p>The CTB (command transport buffer) communication between Host and GuC
is based on u32 data stream written to the shared buffer. One buffer can
be used to transmit data only in one direction (one-directional channel).</p>
<p>Current status of the each buffer is stored in the buffer descriptor.
Buffer descriptor holds tail and head fields that represents active data
stream. The tail field is updated by the data producer (sender), and head
field is updated by the data consumer (receiver):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+------------+
| DESCRIPTOR | +=================+============+========+
+============+ | | MESSAGE(s) | |
| address |--------->+=================+============+========+
+------------+
| head | ^-----head--------^
+------------+
| tail | ^---------tail-----------------^
+------------+
| size | ^---------------size--------------------^
+------------+
</pre></div>
</div>
<p>Each message in data stream starts with the single u32 treated as a header,
followed by optional set of u32 data that makes message specific payload:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+------------+---------+---------+---------+
| MESSAGE |
+------------+---------+---------+---------+
| msg[0] | [1] | ... | [n-1] |
+------------+---------+---------+---------+
| MESSAGE | MESSAGE PAYLOAD |
+ HEADER +---------+---------+---------+
| | 0 | ... | n |
+======+=====+=========+=========+=========+
| 31:16| code| | | |
+------+-----+ | | |
| 15:5|flags| | | |
+------+-----+ | | |
| 4:0| len| | | |
+------+-----+---------+---------+---------+
^-------------len-------------^
</pre></div>
</div>
<p>The message header consists of:</p>
<ul class="simple">
<li><p><strong>len</strong>, indicates length of the message payload (in u32)</p></li>
<li><p><strong>code</strong>, indicates message code</p></li>
<li><p><strong>flags</strong>, holds various bits to control message handling</p></li>
</ul>
<p id="host2guc-self-cfg"><strong>HOST2GUC_SELF_CFG</strong></p>
<p>This message is used by Host KMD to setup of the <a class="reference internal" href="#guc-self-config-klvs">GuC Self Config KLVs</a>.</p>
<p>This message must be sent as <a class="reference internal" href="#mmio-hxg-message">MMIO HXG Message</a>.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN = <a class="reference internal" href="#guc-hxg-origin-host">GUC_HXG_ORIGIN_HOST</a></p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-request">GUC_HXG_TYPE_REQUEST</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p>DATA0 = MBZ</p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p>ACTION = <span class="target" id="guc-action-host2guc-self-cfg">GUC_ACTION_HOST2GUC_SELF_CFG</span> = 0x0508</p></td>
</tr>
<tr class="row-even"><td rowspan="2"><p>1</p></td>
<td><p>31:16</p></td>
<td><p><strong>KLV_KEY</strong> - KLV key, see <a class="reference internal" href="#guc-self-config-klvs">GuC Self Config KLVs</a></p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p><strong>KLV_LEN</strong> - KLV length</p>
<blockquote>
<div><ul class="simple">
<li><p>32 bit KLV = 1</p></li>
<li><p>64 bit KLV = 2</p></li>
</ul>
</div></blockquote>
</td>
</tr>
<tr class="row-even"><td><p>2</p></td>
<td><p>31:0</p></td>
<td><p><strong>VALUE32</strong> - Bits 31-0 of the KLV value</p></td>
</tr>
<tr class="row-odd"><td><p>3</p></td>
<td><p>31:0</p></td>
<td><p><strong>VALUE64</strong> - Bits 63-32 of the KLV value (<strong>KLV_LEN</strong> = 2)</p></td>
</tr>
</tbody>
</table>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN = <a class="reference internal" href="#guc-hxg-origin-guc">GUC_HXG_ORIGIN_GUC</a></p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-response-success">GUC_HXG_TYPE_RESPONSE_SUCCESS</a></p></td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><p>DATA0 = <strong>NUM</strong> - 1 if KLV was parsed, 0 if not recognized</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="host2guc-control-ctb"><strong>HOST2GUC_CONTROL_CTB</strong></p>
<p>This H2G action allows Vf Host to enable or disable H2G and G2H <a class="reference internal" href="#ct-buffer">CT Buffer</a>.</p>
<p>This message must be sent as <a class="reference internal" href="#mmio-hxg-message">MMIO HXG Message</a>.</p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="4"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN = <a class="reference internal" href="#guc-hxg-origin-host">GUC_HXG_ORIGIN_HOST</a></p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-request">GUC_HXG_TYPE_REQUEST</a></p></td>
</tr>
<tr class="row-even"><td><p>27:16</p></td>
<td><p>DATA0 = MBZ</p></td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p>ACTION = <span class="target" id="guc-action-host2guc-control-ctb">GUC_ACTION_HOST2GUC_CONTROL_CTB</span> = 0x4509</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td><p><strong>CONTROL</strong> - control <a class="reference internal" href="#ctb-based-communication">CTB based communication</a></p>
<blockquote>
<div><ul class="simple">
<li><p><span class="target" id="guc-ctb-control-disable">GUC_CTB_CONTROL_DISABLE</span> = 0</p></li>
<li><p><span class="target" id="guc-ctb-control-enable">GUC_CTB_CONTROL_ENABLE</span> = 1</p></li>
</ul>
</div></blockquote>
</td>
</tr>
</tbody>
</table>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="3"><p>0</p></td>
<td><p>31</p></td>
<td><p>ORIGIN = <a class="reference internal" href="#guc-hxg-origin-guc">GUC_HXG_ORIGIN_GUC</a></p></td>
</tr>
<tr class="row-odd"><td><p>30:28</p></td>
<td><p>TYPE = <a class="reference internal" href="#guc-hxg-type-response-success">GUC_HXG_TYPE_RESPONSE_SUCCESS</a></p></td>
</tr>
<tr class="row-even"><td><p>27:0</p></td>
<td><p>DATA0 = MBZ</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="guc-klv"><strong>GuC KLV</strong></p>
<blockquote>
<div><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Bits</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td rowspan="2"><p>0</p></td>
<td><p>31:16</p></td>
<td><dl class="simple">
<dt><strong>KEY</strong> - KLV key identifier</dt><dd><ul class="simple">
<li><p><a class="reference internal" href="#guc-self-config-klvs">GuC Self Config KLVs</a></p></li>
</ul>
</dd>
</dl>
</td>
</tr>
<tr class="row-odd"><td><p>15:0</p></td>
<td><p><strong>LEN</strong> - length of VALUE (in 32bit dwords)</p></td>
</tr>
<tr class="row-even"><td><p>1</p></td>
<td><p>31:0</p></td>
<td rowspan="3"><p><strong>VALUE</strong> - actual value of the KLV (format depends on KEY)</p></td>
</tr>
<tr class="row-odd"><td><p>...</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>n</p></td>
<td><p>31:0</p></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p id="guc-self-config-klvs"><strong>GuC Self Config KLVs</strong></p>
<p><a class="reference internal" href="#guc-klv">GuC KLV</a> keys available for use with <a class="reference internal" href="#host2guc-self-cfg">HOST2GUC_SELF_CFG</a>.</p>
<dl class="simple">
<dt><span class="target" id="guc-klv-self-cfg-h2g-ctb-addr">GUC_KLV_SELF_CFG_H2G_CTB_ADDR</span><span class="classifier">0x0902</span></dt><dd><p>Refers to 64 bit Global Gfx address of H2G <a class="reference internal" href="#ct-buffer">CT Buffer</a>.
Should be above WOPCM address but below APIC base address for native mode.</p>
</dd>
<dt><span class="target" id="guc-klv-self-cfg-h2g-ctb-descriptor-addr">GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR</span><span class="classifier">0x0903</span></dt><dd><p>Refers to 64 bit Global Gfx address of H2G <a class="reference internal" href="#ctb-descriptor">CTB Descriptor</a>.
Should be above WOPCM address but below APIC base address for native mode.</p>
</dd>
<dt><span class="target" id="guc-klv-self-cfg-h2g-ctb-size">GUC_KLV_SELF_CFG_H2G_CTB_SIZE</span><span class="classifier">0x0904</span></dt><dd><p>Refers to size of H2G <a class="reference internal" href="#ct-buffer">CT Buffer</a> in bytes.
Should be a multiple of 4K.</p>
</dd>
<dt><span class="target" id="guc-klv-self-cfg-g2h-ctb-addr">GUC_KLV_SELF_CFG_G2H_CTB_ADDR</span><span class="classifier">0x0905</span></dt><dd><p>Refers to 64 bit Global Gfx address of G2H <a class="reference internal" href="#ct-buffer">CT Buffer</a>.
Should be above WOPCM address but below APIC base address for native mode.</p>
</dd>
<dt><span class="target" id="guc-klv-self-cfg-g2h-ctb-descriptor-addr">GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR</span><span class="classifier">0x0906</span></dt><dd><p>Refers to 64 bit Global Gfx address of G2H <a class="reference internal" href="#ctb-descriptor">CTB Descriptor</a>.
Should be above WOPCM address but below APIC base address for native mode.</p>
</dd>
<dt><span class="target" id="guc-klv-self-cfg-g2h-ctb-size">GUC_KLV_SELF_CFG_G2H_CTB_SIZE</span><span class="classifier">0x0907</span></dt><dd><p>Refers to size of G2H <a class="reference internal" href="#ct-buffer">CT Buffer</a> in bytes.
Should be a multiple of 4K.</p>
</dd>
</dl>
</section>
</section>
<section id="huc">
<h3>HuC<a class="headerlink" href="#huc" title="Link to this heading">¶</a></h3>
<p>The HuC is a dedicated microcontroller for usage in media HEVC (High
Efficiency Video Coding) operations. Userspace can directly use the firmware
capabilities by adding HuC specific commands to batch buffers.</p>
<p>The kernel driver is only responsible for loading the HuC firmware and
triggering its security authentication. This is done differently depending
on the platform:</p>
<ul class="simple">
<li><p>older platforms (from Gen9 to most Gen12s): the load is performed via DMA
and the authentication via GuC</p></li>
<li><p>DG2: load and authentication are both performed via GSC.</p></li>
<li><p>MTL and newer platforms: the load is performed via DMA (same as with
not-DG2 older platforms), while the authentication is done in 2-steps,
a first auth for clear-media workloads via GuC and a second one for all
workloads via GSC.</p></li>
</ul>
<p>On platforms where the GuC does the authentication, to correctly do so the
HuC binary must be loaded before the GuC one.
Loading the HuC is optional; however, not using the HuC might negatively
impact power usage and/or performance of media workloads, depending on the
use-cases.
HuC must be reloaded on events that cause the WOPCM to lose its contents
(S3/S4, FLR); on older platforms the HuC must also be reloaded on GuC/GT
reset, while on newer ones it will survive that.</p>
<p>See <a class="reference external" href="https://github.com/intel/media-driver">https://github.com/intel/media-driver</a> for the latest details on HuC
functionality.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.intel_huc_auth">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">intel_huc_auth</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">intel_huc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">huc</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">intel_huc_authentication_type</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.intel_huc_auth" title="Link to this definition">¶</a><br /></dt>
<dd><p>Authenticate HuC uCode</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">intel_huc</span> <span class="pre">*huc</span></code></dt><dd><p>intel_huc structure</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">intel_huc_authentication_type</span> <span class="pre">type</span></code></dt><dd><p>authentication type (via GuC or via GSC)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Called after HuC and GuC firmware loading during <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_uc_init_hw()</span></code>.</p>
<p>This function invokes the GuC action to authenticate the HuC firmware,
passing the offset of the RSA signature to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">intel_guc_auth_huc()</span></code>. It then
waits for up to 50ms for firmware verification ACK.</p>
</div>
<section id="huc-memory-management">
<h4>HuC Memory Management<a class="headerlink" href="#huc-memory-management" title="Link to this heading">¶</a></h4>
<p>Similarly to the GuC, the HuC can’t do any memory allocations on its own,
with the difference being that the allocations for HuC usage are handled by
the userspace driver instead of the kernel one. The HuC accesses the memory
via the PPGTT belonging to the context loaded on the VCS executing the
HuC-specific commands.</p>
</section>
<section id="huc-firmware-layout">
<h4>HuC Firmware Layout<a class="headerlink" href="#huc-firmware-layout" title="Link to this heading">¶</a></h4>
<p>The HuC FW layout is the same as the GuC one, see <a class="reference internal" href="#guc-firmware-layout">GuC Firmware Layout</a></p>
</section>
</section>
<section id="dmc">
<h3>DMC<a class="headerlink" href="#dmc" title="Link to this heading">¶</a></h3>
<p>See <a class="reference internal" href="#dmc-firmware-support">DMC Firmware Support</a></p>
</section>
</section>
<section id="tracing">
<h2>Tracing<a class="headerlink" href="#tracing" title="Link to this heading">¶</a></h2>
<p>This sections covers all things related to the tracepoints implemented
in the i915 driver.</p>
<section id="i915-ppgtt-create-and-i915-ppgtt-release">
<h3>i915_ppgtt_create and i915_ppgtt_release<a class="headerlink" href="#i915-ppgtt-create-and-i915-ppgtt-release" title="Link to this heading">¶</a></h3>
<p>With full ppgtt enabled each process using drm will allocate at least one
translation table. With these traces it is possible to keep track of the
allocation and of the lifetime of the tables; this can be used during
testing/debug to verify that we are not leaking ppgtts.
These traces identify the ppgtt through the vm pointer, which is also printed
by the i915_vma_bind and i915_vma_unbind tracepoints.</p>
</section>
<section id="i915-context-create-and-i915-context-free">
<h3>i915_context_create and i915_context_free<a class="headerlink" href="#i915-context-create-and-i915-context-free" title="Link to this heading">¶</a></h3>
<p>These tracepoints are used to track creation and deletion of contexts.
If full ppgtt is enabled, they also print the address of the vm assigned to
the context.</p>
</section>
</section>
<section id="perf">
<h2>Perf<a class="headerlink" href="#perf" title="Link to this heading">¶</a></h2>
<section id="overview">
<h3>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h3>
<p>Gen graphics supports a large number of performance counters that can help
driver and application developers understand and optimize their use of the
GPU.</p>
<p>This i915 perf interface enables userspace to configure and open a file
descriptor representing a stream of GPU metrics which can then be read() as
a stream of sample records.</p>
<p>The interface is particularly suited to exposing buffered metrics that are
captured by DMA from the GPU, unsynchronized with and unrelated to the CPU.</p>
<p>Streams representing a single context are accessible to applications with a
corresponding drm file descriptor, such that OpenGL can use the interface
without special privileges. Access to system-wide metrics requires root
privileges by default, unless changed via the dev.i915.perf_event_paranoid
sysctl option.</p>
</section>
<section id="comparison-with-core-perf">
<h3>Comparison with Core Perf<a class="headerlink" href="#comparison-with-core-perf" title="Link to this heading">¶</a></h3>
<p>The interface was initially inspired by the core Perf infrastructure but
some notable differences are:</p>
<p>i915 perf file descriptors represent a “stream” instead of an “event”; where
a perf event primarily corresponds to a single 64bit value, while a stream
might sample sets of tightly-coupled counters, depending on the
configuration. For example the Gen OA unit isn’t designed to support
orthogonal configurations of individual counters; it’s configured for a set
of related counters. Samples for an i915 perf stream capturing OA metrics
will include a set of counter values packed in a compact HW specific format.
The OA unit supports a number of different packing formats which can be
selected by the user opening the stream. Perf has support for grouping
events, but each event in the group is configured, validated and
authenticated individually with separate system calls.</p>
<p>i915 perf stream configurations are provided as an array of u64 (key,value)
pairs, instead of a fixed <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">with</span></code> multiple miscellaneous config members,
interleaved with event-type specific members.</p>
<p>i915 perf doesn’t support exposing metrics via an mmap’d circular buffer.
The supported metrics are being written to memory by the GPU unsynchronized
with the CPU, using HW specific packing formats for counter sets. Sometimes
the constraints on HW configuration require reports to be filtered before it
would be acceptable to expose them to unprivileged applications - to hide
the metrics of other processes/contexts. For these use cases a read() based
interface is a good fit, and provides an opportunity to filter data as it
gets copied from the GPU mapped buffers to userspace buffers.</p>
<section id="issues-hit-with-first-prototype-based-on-core-perf">
<h4>Issues hit with first prototype based on Core Perf<a class="headerlink" href="#issues-hit-with-first-prototype-based-on-core-perf" title="Link to this heading">¶</a></h4>
<p>The first prototype of this driver was based on the core perf
infrastructure, and while we did make that mostly work, with some changes to
perf, we found we were breaking or working around too many assumptions baked
into perf’s currently cpu centric design.</p>
<p>In the end we didn’t see a clear benefit to making perf’s implementation and
interface more complex by changing design assumptions while we knew we still
wouldn’t be able to use any existing perf based userspace tools.</p>
<p>Also considering the Gen specific nature of the Observability hardware and
how userspace will sometimes need to combine i915 perf OA metrics with
side-band OA data captured via MI_REPORT_PERF_COUNT commands; we’re
expecting the interface to be used by a platform specific userspace such as
OpenGL or tools. This is to say; we aren’t inherently missing out on having
a standard vendor/architecture agnostic interface by not using perf.</p>
<p>For posterity, in case we might re-visit trying to adapt core perf to be
better suited to exposing i915 metrics these were the main pain points we
hit:</p>
<ul>
<li><p>The perf based OA PMU driver broke some significant design assumptions:</p>
<p>Existing perf pmus are used for profiling work on a cpu and we were
introducing the idea of _IS_DEVICE pmus with different security
implications, the need to fake cpu-related data (such as user/kernel
registers) to fit with perf’s current design, and adding _DEVICE records
as a way to forward device-specific status records.</p>
<p>The OA unit writes reports of counters into a circular buffer, without
involvement from the CPU, making our PMU driver the first of a kind.</p>
<p>Given the way we were periodically forward data from the GPU-mapped, OA
buffer to perf’s buffer, those bursts of sample writes looked to perf like
we were sampling too fast and so we had to subvert its throttling checks.</p>
<p>Perf supports groups of counters and allows those to be read via
transactions internally but transactions currently seem designed to be
explicitly initiated from the cpu (say in response to a userspace read())
and while we could pull a report out of the OA buffer we can’t
trigger a report from the cpu on demand.</p>
<p>Related to being report based; the OA counters are configured in HW as a
set while perf generally expects counter configurations to be orthogonal.
Although counters can be associated with a group leader as they are
opened, there’s no clear precedent for being able to provide group-wide
configuration attributes (for example we want to let userspace choose the
OA unit report format used to capture all counters in a set, or specify a
GPU context to filter metrics on). We avoided using perf’s grouping
feature and forwarded OA reports to userspace via perf’s ‘raw’ sample
field. This suited our userspace well considering how coupled the counters
are when dealing with normalizing. It would be inconvenient to split
counters up into separate events, only to require userspace to recombine
them. For Mesa it’s also convenient to be forwarded raw, periodic reports
for combining with the side-band raw reports it captures using
MI_REPORT_PERF_COUNT commands.</p>
<ul>
<li><p>As a side note on perf’s grouping feature; there was also some concern
that using PERF_FORMAT_GROUP as a way to pack together counter values
would quite drastically inflate our sample sizes, which would likely
lower the effective sampling resolutions we could use when the available
memory bandwidth is limited.</p>
<p>With the OA unit’s report formats, counters are packed together as 32
or 40bit values, with the largest report size being 256 bytes.</p>
<p>PERF_FORMAT_GROUP values are 64bit, but there doesn’t appear to be a
documented ordering to the values, implying PERF_FORMAT_ID must also be
used to add a 64bit ID before each value; giving 16 bytes per counter.</p>
</li>
</ul>
<p>Related to counter orthogonality; we can’t time share the OA unit, while
event scheduling is a central design idea within perf for allowing
userspace to open + enable more events than can be configured in HW at any
one time. The OA unit is not designed to allow re-configuration while in
use. We can’t reconfigure the OA unit without losing internal OA unit
state which we can’t access explicitly to save and restore. Reconfiguring
the OA unit is also relatively slow, involving ~100 register writes. From
userspace Mesa also depends on a stable OA configuration when emitting
MI_REPORT_PERF_COUNT commands and importantly the OA unit can’t be
disabled while there are outstanding MI_RPC commands lest we hang the
command streamer.</p>
<p>The contents of sample records aren’t extensible by device drivers (i.e.
the sample_type bits). As an example; Sourab Gupta had been looking to
attach GPU timestamps to our OA samples. We were shoehorning OA reports
into sample records by using the ‘raw’ field, but it’s tricky to pack more
than one thing into this field because events/core.c currently only lets a
pmu give a single raw data pointer plus len which will be copied into the
ring buffer. To include more than the OA report we’d have to copy the
report into an intermediate larger buffer. I’d been considering allowing a
vector of data+len values to be specified for copying the raw data, but
it felt like a kludge to being using the raw field for this purpose.</p>
</li>
<li><p>It felt like our perf based PMU was making some technical compromises
just for the sake of using perf:</p>
<p><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">perf_event_open()</span></code> requires events to either relate to a pid or a specific
cpu core, while our device pmu related to neither. Events opened with a
pid will be automatically enabled/disabled according to the scheduling of
that process - so not appropriate for us. When an event is related to a
cpu id, perf ensures pmu methods will be invoked via an inter process
interrupt on that core. To avoid invasive changes our userspace opened OA
perf events for a specific cpu. This was workable but it meant the
majority of the OA driver ran in atomic context, including all OA report
forwarding, which wasn’t really necessary in our case and seems to make
our locking requirements somewhat complex as we handled the interaction
with the rest of the i915 driver.</p>
</li>
</ul>
</section>
</section>
<section id="i915-driver-entry-points">
<h3>i915 Driver Entry Points<a class="headerlink" href="#i915-driver-entry-points" title="Link to this heading">¶</a></h3>
<p>This section covers the entrypoints exported outside of i915_perf.c to
integrate with drm/i915 and to handle the <cite>DRM_I915_PERF_OPEN</cite> ioctl.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_init">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>initialize i915-perf state on module bind</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Initializes i915-perf state without exposing anything to userspace.</p>
<p><strong>Note</strong></p>
<p>i915-perf initialization is split into an ‘init’ and ‘register’
phase with the <a class="reference internal" href="#c.i915_perf_register" title="i915_perf_register"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_register()</span></code></a> exposing state to userspace.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_fini">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_fini</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_fini" title="Link to this definition">¶</a><br /></dt>
<dd><p>Counter part to <a class="reference internal" href="#c.i915_perf_init" title="i915_perf_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_init()</span></code></a></p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_register">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_register</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_register" title="Link to this definition">¶</a><br /></dt>
<dd><p>exposes i915-perf to userspace</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>In particular OA metric sets are advertised under a sysfs metrics/
directory allowing userspace to enumerate valid IDs that can be
used to open an i915-perf stream.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_unregister">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_unregister</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_unregister" title="Link to this definition">¶</a><br /></dt>
<dd><p>hide i915-perf from userspace</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>i915 device instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>i915-perf state cleanup is split up into an ‘unregister’ and
‘deinit’ phase where the interface is first hidden from
userspace by <a class="reference internal" href="#c.i915_perf_unregister" title="i915_perf_unregister"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_unregister()</span></code></a> before cleaning up
remaining state in <a class="reference internal" href="#c.i915_perf_fini" title="i915_perf_fini"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_fini()</span></code></a>.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_open_ioctl">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_open_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_device" title="drm_device"><span class="n"><span class="pre">drm_device</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">data</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_open_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>DRM ioctl() for userspace to open a stream FD</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_device</span> <span class="pre">*dev</span></code></dt><dd><p>drm device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*data</span></code></dt><dd><p>ioctl data copied from userspace (unvalidated)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>drm file</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Validates the stream open parameters given by userspace including flags
and an array of u64 key, value pair properties.</p>
<p>Very little is assumed up front about the nature of the stream being
opened (for instance we don’t assume it’s for periodic OA unit metrics). An
i915-perf stream is expected to be a suitable interface for other forms of
buffered data written by the GPU besides periodic OA metrics.</p>
<p>Note we copy the properties from userspace outside of the i915 perf
mutex to avoid an awkward lockdep with mmap_lock.</p>
<p>Most of the implementation details are handled by
<a class="reference internal" href="#c.i915_perf_open_ioctl_locked" title="i915_perf_open_ioctl_locked"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_open_ioctl_locked()</span></code></a> after taking the <code class="xref c c-type docutils literal notranslate"><span class="pre">gt->perf</span></code>.lock
mutex for serializing with any non-file-operation driver hooks.</p>
<p><strong>Return</strong></p>
<p>A newly opened i915 Perf stream file descriptor or negative
error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_release">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_release</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_release" title="inode"><span class="n"><span class="pre">inode</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inode</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_release" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_release" title="Link to this definition">¶</a><br /></dt>
<dd><p>handles userspace close() of a stream file</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">inode</span> <span class="pre">*inode</span></code></dt><dd><p>anonymous inode associated with file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Cleans up any resources associated with an open i915 perf stream file.</p>
<p>NB: close() can’t really fail from the userspace point of view.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_add_config_ioctl">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_add_config_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_device" title="drm_device"><span class="n"><span class="pre">drm_device</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">data</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_add_config_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>DRM ioctl() for userspace to add a new OA config</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_device</span> <span class="pre">*dev</span></code></dt><dd><p>drm device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*data</span></code></dt><dd><p>ioctl data (pointer to <a class="reference internal" href="driver-uapi.html#c.drm_i915_perf_oa_config" title="drm_i915_perf_oa_config"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_perf_oa_config</span></code></a>) copied from
userspace (unvalidated)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>drm file</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Validates the submitted OA register to be saved into a new OA config that
can then be used for programming the OA unit and its NOA network.</p>
<p><strong>Return</strong></p>
<p>A new allocated config number to be used with the perf open ioctl
or a negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_remove_config_ioctl">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_remove_config_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_device" title="drm_device"><span class="n"><span class="pre">drm_device</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dev</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">data</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_remove_config_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>DRM ioctl() for userspace to remove an OA config</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_device</span> <span class="pre">*dev</span></code></dt><dd><p>drm device</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*data</span></code></dt><dd><p>ioctl data (pointer to u64 integer) copied from userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>drm file</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Configs can be removed while being used, the will stop appearing in sysfs
and their content will be freed when the stream using the config is closed.</p>
<p><strong>Return</strong></p>
<p>0 on success or a negative error code on failure.</p>
</div>
</section>
<section id="i915-perf-stream">
<h3>i915 Perf Stream<a class="headerlink" href="#i915-perf-stream" title="Link to this heading">¶</a></h3>
<p>This section covers the stream-semantics-agnostic structures and functions
for representing an i915 perf stream FD and associated file operations.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_perf_stream">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_stream</span></span></span><a class="headerlink" href="#c.i915_perf_stream" title="Link to this definition">¶</a><br /></dt>
<dd><p>state for a single open stream FD</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_perf_stream {
struct i915_perf *perf;
struct intel_uncore *uncore;
struct intel_engine_cs *engine;
struct mutex lock;
u32 sample_flags;
int sample_size;
struct i915_gem_context *ctx;
bool enabled;
bool hold_preemption;
const struct i915_perf_stream_ops *ops;
struct i915_oa_config *oa_config;
struct llist_head oa_config_bos;
struct intel_context *pinned_ctx;
u32 specific_ctx_id;
u32 specific_ctx_id_mask;
struct hrtimer poll_check_timer;
wait_queue_head_t poll_wq;
bool pollin;
bool periodic;
int period_exponent;
struct {
const struct i915_oa_format *format;
struct i915_vma *vma;
u8 *vaddr;
u32 last_ctx_id;
spinlock_t ptr_lock;
u32 head;
u32 tail;
} oa_buffer;
struct i915_vma *noa_wait;
u64 poll_oa_period;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">perf</span></code></dt><dd><p>i915_perf backpointer</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">uncore</span></code></dt><dd><p>mmio access path</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engine</span></code></dt><dd><p>Engine associated with this performance stream.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">lock</span></code></dt><dd><p>Lock associated with operations on stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sample_flags</span></code></dt><dd><p>Flags representing the <cite>DRM_I915_PERF_PROP_SAMPLE_*</cite>
properties given when opening a stream, representing the contents
of a single sample as read() by userspace.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sample_size</span></code></dt><dd><p>Considering the configured contents of a sample
combined with the required header size, this is the total size
of a single sample record.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ctx</span></code></dt><dd><p><code class="docutils literal notranslate"><span class="pre">NULL</span></code> if measuring system-wide across all contexts or a
specific context that is being monitored.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enabled</span></code></dt><dd><p>Whether the stream is currently enabled, considering
whether the stream was opened in a disabled state and based
on <cite>I915_PERF_IOCTL_ENABLE</cite> and <cite>I915_PERF_IOCTL_DISABLE</cite> calls.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hold_preemption</span></code></dt><dd><p>Whether preemption is put on hold for command
submissions done on the <strong>ctx</strong>. This is useful for some drivers that
cannot easily post process the OA buffer context to subtract delta
of performance counters not associated with <strong>ctx</strong>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ops</span></code></dt><dd><p>The callbacks providing the implementation of this specific
type of configured stream.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_config</span></code></dt><dd><p>The OA configuration used by the stream.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_config_bos</span></code></dt><dd><p>A list of <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_oa_config_bo</span></code> allocated lazily
each time <strong>oa_config</strong> changes.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pinned_ctx</span></code></dt><dd><p>The OA context specific information.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">specific_ctx_id</span></code></dt><dd><p>The id of the specific context.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">specific_ctx_id_mask</span></code></dt><dd><p>The mask used to masking specific_ctx_id bits.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_check_timer</span></code></dt><dd><p>High resolution timer that will periodically
check for data in the circular OA buffer for notifying userspace
(e.g. during a read() or poll()).</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_wq</span></code></dt><dd><p>The wait queue that hrtimer callback wakes when it
sees data ready to read in the circular OA buffer.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pollin</span></code></dt><dd><p>Whether there is data available to read.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">periodic</span></code></dt><dd><p>Whether periodic sampling is currently enabled.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">period_exponent</span></code></dt><dd><p>The OA unit sampling frequency is derived from this.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_buffer</span></code></dt><dd><p>State of the OA buffer.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_buffer.ptr_lock</span></code></dt><dd><p>Locks reads and writes to all
head/tail state</p>
<p>Consider: the head and tail pointer state needs to be read
consistently from a hrtimer callback (atomic context) and
read() fop (user context) with tail pointer updates happening
in atomic context and head updates in user context and the
(unlikely) possibility of read() errors needing to reset all
head/tail state.</p>
<p>Note: Contention/performance aren’t currently a significant
concern here considering the relatively low frequency of
hrtimer callbacks (5ms period) and that reads typically only
happen in response to a hrtimer event and likely complete
before the next callback.</p>
<p>Note: This lock is not held <em>while</em> reading and copying data
to userspace so the value of head observed in htrimer
callbacks won’t represent any partial consumption of data.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_buffer.head</span></code></dt><dd><p>Although we can always read back
the head pointer register,
we prefer to avoid trusting the HW state, just to avoid any
risk that some hardware condition could * somehow bump the
head pointer unpredictably and cause us to forward the wrong
OA buffer data to userspace.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_buffer.tail</span></code></dt><dd><p>The last verified tail that can be
read by userspace.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">noa_wait</span></code></dt><dd><p>A batch buffer doing a wait on the GPU for the NOA logic to be
reprogrammed.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_oa_period</span></code></dt><dd><p>The period in nanoseconds at which the OA
buffer should be checked for available data.</p>
</dd>
</dl>
</div>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_perf_stream_ops">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_stream_ops</span></span></span><a class="headerlink" href="#c.i915_perf_stream_ops" title="Link to this definition">¶</a><br /></dt>
<dd><p>the OPs to support a specific stream type</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_perf_stream_ops {
void (*enable)(struct i915_perf_stream *stream);
void (*disable)(struct i915_perf_stream *stream);
void (*poll_wait)(struct i915_perf_stream *stream, struct file *file, poll_table *wait);
int (*wait_unlocked)(struct i915_perf_stream *stream);
int (*read)(struct i915_perf_stream *stream, char __user *buf, size_t count, size_t *offset);
void (*destroy)(struct i915_perf_stream *stream);
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">enable</span></code></dt><dd><p>Enables the collection of HW samples, either in response to
<cite>I915_PERF_IOCTL_ENABLE</cite> or implicitly called when stream is opened
without <cite>I915_PERF_FLAG_DISABLED</cite>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">disable</span></code></dt><dd><p>Disables the collection of HW samples, either in response
to <cite>I915_PERF_IOCTL_DISABLE</cite> or implicitly called before destroying
the stream.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_wait</span></code></dt><dd><p>Call poll_wait, passing a wait queue that will be woken
once there is something ready to read() for the stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">wait_unlocked</span></code></dt><dd><p>For handling a blocking read, wait until there is
something to ready to read() for the stream. E.g. wait on the same
wait queue that would be passed to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">read</span></code></dt><dd><p>Copy buffered metrics as records to userspace
<strong>buf</strong>: the userspace, destination buffer
<strong>count</strong>: the number of bytes to copy, requested by userspace
<strong>offset</strong>: zero at the start of the read, updated as the read
proceeds, it represents how many bytes have been copied so far and
the buffer offset for copying the next record.</p>
<p>Copy as many buffered i915 perf samples and records for this stream
to userspace as will fit in the given buffer.</p>
<p>Only write complete records; returning -<code class="docutils literal notranslate"><span class="pre">ENOSPC</span></code> if there isn’t room
for a complete record.</p>
<p>Return any error condition that results in a short read such as
-<code class="docutils literal notranslate"><span class="pre">ENOSPC</span></code> or -<code class="docutils literal notranslate"><span class="pre">EFAULT</span></code>, even though these may be squashed before
returning to userspace.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">destroy</span></code></dt><dd><p>Cleanup any stream specific resources.</p>
<p>The stream will always be disabled before this is called.</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.read_properties_unlocked">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">read_properties_unlocked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_perf</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">perf</span></span>, <span class="n"><span class="pre">u64</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">uprops</span></span>, <span class="n"><span class="pre">u32</span></span><span class="w"> </span><span class="n"><span class="pre">n_props</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.perf_open_properties" title="perf_open_properties"><span class="n"><span class="pre">perf_open_properties</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">props</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.read_properties_unlocked" title="Link to this definition">¶</a><br /></dt>
<dd><p>validate + copy userspace stream open properties</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf</span> <span class="pre">*perf</span></code></dt><dd><p>i915 perf instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u64</span> <span class="pre">__user</span> <span class="pre">*uprops</span></code></dt><dd><p>The array of u64 key value pairs given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">u32</span> <span class="pre">n_props</span></code></dt><dd><p>The number of key value pairs expected in <strong>uprops</strong></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">perf_open_properties</span> <span class="pre">*props</span></code></dt><dd><p>The stream configuration built up while validating properties</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Note this function only validates properties in isolation it doesn’t
validate that the combination of properties makes sense or that all
properties necessary for a particular kind of stream have been set.</p>
<p>Note that there currently aren’t any ordering requirements for properties so
we shouldn’t validate or assume anything about ordering here. This doesn’t
rule out defining new properties with ordering requirements in the future.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_open_ioctl_locked">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_open_ioctl_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">i915_perf</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">perf</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_perf_open_param</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">param</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.perf_open_properties" title="perf_open_properties"><span class="n"><span class="pre">perf_open_properties</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">props</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="drm-internals.html#c.drm_file" title="drm_file"><span class="n"><span class="pre">drm_file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_open_ioctl_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>DRM ioctl() for userspace to open a stream FD</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf</span> <span class="pre">*perf</span></code></dt><dd><p>i915 perf instance</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_perf_open_param</span> <span class="pre">*param</span></code></dt><dd><p>The open parameters passed to ‘DRM_I915_PERF_OPEN`</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">perf_open_properties</span> <span class="pre">*props</span></code></dt><dd><p>individually validated u64 property value pairs</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_file</span> <span class="pre">*file</span></code></dt><dd><p>drm file</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>See <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_perf_ioctl_open()</span></code> for interface details.</p>
<p>Implements further stream config validation and stream initialization on
behalf of <a class="reference internal" href="#c.i915_perf_open_ioctl" title="i915_perf_open_ioctl"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_open_ioctl()</span></code></a> with the <code class="xref c c-type docutils literal notranslate"><span class="pre">gt->perf</span></code>.lock mutex
taken to serialize with any non-file-operation driver hooks.</p>
<p><strong>Note</strong></p>
<p>at this point the <strong>props</strong> have only been validated in isolation and
it’s still necessary to validate that the combination of properties makes
sense.</p>
<p>In the case where userspace is interested in OA unit metrics then further
config validation and stream initialization details will be handled by
<a class="reference internal" href="#c.i915_oa_stream_init" title="i915_oa_stream_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_oa_stream_init()</span></code></a>. The code here should only validate config state that
will be relevant to all stream types / backends.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_destroy_locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_destroy_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_destroy_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>destroy an i915 perf stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Frees all resources associated with the given i915 perf <strong>stream</strong>, disabling
any associated data capture in the process.</p>
<p><strong>Note</strong></p>
<p>The <code class="xref c c-type docutils literal notranslate"><span class="pre">gt->perf</span></code>.lock mutex has been taken to serialize
with any non-file-operation driver hooks.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_read">
<span class="n"><span class="pre">ssize_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_read</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_read" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">loff_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">ppos</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_read" title="Link to this definition">¶</a><br /></dt>
<dd><p>handles read() FOP for i915 perf stream FDs</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">loff_t</span> <span class="pre">*ppos</span></code></dt><dd><p>(inout) file seek position (unused)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>The entry point for handling a read() on a stream file descriptor from
userspace. Most of the work is left to the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">i915_perf_read_locked()</span></code> and
<a class="reference internal" href="#c.i915_perf_stream_ops" title="i915_perf_stream_ops"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_perf_stream_ops->read</span></code></a> but to save having stream implementations (of
which we might have multiple later) we handle blocking read here.</p>
<p>We can also consistently treat trying to read from a disabled stream
as an IO error so implementations can assume the stream is enabled
while reading.</p>
<p><strong>Return</strong></p>
<p>The number of bytes copied or a negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_ioctl">
<span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_ioctl</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_ioctl" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">cmd</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">arg</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_ioctl" title="Link to this definition">¶</a><br /></dt>
<dd><p>support ioctl() usage with i915 perf stream FDs</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">cmd</span></code></dt><dd><p>the ioctl request</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">arg</span></code></dt><dd><p>the ioctl data</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Implementation deferred to <a class="reference internal" href="#c.i915_perf_ioctl_locked" title="i915_perf_ioctl_locked"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_ioctl_locked()</span></code></a>.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code. Returns -EINVAL for
an unknown ioctl request.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_enable_locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_enable_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_enable_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle <cite>I915_PERF_IOCTL_ENABLE</cite> ioctl</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>A disabled i915 perf stream</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>[Re]enables the associated capture of data for this stream.</p>
<p>If a stream was previously enabled then there’s currently no intention
to provide userspace any guarantee about the preservation of previously
buffered data.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_disable_locked">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_disable_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_disable_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle <cite>I915_PERF_IOCTL_DISABLE</cite> ioctl</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An enabled i915 perf stream</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Disables the associated capture of data for this stream.</p>
<p>The intention is that disabling an re-enabling a stream will ideally be
cheaper than destroying and re-opening a stream with the same configuration,
though there are no formal guarantees about what state or buffered data
must be retained between disabling and re-enabling a stream.</p>
<p><strong>Note</strong></p>
<p>while a stream is disabled it’s considered an error for userspace
to attempt to read from the stream (-EIO).</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_poll">
<span class="n"><span class="pre">__poll_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_poll</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_poll" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span>, <span class="n"><span class="pre">poll_table</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">wait</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_poll" title="Link to this definition">¶</a><br /></dt>
<dd><p>call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code> with a suitable wait queue for stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_table</span> <span class="pre">*wait</span></code></dt><dd><p>poll() state table</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>For handling userspace polling on an i915 perf stream, this ensures
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code> gets called with a wait queue that will be woken for new stream
data.</p>
<p><strong>Note</strong></p>
<p>Implementation deferred to <a class="reference internal" href="#c.i915_perf_poll_locked" title="i915_perf_poll_locked"><code class="xref c c-func docutils literal notranslate"><span class="pre">i915_perf_poll_locked()</span></code></a></p>
<p><strong>Return</strong></p>
<p>any poll events that are ready without sleeping</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_poll_locked">
<span class="n"><span class="pre">__poll_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_poll_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_poll_locked" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span>, <span class="n"><span class="pre">poll_table</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">wait</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_poll_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code> with a suitable wait queue for stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_table</span> <span class="pre">*wait</span></code></dt><dd><p>poll() state table</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>For handling userspace polling on an i915 perf stream, this calls through to
<a class="reference internal" href="#c.i915_perf_stream_ops" title="i915_perf_stream_ops"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_perf_stream_ops->poll_wait</span></code></a> to call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code> with a wait queue that
will be woken for new stream data.</p>
<p><strong>Return</strong></p>
<p>any poll events that are ready without sleeping</p>
</div>
</section>
<section id="i915-perf-observation-architecture-stream">
<h3>i915 Perf Observation Architecture Stream<a class="headerlink" href="#i915-perf-observation-architecture-stream" title="Link to this heading">¶</a></h3>
<dl class="c struct">
<dt class="sig sig-object c" id="c.i915_oa_ops">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_ops</span></span></span><a class="headerlink" href="#c.i915_oa_ops" title="Link to this definition">¶</a><br /></dt>
<dd><p>Gen specific implementation of an OA unit stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct i915_oa_ops {
bool (*is_valid_b_counter_reg)(struct i915_perf *perf, u32 addr);
bool (*is_valid_mux_reg)(struct i915_perf *perf, u32 addr);
bool (*is_valid_flex_reg)(struct i915_perf *perf, u32 addr);
int (*enable_metric_set)(struct i915_perf_stream *stream, struct i915_active *active);
void (*disable_metric_set)(struct i915_perf_stream *stream);
void (*oa_enable)(struct i915_perf_stream *stream);
void (*oa_disable)(struct i915_perf_stream *stream);
int (*read)(struct i915_perf_stream *stream, char __user *buf, size_t count, size_t *offset);
u32 (*oa_hw_tail_read)(struct i915_perf_stream *stream);
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">is_valid_b_counter_reg</span></code></dt><dd><p>Validates register’s address for
programming boolean counters for a particular platform.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">is_valid_mux_reg</span></code></dt><dd><p>Validates register’s address for programming mux
for a particular platform.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">is_valid_flex_reg</span></code></dt><dd><p>Validates register’s address for programming
flex EU filtering for a particular platform.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enable_metric_set</span></code></dt><dd><p>Selects and applies any MUX configuration to set
up the Boolean and Custom (B/C) counters that are part of the
counter reports being sampled. May apply system constraints such as
disabling EU clock gating as required.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">disable_metric_set</span></code></dt><dd><p>Remove system constraints associated with using
the OA unit.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_enable</span></code></dt><dd><p>Enable periodic sampling</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_disable</span></code></dt><dd><p>Disable periodic sampling</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">read</span></code></dt><dd><p>Copy data from the circular OA buffer into a given userspace
buffer.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_hw_tail_read</span></code></dt><dd><p>read the OA tail pointer register</p>
<p>In particular this enables us to share all the fiddly code for
handling the OA unit tail pointer race that affects multiple
generations.</p>
</dd>
</dl>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_stream_init">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_stream_init</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_perf_open_param</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">param</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.perf_open_properties" title="perf_open_properties"><span class="n"><span class="pre">perf_open_properties</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">props</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_stream_init" title="Link to this definition">¶</a><br /></dt>
<dd><p>validate combined props for OA stream and init</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_perf_open_param</span> <span class="pre">*param</span></code></dt><dd><p>The open parameters passed to <cite>DRM_I915_PERF_OPEN</cite></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">perf_open_properties</span> <span class="pre">*props</span></code></dt><dd><p>The property state that configures stream (individually validated)</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>While <a class="reference internal" href="#c.read_properties_unlocked" title="read_properties_unlocked"><code class="xref c c-func docutils literal notranslate"><span class="pre">read_properties_unlocked()</span></code></a> validates properties in isolation it
doesn’t ensure that the combination necessarily makes sense.</p>
<p>At this point it has been determined that userspace wants a stream of
OA metrics, but still we need to further validate the combined
properties are OK.</p>
<p>If the configuration makes sense then we can allocate memory for
a circular OA buffer and apply the requested metric set configuration.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_read">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_read</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_read" title="Link to this definition">¶</a><br /></dt>
<dd><p>just calls through to <a class="reference internal" href="#c.i915_oa_ops" title="i915_oa_ops"><code class="xref c c-type docutils literal notranslate"><span class="pre">i915_oa_ops->read</span></code></a></p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Updates <strong>offset</strong> according to the number of bytes successfully copied into
the userspace buffer.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_stream_enable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_stream_enable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_stream_enable" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle <cite>I915_PERF_IOCTL_ENABLE</cite> for OA stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream opened for OA metrics</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>[Re]enables hardware periodic sampling according to the period configured
when opening the stream. This also starts a hrtimer that will periodically
check for data in the circular OA buffer for notifying userspace (e.g.
during a read() or poll()).</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_stream_disable">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_stream_disable</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_stream_disable" title="Link to this definition">¶</a><br /></dt>
<dd><p>handle <cite>I915_PERF_IOCTL_DISABLE</cite> for OA stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream opened for OA metrics</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Stops the OA unit from periodically writing counter reports into the
circular OA buffer. This also stops the hrtimer that periodically checks for
data in the circular OA buffer, for notifying userspace.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_wait_unlocked">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_wait_unlocked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_wait_unlocked" title="Link to this definition">¶</a><br /></dt>
<dd><p>handles blocking IO until OA data available</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Called when userspace tries to read() from a blocking stream FD opened
for OA metrics. It waits until the hrtimer callback finds a non-empty
OA buffer and wakes us.</p>
<p><strong>Note</strong></p>
<p>it’s acceptable to have this return with some false positives
since any subsequent read handling will return -EAGAIN if there isn’t
really data ready for userspace yet.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_oa_poll_wait">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_oa_poll_wait</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_oa_poll_wait" title="file"><span class="n"><span class="pre">file</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">file</span></span>, <span class="n"><span class="pre">poll_table</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">wait</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_oa_poll_wait" title="Link to this definition">¶</a><br /></dt>
<dd><p>call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">poll_wait()</span></code> for an OA stream poll()</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">file</span> <span class="pre">*file</span></code></dt><dd><p>An i915 perf stream file</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_table</span> <span class="pre">*wait</span></code></dt><dd><p>poll() state table</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>For handling userspace polling on an i915 perf stream opened for OA metrics,
this starts a poll_wait with the wait queue that our hrtimer callback wakes
when it sees data ready to read in the circular OA buffer.</p>
</div>
</section>
<section id="other-i915-perf-internals">
<h3>Other i915 Perf Internals<a class="headerlink" href="#other-i915-perf-internals" title="Link to this heading">¶</a></h3>
<p>This section simply includes all other currently documented i915 perf internals,
in no particular order, but may include some more minor utilities or platform
specific details than found in the more high-level sections.</p>
<dl class="c struct">
<dt class="sig sig-object c" id="c.perf_open_properties">
<span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">perf_open_properties</span></span></span><a class="headerlink" href="#c.perf_open_properties" title="Link to this definition">¶</a><br /></dt>
<dd><p>for validated properties given to open a stream</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Definition</strong>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct perf_open_properties {
u32 sample_flags;
u64 single_context:1;
u64 hold_preemption:1;
u64 ctx_handle;
int metrics_set;
int oa_format;
bool oa_periodic;
int oa_period_exponent;
struct intel_engine_cs *engine;
bool has_sseu;
struct intel_sseu sseu;
u64 poll_oa_period;
};
</pre></div>
</div>
<p><strong>Members</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">sample_flags</span></code></dt><dd><p><cite>DRM_I915_PERF_PROP_SAMPLE_*</cite> properties are tracked as flags</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">single_context</span></code></dt><dd><p>Whether a single or all gpu contexts should be monitored</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">hold_preemption</span></code></dt><dd><p>Whether the preemption is disabled for the filtered
context</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ctx_handle</span></code></dt><dd><p>A gem ctx handle for use with <strong>single_context</strong></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">metrics_set</span></code></dt><dd><p>An ID for an OA unit metric set advertised via sysfs</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_format</span></code></dt><dd><p>An OA unit HW report format</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_periodic</span></code></dt><dd><p>Whether to enable periodic OA unit sampling</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">oa_period_exponent</span></code></dt><dd><p>The OA unit sampling period is derived from this</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">engine</span></code></dt><dd><p>The engine (typically rcs0) being monitored by the OA unit</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">has_sseu</span></code></dt><dd><p>Whether <strong>sseu</strong> was specified by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">sseu</span></code></dt><dd><p>internal SSEU configuration computed either from the userspace
specified configuration in the opening parameters or a default value
(see <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">get_default_sseu_config()</span></code>)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">poll_oa_period</span></code></dt><dd><p>The period in nanoseconds at which the CPU will check for OA
data availability</p>
</dd>
</dl>
</div>
<p><strong>Description</strong></p>
<p>As <a class="reference internal" href="#c.read_properties_unlocked" title="read_properties_unlocked"><code class="xref c c-func docutils literal notranslate"><span class="pre">read_properties_unlocked()</span></code></a> enumerates and validates the properties given
to open a stream of metrics the configuration is built up in the structure
which starts out zero initialized.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.oa_buffer_check_unlocked">
<span class="kt"><span class="pre">bool</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">oa_buffer_check_unlocked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.oa_buffer_check_unlocked" title="Link to this definition">¶</a><br /></dt>
<dd><p>check for data and update tail ptr state</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>i915 stream instance</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This is either called via fops (for blocking reads in user ctx) or the poll
check hrtimer (atomic ctx) to check the OA buffer tail pointer and check
if there is data available for userspace to read.</p>
<p>This function is central to providing a workaround for the OA unit tail
pointer having a race with respect to what data is visible to the CPU.
It is responsible for reading tail pointers from the hardware and giving
the pointers time to ‘age’ before they are made available for reading.
(See description of OA_TAIL_MARGIN_NSEC above for further details.)</p>
<p>Besides returning true when there is data available to read() this function
also updates the tail in the oa_buffer object.</p>
<p><strong>Note</strong></p>
<p>It’s safe to read OA config state here unlocked, assuming that this is
only called while the stream is enabled, while the global OA configuration
can’t be modified.</p>
<p><strong>Return</strong></p>
<p><code class="docutils literal notranslate"><span class="pre">true</span></code> if the OA buffer contains data, else <code class="docutils literal notranslate"><span class="pre">false</span></code></p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.append_oa_status">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">append_oa_status</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span>, <span class="k"><span class="pre">enum</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_perf_record_type</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.append_oa_status" title="Link to this definition">¶</a><br /></dt>
<dd><p>Appends a status record to a userspace read() buffer.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">drm_i915_perf_record_type</span> <span class="pre">type</span></code></dt><dd><p>The kind of status to report to userspace</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Writes a status record (such as <cite>DRM_I915_PERF_RECORD_OA_REPORT_LOST</cite>)
into the userspace read() buffer.</p>
<p>The <strong>buf</strong> <strong>offset</strong> will only be updated on success.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.append_oa_sample">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">append_oa_sample</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="n"><span class="pre">u8</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">report</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.append_oa_sample" title="Link to this definition">¶</a><br /></dt>
<dd><p>Copies single OA report into userspace read() buffer.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">u8</span> <span class="pre">*report</span></code></dt><dd><p>A single OA report to (optionally) include as part of the sample</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>The contents of a sample are configured through <cite>DRM_I915_PERF_PROP_SAMPLE_*</cite>
properties when opening a stream, tracked as <cite>stream->sample_flags</cite>. This
function copies the requested components of a single sample to the given
read() <strong>buf</strong>.</p>
<p>The <strong>buf</strong> <strong>offset</strong> will only be updated on success.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.gen8_append_oa_reports">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">gen8_append_oa_reports</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.gen8_append_oa_reports" title="Link to this definition">¶</a><br /></dt>
<dd><p>Copies all buffered OA reports into userspace read() buffer.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Notably any error condition resulting in a short read (-<code class="docutils literal notranslate"><span class="pre">ENOSPC</span></code> or
-<code class="docutils literal notranslate"><span class="pre">EFAULT</span></code>) will be returned even though one or more records may
have been successfully copied. In this case it’s up to the caller
to decide if the error should be squashed before returning to
userspace.</p>
<p><strong>Note</strong></p>
<p>reports are consumed from the head, and appended to the
tail, so the tail chases the head?... If you think that’s mad
and back-to-front you’re not alone, but this follows the
Gen PRM naming convention.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.gen8_oa_read">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">gen8_oa_read</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.gen8_oa_read" title="Link to this definition">¶</a><br /></dt>
<dd><p>copy status records then buffered OA reports</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Checks OA unit status registers and if necessary appends corresponding
status records for userspace (such as for a buffer full condition) and then
initiate appending any buffered OA reports.</p>
<p>Updates <strong>offset</strong> according to the number of bytes successfully copied into
the userspace buffer.</p>
<p>NB: some data may be successfully copied to the userspace buffer
even if an error is returned, and this is reflected in the
updated <strong>offset</strong>.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.gen7_append_oa_reports">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">gen7_append_oa_reports</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.gen7_append_oa_reports" title="Link to this definition">¶</a><br /></dt>
<dd><p>Copies all buffered OA reports into userspace read() buffer.</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Notably any error condition resulting in a short read (-<code class="docutils literal notranslate"><span class="pre">ENOSPC</span></code> or
-<code class="docutils literal notranslate"><span class="pre">EFAULT</span></code>) will be returned even though one or more records may
have been successfully copied. In this case it’s up to the caller
to decide if the error should be squashed before returning to
userspace.</p>
<p><strong>Note</strong></p>
<p>reports are consumed from the head, and appended to the
tail, so the tail chases the head?... If you think that’s mad
and back-to-front you’re not alone, but this follows the
Gen PRM naming convention.</p>
<p><strong>Return</strong></p>
<p>0 on success, negative error code on failure.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.gen7_oa_read">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">gen7_oa_read</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="pre">__user</span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">buf</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">count</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">offset</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.gen7_oa_read" title="Link to this definition">¶</a><br /></dt>
<dd><p>copy status records then buffered OA reports</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">__user</span> <span class="pre">*buf</span></code></dt><dd><p>destination buffer given by userspace</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">count</span></code></dt><dd><p>the number of bytes userspace wants to read</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">size_t</span> <span class="pre">*offset</span></code></dt><dd><p>(inout): the current position for writing into <strong>buf</strong></p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Checks Gen 7 specific OA unit status registers and if necessary appends
corresponding status records for userspace (such as for a buffer full
condition) and then initiate appending any buffered OA reports.</p>
<p>Updates <strong>offset</strong> according to the number of bytes successfully copied into
the userspace buffer.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.oa_get_render_ctx_id">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">oa_get_render_ctx_id</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.oa_get_render_ctx_id" title="Link to this definition">¶</a><br /></dt>
<dd><p>determine and hold ctx hw id</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Determine the render context hw id, and ensure it remains fixed for the
lifetime of the stream. This ensures that we don’t have to worry about
updating the context ID in OACONTROL on the fly.</p>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.oa_put_render_ctx_id">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">oa_put_render_ctx_id</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.oa_put_render_ctx_id" title="Link to this definition">¶</a><br /></dt>
<dd><p>counterpart to oa_get_render_ctx_id releases hold</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915-perf stream opened for OA metrics</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>In case anything needed doing to ensure the context HW ID would remain valid
for the lifetime of the stream, then that can be undone here.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_ioctl_locked">
<span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_ioctl_locked</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><a class="reference internal" href="#c.i915_perf_stream" title="i915_perf_stream"><span class="n"><span class="pre">i915_perf_stream</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">stream</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">cmd</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">arg</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_ioctl_locked" title="Link to this definition">¶</a><br /></dt>
<dd><p>support ioctl() usage with i915 perf stream FDs</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">i915_perf_stream</span> <span class="pre">*stream</span></code></dt><dd><p>An i915 perf stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">int</span> <span class="pre">cmd</span></code></dt><dd><p>the ioctl request</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">arg</span></code></dt><dd><p>the ioctl data</p>
</dd>
</dl>
<p><strong>Return</strong></p>
<p>zero on success or a negative error code. Returns -EINVAL for
an unknown ioctl request.</p>
</div>
<dl class="c function">
<dt class="sig sig-object c" id="c.i915_perf_ioctl_version">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">i915_perf_ioctl_version</span></span></span><span class="sig-paren">(</span><span class="k"><span class="pre">struct</span></span><span class="w"> </span><span class="n"><span class="pre">drm_i915_private</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">i915</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.i915_perf_ioctl_version" title="Link to this definition">¶</a><br /></dt>
<dd><p>Version of the i915-perf subsystem</p>
</dd></dl>
<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">drm_i915_private</span> <span class="pre">*i915</span></code></dt><dd><p>The i915 device</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>This version number is used by userspace to detect available features.</p>
</div>
</section>
</section>
<section id="style">
<h2>Style<a class="headerlink" href="#style" title="Link to this heading">¶</a></h2>
<p>The drm/i915 driver codebase has some style rules in addition to (and, in some
cases, deviating from) the kernel coding style.</p>
<section id="register-macro-definition-style">
<h3>Register macro definition style<a class="headerlink" href="#register-macro-definition-style" title="Link to this heading">¶</a></h3>
<p>The style guide for <code class="docutils literal notranslate"><span class="pre">i915_reg.h</span></code>.</p>
<p>Follow the style described here for new macros, and while changing existing
macros. Do <strong>not</strong> mass change existing definitions just to update the style.</p>
<section id="file-layout">
<h4>File Layout<a class="headerlink" href="#file-layout" title="Link to this heading">¶</a></h4>
<p>Keep helper macros near the top. For example, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_PIPE()</span></code> and friends.</p>
<p>Prefix macros that generally should not be used outside of this file with
underscore ‘_’. For example, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">_PIPE()</span></code> and friends, single instances of
registers that are defined solely for the use by function-like macros.</p>
<p>Avoid using the underscore prefixed macros outside of this file. There are
exceptions, but keep them to a minimum.</p>
<p>There are two basic types of register definitions: Single registers and
register groups. Register groups are registers which have two or more
instances, for example one per pipe, port, transcoder, etc. Register groups
should be defined using function-like macros.</p>
<p>For single registers, define the register offset first, followed by register
contents.</p>
<p>For register groups, define the register instance offsets first, prefixed
with underscore, followed by a function-like macro choosing the right
instance based on the parameter, followed by register contents.</p>
<p>Define the register contents (i.e. bit and bit field macros) from most
significant to least significant bit. Indent the register content macros
using two extra spaces between <code class="docutils literal notranslate"><span class="pre">#define</span></code> and the macro name.</p>
<p>Define bit fields using <code class="docutils literal notranslate"><span class="pre">REG_GENMASK(h,</span> <span class="pre">l)</span></code>. Define bit field contents
using <code class="docutils literal notranslate"><span class="pre">REG_FIELD_PREP(mask,</span> <span class="pre">value)</span></code>. This will define the values already
shifted in place, so they can be directly OR’d together. For convenience,
function-like macros may be used to define bit fields, but do note that the
macros may be needed to read as well as write the register contents.</p>
<p>Define bits using <code class="docutils literal notranslate"><span class="pre">REG_BIT(N)</span></code>. Do <strong>not</strong> add <code class="docutils literal notranslate"><span class="pre">_BIT</span></code> suffix to the name.</p>
<p>Group the register and its contents together without blank lines, separate
from other registers and their contents with one blank line.</p>
<p>Indent macro values from macro names using TABs. Align values vertically. Use
braces in macro values as needed to avoid unintended precedence after macro
substitution. Use spaces in macro values according to kernel coding
style. Use lower case in hexadecimal values.</p>
</section>
<section id="naming">
<h4>Naming<a class="headerlink" href="#naming" title="Link to this heading">¶</a></h4>
<p>Try to name registers according to the specs. If the register name changes in
the specs from platform to another, stick to the original name.</p>
<p>Try to reuse existing register macro definitions. Only add new macros for
new register offsets, or when the register contents have changed enough to
warrant a full redefinition.</p>
<p>When a register macro changes for a new platform, prefix the new macro using
the platform acronym or generation. For example, <code class="docutils literal notranslate"><span class="pre">SKL_</span></code> or <code class="docutils literal notranslate"><span class="pre">GEN8_</span></code>. The
prefix signifies the start platform/generation using the register.</p>
<p>When a bit (field) macro changes or gets added for a new platform, while
retaining the existing register macro, add a platform acronym or generation
suffix to the name. For example, <code class="docutils literal notranslate"><span class="pre">_SKL</span></code> or <code class="docutils literal notranslate"><span class="pre">_GEN8</span></code>.</p>
</section>
<section id="examples">
<h4>Examples<a class="headerlink" href="#examples" title="Link to this heading">¶</a></h4>
<p>(Note that the values in the example are indented using spaces instead of
TABs to avoid misalignment in generated documentation. Use TABs in the
definitions.):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#define _FOO_A 0xf000
#define _FOO_B 0xf001
#define FOO(pipe) _MMIO_PIPE(pipe, _FOO_A, _FOO_B)
#define FOO_ENABLE REG_BIT(31)
#define FOO_MODE_MASK REG_GENMASK(19, 16)
#define FOO_MODE_BAR REG_FIELD_PREP(FOO_MODE_MASK, 0)
#define FOO_MODE_BAZ REG_FIELD_PREP(FOO_MODE_MASK, 1)
#define FOO_MODE_QUX_SNB REG_FIELD_PREP(FOO_MODE_MASK, 2)
#define BAR _MMIO(0xb000)
#define GEN8_BAR _MMIO(0xb888)
</pre></div>
</div>
</section>
</section>
</section>
<section id="i915-drm-client-usage-stats-implementation">
<span id="i915-usage-stats"></span><h2>i915 DRM client usage stats implementation<a class="headerlink" href="#i915-drm-client-usage-stats-implementation" title="Link to this heading">¶</a></h2>
<p>The drm/i915 driver implements the DRM client usage stats specification as
documented in <a class="reference internal" href="drm-usage-stats.html#drm-client-usage-stats"><span class="std std-ref">DRM client usage stats</span></a>.</p>
<p>Example of the output showing the implemented key value pairs and entirety of
the currently possible format options:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pos: 0
flags: 0100002
mnt_id: 21
drm-driver: i915
drm-pdev: 0000:00:02.0
drm-client-id: 7
drm-engine-render: 9288864723 ns
drm-engine-copy: 2035071108 ns
drm-engine-video: 0 ns
drm-engine-capacity-video: 2
drm-engine-video-enhance: 0 ns
</pre></div>
</div>
<p>Possible <cite>drm-engine-</cite> key names are: <cite>render</cite>, <cite>copy</cite>, <cite>video</cite> and
<cite>video-enhance</cite>.</p>
</section>
</section>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
©The kernel development community.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
& <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/gpu/i915.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>