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

=====================
Intel North Mux-Agent
=====================

Introduction
============

North Mux-Agent is a function of the Intel PMC firmware that is supported on
most Intel based platforms that have the PMC microcontroller. It's used for
configuring the various USB Multiplexer/DeMultiplexers on the system. The
platforms that allow the mux-agent to be configured from the operating system
have an ACPI device object (node) with HID "INTC105C" that represents it.

The North Mux-Agent (aka. Intel PMC Mux Control, or just mux-agent) driver
communicates with the PMC microcontroller by using the PMC IPC method
(drivers/platform/x86/intel_scu_ipc.c). The driver registers with the USB Type-C
Mux Class which allows the USB Type-C Controller and Interface drivers to
configure the cable plug orientation and mode (with Alternate Modes). The driver
also registers with the USB Role Class in order to support both USB Host and
Device modes. The driver is located here: drivers/usb/typec/mux/intel_pmc_mux.c.

Port nodes
==========

General
-------

For every USB Type-C connector under the mux-agent control on the system, there
is a separate child node under the PMC mux-agent device node. Those nodes do not
represent the actual connectors, but instead the "channels" in the mux-agent
that are associated with the connectors::

	Scope (_SB.PCI0.PMC.MUX)
	{
	    Device (CH0)
	    {
		Name (_ADR, 0)
	    }

	    Device (CH1)
	    {
		Name (_ADR, 1)
	    }
	}

_PLD (Physical Location of Device)
----------------------------------

The optional _PLD object can be used with the port (the channel) nodes. If _PLD
is supplied, it should match the connector node _PLD::

	Scope (_SB.PCI0.PMC.MUX)
	{
	    Device (CH0)
	    {
		Name (_ADR, 0)
	        Method (_PLD, 0, NotSerialized)
                {
		    /* Consider this as pseudocode. */
		    Return (\_SB.USBC.CON0._PLD())
		}
	    }
	}

Mux-agent specific _DSD Device Properties
-----------------------------------------

Port Numbers
~~~~~~~~~~~~

In order to configure the muxes behind a USB Type-C connector, the PMC firmware
needs to know the USB2 port and the USB3 port that is associated with the
connector. The driver extracts the correct port numbers by reading specific _DSD
device properties named "usb2-port-number" and "usb3-port-number". These
properties have integer value that means the port index. The port index number
is 1's based, and value 0 is illegal. The driver uses the numbers extracted from
these device properties as-is when sending the mux-agent specific messages to
the PMC::

	Name (_DSD, Package () {
	    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
	    Package() {
	        Package () {"usb2-port-number", 6},
	        Package () {"usb3-port-number", 3},
	    },
	})

Orientation
~~~~~~~~~~~

Depending on the platform, the data and SBU lines coming from the connector may
be "fixed" from the mux-agent's point of view, which means the mux-agent driver
should not configure them according to the cable plug orientation. This can
happen for example if a retimer on the platform handles the cable plug
orientation. The driver uses a specific device properties "sbu-orientation"
(SBU) and "hsl-orientation" (data) to know if those lines are "fixed", and to
which orientation. The value that these properties have is a string value, and
it can be one that is defined for the USB Type-C connector orientation: "normal"
or "reversed"::

	Name (_DSD, Package () {
	    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
	    Package() {
	        Package () {"sbu-orientation", "normal"},
	        Package () {"hsl-orientation", "normal"},
	    },
	})

Example ASL
===========

The following ASL is an example that shows the mux-agent node, and two
connectors under its control::

	Scope (_SB.PCI0.PMC)
	{
	    Device (MUX)
	    {
	        Name (_HID, "INTC105C")

	        Device (CH0)
	        {
	            Name (_ADR, 0)

	            Name (_DSD, Package () {
	                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
	                Package() {
	                    Package () {"usb2-port-number", 6},
	                    Package () {"usb3-port-number", 3},
	                    Package () {"sbu-orientation", "normal"},
	                    Package () {"hsl-orientation", "normal"},
	                },
	            })
	        }

	        Device (CH1)
	        {
	            Name (_ADR, 1)

	            Name (_DSD, Package () {
	                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
	                Package() {
	                    Package () {"usb2-port-number", 5},
	                    Package () {"usb3-port-number", 2},
	                    Package () {"sbu-orientation", "normal"},
	                    Package () {"hsl-orientation", "normal"},
	                },
	            })
	        }
	    }
	}


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

===========================
Low Power Idle Table (LPIT)
===========================

To enumerate platform Low Power Idle states, Intel platforms are using
“Low Power Idle Table” (LPIT). More details about this table can be
downloaded from:
https://www.uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf

Residencies for each low power state can be read via FFH
(Function fixed hardware) or a memory mapped interface.

On platforms supporting S0ix sleep states, there can be two types of
residencies:

  - CPU PKG C10 (Read via FFH interface)
  - Platform Controller Hub (PCH) SLP_S0 (Read via memory mapped interface)

The following attributes are added dynamically to the cpuidle
sysfs attribute group::

  /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
  /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us

The "low_power_idle_cpu_residency_us" attribute shows time spent
by the CPU package in PKG C10

The "low_power_idle_system_residency_us" attribute shows SLP_S0
residency, or system time spent with the SLP_S0# signal asserted.
This is the lowest possible system power state, achieved only when CPU is in
PKG C10 and all functional blocks in PCH are in a low power state.

repo_name: angery/linux


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

=======================================
Linux ACPI Custom Control Method How To
=======================================

:Author: Zhang Rui <rui.zhang@intel.com>

Linux supports customizing ACPI control methods at runtime.

Users can use this to:

1. override an existing method which may not work correctly,
   or just for debugging purposes.
2. insert a completely new method in order to create a missing
   method such as _OFF, _ON, _STA, _INI, etc.

For these cases, it is far simpler to dynamically install a single
control method rather than override the entire DSDT, because kernel
rebuild/reboot is not needed and test result can be got in minutes.

.. note::

  - Only ACPI METHOD can be overridden, any other object types like
    "Device", "OperationRegion", are not recognized. Methods
    declared inside scope operators are also not supported.

  - The same ACPI control method can be overridden for many times,
    and it's always the latest one that used by Linux/kernel.

  - To get the ACPI debug object output (Store (AAAA, Debug)),
    please run::

      echo 1 > /sys/module/acpi/parameters/aml_debug_output

1. override an existing method
==============================
a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,
   just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat"
b) disassemble the table by running "iasl -d dsdt.dat".
c) rewrite the ASL code of the method and save it in a new file,
d) package the new file (psr.asl) to an ACPI table format.
   Here is an example of a customized \_SB._AC._PSR method::

      DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715)
      {
         Method (\_SB_.AC._PSR, 0, NotSerialized)
         {
            Store ("In AC _PSR", Debug)
            Return (ACON)
         }
      }

   Note that the full pathname of the method in ACPI namespace
   should be used.
e) assemble the file to generate the AML code of the method.
   e.g. "iasl -vw 6084 psr.asl" (psr.aml is generated as a result)
   If parameter "-vw 6084" is not supported by your iASL compiler,
   please try a newer version.
f) mount debugfs by "mount -t debugfs none /sys/kernel/debug"
g) override the old method via the debugfs by running
   "cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method"

2. insert a new method
======================
This is easier than overriding an existing method.
We just need to create the ASL code of the method we want to
insert and then follow the step c) ~ g) in section 1.

3. undo your changes
====================
The "undo" operation is not supported for a new inserted method
right now, i.e. we can not remove a method currently.
For an overridden method, in order to undo your changes, please
save a copy of the method original ASL code in step c) section 1,
and redo step c) ~ g) to override the method with the original one.

.. note:: We can use a kernel with multiple custom ACPI method running,
   But each individual write to debugfs can implement a SINGLE
   method override. i.e. if we want to insert/override multiple
   ACPI methods, we need to redo step c) ~ g) for multiple times.

.. note:: Be aware that root can mis-use this driver to modify arbitrary
   memory and gain additional rights, if root's privileges got
   restricted (for example if root is not allowed to load additional
   modules after boot).


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

=====================
ACPICA Trace Facility
=====================

:Copyright: |copy| 2015, Intel Corporation
:Author: Lv Zheng <lv.zheng@intel.com>

Abstract
========
This document describes the functions and the interfaces of the
method tracing facility.

Functionalities and usage examples
==================================

ACPICA provides method tracing capability. And two functions are
currently implemented using this capability.

Log reducer
-----------

ACPICA subsystem provides debugging outputs when CONFIG_ACPI_DEBUG is
enabled. The debugging messages which are deployed via
ACPI_DEBUG_PRINT() macro can be reduced at 2 levels - per-component
level (known as debug layer, configured via
/sys/module/acpi/parameters/debug_layer) and per-type level (known as
debug level, configured via /sys/module/acpi/parameters/debug_level).

But when the particular layer/level is applied to the control method
evaluations, the quantity of the debugging outputs may still be too
large to be put into the kernel log buffer. The idea thus is worked out
to only enable the particular debug layer/level (normally more detailed)
logs when the control method evaluation is started, and disable the
detailed logging when the control method evaluation is stopped.

The following command examples illustrate the usage of the "log reducer"
functionality:

a. Filter out the debug layer/level matched logs when control methods
   are being evaluated::

      # cd /sys/module/acpi/parameters
      # echo "0xXXXXXXXX" > trace_debug_layer
      # echo "0xYYYYYYYY" > trace_debug_level
      # echo "enable" > trace_state

b. Filter out the debug layer/level matched logs when the specified
   control method is being evaluated::

      # cd /sys/module/acpi/parameters
      # echo "0xXXXXXXXX" > trace_debug_layer
      # echo "0xYYYYYYYY" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "method" > /sys/module/acpi/parameters/trace_state

c. Filter out the debug layer/level matched logs when the specified
   control method is being evaluated for the first time::

      # cd /sys/module/acpi/parameters
      # echo "0xXXXXXXXX" > trace_debug_layer
      # echo "0xYYYYYYYY" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "method-once" > /sys/module/acpi/parameters/trace_state

Where:
   0xXXXXXXXX/0xYYYYYYYY
     Refer to Documentation/firmware-guide/acpi/debug.rst for possible debug layer/level
     masking values.
   \PPPP.AAAA.TTTT.HHHH
     Full path of a control method that can be found in the ACPI namespace.
     It needn't be an entry of a control method evaluation.

AML tracer
----------

There are special log entries added by the method tracing facility at
the "trace points" the AML interpreter starts/stops to execute a control
method, or an AML opcode. Note that the format of the log entries are
subject to change::

   [    0.186427]   exdebug-0398 ex_trace_point        : Method Begin [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.
   [    0.186630]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905c88:If] execution.
   [    0.186820]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905cc0:LEqual] execution.
   [    0.187010]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905a20:-NamePath-] execution.
   [    0.187214]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905a20:-NamePath-] execution.
   [    0.187407]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905f60:One] execution.
   [    0.187594]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905f60:One] execution.
   [    0.187789]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905cc0:LEqual] execution.
   [    0.187980]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905cc0:Return] execution.
   [    0.188146]   exdebug-0398 ex_trace_point        : Opcode Begin [0xf5905f60:One] execution.
   [    0.188334]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905f60:One] execution.
   [    0.188524]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905cc0:Return] execution.
   [    0.188712]   exdebug-0398 ex_trace_point        : Opcode End [0xf5905c88:If] execution.
   [    0.188903]   exdebug-0398 ex_trace_point        : Method End [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.

Developers can utilize these special log entries to track the AML
interpretation, thus can aid issue debugging and performance tuning. Note
that, as the "AML tracer" logs are implemented via ACPI_DEBUG_PRINT()
macro, CONFIG_ACPI_DEBUG is also required to be enabled for enabling
"AML tracer" logs.

The following command examples illustrate the usage of the "AML tracer"
functionality:

a. Filter out the method start/stop "AML tracer" logs when control
   methods are being evaluated::

      # cd /sys/module/acpi/parameters
      # echo "0x80" > trace_debug_layer
      # echo "0x10" > trace_debug_level
      # echo "enable" > trace_state

b. Filter out the method start/stop "AML tracer" when the specified
   control method is being evaluated::

      # cd /sys/module/acpi/parameters
      # echo "0x80" > trace_debug_layer
      # echo "0x10" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "method" > trace_state

c. Filter out the method start/stop "AML tracer" logs when the specified
   control method is being evaluated for the first time::

      # cd /sys/module/acpi/parameters
      # echo "0x80" > trace_debug_layer
      # echo "0x10" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "method-once" > trace_state

d. Filter out the method/opcode start/stop "AML tracer" when the
   specified control method is being evaluated::

      # cd /sys/module/acpi/parameters
      # echo "0x80" > trace_debug_layer
      # echo "0x10" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "opcode" > trace_state

e. Filter out the method/opcode start/stop "AML tracer" when the
   specified control method is being evaluated for the first time::

      # cd /sys/module/acpi/parameters
      # echo "0x80" > trace_debug_layer
      # echo "0x10" > trace_debug_level
      # echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
      # echo "opcode-opcode" > trace_state

Note that all above method tracing facility related module parameters can
be used as the boot parameters, for example::

   acpi.trace_debug_layer=0x80 acpi.trace_debug_level=0x10 \
   acpi.trace_method_name=\_SB.LID0._LID acpi.trace_state=opcode-once

Interface descriptions
======================

All method tracing functions can be configured via ACPI module
parameters that are accessible at /sys/module/acpi/parameters/:

trace_method_name
  The full path of the AML method that the user wants to trace.

  Note that the full path shouldn't contain the trailing "_"s in its
  name segments but may contain "\" to form an absolute path.

trace_debug_layer
  The temporary debug_layer used when the tracing feature is enabled.

  Using ACPI_EXECUTER (0x80) by default, which is the debug_layer
  used to match all "AML tracer" logs.

trace_debug_level
  The temporary debug_level used when the tracing feature is enabled.

  Using ACPI_LV_TRACE_POINT (0x10) by default, which is the
  debug_level used to match all "AML tracer" logs.

trace_state
  The status of the tracing feature.

  Users can enable/disable this debug tracing feature by executing
  the following command::

   # echo string > /sys/module/acpi/parameters/trace_state

Where "string" should be one of the following:

"disable"
  Disable the method tracing feature.

"enable"
  Enable the method tracing feature.

  ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
  during any method execution will be logged.

"method"
  Enable the method tracing feature.

  ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
  during method execution of "trace_method_name" will be logged.

"method-once"
  Enable the method tracing feature.

  ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
  during method execution of "trace_method_name" will be logged only once.

"opcode"
  Enable the method tracing feature.

  ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
  during method/opcode execution of "trace_method_name" will be logged.

"opcode-once"
  Enable the method tracing feature.

  ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
  during method/opcode execution of "trace_method_name" will be logged only
  once.

Note that, the difference between the "enable" and other feature
enabling options are:

1. When "enable" is specified, since
   "trace_debug_layer/trace_debug_level" shall apply to all control
   method evaluations, after configuring "trace_state" to "enable",
   "trace_method_name" will be reset to NULL.
2. When "method/opcode" is specified, if
   "trace_method_name" is NULL when "trace_state" is configured to
   these options, the "trace_debug_layer/trace_debug_level" will
   apply to all control method evaluations.


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

===================================================
ACPI Device Tree - Representation of ACPI Namespace
===================================================

:Copyright: |copy| 2013, Intel Corporation

:Author: Lv Zheng <lv.zheng@intel.com>

:Credit:   Thanks for the help from Zhang Rui <rui.zhang@intel.com> and
           Rafael J.Wysocki <rafael.j.wysocki@intel.com>.

Abstract
========
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon
receiving ACPI hotplug notification events.  For each device object
in this hierarchy there is a corresponding symbolic link in the
/sys/bus/acpi/devices.

This document illustrates the structure of the ACPI device tree.

ACPI Definition Blocks
======================

The ACPI firmware sets up RSDP (Root System Description Pointer) in the
system memory address space pointing to the XSDT (Extended System
Description Table).  The XSDT always points to the FADT (Fixed ACPI
Description Table) using its first entry, the data within the FADT
includes various fixed-length entries that describe fixed ACPI features
of the hardware.  The FADT contains a pointer to the DSDT
(Differentiated System Descripition Table).  The XSDT also contains
entries pointing to possibly multiple SSDTs (Secondary System
Description Table).

The DSDT and SSDT data is organized in data structures called definition
blocks that contain definitions of various objects, including ACPI
control methods, encoded in AML (ACPI Machine Language).  The data block
of the DSDT along with the contents of SSDTs represents a hierarchical
data structure called the ACPI namespace whose topology reflects the
structure of the underlying hardware platform.

The relationships between ACPI System Definition Tables described above
are illustrated in the following diagram::

   +---------+    +-------+    +--------+    +------------------------+
   |  RSDP   | +->| XSDT  | +->|  FADT  |    |  +-------------------+ |
   +---------+ |  +-------+ |  +--------+  +-|->|       DSDT        | |
   | Pointer | |  | Entry |-+  | ...... |  | |  +-------------------+ |
   +---------+ |  +-------+    | X_DSDT |--+ |  | Definition Blocks | |
   | Pointer |-+  | ..... |    | ...... |    |  +-------------------+ |
   +---------+    +-------+    +--------+    |  +-------------------+ |
                  | Entry |------------------|->|       SSDT        | |
                  +- - - -+                  |  +-------------------| |
                  | Entry | - - - - - - - -+ |  | Definition Blocks | |
                  +- - - -+                | |  +-------------------+ |
                                           | |  +- - - - - - - - - -+ |
                                           +-|->|       SSDT        | |
                                             |  +-------------------+ |
                                             |  | Definition Blocks | |
                                             |  +- - - - - - - - - -+ |
                                             +------------------------+
                                                          |
                                             OSPM Loading |
                                                         \|/
                                                   +----------------+
                                                   | ACPI Namespace |
                                                   +----------------+

                  Figure 1. ACPI Definition Blocks

.. note:: RSDP can also contain a pointer to the RSDT (Root System
   Description Table).  Platforms provide RSDT to enable
   compatibility with ACPI 1.0 operating systems.  The OS is expected
   to use XSDT, if present.

Example ACPI Namespace
======================

All definition blocks are loaded into a single namespace.  The namespace
is a hierarchy of objects identified by names and paths.
The following naming conventions apply to object names in the ACPI
namespace:

   1. All names are 32 bits long.
   2. The first byte of a name must be one of 'A' - 'Z', '_'.
   3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
      - '9', '_'.
   4. Names starting with '_' are reserved by the ACPI specification.
   5. The '\' symbol represents the root of the namespace (i.e. names
      prepended with '\' are relative to the namespace root).
   6. The '^' symbol represents the parent of the current namespace node
      (i.e. names prepended with '^' are relative to the parent of the
      current namespace node).

The figure below shows an example ACPI namespace::

   +------+
   | \    |                     Root
   +------+
     |
     | +------+
     +-| _PR  |                 Scope(_PR): the processor namespace
     | +------+
     |   |
     |   | +------+
     |   +-| CPU0 |             Processor(CPU0): the first processor
     |     +------+
     |
     | +------+
     +-| _SB  |                 Scope(_SB): the system bus namespace
     | +------+
     |   |
     |   | +------+
     |   +-| LID0 |             Device(LID0); the lid device
     |   | +------+
     |   |   |
     |   |   | +------+
     |   |   +-| _HID |         Name(_HID, "PNP0C0D"): the hardware ID
     |   |   | +------+
     |   |   |
     |   |   | +------+
     |   |   +-| _STA |         Method(_STA): the status control method
     |   |     +------+
     |   |
     |   | +------+
     |   +-| PCI0 |             Device(PCI0); the PCI root bridge
     |     +------+
     |       |
     |       | +------+
     |       +-| _HID |         Name(_HID, "PNP0A08"): the hardware ID
     |       | +------+
     |       |
     |       | +------+
     |       +-| _CID |         Name(_CID, "PNP0A03"): the compatible ID
     |       | +------+
     |       |
     |       | +------+
     |       +-| RP03 |         Scope(RP03): the PCI0 power scope
     |       | +------+
     |       |   |
     |       |   | +------+
     |       |   +-| PXP3 |     PowerResource(PXP3): the PCI0 power resource
     |       |     +------+
     |       |
     |       | +------+
     |       +-| GFX0 |         Device(GFX0): the graphics adapter
     |         +------+
     |           |
     |           | +------+
     |           +-| _ADR |     Name(_ADR, 0x00020000): the PCI bus address
     |           | +------+
     |           |
     |           | +------+
     |           +-| DD01 |     Device(DD01): the LCD output device
     |             +------+
     |               |
     |               | +------+
     |               +-| _BCL | Method(_BCL): the backlight control method
     |                 +------+
     |
     | +------+
     +-| _TZ  |                 Scope(_TZ): the thermal zone namespace
     | +------+
     |   |
     |   | +------+
     |   +-| FN00 |             PowerResource(FN00): the FAN0 power resource
     |   | +------+
     |   |
     |   | +------+
     |   +-| FAN0 |             Device(FAN0): the FAN0 cooling device
     |   | +------+
     |   |   |
     |   |   | +------+
     |   |   +-| _HID |         Name(_HID, "PNP0A0B"): the hardware ID
     |   |     +------+
     |   |
     |   | +------+
     |   +-| TZ00 |             ThermalZone(TZ00); the FAN thermal zone
     |     +------+
     |
     | +------+
     +-| _GPE |                 Scope(_GPE): the GPE namespace
       +------+

                     Figure 2. Example ACPI Namespace

Linux ACPI Device Objects
=========================

The Linux kernel's core ACPI subsystem creates struct acpi_device
objects for ACPI namespace objects representing devices, power resources
processors, thermal zones.  Those objects are exported to user space via
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00.  The
format of their names is <bus_id:instance>, where 'bus_id' refers to the
ACPI namespace representation of the given object and 'instance' is used
for distinguishing different object of the same 'bus_id' (it is
two-digit decimal representation of an unsigned integer).

The value of 'bus_id' depends on the type of the object whose name it is
part of as listed in the table below::

                +---+-----------------+-------+----------+
                |   | Object/Feature  | Table | bus_id   |
                +---+-----------------+-------+----------+
                | N | Root            | xSDT  | LNXSYSTM |
                +---+-----------------+-------+----------+
                | N | Device          | xSDT  | _HID     |
                +---+-----------------+-------+----------+
                | N | Processor       | xSDT  | LNXCPU   |
                +---+-----------------+-------+----------+
                | N | ThermalZone     | xSDT  | LNXTHERM |
                +---+-----------------+-------+----------+
                | N | PowerResource   | xSDT  | LNXPOWER |
                +---+-----------------+-------+----------+
                | N | Other Devices   | xSDT  | device   |
                +---+-----------------+-------+----------+
                | F | PWR_BUTTON      | FADT  | LNXPWRBN |
                +---+-----------------+-------+----------+
                | F | SLP_BUTTON      | FADT  | LNXSLPBN |
                +---+-----------------+-------+----------+
                | M | Video Extension | xSDT  | LNXVIDEO |
                +---+-----------------+-------+----------+
                | M | ATA Controller  | xSDT  | LNXIOBAY |
                +---+-----------------+-------+----------+
                | M | Docking Station | xSDT  | LNXDOCK  |
                +---+-----------------+-------+----------+

                 Table 1. ACPI Namespace Objects Mapping

The following rules apply when creating struct acpi_device objects on
the basis of the contents of ACPI System Description Tables (as
indicated by the letter in the first column and the notation in the
second column of the table above):

   N:
      The object's source is an ACPI namespace node (as indicated by the
      named object's type in the second column).  In that case the object's
      directory in sysfs will contain the 'path' attribute whose value is
      the full path to the node from the namespace root.
   F:
      The struct acpi_device object is created for a fixed hardware
      feature (as indicated by the fixed feature flag's name in the second
      column), so its sysfs directory will not contain the 'path'
      attribute.
   M:
      The struct acpi_device object is created for an ACPI namespace node
      with specific control methods (as indicated by the ACPI defined
      device's type in the second column).  The 'path' attribute containing
      its namespace path will be present in its sysfs directory.  For
      example, if the _BCL method is present for an ACPI namespace node, a
      struct acpi_device object with LNXVIDEO 'bus_id' will be created for
      it.

The third column of the above table indicates which ACPI System
Description Tables contain information used for the creation of the
struct acpi_device objects represented by the given row (xSDT means DSDT
or SSDT).

The fourth column of the above table indicates the 'bus_id' generation
rule of the struct acpi_device object:

   _HID:
      _HID in the last column of the table means that the object's bus_id
      is derived from the _HID/_CID identification objects present under
      the corresponding ACPI namespace node. The object's sysfs directory
      will then contain the 'hid' and 'modalias' attributes that can be
      used to retrieve the _HID and _CIDs of that object.
   LNXxxxxx:
      The 'modalias' attribute is also present for struct acpi_device
      objects having bus_id of the "LNXxxxxx" form (pseudo devices), in
      which cases it contains the bus_id string itself.
   device:
      'device' in the last column of the table indicates that the object's
      bus_id cannot be determined from _HID/_CID of the corresponding
      ACPI namespace node, although that object represents a device (for
      example, it may be a PCI device with _ADR defined and without _HID
      or _CID).  In that case the string 'device' will be used as the
      object's bus_id.

Linux ACPI Physical Device Glue
===============================

ACPI device (i.e. struct acpi_device) objects may be linked to other
objects in the Linux' device hierarchy that represent "physical" devices
(for example, devices on the PCI bus).  If that happens, it means that
the ACPI device object is a "companion" of a device otherwise
represented in a different way and is used (1) to provide configuration
information on that device which cannot be obtained by other means and
(2) to do specific things to the device with the help of its ACPI
control methods.  One ACPI device object may be linked this way to
multiple "physical" devices.

If an ACPI device object is linked to a "physical" device, its sysfs
directory contains the "physical_node" symbolic link to the sysfs
directory of the target device object.  In turn, the target device's
sysfs directory will then contain the "firmware_node" symbolic link to
the sysfs directory of the companion ACPI device object.
The linking mechanism relies on device identification provided by the
ACPI namespace.  For example, if there's an ACPI namespace object
representing a PCI device (i.e. a device object under an ACPI namespace
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
bus number of the parent PCI bridge is 0, the sysfs directory
representing the struct acpi_device object created for that ACPI
namespace object will contain the 'physical_node' symbolic link to the
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
corresponding PCI device.

The linking mechanism is generally bus-specific.  The core of its
implementation is located in the drivers/acpi/glue.c file, but there are
complementary parts depending on the bus types in question located
elsewhere.  For example, the PCI-specific part of it is located in
drivers/pci/pci-acpi.c.

Example Linux ACPI Device Tree
=================================

The sysfs hierarchy of struct acpi_device objects corresponding to the
example ACPI namespace illustrated in Figure 2 with the addition of
fixed PWR_BUTTON/SLP_BUTTON devices is shown below::

   +--------------+---+-----------------+
   | LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: |
   +--------------+---+-----------------+
     |
     | +-------------+-----+----------------+
     +-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: |
     | +-------------+-----+----------------+
     |
     | +-------------+-----+----------------+
     +-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: |
     | +-------------+-----+----------------+
     |
     | +-----------+------------+--------------+
     +-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: |
     | +-----------+------------+--------------+
     |
     | +-------------+-------+----------------+
     +-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: |
     | +-------------+-------+----------------+
     |   |
     |   | +- - - - - - - +- - - - - - +- - - - - - - -+
     |   +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
     |   | +- - - - - - - +- - - - - - +- - - - - - - -+
     |   |
     |   | +------------+------------+-----------------------+
     |   +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: |
     |     +------------+------------+-----------------------+
     |       |
     |       | +-----------+-----------------+-----+
     |       +-| device:00 | \_SB_.PCI0.RP03 | N/A |
     |       | +-----------+-----------------+-----+
     |       |   |
     |       |   | +-------------+----------------------+----------------+
     |       |   +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: |
     |       |     +-------------+----------------------+----------------+
     |       |
     |       | +-------------+-----------------+----------------+
     |       +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: |
     |         +-------------+-----------------+----------------+
     |           |
     |           | +-----------+-----------------+-----+
     |           +-| device:01 | \_SB_.PCI0.DD01 | N/A |
     |             +-----------+-----------------+-----+
     |
     | +-------------+-------+----------------+
     +-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: |
       +-------------+-------+----------------+
         |
         | +-------------+------------+----------------+
         +-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: |
         | +-------------+------------+----------------+
         |
         | +------------+------------+---------------+
         +-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: |
         | +------------+------------+---------------+
         |
         | +-------------+------------+----------------+
         +-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: |
           +-------------+------------+----------------+

                  Figure 3. Example Linux ACPI Device Tree

.. note:: Each node is represented as "object/path/modalias", where:

   1. 'object' is the name of the object's directory in sysfs.
   2. 'path' is the ACPI namespace path of the corresponding
      ACPI namespace object, as returned by the object's 'path'
      sysfs attribute.
   3. 'modalias' is the value of the object's 'modalias' sysfs
      attribute (as described earlier in this document).

.. note:: N/A indicates the device object does not have the 'path' or the
   'modalias' attribute.


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

========================================
Probing devices in other D states than 0
========================================

Introduction
============

In some cases it may be preferred to leave certain devices powered off for the
entire system bootup if powering on these devices has adverse side effects,
beyond just powering on the said device.

How it works
============

The _DSC (Device State for Configuration) object that evaluates to an integer
may be used to tell Linux the highest allowed D state for a device during
probe. The support for _DSC requires support from the kernel bus type if the
bus driver normally sets the device in D0 state for probe.

The downside of using _DSC is that as the device is not powered on, even if
there's a problem with the device, the driver likely probes just fine but the
first user will find out the device doesn't work, instead of a failure at probe
time. This feature should thus be used sparingly.

I²C
---

If an I²C driver indicates its support for this by setting the
I2C_DRV_ACPI_WAIVE_D0_PROBE flag in struct i2c_driver.flags field and the
_DSC object evaluates to integer higher than the D state of the device,
the device will not be powered on (put in D0 state) for probe.

D states
--------

The D states and thus also the allowed values for _DSC are listed below. Refer
to [1] for more information on device power states.

.. code-block:: text

	Number	State	Description
	0	D0	Device fully powered on
	1	D1
	2	D2
	3	D3hot
	4	D3cold	Off

References
==========

[1] https://uefi.org/specifications/ACPI/6.4/02_Definition_of_Terms/Definition_of_Terms.html#device-power-state-definitions

Example
=======

An ASL example describing an ACPI device using _DSC object to tell Operating
System the device should remain powered off during probe looks like this. Some
objects not relevant from the example point of view have been omitted.

.. code-block:: text

	Device (CAM0)
	{
		Name (_HID, "SONY319A")
		Name (_UID, Zero)
		Name (_CRS, ResourceTemplate ()
		{
			I2cSerialBus(0x0020, ControllerInitiated, 0x00061A80,
				     AddressingMode7Bit, "\\_SB.PCI0.I2C0",
				     0x00, ResourceConsumer)
		})
		Method (_DSC, 0, NotSerialized)
		{
			Return (0x4)
		}
	}


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

==========================
ACPI _OSI and _REV methods
==========================

An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
to find out what the operating system supports. Eg. If BIOS
AML code includes _OSI("XYZ"), the kernel's AML interpreter
can evaluate that method, look to see if it supports 'XYZ'
and answer YES or NO to the BIOS.

The ACPI _REV method returns the "Revision of the ACPI specification
that OSPM supports"

This document explains how and why the BIOS and Linux should use these methods.
It also explains how and why they are widely misused.

How to use _OSI
===============

Linux runs on two groups of machines -- those that are tested by the OEM
to be compatible with Linux, and those that were never tested with Linux,
but where Linux was installed to replace the original OS (Windows or OSX).

The larger group is the systems tested to run only Windows.  Not only that,
but many were tested to run with just one specific version of Windows.
So even though the BIOS may use _OSI to query what version of Windows is running,
only a single path through the BIOS has actually been tested.
Experience shows that taking untested paths through the BIOS
exposes Linux to an entire category of BIOS bugs.
For this reason, Linux _OSI defaults must continue to claim compatibility
with all versions of Windows.

But Linux isn't actually compatible with Windows, and the Linux community
has also been hurt with regressions when Linux adds the latest version of
Windows to its list of _OSI strings.  So it is possible that additional strings
will be more thoroughly vetted before shipping upstream in the future.
But it is likely that they will all eventually be added.

What should an OEM do if they want to support Linux and Windows
using the same BIOS image?  Often they need to do something different
for Linux to deal with how Linux is different from Windows.

In this case, the OEM should create custom ASL to be executed by the
Linux kernel and changes to Linux kernel drivers to execute this custom
ASL.  The easiest way to accomplish this is to introduce a device specific
method (_DSM) that is called from the Linux kernel.

In the past the kernel used to support something like:
_OSI("Linux-OEM-my_interface_name")
where 'OEM' is needed if this is an OEM-specific hook,
and 'my_interface_name' describes the hook, which could be a
quirk, a bug, or a bug-fix.

However this was discovered to be abused by other BIOS vendors to change
completely unrelated code on completely unrelated systems.  This prompted
an evaluation of all of it's uses. This uncovered that they aren't needed
for any of the original reasons. As such, the kernel will not respond to
any custom Linux-* strings by default.

That was easy.  Read on, to find out how to do it wrong.

Before _OSI, there was _OS
==========================

ACPI 1.0 specified "_OS" as an
"object that evaluates to a string that identifies the operating system."

The ACPI BIOS flow would include an evaluation of _OS, and the AML
interpreter in the kernel would return to it a string identifying the OS:

Windows 98, SE: "Microsoft Windows"
Windows ME: "Microsoft WindowsME:Millennium Edition"
Windows NT: "Microsoft Windows NT"

The idea was on a platform tasked with running multiple OS's,
the BIOS could use _OS to enable devices that an OS
might support, or enable quirks or bug workarounds
necessary to make the platform compatible with that pre-existing OS.

But _OS had fundamental problems.  First, the BIOS needed to know the name
of every possible version of the OS that would run on it, and needed to know
all the quirks of those OS's.  Certainly it would make more sense
for the BIOS to ask *specific* things of the OS, such
"do you support a specific interface", and thus in ACPI 3.0,
_OSI was born to replace _OS.

_OS was abandoned, though even today, many BIOS look for
_OS "Microsoft Windows NT", though it seems somewhat far-fetched
that anybody would install those old operating systems
over what came with the machine.

Linux answers "Microsoft Windows NT" to please that BIOS idiom.
That is the *only* viable strategy, as that is what modern Windows does,
and so doing otherwise could steer the BIOS down an untested path.

_OSI is born, and immediately misused
=====================================

With _OSI, the *BIOS* provides the string describing an interface,
and asks the OS: "YES/NO, are you compatible with this interface?"

eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
to deal with the thermal extensions made to the ACPI 3.0 specification.
An old OS that doesn't know about those extensions would answer FALSE,
and a new OS may be able to return TRUE.

For an OS-specific interface, the ACPI spec said that the BIOS and the OS
were to agree on a string of the form such as "Windows-interface_name".

But two bad things happened.  First, the Windows ecosystem used _OSI
not as designed, but as a direct replacement for _OS -- identifying
the OS version, rather than an OS supported interface.  Indeed, right
from the start, the ACPI 3.0 spec itself codified this misuse
in example code using _OSI("Windows 2001").

This misuse was adopted and continues today.

Linux had no choice but to also return TRUE to _OSI("Windows 2001")
and its successors.  To do otherwise would virtually guarantee breaking
a BIOS that has been tested only with that _OSI returning TRUE.

This strategy is problematic, as Linux is never completely compatible with
the latest version of Windows, and sometimes it takes more than a year
to iron out incompatibilities.

Not to be out-done, the Linux community made things worse by returning TRUE
to _OSI("Linux").  Doing so is even worse than the Windows misuse
of _OSI, as "Linux" does not even contain any version information.
_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
using it in untested BIOS flows.  But some OEM's used _OSI("Linux")
in tested flows to support real Linux features.  In 2009, Linux
removed _OSI("Linux"), and added a cmdline parameter to restore it
for legacy systems still needed it.  Further a BIOS_BUG warning prints
for all BIOS's that invoke it.

No BIOS should use _OSI("Linux").

The result is a strategy for Linux to maximize compatibility with
ACPI BIOS that are tested on Windows machines.  There is a real risk
of over-stating that compatibility; but the alternative has often been
catastrophic failure resulting from the BIOS taking paths that
were never validated under *any* OS.

Do not use _REV
===============

Since _OSI("Linux") went away, some BIOS writers used _REV
to support Linux and Windows differences in the same BIOS.

_REV was defined in ACPI 1.0 to return the version of ACPI
supported by the OS and the OS AML interpreter.

Modern Windows returns _REV = 2.  Linux used ACPI_CA_SUPPORT_LEVEL,
which would increment, based on the version of the spec supported.

Unfortunately, _REV was also misused.  eg. some BIOS would check
for _REV = 3, and do something for Linux, but when Linux returned
_REV = 4, that support broke.

In response to this problem, Linux returns _REV = 2 always,
from mid-2015 onward.  The ACPI specification will also be updated
to reflect that _REV is deprecated, and always returns 2.

Apple Mac and _OSI("Darwin")
============================

On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
to determine if the machine is running Apple OSX.

Like Linux's _OSI("*Windows*") strategy, Linux defaults to
answering YES to _OSI("Darwin") to enable full access
to the hardware and validated BIOS paths seen by OSX.
Just like on Windows-tested platforms, this strategy has risks.

Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
for the purpose of enabling Mac Thunderbolt support.  Further,
if the kernel noticed _OSI("Darwin") being invoked, it additionally
disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
from going down untested combinations of paths.

The Linux-3.18 change in default caused power regressions on Mac
laptops, and the 3.18 implementation did not allow changing
the default via cmdline "acpi_osi=!Darwin".  Linux-4.7 fixed
the ability to use acpi_osi=!Darwin as a workaround, and
we hope to see Mac Thunderbolt power management support in Linux-4.11.


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

=====================
ACPI video extensions
=====================

This driver implement the ACPI Extensions For Display Adapters for
integrated graphics devices on motherboard, as specified in ACPI 2.0
Specification, Appendix B, allowing to perform some basic control like
defining the video POST device, retrieving EDID information or to
setup a video output, etc.  Note that this is an ref. implementation
only.  It may or may not work for your integrated video device.

The ACPI video driver does 3 things regarding backlight control.

Export a sysfs interface for user space to control backlight level
==================================================================

If the ACPI table has a video device, and acpi_backlight=vendor kernel
command line is not present, the driver will register a backlight device
and set the required backlight operation structure for it for the sysfs
interface control. For every registered class device, there will be a
directory named acpi_videoX under /sys/class/backlight.

The backlight sysfs interface has a standard definition here:
Documentation/ABI/stable/sysfs-class-backlight.

And what ACPI video driver does is:

actual_brightness:
  on read, control method _BQC will be evaluated to
  get the brightness level the firmware thinks it is at;
bl_power:
  not implemented, will set the current brightness instead;
brightness:
  on write, control method _BCM will run to set the requested brightness level;
max_brightness:
  Derived from the _BCL package(see below);
type:
  firmware

Note that ACPI video backlight driver will always use index for
brightness, actual_brightness and max_brightness. So if we have
the following _BCL package::

	Method (_BCL, 0, NotSerialized)
	{
		Return (Package (0x0C)
		{
			0x64,
			0x32,
			0x0A,
			0x14,
			0x1E,
			0x28,
			0x32,
			0x3C,
			0x46,
			0x50,
			0x5A,
			0x64
		})
	}

The first two levels are for when laptop are on AC or on battery and are
not used by Linux currently. The remaining 10 levels are supported levels
that we can choose from. The applicable index values are from 0 (that
corresponds to the 0x0A brightness value) to 9 (that corresponds to the
0x64 brightness value) inclusive. Each of those index values is regarded
as a "brightness level" indicator. Thus from the user space perspective
the range of available brightness levels is from 0 to 9 (max_brightness)
inclusive.

Notify user space about hotkey event
====================================

There are generally two cases for hotkey event reporting:

i) For some laptops, when user presses the hotkey, a scancode will be
   generated and sent to user space through the input device created by
   the keyboard driver as a key type input event, with proper remap, the
   following key code will appear to user space::

	EV_KEY, KEY_BRIGHTNESSUP
	EV_KEY, KEY_BRIGHTNESSDOWN
	etc.

For this case, ACPI video driver does not need to do anything(actually,
it doesn't even know this happened).

ii) For some laptops, the press of the hotkey will not generate the
    scancode, instead, firmware will notify the video device ACPI node
    about the event. The event value is defined in the ACPI spec. ACPI
    video driver will generate an key type input event according to the
    notify value it received and send the event to user space through the
    input device it created:

	=====		==================
	event		keycode
	=====		==================
	0x86		KEY_BRIGHTNESSUP
	0x87		KEY_BRIGHTNESSDOWN
	etc.
	=====		==================

so this would lead to the same effect as case i) now.

Once user space tool receives this event, it can modify the backlight
level through the sysfs interface.

Change backlight level in the kernel
====================================

This works for machines covered by case ii) in Section 2. Once the driver
received a notification, it will set the backlight level accordingly. This does
not affect the sending of event to user space, they are always sent to user
space regardless of whether or not the video module controls the backlight level
directly. This behaviour can be controlled through the brightness_switch_enabled
module parameter as documented in admin-guide/kernel-parameters.rst. It is
recommended to disable this behaviour once a GUI environment starts up and
wants to have full control of the backlight level.


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

===============================
The Linux kernel firmware guide
===============================

This section describes the ACPI subsystem in Linux from firmware perspective.

.. toctree::
   :maxdepth: 1

   acpi/index


code:
#!/bin/sh

# Simple hotplug script sample:
#
# Both $DEVPATH and $FIRMWARE are already provided in the environment.

HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/

if [ "$SUBSYSTEM" == "firmware" -a "$ACTION" == "add" ]; then
  if [ -f $HOTPLUG_FW_DIR/$FIRMWARE ]; then
    echo 1 > /sys/$DEVPATH/loading
    cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
    echo 0 > /sys/$DEVPATH/loading
  else
    echo -1 > /sys/$DEVPATH/loading
  fi
fi


code:
=================================================
FPGA Device Feature List (DFL) Framework Overview
=================================================

Authors:

- Enno Luebbers <enno.luebbers@intel.com>
- Xiao Guangrong <guangrong.xiao@linux.intel.com>
- Wu Hao <hao.wu@intel.com>
- Xu Yilun <yilun.xu@intel.com>

The Device Feature List (DFL) FPGA framework (and drivers according to
this framework) hides the very details of low layer hardware and provides
unified interfaces to userspace. Applications could use these interfaces to
configure, enumerate, open and access FPGA accelerators on platforms which
implement the DFL in the device memory. Besides this, the DFL framework
enables system level management functions such as FPGA reconfiguration.

Device Feature List (DFL) Overview
==================================
Device Feature List (DFL) defines a linked list of feature headers within the
device MMIO space to provide an extensible way of adding features. Software can
walk through these predefined data structures to enumerate FPGA features:
FPGA Interface Unit (FIU), Accelerated Function Unit (AFU) and Private Features,
as illustrated below::

    Header            Header            Header            Header
 +----------+  +-->+----------+  +-->+----------+  +-->+----------+
 |   Type   |  |   |  Type    |  |   |  Type    |  |   |  Type    |
 |   FIU    |  |   | Private  |  |   | Private  |  |   | Private  |
 +----------+  |   | Feature  |  |   | Feature  |  |   | Feature  |
 | Next_DFH |--+   +----------+  |   +----------+  |   +----------+
 +----------+      | Next_DFH |--+   | Next_DFH |--+   | Next_DFH |--> NULL
 |    ID    |      +----------+      +----------+      +----------+
 +----------+      |    ID    |      |    ID    |      |    ID    |
 | Next_AFU |--+   +----------+      +----------+      +----------+
 +----------+  |   | Feature  |      | Feature  |      | Feature  |
 |  Header  |  |   | Register |      | Register |      | Register |
 | Register |  |   |   Set    |      |   Set    |      |   Set    |
 |   Set    |  |   +----------+      +----------+      +----------+
 +----------+  |      Header
               +-->+----------+
                   |   Type   |
                   |   AFU    |
                   +----------+
                   | Next_DFH |--> NULL
                   +----------+
                   |   GUID   |
                   +----------+
                   |  Header  |
                   | Register |
                   |   Set    |
                   +----------+

FPGA Interface Unit (FIU) represents a standalone functional unit for the
interface to FPGA, e.g. the FPGA Management Engine (FME) and Port (more
descriptions on FME and Port in later sections).

Accelerated Function Unit (AFU) represents an FPGA programmable region and
always connects to a FIU (e.g. a Port) as its child as illustrated above.

Private Features represent sub features of the FIU and AFU. They could be
various function blocks with different IDs, but all private features which
belong to the same FIU or AFU, must be linked to one list via the Next Device
Feature Header (Next_DFH) pointer.

Each FIU, AFU and Private Feature could implement its own functional registers.
The functional register set for FIU and AFU, is named as Header Register Set,
e.g. FME Header Register Set, and the one for Private Feature, is named as
Feature Register Set, e.g. FME Partial Reconfiguration Feature Register Set.

This Device Feature List provides a way of linking features together, it's
convenient for software to locate each feature by walking through this list,
and can be implemented in register regions of any FPGA device.

FIU - FME (FPGA Management Engine)
==================================
The FPGA Management Engine performs reconfiguration and other infrastructure
functions. Each FPGA device only has one FME.

User-space applications can acquire exclusive access to the FME using open(),
and release it using close().

The following functions are exposed through ioctls:

- Get driver API version (DFL_FPGA_GET_API_VERSION)
- Check for extensions (DFL_FPGA_CHECK_EXTENSION)
- Program bitstream (DFL_FPGA_FME_PORT_PR)
- Assign port to PF (DFL_FPGA_FME_PORT_ASSIGN)
- Release port from PF (DFL_FPGA_FME_PORT_RELEASE)
- Get number of irqs of FME global error (DFL_FPGA_FME_ERR_GET_IRQ_NUM)
- Set interrupt trigger for FME error (DFL_FPGA_FME_ERR_SET_IRQ)

More functions are exposed through sysfs
(/sys/class/fpga_region/regionX/dfl-fme.n/):

 Read bitstream ID (bitstream_id)
     bitstream_id indicates version of the static FPGA region.

 Read bitstream metadata (bitstream_metadata)
     bitstream_metadata includes detailed information of static FPGA region,
     e.g. synthesis date and seed.

 Read number of ports (ports_num)
     one FPGA device may have more than one port, this sysfs interface indicates
     how many ports the FPGA device has.

 Global error reporting management (errors/)
     error reporting sysfs interfaces allow user to read errors detected by the
     hardware, and clear the logged errors.

 Power management (dfl_fme_power hwmon)
     power management hwmon sysfs interfaces allow user to read power management
     information (power consumption, thresholds, threshold status, limits, etc.)
     and configure power thresholds for different throttling levels.

 Thermal management (dfl_fme_thermal hwmon)
     thermal management hwmon sysfs interfaces allow user to read thermal
     management information (current temperature, thresholds, threshold status,
     etc.).

 Performance reporting
     performance counters are exposed through perf PMU APIs. Standard perf tool
     can be used to monitor all available perf events. Please see performance
     counter section below for more detailed information.

FIU - PORT
==========
A port represents the interface between the static FPGA fabric and a partially
reconfigurable region containing an AFU. It controls the communication from SW
to the accelerator and exposes features such as reset and debug. Each FPGA
device may have more than one port, but always one AFU per port.

AFU
===
An AFU is attached to a port FIU and exposes a fixed length MMIO region to be
used for accelerator-specific control registers.

User-space applications can acquire exclusive access to an AFU attached to a
port by using open() on the port device node and release it using close().

The following functions are exposed through ioctls:

- Get driver API version (DFL_FPGA_GET_API_VERSION)
- Check for extensions (DFL_FPGA_CHECK_EXTENSION)
- Get port info (DFL_FPGA_PORT_GET_INFO)
- Get MMIO region info (DFL_FPGA_PORT_GET_REGION_INFO)
- Map DMA buffer (DFL_FPGA_PORT_DMA_MAP)
- Unmap DMA buffer (DFL_FPGA_PORT_DMA_UNMAP)
- Reset AFU (DFL_FPGA_PORT_RESET)
- Get number of irqs of port error (DFL_FPGA_PORT_ERR_GET_IRQ_NUM)
- Set interrupt trigger for port error (DFL_FPGA_PORT_ERR_SET_IRQ)
- Get number of irqs of UINT (DFL_FPGA_PORT_UINT_GET_IRQ_NUM)
- Set interrupt trigger for UINT (DFL_FPGA_PORT_UINT_SET_IRQ)

DFL_FPGA_PORT_RESET:
  reset the FPGA Port and its AFU. Userspace can do Port
  reset at any time, e.g. during DMA or Partial Reconfiguration. But it should
  never cause any system level issue, only functional failure (e.g. DMA or PR
  operation failure) and be recoverable from the failure.

User-space applications can also mmap() accelerator MMIO regions.

More functions are exposed through sysfs:
(/sys/class/fpga_region/<regionX>/<dfl-port.m>/):

 Read Accelerator GUID (afu_id)
     afu_id indicates which PR bitstream is programmed to this AFU.

 Error reporting (errors/)
     error reporting sysfs interfaces allow user to read port/afu errors
     detected by the hardware, and clear the logged errors.

DFL Framework Overview
======================

::

         +----------+    +--------+ +--------+ +--------+
         |   FME    |    |  AFU   | |  AFU   | |  AFU   |
         |  Module  |    | Module | | Module | | Module |
         +----------+    +--------+ +--------+ +--------+
                 +-----------------------+
                 | FPGA Container Device |    Device Feature List
                 |  (FPGA Base Region)   |         Framework
                 +-----------------------+
  ------------------------------------------------------------------
               +----------------------------+
               |   FPGA DFL Device Module   |
               | (e.g. PCIE/Platform Device)|
               +----------------------------+
                 +------------------------+
                 |  FPGA Hardware Device  |
                 +------------------------+

DFL framework in kernel provides common interfaces to create container device
(FPGA base region), discover feature devices and their private features from the
given Device Feature Lists and create platform devices for feature devices
(e.g. FME, Port and AFU) with related resources under the container device. It
also abstracts operations for the private features and exposes common ops to
feature device drivers.

The FPGA DFL Device could be different hardware, e.g. PCIe device, platform
device and etc. Its driver module is always loaded first once the device is
created by the system. This driver plays an infrastructural role in the
driver architecture. It locates the DFLs in the device memory, handles them
and related resources to common interfaces from DFL framework for enumeration.
(Please refer to drivers/fpga/dfl.c for detailed enumeration APIs).

The FPGA Management Engine (FME) driver is a platform driver which is loaded
automatically after FME platform device creation from the DFL device module. It
provides the key features for FPGA management, including:

	a) Expose static FPGA region information, e.g. version and metadata.
	   Users can read related information via sysfs interfaces exposed
	   by FME driver.

	b) Partial Reconfiguration. The FME driver creates FPGA manager, FPGA
	   bridges and FPGA regions during PR sub feature initialization. Once
	   it receives a DFL_FPGA_FME_PORT_PR ioctl from user, it invokes the
	   common interface function from FPGA Region to complete the partial
	   reconfiguration of the PR bitstream to the given port.

Similar to the FME driver, the FPGA Accelerated Function Unit (AFU) driver is
probed once the AFU platform device is created. The main function of this module
is to provide an interface for userspace applications to access the individual
accelerators, including basic reset control on port, AFU MMIO region export, dma
buffer mapping service functions.

After feature platform devices creation, matched platform drivers will be loaded
automatically to handle different functionalities. Please refer to next sections
for detailed information on functional units which have been already implemented
under this DFL framework.

Partial Reconfiguration
=======================
As mentioned above, accelerators can be reconfigured through partial
reconfiguration of a PR bitstream file. The PR bitstream file must have been
generated for the exact static FPGA region and targeted reconfigurable region
(port) of the FPGA, otherwise, the reconfiguration operation will fail and
possibly cause system instability. This compatibility can be checked by
comparing the compatibility ID noted in the header of PR bitstream file against
the compat_id exposed by the target FPGA region. This check is usually done by
userspace before calling the reconfiguration IOCTL.

FPGA virtualization - PCIe SRIOV
================================
This section describes the virtualization support on DFL based FPGA device to
enable accessing an accelerator from applications running in a virtual machine
(VM). This section only describes the PCIe based FPGA device with SRIOV support.

Features supported by the particular FPGA device are exposed through Device
Feature Lists, as illustrated below:

::

    +-------------------------------+  +-------------+
    |              PF               |  |     VF      |
    +-------------------------------+  +-------------+
        ^            ^         ^              ^
        |            |         |              |
  +-----|------------|---------|--------------|-------+
  |     |            |         |              |       |
  |  +-----+     +-------+ +-------+      +-------+   |
  |  | FME |     | Port0 | | Port1 |      | Port2 |   |
  |  +-----+     +-------+ +-------+      +-------+   |
  |                  ^         ^              ^       |
  |                  |         |              |       |
  |              +-------+ +------+       +-------+   |
  |              |  AFU  | |  AFU |       |  AFU  |   |
  |              +-------+ +------+       +-------+   |
  |                                                   |
  |            DFL based FPGA PCIe Device             |
  +---------------------------------------------------+

FME is always accessed through the physical function (PF).

Ports (and related AFUs) are accessed via PF by default, but could be exposed
through virtual function (VF) devices via PCIe SRIOV. Each VF only contains
1 Port and 1 AFU for isolation. Users could assign individual VFs (accelerators)
created via PCIe SRIOV interface, to virtual machines.

The driver organization in virtualization case is illustrated below:
::

    +-------++------++------+             |
    | FME   || FME  || FME  |             |
    | FPGA  || FPGA || FPGA |             |
    |Manager||Bridge||Region|             |
    +-------++------++------+             |
    +-----------------------+  +--------+ |             +--------+
    |          FME          |  |  AFU   | |             |  AFU   |
    |         Module        |  | Module | |             | Module |
    +-----------------------+  +--------+ |             +--------+
          +-----------------------+       |       +-----------------------+
          | FPGA Container Device |       |       | FPGA Container Device |
          |  (FPGA Base Region)   |       |       |  (FPGA Base Region)   |
          +-----------------------+       |       +-----------------------+
            +------------------+          |         +------------------+
            | FPGA PCIE Module |          | Virtual | FPGA PCIE Module |
            +------------------+   Host   | Machine +------------------+
   -------------------------------------- | ------------------------------
             +---------------+            |          +---------------+
             | PCI PF Device |            |          | PCI VF Device |
             +---------------+            |          +---------------+

FPGA PCIe device driver is always loaded first once an FPGA PCIe PF or VF device
is detected. It:

* Finishes enumeration on both FPGA PCIe PF and VF device using common
  interfaces from DFL framework.
* Supports SRIOV.

The FME device driver plays a management role in this driver architecture, it
provides ioctls to release Port from PF and assign Port to PF. After release
a port from PF, then it's safe to expose this port through a VF via PCIe SRIOV
sysfs interface.

To enable accessing an accelerator from applications running in a VM, the
respective AFU's port needs to be assigned to a VF using the following steps:

#. The PF owns all AFU ports by default. Any port that needs to be
   reassigned to a VF must first be released through the
   DFL_FPGA_FME_PORT_RELEASE ioctl on the FME device.

#. Once N ports are released from PF, then user can use command below
   to enable SRIOV and VFs. Each VF owns only one Port with AFU.

   ::

      echo N > $PCI_DEVICE_PATH/sriov_numvfs

#. Pass through the VFs to VMs

#. The AFU under VF is accessible from applications in VM (using the
   same driver inside the VF).

Note that an FME can't be assigned to a VF, thus PR and other management
functions are only available via the PF.

Device enumeration
==================
This section introduces how applications enumerate the fpga device from
the sysfs hierarchy under /sys/class/fpga_region.

In the example below, two DFL based FPGA devices are installed in the host. Each
fpga device has one FME and two ports (AFUs).

FPGA regions are created under /sys/class/fpga_region/::

	/sys/class/fpga_region/region0
	/sys/class/fpga_region/region1
	/sys/class/fpga_region/region2
	...

Application needs to search each regionX folder, if feature device is found,
(e.g. "dfl-port.n" or "dfl-fme.m" is found), then it's the base
fpga region which represents the FPGA device.

Each base region has one FME and two ports (AFUs) as child devices::

	/sys/class/fpga_region/region0/dfl-fme.0
	/sys/class/fpga_region/region0/dfl-port.0
	/sys/class/fpga_region/region0/dfl-port.1
	...

	/sys/class/fpga_region/region3/dfl-fme.1
	/sys/class/fpga_region/region3/dfl-port.2
	/sys/class/fpga_region/region3/dfl-port.3
	...

In general, the FME/AFU sysfs interfaces are named as follows::

	/sys/class/fpga_region/<regionX>/<dfl-fme.n>/
	/sys/class/fpga_region/<regionX>/<dfl-port.m>/

with 'n' consecutively numbering all FMEs and 'm' consecutively numbering all
ports.

The device nodes used for ioctl() or mmap() can be referenced through::

	/sys/class/fpga_region/<regionX>/<dfl-fme.n>/dev
	/sys/class/fpga_region/<regionX>/<dfl-port.n>/dev

Performance Counters
====================
Performance reporting is one private feature implemented in FME. It could
supports several independent, system-wide, device counter sets in hardware to
monitor and count for performance events, including "basic", "cache", "fabric",
"vtd" and "vtd_sip" counters. Users could use standard perf tool to monitor
FPGA cache hit/miss rate, transaction number, interface clock counter of AFU
and other FPGA performance events.

Different FPGA devices may have different counter sets, depending on hardware
implementation. E.g., some discrete FPGA cards don't have any cache. User could
use "perf list" to check which perf events are supported by target hardware.

In order to allow user to use standard perf API to access these performance
counters, driver creates a perf PMU, and related sysfs interfaces in
/sys/bus/event_source/devices/dfl_fme* to describe available perf events and
configuration options.

The "format" directory describes the format of the config field of struct
perf_event_attr. There are 3 bitfields for config: "evtype" defines which type
the perf event belongs to; "event" is the identity of the event within its
category; "portid" is introduced to decide counters set to monitor on FPGA
overall data or a specific port.

The "events" directory describes the configuration templates for all available
events which can be used with perf tool directly. For example, fab_mmio_read
has the configuration "event=0x06,evtype=0x02,portid=0xff", which shows this
event belongs to fabric type (0x02), the local event id is 0x06 and it is for
overall monitoring (portid=0xff).

Example usage of perf::

  $# perf list |grep dfl_fme

  dfl_fme0/fab_mmio_read/                              [Kernel PMU event]
  <...>
  dfl_fme0/fab_port_mmio_read,portid=?/                [Kernel PMU event]
  <...>

  $# perf stat -a -e dfl_fme0/fab_mmio_read/ <command>
  or
  $# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0xff/ <command>
  or
  $# perf stat -a -e dfl_fme0/config=0xff2006/ <command>

Another example, fab_port_mmio_read monitors mmio read of a specific port. So
its configuration template is "event=0x06,evtype=0x01,portid=?". The portid
should be explicitly set.

Its usage of perf::

  $# perf stat -a -e dfl_fme0/fab_port_mmio_read,portid=0x0/ <command>
  or
  $# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0x0/ <command>
  or
  $# perf stat -a -e dfl_fme0/config=0x2006/ <command>

Please note for fabric counters, overall perf events (fab_*) and port perf
events (fab_port_*) actually share one set of counters in hardware, so it can't
monitor both at the same time. If this set of counters is configured to monitor
overall data, then per port perf data is not supported. See below example::

  $# perf stat -e dfl_fme0/fab_mmio_read/,dfl_fme0/fab_port_mmio_write,\
                                                    portid=0/ sleep 1

  Performance counter stats for 'system wide':

                 3      dfl_fme0/fab_mmio_read/
   <not supported>      dfl_fme0/fab_port_mmio_write,portid=0x0/

       1.001750904 seconds time elapsed

The driver also provides a "cpumask" sysfs attribute, which contains only one
CPU id used to access these perf events. Counting on multiple CPU is not allowed
since they are system-wide counters on FPGA device.

The current driver does not support sampling. So "perf record" is unsupported.

Interrupt support
=================
Some FME and AFU private features are able to generate interrupts. As mentioned
above, users could call ioctl (DFL_FPGA_*_GET_IRQ_NUM) to know whether or how
many interrupts are supported for this private feature. Drivers also implement
an eventfd based interrupt handling mechanism for users to get notified when
interrupt happens. Users could set eventfds to driver via
ioctl (DFL_FPGA_*_SET_IRQ), and then poll/select on these eventfds waiting for
notification.
In Current DFL, 3 sub features (Port error, FME global error and AFU interrupt)
support interrupts.

Add new FIUs support
====================
It's possible that developers made some new function blocks (FIUs) under this
DFL framework, then new platform device driver needs to be developed for the
new feature dev (FIU) following the same way as existing feature dev drivers
(e.g. FME and Port/AFU platform device driver). Besides that, it requires
modification on DFL framework enumeration code too, for new FIU type detection
and related platform devices creation.

Add new private features support
================================
In some cases, we may need to add some new private features to existing FIUs
(e.g. FME or Port). Developers don't need to touch enumeration code in DFL
framework, as each private feature will be parsed automatically and related
mmio resources can be found under FIU platform device created by DFL framework.
Developer only needs to provide a sub feature driver with matched feature id.
FME Partial Reconfiguration Sub Feature driver (see drivers/fpga/dfl-fme-pr.c)
could be a reference.

Please refer to below link to existing feature id table and guide for new feature
ids application.
https://github.com/OPAE/dfl-feature-id

Location of DFLs on a PCI Device
================================
The original method for finding a DFL on a PCI device assumed the start of the
first DFL to offset 0 of bar 0.  If the first node of the DFL is an FME,
then further DFLs in the port(s) are specified in FME header registers.
Alternatively, a PCIe vendor specific capability structure can be used to
specify the location of all the DFLs on the device, providing flexibility
for the type of starting node in the DFL.  Intel has reserved the
VSEC ID of 0x43 for this purpose.  The vendor specific
data begins with a 4 byte vendor specific register for the number of DFLs followed 4 byte
Offset/BIR vendor specific registers for each DFL. Bits 2:0 of Offset/BIR register
indicates the BAR, and bits 31:3 form the 8 byte aligned offset where bits 2:0 are
zero.
::

        +----------------------------+
        |31     Number of DFLS      0|
        +----------------------------+
        |31     Offset     3|2 BIR  0|
        +----------------------------+
                      . . .
        +----------------------------+
        |31     Offset     3|2 BIR  0|
        +----------------------------+

Being able to specify more than one DFL per BAR has been considered, but it
was determined the use case did not provide value.  Specifying a single DFL
per BAR simplifies the implementation and allows for extra error checking.

Userspace driver support for DFL devices
========================================
The purpose of an FPGA is to be reprogrammed with newly developed hardware
components. New hardware can instantiate a new private feature in the DFL, and
then present a DFL device in the system. In some cases users may need a
userspace driver for the DFL device:

* Users may need to run some diagnostic test for their hardware.
* Users may prototype the kernel driver in user space.
* Some hardware is designed for specific purposes and does not fit into one of
  the standard kernel subsystems.

This requires direct access to MMIO space and interrupt handling from
userspace. The uio_dfl module exposes the UIO device interfaces for this
purpose.

Currently the uio_dfl driver only supports the Ether Group sub feature, which
has no irq in hardware. So the interrupt handling is not added in this driver.

UIO_DFL should be selected to enable the uio_dfl module driver. To support a
new DFL feature via UIO direct access, its feature id should be added to the
driver's id_table.

Open discussion
===============
FME driver exports one ioctl (DFL_FPGA_FME_PORT_PR) for partial reconfiguration
to user now. In the future, if unified user interfaces for reconfiguration are
added, FME driver should switch to them from ioctl interface.


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

====
fpga
====

.. toctree::
    :maxdepth: 1

    dfl

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


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

===================================
 Arm Framebuffer Compression (AFBC)
===================================

AFBC is a proprietary lossless image compression protocol and format.
It provides fine-grained random access and minimizes the amount of
data transferred between IP blocks.

AFBC can be enabled on drivers which support it via use of the AFBC
format modifiers defined in drm_fourcc.h. See DRM_FORMAT_MOD_ARM_AFBC(*).

All users of the AFBC modifiers must follow the usage guidelines laid
out in this document, to ensure compatibility across different AFBC
producers and consumers.

Components and Ordering
=======================

AFBC streams can contain several components - where a component
corresponds to a color channel (i.e. R, G, B, X, A, Y, Cb, Cr).
The assignment of input/output color channels must be consistent
between the encoder and the decoder for correct operation, otherwise
the consumer will interpret the decoded data incorrectly.

Furthermore, when the lossless colorspace transform is used
(AFBC_FORMAT_MOD_YTR, which should be enabled for RGB buffers for
maximum compression efficiency), the component order must be:

 * Component 0: R
 * Component 1: G
 * Component 2: B

The component ordering is communicated via the fourcc code in the
fourcc:modifier pair. In general, component '0' is considered to
reside in the least-significant bits of the corresponding linear
format. For example, COMP(bits):

 * DRM_FORMAT_ABGR8888

   * Component 0: R(8)
   * Component 1: G(8)
   * Component 2: B(8)
   * Component 3: A(8)

 * DRM_FORMAT_BGR888

   * Component 0: R(8)
   * Component 1: G(8)
   * Component 2: B(8)

 * DRM_FORMAT_YUYV

   * Component 0: Y(8)
   * Component 1: Cb(8, 2x1 subsampled)
   * Component 2: Cr(8, 2x1 subsampled)

In AFBC, 'X' components are not treated any differently from any other
component. Therefore, an AFBC buffer with fourcc DRM_FORMAT_XBGR8888
encodes with 4 components, like so:

 * DRM_FORMAT_XBGR8888

   * Component 0: R(8)
   * Component 1: G(8)
   * Component 2: B(8)
   * Component 3: X(8)

Please note, however, that the inclusion of a "wasted" 'X' channel is
bad for compression efficiency, and so it's recommended to avoid
formats containing 'X' bits. If a fourth component is
required/expected by the encoder/decoder, then it is recommended to
instead use an equivalent format with alpha, setting all alpha bits to
'1'. If there is no requirement for a fourth component, then a format
which doesn't include alpha can be used, e.g. DRM_FORMAT_BGR888.

Number of Planes
================

Formats which are typically multi-planar in linear layouts (e.g. YUV
420), can be encoded into one, or multiple, AFBC planes. As with
component order, the encoder and decoder must agree about the number
of planes in order to correctly decode the buffer. The fourcc code is
used to determine the number of encoded planes in an AFBC buffer,
matching the number of planes for the linear (unmodified) format.
Within each plane, the component ordering also follows the fourcc
code:

For example:

 * DRM_FORMAT_YUYV: nplanes = 1

   * Plane 0:

     * Component 0: Y(8)
     * Component 1: Cb(8, 2x1 subsampled)
     * Component 2: Cr(8, 2x1 subsampled)

 * DRM_FORMAT_NV12: nplanes = 2

   * Plane 0:

     * Component 0: Y(8)

   * Plane 1:

     * Component 0: Cb(8, 2x1 subsampled)
     * Component 1: Cr(8, 2x1 subsampled)

Cross-device interoperability
=============================

For maximum compatibility across devices, the table below defines
canonical formats for use between AFBC-enabled devices. Formats which
are listed here must be used exactly as specified when using the AFBC
modifiers. Formats which are not listed should be avoided.

.. flat-table:: AFBC formats

   * - Fourcc code
     - Description
     - Planes/Components

   * - DRM_FORMAT_ABGR2101010
     - 10-bit per component RGB, with 2-bit alpha
     - Plane 0: 4 components
              * Component 0: R(10)
              * Component 1: G(10)
              * Component 2: B(10)
              * Component 3: A(2)

   * - DRM_FORMAT_ABGR8888
     - 8-bit per component RGB, with 8-bit alpha
     - Plane 0: 4 components
              * Component 0: R(8)
              * Component 1: G(8)
              * Component 2: B(8)
              * Component 3: A(8)

   * - DRM_FORMAT_BGR888
     - 8-bit per component RGB
     - Plane 0: 3 components
              * Component 0: R(8)
              * Component 1: G(8)
              * Component 2: B(8)

   * - DRM_FORMAT_BGR565
     - 5/6-bit per component RGB
     - Plane 0: 3 components
              * Component 0: R(5)
              * Component 1: G(6)
              * Component 2: B(5)

   * - DRM_FORMAT_ABGR1555
     - 5-bit per component RGB, with 1-bit alpha
     - Plane 0: 4 components
              * Component 0: R(5)
              * Component 1: G(5)
              * Component 2: B(5)
              * Component 3: A(1)

   * - DRM_FORMAT_VUY888
     - 8-bit per component YCbCr 444, single plane
     - Plane 0: 3 components
              * Component 0: Y(8)
              * Component 1: Cb(8)
              * Component 2: Cr(8)

   * - DRM_FORMAT_VUY101010
     - 10-bit per component YCbCr 444, single plane
     - Plane 0: 3 components
              * Component 0: Y(10)
              * Component 1: Cb(10)
              * Component 2: Cr(10)

   * - DRM_FORMAT_YUYV
     - 8-bit per component YCbCr 422, single plane
     - Plane 0: 3 components
              * Component 0: Y(8)
              * Component 1: Cb(8, 2x1 subsampled)
              * Component 2: Cr(8, 2x1 subsampled)

   * - DRM_FORMAT_NV16
     - 8-bit per component YCbCr 422, two plane
     - Plane 0: 1 component
              * Component 0: Y(8)
       Plane 1: 2 components
              * Component 0: Cb(8, 2x1 subsampled)
              * Component 1: Cr(8, 2x1 subsampled)

   * - DRM_FORMAT_Y210
     - 10-bit per component YCbCr 422, single plane
     - Plane 0: 3 components
              * Component 0: Y(10)
              * Component 1: Cb(10, 2x1 subsampled)
              * Component 2: Cr(10, 2x1 subsampled)

   * - DRM_FORMAT_P210
     - 10-bit per component YCbCr 422, two plane
     - Plane 0: 1 component
              * Component 0: Y(10)
       Plane 1: 2 components
              * Component 0: Cb(10, 2x1 subsampled)
              * Component 1: Cr(10, 2x1 subsampled)

   * - DRM_FORMAT_YUV420_8BIT
     - 8-bit per component YCbCr 420, single plane
     - Plane 0: 3 components
              * Component 0: Y(8)
              * Component 1: Cb(8, 2x2 subsampled)
              * Component 2: Cr(8, 2x2 subsampled)

   * - DRM_FORMAT_YUV420_10BIT
     - 10-bit per component YCbCr 420, single plane
     - Plane 0: 3 components
              * Component 0: Y(10)
              * Component 1: Cb(10, 2x2 subsampled)
              * Component 2: Cr(10, 2x2 subsampled)

   * - DRM_FORMAT_NV12
     - 8-bit per component YCbCr 420, two plane
     - Plane 0: 1 component
              * Component 0: Y(8)
       Plane 1: 2 components
              * Component 0: Cb(8, 2x2 subsampled)
              * Component 1: Cr(8, 2x2 subsampled)

   * - DRM_FORMAT_P010
     - 10-bit per component YCbCr 420, two plane
     - Plane 0: 1 component
              * Component 0: Y(10)
       Plane 1: 2 components
              * Component 0: Cb(10, 2x2 subsampled)
              * Component 1: Cr(10, 2x2 subsampled)


code:
===============
AMDGPU Glossary
===============

Here you can find some generic acronyms used in the amdgpu driver. Notice that
we have a dedicated glossary for Display Core at
'Documentation/gpu/amdgpu/display/dc-glossary.rst'.

.. glossary::

    active_cu_number
      The number of CUs that are active on the system.  The number of active
      CUs may be less than SE * SH * CU depending on the board configuration.

    CP
      Command Processor

    CPLIB
      Content Protection Library

    CU
      Compute Unit

    DFS
      Digital Frequency Synthesizer

    ECP
      Enhanced Content Protection

    EOP
      End Of Pipe/Pipeline

    GART
      Graphics Address Remapping Table.  This is the name we use for the GPUVM
      page table used by the GPU kernel driver.  It remaps system resources
      (memory or MMIO space) into the GPU's address space so the GPU can access
      them.  The name GART harkens back to the days of AGP when the platform
      provided an MMU that the GPU could use to get a contiguous view of
      scattered pages for DMA.  The MMU has since moved on to the GPU, but the
      name stuck.

    GC
      Graphics and Compute

    GMC
      Graphic Memory Controller

    GPUVM
      GPU Virtual Memory.  This is the GPU's MMU.  The GPU supports multiple
      virtual address spaces that can be in flight at any given time.  These
      allow the GPU to remap VRAM and system resources into GPU virtual address
      spaces for use by the GPU kernel driver and applications using the GPU.
      These provide memory protection for different applications using the GPU.

    GTT
      Graphics Translation Tables.  This is a memory pool managed through TTM
      which provides access to system resources (memory or MMIO space) for
      use by the GPU. These addresses can be mapped into the "GART" GPUVM page
      table for use by the kernel driver or into per process GPUVM page tables
      for application usage.

    IH
      Interrupt Handler

    HQD
      Hardware Queue Descriptor

    IB
      Indirect Buffer

    IP
        Intellectual Property blocks

    KCQ
      Kernel Compute Queue

    KGQ
      Kernel Graphics Queue

    KIQ
      Kernel Interface Queue

    MEC
      MicroEngine Compute

    MES
      MicroEngine Scheduler

    MMHUB
      Multi-Media HUB

    MQD
      Memory Queue Descriptor

    PPLib
      PowerPlay Library - PowerPlay is the power management component.

    PSP
        Platform Security Processor

    RLC
      RunList Controller

    SDMA
      System DMA

    SE
      Shader Engine

    SH
      SHader array

    SMU
      System Management Unit

    SS
      Spread Spectrum

    VCE
      Video Compression Engine

    VCN
      Video Codec Next


code:
Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version
Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0
Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1
SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1
Ryzen 5000 series, GREEN SARDINE, DCN 2.1, 9.3, VCN 2.2, 4.1.1
Ryzen 6000 Zen, YELLOW CARP, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3