| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- ====================
- DC Programming Model
- ====================
- In the :ref:`Display Core Next (DCN) <dcn_overview>` and :ref:`DCN Block
- <dcn_blocks>` pages, you learned about the hardware components and how they
- interact with each other. On this page, the focus is shifted to the display
- code architecture. Hence, it is reasonable to remind the reader that the code
- in DC is shared with other OSes; for this reason, DC provides a set of
- abstractions and operations to connect different APIs with the hardware
- configuration. See DC as a service available for a Display Manager (amdgpu_dm)
- to access and configure DCN/DCE hardware (DCE is also part of DC, but for
- simplicity's sake, this documentation only examines DCN).
- .. note::
- For this page, we will use the term GPU to refers to dGPU and APU.
- Overview
- ========
- From the display hardware perspective, it is plausible to expect that if a
- problem is well-defined, it will probably be implemented at the hardware level.
- On the other hand, when there are multiple ways of achieving something without
- a very well-defined scope, the solution is usually implemented as a policy at
- the DC level. In other words, some policies are defined in the DC core
- (resource management, power optimization, image quality, etc.), and the others
- implemented in hardware are enabled via DC configuration.
- In terms of hardware management, DCN has multiple instances of the same block
- (e.g., HUBP, DPP, MPC, etc), and during the driver execution, it might be
- necessary to use some of these instances. The core has policies in place for
- handling those instances. Regarding resource management, the DC objective is
- quite simple: minimize the hardware shuffle when the driver performs some
- actions. When the state changes from A to B, the transition is considered
- easier to maneuver if the hardware resource is still used for the same set of
- driver objects. Usually, adding and removing a resource to a `pipe_ctx` (more
- details below) is not a problem; however, moving a resource from one `pipe_ctx`
- to another should be avoided.
- Another area of influence for DC is power optimization, which has a myriad of
- arrangement possibilities. In some way, just displaying an image via DCN should
- be relatively straightforward; however, showing it with the best power
- footprint is more desirable, but it has many associated challenges.
- Unfortunately, there is no straight-forward analytic way to determine if a
- configuration is the best one for the context due to the enormous variety of
- variables related to this problem (e.g., many different DCN/DCE hardware
- versions, different displays configurations, etc.) for this reason DC
- implements a dedicated library for trying some configuration and verify if it
- is possible to support it or not. This type of policy is extremely complex to
- create and maintain, and amdgpu driver relies on Display Mode Library (DML) to
- generate the best decisions.
- In summary, DC must deal with the complexity of handling multiple scenarios and
- determine policies to manage them. All of the above information is conveyed to
- give the reader some idea about the complexity of driving a display from the
- driver's perspective. This page hopes to allow the reader to better navigate
- over the amdgpu display code.
- Display Driver Architecture Overview
- ====================================
- The diagram below provides an overview of the display driver architecture;
- notice it illustrates the software layers adopted by DC:
- .. kernel-figure:: dc-components.svg
- The first layer of the diagram is the high-level DC API represented by the
- `dc.h` file; below it are two big blocks represented by Core and Link. Next is
- the hardware configuration block; the main file describing it is
- the`hw_sequencer.h`, where the implementation of the callbacks can be found in
- the hardware sequencer folder. Almost at the end, you can see the block level
- API (`dc/inc/hw`), which represents each DCN low-level block, such as HUBP,
- DPP, MPC, OPTC, etc. Notice on the left side of the diagram that we have a
- different set of layers representing the interaction with the DMUB
- microcontroller.
- Basic Objects
- -------------
- The below diagram outlines the basic display objects. In particular, pay
- attention to the names in the boxes since they represent a data structure in
- the driver:
- .. kernel-figure:: dc-arch-overview.svg
- Let's start with the central block in the image, `dc`. The `dc` struct is
- initialized per GPU; for example, one GPU has one `dc` instance, two GPUs have
- two `dc` instances, and so forth. In other words we have one 'dc' per 'amdgpu'
- instance. In some ways, this object behaves like the `Singleton` pattern.
- After the `dc` block in the diagram, you can see the `dc_link` component, which
- is a low-level abstraction for the connector. One interesting aspect of the
- image is that connectors are not part of the DCN block; they are defined by the
- platform/board and not by the SoC. The `dc_link` struct is the high-level data
- container with information such as connected sinks, connection status, signal
- types, etc. After `dc_link`, there is the `dc_sink`, which is the object that
- represents the connected display.
- .. note::
- For historical reasons, we used the name `dc_link`, which gives the
- wrong impression that this abstraction only deals with physical connections
- that the developer can easily manipulate. However, this also covers
- connections like eDP or cases where the output is connected to other devices.
- There are two structs that are not represented in the diagram since they were
- elaborated in the DCN overview page (check the DCN block diagram :ref:`Display
- Core Next (DCN) <dcn_overview>`); still, it is worth bringing back for this
- overview which is `dc_stream` and `dc_state`. The `dc_stream` stores many
- properties associated with the data transmission, but most importantly, it
- represents the data flow from the connector to the display. Next we have
- `dc_state`, which represents the logic state within the hardware at the moment;
- `dc_state` is composed of `dc_stream` and `dc_plane`. The `dc_stream` is the DC
- version of `drm_crtc` and represents the post-blending pipeline.
- Speaking of the `dc_plane` data structure (first part of the diagram), you can
- think about it as an abstraction similar to `drm_plane` that represents the
- pre-blending portion of the pipeline. This image was probably processed by GFX
- and is ready to be composited under a `dc_stream`. Normally, the driver may
- have one or more `dc_plane` connected to the same `dc_stream`, which defines a
- composition at the DC level.
- Basic Operations
- ----------------
- Now that we have covered the basic objects, it is time to examine some of the
- basic hardware/software operations. Let's start with the `dc_create()`
- function, which directly works with the `dc` data struct; this function behaves
- like a constructor responsible for the basic software initialization and
- preparing for enabling other parts of the API. It is important to highlight
- that this operation does not touch any hardware configuration; it is only a
- software initialization.
- Next, we have the `dc_hardware_init()`, which also relies on the `dc` data
- struct. Its main function is to put the hardware in a valid state. It is worth
- highlighting that the hardware might initialize in an unknown state, and it is
- a requirement to put it in a valid state; this function has multiple callbacks
- for the hardware-specific initialization, whereas `dc_hardware_init` does the
- hardware initialization and is the first point where we touch hardware.
- The `dc_get_link_at_index` is an operation that depends on the `dc_link` data
- structure. This function retrieves and enumerates all the `dc_links` available
- on the device; this is required since this information is not part of the SoC
- definition but depends on the board configuration. As soon as the `dc_link` is
- initialized, it is useful to figure out if any of them are already connected to
- the display by using the `dc_link_detect()` function. After the driver figures
- out if any display is connected to the device, the challenging phase starts:
- configuring the monitor to show something. Nonetheless, dealing with the ideal
- configuration is not a DC task since this is the Display Manager (`amdgpu_dm`)
- responsibility which in turn is responsible for dealing with the atomic
- commits. The only interface DC provides to the configuration phase is the
- function `dc_validate_with_context` that receives the configuration information
- and, based on that, validates whether the hardware can support it or not. It is
- important to add that even if the display supports some specific configuration,
- it does not mean the DCN hardware can support it.
- After the DM and DC agree upon the configuration, the stream configuration
- phase starts. This task activates one or more `dc_stream` at this phase, and in
- the best-case scenario, you might be able to turn the display on with a black
- screen (it does not show anything yet since it does not have any plane
- associated with it). The final step would be to call the
- `dc_update_planes_and_stream,` which will add or remove planes.
|