162306a36Sopenharmony_ci=======================
262306a36Sopenharmony_ciDisplay Core Next (DCN)
362306a36Sopenharmony_ci=======================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciTo equip our readers with the basic knowledge of how AMD Display Core Next
662306a36Sopenharmony_ci(DCN) works, we need to start with an overview of the hardware pipeline. Below
762306a36Sopenharmony_ciyou can see a picture that provides a DCN overview, keep in mind that this is a
862306a36Sopenharmony_cigeneric diagram, and we have variations per ASIC.
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci.. kernel-figure:: dc_pipeline_overview.svg
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciBased on this diagram, we can pass through each block and briefly describe
1362306a36Sopenharmony_cithem:
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci* **Display Controller Hub (DCHUB)**: This is the gateway between the Scalable
1662306a36Sopenharmony_ci  Data Port (SDP) and DCN. This component has multiple features, such as memory
1762306a36Sopenharmony_ci  arbitration, rotation, and cursor manipulation.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci* **Display Pipe and Plane (DPP)**: This block provides pre-blend pixel
2062306a36Sopenharmony_ci  processing such as color space conversion, linearization of pixel data, tone
2162306a36Sopenharmony_ci  mapping, and gamut mapping.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci* **Multiple Pipe/Plane Combined (MPC)**: This component performs blending of
2462306a36Sopenharmony_ci  multiple planes, using global or per-pixel alpha.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci* **Output Pixel Processing (OPP)**: Process and format pixels to be sent to
2762306a36Sopenharmony_ci  the display.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci* **Output Pipe Timing Combiner (OPTC)**: It generates time output to combine
3062306a36Sopenharmony_ci  streams or divide capabilities. CRC values are generated in this block.
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci* **Display Output (DIO)**: Codify the output to the display connected to our
3362306a36Sopenharmony_ci  GPU.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci* **Display Writeback (DWB)**: It provides the ability to write the output of
3662306a36Sopenharmony_ci  the display pipe back to memory as video frames.
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci* **Multi-Media HUB (MMHUBBUB)**: Memory controller interface for DMCUB and DWB
3962306a36Sopenharmony_ci  (Note that DWB is not hooked yet).
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci* **DCN Management Unit (DMU)**: It provides registers with access control and
4262306a36Sopenharmony_ci  interrupts the controller to the SOC host interrupt unit. This block includes
4362306a36Sopenharmony_ci  the Display Micro-Controller Unit - version B (DMCUB), which is handled via
4462306a36Sopenharmony_ci  firmware.
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci* **DCN Clock Generator Block (DCCG)**: It provides the clocks and resets
4762306a36Sopenharmony_ci  for all of the display controller clock domains.
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci* **Azalia (AZ)**: Audio engine.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciThe above diagram is an architecture generalization of DCN, which means that
5262306a36Sopenharmony_cievery ASIC has variations around this base model. Notice that the display
5362306a36Sopenharmony_cipipeline is connected to the Scalable Data Port (SDP) via DCHUB; you can see
5462306a36Sopenharmony_cithe SDP as the element from our Data Fabric that feeds the display pipe.
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciAlways approach the DCN architecture as something flexible that can be
5762306a36Sopenharmony_ciconfigured and reconfigured in multiple ways; in other words, each block can be
5862306a36Sopenharmony_cisetup or ignored accordingly with userspace demands. For example, if we
5962306a36Sopenharmony_ciwant to drive an 8k@60Hz with a DSC enabled, our DCN may require 4 DPP and 2
6062306a36Sopenharmony_ciOPP. It is DC's responsibility to drive the best configuration for each
6162306a36Sopenharmony_cispecific scenario. Orchestrate all of these components together requires a
6262306a36Sopenharmony_cisophisticated communication interface which is highlighted in the diagram by
6362306a36Sopenharmony_cithe edges that connect each block; from the chart, each connection between
6462306a36Sopenharmony_cithese blocks represents:
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci1. Pixel data interface (red): Represents the pixel data flow;
6762306a36Sopenharmony_ci2. Global sync signals (green): It is a set of synchronization signals composed
6862306a36Sopenharmony_ci   by VStartup, VUpdate, and VReady;
6962306a36Sopenharmony_ci3. Config interface: Responsible to configure blocks;
7062306a36Sopenharmony_ci4. Sideband signals: All other signals that do not fit the previous one.
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciThese signals are essential and play an important role in DCN. Nevertheless,
7362306a36Sopenharmony_cithe Global Sync deserves an extra level of detail described in the next
7462306a36Sopenharmony_cisection.
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciAll of these components are represented by a data structure named dc_state.
7762306a36Sopenharmony_ciFrom DCHUB to MPC, we have a representation called dc_plane; from MPC to OPTC,
7862306a36Sopenharmony_ciwe have dc_stream, and the output (DIO) is handled by dc_link. Keep in mind
7962306a36Sopenharmony_cithat HUBP accesses a surface using a specific format read from memory, and our
8062306a36Sopenharmony_cidc_plane should work to convert all pixels in the plane to something that can
8162306a36Sopenharmony_cibe sent to the display via dc_stream and dc_link.
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciFront End and Back End
8462306a36Sopenharmony_ci----------------------
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ciDisplay pipeline can be broken down into two components that are usually
8762306a36Sopenharmony_cireferred as **Front End (FE)** and **Back End (BE)**, where FE consists of:
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci* DCHUB (Mainly referring to a subcomponent named HUBP)
9062306a36Sopenharmony_ci* DPP
9162306a36Sopenharmony_ci* MPC
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciOn the other hand, BE consist of
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci* OPP
9662306a36Sopenharmony_ci* OPTC
9762306a36Sopenharmony_ci* DIO (DP/HDMI stream encoder and link encoder)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciOPP and OPTC are two joining blocks between FE and BE. On a side note, this is
10062306a36Sopenharmony_cia one-to-one mapping of the link encoder to PHY, but we can configure the DCN
10162306a36Sopenharmony_cito choose which link encoder to connect to which PHY. FE's main responsibility
10262306a36Sopenharmony_ciis to change, blend and compose pixel data, while BE's job is to frame a
10362306a36Sopenharmony_cigeneric pixel stream to a specific display's pixel stream.
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciData Flow
10662306a36Sopenharmony_ci---------
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ciInitially, data is passed in from VRAM through Data Fabric (DF) in native pixel
10962306a36Sopenharmony_ciformats. Such data format stays through till HUBP in DCHUB, where HUBP unpacks
11062306a36Sopenharmony_cidifferent pixel formats and outputs them to DPP in uniform streams through 4
11162306a36Sopenharmony_cichannels (1 for alpha + 3 for colors).
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciThe Converter and Cursor (CNVC) in DPP would then normalize the data
11462306a36Sopenharmony_cirepresentation and convert them to a DCN specific floating-point format (i.e.,
11562306a36Sopenharmony_cidifferent from the IEEE floating-point format). In the process, CNVC also
11662306a36Sopenharmony_ciapplies a degamma function to transform the data from non-linear to linear
11762306a36Sopenharmony_cispace to relax the floating-point calculations following. Data would stay in
11862306a36Sopenharmony_cithis floating-point format from DPP to OPP.
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciStarting OPP, because color transformation and blending have been completed
12162306a36Sopenharmony_ci(i.e alpha can be dropped), and the end sinks do not require the precision and
12262306a36Sopenharmony_cidynamic range that floating points provide (i.e. all displays are in integer
12362306a36Sopenharmony_cidepth format), bit-depth reduction/dithering would kick in. In OPP, we would
12462306a36Sopenharmony_cialso apply a regamma function to introduce the gamma removed earlier back.
12562306a36Sopenharmony_ciEventually, we output data in integer format at DIO.
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciAMD Hardware Pipeline
12862306a36Sopenharmony_ci---------------------
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ciWhen discussing graphics on Linux, the **pipeline** term can sometimes be
13162306a36Sopenharmony_cioverloaded with multiple meanings, so it is important to define what we mean
13262306a36Sopenharmony_ciwhen we say **pipeline**. In the DCN driver, we use the term **hardware
13362306a36Sopenharmony_cipipeline** or **pipeline** or just **pipe** as an abstraction to indicate a
13462306a36Sopenharmony_cisequence of DCN blocks instantiated to address some specific configuration. DC
13562306a36Sopenharmony_cicore treats DCN blocks as individual resources, meaning we can build a pipeline
13662306a36Sopenharmony_ciby taking resources for all individual hardware blocks to compose one pipeline.
13762306a36Sopenharmony_ciIn actuality, we can't connect an arbitrary block from one pipe to a block from
13862306a36Sopenharmony_cianother pipe; they are routed linearly, except for DSC, which can be
13962306a36Sopenharmony_ciarbitrarily assigned as needed. We have this pipeline concept for trying to
14062306a36Sopenharmony_cioptimize bandwidth utilization.
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci.. kernel-figure:: pipeline_4k_no_split.svg
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciAdditionally, let's take a look at parts of the DTN log (see
14562306a36Sopenharmony_ci'Documentation/gpu/amdgpu/display/dc-debug.rst' for more information) since
14662306a36Sopenharmony_cithis log can help us to see part of this pipeline behavior in real-time::
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci HUBP:  format  addr_hi  width  height ...
14962306a36Sopenharmony_ci [ 0]:      8h      81h   3840    2160
15062306a36Sopenharmony_ci [ 1]:      0h       0h      0       0
15162306a36Sopenharmony_ci [ 2]:      0h       0h      0       0
15262306a36Sopenharmony_ci [ 3]:      0h       0h      0       0
15362306a36Sopenharmony_ci [ 4]:      0h       0h      0       0
15462306a36Sopenharmony_ci ...
15562306a36Sopenharmony_ci MPCC:  OPP  DPP ...
15662306a36Sopenharmony_ci [ 0]:   0h   0h ...
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciThe first thing to notice from the diagram and DTN log it is the fact that we
15962306a36Sopenharmony_cihave different clock domains for each part of the DCN blocks. In this example,
16062306a36Sopenharmony_ciwe have just a single **pipeline** where the data flows from DCHUB to DIO, as
16162306a36Sopenharmony_ciwe intuitively expect. Nonetheless, DCN is flexible, as mentioned before, and
16262306a36Sopenharmony_ciwe can split this single pipe differently, as described in the below diagram:
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci.. kernel-figure:: pipeline_4k_split.svg
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciNow, if we inspect the DTN log again we can see some interesting changes::
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci HUBP:  format  addr_hi  width  height ...
16962306a36Sopenharmony_ci [ 0]:      8h      81h   1920    2160 ...
17062306a36Sopenharmony_ci ...
17162306a36Sopenharmony_ci [ 4]:      0h       0h      0       0 ...
17262306a36Sopenharmony_ci [ 5]:      8h      81h   1920    2160 ...
17362306a36Sopenharmony_ci ...
17462306a36Sopenharmony_ci MPCC:  OPP  DPP ...
17562306a36Sopenharmony_ci [ 0]:   0h   0h ...
17662306a36Sopenharmony_ci [ 5]:   0h   5h ...
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciFrom the above example, we now split the display pipeline into two vertical
17962306a36Sopenharmony_ciparts of 1920x2160 (i.e., 3440x2160), and as a result, we could reduce the
18062306a36Sopenharmony_ciclock frequency in the DPP part. This is not only useful for saving power but
18162306a36Sopenharmony_cialso to better handle the required throughput. The idea to keep in mind here is
18262306a36Sopenharmony_cithat the pipe configuration can vary a lot according to the display
18362306a36Sopenharmony_ciconfiguration, and it is the DML's responsibility to set up all required
18462306a36Sopenharmony_ciconfiguration parameters for multiple scenarios supported by our hardware.
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciGlobal Sync
18762306a36Sopenharmony_ci-----------
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ciMany DCN registers are double buffered, most importantly the surface address.
19062306a36Sopenharmony_ciThis allows us to update DCN hardware atomically for page flips, as well as
19162306a36Sopenharmony_cifor most other updates that don't require enabling or disabling of new pipes.
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci(Note: There are many scenarios when DC will decide to reserve extra pipes
19462306a36Sopenharmony_ciin order to support outputs that need a very high pixel clock, or for
19562306a36Sopenharmony_cipower saving purposes.)
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ciThese atomic register updates are driven by global sync signals in DCN. In
19862306a36Sopenharmony_ciorder to understand how atomic updates interact with DCN hardware, and how DCN
19962306a36Sopenharmony_cisignals page flip and vblank events it is helpful to understand how global sync
20062306a36Sopenharmony_ciis programmed.
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciGlobal sync consists of three signals, VSTARTUP, VUPDATE, and VREADY. These are
20362306a36Sopenharmony_cicalculated by the Display Mode Library - DML (drivers/gpu/drm/amd/display/dc/dml)
20462306a36Sopenharmony_cibased on a large number of parameters and ensure our hardware is able to feed
20562306a36Sopenharmony_cithe DCN pipeline without underflows or hangs in any given system configuration.
20662306a36Sopenharmony_ciThe global sync signals always happen during VBlank, are independent from the
20762306a36Sopenharmony_ciVSync signal, and do not overlap each other.
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ciVUPDATE is the only signal that is of interest to the rest of the driver stack
21062306a36Sopenharmony_cior userspace clients as it signals the point at which hardware latches to
21162306a36Sopenharmony_ciatomically programmed (i.e. double buffered) registers. Even though it is
21262306a36Sopenharmony_ciindependent of the VSync signal we use VUPDATE to signal the VSync event as it
21362306a36Sopenharmony_ciprovides the best indication of how atomic commits and hardware interact.
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ciSince DCN hardware is double-buffered the DC driver is able to program the
21662306a36Sopenharmony_cihardware at any point during the frame.
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ciThe below picture illustrates the global sync signals:
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci.. kernel-figure:: global_sync_vblank.svg
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ciThese signals affect core DCN behavior. Programming them incorrectly will lead
22362306a36Sopenharmony_cito a number of negative consequences, most of them quite catastrophic.
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciThe following picture shows how global sync allows for a mailbox style of
22662306a36Sopenharmony_ciupdates, i.e. it allows for multiple re-configurations between VUpdate
22762306a36Sopenharmony_cievents where only the last configuration programmed before the VUpdate signal
22862306a36Sopenharmony_cibecomes effective.
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci.. kernel-figure:: config_example.svg
231