1==================== 2DC Programming Model 3==================== 4 5In the :ref:`Display Core Next (DCN) <dcn_overview>` and :ref:`DCN Block 6<dcn_blocks>` pages, you learned about the hardware components and how they 7interact with each other. On this page, the focus is shifted to the display 8code architecture. Hence, it is reasonable to remind the reader that the code 9in DC is shared with other OSes; for this reason, DC provides a set of 10abstractions and operations to connect different APIs with the hardware 11configuration. See DC as a service available for a Display Manager (amdgpu_dm) 12to access and configure DCN/DCE hardware (DCE is also part of DC, but for 13simplicity's sake, this documentation only examines DCN). 14 15.. note:: 16 For this page, we will use the term GPU to refers to dGPU and APU. 17 18Overview 19======== 20 21From the display hardware perspective, it is plausible to expect that if a 22problem is well-defined, it will probably be implemented at the hardware level. 23On the other hand, when there are multiple ways of achieving something without 24a very well-defined scope, the solution is usually implemented as a policy at 25the DC level. In other words, some policies are defined in the DC core 26(resource management, power optimization, image quality, etc.), and the others 27implemented in hardware are enabled via DC configuration. 28 29In terms of hardware management, DCN has multiple instances of the same block 30(e.g., HUBP, DPP, MPC, etc), and during the driver execution, it might be 31necessary to use some of these instances. The core has policies in place for 32handling those instances. Regarding resource management, the DC objective is 33quite simple: minimize the hardware shuffle when the driver performs some 34actions. When the state changes from A to B, the transition is considered 35easier to maneuver if the hardware resource is still used for the same set of 36driver objects. Usually, adding and removing a resource to a `pipe_ctx` (more 37details below) is not a problem; however, moving a resource from one `pipe_ctx` 38to another should be avoided. 39 40Another area of influence for DC is power optimization, which has a myriad of 41arrangement possibilities. In some way, just displaying an image via DCN should 42be relatively straightforward; however, showing it with the best power 43footprint is more desirable, but it has many associated challenges. 44Unfortunately, there is no straight-forward analytic way to determine if a 45configuration is the best one for the context due to the enormous variety of 46variables related to this problem (e.g., many different DCN/DCE hardware 47versions, different displays configurations, etc.) for this reason DC 48implements a dedicated library for trying some configuration and verify if it 49is possible to support it or not. This type of policy is extremely complex to 50create and maintain, and amdgpu driver relies on Display Mode Library (DML) to 51generate the best decisions. 52 53In summary, DC must deal with the complexity of handling multiple scenarios and 54determine policies to manage them. All of the above information is conveyed to 55give the reader some idea about the complexity of driving a display from the 56driver's perspective. This page hopes to allow the reader to better navigate 57over the amdgpu display code. 58 59Display Driver Architecture Overview 60==================================== 61 62The diagram below provides an overview of the display driver architecture; 63notice it illustrates the software layers adopted by DC: 64 65.. kernel-figure:: dc-components.svg 66 67The first layer of the diagram is the high-level DC API represented by the 68`dc.h` file; below it are two big blocks represented by Core and Link. Next is 69the hardware configuration block; the main file describing it is 70the`hw_sequencer.h`, where the implementation of the callbacks can be found in 71the hardware sequencer folder. Almost at the end, you can see the block level 72API (`dc/inc/hw`), which represents each DCN low-level block, such as HUBP, 73DPP, MPC, OPTC, etc. Notice on the left side of the diagram that we have a 74different set of layers representing the interaction with the DMUB 75microcontroller. 76 77Basic Objects 78------------- 79 80The below diagram outlines the basic display objects. In particular, pay 81attention to the names in the boxes since they represent a data structure in 82the driver: 83 84.. kernel-figure:: dc-arch-overview.svg 85 86Let's start with the central block in the image, `dc`. The `dc` struct is 87initialized per GPU; for example, one GPU has one `dc` instance, two GPUs have 88two `dc` instances, and so forth. In other words we have one 'dc' per 'amdgpu' 89instance. In some ways, this object behaves like the `Singleton` pattern. 90 91After the `dc` block in the diagram, you can see the `dc_link` component, which 92is a low-level abstraction for the connector. One interesting aspect of the 93image is that connectors are not part of the DCN block; they are defined by the 94platform/board and not by the SoC. The `dc_link` struct is the high-level data 95container with information such as connected sinks, connection status, signal 96types, etc. After `dc_link`, there is the `dc_sink`, which is the object that 97represents the connected display. 98 99.. note:: 100 For historical reasons, we used the name `dc_link`, which gives the 101 wrong impression that this abstraction only deals with physical connections 102 that the developer can easily manipulate. However, this also covers 103 conections like eDP or cases where the output is connected to other devices. 104 105There are two structs that are not represented in the diagram since they were 106elaborated in the DCN overview page (check the DCN block diagram :ref:`Display 107Core Next (DCN) <dcn_overview>`); still, it is worth bringing back for this 108overview which is `dc_stream` and `dc_state`. The `dc_stream` stores many 109properties associated with the data transmission, but most importantly, it 110represents the data flow from the connector to the display. Next we have 111`dc_state`, which represents the logic state within the hardware at the moment; 112`dc_state` is composed of `dc_stream` and `dc_plane`. The `dc_stream` is the DC 113version of `drm_crtc` and represents the post-blending pipeline. 114 115Speaking of the `dc_plane` data structure (first part of the diagram), you can 116think about it as an abstraction similar to `drm_plane` that represents the 117pre-blending portion of the pipeline. This image was probably processed by GFX 118and is ready to be composited under a `dc_stream`. Normally, the driver may 119have one or more `dc_plane` connected to the same `dc_stream`, which defines a 120composition at the DC level. 121 122Basic Operations 123---------------- 124 125Now that we have covered the basic objects, it is time to examine some of the 126basic hardware/software operations. Let's start with the `dc_create()` 127function, which directly works with the `dc` data struct; this function behaves 128like a constructor responsible for the basic software initialization and 129preparing for enabling other parts of the API. It is important to highlight 130that this operation does not touch any hardware configuration; it is only a 131software initialization. 132 133Next, we have the `dc_hardware_init()`, which also relies on the `dc` data 134struct. Its main function is to put the hardware in a valid state. It is worth 135highlighting that the hardware might initialize in an unknown state, and it is 136a requirement to put it in a valid state; this function has multiple callbacks 137for the hardware-specific initialization, whereas `dc_hardware_init` does the 138hardware initialization and is the first point where we touch hardware. 139 140The `dc_get_link_at_index` is an operation that depends on the `dc_link` data 141structure. This function retrieves and enumerates all the `dc_links` available 142on the device; this is required since this information is not part of the SoC 143definition but depends on the board configuration. As soon as the `dc_link` is 144initialized, it is useful to figure out if any of them are already connected to 145the display by using the `dc_link_detect()` function. After the driver figures 146out if any display is connected to the device, the challenging phase starts: 147configuring the monitor to show something. Nonetheless, dealing with the ideal 148configuration is not a DC task since this is the Display Manager (`amdgpu_dm`) 149responsibility which in turn is responsible for dealing with the atomic 150commits. The only interface DC provides to the configuration phase is the 151function `dc_validate_with_context` that receives the configuration information 152and, based on that, validates whether the hardware can support it or not. It is 153important to add that even if the display supports some specific configuration, 154it does not mean the DCN hardware can support it. 155 156After the DM and DC agree upon the configuration, the stream configuration 157phase starts. This task activates one or more `dc_stream` at this phase, and in 158the best-case scenario, you might be able to turn the display on with a black 159screen (it does not show anything yet since it does not have any plane 160associated with it). The final step would be to call the 161`dc_update_planes_and_stream,` which will add or remove planes. 162 163