code:
===========================
 drm/i915 Intel GFX Driver
===========================

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.

Core Driver Infrastructure
==========================

This section covers core driver infrastructure used by both the display
and the GEM parts of the driver.

Runtime Power Management
------------------------

.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c
   :doc: runtime pm

.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/intel_uncore.c
   :internal:

Interrupt Handling
------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
   :doc: interrupt handling

.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
   :functions: intel_irq_init intel_irq_init_hw intel_hpd_init

.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
   :functions: intel_runtime_pm_disable_interrupts

.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
   :functions: intel_runtime_pm_enable_interrupts

Intel GVT-g Guest Support(vGPU)
-------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c
   :doc: Intel GVT-g guest support

.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c
   :internal:

Intel GVT-g Host Support(vGPU device model)
-------------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
   :doc: Intel GVT-g host support

.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
   :internal:

Workarounds
-----------

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_workarounds.c
   :doc: Hardware workarounds

Display Hardware Handling
=========================

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.

Mode Setting Infrastructure
---------------------------

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.

Frontbuffer Tracking
--------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.c
   :doc: frontbuffer tracking

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.h
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.c
   :internal:

Display FIFO Underrun Reporting
-------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_fifo_underrun.c
   :doc: fifo underrun handling

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_fifo_underrun.c
   :internal:

Plane Configuration
-------------------

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.

Atomic Plane Helpers
--------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c
   :doc: atomic plane helpers

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c
   :internal:

Asynchronous Page Flip
----------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_display.c
   :doc: asynchronous flip implementation

Output Probing
--------------

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.

Hotplug
-------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_hotplug.c
   :doc: Hotplug

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_hotplug.c
   :internal:

High Definition Audio
---------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_audio.c
   :doc: High Definition Audio over HDMI and Display Port

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_audio.c
   :internal:

.. kernel-doc:: include/drm/i915_component.h
   :internal:

Intel HDMI LPE Audio Support
----------------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_lpe_audio.c
   :doc: LPE Audio integration for HDMI or DP playback

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_lpe_audio.c
   :internal:

Panel Self Refresh PSR (PSR/SRD)
--------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_psr.c
   :doc: Panel Self Refresh (PSR/SRD)

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_psr.c
   :internal:

Frame Buffer Compression (FBC)
------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_fbc.c
   :doc: Frame Buffer Compression (FBC)

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_fbc.c
   :internal:

Display Refresh Rate Switching (DRRS)
-------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
   :doc: Display Refresh Rate Switching (DRRS)

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
   :internal:

DPIO
----

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dpio_phy.c
   :doc: DPIO

DMC Firmware Support
--------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc.c
   :doc: DMC Firmware Support

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc.c
   :internal:

Video BIOS Table (VBT)
----------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_bios.c
   :doc: Video BIOS Table (VBT)

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_bios.c
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_vbt_defs.h
   :internal:

Display clocks
--------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_cdclk.c
   :doc: CDCLK / RAWCLK

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_cdclk.c
   :internal:

Display PLLs
------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dpll_mgr.c
   :doc: Display PLLs

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dpll_mgr.c
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dpll_mgr.h
   :internal:

Display State Buffer
--------------------

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dsb.c
   :doc: DSB

.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dsb.c
   :internal:

GT Programming
==============

Multicast/Replicated (MCR) Registers
------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_gt_mcr.c
   :doc: GT Multicast/Replicated (MCR) Register Support

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_gt_mcr.c
   :internal:

Memory Management and Command Submission
========================================

This sections covers all things related to the GEM implementation in the
i915 driver.

Intel GPU Basics
----------------

An Intel GPU has multiple engines. There are several engine types.

- RCS engine is for rendering 3D and performing compute, this is named
  `I915_EXEC_RENDER` in user space.
- BCS is a blitting (copy) engine, this is named `I915_EXEC_BLT` in user
  space.
- VCS is a video encode and decode engine, this is named `I915_EXEC_BSD`
  in user space
- VECS is video enhancement engine, this is named `I915_EXEC_VEBOX` in user
  space.
- The enumeration `I915_EXEC_DEFAULT` does not refer to specific engine;
  instead it is to be used by user space to specify a default rendering
  engine (for 3D) that may or may not be the same as RCS.

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 `DRM_IOCTL_I915_GEM_EXECBUFFER2`
or `DRM_IOCTL_I915_GEM_EXECBUFFER2_WR`. 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
`DRM_IOCTL_I915_GEM_CREATE`). 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
`GEM BO Management Implementation Details`_.

The i915 driver allows user space to create a context via the ioctl
`DRM_IOCTL_I915_GEM_CONTEXT_CREATE` 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 atleast) 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 atleast) 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.

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.

Locking Guidelines
------------------

.. note::
   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.

#. All locking rules and interface contracts with cross-driver interfaces
   (dma-buf, dma_fence) need to be followed.

#. No struct_mutex anywhere in the code

#. 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

#. While holding lru/memory manager (buddy, drm_mm, whatever) locks
   system memory allocations are not allowed

	* Enforce this by priming lockdep (with fs_reclaim). If we
	  allocate memory while holding these looks we get a rehash
	  of the shrinker vs. struct_mutex saga, and that would be
	  real bad.

#. 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.

#. The suggestion for lru/memory managers locks is that they are small
   enough to be spinlocks.

#. All features need to come with exhaustive kernel selftests and/or
   IGT tests when appropriate

#. All LMEM uAPI paths need to be fully restartable (_interruptible()
   for all locks/waits/sleeps)

	* 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.

	* -EDEADLK handling with ww_mutex

GEM BO Management Implementation Details
----------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_vma_types.h
   :doc: Virtual Memory Address

Buffer Object Eviction
----------------------

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.

.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c
   :internal:

Buffer Object Memory Shrinking
------------------------------

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.

.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
   :internal:

Batchbuffer Parsing
-------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c
   :doc: batch buffer command parser

.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c
   :internal:

User Batchbuffer Execution
--------------------------

.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_context_types.h

.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
   :doc: User command execution

Scheduling
----------
.. kernel-doc:: drivers/gpu/drm/i915/i915_scheduler_types.h
   :functions: i915_sched_engine

Logical Rings, Logical Ring Contexts and Execlists
--------------------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_execlists_submission.c
   :doc: Logical Rings, Logical Ring Contexts and Execlists

Global GTT views
----------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_vma_types.h
   :doc: Global GTT views

.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c
   :internal:

GTT Fences and Swizzling
------------------------

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
   :internal:

Global GTT Fence Handling
~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
   :doc: fence register handling

Hardware Tiling and Swizzling Details
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
   :doc: tiling swizzling details

Object Tiling IOCTLs
--------------------

.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_tiling.c
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_tiling.c
   :doc: buffer object tiling

Protected Objects
-----------------

.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp.c
   :doc: PXP

.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp_types.h

Microcontrollers
================

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.

WOPCM
-----

WOPCM Layout
~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_wopcm.c
   :doc: WOPCM Layout

GuC
---

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
   :doc: GuC

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.h

GuC Firmware Layout
~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
   :doc: Firmware Layout

GuC Memory Management
~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
   :doc: GuC Memory Management
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
   :functions: intel_guc_allocate_vma

GuC-specific firmware loader
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
   :internal:

GuC-based command submission
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
   :doc: GuC-based command submission

GuC ABI
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h

HuC
---
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_huc.c
   :doc: HuC
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_huc.c
   :functions: intel_huc_auth

HuC Memory Management
~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_huc.c
   :doc: HuC Memory Management

HuC Firmware Layout
~~~~~~~~~~~~~~~~~~~
The HuC FW layout is the same as the GuC one, see `GuC Firmware Layout`_

DMC
---
See `DMC Firmware Support`_

Tracing
=======

This sections covers all things related to the tracepoints implemented
in the i915 driver.

i915_ppgtt_create and i915_ppgtt_release
----------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h
   :doc: i915_ppgtt_create and i915_ppgtt_release tracepoints

i915_context_create and i915_context_free
-----------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h
   :doc: i915_context_create and i915_context_free tracepoints

Perf
====

Overview
--------
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :doc: i915 Perf Overview

Comparison with Core Perf
-------------------------
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :doc: i915 Perf History and Comparison with Core Perf

i915 Driver Entry Points
------------------------

This section covers the entrypoints exported outside of i915_perf.c to
integrate with drm/i915 and to handle the `DRM_I915_PERF_OPEN` ioctl.

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_init
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_fini
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_register
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_unregister
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_open_ioctl
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_release
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_add_config_ioctl
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_remove_config_ioctl

i915 Perf Stream
----------------

This section covers the stream-semantics-agnostic structures and functions
for representing an i915 perf stream FD and associated file operations.

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf_types.h
   :functions: i915_perf_stream
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf_types.h
   :functions: i915_perf_stream_ops

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: read_properties_unlocked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_open_ioctl_locked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_destroy_locked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_read
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_ioctl
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_enable_locked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_disable_locked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_poll
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_perf_poll_locked

i915 Perf Observation Architecture Stream
-----------------------------------------

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf_types.h
   :functions: i915_oa_ops

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_stream_init
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_read
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_stream_enable
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_stream_disable
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_wait_unlocked
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :functions: i915_oa_poll_wait

Other i915 Perf Internals
-------------------------

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.

.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
   :internal:
   :no-identifiers:
       i915_perf_init
       i915_perf_fini
       i915_perf_register
       i915_perf_unregister
       i915_perf_open_ioctl
       i915_perf_release
       i915_perf_add_config_ioctl
       i915_perf_remove_config_ioctl
       read_properties_unlocked
       i915_perf_open_ioctl_locked
       i915_perf_destroy_locked
       i915_perf_read i915_perf_ioctl
       i915_perf_enable_locked
       i915_perf_disable_locked
       i915_perf_poll i915_perf_poll_locked
       i915_oa_stream_init i915_oa_read
       i915_oa_stream_enable
       i915_oa_stream_disable
       i915_oa_wait_unlocked
       i915_oa_poll_wait

Style
=====

The drm/i915 driver codebase has some style rules in addition to (and, in some
cases, deviating from) the kernel coding style.

Register macro definition style
-------------------------------

The style guide for ``i915_reg.h``.

.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h
   :doc: The i915 register macro definition style guide

.. _i915-usage-stats:

i915 DRM client usage stats implementation
==========================================

The drm/i915 driver implements the DRM client usage stats specification as
documented in :ref:`drm-client-usage-stats`.

Example of the output showing the implemented key value pairs and entirety of
the currently possible format options:

::

      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

Possible `drm-engine-` key names are: `render`, `copy`, `video` and
`video-enhance`.


code:
==================================
Linux GPU Driver Developer's Guide
==================================

.. toctree::

   introduction
   drm-internals
   drm-mm
   drm-kms
   drm-kms-helpers
   drm-uapi
   drm-usage-stats
   driver-uapi
   drm-client
   drivers
   backlight
   vga-switcheroo
   vgaarbiter
   todo
   rfc/index

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`

repo_name: angery/linux


code:
============
Introduction
============

The Linux DRM layer contains code intended to support the needs of
complex graphics devices, usually containing programmable pipelines well
suited to 3D graphics acceleration. Graphics drivers in the kernel may
make use of DRM functions to make tasks like memory management,
interrupt handling and DMA easier, and provide a uniform interface to
applications.

A note on versions: this guide covers features found in the DRM tree,
including the TTM memory manager, output configuration and mode setting,
and the new vblank internals, in addition to all the regular features
found in current kernels.

[Insert diagram of typical DRM stack here]

Style Guidelines
================

For consistency this documentation uses American English. Abbreviations
are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so
on. To aid in reading, documentations make full use of the markup
characters kerneldoc provides: @parameter for function parameters,
@member for structure members (within the same structure), &struct structure to
reference structures and function() for functions. These all get automatically
hyperlinked if kerneldoc for the referenced objects exists. When referencing
entries in function vtables (and structure members in general) please use
&vtable_name.vfunc. Unfortunately this does not yet yield a direct link to the
member, only the structure.

Except in special situations (to separate locked from unlocked variants)
locking requirements for functions aren't documented in the kerneldoc.
Instead locking should be check at runtime using e.g.
``WARN_ON(!mutex_is_locked(...));``. Since it's much easier to ignore
documentation than runtime noise this provides more value. And on top of
that runtime checks do need to be updated when the locking rules change,
increasing the chances that they're correct. Within the documentation
the locking rules should be explained in the relevant structures: Either
in the comment for the lock explaining what it protects, or data fields
need a note about which lock protects them, or both.

Functions which have a non-\ ``void`` return value should have a section
called "Returns" explaining the expected return values in different
cases and their meanings. Currently there's no consensus whether that
section name should be all upper-case or not, and whether it should end
in a colon or not. Go with the file-local style. Other common section
names are "Notes" with information for dangerous or tricky corner cases,
and "FIXME" where the interface could be cleaned up.

Also read the :ref:`guidelines for the kernel documentation at large <doc_guide>`.

Documentation Requirements for kAPI
-----------------------------------

All kernel APIs exported to other modules must be documented, including their
datastructures and at least a short introductory section explaining the overall
concepts. Documentation should be put into the code itself as kerneldoc comments
as much as reasonable.

Do not blindly document everything, but document only what's relevant for driver
authors: Internal functions of drm.ko and definitely static functions should not
have formal kerneldoc comments. Use normal C comments if you feel like a comment
is warranted. You may use kerneldoc syntax in the comment, but it shall not
start with a /** kerneldoc marker. Similar for data structures, annotate
anything entirely private with ``/* private: */`` comments as per the
documentation guide.

Getting Started
===============

Developers interested in helping out with the DRM subsystem are very welcome.
Often people will resort to sending in patches for various issues reported by
checkpatch or sparse. We welcome such contributions.

Anyone looking to kick it up a notch can find a list of janitorial tasks on
the :ref:`TODO list <todo>`.

Contribution Process
====================

Mostly the DRM subsystem works like any other kernel subsystem, see :ref:`the
main process guidelines and documentation <process_index>` for how things work.
Here we just document some of the specialities of the GPU subsystem.

Feature Merge Deadlines
-----------------------

All feature work must be in the linux-next tree by the -rc6 release of the
current release cycle, otherwise they must be postponed and can't reach the next
merge window. All patches must have landed in the drm-next tree by latest -rc7,
but if your branch is not in linux-next then this must have happened by -rc6
already.

After that point only bugfixes (like after the upstream merge window has closed
with the -rc1 release) are allowed. No new platform enabling or new drivers are
allowed.

This means that there's a blackout-period of about one month where feature work
can't be merged. The recommended way to deal with that is having a -next tree
that's always open, but making sure to not feed it into linux-next during the
blackout period. As an example, drm-misc works like that.

Code of Conduct
---------------

As a freedesktop.org project, dri-devel, and the DRM community, follows the
Contributor Covenant, found at: https://www.freedesktop.org/wiki/CodeOfConduct

Please conduct yourself in a respectful and civilised manner when
interacting with community members on mailing lists, IRC, or bug
trackers. The community represents the project as a whole, and abusive
or bullying behaviour is not tolerated by the project.

Simple DRM drivers to use as examples
=====================================

The DRM subsystem contains a lot of helper functions to ease writing drivers for
simple graphic devices. For example, the `drivers/gpu/drm/tiny/` directory has a
set of drivers that are simple enough to be implemented in a single source file.

These drivers make use of the `struct drm_simple_display_pipe_funcs`, that hides
any complexity of the DRM subsystem and just requires drivers to implement a few
functions needed to operate the device. This could be used for devices that just
need a display pipeline with one full-screen scanout buffer feeding one output.

The tiny DRM drivers are good examples to understand how DRM drivers should look
like. Since are just a few hundreds lines of code, they are quite easy to read.

External References
===================

Delving into a Linux kernel subsystem for the first time can be an overwhelming
experience, one needs to get familiar with all the concepts and learn about the
subsystem's internals, among other details.

To shallow the learning curve, this section contains a list of presentations
and documents that can be used to learn about DRM/KMS and graphics in general.

There are different reasons why someone might want to get into DRM: porting an
existing fbdev driver, write a DRM driver for a new hardware, fixing bugs that
could face when working on the graphics user-space stack, etc. For this reason,
the learning material covers many aspects of the Linux graphics stack. From an
overview of the kernel and user-space stacks to very specific topics.

The list is sorted in reverse chronological order, to keep the most up-to-date
material at the top. But all of them contain useful information, and it can be
valuable to go through older material to understand the rationale and context
in which the changes to the DRM subsystem were made.

Conference talks
----------------

* `An Overview of the Linux and Userspace Graphics Stack <https://www.youtube.com/watch?v=wjAJmqwg47k>`_ - Paul Kocialkowski (2020)
* `Getting pixels on screen on Linux: introduction to Kernel Mode Setting <https://www.youtube.com/watch?v=haes4_Xnc5Q>`_ - Simon Ser (2020)
* `Everything Great about Upstream Graphics <https://www.youtube.com/watch?v=kVzHOgt6WGE>`_ - Daniel Vetter (2019)
* `An introduction to the Linux DRM subsystem <https://www.youtube.com/watch?v=LbDOCJcDRoo>`_ - Maxime Ripard (2017)
* `Embrace the Atomic (Display) Age <https://www.youtube.com/watch?v=LjiB_JeDn2M>`_ - Daniel Vetter (2016)
* `Anatomy of an Atomic KMS Driver <https://www.youtube.com/watch?v=lihqR9sENpc>`_ - Laurent Pinchart (2015)
* `Atomic Modesetting for Drivers <https://www.youtube.com/watch?v=kl9suFgbTc8>`_ - Daniel Vetter (2015)
* `Anatomy of an Embedded KMS Driver <https://www.youtube.com/watch?v=Ja8fM7rTae4>`_ - Laurent Pinchart (2013)

Slides and articles
-------------------

* `Understanding the Linux Graphics Stack <https://bootlin.com/doc/training/graphics/graphics-slides.pdf>`_ - Bootlin (2022)
* `DRM KMS overview <https://wiki.st.com/stm32mpu/wiki/DRM_KMS_overview>`_ - STMicroelectronics (2021)
* `Linux graphic stack <https://studiopixl.com/2017-05-13/linux-graphic-stack-an-overview>`_ - Nathan Gauër (2017)
* `Atomic mode setting design overview, part 1 <https://lwn.net/Articles/653071/>`_ - Daniel Vetter (2015)
* `Atomic mode setting design overview, part 2 <https://lwn.net/Articles/653466/>`_ - Daniel Vetter (2015)
* `The DRM/KMS subsystem from a newbie’s point of view <https://bootlin.com/pub/conferences/2014/elce/brezillon-drm-kms/brezillon-drm-kms.pdf>`_ - Boris Brezillon (2014)
* `A brief introduction to the Linux graphics stack <https://blogs.igalia.com/itoral/2014/07/29/a-brief-introduction-to-the-linux-graphics-stack/>`_ - Iago Toral (2014)
* `The Linux Graphics Stack <https://blog.mecheye.net/2012/06/the-linux-graphics-stack/>`_ - Jasper St. Pierre (2012)


code:
Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,Description/Restrictions
,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
,,“select subconnector”,ENUM,"{ ""Automatic"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
,,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
,,“left margin”,RANGE,"Min=0, Max=100",Connector,TBD
,,“right margin”,RANGE,"Min=0, Max=100",Connector,TBD
,,“top margin”,RANGE,"Min=0, Max=100",Connector,TBD
,,“bottom margin”,RANGE,"Min=0, Max=100",Connector,TBD
,,“brightness”,RANGE,"Min=0, Max=100",Connector,TBD
,,“contrast”,RANGE,"Min=0, Max=100",Connector,TBD
,,“flicker reduction”,RANGE,"Min=0, Max=100",Connector,TBD
,,“overscan”,RANGE,"Min=0, Max=100",Connector,TBD
,,“saturation”,RANGE,"Min=0, Max=100",Connector,TBD
,,“hue”,RANGE,"Min=0, Max=100",Connector,TBD
,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255."
,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""right_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""top_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""bottom_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“hpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“vpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“contrast”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“saturation”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“hue”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“sharpness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter_adaptive”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter_2d”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“tv_chroma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“tv_luma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“dot_crawl”,RANGE,"Min=0, Max=1",Connector,TBD
,SDVO-TV/LVDS,“brightness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
CDV gma-500,Generic,"""Broadcast RGB""",ENUM,"{ “Full”, “Limited 16:235” }",Connector,TBD
,,"""Broadcast RGB""",ENUM,"{ “off”, “auto”, “on” }",Connector,TBD
Poulsbo,Generic,“backlight”,RANGE,"Min=0, Max=100",Connector,TBD
,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""right_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""top_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,"""bottom_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“hpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“vpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“contrast”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“saturation”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“hue”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“sharpness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter_adaptive”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“flicker_filter_2d”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“tv_chroma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“tv_luma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
,,“dot_crawl”,RANGE,"Min=0, Max=1",Connector,TBD
,SDVO-TV/LVDS,“brightness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
armada,CRTC,"""CSC_YUV""",ENUM,"{ ""Auto"" , ""CCIR601"", ""CCIR709"" }",CRTC,TBD
,,"""CSC_RGB""",ENUM,"{ ""Auto"", ""Computer system"", ""Studio"" }",CRTC,TBD
,Overlay,"""colorkey""",RANGE,"Min=0, Max=0xffffff",Plane,TBD
,,"""colorkey_min""",RANGE,"Min=0, Max=0xffffff",Plane,TBD
,,"""colorkey_max""",RANGE,"Min=0, Max=0xffffff",Plane,TBD
,,"""colorkey_val""",RANGE,"Min=0, Max=0xffffff",Plane,TBD
,,"""colorkey_alpha""",RANGE,"Min=0, Max=0xffffff",Plane,TBD
,,"""colorkey_mode""",ENUM,"{ ""disabled"", ""Y component"", ""U component"" , ""V component"", ""RGB"", “R component"", ""G component"", ""B component"" }",Plane,TBD
,,"""brightness""",RANGE,"Min=0, Max=256 + 255",Plane,TBD
,,"""contrast""",RANGE,"Min=0, Max=0x7fff",Plane,TBD
,,"""saturation""",RANGE,"Min=0, Max=0x7fff",Plane,TBD
exynos,CRTC,“mode”,ENUM,"{ ""normal"", ""blank"" }",CRTC,TBD
i2c/ch7006_drv,Generic,“scale”,RANGE,"Min=0, Max=2",Connector,TBD
,TV,“mode”,ENUM,"{ ""PAL"", ""PAL-M"",""PAL-N""}, ”PAL-Nc"" , ""PAL-60"", ""NTSC-M"", ""NTSC-J"" }",Connector,TBD
nouveau,NV10 Overlay,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
,,“contrast”,RANGE,"Min=0, Max=8192-1",Plane,TBD
,,“brightness”,RANGE,"Min=0, Max=1024",Plane,TBD
,,“hue”,RANGE,"Min=0, Max=359",Plane,TBD
,,“saturation”,RANGE,"Min=0, Max=8192-1",Plane,TBD
,,“iturbt_709”,RANGE,"Min=0, Max=1",Plane,TBD
,Nv04 Overlay,“colorkey”,RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
,,“brightness”,RANGE,"Min=0, Max=1024",Plane,TBD
,Display,“dithering mode”,ENUM,"{ ""auto"", ""off"", ""on"" }",Connector,TBD
,,“dithering depth”,ENUM,"{ ""auto"", ""off"", ""on"", ""static 2x2"", ""dynamic 2x2"", ""temporal"" }",Connector,TBD
,,“underscan”,ENUM,"{ ""auto"", ""6 bpc"", ""8 bpc"" }",Connector,TBD
,,“underscan hborder”,RANGE,"Min=0, Max=128",Connector,TBD
,,“underscan vborder”,RANGE,"Min=0, Max=128",Connector,TBD
,,“vibrant hue”,RANGE,"Min=0, Max=180",Connector,TBD
,,“color vibrance”,RANGE,"Min=0, Max=200",Connector,TBD
omap,Generic,“zorder”,RANGE,"Min=0, Max=3","CRTC, Plane",TBD
qxl,Generic,"“hotplug_mode_update""",RANGE,"Min=0, Max=1",Connector,TBD
radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
,DAC enable load detect,“load detection”,RANGE,"Min=0, Max=1",Connector,TBD
,TV Standard,"""tv standard""",ENUM,"{ ""ntsc"", ""pal"", ""pal-m"", ""pal-60"", ""ntsc-j"" , ""scart-pal"", ""pal-cn"", ""secam"" }",Connector,TBD
,legacy TMDS PLL detect,"""tmds_pll""",ENUM,"{ ""driver"", ""bios"" }",-,TBD
,Underscan,"""underscan""",ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
,,"""underscan hborder""",RANGE,"Min=0, Max=128",Connector,TBD
,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD


code:
.. SPDX-License-Identifier: GPL-2.0

==============================
 drm/komeda Arm display driver
==============================

The drm/komeda driver supports the Arm display processor D71 and later products,
this document gives a brief overview of driver design: how it works and why
design it like that.

Overview of D71 like display IPs
================================

From D71, Arm display IP begins to adopt a flexible and modularized
architecture. A display pipeline is made up of multiple individual and
functional pipeline stages called components, and every component has some
specific capabilities that can give the flowed pipeline pixel data a
particular processing.

Typical D71 components:

Layer
-----
Layer is the first pipeline stage, which prepares the pixel data for the next
stage. It fetches the pixel from memory, decodes it if it's AFBC, rotates the
source image, unpacks or converts YUV pixels to the device internal RGB pixels,
then adjusts the color_space of pixels if needed.

Scaler
------
As its name suggests, scaler takes responsibility for scaling, and D71 also
supports image enhancements by scaler.
The usage of scaler is very flexible and can be connected to layer output
for layer scaling, or connected to compositor and scale the whole display
frame and then feed the output data into wb_layer which will then write it
into memory.

Compositor (compiz)
-------------------
Compositor blends multiple layers or pixel data flows into one single display
frame. its output frame can be fed into post image processor for showing it on
the monitor or fed into wb_layer and written to memory at the same time.
user can also insert a scaler between compositor and wb_layer to down scale
the display frame first and then write to memory.

Writeback Layer (wb_layer)
--------------------------
Writeback layer does the opposite things of Layer, which connects to compiz
and writes the composition result to memory.

Post image processor (improc)
-----------------------------
Post image processor adjusts frame data like gamma and color space to fit the
requirements of the monitor.

Timing controller (timing_ctrlr)
--------------------------------
Final stage of display pipeline, Timing controller is not for the pixel
handling, but only for controlling the display timing.

Merger
------
D71 scaler mostly only has the half horizontal input/output capabilities
compared with Layer, like if Layer supports 4K input size, the scaler only can
support 2K input/output in the same time. To achieve the ful frame scaling, D71
introduces Layer Split, which splits the whole image to two half parts and feeds
them to two Layers A and B, and does the scaling independently. After scaling
the result need to be fed to merger to merge two part images together, and then
output merged result to compiz.

Splitter
--------
Similar to Layer Split, but Splitter is used for writeback, which splits the
compiz result to two parts and then feed them to two scalers.

Possible D71 Pipeline usage
===========================

Benefitting from the modularized architecture, D71 pipelines can be easily
adjusted to fit different usages. And D71 has two pipelines, which support two
types of working mode:

-   Dual display mode
    Two pipelines work independently and separately to drive two display outputs.

-   Single display mode
    Two pipelines work together to drive only one display output.

    On this mode, pipeline_B doesn't work indenpendently, but outputs its
    composition result into pipeline_A, and its pixel timing also derived from
    pipeline_A.timing_ctrlr. The pipeline_B works just like a "slave" of
    pipeline_A(master)

Single pipeline data flow
-------------------------

.. kernel-render:: DOT
   :alt: Single pipeline digraph
   :caption: Single pipeline data flow

   digraph single_ppl {
      rankdir=LR;

      subgraph {
         "Memory";
         "Monitor";
      }

      subgraph cluster_pipeline {
          style=dashed
          node [shape=box]
          {
              node [bgcolor=grey style=dashed]
              "Scaler-0";
              "Scaler-1";
              "Scaler-0/1"
          }

         node [bgcolor=grey style=filled]
         "Layer-0" -> "Scaler-0"
         "Layer-1" -> "Scaler-0"
         "Layer-2" -> "Scaler-1"
         "Layer-3" -> "Scaler-1"

         "Layer-0" -> "Compiz"
         "Layer-1" -> "Compiz"
         "Layer-2" -> "Compiz"
         "Layer-3" -> "Compiz"
         "Scaler-0" -> "Compiz"
         "Scaler-1" -> "Compiz"

         "Compiz" -> "Scaler-0/1" -> "Wb_layer"
         "Compiz" -> "Improc" -> "Timing Controller"
      }

      "Wb_layer" -> "Memory"
      "Timing Controller" -> "Monitor"
   }

Dual pipeline with Slave enabled
--------------------------------

.. kernel-render:: DOT
   :alt: Slave pipeline digraph
   :caption: Slave pipeline enabled data flow

   digraph slave_ppl {
      rankdir=LR;

      subgraph {
         "Memory";
         "Monitor";
      }
      node [shape=box]
      subgraph cluster_pipeline_slave {
          style=dashed
          label="Slave Pipeline_B"
          node [shape=box]
          {
              node [bgcolor=grey style=dashed]
              "Slave.Scaler-0";
              "Slave.Scaler-1";
          }

         node [bgcolor=grey style=filled]
         "Slave.Layer-0" -> "Slave.Scaler-0"
         "Slave.Layer-1" -> "Slave.Scaler-0"
         "Slave.Layer-2" -> "Slave.Scaler-1"
         "Slave.Layer-3" -> "Slave.Scaler-1"

         "Slave.Layer-0" -> "Slave.Compiz"
         "Slave.Layer-1" -> "Slave.Compiz"
         "Slave.Layer-2" -> "Slave.Compiz"
         "Slave.Layer-3" -> "Slave.Compiz"
         "Slave.Scaler-0" -> "Slave.Compiz"
         "Slave.Scaler-1" -> "Slave.Compiz"
      }

      subgraph cluster_pipeline_master {
          style=dashed
          label="Master Pipeline_A"
          node [shape=box]
          {
              node [bgcolor=grey style=dashed]
              "Scaler-0";
              "Scaler-1";
              "Scaler-0/1"
          }

         node [bgcolor=grey style=filled]
         "Layer-0" -> "Scaler-0"
         "Layer-1" -> "Scaler-0"
         "Layer-2" -> "Scaler-1"
         "Layer-3" -> "Scaler-1"

         "Slave.Compiz" -> "Compiz"
         "Layer-0" -> "Compiz"
         "Layer-1" -> "Compiz"
         "Layer-2" -> "Compiz"
         "Layer-3" -> "Compiz"
         "Scaler-0" -> "Compiz"
         "Scaler-1" -> "Compiz"

         "Compiz" -> "Scaler-0/1" -> "Wb_layer"
         "Compiz" -> "Improc" -> "Timing Controller"
      }

      "Wb_layer" -> "Memory"
      "Timing Controller" -> "Monitor"
   }

Sub-pipelines for input and output
----------------------------------

A complete display pipeline can be easily divided into three sub-pipelines
according to the in/out usage.

Layer(input) pipeline
~~~~~~~~~~~~~~~~~~~~~

.. kernel-render:: DOT
   :alt: Layer data digraph
   :caption: Layer (input) data flow

   digraph layer_data_flow {
      rankdir=LR;
      node [shape=box]

      {
         node [bgcolor=grey style=dashed]
           "Scaler-n";
      }

      "Layer-n" -> "Scaler-n" -> "Compiz"
   }

.. kernel-render:: DOT
   :alt: Layer Split digraph
   :caption: Layer Split pipeline

   digraph layer_data_flow {
      rankdir=LR;
      node [shape=box]

      "Layer-0/1" -> "Scaler-0" -> "Merger"
      "Layer-2/3" -> "Scaler-1" -> "Merger"
      "Merger" -> "Compiz"
   }

Writeback(output) pipeline
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-render:: DOT
   :alt: writeback digraph
   :caption: Writeback(output) data flow

   digraph writeback_data_flow {
      rankdir=LR;
      node [shape=box]

      {
         node [bgcolor=grey style=dashed]
           "Scaler-n";
      }

      "Compiz" -> "Scaler-n" -> "Wb_layer"
   }

.. kernel-render:: DOT
   :alt: split writeback digraph
   :caption: Writeback(output) Split data flow

   digraph writeback_data_flow {
      rankdir=LR;
      node [shape=box]

      "Compiz" -> "Splitter"
      "Splitter" -> "Scaler-0" -> "Merger"
      "Splitter" -> "Scaler-1" -> "Merger"
      "Merger" -> "Wb_layer"
   }

Display output pipeline
~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-render:: DOT
   :alt: display digraph
   :caption: display output data flow

   digraph single_ppl {
      rankdir=LR;
      node [shape=box]

      "Compiz" -> "Improc" -> "Timing Controller"
   }

In the following section we'll see these three sub-pipelines will be handled
by KMS-plane/wb_conn/crtc respectively.

Komeda Resource abstraction
===========================

struct komeda_pipeline/component
--------------------------------

To fully utilize and easily access/configure the HW, the driver side also uses
a similar architecture: Pipeline/Component to describe the HW features and
capabilities, and a specific component includes two parts:

-  Data flow controlling.
-  Specific component capabilities and features.

So the driver defines a common header struct komeda_component to describe the
data flow control and all specific components are a subclass of this base
structure.

.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
   :internal:

Resource discovery and initialization
=====================================

Pipeline and component are used to describe how to handle the pixel data. We
still need a @struct komeda_dev to describe the whole view of the device, and
the control-abilites of device.

We have &komeda_dev, &komeda_pipeline, &komeda_component. Now fill devices with
pipelines. Since komeda is not for D71 only but also intended for later products,
of course we’d better share as much as possible between different products. To
achieve this, split the komeda device into two layers: CORE and CHIP.

-   CORE: for common features and capabilities handling.
-   CHIP: for register programing and HW specific feature (limitation) handling.

CORE can access CHIP by three chip function structures:

-   struct komeda_dev_funcs
-   struct komeda_pipeline_funcs
-   struct komeda_component_funcs

.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_dev.h
   :internal:

Format handling
===============

.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
   :internal:
.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
   :internal:

Attach komeda_dev to DRM-KMS
============================

Komeda abstracts resources by pipeline/component, but DRM-KMS uses
crtc/plane/connector. One KMS-obj cannot represent only one single component,
since the requirements of a single KMS object cannot simply be achieved by a
single component, usually that needs multiple components to fit the requirement.
Like set mode, gamma, ctm for KMS all target on CRTC-obj, but komeda needs
compiz, improc and timing_ctrlr to work together to fit these requirements.
And a KMS-Plane may require multiple komeda resources: layer/scaler/compiz.

So, one KMS-Obj represents a sub-pipeline of komeda resources.

-   Plane: `Layer(input) pipeline`_
-   Wb_connector: `Writeback(output) pipeline`_
-   Crtc: `Display output pipeline`_

So, for komeda, we treat KMS crtc/plane/connector as users of pipeline and
component, and at any one time a pipeline/component only can be used by one
user. And pipeline/component will be treated as private object of DRM-KMS; the
state will be managed by drm_atomic_state as well.

How to map plane to Layer(input) pipeline
-----------------------------------------

Komeda has multiple Layer input pipelines, see:
-   `Single pipeline data flow`_
-   `Dual pipeline with Slave enabled`_

The easiest way is binding a plane to a fixed Layer pipeline, but consider the
komeda capabilities:

-   Layer Split, See `Layer(input) pipeline`_

    Layer_Split is quite complicated feature, which splits a big image into two
    parts and handles it by two layers and two scalers individually. But it
    imports an edge problem or effect in the middle of the image after the split.
    To avoid such a problem, it needs a complicated Split calculation and some
    special configurations to the layer and scaler. We'd better hide such HW
    related complexity to user mode.

-   Slave pipeline, See `Dual pipeline with Slave enabled`_

    Since the compiz component doesn't output alpha value, the slave pipeline
    only can be used for bottom layers composition. The komeda driver wants to
    hide this limitation to the user. The way to do this is to pick a suitable
    Layer according to plane_state->zpos.

So for komeda, the KMS-plane doesn't represent a fixed komeda layer pipeline,
but multiple Layers with same capabilities. Komeda will select one or more
Layers to fit the requirement of one KMS-plane.

Make component/pipeline to be drm_private_obj
---------------------------------------------

Add :c:type:`drm_private_obj` to :c:type:`komeda_component`, :c:type:`komeda_pipeline`

.. code-block:: c

    struct komeda_component {
        struct drm_private_obj obj;
        ...
    }

    struct komeda_pipeline {
        struct drm_private_obj obj;
        ...
    }

Tracking component_state/pipeline_state by drm_atomic_state
-----------------------------------------------------------

Add :c:type:`drm_private_state` and user to :c:type:`komeda_component_state`,
:c:type:`komeda_pipeline_state`

.. code-block:: c

    struct komeda_component_state {
        struct drm_private_state obj;
        void *binding_user;
        ...
    }

    struct komeda_pipeline_state {
        struct drm_private_state obj;
        struct drm_crtc *crtc;
        ...
    }

komeda component validation
---------------------------

Komeda has multiple types of components, but the process of validation are
similar, usually including the following steps:

.. code-block:: c

    int komeda_xxxx_validate(struct komeda_component_xxx xxx_comp,
                struct komeda_component_output *input_dflow,
                struct drm_plane/crtc/connector *user,
                struct drm_plane/crtc/connector_state, *user_state)
    {
         setup 1: check if component is needed, like the scaler is optional depending
                  on the user_state; if unneeded, just return, and the caller will
                  put the data flow into next stage.
         Setup 2: check user_state with component features and capabilities to see
                  if requirements can be met; if not, return fail.
         Setup 3: get component_state from drm_atomic_state, and try set to set
                  user to component; fail if component has been assigned to another
                  user already.
         Setup 3: configure the component_state, like set its input component,
                  convert user_state to component specific state.
         Setup 4: adjust the input_dflow and prepare it for the next stage.
    }

komeda_kms Abstraction
----------------------

.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_kms.h
   :internal:

komde_kms Functions
-------------------
.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
   :internal:
.. kernel-doc:: drivers/gpu/drm/arm/display/komeda/komeda_plane.c
   :internal:

Build komeda to be a Linux module driver
========================================

Now we have two level devices:

-   komeda_dev: describes the real display hardware.
-   komeda_kms_dev: attachs or connects komeda_dev to DRM-KMS.

All komeda operations are supplied or operated by komeda_dev or komeda_kms_dev,
the module driver is only a simple wrapper to pass the Linux command
(probe/remove/pm) into komeda_dev or komeda_kms_dev.


code:
=============================================
drm/meson AmLogic Meson Video Processing Unit
=============================================

.. kernel-doc:: drivers/gpu/drm/meson/meson_drv.c
   :doc: Video Processing Unit

Video Processing Unit
=====================

The Amlogic Meson Display controller is composed of several components
that are going to be documented below:

.. code::

  DMC|---------------VPU (Video Processing Unit)----------------|------HHI------|
     | vd1   _______     _____________    _________________     |               |
  D  |-------|      |----|            |   |                |    |   HDMI PLL    |
  D  | vd2   | VIU  |    | Video Post |   | Video Encoders |<---|-----VCLK      |
  R  |-------|      |----| Processing |   |                |    |               |
     | osd2  |      |    |            |---| Enci ----------|----|-----VDAC------|
  R  |-------| CSC  |----| Scalers    |   | Encp ----------|----|----HDMI-TX----|
  A  | osd1  |      |    | Blenders   |   | Encl ----------|----|---------------|
  M  |-------|______|----|____________|   |________________|    |               |
  ___|__________________________________________________________|_______________|

Video Input Unit
================

.. kernel-doc:: drivers/gpu/drm/meson/meson_viu.c
   :doc: Video Input Unit

Video Post Processing
=====================

.. kernel-doc:: drivers/gpu/drm/meson/meson_vpp.c
   :doc: Video Post Processing

Video Encoder
=============

.. kernel-doc:: drivers/gpu/drm/meson/meson_venc.c
   :doc: Video Encoder

Video Clocks
============

.. kernel-doc:: drivers/gpu/drm/meson/meson_vclk.c
   :doc: Video Clocks

HDMI Video Output
=================

.. kernel-doc:: drivers/gpu/drm/meson/meson_dw_hdmi.c
   :doc: HDMI Output


code:
:orphan:

=====================
MSM Crash Dump Format
=====================

Following a GPU hang the MSM driver outputs debugging information via
/sys/kernel/dri/X/show or via devcoredump (/sys/class/devcoredump/dcdX/data).
This document describes how the output is formatted.

Each entry is in the form key: value. Sections headers will not have a value
and all the contents of a section will be indented two spaces from the header.
Each section might have multiple array entries the start of which is designated
by a (-).

Mappings
--------

kernel
	The kernel version that generated the dump (UTS_RELEASE).

module
	The module that generated the crashdump.

time
	The kernel time at crash formated as seconds.microseconds.

comm
	Comm string for the binary that generated the fault.

cmdline
	Command line for the binary that generated the fault.

revision
	ID of the GPU that generated the crash formatted as
	core.major.minor.patchlevel separated by dots.

rbbm-status
	The current value of RBBM_STATUS which shows what top level GPU
	components are in use at the time of crash.

ringbuffer
	Section containing the contents of each ringbuffer. Each ringbuffer is
	identified with an id number.

	id
		Ringbuffer ID (0 based index).  Each ringbuffer in the section
		will have its own unique id.
	iova
		GPU address of the ringbuffer.

	last-fence
		The last fence that was issued on the ringbuffer

	retired-fence
		The last fence retired on the ringbuffer.

	rptr
		The current read pointer (rptr) for the ringbuffer.

	wptr
		The current write pointer (wptr) for the ringbuffer.

	size
		Maximum size of the ringbuffer programmed in the hardware.

	data
		The contents of the ring encoded as ascii85.  Only the used
		portions of the ring will be printed.

bo
	List of buffers from the hanging submission if available.
	Each buffer object will have a uinque iova.

	iova
		GPU address of the buffer object.

	size
		Allocated size of the buffer object.

	data
		The contents of the buffer object encoded with ascii85.  Only
		Trailing zeros at the end of the buffer will be skipped.

registers
	Set of registers values. Each entry is on its own line enclosed
	by brackets { }.

	offset
		Byte offset of the register from the start of the
		GPU memory region.

	value
		Hexadecimal value of the register.

registers-hlsq
		(5xx only) Register values from the HLSQ aperture.
		Same format as the register section.


code:
=========================
I915 DG1/LMEM RFC Section
=========================

Upstream plan
=============
For upstream the overall plan for landing all the DG1 stuff and turning it for
real, with all the uAPI bits is:

* Merge basic HW enabling of DG1(still without pciid)
* Merge the uAPI bits behind special CONFIG_BROKEN(or so) flag
        * At this point we can still make changes, but importantly this lets us
          start running IGTs which can utilize local-memory in CI
* Convert over to TTM, make sure it all keeps working. Some of the work items:
        * TTM shrinker for discrete
        * dma_resv_lockitem for full dma_resv_lock, i.e not just trylock
        * Use TTM CPU pagefault handler
        * Route shmem backend over to TTM SYSTEM for discrete
        * TTM purgeable object support
        * Move i915 buddy allocator over to TTM
* Send RFC(with mesa-dev on cc) for final sign off on the uAPI
* Add pciid for DG1 and turn on uAPI for real


code:
=========================================
I915 GuC Submission/DRM Scheduler Section
=========================================

Upstream plan
=============
For upstream the overall plan for landing GuC submission and integrating the
i915 with the DRM scheduler is:

* Merge basic GuC submission
	* Basic submission support for all gen11+ platforms
	* Not enabled by default on any current platforms but can be enabled via
	  modparam enable_guc
	* Lots of rework will need to be done to integrate with DRM scheduler so
	  no need to nit pick everything in the code, it just should be
	  functional, no major coding style / layering errors, and not regress
	  execlists
	* Update IGTs / selftests as needed to work with GuC submission
	* Enable CI on supported platforms for a baseline
	* Rework / get CI heathly for GuC submission in place as needed
* Merge new parallel submission uAPI
	* Bonding uAPI completely incompatible with GuC submission, plus it has
	  severe design issues in general, which is why we want to retire it no
	  matter what
	* New uAPI adds I915_CONTEXT_ENGINES_EXT_PARALLEL context setup step
	  which configures a slot with N contexts
	* After I915_CONTEXT_ENGINES_EXT_PARALLEL a user can submit N batches to
	  a slot in a single execbuf IOCTL and the batches run on the GPU in
	  paralllel
	* Initially only for GuC submission but execlists can be supported if
	  needed
* Convert the i915 to use the DRM scheduler
	* GuC submission backend fully integrated with DRM scheduler
		* All request queues removed from backend (e.g. all backpressure
		  handled in DRM scheduler)
		* Resets / cancels hook in DRM scheduler
		* Watchdog hooks into DRM scheduler
		* Lots of complexity of the GuC backend can be pulled out once
		  integrated with DRM scheduler (e.g. state machine gets
		  simplier, locking gets simplier, etc...)
	* Execlists backend will minimum required to hook in the DRM scheduler
		* Legacy interface
		* Features like timeslicing / preemption / virtual engines would
		  be difficult to integrate with the DRM scheduler and these
		  features are not required for GuC submission as the GuC does
		  these things for us
		* ROI low on fully integrating into DRM scheduler
		* Fully integrating would add lots of complexity to DRM
		  scheduler
	* Port i915 priority inheritance / boosting feature in DRM scheduler
		* Used for i915 page flip, may be useful to other DRM drivers as
		  well
		* Will be an optional feature in the DRM scheduler
	* Remove in-order completion assumptions from DRM scheduler
		* Even when using the DRM scheduler the backends will handle
		  preemption, timeslicing, etc... so it is possible for jobs to
		  finish out of order
	* Pull out i915 priority levels and use DRM priority levels
	* Optimize DRM scheduler as needed

TODOs for GuC submission upstream
=================================

* Need an update to GuC firmware / i915 to enable error state capture
* Open source tool to decode GuC logs
* Public GuC spec

New uAPI for basic GuC submission
=================================
No major changes are required to the uAPI for basic GuC submission. The only
change is a new scheduler attribute: I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP.
This attribute indicates the 2k i915 user priority levels are statically mapped
into 3 levels as follows:

* -1k to -1 Low priority
* 0 Medium priority
* 1 to 1k High priority

This is needed because the GuC only has 4 priority bands. The highest priority
band is reserved with the kernel. This aligns with the DRM scheduler priority
levels too.

Spec references:
----------------
* https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt
* https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap5.html#devsandqueues-priority
* https://spec.oneapi.com/level-zero/latest/core/api.html#ze-command-queue-priority-t

New parallel submission uAPI
============================
The existing bonding uAPI is completely broken with GuC submission because
whether a submission is a single context submit or parallel submit isn't known
until execbuf time activated via the I915_SUBMIT_FENCE. To submit multiple
contexts in parallel with the GuC the context must be explicitly registered with
N contexts and all N contexts must be submitted in a single command to the GuC.
The GuC interfaces do not support dynamically changing between N contexts as the
bonding uAPI does. Hence the need for a new parallel submission interface. Also
the legacy bonding uAPI is quite confusing and not intuitive at all. Furthermore
I915_SUBMIT_FENCE is by design a future fence, so not really something we should
continue to support.

The new parallel submission uAPI consists of 3 parts:

* Export engines logical mapping
* A 'set_parallel' extension to configure contexts for parallel
  submission
* Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL

Export engines logical mapping
------------------------------
Certain use cases require BBs to be placed on engine instances in logical order
(e.g. split-frame on gen11+). The logical mapping of engine instances can change
based on fusing. Rather than making UMDs be aware of fusing, simply expose the
logical mapping with the existing query engine info IOCTL. Also the GuC
submission interface currently only supports submitting multiple contexts to
engines in logical order which is a new requirement compared to execlists.
Lastly, all current platforms have at most 2 engine instances and the logical
order is the same as uAPI order. This will change on platforms with more than 2
engine instances.

A single bit will be added to drm_i915_engine_info.flags indicating that the
logical instance has been returned and a new field,
drm_i915_engine_info.logical_instance, returns the logical instance.

A 'set_parallel' extension to configure contexts for parallel submission
------------------------------------------------------------------------
The 'set_parallel' extension configures a slot for parallel submission of N BBs.
It is a setup step that must be called before using any of the contexts. See
I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE or I915_CONTEXT_ENGINES_EXT_BOND for
similar existing examples. Once a slot is configured for parallel submission the
execbuf2 IOCTL can be called submitting N BBs in a single IOCTL. Initially only
supports GuC submission. Execlists supports can be added later if needed.

Add I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT and
drm_i915_context_engines_parallel_submit to the uAPI to implement this
extension.

.. kernel-doc:: include/uapi/drm/i915_drm.h
        :functions: i915_context_engines_parallel_submit

Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL
-------------------------------------------------------------------
Contexts that have been configured with the 'set_parallel' extension can only
submit N BBs in a single execbuf2 IOCTL. The BBs are either the last N objects
in the drm_i915_gem_exec_object2 list or the first N if I915_EXEC_BATCH_FIRST is
set. The number of BBs is implicit based on the slot submitted and how it has
been configured by 'set_parallel' or other extensions. No uAPI changes are
required to the execbuf2 IOCTL.


code:
/**
 * struct __drm_i915_memory_region_info - Describes one region as known to the
 * driver.
 *
 * Note this is using both struct drm_i915_query_item and struct drm_i915_query.
 * For this new query we are adding the new query id DRM_I915_QUERY_MEMORY_REGIONS
 * at &drm_i915_query_item.query_id.
 */
struct __drm_i915_memory_region_info {
	/** @region: The class:instance pair encoding */
	struct drm_i915_gem_memory_class_instance region;

	/** @rsvd0: MBZ */
	__u32 rsvd0;

	/**
	 * @probed_size: Memory probed by the driver
	 *
	 * Note that it should not be possible to ever encounter a zero value
	 * here, also note that no current region type will ever return -1 here.
	 * Although for future region types, this might be a possibility. The
	 * same applies to the other size fields.
	 */
	__u64 probed_size;

	/**
	 * @unallocated_size: Estimate of memory remaining
	 *
	 * Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable accounting.
	 * Without this (or if this is an older kernel) the value here will
	 * always equal the @probed_size. Note this is only currently tracked
	 * for I915_MEMORY_CLASS_DEVICE regions (for other types the value here
	 * will always equal the @probed_size).
	 */
	__u64 unallocated_size;

	union {
		/** @rsvd1: MBZ */
		__u64 rsvd1[8];
		struct {
			/**
			 * @probed_cpu_visible_size: Memory probed by the driver
			 * that is CPU accessible.
			 *
			 * This will be always be <= @probed_size, and the
			 * remainder (if there is any) will not be CPU
			 * accessible.
			 *
			 * On systems without small BAR, the @probed_size will
			 * always equal the @probed_cpu_visible_size, since all
			 * of it will be CPU accessible.
			 *
			 * Note this is only tracked for
			 * I915_MEMORY_CLASS_DEVICE regions (for other types the
			 * value here will always equal the @probed_size).
			 *
			 * Note that if the value returned here is zero, then
			 * this must be an old kernel which lacks the relevant
			 * small-bar uAPI support (including
			 * I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS), but on
			 * such systems we should never actually end up with a
			 * small BAR configuration, assuming we are able to load
			 * the kernel module. Hence it should be safe to treat
			 * this the same as when @probed_cpu_visible_size ==
			 * @probed_size.
			 */
			__u64 probed_cpu_visible_size;

			/**
			 * @unallocated_cpu_visible_size: Estimate of CPU
			 * visible memory remaining
			 *
			 * Note this is only tracked for
			 * I915_MEMORY_CLASS_DEVICE regions (for other types the
			 * value here will always equal the
			 * @probed_cpu_visible_size).
			 *
			 * Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable
			 * accounting.  Without this the value here will always
			 * equal the @probed_cpu_visible_size. Note this is only
			 * currently tracked for I915_MEMORY_CLASS_DEVICE
			 * regions (for other types the value here will also
			 * always equal the @probed_cpu_visible_size).
			 *
			 * If this is an older kernel the value here will be
			 * zero, see also @probed_cpu_visible_size.
			 */
			__u64 unallocated_cpu_visible_size;
		};
	};
};

/**
 * struct __drm_i915_gem_create_ext - Existing gem_create behaviour, with added
 * extension support using struct i915_user_extension.
 *
 * Note that new buffer flags should be added here, at least for the stuff that
 * is immutable. Previously we would have two ioctls, one to create the object
 * with gem_create, and another to apply various parameters, however this
 * creates some ambiguity for the params which are considered immutable. Also in
 * general we're phasing out the various SET/GET ioctls.
 */
struct __drm_i915_gem_create_ext {
	/**
	 * @size: Requested size for the object.
	 *
	 * The (page-aligned) allocated size for the object will be returned.
	 *
	 * Note that for some devices we have might have further minimum
	 * page-size restrictions (larger than 4K), like for device local-memory.
	 * However in general the final size here should always reflect any
	 * rounding up, if for example using the I915_GEM_CREATE_EXT_MEMORY_REGIONS
	 * extension to place the object in device local-memory. The kernel will
	 * always select the largest minimum page-size for the set of possible
	 * placements as the value to use when rounding up the @size.
	 */
	__u64 size;

	/**
	 * @handle: Returned handle for the object.
	 *
	 * Object handles are nonzero.
	 */
	__u32 handle;

	/**
	 * @flags: Optional flags.
	 *
	 * Supported values:
	 *
	 * I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS - Signal to the kernel that
	 * the object will need to be accessed via the CPU.
	 *
	 * Only valid when placing objects in I915_MEMORY_CLASS_DEVICE, and only
	 * strictly required on configurations where some subset of the device
	 * memory is directly visible/mappable through the CPU (which we also
	 * call small BAR), like on some DG2+ systems. Note that this is quite
	 * undesirable, but due to various factors like the client CPU, BIOS etc
	 * it's something we can expect to see in the wild. See
	 * &__drm_i915_memory_region_info.probed_cpu_visible_size for how to
	 * determine if this system applies.
	 *
	 * Note that one of the placements MUST be I915_MEMORY_CLASS_SYSTEM, to
	 * ensure the kernel can always spill the allocation to system memory,
	 * if the object can't be allocated in the mappable part of
	 * I915_MEMORY_CLASS_DEVICE.
	 *
	 * Also note that since the kernel only supports flat-CCS on objects
	 * that can *only* be placed in I915_MEMORY_CLASS_DEVICE, we therefore
	 * don't support I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS together with
	 * flat-CCS.
	 *
	 * Without this hint, the kernel will assume that non-mappable
	 * I915_MEMORY_CLASS_DEVICE is preferred for this object. Note that the
	 * kernel can still migrate the object to the mappable part, as a last
	 * resort, if userspace ever CPU faults this object, but this might be
	 * expensive, and so ideally should be avoided.
	 *
	 * On older kernels which lack the relevant small-bar uAPI support (see
	 * also &__drm_i915_memory_region_info.probed_cpu_visible_size),
	 * usage of the flag will result in an error, but it should NEVER be
	 * possible to end up with a small BAR configuration, assuming we can
	 * also successfully load the i915 kernel module. In such cases the
	 * entire I915_MEMORY_CLASS_DEVICE region will be CPU accessible, and as
	 * such there are zero restrictions on where the object can be placed.
	 */
#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0)
	__u32 flags;

	/**
	 * @extensions: The chain of extensions to apply to this object.
	 *
	 * This will be useful in the future when we need to support several
	 * different extensions, and we need to apply more than one when
	 * creating the object. See struct i915_user_extension.
	 *
	 * If we don't supply any extensions then we get the same old gem_create
	 * behaviour.
	 *
	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
	 * struct drm_i915_gem_create_ext_memory_regions.
	 *
	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
	 * struct drm_i915_gem_create_ext_protected_content.
	 */
#define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
	__u64 extensions;
};


code:
==========================
I915 Small BAR RFC Section
==========================
Starting from DG2 we will have resizable BAR support for device local-memory(i.e
I915_MEMORY_CLASS_DEVICE), but in some cases the final BAR size might still be
smaller than the total probed_size. In such cases, only some subset of
I915_MEMORY_CLASS_DEVICE will be CPU accessible(for example the first 256M),
while the remainder is only accessible via the GPU.

I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS flag
----------------------------------------------
New gem_create_ext flag to tell the kernel that a BO will require CPU access.
This becomes important when placing an object in I915_MEMORY_CLASS_DEVICE, where
underneath the device has a small BAR, meaning only some portion of it is CPU
accessible. Without this flag the kernel will assume that CPU access is not
required, and prioritize using the non-CPU visible portion of
I915_MEMORY_CLASS_DEVICE.

.. kernel-doc:: Documentation/gpu/rfc/i915_small_bar.h
   :functions: __drm_i915_gem_create_ext

probed_cpu_visible_size attribute
---------------------------------
New struct__drm_i915_memory_region attribute which returns the total size of the
CPU accessible portion, for the particular region. This should only be
applicable for I915_MEMORY_CLASS_DEVICE. We also report the
unallocated_cpu_visible_size, alongside the unallocated_size.

Vulkan will need this as part of creating a separate VkMemoryHeap with the
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set, to represent the CPU visible portion,
where the total size of the heap needs to be known. It also wants to be able to
give a rough estimate of how memory can potentially be allocated.

.. kernel-doc:: Documentation/gpu/rfc/i915_small_bar.h
   :functions: __drm_i915_memory_region_info

Error Capture restrictions
--------------------------
With error capture we have two new restrictions:

    1) Error capture is best effort on small BAR systems; if the pages are not
    CPU accessible, at the time of capture, then the kernel is free to skip
    trying to capture them.

    2) On discrete and newer integrated platforms we now reject error capture
    on recoverable contexts. In the future the kernel may want to blit during
    error capture, when for example something is not currently CPU accessible.


code:
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2022 Intel Corporation
 */

/**
 * DOC: I915_PARAM_VM_BIND_VERSION
 *
 * VM_BIND feature version supported.
 * See typedef drm_i915_getparam_t param.
 *
 * Specifies the VM_BIND feature version supported.
 * The following versions of VM_BIND have been defined:
 *
 * 0: No VM_BIND support.
 *
 * 1: In VM_UNBIND calls, the UMD must specify the exact mappings created
 *    previously with VM_BIND, the ioctl will not support unbinding multiple
 *    mappings or splitting them. Similarly, VM_BIND calls will not replace
 *    any existing mappings.
 *
 * 2: The restrictions on unbinding partial or multiple mappings is
 *    lifted, Similarly, binding will replace any mappings in the given range.
 *
 * See struct drm_i915_gem_vm_bind and struct drm_i915_gem_vm_unbind.
 */
#define I915_PARAM_VM_BIND_VERSION	57

/**
 * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
 *
 * Flag to opt-in for VM_BIND mode of binding during VM creation.
 * See struct drm_i915_gem_vm_control flags.
 *
 * The older execbuf2 ioctl will not support VM_BIND mode of operation.
 * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
 * execlist (See struct drm_i915_gem_execbuffer3 for more details).
 */
#define I915_VM_CREATE_FLAGS_USE_VM_BIND	(1 << 0)

/* VM_BIND related ioctls */
#define DRM_I915_GEM_VM_BIND		0x3d
#define DRM_I915_GEM_VM_UNBIND		0x3e
#define DRM_I915_GEM_EXECBUFFER3	0x3f

#define DRM_IOCTL_I915_GEM_VM_BIND		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
#define DRM_IOCTL_I915_GEM_VM_UNBIND		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
#define DRM_IOCTL_I915_GEM_EXECBUFFER3		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)

/**
 * struct drm_i915_gem_timeline_fence - An input or output timeline fence.
 *
 * The operation will wait for input fence to signal.
 *
 * The returned output fence will be signaled after the completion of the
 * operation.
 */
struct drm_i915_gem_timeline_fence {
	/** @handle: User's handle for a drm_syncobj to wait on or signal. */
	__u32 handle;

	/**
	 * @flags: Supported flags are:
	 *
	 * I915_TIMELINE_FENCE_WAIT:
	 * Wait for the input fence before the operation.
	 *
	 * I915_TIMELINE_FENCE_SIGNAL:
	 * Return operation completion fence as output.
	 */
	__u32 flags;
#define I915_TIMELINE_FENCE_WAIT            (1 << 0)
#define I915_TIMELINE_FENCE_SIGNAL          (1 << 1)
#define __I915_TIMELINE_FENCE_UNKNOWN_FLAGS (-(I915_TIMELINE_FENCE_SIGNAL << 1))

	/**
	 * @value: A point in the timeline.
	 * Value must be 0 for a binary drm_syncobj. A Value of 0 for a
	 * timeline drm_syncobj is invalid as it turns a drm_syncobj into a
	 * binary one.
	 */
	__u64 value;
};

/**
 * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
 *
 * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
 * virtual address (VA) range to the section of an object that should be bound
 * in the device page table of the specified address space (VM).
 * The VA range specified must be unique (ie., not currently bound) and can
 * be mapped to whole object or a section of the object (partial binding).
 * Multiple VA mappings can be created to the same section of the object
 * (aliasing).
 *
 * The @start, @offset and @length must be 4K page aligned. However the DG2
 * and XEHPSDV has 64K page size for device local memory and has compact page
 * table. On those platforms, for binding device local-memory objects, the
 * @start, @offset and @length must be 64K aligned. Also, UMDs should not mix
 * the local memory 64K page and the system memory 4K page bindings in the same
 * 2M range.
 *
 * Error code -EINVAL will be returned if @start, @offset and @length are not
 * properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), error code
 * -ENOSPC will be returned if the VA range specified can't be reserved.
 *
 * VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
 * are not ordered. Furthermore, parts of the VM_BIND operation can be done
 * asynchronously, if valid @fence is specified.
 */
struct drm_i915_gem_vm_bind {
	/** @vm_id: VM (address space) id to bind */
	__u32 vm_id;

	/** @handle: Object handle */
	__u32 handle;

	/** @start: Virtual Address start to bind */
	__u64 start;

	/** @offset: Offset in object to bind */
	__u64 offset;

	/** @length: Length of mapping to bind */
	__u64 length;

	/**
	 * @flags: Supported flags are:
	 *
	 * I915_GEM_VM_BIND_CAPTURE:
	 * Capture this mapping in the dump upon GPU error.
	 *
	 * Note that @fence carries its own flags.
	 */
	__u64 flags;
#define I915_GEM_VM_BIND_CAPTURE	(1 << 0)

	/**
	 * @fence: Timeline fence for bind completion signaling.
	 *
	 * Timeline fence is of format struct drm_i915_gem_timeline_fence.
	 *
	 * It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
	 * is invalid, and an error will be returned.
	 *
	 * If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
	 * is not requested and binding is completed synchronously.
	 */
	struct drm_i915_gem_timeline_fence fence;

	/**
	 * @extensions: Zero-terminated chain of extensions.
	 *
	 * For future extensions. See struct i915_user_extension.
	 */
	__u64 extensions;
};

/**
 * struct drm_i915_gem_vm_unbind - VA to object mapping to unbind.
 *
 * This structure is passed to VM_UNBIND ioctl and specifies the GPU virtual
 * address (VA) range that should be unbound from the device page table of the
 * specified address space (VM). VM_UNBIND will force unbind the specified
 * range from device page table without waiting for any GPU job to complete.
 * It is UMDs responsibility to ensure the mapping is no longer in use before
 * calling VM_UNBIND.
 *
 * If the specified mapping is not found, the ioctl will simply return without
 * any error.
 *
 * VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
 * are not ordered. Furthermore, parts of the VM_UNBIND operation can be done
 * asynchronously, if valid @fence is specified.
 */
struct drm_i915_gem_vm_unbind {
	/** @vm_id: VM (address space) id to bind */
	__u32 vm_id;

	/** @rsvd: Reserved, MBZ */
	__u32 rsvd;

	/** @start: Virtual Address start to unbind */
	__u64 start;

	/** @length: Length of mapping to unbind */
	__u64 length;

	/**
	 * @flags: Currently reserved, MBZ.
	 *
	 * Note that @fence carries its own flags.
	 */
	__u64 flags;

	/**
	 * @fence: Timeline fence for unbind completion signaling.
	 *
	 * Timeline fence is of format struct drm_i915_gem_timeline_fence.
	 *
	 * It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
	 * is invalid, and an error will be returned.
	 *
	 * If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
	 * is not requested and unbinding is completed synchronously.
	 */
	struct drm_i915_gem_timeline_fence fence;

	/**
	 * @extensions: Zero-terminated chain of extensions.
	 *
	 * For future extensions. See struct i915_user_extension.
	 */
	__u64 extensions;
};

/**
 * struct drm_i915_gem_execbuffer3 - Structure for DRM_I915_GEM_EXECBUFFER3
 * ioctl.
 *
 * DRM_I915_GEM_EXECBUFFER3 ioctl only works in VM_BIND mode and VM_BIND mode
 * only works with this ioctl for submission.
 * See I915_VM_CREATE_FLAGS_USE_VM_BIND.
 */
struct drm_i915_gem_execbuffer3 {
	/**
	 * @ctx_id: Context id
	 *
	 * Only contexts with user engine map are allowed.
	 */
	__u32 ctx_id;

	/**
	 * @engine_idx: Engine index
	 *
	 * An index in the user engine map of the context specified by @ctx_id.
	 */
	__u32 engine_idx;

	/**
	 * @batch_address: Batch gpu virtual address/es.
	 *
	 * For normal submission, it is the gpu virtual address of the batch
	 * buffer. For parallel submission, it is a pointer to an array of
	 * batch buffer gpu virtual addresses with array size equal to the
	 * number of (parallel) engines involved in that submission (See
	 * struct i915_context_engines_parallel_submit).
	 */
	__u64 batch_address;

	/** @flags: Currently reserved, MBZ */
	__u64 flags;

	/** @rsvd1: Reserved, MBZ */
	__u32 rsvd1;

	/** @fence_count: Number of fences in @timeline_fences array. */
	__u32 fence_count;

	/**
	 * @timeline_fences: Pointer to an array of timeline fences.
	 *
	 * Timeline fences are of format struct drm_i915_gem_timeline_fence.
	 */
	__u64 timeline_fences;

	/** @rsvd2: Reserved, MBZ */
	__u64 rsvd2;

	/**
	 * @extensions: Zero-terminated chain of extensions.
	 *
	 * For future extensions. See struct i915_user_extension.
	 */
	__u64 extensions;
};

/**
 * struct drm_i915_gem_create_ext_vm_private - Extension to make the object
 * private to the specified VM.
 *
 * See struct drm_i915_gem_create_ext.
 */
struct drm_i915_gem_create_ext_vm_private {
#define I915_GEM_CREATE_EXT_VM_PRIVATE		2
	/** @base: Extension link. See struct i915_user_extension. */
	struct i915_user_extension base;

	/** @vm_id: Id of the VM to which the object is private */
	__u32 vm_id;
};


code:
==========================================
I915 VM_BIND feature design and use cases
==========================================

VM_BIND feature
================
DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
objects (BOs) or sections of a BOs at specified GPU virtual addresses on a
specified address space (VM). These mappings (also referred to as persistent
mappings) will be persistent across multiple GPU submissions (execbuf calls)
issued by the UMD, without user having to provide a list of all required
mappings during each submission (as required by older execbuf mode).

The VM_BIND/UNBIND calls allow UMDs to request a timeline out fence for
signaling the completion of bind/unbind operation.

VM_BIND feature is advertised to user via I915_PARAM_VM_BIND_VERSION.
User has to opt-in for VM_BIND mode of binding for an address space (VM)
during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.

VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently are
not ordered. Furthermore, parts of the VM_BIND/UNBIND operations can be done
asynchronously, when valid out fence is specified.

VM_BIND features include:

* Multiple Virtual Address (VA) mappings can map to the same physical pages
  of an object (aliasing).
* VA mapping can map to a partial section of the BO (partial binding).
* Support capture of persistent mappings in the dump upon GPU error.
* Support for userptr gem objects (no special uapi is required for this).

TLB flush consideration
------------------------
The i915 driver flushes the TLB for each submission and when an object's
pages are released. The VM_BIND/UNBIND operation will not do any additional
TLB flush. Any VM_BIND mapping added will be in the working set for subsequent
submissions on that VM and will not be in the working set for currently running
batches (which would require additional TLB flushes, which is not supported).

Execbuf ioctl in VM_BIND mode
-------------------------------
A VM in VM_BIND mode will not support older execbuf mode of binding.
The execbuf ioctl handling in VM_BIND mode differs significantly from the
older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2).
Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See
struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any
execlist. Hence, no support for implicit sync. It is expected that the below
work will be able to support requirements of object dependency setting in all
use cases:

"dma-buf: Add an API for exporting sync files"
(https://lwn.net/Articles/859290/)

The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
works with execbuf3 ioctl for submission. All BOs mapped on that VM (through
VM_BIND call) at the time of execbuf3 call are deemed required for that
submission.

The execbuf3 ioctl directly specifies the batch addresses instead of as
object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
support many of the older features like in/out/submit fences, fence array,
default gem context and many more (See struct drm_i915_gem_execbuffer3).

In VM_BIND mode, VA allocation is completely managed by the user instead of
the i915 driver. Hence all VA assignment, eviction are not applicable in
VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not
be using the i915_vma active reference tracking. It will instead use dma-resv
object for that (See `VM_BIND dma_resv usage`_).

So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA
evictions, vma lookup table, implicit sync, vma active reference tracking etc.,
are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling
should be in a separate file and only functionalities common to these ioctls
can be the shared code where possible.

VM_PRIVATE objects
-------------------
By default, BOs can be mapped on multiple VMs and can also be dma-buf
exported. Hence these BOs are referred to as Shared BOs.
During each execbuf submission, the request fence must be added to the
dma-resv fence list of all shared BOs mapped on the VM.

VM_BIND feature introduces an optimization where user can create BO which
is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during
BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on
the VM they are private to and can't be dma-buf exported.
All private BOs of a VM share the dma-resv object. Hence during each execbuf
submission, they need only one dma-resv fence list updated. Thus, the fast
path (where required mappings are already bound) submission latency is O(1)
w.r.t the number of VM private BOs.

VM_BIND locking hirarchy
-------------------------
The locking design here supports the older (execlist based) execbuf mode, the
newer VM_BIND mode, the VM_BIND mode with GPU page faults and possible future
system allocator support (See `Shared Virtual Memory (SVM) support`_).
The older execbuf mode and the newer VM_BIND mode without page faults manages
residency of backing storage using dma_fence. The VM_BIND mode with page faults
and the system allocator support do not use any dma_fence at all.

VM_BIND locking order is as below.

1) Lock-A: A vm_bind mutex will protect vm_bind lists. This lock is taken in
   vm_bind/vm_unbind ioctl calls, in the execbuf path and while releasing the
   mapping.

   In future, when GPU page faults are supported, we can potentially use a
   rwsem instead, so that multiple page fault handlers can take the read side
   lock to lookup the mapping and hence can run in parallel.
   The older execbuf mode of binding do not need this lock.

2) Lock-B: The object's dma-resv lock will protect i915_vma state and needs to
   be held while binding/unbinding a vma in the async worker and while updating
   dma-resv fence list of an object. Note that private BOs of a VM will all
   share a dma-resv object.

   The future system allocator support will use the HMM prescribed locking
   instead.

3) Lock-C: Spinlock/s to protect some of the VM's lists like the list of
   invalidated vmas (due to eviction and userptr invalidation) etc.

When GPU page faults are supported, the execbuf path do not take any of these
locks. There we will simply smash the new batch buffer address into the ring and
then tell the scheduler run that. The lock taking only happens from the page
fault handler, where we take lock-A in read mode, whichever lock-B we need to
find the backing storage (dma_resv lock for gem objects, and hmm/core mm for
system allocator) and some additional locks (lock-D) for taking care of page
table races. Page fault mode should not need to ever manipulate the vm lists,
so won't ever need lock-C.

VM_BIND LRU handling
---------------------
We need to ensure VM_BIND mapped objects are properly LRU tagged to avoid
performance degradation. We will also need support for bulk LRU movement of
VM_BIND objects to avoid additional latencies in execbuf path.

The page table pages are similar to VM_BIND mapped objects (See
`Evictable page table allocations`_) and are maintained per VM and needs to
be pinned in memory when VM is made active (ie., upon an execbuf call with
that VM). So, bulk LRU movement of page table pages is also needed.

VM_BIND dma_resv usage
-----------------------
Fences needs to be added to all VM_BIND mapped objects. During each execbuf
submission, they are added with DMA_RESV_USAGE_BOOKKEEP usage to prevent
over sync (See enum dma_resv_usage). One can override it with either
DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE usage during explicit object
dependency setting.

Note that DRM_I915_GEM_WAIT and DRM_I915_GEM_BUSY ioctls do not check for
DMA_RESV_USAGE_BOOKKEEP usage and hence should not be used for end of batch
check. Instead, the execbuf3 out fence should be used for end of batch check
(See struct drm_i915_gem_execbuffer3).

Also, in VM_BIND mode, use dma-resv apis for determining object activeness
(See dma_resv_test_signaled() and dma_resv_wait_timeout()) and do not use the
older i915_vma active reference tracking which is deprecated. This should be
easier to get it working with the current TTM backend.

Mesa use case
--------------
VM_BIND can potentially reduce the CPU overhead in Mesa (both Vulkan and Iris),
hence improving performance of CPU-bound applications. It also allows us to
implement Vulkan's Sparse Resources. With increasing GPU hardware performance,
reducing CPU overhead becomes more impactful.

Other VM_BIND use cases
========================

Long running Compute contexts
------------------------------
Usage of dma-fence expects that they complete in reasonable amount of time.
Compute on the other hand can be long running. Hence it is appropriate for
compute to use user/memory fence (See `User/Memory Fence`_) and dma-fence usage
must be limited to in-kernel consumption only.

Where GPU page faults are not available, kernel driver upon buffer invalidation
will initiate a suspend (preemption) of long running context, finish the
invalidation, revalidate the BO and then resume the compute context. This is
done by having a per-context preempt fence which is enabled when someone tries
to wait on it and triggers the context preemption.

User/Memory Fence
~~~~~~~~~~~~~~~~~~
User/Memory fence is a <address, value> pair. To signal the user fence, the
specified value will be written at the specified virtual address and wakeup the
waiting process. User fence can be signaled either by the GPU or kernel async
worker (like upon bind completion). User can wait on a user fence with a new
user fence wait ioctl.

Here is some prior work on this:
https://patchwork.freedesktop.org/patch/349417/

Low Latency Submission
~~~~~~~~~~~~~~~~~~~~~~~
Allows compute UMD to directly submit GPU jobs instead of through execbuf
ioctl. This is made possible by VM_BIND is not being synchronized against
execbuf. VM_BIND allows bind/unbind of mappings required for the directly
submitted jobs.

Debugger
---------
With debug event interface user space process (debugger) is able to keep track
of and act upon resources created by another process (debugged) and attached
to GPU via vm_bind interface.

GPU page faults
----------------
GPU page faults when supported (in future), will only be supported in the
VM_BIND mode. While both the older execbuf mode and the newer VM_BIND mode of
binding will require using dma-fence to ensure residency, the GPU page faults
mode when supported, will not use any dma-fence as residency is purely managed
by installing and removing/invalidating page table entries.

Page level hints settings
--------------------------
VM_BIND allows any hints setting per mapping instead of per BO. Possible hints
include placement and atomicity. Sub-BO level placement hint will be even more
relevant with upcoming GPU on-demand page fault support.

Page level Cache/CLOS settings
-------------------------------
VM_BIND allows cache/CLOS settings per mapping instead of per BO.

Evictable page table allocations
---------------------------------
Make pagetable allocations evictable and manage them similar to VM_BIND
mapped objects. Page table pages are similar to persistent mappings of a
VM (difference here are that the page table pages will not have an i915_vma
structure and after swapping pages back in, parent page link needs to be
updated).

Shared Virtual Memory (SVM) support
------------------------------------
VM_BIND interface can be used to map system memory directly (without gem BO
abstraction) using the HMM interface. SVM is only supported with GPU page
faults enabled.

VM_BIND UAPI
=============

.. kernel-doc:: Documentation/gpu/rfc/i915_vm_bind.h


code:
===============
GPU RFC Section
===============

For complex work, especially new uapi, it is often good to nail the high level
design issues before getting lost in the code details. This section is meant to
host such documentation:

* Each RFC should be a section in this file, explaining the goal and main design
  considerations. Especially for uapi make sure you Cc: all relevant project
  mailing lists and involved people outside of dri-devel.

* For uapi structures add a file to this directory with and then pull the
  kerneldoc in like with real uapi headers.

* Once the code has landed move all the documentation to the right places in
  the main core, helper or driver sections.

.. toctree::

    i915_gem_lmem.rst

.. toctree::

    i915_scheduler.rst

.. toctree::

    i915_small_bar.rst

.. toctree::

    i915_vm_bind.rst