programming-model-dcn.rst 8.9 KB

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