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