Merge tag 'amd-drm-next-6.1-2022-09-08' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.1-2022-09-08:

amdgpu:
- Mode2 reset for RDNA2
- Lots of new DC documentation
- Add documentation about different asic families
- DSC improvements
- Aldebaran fixes
- Misc spelling and grammar fixes
- GFXOFF stats support for vangogh
- DC frame size fixes
- NBIO 7.7 updates
- DCN 3.2 updates
- DCN 3.1.4 Updates
- SMU 13.x updates
- Misc bug fixes
- Rework DC register offset handling
- GC 11.x updates
- PSP 13.x updates
- SDMA 6.x updates
- GMC 11.x updates
- SR-IOV updates
- PSP fixes for TA unloading
- DSC passthrough support
- Misc code cleanups

amdkfd:
- ISA fixes for some GC 10.3 IPs
- Misc code cleanups

radeon:
- Delayed work flush fix
- Use time_after for some jiffies calculations

drm:
- DSC passthrough aux support

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220908155202.57862-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2022-09-12 19:17:40 +10:00
commit 47519d8224
181 changed files with 69775 additions and 3688 deletions

View File

@ -0,0 +1,8 @@
Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version
Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0
Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1
SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1
Ryzen 5000 series, GREEN SARDINE, DCN 2.1, 9.3, VCN 2.2, 4.1.1
Ryzen 6000 Zen, YELLOW CARP, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3
1 Product Name Code Reference DCN/DCE version GC version VCE/UVD/VCN version SDMA version
2 Radeon R* Graphics CARRIZO/STONEY DCE 11 8 VCE 3 / UVD 6 3
3 Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx RAVEN/PICASSO DCN 1.0 9.1.0 VCN 1.0 4.1.0
4 Ryzen 4000 series RENOIR DCN 2.1 9.3 VCN 2.2 4.1.2
5 Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx RAVEN2 DCN 1.0 9.2.2 VCN 1.0.1 4.1.1
6 SteamDeck VANGOGH DCN 3.0.1 10.3.1 VCN 3.1.0 5.2.1
7 Ryzen 5000 series GREEN SARDINE DCN 2.1 9.3 VCN 2.2 4.1.1
8 Ryzen 6000 Zen YELLOW CARP 3.1.2 10.3.3 VCN 3.1.1 5.2.3

View File

@ -0,0 +1,24 @@
Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version
AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, --
AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1
AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1
AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2
AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3
AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3
Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0
AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0
MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2
MI200, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0
AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0
AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2
AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0
AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2
AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4
AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5
1 Product Name Code Reference DCN/DCE version GC version VCN version SDMA version
2 AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series HAINAN -- 6 -- --
3 AMD Radeon HD 7800 /7900 /FireGL Series TAHITI DCE 6 6 VCE 1 / UVD 3 --
4 AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M OLAND DCE 6 6 VCE 1 / UVD 3 --
5 AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series PITCAIRN DCE 6 6 VCE 1 / UVD 3 --
6 AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series VERDE DCE 6 6 VCE 1 / UVD 3 --
7 AMD Radeon HD M280X /M380 /7700 /8950 /W5100 BONAIRE DCE 8 7 VCE 2 / UVD 4.2 1
8 AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series HAWAII DCE 8 7 VCE 2 / UVD 4.2 1
9 AMD Radeon (TM) R(5|7) M315 /M340 /M360 TOPAZ * 8 -- 2
10 AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series TONGA DCE 10 8 VCE 3 / UVD 5 3
11 AMD Radeon (FirePro) (TM) R9 Fury Series FIJI DCE 10 8 VCE 3 / UVD 6 3
12 Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH POLARIS10 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
13 Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series POLARIS11 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
14 Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series POLARIS12 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
15 Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU VEGA10 DCE 12 9.0.1 VCE 4.0.0 / UVD 7.0.0 4.0.0
16 AMD Radeon (Pro) VII /MI50 /MI60 VEGA20 DCE 12 9.4.0 VCE 4.1.0 / UVD 7.2.0 4.2.0
17 MI100 ARCTURUS * 9.4.1 VCN 2.5.0 4.2.2
18 MI200 ALDEBARAN * 9.4.2 VCN 2.6.0 4.4.0
19 AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700 NAVI10 DCN 2.0.0 10.1.10 VCN 2.0.0 5.0.0
20 AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500 NAVI14 DCN 2.0.0 10.1.1 VCN 2.0.2 5.0.2
21 AMD Radeon RX 6800(XT) /6900(XT) /W6800 SIENNA_CICHLID DCN 3.0.0 10.3.0 VCN 3.0.0 5.2.0
22 AMD Radeon RX 6700 XT / 6800M / 6700M NAVY_FLOUNDER DCN 3.0.0 10.3.2 VCN 3.0.0 5.2.2
23 AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M DIMGREY_CAVEFISH DCN 3.0.2 10.3.4 VCN 3.0.16 5.2.4
24 AMD Radeon RX 6500M /6300M /W6500M /W6300M BEIGE_GOBY DCN 3.0.3 10.3.5 VCN 3.0.33 5.2.5

View File

@ -170,7 +170,7 @@ consider asking in the amdgfx and update this page.
MC
Memory Controller
MPC
MPC/MPCC
Multiple pipes and plane combine
MPO

View File

@ -124,6 +124,65 @@ depth format), bit-depth reduction/dithering would kick in. In OPP, we would
also apply a regamma function to introduce the gamma removed earlier back.
Eventually, we output data in integer format at DIO.
AMD Hardware Pipeline
---------------------
When discussing graphics on Linux, the **pipeline** term can sometimes be
overloaded with multiple meanings, so it is important to define what we mean
when we say **pipeline**. In the DCN driver, we use the term **hardware
pipeline** or **pipeline** or just **pipe** as an abstraction to indicate a
sequence of DCN blocks instantiated to address some specific configuration. DC
core treats DCN blocks as individual resources, meaning we can build a pipeline
by taking resources for all individual hardware blocks to compose one pipeline.
In actuality, we can't connect an arbitrary block from one pipe to a block from
another pipe; they are routed linearly, except for DSC, which can be
arbitrarily assigned as needed. We have this pipeline concept for trying to
optimize bandwidth utilization.
.. kernel-figure:: pipeline_4k_no_split.svg
Additionally, let's take a look at parts of the DTN log (see
'Documentation/gpu/amdgpu/display/dc-debug.rst' for more information) since
this log can help us to see part of this pipeline behavior in real-time::
HUBP: format addr_hi width height ...
[ 0]: 8h 81h 3840 2160
[ 1]: 0h 0h 0 0
[ 2]: 0h 0h 0 0
[ 3]: 0h 0h 0 0
[ 4]: 0h 0h 0 0
...
MPCC: OPP DPP ...
[ 0]: 0h 0h ...
The first thing to notice from the diagram and DTN log it is the fact that we
have different clock domains for each part of the DCN blocks. In this example,
we have just a single **pipeline** where the data flows from DCHUB to DIO, as
we intuitively expect. Nonetheless, DCN is flexible, as mentioned before, and
we can split this single pipe differently, as described in the below diagram:
.. kernel-figure:: pipeline_4k_split.svg
Now, if we inspect the DTN log again we can see some interesting changes::
HUBP: format addr_hi width height ...
[ 0]: 8h 81h 1920 2160 ...
...
[ 4]: 0h 0h 0 0 ...
[ 5]: 8h 81h 1920 2160 ...
...
MPCC: OPP DPP ...
[ 0]: 0h 0h ...
[ 5]: 0h 5h ...
From the above example, we now split the display pipeline into two vertical
parts of 1920x2160 (i.e., 3440x2160), and as a result, we could reduce the
clock frequency in the DPP part. This is not only useful for saving power but
also to better handle the required throughput. The idea to keep in mind here is
that the pipe configuration can vary a lot according to the display
configuration, and it is the DML's responsibility to set up all required
configuration parameters for multiple scenarios supported by our hardware.
Global Sync
-----------

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -40,3 +40,144 @@ Atomic Implementation
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
:functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
Color Management Properties
===========================
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
:doc: overview
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
:internal:
DC Color Capabilities between DCN generations
---------------------------------------------
DRM/KMS framework defines three CRTC color correction properties: degamma,
color transformation matrix (CTM) and gamma, and two properties for degamma and
gamma LUT sizes. AMD DC programs some of the color correction features
pre-blending but DRM/KMS has not per-plane color correction properties.
In general, the DRM CRTC color properties are programmed to DC, as follows:
CRTC gamma after blending, and CRTC degamma pre-blending. Although CTM is
programmed after blending, it is mapped to DPP hw blocks (pre-blending). Other
color caps available in the hw is not currently exposed by DRM interface and
are bypassed.
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
:doc: color-management-caps
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
:internal:
The color pipeline has undergone major changes between DCN hardware
generations. What's possible to do before and after blending depends on
hardware capabilities, as illustrated below by the DCN 2.0 and DCN 3.0 families
schemas.
**DCN 2.0 family color caps and mapping**
.. kernel-figure:: dcn2_cm_drm_current.svg
**DCN 3.0 family color caps and mapping**
.. kernel-figure:: dcn3_cm_drm_current.svg
Blend Mode Properties
=====================
Pixel blend mode is a DRM plane composition property of :c:type:`drm_plane` used to
describes how pixels from a foreground plane (fg) are composited with the
background plane (bg). Here, we present main concepts of DRM blend mode to help
to understand how this property is mapped to AMD DC interface. See more about
this DRM property and the alpha blending equations in :ref:`DRM Plane
Composition Properties <plane_composition_properties>`.
Basically, a blend mode sets the alpha blending equation for plane
composition that fits the mode in which the alpha channel affects the state of
pixel color values and, therefore, the resulted pixel color. For
example, consider the following elements of the alpha blending equation:
- *fg.rgb*: Each of the RGB component values from the foreground's pixel.
- *fg.alpha*: Alpha component value from the foreground's pixel.
- *bg.rgb*: Each of the RGB component values from the background.
- *plane_alpha*: Plane alpha value set by the **plane "alpha" property**, see
more in :ref:`DRM Plane Composition Properties <plane_composition_properties>`.
in the basic alpha blending equation::
out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
the alpha channel value of each pixel in a plane is ignored and only the plane
alpha affects the resulted pixel color values.
DRM has three blend mode to define the blend formula in the plane composition:
* **None**: Blend formula that ignores the pixel alpha.
* **Pre-multiplied**: Blend formula that assumes the pixel color values in a
plane was already pre-multiplied by its own alpha channel before storage.
* **Coverage**: Blend formula that assumes the pixel color values were not
pre-multiplied with the alpha channel values.
and pre-multiplied is the default pixel blend mode, that means, when no blend
mode property is created or defined, DRM considers the plane's pixels has
pre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend test
provides a set of subtests to verify plane alpha and blend mode properties.
The DRM blend mode and its elements are then mapped by AMDGPU display manager
(DM) to program the blending configuration of the Multiple Pipe/Plane Combined
(MPC), as follows:
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:doc: mpc-overview
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:functions: mpcc_blnd_cfg
Therefore, the blending configuration for a single MPCC instance on the MPC
tree is defined by :c:type:`mpcc_blnd_cfg`, where
:c:type:`pre_multiplied_alpha` is the alpha pre-multiplied mode flag used to
set :c:type:`MPCC_ALPHA_MULTIPLIED_MODE`. It controls whether alpha is
multiplied (true/false), being only true for DRM pre-multiplied blend mode.
:c:type:`mpcc_alpha_blend_mode` defines the alpha blend mode regarding pixel
alpha and plane alpha values. It sets one of the three modes for
:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:functions: mpcc_alpha_blend_mode
DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the DRM
blend formula, as follows:
* *MPC pixel alpha* matches *DRM fg.alpha* as the alpha component value
from the plane's pixel
* *MPC global alpha* matches *DRM plane_alpha* when the pixel alpha should
be ignored and, therefore, pixel values are not pre-multiplied
* *MPC global gain* assumes *MPC global alpha* value when both *DRM
fg.alpha* and *DRM plane_alpha* participate in the blend equation
In short, *fg.alpha* is ignored by selecting
:c:type:`MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA`. On the other hand, (plane_alpha *
fg.alpha) component becomes available by selecting
:c:type:`MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN`. And the
:c:type:`MPCC_ALPHA_MULTIPLIED_MODE` defines if the pixel color values are
pre-multiplied by alpha or not.
Blend configuration flow
------------------------
The alpha blending equation is configured from DRM to DC interface by the
following path:
1. When updating a :c:type:`drm_plane_state <drm_plane_state>`, DM calls
:c:type:`fill_blending_from_plane_state()` that maps
:c:type:`drm_plane_state <drm_plane_state>` attributes to
:c:type:`dc_plane_info <dc_plane_info>` struct to be handled in the
OS-agnostic component (DC).
2. On DC interface, :c:type:`struct mpcc_blnd_cfg <mpcc_blnd_cfg>` programs the
MPCC blend configuration considering the :c:type:`dc_plane_info
<dc_plane_info>` input from DPP.

View File

@ -28,4 +28,5 @@ table of content:
display-manager.rst
dc-debug.rst
dcn-overview.rst
mpo-overview.rst
dc-glossary.rst

View File

@ -0,0 +1,435 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="160.5318mm"
height="65.443306mm"
viewBox="0 0 160.5318 65.443308"
version="1.1"
id="svg843"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="mpo-cursor.svg">
<defs
id="defs837">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1568"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1562"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker1837"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1835"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1580"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-5"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-5-2"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7-1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9-6-9"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7-1-3"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="895.68984"
inkscape:cy="-284.87808"
inkscape:document-units="mm"
inkscape:current-layer="g1433-6"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata840">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(70.035531,-11.72001)">
<g
id="g1438"
transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396545)">
<rect
y="51.228218"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392"
y="73.238098"
x="-59.718166"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="73.238098"
x="-59.718166"
id="tspan1390"
sodipodi:role="line">Cursor</tspan></text>
</g>
<g
id="g1433"
transform="matrix(0.33108827,0,0,0.33108827,-49.701591,6.5552955)">
<rect
y="116.32738"
x="-60.476192"
height="34.773811"
width="66.523811"
id="rect1388-3"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-6"
y="138.44888"
x="-53.932037"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="138.44888"
x="-53.932037"
id="tspan1390-7"
sodipodi:role="line">Plane 1</tspan></text>
</g>
<g
id="g1428"
transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396518)">
<rect
y="173.66814"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-5"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-3"
y="195.78964"
x="-62.437382"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="195.78964"
x="-62.437382"
id="tspan1390-5"
sodipodi:role="line">Plane 2</tspan></text>
</g>
<g
id="g1433-6"
transform="translate(116.41667,-9.0714256)">
<g
id="g1467"
transform="matrix(0.33108827,0,0,0.33108827,-132.72925,15.626721)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1388-3-2"
width="66.523811"
height="34.773811"
x="-60.476192"
y="116.32738" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-45.380619"
y="138.33725"
id="text1392-6-9"><tspan
sodipodi:role="line"
id="tspan1390-7-1"
x="-45.380619"
y="138.33725"
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
</g>
<g
id="g1438-2"
transform="matrix(0.33108827,0,0,0.33108827,-92.282164,27.16881)">
<rect
y="51.228218"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-7"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-0"
y="73.238098"
x="-59.718166"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="73.238098"
x="-59.718166"
id="tspan1390-9"
sodipodi:role="line">Cursor</tspan></text>
</g>
<g
id="g1433-3"
transform="matrix(0.33108827,0,0,0.33108827,-61.59731,5.6152398)">
<rect
y="116.32738"
x="-60.476192"
height="34.773811"
width="66.523811"
id="rect1388-3-6"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-6-0"
y="138.44888"
x="-53.932037"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="138.44888"
x="-53.932037"
id="tspan1390-7-6"
sodipodi:role="line">Plane 1</tspan></text>
</g>
<g
id="g1428-2"
transform="matrix(0.33108827,0,0,0.33108827,-58.743296,6.7994816)">
<rect
y="173.66814"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-5-6"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-3-1"
y="195.78964"
x="-62.437382"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="195.78964"
x="-62.437382"
id="tspan1390-5-8"
sodipodi:role="line">Plane 2</tspan></text>
</g>
<g
id="g1467-7"
transform="matrix(0.33108827,0,0,0.33108827,-28.233674,5.6152398)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1388-3-2-9"
width="66.523811"
height="34.773811"
x="-60.476192"
y="116.32738" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-45.380619"
y="138.33725"
id="text1392-6-9-2"><tspan
sodipodi:role="line"
id="tspan1390-7-1-0"
x="-45.380619"
y="138.33725"
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
x="-164.26541"
y="24.302296"
id="text1531"><tspan
sodipodi:role="line"
id="tspan1529"
x="-164.26541"
y="24.302296"
style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">DRM</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
x="-89.233742"
y="24.341078"
id="text1531-2"><tspan
sodipodi:role="line"
id="tspan1529-3"
x="-89.233742"
y="24.341078"
style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">AMD Hardware</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)"
d="m -164.26541,39.407343 h 20.27325 v 11.262913"
id="path1551"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7)"
d="m -164.11597,80.385815 h 20.27325 v -11.26291"
id="path1551-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7-2)"
d="m -59.24211,70.452123 h 20.273243 V 59.18921"
id="path1551-9-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9)"
d="m -163.61178,59.821549 h 9.26062"
id="path1551-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6)"
d="m -93.426241,50.16968 h 9.260617"
id="path1551-3-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6-9)"
d="m -59.637503,50.169684 h 9.260618"
id="path1551-3-2-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,242 @@
========================
Multiplane Overlay (MPO)
========================
.. note:: You will get more from this page if you have already read the
'Documentation/gpu/amdgpu/display/dcn-overview.rst'.
Multiplane Overlay (MPO) allows for multiple framebuffers to be composited via
fixed-function hardware in the display controller rather than using graphics or
compute shaders for composition. This can yield some power savings if it means
the graphics/compute pipelines can be put into low-power states. In summary,
MPO can bring the following benefits:
* Decreased GPU and CPU workload - no composition shaders needed, no extra
buffer copy needed, GPU can remain idle.
* Plane independent page flips - No need to be tied to global compositor
page-flip present rate, reduced latency, independent timing.
.. note:: Keep in mind that MPO is all about power-saving; if you want to learn
more about power-save in the display context, check the link:
`Power <https://gitlab.freedesktop.org/pq/color-and-hdr/-/blob/main/doc/power.rst>`__.
Multiplane Overlay is only available using the DRM atomic model. The atomic
model only uses a single userspace IOCTL for configuring the display hardware
(modesetting, page-flipping, etc) - drmModeAtomicCommit. To query hardware
resources and limitations userspace also calls into drmModeGetResources which
reports back the number of planes, CRTCs, and connectors. There are three types
of DRM planes that the driver can register and work with:
* ``DRM_PLANE_TYPE_PRIMARY``: Primary planes represent a "main" plane for a
CRTC, primary planes are the planes operated upon by CRTC modesetting and
flipping operations.
* ``DRM_PLANE_TYPE_CURSOR``: Cursor planes represent a "cursor" plane for a
CRTC. Cursor planes are the planes operated upon by the cursor IOCTLs
* ``DRM_PLANE_TYPE_OVERLAY``: Overlay planes represent all non-primary,
non-cursor planes. Some drivers refer to these types of planes as "sprites"
internally.
To illustrate how it works, let's take a look at a device that exposes the
following planes to userspace:
* 4 Primary planes (1 per CRTC).
* 4 Cursor planes (1 per CRTC).
* 1 Overlay plane (shared among CRTCs).
.. note:: Keep in mind that different ASICs might expose other numbers of
planes.
For this hardware example, we have 4 pipes (if you don't know what AMD pipe
means, look at 'Documentation/gpu/amdgpu/display/dcn-overview.rst', section
"AMD Hardware Pipeline"). Typically most AMD devices operate in a pipe-split
configuration for optimal single display output (e.g., 2 pipes per plane).
A typical MPO configuration from userspace - 1 primary + 1 overlay on a single
display - will see 4 pipes in use, 2 per plane.
At least 1 pipe must be used per plane (primary and overlay), so for this
hypothetical hardware that we are using as an example, we have an absolute
limit of 4 planes across all CRTCs. Atomic commits will be rejected for display
configurations using more than 4 planes. Again, it is important to stress that
every DCN has different restrictions; here, we are just trying to provide the
concept idea.
Plane Restrictions
==================
AMDGPU imposes restrictions on the use of DRM planes in the driver.
Atomic commits will be rejected for commits which do not follow these
restrictions:
* Overlay planes must be in ARGB8888 or XRGB8888 format
* Planes cannot be placed outside of the CRTC destination rectangle
* Planes cannot be downscaled more than 1/4x of their original size
* Planes cannot be upscaled more than 16x of their original size
Not every property is available on every plane:
* Only primary planes have color-space and non-RGB format support
* Only overlay planes have alpha blending support
Cursor Restrictions
===================
Before we start to describe some restrictions around cursor and MPO, see the
below image:
.. kernel-figure:: mpo-cursor.svg
The image on the left side represents how DRM expects the cursor and planes to
be blended. However, AMD hardware handles cursors differently, as you can see
on the right side; basically, our cursor cannot be drawn outside its associated
plane as it is being treated as part of the plane. Another consequence of that
is that cursors inherit the color and scale from the plane.
As a result of the above behavior, do not use legacy API to set up the cursor
plane when working with MPO; otherwise, you might encounter unexpected
behavior.
In short, AMD HW has no dedicated cursor planes. A cursor is attached to
another plane and therefore inherits any scaling or color processing from its
parent plane.
Use Cases
=========
Picture-in-Picture (PIP) playback - Underlay strategy
-----------------------------------------------------
Video playback should be done using the "primary plane as underlay" MPO
strategy. This is a 2 planes configuration:
* 1 YUV DRM Primary Plane (e.g. NV12 Video)
* 1 RGBA DRM Overlay Plane (e.g. ARGB8888 desktop). The compositor should
prepare the framebuffers for the planes as follows:
- The overlay plane contains general desktop UI, video player controls, and video subtitles
- Primary plane contains one or more videos
.. note:: Keep in mind that we could extend this configuration to more planes,
but that is currently not supported by our driver yet (maybe if we have a
userspace request in the future, we can change that).
See below a single-video example:
.. kernel-figure:: single-display-mpo.svg
.. note:: We could extend this behavior to more planes, but that is currently
not supported by our driver.
The video buffer should be used directly for the primary plane. The video can
be scaled and positioned for the desktop using the properties: CRTC_X, CRTC_Y,
CRTC_W, and CRTC_H. The primary plane should also have the color encoding and
color range properties set based on the source content:
* ``COLOR_RANGE``, ``COLOR_ENCODING``
The overlay plane should be the native size of the CRTC. The compositor must
draw a transparent cutout for where the video should be placed on the desktop
(i.e., set the alpha to zero). The primary plane video will be visible through
the underlay. The overlay plane's buffer may remain static while the primary
plane's framebuffer is used for standard double-buffered playback.
The compositor should create a YUV buffer matching the native size of the CRTC.
Each video buffer should be composited onto this YUV buffer for direct YUV
scanout. The primary plane should have the color encoding and color range
properties set based on the source content: ``COLOR_RANGE``,
``COLOR_ENCODING``. However, be mindful that the source color space and
encoding match for each video since it affect the entire plane.
The overlay plane should be the native size of the CRTC. The compositor must
draw a transparent cutout for where each video should be placed on the desktop
(i.e., set the alpha to zero). The primary plane videos will be visible through
the underlay. The overlay plane's buffer may remain static while compositing
operations for video playback will be done on the video buffer.
This kernel interface is validated using IGT GPU Tools. The following tests can
be run to validate positioning, blending, scaling under a variety of sequences
and interactions with operations such as DPMS and S3:
- ``kms_plane@plane-panning-bottom-right-pipe-*-planes``
- ``kms_plane@plane-panning-bottom-right-suspend-pipe-*-``
- ``kms_plane@plane-panning-top-left-pipe-*-``
- ``kms_plane@plane-position-covered-pipe-*-``
- ``kms_plane@plane-position-hole-dpms-pipe-*-``
- ``kms_plane@plane-position-hole-pipe-*-``
- ``kms_plane_multiple@atomic-pipe-*-tiling-``
- ``kms_plane_scaling@pipe-*-plane-scaling``
- ``kms_plane_alpha_blend@pipe-*-alpha-basic``
- ``kms_plane_alpha_blend@pipe-*-alpha-transparant-fb``
- ``kms_plane_alpha_blend@pipe-*-alpha-opaque-fb``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-min``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-mid``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-max``
Multiple Display MPO
--------------------
AMDGPU supports display MPO when using multiple displays; however, this feature
behavior heavily relies on the compositor implementation. Keep in mind that
usespace can define different policies. For example, some OSes can use MPO to
protect the plane that handles the video playback; notice that we don't have
many limitations for a single display. Nonetheless, this manipulation can have
many more restrictions for a multi-display scenario. The below example shows a
video playback in the middle of two displays, and it is up to the compositor to
define a policy on how to handle it:
.. kernel-figure:: multi-display-hdcp-mpo.svg
Let's discuss some of the hardware limitations we have when dealing with
multi-display with MPO.
Limitations
~~~~~~~~~~~
For simplicity's sake, for discussing the hardware limitation, this
documentation supposes an example where we have two displays and video playback
that will be moved around different displays.
* **Hardware limitations**
From the DCN overview page, each display requires at least one pipe and each
MPO plane needs another pipe. As a result, when the video is in the middle of
the two displays, we need to use 2 pipes. See the example below where we avoid
pipe split:
- 1 display (1 pipe) + MPO (1 pipe), we will use two pipes
- 2 displays (2 pipes) + MPO (1-2 pipes); we will use 4 pipes. MPO in the
middle of both displays needs 2 pipes.
- 3 Displays (3 pipes) + MPO (1-2 pipes), we need 5 pipes.
If we use MPO with multiple displays, the userspace has to decide to enable
multiple MPO by the price of limiting the number of external displays supported
or disable it in favor of multiple displays; it is a policy decision. For
example:
* When ASIC has 3 pipes, AMD hardware can NOT support 2 displays with MPO
* When ASIC has 4 pipes, AMD hardware can NOT support 3 displays with MPO
Let's briefly explore how userspace can handle these two display configurations
on an ASIC that only supports three pipes. We can have:
.. kernel-figure:: multi-display-hdcp-mpo-less-pipe-ex.svg
- Total pipes are 3
- User lights up 2 displays (2 out of 3 pipes are used)
- User launches video (1 pipe used for MPO)
- Now, if the user moves the video in the middle of 2 displays, one part of the
video won't be MPO since we have used 3/3 pipes.
* **Scaling limitation**
MPO cannot handle scaling less than 0.25 and more than x16. For example:
If 4k video (3840x2160) is playing in windowed mode, the physical size of the
window cannot be smaller than (960x540).
.. note:: These scaling limitations might vary from ASIC to ASIC.
* **Size Limitation**
The minimum MPO size is 12px.

View File

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.08798mm"
height="30.335283mm"
viewBox="0 0 103.08798 30.335284"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="multi-display-hdcp-mpo-less-pipe-ex.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="205.69673"
inkscape:cy="33.960031"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1288"
inkscape:window-height="1376"
inkscape:window-x="1272"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(112.75816,51.721433)">
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="-112.44358"
y="-51.189243"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834"
width="14.422765"
height="15.872559"
x="-78.227928"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-71.189278"
y="-48.114422"
id="text844"><tspan
sodipodi:role="line"
x="-71.189278"
y="-48.114422"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Protected</tspan><tspan
sodipodi:role="line"
x="-71.189278"
y="-45.584015"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288">MPO plane</tspan></text>
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-3"
width="48.988979"
height="29.48851"
x="-58.973743"
y="-51.406849"
ry="0" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="6.1374092"
height="15.872559"
x="-58.632965"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-107.96788"
y="-47.033775"
id="text844-7"><tspan
sodipodi:role="line"
x="-107.96788"
y="-47.033775"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-3">#1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-15.20074"
y="-46.715996"
id="text844-7-2"><tspan
sodipodi:role="line"
x="-15.20074"
y="-46.715996"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-3-9">#2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-88.926605"
y="-23.173674"
id="text844-1"><tspan
sodipodi:role="line"
x="-88.926605"
y="-23.173674"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-33.770744"
y="-23.819901"
id="text844-1-0"><tspan
sodipodi:role="line"
x="-33.770744"
y="-23.819901"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-9">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-75.17498"
y="-41.219398"
id="text844-7-2-3"><tspan
sodipodi:role="line"
x="-75.17498"
y="-41.219398"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
id="tspan846-3-9-6">#3</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-47.142235"
y="-48.056866"
id="text844-0"><tspan
sodipodi:role="line"
x="-47.142235"
y="-48.056866"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288-2">Software</tspan><tspan
sodipodi:role="line"
x="-47.142235"
y="-45.526459"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2313">Composited Video</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-36.23288"
y="-34.592064"
id="text844-1-6"><tspan
sodipodi:role="line"
x="-36.23288"
y="-34.592064"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-1">Video will not be displayed</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.08798mm"
height="30.335283mm"
viewBox="0 0 103.08798 30.335284"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="multi-display-hdcp-mpo.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="196.85789"
inkscape:cy="33.960027"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1288"
inkscape:window-height="1376"
inkscape:window-x="1272"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(112.75816,51.721433)">
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="-112.44358"
y="-51.189243"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834"
width="14.422765"
height="15.872559"
x="-78.227928"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-71.189278"
y="-48.114422"
id="text844"><tspan
sodipodi:role="line"
x="-71.189278"
y="-48.114422"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Protected</tspan><tspan
sodipodi:role="line"
x="-71.189278"
y="-45.584015"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288">MPO plane</tspan></text>
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-3"
width="48.988979"
height="29.48851"
x="-58.973743"
y="-51.406849"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="6.1374092"
height="15.872559"
x="-58.632965"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-88.926605"
y="-23.173674"
id="text844-1"><tspan
sodipodi:role="line"
x="-88.926605"
y="-23.173674"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-33.770744"
y="-23.819901"
id="text844-1-0"><tspan
sodipodi:role="line"
x="-33.770744"
y="-23.819901"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-9">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-70.364128"
y="-35.740372"
id="text844-7-2-3"><tspan
sodipodi:role="line"
x="-70.364128"
y="-35.740372"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
id="tspan846-3-9-6">Video</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,958 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1055.4928"
height="404.60379"
viewBox="0 0 279.26579 107.05142"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="pipeline_4k_no_split.svg">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616"
style="fill:#aa00d4;fill-opacity:1;fill-rule:evenodd;stroke:#aa00d4;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Send"
orient="auto"
refY="0"
refX="0"
id="Arrow2Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8622"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8592"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8610"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-8"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-4"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-5"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-1"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-4"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1-0"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616-5"
style="fill:#00ffcc;fill-opacity:1;fill-rule:evenodd;stroke:#00ffcc;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-56"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-9"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-9"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-3"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-7"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-4"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-1"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-4"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2-4"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-8"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-7"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="213.41584"
inkscape:cy="301.17934"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
showguides="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(349.34521,-0.81564989)">
<rect
style="fill:none;stroke:#000000;stroke-width:1.00353587;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none"
id="rect834"
width="30.251244"
height="88.477814"
x="-317.81958"
y="14.782127"
ry="2.5590618e-06" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-314.73792"
y="21.83947"
id="text838"><tspan
sodipodi:role="line"
id="tspan836"
x="-314.73792"
y="21.83947"
style="stroke-width:0.16370411">DCHUB</tspan></text>
<g
id="g2025"
transform="translate(-2.4916954,-1.2533369)">
<text
id="text838-5"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3"
sodipodi:role="line">DPP</tspan><tspan
id="tspan936"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.1637041"
x="-297.75696"
y="109.44505"
id="text1063"><tspan
sodipodi:role="line"
id="tspan1061"
x="-297.75696"
y="115.23865"
style="stroke-width:0.1637041" /></text>
<g
id="g1878"
transform="translate(-0.62971878)">
<text
id="text846"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(0)</tspan></text>
<g
id="g1853">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<g
transform="translate(-0.62971878,18.810271)"
id="g1878-1">
<text
id="text846-2"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844-7"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863-0"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(1)</tspan></text>
<g
id="g1853-9">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850-3"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<g
transform="translate(-0.62971878,57.029814)"
id="g1878-8">
<text
id="text846-7"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844-9"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863-20"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(5)</tspan></text>
<g
id="g1853-2">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850-37"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-310.7348"
y="72.106789"
id="text8862-5"><tspan
sodipodi:role="line"
id="tspan8860-9"
x="-310.7348"
y="72.106789"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#44aa00;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94)"
d="m -288.90777,32.862737 h 14.20296"
id="path1171"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-264.85431"
y="62.072891"
id="text8862-5-8"><tspan
sodipodi:role="line"
id="tspan8860-9-4"
x="-264.85431"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<g
id="g2025-5"
transform="translate(40.522337,-1.1484419)" />
<g
id="g7343"
transform="translate(40.522337,-1.2533369)">
<text
id="text838-5-6"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3-3"
sodipodi:role="line">MPC</tspan><tspan
id="tspan936-2"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5-0"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<g
id="g7343-2"
transform="translate(84.178583,-1.2533369)">
<text
id="text838-5-6-54"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3-3-7"
sodipodi:role="line">OPP</tspan><tspan
id="tspan936-2-44"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5-0-3"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-221.84029"
y="62.072891"
id="text8862-5-8-6"><tspan
sodipodi:role="line"
id="tspan8860-9-4-5"
x="-221.84029"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6)"
d="m -240.90479,32.86192 h 10.61353"
id="path1171-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0)"
d="m -198.19009,32.86192 h 10.61353"
id="path1171-3-8"
inkscape:connector-curvature="0" />
<g
id="g7343-2-2"
transform="translate(127.15447,-1.1484419)">
<text
id="text838-5-6-54-0"
y="65.122154"
x="-254.32814"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
id="tspan936-2-44-8"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="65.122154"
x="-254.32814"
sodipodi:role="line">OPTC</tspan></text>
<rect
ry="2.4256708e-06"
y="20.805576"
x="-269.46042"
height="83.865906"
width="30.277332"
id="rect834-5-0-3-9"
style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2)"
d="m -154.34485,32.86192 h 10.61353"
id="path1171-3-8-6"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-178.18404"
y="62.072891"
id="text8862-5-8-6-0"><tspan
sodipodi:role="line"
id="tspan8860-9-4-5-4"
x="-178.18404"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:#000000;stroke:#000000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-8)"
d="m -335.20986,59.030276 h 14.20296"
id="path1171-17"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-349.77686"
y="61.404655"
id="text838-2"><tspan
sodipodi:role="line"
id="tspan836-7"
x="-349.77686"
y="61.404655"
style="stroke-width:0.16370411">SDP</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291667, 1.32291667;stroke-dashoffset:0;stroke-opacity:1"
d="M -279.04164,107.86706 V 0.89985833"
id="path11907"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.3229167, 1.3229167;stroke-dashoffset:0;stroke-opacity:1"
d="M -235.57438,107.86707 V 0.89985663"
id="path11907-6-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291671, 1.32291671;stroke-dashoffset:0;stroke-opacity:1"
d="M -149.96277,107.86707 V 0.89985223"
id="path11907-6-1-0"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-257.38275"
y="5.003336"
id="text838-6"><tspan
sodipodi:role="line"
id="tspan836-1"
x="-257.38275"
y="5.003336"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DPPCLK</tspan><tspan
sodipodi:role="line"
x="-257.38275"
y="13.188541"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
id="tspan12658">535.916Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-192.85298"
y="5.003336"
id="text838-6-5"><tspan
sodipodi:role="line"
id="tspan836-1-9"
x="-192.85298"
y="5.003336"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DISPCLK</tspan><tspan
sodipodi:role="line"
x="-192.85298"
y="13.188541"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
id="tspan12662">541.275 Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-302.03766"
y="5.003336"
id="text838-6-5-4"><tspan
sodipodi:role="line"
id="tspan836-1-9-9"
x="-312.23135"
y="5.003336"
style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center">DCFCLK</tspan><tspan
sodipodi:role="line"
x="-312.23135"
y="13.188541"
style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center"
id="tspan12660">506 Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-96.075348"
y="4.568048"
id="text838-6-5-0"><tspan
sodipodi:role="line"
id="tspan836-1-9-91"
x="-96.075348"
y="4.568048"
style="font-size:4.93888903px;stroke-width:0.16370411">SymCLK</tspan></text>
<g
id="g7343-2-2-7"
transform="translate(168.61494,-1.1484419)">
<text
id="text838-5-6-54-0-7"
y="65.122154"
x="-254.32814"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
id="tspan936-2-44-8-1"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="65.122154"
x="-254.32814"
sodipodi:role="line">DIO</tspan></text>
<rect
ry="2.4256708e-06"
y="20.805576"
x="-269.46042"
height="83.865906"
width="30.277332"
id="rect834-5-0-3-9-1"
style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291672, 1.32291672;stroke-dashoffset:0;stroke-opacity:1"
d="M -108.38539,107.86707 V 0.89985092"
id="path11907-6-1-0-5"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-143.52292"
y="5.0467439"
id="text838-6-5-0-9"><tspan
sodipodi:role="line"
id="tspan836-1-9-91-7"
x="-143.52292"
y="5.0467439"
style="font-size:4.93888903px;stroke-width:0.16370411">VirtualPCLK</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2-7)"
d="m -112.24183,60.747629 h 10.61353"
id="path1171-3-8-6-7"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="112.16296mm"
height="93.314507mm"
viewBox="0 0 112.16296 93.314508"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="single-display-mpo-multi-video.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1006"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="255.95284"
inkscape:cy="222.25473"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1514"
inkscape:window-height="1376"
inkscape:window-x="1046"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.189925,5.2546503)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-2.2053311"
y="32.839729"
id="text844"><tspan
sodipodi:role="line"
x="-2.2053313"
y="32.839729"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Video Buffer (YUV)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="30.867918"
y="87.638779"
id="text844-2"><tspan
sodipodi:role="line"
x="30.867918"
y="87.638779"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0">CRTC Output</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.53249496;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.59748484, 0.53249495;stroke-dashoffset:0"
id="rect969"
width="111.63046"
height="44.238331"
x="-25.923677"
y="-4.9884028" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="48.037342"
y="45.781586"
id="text844-2-9"><tspan
sodipodi:role="line"
x="48.037342"
y="45.781586"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2868">Hardware Composition</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
d="m 32.66992,40.326865 v 9.760144"
id="path989"
inkscape:connector-curvature="0" />
<g
id="g4447"
style="stroke:#000000">
<rect
ry="0"
y="0.23764905"
x="-23.784248"
height="29.48851"
width="48.988979"
id="rect836"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184125"
x="-20.589451"
height="6.9794898"
width="11.594959"
id="rect836-2-6"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184123"
x="-5.6613555"
height="6.9794903"
width="11.594959"
id="rect836-2-6-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184121"
x="10.374816"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="-20.341679"
height="6.9794903"
width="11.594959"
id="rect836-2-6-7"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="-5.4135842"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-9"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="10.622585"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-2"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
<rect
style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2"
width="48.988979"
height="29.48851"
x="31.367332"
y="0.45039755"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-3"
width="11.594959"
height="6.9794898"
x="34.56213"
y="4.0311608"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-7"
width="11.594959"
height="6.9794903"
x="49.490223"
y="4.0311608"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-8-5"
width="11.594959"
height="6.9794908"
x="65.526398"
y="4.0311604"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-7-9"
width="11.594959"
height="6.9794903"
x="34.809902"
y="18.599392"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-9-2"
width="11.594959"
height="6.9794908"
x="49.737995"
y="18.599392"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-8-2-2"
width="11.594959"
height="6.9794908"
x="65.774162"
y="18.599392"
ry="0" />
<g
id="g4562"
transform="translate(0,11.22532)">
<rect
ry="0"
y="43.21352"
x="5.9767256"
height="29.48851"
width="48.988979"
id="rect836-97"
style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="9.1715231"
height="6.9794898"
width="11.594959"
id="rect836-2-6-36"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="24.099619"
height="6.9794903"
width="11.594959"
id="rect836-2-6-1-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="40.135792"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-29"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="9.4192953"
height="6.9794903"
width="11.594959"
id="rect836-2-6-7-3"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="24.347389"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-9-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="40.38356"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-2-9"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="57.012939"
y="33.603645"
id="text844-4"><tspan
sodipodi:role="line"
x="57.012939"
y="33.603645"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop Buffer (ARGB)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,266 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="148.71147mm"
height="38.356358mm"
viewBox="0 0 148.71148 38.356358"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="single-display-mpo.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1006"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="266.07058"
inkscape:cy="81.254796"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1514"
inkscape:window-height="1376"
inkscape:window-x="1046"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.323559,-14.790568)">
<rect
style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="4.9472256"
y="17.075632"
ry="0" />
<g
id="g905"
transform="matrix(0.26082945,0,0,0.26082945,-26.950235,-0.99631462)">
<rect
y="67.568451"
x="12.473214"
height="60.854164"
width="102.43154"
id="rect834"
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<path
inkscape:transform-center-y="-3.581986e-06"
inkscape:transform-center-x="-3.3106064"
d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471976"
sodipodi:arg1="0"
sodipodi:r2="6.6212125"
sodipodi:r1="13.242425"
sodipodi:cy="97.995537"
sodipodi:cx="60.37838"
sodipodi:sides="3"
id="path840"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="star" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-10.357052"
y="34.176075"
id="text844"><tspan
sodipodi:role="line"
id="tspan842"
x="-10.357052"
y="34.176075"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112">Video Buffer (YUV)</tspan><tspan
sodipodi:role="line"
x="-10.357052"
y="36.706482"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">DRM PRIMARY PLANE</tspan></text>
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.5216589;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-3"
width="26.717165"
height="15.872559"
x="16.083126"
y="23.883608" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="28.437061"
y="49.158085"
id="text844-6"><tspan
sodipodi:role="line"
x="28.437061"
y="49.158085"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-5">Desktop Buffer (ARGB)</tspan><tspan
sodipodi:role="line"
x="28.437061"
y="51.688492"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan886">DRM OVERLAY PLANE</tspan></text>
<g
id="g2874"
transform="matrix(1.0858687,0,0,1.0858687,-4.5597909,-2.06277)">
<rect
ry="0"
y="17.624969"
x="71.504173"
height="27.156607"
width="45.115009"
id="rect836-9"
style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.57941455;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<g
id="g905-5"
transform="matrix(0.24020349,0,0,0.24020349,78.763353,7.664402)">
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="102.43154"
height="60.854164"
x="12.473214"
y="67.568451" />
<path
sodipodi:type="star"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="path840-2"
sodipodi:sides="3"
sodipodi:cx="60.37838"
sodipodi:cy="97.995537"
sodipodi:r1="13.242425"
sodipodi:r2="6.6212125"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
inkscape:transform-center-x="-3.3106064"
inkscape:transform-center-y="-3.581986e-06" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="97.551666"
y="50.221046"
id="text844-2"><tspan
sodipodi:role="line"
x="97.551666"
y="50.221046"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0">CRTC Output</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.42211887;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.26635657, 0.42211886;stroke-dashoffset:0"
id="rect969"
width="81.806648"
height="37.934238"
x="-26.112499"
y="15.001627" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="64.474419"
y="31.883568"
id="text844-2-9"><tspan
sodipodi:role="line"
x="64.474419"
y="31.883568"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0-3">Hardware</tspan><tspan
sodipodi:role="line"
x="64.474419"
y="34.413975"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2868">Composition</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
d="m 57.401149,24.81643 h 9.760144"
id="path989"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL-6)"
d="m 57.401149,41.794278 h 9.760144"
id="path989-6"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -32,6 +32,23 @@ unique_id
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: unique_id
Accelerated Processing Units (APU) Info
---------------------------------------
.. csv-table::
:header-rows: 1
:widths: 3, 2, 2, 1, 1, 1
:file: ./apu-asic-info-table.csv
Discrete GPU Info
-----------------
.. csv-table::
:header-rows: 1
:widths: 3, 2, 2, 1, 1, 1
:file: ./dgpu-asic-info-table.csv
GPU Memory Usage Information
============================

View File

@ -72,7 +72,8 @@ card's RLC (RunList Controller) firmware powers off the gfx engine
dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by
default on supported GPUs.
Userspace can interact with GFXOFF through a debugfs interface:
Userspace can interact with GFXOFF through a debugfs interface (all values in
`uint32_t`, unless otherwise noted):
``amdgpu_gfxoff``
-----------------
@ -104,3 +105,18 @@ Read it to check current GFXOFF's status of a GPU::
If GFXOFF is enabled, the value will be transitioning around [0, 3], always
getting into 0 when possible. When it's disabled, it's always at 2. Returns
``-EINVAL`` if it's not supported.
``amdgpu_gfxoff_count``
-----------------------
Read it to get the total GFXOFF entry count at the time of query since system
power-up. The value is an `uint64_t` type, however, due to firmware limitations,
it can currently overflow as an `uint32_t`. *Only supported in vangogh*
``amdgpu_gfxoff_residency``
---------------------------
Write 1 to amdgpu_gfxoff_residency to start logging, and 0 to stop. Read it to
get average GFXOFF residency % multiplied by 100 during the last logging
interval. E.g. a value of 7854 means 78.54% of the time in the last logging
interval the GPU was in GFXOFF mode. *Only supported in vangogh*

View File

@ -532,6 +532,8 @@ Standard Plane Properties
.. kernel-doc:: drivers/gpu/drm/drm_plane.c
:doc: standard plane properties
.. _plane_composition_properties:
Plane Composition Properties
----------------------------

View File

@ -75,7 +75,7 @@ amdgpu-y += \
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
sienna_cichlid.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
# add DF block
amdgpu-y += \
@ -89,7 +89,7 @@ amdgpu-y += \
gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
mmhub_v3_0_1.o
mmhub_v3_0_1.o gfxhub_v3_0_3.o
# add UMC block
amdgpu-y += \
@ -134,7 +134,8 @@ amdgpu-y += \
gfx_v9_4_2.o \
gfx_v10_0.o \
imu_v11_0.o \
gfx_v11_0.o
gfx_v11_0.o \
imu_v11_0_3.o
# add async DMA block
amdgpu-y += \

View File

@ -274,6 +274,9 @@ extern int amdgpu_vcnfw_log;
#define AMDGPU_RESET_VCE (1 << 13)
#define AMDGPU_RESET_VCE1 (1 << 14)
#define AMDGPU_RESET_LEVEL_SOFT_RECOVERY (1 << 0)
#define AMDGPU_RESET_LEVEL_MODE2 (1 << 1)
/* max cursor sizes (in pixels) */
#define CIK_CURSOR_WIDTH 128
#define CIK_CURSOR_HEIGHT 128
@ -1060,6 +1063,9 @@ struct amdgpu_device {
uint32_t scpm_status;
struct work_struct reset_work;
uint32_t amdgpu_reset_level_mask;
bool job_hang;
};
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)

View File

@ -1066,6 +1066,12 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
(pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
return false;
/*
* If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
* risky to do any special firmware-related preparations for entering
* S0ix even though the system is suspending to idle, so return false
* in that case.
*/
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
dev_warn_once(adev->dev,
"Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"

View File

@ -135,6 +135,7 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}

View File

@ -1728,7 +1728,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
if (user_addr) {
pr_debug("creating userptr BO for user_addr = %llu\n", user_addr);
pr_debug("creating userptr BO for user_addr = %llx\n", user_addr);
ret = init_user_pages(*mem, user_addr, criu_resume);
if (ret)
goto allocate_init_user_pages_failed;

View File

@ -402,7 +402,7 @@ static void amdgpu_ctx_fini(struct kref *ref)
}
}
if (drm_dev_enter(&adev->ddev, &idx)) {
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
drm_dev_exit(idx);
}

View File

@ -1042,6 +1042,157 @@ err:
return r;
}
/**
* amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency
*
* @f: open file handle
* @buf: User buffer to store read data in
* @size: Number of bytes to read
* @pos: Offset to seek to
*
* Read the last residency value logged. It doesn't auto update, one needs to
* stop logging before getting the current value.
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
uint32_t value;
r = amdgpu_get_gfx_off_residency(adev, &value);
if (r)
goto out;
r = put_user(value, (uint32_t *)buf);
if (r)
goto out;
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency
*
* @f: open file handle
* @buf: User buffer to write data from
* @size: Number of bytes to write
* @pos: Offset to seek to
*
* Write a 32-bit non-zero to start logging; write a 32-bit zero to stop
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
u32 value;
r = get_user(value, (uint32_t *)buf);
if (r)
goto out;
amdgpu_set_gfx_off_residency(adev, value ? true : false);
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count
*
* @f: open file handle
* @buf: User buffer to store read data in
* @size: Number of bytes to read
* @pos: Offset to seek to
*/
static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
u64 value = 0;
r = amdgpu_get_gfx_off_entrycount(adev, &value);
if (r)
goto out;
r = put_user(value, (u64 *)buf);
if (r)
goto out;
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
*
@ -1249,6 +1400,19 @@ static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
.llseek = default_llseek
};
static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = {
.owner = THIS_MODULE,
.read = amdgpu_debugfs_gfxoff_count_read,
.llseek = default_llseek
};
static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = {
.owner = THIS_MODULE,
.read = amdgpu_debugfs_gfxoff_residency_read,
.write = amdgpu_debugfs_gfxoff_residency_write,
.llseek = default_llseek
};
static const struct file_operations *debugfs_regs[] = {
&amdgpu_debugfs_regs_fops,
&amdgpu_debugfs_regs2_fops,
@ -1261,6 +1425,8 @@ static const struct file_operations *debugfs_regs[] = {
&amdgpu_debugfs_gpr_fops,
&amdgpu_debugfs_gfxoff_fops,
&amdgpu_debugfs_gfxoff_status_fops,
&amdgpu_debugfs_gfxoff_count_fops,
&amdgpu_debugfs_gfxoff_residency_fops,
};
static const char *debugfs_regs_names[] = {
@ -1275,6 +1441,8 @@ static const char *debugfs_regs_names[] = {
"amdgpu_gpr",
"amdgpu_gfxoff",
"amdgpu_gfxoff_status",
"amdgpu_gfxoff_count",
"amdgpu_gfxoff_residency",
};
/**
@ -1786,6 +1954,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
return PTR_ERR(ent);
}
debugfs_create_u32("amdgpu_reset_level", 0600, root, &adev->amdgpu_reset_level_mask);
/* Register debugfs entries for amdgpu_ttm */
amdgpu_ttm_debugfs_init(adev);
amdgpu_debugfs_pm_init(adev);

View File

@ -2456,12 +2456,14 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (!hive->reset_domain ||
!amdgpu_reset_get_reset_domain(hive->reset_domain)) {
r = -ENOENT;
amdgpu_put_xgmi_hive(hive);
goto init_failed;
}
/* Drop the early temporary reset domain we created for device */
amdgpu_reset_put_reset_domain(adev->reset_domain);
adev->reset_domain = hive->reset_domain;
amdgpu_put_xgmi_hive(hive);
}
}
@ -3577,6 +3579,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
adev->gfx.gfx_off_req_count = 1;
adev->gfx.gfx_off_residency = 0;
adev->gfx.gfx_off_entrycount = 0;
adev->pm.ac_power = power_supply_is_system_supplied() > 0;
atomic_set(&adev->throttling_logging_enabled, 1);
@ -3965,8 +3969,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
amdgpu_gart_dummy_page_fini(adev);
if (drm_dev_is_unplugged(adev_to_drm(adev)))
amdgpu_device_unmap_mmio(adev);
amdgpu_device_unmap_mmio(adev);
}
@ -4413,8 +4416,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
retry:
amdgpu_amdkfd_pre_reset(adev);
amdgpu_amdkfd_pre_reset(adev);
if (from_hypervisor)
r = amdgpu_virt_request_full_gpu(adev, true);
else
@ -4509,14 +4510,15 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
*/
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
{
if (!amdgpu_device_ip_check_soft_reset(adev)) {
dev_info(adev->dev, "Timeout, but no hardware hang detected.\n");
return false;
}
if (amdgpu_gpu_recovery == 0)
goto disabled;
if (!amdgpu_device_ip_check_soft_reset(adev)) {
dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
return false;
}
if (amdgpu_sriov_vf(adev))
return true;
@ -4641,7 +4643,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
if (!need_full_reset)
need_full_reset = amdgpu_device_ip_need_full_reset(adev);
if (!need_full_reset) {
if (!need_full_reset && amdgpu_gpu_recovery) {
amdgpu_device_ip_pre_soft_reset(adev);
r = amdgpu_device_ip_soft_reset(adev);
amdgpu_device_ip_post_soft_reset(adev);
@ -5039,6 +5041,7 @@ static void amdgpu_device_recheck_guilty_jobs(
/* set guilty */
drm_sched_increase_karma(s_job);
amdgpu_reset_prepare_hwcontext(adev, reset_context);
retry:
/* do hw reset */
if (amdgpu_sriov_vf(adev)) {
@ -5148,6 +5151,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
reset_context->job = job;
reset_context->hive = hive;
/*
* Build list of devices to reset.
* In case we are in XGMI hive mode, resort the device list
@ -5267,8 +5271,11 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
amdgpu_ras_resume(adev);
} else {
r = amdgpu_do_asic_reset(device_list_handle, reset_context);
if (r && r == -EAGAIN)
if (r && r == -EAGAIN) {
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags);
adev->asic_reset_res = 0;
goto retry;
}
}
skip_hw_reset:
@ -5524,7 +5531,8 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
resource_size_t aper_limit =
adev->gmc.aper_base + adev->gmc.aper_size - 1;
bool p2p_access = !(pci_p2pdma_distance_many(adev->pdev,
bool p2p_access = !adev->gmc.xgmi.connected_to_cpu &&
!(pci_p2pdma_distance_many(adev->pdev,
&peer_adev->dev, 1, true) < 0);
return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
@ -5699,6 +5707,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
reset_context.reset_req_dev = adev;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
adev->no_hw_access = true;
r = amdgpu_device_pre_asic_reset(adev, &reset_context);

View File

@ -1506,6 +1506,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
break;
default:
@ -1549,6 +1550,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
break;
default:
@ -1633,6 +1635,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 7):
case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
break;
case IP_VERSION(13, 0, 4):
@ -1682,6 +1685,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 7):
case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
break;
default:
@ -1780,6 +1784,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
break;
default:
@ -1823,6 +1828,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
break;
default:
@ -1903,7 +1909,8 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(4, 0, 2):
case IP_VERSION(4, 0, 4):
amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
if (!amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
break;
default:
dev_err(adev->dev,
@ -1940,6 +1947,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
adev->enable_mes = true;
adev->enable_mes_kiq = true;
@ -2165,6 +2173,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
break;
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
adev->family = AMDGPU_FAMILY_GC_11_0_0;
break;
case IP_VERSION(11, 0, 1):
@ -2234,7 +2243,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
break;
case IP_VERSION(4, 3, 0):
case IP_VERSION(4, 3, 1):
adev->nbio.funcs = &nbio_v4_3_funcs;
if (amdgpu_sriov_vf(adev))
adev->nbio.funcs = &nbio_v4_3_sriov_funcs;
else
adev->nbio.funcs = &nbio_v4_3_funcs;
adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
break;
case IP_VERSION(7, 7, 0):
@ -2332,6 +2344,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
adev->lsdma.funcs = &lsdma_v6_0_funcs;
break;
default:

View File

@ -2181,8 +2181,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)
struct drm_device *dev = pci_get_drvdata(pdev);
struct amdgpu_device *adev = drm_to_adev(dev);
drm_dev_unplug(dev);
if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev);
@ -2190,6 +2188,8 @@ amdgpu_pci_remove(struct pci_dev *pdev)
amdgpu_driver_unload_kms(dev);
drm_dev_unplug(dev);
/*
* Flush any in flight DMA operations from device.
* Clear the Bus Master Enable bit and then wait on the PCIe Device
@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
amdgpu_device_baco_exit(drm_dev);
}
ret = amdgpu_device_resume(drm_dev, false);
if (ret)
if (ret) {
if (amdgpu_device_supports_px(drm_dev))
pci_disable_device(pdev);
return ret;
}
if (amdgpu_device_supports_px(drm_dev))
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;

View File

@ -66,10 +66,15 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
return true;
case CHIP_SIENNA_CICHLID:
if (strnstr(atom_ctx->vbios_version, "D603",
sizeof(atom_ctx->vbios_version))) {
if (strnstr(atom_ctx->vbios_version, "D603GLXE",
sizeof(atom_ctx->vbios_version)))
return true;
else
return false;
else
return true;
} else {
return false;
}
default:
return false;
}

View File

@ -477,7 +477,7 @@ int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev)
kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i],
RESET_QUEUES, 0, 0);
if (adev->gfx.kiq.ring.sched.ready)
if (adev->gfx.kiq.ring.sched.ready && !adev->job_hang)
r = amdgpu_ring_test_helper(kiq_ring);
spin_unlock(&adev->gfx.kiq.ring_lock);
@ -610,6 +610,45 @@ unlock:
mutex_unlock(&adev->gfx.gfx_off_mutex);
}
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_set_residency_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_get_residency_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_get_entrycount_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
{

View File

@ -332,10 +332,12 @@ struct amdgpu_gfx {
uint32_t srbm_soft_reset;
/* gfx off */
bool gfx_off_state; /* true: enabled, false: disabled */
struct mutex gfx_off_mutex;
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
struct delayed_work gfx_off_delay_work;
bool gfx_off_state; /* true: enabled, false: disabled */
struct mutex gfx_off_mutex; /* mutex to change gfxoff state */
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
struct delayed_work gfx_off_delay_work; /* async work to set gfx block off */
uint32_t gfx_off_residency; /* last logged residency */
uint64_t gfx_off_entrycount; /* count of times GPU has get into GFXOFF state */
/* pipe reservation */
struct mutex pipe_reserve_mutex;
@ -407,6 +409,10 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value);
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *residency);
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value);
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
struct amdgpu_iv_entry *entry);

View File

@ -35,6 +35,9 @@ struct amdgpu_gfxhub_funcs {
void (*init)(struct amdgpu_device *adev);
int (*get_xgmi_info)(struct amdgpu_device *adev);
void (*utcl2_harvest)(struct amdgpu_device *adev);
void (*mode2_save_regs)(struct amdgpu_device *adev);
void (*mode2_restore_regs)(struct amdgpu_device *adev);
void (*halt)(struct amdgpu_device *adev);
};
struct amdgpu_gfxhub {

View File

@ -264,6 +264,32 @@ struct amdgpu_gmc {
u64 mall_size;
/* number of UMC instances */
int num_umc;
/* mode2 save restore */
u64 VM_L2_CNTL;
u64 VM_L2_CNTL2;
u64 VM_DUMMY_PAGE_FAULT_CNTL;
u64 VM_DUMMY_PAGE_FAULT_ADDR_LO32;
u64 VM_DUMMY_PAGE_FAULT_ADDR_HI32;
u64 VM_L2_PROTECTION_FAULT_CNTL;
u64 VM_L2_PROTECTION_FAULT_CNTL2;
u64 VM_L2_PROTECTION_FAULT_MM_CNTL3;
u64 VM_L2_PROTECTION_FAULT_MM_CNTL4;
u64 VM_L2_PROTECTION_FAULT_ADDR_LO32;
u64 VM_L2_PROTECTION_FAULT_ADDR_HI32;
u64 VM_DEBUG;
u64 VM_L2_MM_GROUP_RT_CLASSES;
u64 VM_L2_BANK_SELECT_RESERVED_CID;
u64 VM_L2_BANK_SELECT_RESERVED_CID2;
u64 VM_L2_CACHE_PARITY_CNTL;
u64 VM_L2_IH_LOG_CNTL;
u64 VM_CONTEXT_CNTL[16];
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[16];
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[16];
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[16];
u64 MC_VM_MX_L1_TLB_CNTL;
};
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))

View File

@ -49,6 +49,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
}
memset(&ti, 0, sizeof(struct amdgpu_task_info));
adev->job_hang = true;
if (amdgpu_gpu_recovery &&
amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
@ -71,6 +72,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
if (r)
@ -82,6 +84,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
}
exit:
adev->job_hang = false;
drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NOMINAL;
}
@ -159,7 +162,10 @@ void amdgpu_job_free(struct amdgpu_job *job)
amdgpu_sync_free(&job->sync);
amdgpu_sync_free(&job->sched_sync);
dma_fence_put(&job->hw_fence);
if (!job->hw_fence.ops)
kfree(job);
else
dma_fence_put(&job->hw_fence);
}
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,

View File

@ -181,6 +181,9 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
for (i = 0; i < AMDGPU_MES_MAX_SDMA_PIPES; i++) {
if (adev->ip_versions[SDMA0_HWIP][0] < IP_VERSION(6, 0, 0))
adev->mes.sdma_hqd_mask[i] = i ? 0 : 0x3fc;
/* zero sdma_hqd_mask for non-existent engine */
else if (adev->sdma.num_instances == 1)
adev->mes.sdma_hqd_mask[i] = i ? 0 : 0xfc;
else
adev->mes.sdma_hqd_mask[i] = 0xfc;
}

View File

@ -138,6 +138,7 @@ static int psp_early_init(void *handle)
case IP_VERSION(13, 0, 3):
case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
psp_v13_0_set_psp_funcs(psp);
psp->autoload_supported = true;
break;
@ -327,23 +328,32 @@ static int psp_init_sriov_microcode(struct psp_context *psp)
switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(9, 0, 0):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "vega10");
break;
case IP_VERSION(11, 0, 9):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "navi12");
break;
case IP_VERSION(11, 0, 7):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "sienna_cichlid");
break;
case IP_VERSION(13, 0, 2):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "aldebaran");
ret &= psp_init_ta_microcode(psp, "aldebaran");
break;
case IP_VERSION(13, 0, 0):
adev->virt.autoload_ucode_id = 0;
break;
case IP_VERSION(13, 0, 10):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
break;
default:
BUG();
break;
}
return ret;
}
@ -486,11 +496,14 @@ static int psp_sw_fini(void *handle)
release_firmware(psp->ta_fw);
psp->ta_fw = NULL;
}
if (adev->psp.cap_fw) {
if (psp->cap_fw) {
release_firmware(psp->cap_fw);
psp->cap_fw = NULL;
}
if (psp->toc_fw) {
release_firmware(psp->toc_fw);
psp->toc_fw = NULL;
}
if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) ||
adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7))
psp_sysfs_fini(adev);
@ -766,6 +779,7 @@ static bool psp_skip_tmr(struct psp_context *psp)
case IP_VERSION(11, 0, 9):
case IP_VERSION(11, 0, 7):
case IP_VERSION(13, 0, 2):
case IP_VERSION(13, 0, 10):
return true;
default:
return false;
@ -812,7 +826,7 @@ static int psp_tmr_unload(struct psp_context *psp)
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
psp_prep_tmr_unload_cmd_buf(psp, cmd);
DRM_INFO("free PSP TMR buffer\n");
dev_info(psp->adev->dev, "free PSP TMR buffer\n");
ret = psp_cmd_submit_buf(psp, NULL, cmd,
psp->fence_buf_mc_addr);
@ -2401,7 +2415,7 @@ static int psp_load_smu_fw(struct psp_context *psp)
static bool fw_load_skip_check(struct psp_context *psp,
struct amdgpu_firmware_info *ucode)
{
if (!ucode->fw)
if (!ucode->fw || !ucode->ucode_size)
return true;
if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
@ -2411,20 +2425,7 @@ static bool fw_load_skip_check(struct psp_context *psp,
return true;
if (amdgpu_sriov_vf(psp->adev) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|| ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
/*skip ucode loading in SRIOV VF */
amdgpu_virt_fw_load_skip_check(psp->adev, ucode->ucode_id))
return true;
if (psp->autoload_supported &&
@ -2498,7 +2499,7 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
/* Start rlc autoload after psp recieved all the gfx firmware */
if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) {
adev->virt.autoload_ucode_id : AMDGPU_UCODE_ID_RLC_G)) {
ret = psp_rlc_autoload_start(psp);
if (ret) {
DRM_ERROR("Failed to start rlc autoload\n");
@ -2641,6 +2642,9 @@ static int psp_hw_fini(void *handle)
psp_rap_terminate(psp);
psp_dtm_terminate(psp);
psp_hdcp_terminate(psp);
if (adev->gmc.xgmi.num_physical_nodes > 1)
psp_xgmi_terminate(psp);
}
psp_asd_terminate(psp);

View File

@ -1949,6 +1949,7 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
}

View File

@ -23,6 +23,7 @@
#include "amdgpu_reset.h"
#include "aldebaran.h"
#include "sienna_cichlid.h"
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_handler *handler)
@ -36,10 +37,15 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
{
int ret = 0;
adev->amdgpu_reset_level_mask = 0x1;
switch (adev->ip_versions[MP1_HWIP][0]) {
case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_init(adev);
break;
case IP_VERSION(11, 0, 7):
ret = sienna_cichlid_reset_init(adev);
break;
default:
break;
}
@ -55,6 +61,9 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_fini(adev);
break;
case IP_VERSION(11, 0, 7):
ret = sienna_cichlid_reset_fini(adev);
break;
default:
break;
}
@ -67,6 +76,12 @@ int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev,
{
struct amdgpu_reset_handler *reset_handler = NULL;
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
return -ENOSYS;
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
return -ENOSYS;
if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
reset_handler = adev->reset_cntl->get_reset_handler(
adev->reset_cntl, reset_context);
@ -83,6 +98,12 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
int ret;
struct amdgpu_reset_handler *reset_handler = NULL;
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
return -ENOSYS;
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
return -ENOSYS;
if (adev->reset_cntl)
reset_handler = adev->reset_cntl->get_reset_handler(
adev->reset_cntl, reset_context);

View File

@ -30,6 +30,7 @@ enum AMDGPU_RESET_FLAGS {
AMDGPU_NEED_FULL_RESET = 0,
AMDGPU_SKIP_HW_RESET = 1,
AMDGPU_SKIP_MODE2_RESET = 2,
};
struct amdgpu_reset_context {

View File

@ -405,6 +405,9 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
{
ktime_t deadline = ktime_add_us(ktime_get(), 10000);
if (!(ring->adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_SOFT_RECOVERY))
return false;
if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
return false;

View File

@ -390,6 +390,7 @@ union amdgpu_firmware_header {
struct rlc_firmware_header_v2_1 rlc_v2_1;
struct rlc_firmware_header_v2_2 rlc_v2_2;
struct rlc_firmware_header_v2_3 rlc_v2_3;
struct rlc_firmware_header_v2_4 rlc_v2_4;
struct sdma_firmware_header_v1_0 sdma;
struct sdma_firmware_header_v1_1 sdma_v1_1;
struct sdma_firmware_header_v2_0 sdma_v2_0;

View File

@ -161,6 +161,7 @@
#define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
#define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10)
#define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
#define AMDGPU_VCN_VF_RB_SETUP_FLAG (1 << 12)
#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001
#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001
@ -317,12 +318,24 @@ struct amdgpu_fw_shared {
struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
};
struct amdgpu_fw_shared_rb_setup {
uint32_t is_rb_enabled_flags;
uint32_t rb_addr_lo;
uint32_t rb_addr_hi;
uint32_t rb_size;
uint32_t rb4_addr_lo;
uint32_t rb4_addr_hi;
uint32_t rb4_size;
uint32_t reserved[6];
};
struct amdgpu_vcn4_fw_shared {
uint32_t present_flag_0;
uint8_t pad[12];
struct amdgpu_fw_shared_unified_queue_struct sq;
uint8_t pad1[8];
struct amdgpu_fw_shared_fw_logging fw_log;
struct amdgpu_fw_shared_rb_setup rb_setup;
};
struct amdgpu_vcn_fwlog {

View File

@ -690,7 +690,6 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
}
}
void amdgpu_detect_virtualization(struct amdgpu_device *adev)
{
uint32_t reg;
@ -707,6 +706,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
case CHIP_SIENNA_CICHLID:
case CHIP_ARCTURUS:
case CHIP_ALDEBARAN:
case CHIP_IP_DISCOVERY:
reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
break;
default: /* other chip doesn't support SRIOV */
@ -750,6 +750,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
case CHIP_NAVI10:
case CHIP_NAVI12:
case CHIP_SIENNA_CICHLID:
case CHIP_IP_DISCOVERY:
nv_set_virt_ops(adev);
/* try send GPU_INIT_DATA request to host */
amdgpu_virt_request_init_data(adev);
@ -807,6 +808,60 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
return mode;
}
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev, uint32_t ucode_id)
{
switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(13, 0, 0):
/* no vf autoload, white list */
if (ucode_id == AMDGPU_UCODE_ID_VCN1 ||
ucode_id == AMDGPU_UCODE_ID_VCN)
return false;
else
return true;
case IP_VERSION(13, 0, 10):
/* white list */
if (ucode_id == AMDGPU_UCODE_ID_CAP
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_MES
|| ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1_DATA
|| ucode_id == AMDGPU_UCODE_ID_VCN1
|| ucode_id == AMDGPU_UCODE_ID_VCN)
return false;
else
return true;
default:
/* lagacy black list */
if (ucode_id == AMDGPU_UCODE_ID_SDMA0
|| ucode_id == AMDGPU_UCODE_ID_SDMA1
|| ucode_id == AMDGPU_UCODE_ID_SDMA2
|| ucode_id == AMDGPU_UCODE_ID_SDMA3
|| ucode_id == AMDGPU_UCODE_ID_SDMA4
|| ucode_id == AMDGPU_UCODE_ID_SDMA5
|| ucode_id == AMDGPU_UCODE_ID_SDMA6
|| ucode_id == AMDGPU_UCODE_ID_SDMA7
|| ucode_id == AMDGPU_UCODE_ID_RLC_G
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|| ucode_id == AMDGPU_UCODE_ID_SMC)
return true;
else
return false;
}
}
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
struct amdgpu_video_codec_info *decode, uint32_t decode_array_size)

View File

@ -253,6 +253,9 @@ struct amdgpu_virt {
uint32_t decode_max_frame_pixels;
uint32_t encode_max_dimension_pixels;
uint32_t encode_max_frame_pixels;
/* the ucode id to signal the autoload */
uint32_t autoload_ucode_id;
};
struct amdgpu_video_codec_info;
@ -343,4 +346,6 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
u32 acc_flags, u32 hwip);
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
u32 offset, u32 acc_flags, u32 hwip);
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
uint32_t ucode_id);
#endif

View File

@ -504,6 +504,9 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
{
int ret;
if (amdgpu_sriov_vf(adev))
return 0;
/* Each psp need to set the latest topology */
ret = psp_xgmi_set_topology_info(&adev->psp,
atomic_read(&hive->number_devices),
@ -742,7 +745,7 @@ int amdgpu_xgmi_remove_device(struct amdgpu_device *adev)
amdgpu_put_xgmi_hive(hive);
}
return psp_xgmi_terminate(&adev->psp);
return 0;
}
static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)

View File

@ -4274,35 +4274,45 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
if (adev->gfx.rlc.global_tap_delays_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
if (adev->gfx.rlc.se0_tap_delays_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
if (adev->gfx.rlc.se1_tap_delays_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
if (adev->gfx.rlc.se2_tap_delays_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
if (adev->gfx.rlc.se3_tap_delays_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
@ -5971,6 +5981,9 @@ static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp);
}
if (adev->job_hang && !enable)
return 0;
for (i = 0; i < adev->usec_timeout; i++) {
if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0)
break;
@ -7569,8 +7582,10 @@ static int gfx_v10_0_kiq_disable_kgq(struct amdgpu_device *adev)
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.gfx_ring[i],
PREEMPT_QUEUES, 0, 0);
return amdgpu_ring_test_helper(kiq_ring);
if (!adev->job_hang)
return amdgpu_ring_test_helper(kiq_ring);
else
return 0;
}
#endif

View File

@ -73,21 +73,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
static const struct soc15_reg_golden golden_settings_gc_11_0[] =
{
/* Pending on emulation bring up */
};
static const struct soc15_reg_golden golden_settings_gc_11_0_0[] =
{
/* Pending on emulation bring up */
};
static const struct soc15_reg_golden golden_settings_gc_rlc_spm_11_0[] =
{
/* Pending on emulation bring up */
};
MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
{
@ -131,6 +120,8 @@ static void gfx_v11_0_ring_invalidate_tlbs(struct amdgpu_ring *ring,
bool all_hub, uint8_t dst_sel);
static void gfx_v11_0_set_safe_mode(struct amdgpu_device *adev);
static void gfx_v11_0_unset_safe_mode(struct amdgpu_device *adev);
static void gfx_v11_0_update_perf_clk(struct amdgpu_device *adev,
bool enable);
static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
{
@ -267,34 +258,10 @@ static void gfx_v11_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
adev->gfx.kiq.pmf = &gfx_v11_0_kiq_pm4_funcs;
}
static void gfx_v11_0_init_spm_golden_registers(struct amdgpu_device *adev)
{
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(11, 0, 0):
soc15_program_register_sequence(adev,
golden_settings_gc_rlc_spm_11_0,
(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_11_0));
break;
default:
break;
}
}
static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
{
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(11, 0, 0):
soc15_program_register_sequence(adev,
golden_settings_gc_11_0,
(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
soc15_program_register_sequence(adev,
golden_settings_gc_11_0_0,
(const u32)ARRAY_SIZE(golden_settings_gc_11_0_0));
break;
case IP_VERSION(11, 0, 1):
soc15_program_register_sequence(adev,
golden_settings_gc_11_0,
(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
soc15_program_register_sequence(adev,
golden_settings_gc_11_0_1,
(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
@ -302,7 +269,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
default:
break;
}
gfx_v11_0_init_spm_golden_registers(adev);
}
static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel,
@ -1138,7 +1104,7 @@ static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
.read_wave_sgprs = &gfx_v11_0_read_wave_sgprs,
.read_wave_vgprs = &gfx_v11_0_read_wave_vgprs,
.select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
.init_spm_golden = &gfx_v11_0_init_spm_golden_registers,
.update_perfmon_mgcg = &gfx_v11_0_update_perf_clk,
};
static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
@ -1148,6 +1114,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@ -1583,6 +1550,7 @@ static int gfx_v11_0_sw_init(void *handle)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
@ -2757,6 +2725,21 @@ static void gfx_v11_0_config_gfx_rs64(struct amdgpu_device *adev)
mec_hdr->ucode_start_addr_hi >> 2);
}
soc21_grbm_select(adev, 0, 0, 0, 0);
/* reset mec pipe */
tmp = RREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 1);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 1);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 1);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 1);
WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
/* clear mec pipe reset */
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 0);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 0);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 0);
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 0);
WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
}
static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
@ -5182,9 +5165,12 @@ static void gfx_v11_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
data = REG_SET_FIELD(data, SDMA0_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
data = REG_SET_FIELD(data, SDMA1_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
/* Some ASICs only have one SDMA instance, not need to configure SDMA1 */
if (adev->sdma.num_instances > 1) {
data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
data = REG_SET_FIELD(data, SDMA1_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
}
} else {
/* Program RLC_CGCG_CGLS_CTRL */
def = data = RREG32_SOC15(GC, 0, regRLC_CGCG_CGLS_CTRL);
@ -5213,9 +5199,12 @@ static void gfx_v11_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
data &= ~SDMA0_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
data &= ~SDMA1_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
/* Some ASICs only have one SDMA instance, not need to configure SDMA1 */
if (adev->sdma.num_instances > 1) {
data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
data &= ~SDMA1_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
}
}
}
@ -5328,8 +5317,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
break;
case IP_VERSION(11, 0, 1):
gfx_v11_cntl_pg(adev, enable);
/* TODO: Enable this when GFXOFF is ready */
// amdgpu_gfx_off_ctrl(adev, enable);
amdgpu_gfx_off_ctrl(adev, enable);
break;
default:
break;

View File

@ -126,6 +126,8 @@ MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
#define mmTCP_CHAN_STEER_0_ARCT 0x0b03
#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0
@ -1496,7 +1498,11 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
const struct common_firmware_header *header = NULL;
const struct gfx_firmware_header_v1_0 *cp_hdr;
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", chip_name);
else
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
if (err)
goto out;
@ -1509,7 +1515,11 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec2.bin", chip_name);
else
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
if (!err) {
err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
@ -2587,7 +2597,8 @@ static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
gfx_v9_0_tiling_mode_table_init(adev);
gfx_v9_0_setup_rb(adev);
if (adev->gfx.num_gfx_rings)
gfx_v9_0_setup_rb(adev);
gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info);
adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2);

View File

@ -576,6 +576,111 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
}
}
static void gfxhub_v2_1_save_regs(struct amdgpu_device *adev)
{
int i;
adev->gmc.VM_L2_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL);
adev->gmc.VM_L2_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2);
adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL);
adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32);
adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32);
adev->gmc.VM_L2_PROTECTION_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2);
adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3);
adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4);
adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32);
adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32);
adev->gmc.VM_DEBUG = RREG32_SOC15(GC, 0, mmGCVM_DEBUG);
adev->gmc.VM_L2_MM_GROUP_RT_CLASSES = RREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES);
adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID);
adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2 = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2);
adev->gmc.VM_L2_CACHE_PARITY_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL);
adev->gmc.VM_L2_IH_LOG_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL);
for (i = 0; i <= 15; i++) {
adev->gmc.VM_CONTEXT_CNTL[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i);
adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2);
adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2);
adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2);
adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2);
adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2);
adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2);
}
adev->gmc.MC_VM_MX_L1_TLB_CNTL = RREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL);
}
static void gfxhub_v2_1_restore_regs(struct amdgpu_device *adev)
{
int i;
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL, adev->gmc.VM_L2_CNTL);
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, adev->gmc.VM_L2_CNTL2);
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL, adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL);
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32);
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32);
WREG32_SOC15(GC, 0, mmGCVM_DEBUG, adev->gmc.VM_DEBUG);
WREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES, adev->gmc.VM_L2_MM_GROUP_RT_CLASSES);
WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID);
WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2);
WREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL, adev->gmc.VM_L2_CACHE_PARITY_CNTL);
WREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL, adev->gmc.VM_L2_IH_LOG_CNTL);
for (i = 0; i <= 15; i++) {
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i, adev->gmc.VM_CONTEXT_CNTL[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i]);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i]);
}
WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_BASE, adev->gmc.vram_start >> 24);
WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_TOP, adev->gmc.vram_end >> 24);
WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, adev->gmc.MC_VM_MX_L1_TLB_CNTL);
}
static void gfxhub_v2_1_halt(struct amdgpu_device *adev)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
int i;
uint32_t tmp;
int time = 1000;
gfxhub_v2_1_set_fault_enable_default(adev, false);
for (i = 0; i <= 14; i++) {
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
i * hub->ctx_addr_distance, ~0);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
i * hub->ctx_addr_distance, ~0);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
i * hub->ctx_addr_distance,
0);
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
i * hub->ctx_addr_distance,
0);
}
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
while ((tmp & (GRBM_STATUS2__EA_BUSY_MASK |
GRBM_STATUS2__EA_LINK_BUSY_MASK)) != 0 &&
time) {
udelay(100);
time--;
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
}
if (!time) {
DRM_WARN("failed to wait for GRBM(EA) idle\n");
}
}
const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
.get_fb_location = gfxhub_v2_1_get_fb_location,
.get_mc_fb_offset = gfxhub_v2_1_get_mc_fb_offset,
@ -586,4 +691,7 @@ const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
.init = gfxhub_v2_1_init,
.get_xgmi_info = gfxhub_v2_1_get_xgmi_info,
.utcl2_harvest = gfxhub_v2_1_utcl2_harvest,
.mode2_save_regs = gfxhub_v2_1_save_regs,
.mode2_restore_regs = gfxhub_v2_1_restore_regs,
.halt = gfxhub_v2_1_halt,
};

View File

@ -0,0 +1,511 @@
/*
* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "amdgpu.h"
#include "gfxhub_v3_0_3.h"
#include "gc/gc_11_0_3_offset.h"
#include "gc/gc_11_0_3_sh_mask.h"
#include "navi10_enum.h"
#include "soc15_common.h"
#define regGCVM_L2_CNTL3_DEFAULT 0x80100007
#define regGCVM_L2_CNTL4_DEFAULT 0x000000c1
#define regGCVM_L2_CNTL5_DEFAULT 0x00003fe0
static const char *gfxhub_client_ids[] = {
"CB/DB",
"Reserved",
"GE1",
"GE2",
"CPF",
"CPC",
"CPG",
"RLC",
"TCP",
"SQC (inst)",
"SQC (data)",
"SQG",
"Reserved",
"SDMA0",
"SDMA1",
"GCR",
"SDMA2",
"SDMA3",
};
static uint32_t gfxhub_v3_0_3_get_invalidate_req(unsigned int vmid,
uint32_t flush_type)
{
u32 req = 0;
/* invalidate using legacy mode on vmid*/
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
PER_VMID_INVALIDATE_REQ, 1 << vmid);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0);
return req;
}
static void
gfxhub_v3_0_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
uint32_t status)
{
u32 cid = REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, CID);
dev_err(adev->dev,
"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
status);
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid],
cid);
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
dev_err(adev->dev, "\t RW: 0x%lx\n",
REG_GET_FIELD(status,
GCVM_L2_PROTECTION_FAULT_STATUS, RW));
}
static u64 gfxhub_v3_0_3_get_fb_location(struct amdgpu_device *adev)
{
u64 base = RREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE);
base &= GCMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
base <<= 24;
return base;
}
static u64 gfxhub_v3_0_3_get_mc_fb_offset(struct amdgpu_device *adev)
{
return (u64)RREG32_SOC15(GC, 0, regGCMC_VM_FB_OFFSET) << 24;
}
static void gfxhub_v3_0_3_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
uint64_t page_table_base)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
hub->ctx_addr_distance * vmid,
lower_32_bits(page_table_base));
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
hub->ctx_addr_distance * vmid,
upper_32_bits(page_table_base));
}
static void gfxhub_v3_0_3_init_gart_aperture_regs(struct amdgpu_device *adev)
{
uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
gfxhub_v3_0_3_setup_vm_pt_regs(adev, 0, pt_base);
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
(u32)(adev->gmc.gart_start >> 12));
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
(u32)(adev->gmc.gart_start >> 44));
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
(u32)(adev->gmc.gart_end >> 12));
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
(u32)(adev->gmc.gart_end >> 44));
}
static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
{
uint64_t value;
/* Disable AGP. */
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0);
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0);
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, 0x00FFFFFF);
/* Program the system aperture low logical page number. */
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->gmc.vram_start >> 18);
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
adev->gmc.vram_end >> 18);
/* Set default page address. */
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
+ adev->vm_manager.vram_base_offset;
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
(u32)(value >> 12));
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
(u32)(value >> 44));
/* Program "protection fault". */
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
(u32)(adev->dummy_page_addr >> 12));
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
(u32)((u64)adev->dummy_page_addr >> 44));
WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_PROTECTION_FAULT_CNTL2,
ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
}
static void gfxhub_v3_0_3_init_tlb_regs(struct amdgpu_device *adev)
{
uint32_t tmp;
/* Setup TLB control */
tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
ENABLE_ADVANCED_DRIVER_MODEL, 1);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
MTYPE, MTYPE_UC); /* UC, uncached */
WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
}
static void gfxhub_v3_0_3_init_cache_regs(struct amdgpu_device *adev)
{
uint32_t tmp;
/* These registers are not accessible to VF-SRIOV.
* The PF will program them instead.
*/
if (amdgpu_sriov_vf(adev))
return;
/* Setup L2 cache */
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_CACHE, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
/* XXX for emulation, Refer to closed source code.*/
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
L2_PDE0_CACHE_TAG_GENERATION_MODE, 0);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL, tmp);
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL2);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL2, tmp);
tmp = regGCVM_L2_CNTL3_DEFAULT;
if (adev->gmc.translate_further) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
} else {
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
}
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, tmp);
tmp = regGCVM_L2_CNTL4_DEFAULT;
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL4, tmp);
tmp = regGCVM_L2_CNTL5_DEFAULT;
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL5, tmp);
}
static void gfxhub_v3_0_3_enable_system_domain(struct amdgpu_device *adev)
{
uint32_t tmp;
tmp = RREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL,
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL, tmp);
}
static void gfxhub_v3_0_3_disable_identity_aperture(struct amdgpu_device *adev)
{
/* These registers are not accessible to VF-SRIOV.
* The PF will program them instead.
*/
if (amdgpu_sriov_vf(adev))
return;
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
0xFFFFFFFF);
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
0x0000000F);
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32,
0);
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32,
0);
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, 0);
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, 0);
}
static void gfxhub_v3_0_3_setup_vmid_config(struct amdgpu_device *adev)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
int i;
uint32_t tmp;
for (i = 0; i <= 14; i++) {
tmp = RREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL, i);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
adev->vm_manager.num_level);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
/* Send no-retry XNACK on fault to suppress VM fault storm. */
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
!amdgpu_noretry);
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL,
i * hub->ctx_distance, tmp);
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
i * hub->ctx_addr_distance, 0);
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
i * hub->ctx_addr_distance, 0);
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
i * hub->ctx_addr_distance,
lower_32_bits(adev->vm_manager.max_pfn - 1));
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
i * hub->ctx_addr_distance,
upper_32_bits(adev->vm_manager.max_pfn - 1));
}
hub->vm_cntx_cntl = tmp;
}
static void gfxhub_v3_0_3_program_invalidation(struct amdgpu_device *adev)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
unsigned i;
for (i = 0 ; i < 18; ++i) {
WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
i * hub->eng_addr_distance, 0xffffffff);
WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
i * hub->eng_addr_distance, 0x1f);
}
}
static int gfxhub_v3_0_3_gart_enable(struct amdgpu_device *adev)
{
if (amdgpu_sriov_vf(adev)) {
/*
* GCMC_VM_FB_LOCATION_BASE/TOP is NULL for VF, becuase they are
* VF copy registers so vbios post doesn't program them, for
* SRIOV driver need to program them
*/
WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE,
adev->gmc.vram_start >> 24);
WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_TOP,
adev->gmc.vram_end >> 24);
}
/* GART Enable. */
gfxhub_v3_0_3_init_gart_aperture_regs(adev);
gfxhub_v3_0_3_init_system_aperture_regs(adev);
gfxhub_v3_0_3_init_tlb_regs(adev);
gfxhub_v3_0_3_init_cache_regs(adev);
gfxhub_v3_0_3_enable_system_domain(adev);
gfxhub_v3_0_3_disable_identity_aperture(adev);
gfxhub_v3_0_3_setup_vmid_config(adev);
gfxhub_v3_0_3_program_invalidation(adev);
return 0;
}
static void gfxhub_v3_0_3_gart_disable(struct amdgpu_device *adev)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
u32 tmp;
u32 i;
/* Disable all tables */
for (i = 0; i < 16; i++)
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL,
i * hub->ctx_distance, 0);
/* Setup TLB control */
tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
ENABLE_ADVANCED_DRIVER_MODEL, 0);
WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
/* Setup L2 cache */
WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_CNTL, ENABLE_L2_CACHE, 0);
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, 0);
}
/**
* gfxhub_v3_0_3_set_fault_enable_default - update GART/VM fault handling
*
* @adev: amdgpu_device pointer
* @value: true redirects VM faults to the default page
*/
static void gfxhub_v3_0_3_set_fault_enable_default(struct amdgpu_device *adev,
bool value)
{
u32 tmp;
/* These registers are not accessible to VF-SRIOV.
* The PF will program them instead.
*/
if (amdgpu_sriov_vf(adev))
return;
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}
static const struct amdgpu_vmhub_funcs gfxhub_v3_0_3_vmhub_funcs = {
.print_l2_protection_fault_status = gfxhub_v3_0_3_print_l2_protection_fault_status,
.get_invalidate_req = gfxhub_v3_0_3_get_invalidate_req,
};
static void gfxhub_v3_0_3_init(struct amdgpu_device *adev)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
hub->ctx0_ptb_addr_lo32 =
SOC15_REG_OFFSET(GC, 0,
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
hub->ctx0_ptb_addr_hi32 =
SOC15_REG_OFFSET(GC, 0,
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
hub->vm_inv_eng0_sem =
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_SEM);
hub->vm_inv_eng0_req =
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_REQ);
hub->vm_inv_eng0_ack =
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ACK);
hub->vm_context0_cntl =
SOC15_REG_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL);
hub->vm_l2_pro_fault_status =
SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_STATUS);
hub->vm_l2_pro_fault_cntl =
SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
hub->ctx_distance = regGCVM_CONTEXT1_CNTL - regGCVM_CONTEXT0_CNTL;
hub->ctx_addr_distance = regGCVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
hub->eng_distance = regGCVM_INVALIDATE_ENG1_REQ -
regGCVM_INVALIDATE_ENG0_REQ;
hub->eng_addr_distance = regGCVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
hub->vm_cntx_cntl_vm_fault = GCVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
hub->vmhub_funcs = &gfxhub_v3_0_3_vmhub_funcs;
}
const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs = {
.get_fb_location = gfxhub_v3_0_3_get_fb_location,
.get_mc_fb_offset = gfxhub_v3_0_3_get_mc_fb_offset,
.setup_vm_pt_regs = gfxhub_v3_0_3_setup_vm_pt_regs,
.gart_enable = gfxhub_v3_0_3_gart_enable,
.gart_disable = gfxhub_v3_0_3_gart_disable,
.set_fault_enable_default = gfxhub_v3_0_3_set_fault_enable_default,
.init = gfxhub_v3_0_3_init,
};

View File

@ -0,0 +1,29 @@
/*
* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __GFXHUB_V3_0_3_H__
#define __GFXHUB_V3_0_3_H__
extern const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs;
#endif

View File

@ -39,6 +39,7 @@
#include "soc15_common.h"
#include "nbio_v4_3.h"
#include "gfxhub_v3_0.h"
#include "gfxhub_v3_0_3.h"
#include "mmhub_v3_0.h"
#include "mmhub_v3_0_1.h"
#include "mmhub_v3_0_2.h"
@ -233,7 +234,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
/* Issue additional private vm invalidation to MMHUB */
if ((vmhub != AMDGPU_GFXHUB_0) &&
(hub->vm_l2_bank_select_reserved_cid2)) {
(hub->vm_l2_bank_select_reserved_cid2) &&
!amdgpu_sriov_vf(adev)) {
inv_req = RREG32_NO_KIQ(hub->vm_l2_bank_select_reserved_cid2);
/* bit 25: RSERVED_CACHE_PRIVATE_INVALIDATION */
inv_req |= (1 << 25);
@ -590,7 +592,14 @@ static void gmc_v11_0_set_mmhub_funcs(struct amdgpu_device *adev)
static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
{
adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(11, 0, 3):
adev->gfxhub.funcs = &gfxhub_v3_0_3_funcs;
break;
default:
adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
break;
}
}
static int gmc_v11_0_early_init(void *handle)
@ -640,7 +649,10 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev,
amdgpu_gmc_gart_location(adev, mc);
/* base offset of vram pages */
adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
if (amdgpu_sriov_vf(adev))
adev->vm_manager.vram_base_offset = 0;
else
adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
}
/**
@ -732,6 +744,7 @@ static int gmc_v11_0_sw_init(void *handle)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
adev->num_vmhubs = 2;
/*
* To fulfill 4-level page support,

View File

@ -105,7 +105,13 @@ force_update_wptr_for_self_int(struct amdgpu_device *adev,
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
RB_USED_INT_THRESHOLD, threshold);
WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, ih_rb_cntl))
return;
} else {
WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
}
WREG32_SOC15(OSSSYS, 0, regIH_CNTL2, ih_cntl);
}
@ -132,7 +138,13 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
/* enable_intr field is only valid in ring0 */
if (ih == &adev->irq.ih)
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
WREG32(ih_regs->ih_rb_cntl, tmp);
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
return -ETIMEDOUT;
} else {
WREG32(ih_regs->ih_rb_cntl, tmp);
}
if (enable) {
ih->enabled = true;
@ -242,7 +254,15 @@ static int ih_v6_0_enable_ring(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
}
WREG32(ih_regs->ih_rb_cntl, tmp);
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
return -ETIMEDOUT;
}
} else {
WREG32(ih_regs->ih_rb_cntl, tmp);
}
if (ih == &adev->irq.ih) {
/* set the ih ring 0 writeback address whether it's enabled or not */

View File

@ -26,12 +26,15 @@
#include "amdgpu_imu.h"
#include "amdgpu_dpm.h"
#include "imu_v11_0_3.h"
#include "gc/gc_11_0_0_offset.h"
#include "gc/gc_11_0_0_sh_mask.h"
MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_imu.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_imu.bin");
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
{
@ -360,6 +363,9 @@ static void imu_v11_0_program_rlc_ram(struct amdgpu_device *adev)
program_imu_rlc_ram(adev, imu_rlc_ram_golden_11_0_2,
(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_2));
break;
case IP_VERSION(11, 0, 3):
imu_v11_0_3_program_rlc_ram(adev);
break;
default:
BUG();
break;

View File

@ -0,0 +1,144 @@
/*
* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "amdgpu.h"
#include "amdgpu_imu.h"
#include "gc/gc_11_0_3_offset.h"
#include "gc/gc_11_0_3_sh_mask.h"
static const struct imu_rlc_ram_golden imu_rlc_ram_golden_11_0_3[] = {
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_RD_COMBINE_FLUSH, 0x00055555, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_WR_COMBINE_FLUSH, 0x00055555, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_DRAM_COMBINE_FLUSH, 0x00555555, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC2, 0x00001ffe, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_CREDITS, 0x003f3fff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_TAG_RESERVE1, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE0, 0x00041000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE1, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE0, 0x00040000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE1, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC, 0x00000017, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_ENABLE, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_CREDITS, 0x003f3fbf, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE0, 0x10200800, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE1, 0x00000088, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE0, 0x1d041040, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE1, 0x80000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_IO_PRIORITY, 0x88888888, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MAM_CTRL, 0x0000d800, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ARB_FINAL, 0x000007ff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_DRAM_PAGE_BURST, 0x20080200, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ENABLE, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_CACHEABLE_DRAM_ADDRESS_END, 0x000fffff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MISC, 0x0c48bff0, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SA_UNIT_DISABLE, 0x00fffc01, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_PRIM_CONFIG, 0x000fffe1, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_RB_BACKEND_DISABLE, 0xffffff01, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x40000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x42000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x44000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x46000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x48000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x4A000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCGTS_TCC_DISABLE, 0x00000001, 0x00000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_RATE_CONFIG, 0x00000001, 0x00000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_EDC_CONFIG, 0x00000001, 0x00000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000500, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_START, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_END, 0x000005ff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_BASE, 0x00006000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_TOP, 0x000065ff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_TOP_OF_DRAM_SLOT1, 0xff800000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_LOWER_TOP_OF_DRAM2, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_UPPER_TOP_OF_DRAM2, 0x00000fff, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, 0x00001ffc, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000551, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL, 0x00080603, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL2, 0x00000003, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL3, 0x00100003, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL5, 0x00003fe0, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT0_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000001, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT1_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000444, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_0, 0x54105410, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_2, 0x76323276, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000244, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCUTCL2_HARVEST_BYPASS_GROUPS, 0x00000006, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BASE, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BOT, 0x00000002, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_TOP, 0x00000000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA0_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA1_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPC_PSP_DEBUG, CPC_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPG_PSP_DEBUG, CPG_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
};
static void program_rlc_ram_register_setting(struct amdgpu_device *adev,
const struct imu_rlc_ram_golden *regs,
const u32 array_size)
{
const struct imu_rlc_ram_golden *entry;
u32 reg, data;
int i;
for (i = 0; i < array_size; ++i) {
entry = &regs[i];
reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
reg |= entry->addr_mask;
data = entry->data;
if (entry->reg == regGCMC_VM_AGP_BASE)
data = 0x00ffffff;
else if (entry->reg == regGCMC_VM_AGP_TOP)
data = 0x0;
else if (entry->reg == regGCMC_VM_FB_LOCATION_BASE)
data = adev->gmc.vram_start >> 24;
else if (entry->reg == regGCMC_VM_FB_LOCATION_TOP)
data = adev->gmc.vram_end >> 24;
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, reg);
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, data);
}
//Indicate the latest entry
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, 0);
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, 0);
}
void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev)
{
program_rlc_ram_register_setting(adev,
imu_rlc_ram_golden_11_0_3,
(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_3));
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __IMU_V11_0_3_H__
#define __IMU_V11_0_3_H__
void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev);
#endif

View File

@ -38,6 +38,8 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
static int mes_v11_0_hw_fini(void *handle);
static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
@ -183,6 +185,7 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
mes_add_queue_pkt.tma_addr = input->tma_addr;
mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
mes_add_queue_pkt.trap_en = 1;
return mes_v11_0_submit_pkt_and_poll_completion(mes,
&mes_add_queue_pkt, sizeof(mes_add_queue_pkt),

View File

@ -176,6 +176,7 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
tmp = mmVM_L2_CNTL3_DEFAULT;
if (adev->gmc.translate_further) {
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,

View File

@ -169,17 +169,17 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
uint64_t value;
uint32_t tmp;
/* Disable AGP. */
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
if (!amdgpu_sriov_vf(adev)) {
/*
* the new L1 policy will block SRIOV guest from writing
* these regs, and they will be programed at host.
* so skip programing these regs.
*/
/* Disable AGP. */
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
/* Program the system aperture low logical page number. */
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->gmc.vram_start >> 18);

View File

@ -295,9 +295,17 @@ static void mmhub_v9_4_disable_identity_aperture(struct amdgpu_device *adev,
static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
{
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
unsigned int num_level, block_size;
uint32_t tmp;
int i;
num_level = adev->vm_manager.num_level;
block_size = adev->vm_manager.block_size;
if (adev->gmc.translate_further)
num_level -= 1;
else
block_size -= 9;
for (i = 0; i <= 14; i++) {
tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmVML2VC0_VM_CONTEXT1_CNTL,
hubid * MMHUB_INSTANCE_REGISTER_OFFSET + i);
@ -305,7 +313,7 @@ static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
ENABLE_CONTEXT, 1);
tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
PAGE_TABLE_DEPTH,
adev->vm_manager.num_level);
num_level);
tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
@ -323,7 +331,7 @@ static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
block_size);
/* Send no-retry XNACK on fault to suppress VM fault storm. */
tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,

View File

@ -0,0 +1,140 @@
/*
* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __MMSCH_V4_0_H__
#define __MMSCH_V4_0_H__
#include "amdgpu_vcn.h"
#define MMSCH_VERSION_MAJOR 4
#define MMSCH_VERSION_MINOR 0
#define MMSCH_VERSION (MMSCH_VERSION_MAJOR << 16 | MMSCH_VERSION_MINOR)
#define RB_ENABLED (1 << 0)
#define RB4_ENABLED (1 << 1)
#define MMSCH_DOORBELL_OFFSET 0x8
#define MMSCH_VF_ENGINE_STATUS__PASS 0x1
#define MMSCH_VF_MAILBOX_RESP__OK 0x1
#define MMSCH_VF_MAILBOX_RESP__INCOMPLETE 0x2
enum mmsch_v4_0_command_type {
MMSCH_COMMAND__DIRECT_REG_WRITE = 0,
MMSCH_COMMAND__DIRECT_REG_POLLING = 2,
MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE = 3,
MMSCH_COMMAND__INDIRECT_REG_WRITE = 8,
MMSCH_COMMAND__END = 0xf
};
struct mmsch_v4_0_table_info {
uint32_t init_status;
uint32_t table_offset;
uint32_t table_size;
};
struct mmsch_v4_0_init_header {
uint32_t version;
uint32_t total_size;
struct mmsch_v4_0_table_info inst[AMDGPU_MAX_VCN_INSTANCES];
struct mmsch_v4_0_table_info jpegdec;
};
struct mmsch_v4_0_cmd_direct_reg_header {
uint32_t reg_offset : 28;
uint32_t command_type : 4;
};
struct mmsch_v4_0_cmd_indirect_reg_header {
uint32_t reg_offset : 20;
uint32_t reg_idx_space : 8;
uint32_t command_type : 4;
};
struct mmsch_v4_0_cmd_direct_write {
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
uint32_t reg_value;
};
struct mmsch_v4_0_cmd_direct_read_modify_write {
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
uint32_t write_data;
uint32_t mask_value;
};
struct mmsch_v4_0_cmd_direct_polling {
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
uint32_t mask_value;
uint32_t wait_value;
};
struct mmsch_v4_0_cmd_end {
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
};
struct mmsch_v4_0_cmd_indirect_write {
struct mmsch_v4_0_cmd_indirect_reg_header cmd_header;
uint32_t reg_value;
};
#define MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(reg, mask, data) { \
size = sizeof(struct mmsch_v4_0_cmd_direct_read_modify_write); \
size_dw = size / 4; \
direct_rd_mod_wt.cmd_header.reg_offset = reg; \
direct_rd_mod_wt.mask_value = mask; \
direct_rd_mod_wt.write_data = data; \
memcpy((void *)table_loc, &direct_rd_mod_wt, size); \
table_loc += size_dw; \
table_size += size_dw; \
}
#define MMSCH_V4_0_INSERT_DIRECT_WT(reg, value) { \
size = sizeof(struct mmsch_v4_0_cmd_direct_write); \
size_dw = size / 4; \
direct_wt.cmd_header.reg_offset = reg; \
direct_wt.reg_value = value; \
memcpy((void *)table_loc, &direct_wt, size); \
table_loc += size_dw; \
table_size += size_dw; \
}
#define MMSCH_V4_0_INSERT_DIRECT_POLL(reg, mask, wait) { \
size = sizeof(struct mmsch_v4_0_cmd_direct_polling); \
size_dw = size / 4; \
direct_poll.cmd_header.reg_offset = reg; \
direct_poll.mask_value = mask; \
direct_poll.wait_value = wait; \
memcpy((void *)table_loc, &direct_poll, size); \
table_loc += size_dw; \
table_size += size_dw; \
}
#define MMSCH_V4_0_INSERT_END() { \
size = sizeof(struct mmsch_v4_0_cmd_end); \
size_dw = size / 4; \
memcpy((void *)table_loc, &end, size); \
table_loc += size_dw; \
table_size += size_dw; \
}
#endif

View File

@ -290,6 +290,7 @@ flr_done:
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}

View File

@ -317,6 +317,7 @@ flr_done:
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}

View File

@ -529,6 +529,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work)
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}

View File

@ -488,3 +488,47 @@ const struct amdgpu_nbio_funcs nbio_v4_3_funcs = {
.get_rom_offset = nbio_v4_3_get_rom_offset,
.program_aspm = nbio_v4_3_program_aspm,
};
static void nbio_v4_3_sriov_ih_doorbell_range(struct amdgpu_device *adev,
bool use_doorbell, int doorbell_index)
{
}
static void nbio_v4_3_sriov_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
bool use_doorbell, int doorbell_index,
int doorbell_size)
{
}
static void nbio_v4_3_sriov_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
int doorbell_index, int instance)
{
}
static void nbio_v4_3_sriov_gc_doorbell_init(struct amdgpu_device *adev)
{
}
const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs = {
.get_hdp_flush_req_offset = nbio_v4_3_get_hdp_flush_req_offset,
.get_hdp_flush_done_offset = nbio_v4_3_get_hdp_flush_done_offset,
.get_pcie_index_offset = nbio_v4_3_get_pcie_index_offset,
.get_pcie_data_offset = nbio_v4_3_get_pcie_data_offset,
.get_rev_id = nbio_v4_3_get_rev_id,
.mc_access_enable = nbio_v4_3_mc_access_enable,
.get_memsize = nbio_v4_3_get_memsize,
.sdma_doorbell_range = nbio_v4_3_sriov_sdma_doorbell_range,
.vcn_doorbell_range = nbio_v4_3_sriov_vcn_doorbell_range,
.gc_doorbell_init = nbio_v4_3_sriov_gc_doorbell_init,
.enable_doorbell_aperture = nbio_v4_3_enable_doorbell_aperture,
.enable_doorbell_selfring_aperture = nbio_v4_3_enable_doorbell_selfring_aperture,
.ih_doorbell_range = nbio_v4_3_sriov_ih_doorbell_range,
.update_medium_grain_clock_gating = nbio_v4_3_update_medium_grain_clock_gating,
.update_medium_grain_light_sleep = nbio_v4_3_update_medium_grain_light_sleep,
.get_clockgating_state = nbio_v4_3_get_clockgating_state,
.ih_control = nbio_v4_3_ih_control,
.init_registers = nbio_v4_3_init_registers,
.remap_hdp_registers = nbio_v4_3_remap_hdp_registers,
.get_rom_offset = nbio_v4_3_get_rom_offset,
};

View File

@ -28,5 +28,6 @@
extern const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg;
extern const struct amdgpu_nbio_funcs nbio_v4_3_funcs;
extern const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs;
#endif

View File

@ -68,12 +68,6 @@ static void nbio_v7_7_sdma_doorbell_range(struct amdgpu_device *adev, int instan
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC0_BIF_CSDMA_DOORBELL_RANGE,
SIZE, doorbell_size);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC0_BIF_SDMA0_DOORBELL_RANGE,
OFFSET, doorbell_index);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC0_BIF_SDMA0_DOORBELL_RANGE,
SIZE, doorbell_size);
} else {
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC0_BIF_SDMA0_DOORBELL_RANGE,
@ -247,6 +241,81 @@ static void nbio_v7_7_init_registers(struct amdgpu_device *adev)
}
static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
bool enable)
{
uint32_t def, data;
if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
return;
def = data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL);
if (enable) {
data |= (BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
} else {
data &= ~(BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
}
if (def != data)
WREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL, data);
}
static void nbio_v7_7_update_medium_grain_light_sleep(struct amdgpu_device *adev,
bool enable)
{
uint32_t def, data;
if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
return;
def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2);
if (enable)
data |= BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK;
else
data &= ~BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2, data);
def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1);
if (enable) {
data |= (BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
} else {
data &= ~(BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
}
if (def != data)
WREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1, data);
}
static void nbio_v7_7_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags)
{
uint32_t data;
/* AMD_CG_SUPPORT_BIF_MGCG */
data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL);
if (data & BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK)
*flags |= AMD_CG_SUPPORT_BIF_MGCG;
/* AMD_CG_SUPPORT_BIF_LS */
data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2);
if (data & BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK)
*flags |= AMD_CG_SUPPORT_BIF_LS;
}
const struct amdgpu_nbio_funcs nbio_v7_7_funcs = {
.get_hdp_flush_req_offset = nbio_v7_7_get_hdp_flush_req_offset,
.get_hdp_flush_done_offset = nbio_v7_7_get_hdp_flush_done_offset,
@ -262,6 +331,9 @@ const struct amdgpu_nbio_funcs nbio_v7_7_funcs = {
.enable_doorbell_aperture = nbio_v7_7_enable_doorbell_aperture,
.enable_doorbell_selfring_aperture = nbio_v7_7_enable_doorbell_selfring_aperture,
.ih_doorbell_range = nbio_v7_7_ih_doorbell_range,
.update_medium_grain_clock_gating = nbio_v7_7_update_medium_grain_clock_gating,
.update_medium_grain_light_sleep = nbio_v7_7_update_medium_grain_light_sleep,
.get_clockgating_state = nbio_v7_7_get_clockgating_state,
.ih_control = nbio_v7_7_ih_control,
.init_registers = nbio_v7_7_init_registers,
};

View File

@ -44,6 +44,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
/* For large FW files the time to complete can be very long */
#define USBC_PD_POLLING_LIMIT_S 240
@ -109,6 +110,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
break;
case IP_VERSION(13, 0, 0):
case IP_VERSION(13, 0, 7):
case IP_VERSION(13, 0, 10):
err = psp_init_sos_microcode(psp, chip_name);
if (err)
return err;

View File

@ -2002,7 +2002,6 @@ static int sdma_v4_0_sw_fini(void *handle)
static int sdma_v4_0_hw_init(void *handle)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->flags & AMD_IS_APU)
@ -2011,9 +2010,7 @@ static int sdma_v4_0_hw_init(void *handle)
if (!amdgpu_sriov_vf(adev))
sdma_v4_0_init_golden_registers(adev);
r = sdma_v4_0_start(adev);
return r;
return sdma_v4_0_start(adev);
}
static int sdma_v4_0_hw_fini(void *handle)

View File

@ -1413,12 +1413,9 @@ static int sdma_v5_2_sw_fini(void *handle)
static int sdma_v5_2_hw_init(void *handle)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = sdma_v5_2_start(adev);
return r;
return sdma_v5_2_start(adev);
}
static int sdma_v5_2_hw_fini(void *handle)

View File

@ -47,6 +47,7 @@
MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
#define SDMA1_REG_OFFSET 0x600
#define SDMA0_HYP_DEC_REG_START 0x5880
@ -559,7 +560,8 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
for (i = 0; i < adev->sdma.num_instances; i++) {
ring = &adev->sdma.instance[i].ring;
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
if (!amdgpu_sriov_vf(adev))
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
/* Set ring buffer size in dwords */
rb_bufsz = order_base_2(ring->ring_size / 4);
@ -593,7 +595,10 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
if (amdgpu_sriov_vf(adev))
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 1);
else
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, F32_WPTR_POLL_ENABLE, 1);
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE), ring->gpu_addr >> 8);

View File

@ -0,0 +1,303 @@
/*
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "sienna_cichlid.h"
#include "amdgpu_reset.h"
#include "amdgpu_amdkfd.h"
#include "amdgpu_dpm.h"
#include "amdgpu_job.h"
#include "amdgpu_ring.h"
#include "amdgpu_ras.h"
#include "amdgpu_psp.h"
#include "amdgpu_xgmi.h"
static struct amdgpu_reset_handler *
sienna_cichlid_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
struct amdgpu_reset_handler *handler;
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
if (reset_context->method != AMD_RESET_METHOD_NONE) {
list_for_each_entry(handler, &reset_ctl->reset_handlers,
handler_list) {
if (handler->reset_method == reset_context->method)
return handler;
}
} else {
list_for_each_entry(handler, &reset_ctl->reset_handlers,
handler_list) {
if (handler->reset_method == AMD_RESET_METHOD_MODE2 &&
adev->pm.fw_version >= 0x3a5500 &&
!amdgpu_sriov_vf(adev)) {
reset_context->method = AMD_RESET_METHOD_MODE2;
return handler;
}
}
}
return NULL;
}
static int sienna_cichlid_mode2_suspend_ip(struct amdgpu_device *adev)
{
int r, i;
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!(adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_GFX ||
adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_SDMA))
continue;
r = adev->ip_blocks[i].version->funcs->suspend(adev);
if (r) {
dev_err(adev->dev,
"suspend of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
adev->ip_blocks[i].status.hw = false;
}
return r;
}
static int
sienna_cichlid_mode2_prepare_hwcontext(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
int r = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
if (!amdgpu_sriov_vf(adev)) {
if (adev->gfxhub.funcs->mode2_save_regs)
adev->gfxhub.funcs->mode2_save_regs(adev);
if (adev->gfxhub.funcs->halt)
adev->gfxhub.funcs->halt(adev);
r = sienna_cichlid_mode2_suspend_ip(adev);
}
return r;
}
static void sienna_cichlid_async_reset(struct work_struct *work)
{
struct amdgpu_reset_handler *handler;
struct amdgpu_reset_control *reset_ctl =
container_of(work, struct amdgpu_reset_control, reset_work);
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
list_for_each_entry(handler, &reset_ctl->reset_handlers,
handler_list) {
if (handler->reset_method == reset_ctl->active_reset) {
dev_dbg(adev->dev, "Resetting device\n");
handler->do_reset(adev);
break;
}
}
}
static int sienna_cichlid_mode2_reset(struct amdgpu_device *adev)
{
/* disable BM */
pci_clear_master(adev->pdev);
return amdgpu_dpm_mode2_reset(adev);
}
static int
sienna_cichlid_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
int r;
r = sienna_cichlid_mode2_reset(adev);
if (r) {
dev_err(adev->dev,
"ASIC reset failed with error, %d ", r);
}
return r;
}
static int sienna_cichlid_mode2_restore_ip(struct amdgpu_device *adev)
{
int i, r;
struct psp_context *psp = &adev->psp;
r = psp_rlc_autoload_start(psp);
if (r) {
dev_err(adev->dev, "Failed to start rlc autoload\n");
return r;
}
/* Reinit GFXHUB */
if (adev->gfxhub.funcs->mode2_restore_regs)
adev->gfxhub.funcs->mode2_restore_regs(adev);
adev->gfxhub.funcs->init(adev);
r = adev->gfxhub.funcs->gart_enable(adev);
if (r) {
dev_err(adev->dev, "GFXHUB gart reenable failed after reset\n");
return r;
}
for (i = 0; i < adev->num_ip_blocks; i++) {
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
dev_err(adev->dev,
"resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
adev->ip_blocks[i].status.hw = true;
}
}
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!(adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_GFX ||
adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_SDMA))
continue;
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
dev_err(adev->dev,
"resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
adev->ip_blocks[i].status.hw = true;
}
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!(adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_GFX ||
adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_SDMA))
continue;
if (adev->ip_blocks[i].version->funcs->late_init) {
r = adev->ip_blocks[i].version->funcs->late_init(
(void *)adev);
if (r) {
dev_err(adev->dev,
"late_init of IP block <%s> failed %d after reset\n",
adev->ip_blocks[i].version->funcs->name,
r);
return r;
}
}
adev->ip_blocks[i].status.late_initialized = true;
}
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
return r;
}
static int
sienna_cichlid_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
int r;
struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle;
dev_info(tmp_adev->dev,
"GPU reset succeeded, trying to resume\n");
r = sienna_cichlid_mode2_restore_ip(tmp_adev);
if (r)
goto end;
/*
* Add this ASIC as tracked as reset was already
* complete successfully.
*/
amdgpu_register_gpu_instance(tmp_adev);
/* Resume RAS */
amdgpu_ras_resume(tmp_adev);
amdgpu_irq_gpu_reset_resume_helper(tmp_adev);
r = amdgpu_ib_ring_tests(tmp_adev);
if (r) {
dev_err(tmp_adev->dev,
"ib ring test failed (%d).\n", r);
r = -EAGAIN;
goto end;
}
end:
if (r)
return -EAGAIN;
else
return r;
}
static struct amdgpu_reset_handler sienna_cichlid_mode2_handler = {
.reset_method = AMD_RESET_METHOD_MODE2,
.prepare_env = NULL,
.prepare_hwcontext = sienna_cichlid_mode2_prepare_hwcontext,
.perform_reset = sienna_cichlid_mode2_perform_reset,
.restore_hwcontext = sienna_cichlid_mode2_restore_hwcontext,
.restore_env = NULL,
.do_reset = sienna_cichlid_mode2_reset,
};
int sienna_cichlid_reset_init(struct amdgpu_device *adev)
{
struct amdgpu_reset_control *reset_ctl;
reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL);
if (!reset_ctl)
return -ENOMEM;
reset_ctl->handle = adev;
reset_ctl->async_reset = sienna_cichlid_async_reset;
reset_ctl->active_reset = AMD_RESET_METHOD_NONE;
reset_ctl->get_reset_handler = sienna_cichlid_get_reset_handler;
INIT_LIST_HEAD(&reset_ctl->reset_handlers);
INIT_WORK(&reset_ctl->reset_work, reset_ctl->async_reset);
/* Only mode2 is handled through reset control now */
amdgpu_reset_add_handler(reset_ctl, &sienna_cichlid_mode2_handler);
adev->reset_cntl = reset_ctl;
return 0;
}
int sienna_cichlid_reset_fini(struct amdgpu_device *adev)
{
kfree(adev->reset_cntl);
adev->reset_cntl = NULL;
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 Advanced Micro Devices, Inc.
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -19,16 +19,14 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef DML_WRAPPER_H_
#define DML_WRAPPER_H_
#ifndef __SIENNA_CICHLID_H__
#define __SIENNA_CICHLID_H__
#include "dc.h"
#include "dml/display_mode_vba.h"
#include "amdgpu.h"
bool dml_validate(struct dc *dc, struct dc_state *context, bool fast_validate);
int sienna_cichlid_reset_init(struct amdgpu_device *adev);
int sienna_cichlid_reset_fini(struct amdgpu_device *adev);
#endif

View File

@ -179,7 +179,7 @@ void soc21_grbm_select(struct amdgpu_device *adev,
grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL), grbm_gfx_cntl);
WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, grbm_gfx_cntl);
}
static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
@ -494,6 +494,20 @@ static void soc21_pre_asic_init(struct amdgpu_device *adev)
{
}
static int soc21_update_umd_stable_pstate(struct amdgpu_device *adev,
bool enter)
{
if (enter)
amdgpu_gfx_rlc_enter_safe_mode(adev);
else
amdgpu_gfx_rlc_exit_safe_mode(adev);
if (adev->gfx.funcs->update_perfmon_mgcg)
adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);
return 0;
}
static const struct amdgpu_asic_funcs soc21_asic_funcs =
{
.read_disabled_bios = &soc21_read_disabled_bios,
@ -513,6 +527,7 @@ static const struct amdgpu_asic_funcs soc21_asic_funcs =
.supports_baco = &amdgpu_dpm_is_baco_supported,
.pre_asic_init = &soc21_pre_asic_init,
.query_video_codecs = &soc21_query_video_codecs,
.update_umd_stable_pstate = &soc21_update_umd_stable_pstate,
};
static int soc21_common_early_init(void *handle)
@ -567,6 +582,10 @@ static int soc21_common_early_init(void *handle)
AMD_PG_SUPPORT_JPEG |
AMD_PG_SUPPORT_ATHUB |
AMD_PG_SUPPORT_MMHUB;
if (amdgpu_sriov_vf(adev)) {
adev->cg_flags = 0;
adev->pg_flags = 0;
}
adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
break;
case IP_VERSION(11, 0, 2):
@ -603,6 +622,8 @@ static int soc21_common_early_init(void *handle)
AMD_CG_SUPPORT_ATHUB_MGCG |
AMD_CG_SUPPORT_ATHUB_LS |
AMD_CG_SUPPORT_IH_CG |
AMD_CG_SUPPORT_BIF_MGCG |
AMD_CG_SUPPORT_BIF_LS |
AMD_CG_SUPPORT_VCN_MGCG |
AMD_CG_SUPPORT_JPEG_MGCG;
adev->pg_flags =
@ -610,6 +631,19 @@ static int soc21_common_early_init(void *handle)
AMD_PG_SUPPORT_JPEG;
adev->external_rev_id = adev->rev_id + 0x1;
break;
case IP_VERSION(11, 0, 3):
adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG |
AMD_CG_SUPPORT_JPEG_MGCG;
adev->pg_flags = AMD_PG_SUPPORT_VCN |
AMD_PG_SUPPORT_VCN_DPG |
AMD_PG_SUPPORT_JPEG;
if (amdgpu_sriov_vf(adev)) {
/* hypervisor control CG and PG enablement */
adev->cg_flags = 0;
adev->pg_flags = 0;
}
adev->external_rev_id = adev->rev_id + 0x20;
break;
default:
/* FIXME: not supported yet */
return -EINVAL;
@ -702,6 +736,7 @@ static int soc21_common_set_clockgating_state(void *handle,
switch (adev->ip_versions[NBIO_HWIP][0]) {
case IP_VERSION(4, 3, 0):
case IP_VERSION(4, 3, 1):
case IP_VERSION(7, 7, 0):
adev->nbio.funcs->update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE);
adev->nbio.funcs->update_medium_grain_light_sleep(adev,
@ -709,10 +744,6 @@ static int soc21_common_set_clockgating_state(void *handle,
adev->hdp.funcs->update_clock_gating(adev,
state == AMD_CG_STATE_GATE);
break;
case IP_VERSION(7, 7, 0):
adev->hdp.funcs->update_clock_gating(adev,
state == AMD_CG_STATE_GATE);
break;
default:
break;
}

View File

@ -30,6 +30,7 @@
#include "soc15d.h"
#include "soc15_hw_ip.h"
#include "vcn_v2_0.h"
#include "mmsch_v4_0.h"
#include "vcn/vcn_4_0_0_offset.h"
#include "vcn/vcn_4_0_0_sh_mask.h"
@ -45,6 +46,8 @@
#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00
#define VCN1_VID_SOC_ADDRESS_3_0 0x48300
#define VCN_HARVEST_MMSCH 0
#define RDECODE_MSG_CREATE 0x00000000
#define RDECODE_MESSAGE_CREATE 0x00000001
@ -53,12 +56,14 @@ static int amdgpu_ih_clientid_vcns[] = {
SOC15_IH_CLIENTID_VCN1
};
static int vcn_v4_0_start_sriov(struct amdgpu_device *adev);
static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev);
static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev);
static int vcn_v4_0_set_powergating_state(void *handle,
enum amd_powergating_state state);
static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev,
int inst_idx, struct dpg_pause_state *new_state);
static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring);
/**
* vcn_v4_0_early_init - set function pointers
@ -71,6 +76,9 @@ static int vcn_v4_0_early_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (amdgpu_sriov_vf(adev))
adev->vcn.harvest_config = VCN_HARVEST_MMSCH;
/* re-use enc ring as unified ring */
adev->vcn.num_enc_rings = 1;
@ -92,6 +100,7 @@ static int vcn_v4_0_sw_init(void *handle)
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i, r;
int vcn_doorbell_index = 0;
r = amdgpu_vcn_sw_init(adev);
if (r)
@ -103,6 +112,12 @@ static int vcn_v4_0_sw_init(void *handle)
if (r)
return r;
if (amdgpu_sriov_vf(adev)) {
vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
/* get DWORD offset */
vcn_doorbell_index = vcn_doorbell_index << 1;
}
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
@ -119,7 +134,10 @@ static int vcn_v4_0_sw_init(void *handle)
ring = &adev->vcn.inst[i].ring_enc[0];
ring->use_doorbell = true;
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
if (amdgpu_sriov_vf(adev))
ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1;
else
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
sprintf(ring->name, "vcn_unified_%d", i);
@ -132,10 +150,19 @@ static int vcn_v4_0_sw_init(void *handle)
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
fw_shared->sq.is_enabled = 1;
if (amdgpu_sriov_vf(adev))
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
if (amdgpu_vcnfw_log)
amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
}
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_virt_alloc_mm_table(adev);
if (r)
return r;
}
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
@ -169,6 +196,9 @@ static int vcn_v4_0_sw_fini(void *handle)
drm_dev_exit(idx);
}
if (amdgpu_sriov_vf(adev))
amdgpu_virt_free_mm_table(adev);
r = amdgpu_vcn_suspend(adev);
if (r)
return r;
@ -191,18 +221,42 @@ static int vcn_v4_0_hw_init(void *handle)
struct amdgpu_ring *ring;
int i, r;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
continue;
ring = &adev->vcn.inst[i].ring_enc[0];
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
r = amdgpu_ring_test_helper(ring);
if (amdgpu_sriov_vf(adev)) {
r = vcn_v4_0_start_sriov(adev);
if (r)
goto done;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
continue;
ring = &adev->vcn.inst[i].ring_enc[0];
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
ring->sched.ready = false;
ring->no_scheduler = true;
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
} else {
ring->wptr = 0;
ring->wptr_old = 0;
vcn_v4_0_unified_ring_set_wptr(ring);
ring->sched.ready = true;
}
}
} else {
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
continue;
ring = &adev->vcn.inst[i].ring_enc[0];
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
r = amdgpu_ring_test_helper(ring);
if (r)
goto done;
}
}
done:
@ -230,12 +284,14 @@ static int vcn_v4_0_hw_fini(void *handle)
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
continue;
if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
if (!amdgpu_sriov_vf(adev)) {
if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
(adev->vcn.cur_state != AMD_PG_STATE_GATE &&
RREG32_SOC15(VCN, i, regUVD_STATUS))) {
vcn_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
}
}
}
return 0;
@ -1107,6 +1163,214 @@ static int vcn_v4_0_start(struct amdgpu_device *adev)
return 0;
}
static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
{
int i;
struct amdgpu_ring *ring_enc;
uint64_t cache_addr;
uint64_t rb_enc_addr;
uint64_t ctx_addr;
uint32_t param, resp, expected;
uint32_t offset, cache_size;
uint32_t tmp, timeout;
struct amdgpu_mm_table *table = &adev->virt.mm_table;
uint32_t *table_loc;
uint32_t table_size;
uint32_t size, size_dw;
uint32_t init_status;
uint32_t enabled_vcn;
struct mmsch_v4_0_cmd_direct_write
direct_wt = { {0} };
struct mmsch_v4_0_cmd_direct_read_modify_write
direct_rd_mod_wt = { {0} };
struct mmsch_v4_0_cmd_end end = { {0} };
struct mmsch_v4_0_init_header header;
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
volatile struct amdgpu_fw_shared_rb_setup *rb_setup;
direct_wt.cmd_header.command_type =
MMSCH_COMMAND__DIRECT_REG_WRITE;
direct_rd_mod_wt.cmd_header.command_type =
MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
end.cmd_header.command_type =
MMSCH_COMMAND__END;
header.version = MMSCH_VERSION;
header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2;
for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
header.inst[i].init_status = 0;
header.inst[i].table_offset = 0;
header.inst[i].table_size = 0;
}
table_loc = (uint32_t *)table->cpu_addr;
table_loc += header.total_size;
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
if (adev->vcn.harvest_config & (1 << i))
continue;
table_size = 0;
MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_STATUS),
~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
offset = 0;
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_OFFSET0),
0);
} else {
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
lower_32_bits(adev->vcn.inst[i].gpu_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
upper_32_bits(adev->vcn.inst[i].gpu_addr));
offset = cache_size;
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_OFFSET0),
AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
}
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_SIZE0),
cache_size);
cache_addr = adev->vcn.inst[i].gpu_addr + offset;
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
lower_32_bits(cache_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
upper_32_bits(cache_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_OFFSET1),
0);
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_SIZE1),
AMDGPU_VCN_STACK_SIZE);
cache_addr = adev->vcn.inst[i].gpu_addr + offset +
AMDGPU_VCN_STACK_SIZE;
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
lower_32_bits(cache_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
upper_32_bits(cache_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_OFFSET2),
0);
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_CACHE_SIZE2),
AMDGPU_VCN_CONTEXT_SIZE);
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
rb_setup = &fw_shared->rb_setup;
ring_enc = &adev->vcn.inst[i].ring_enc[0];
ring_enc->wptr = 0;
rb_enc_addr = ring_enc->gpu_addr;
rb_setup->is_rb_enabled_flags |= RB_ENABLED;
rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
rb_setup->rb_size = ring_enc->ring_size / 4;
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_VCPU_NONCACHE_SIZE0),
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
/* add end packet */
MMSCH_V4_0_INSERT_END();
/* refine header */
header.inst[i].init_status = 0;
header.inst[i].table_offset = header.total_size;
header.inst[i].table_size = table_size;
header.total_size += table_size;
}
/* Update init table header in memory */
size = sizeof(struct mmsch_v4_0_init_header);
table_loc = (uint32_t *)table->cpu_addr;
memcpy((void *)table_loc, &header, size);
/* message MMSCH (in VCN[0]) to initialize this client
* 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
* of memory descriptor location
*/
ctx_addr = table->gpu_addr;
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
/* 2, update vmid of descriptor */
tmp = RREG32_SOC15(VCN, 0, regMMSCH_VF_VMID);
tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
/* use domain0 for MM scheduler */
tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
WREG32_SOC15(VCN, 0, regMMSCH_VF_VMID, tmp);
/* 3, notify mmsch about the size of this descriptor */
size = header.total_size;
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE, size);
/* 4, set resp to zero */
WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP, 0);
/* 5, kick off the initialization and wait until
* MMSCH_VF_MAILBOX_RESP becomes non-zero
*/
param = 0x00000001;
WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_HOST, param);
tmp = 0;
timeout = 1000;
resp = 0;
expected = MMSCH_VF_MAILBOX_RESP__OK;
while (resp != expected) {
resp = RREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP);
if (resp != 0)
break;
udelay(10);
tmp = tmp + 10;
if (tmp >= timeout) {
DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
" waiting for regMMSCH_VF_MAILBOX_RESP "\
"(expected=0x%08x, readback=0x%08x)\n",
tmp, expected, resp);
return -EBUSY;
}
}
enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0;
init_status = ((struct mmsch_v4_0_init_header *)(table_loc))->inst[enabled_vcn].init_status;
if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE
&& init_status != MMSCH_VF_ENGINE_STATUS__PASS)
DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\
"status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status);
return 0;
}
/**
* vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode
*
@ -1596,6 +1860,15 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int ret;
/* for SRIOV, guest should not control VCN Power-gating
* MMSCH FW should control Power-gating and clock-gating
* guest should avoid touching CGC and PG
*/
if (amdgpu_sriov_vf(adev)) {
adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
return 0;
}
if(state == adev->vcn.cur_state)
return 0;

View File

@ -327,6 +327,12 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
goto err_bind_process;
}
if (!pdd->doorbell_index &&
kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
err = -ENOMEM;
goto err_alloc_doorbells;
}
/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
* on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
*/
@ -404,6 +410,7 @@ err_create_queue:
if (wptr_bo)
amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
err_wptr_map_gart:
err_alloc_doorbells:
err_bind_process:
err_pdd:
mutex_unlock(&p->mutex);
@ -869,14 +876,11 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
void *data)
{
struct kfd_ioctl_wait_events_args *args = data;
int err;
err = kfd_wait_on_events(p, args->num_events,
return kfd_wait_on_events(p, args->num_events,
(void __user *)args->events_ptr,
(args->wait_for_all != 0),
&args->timeout, &args->wait_result);
return err;
}
static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
struct kfd_process *p, void *data)
@ -1092,6 +1096,10 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
goto err_unlock;
}
offset = kfd_get_process_doorbells(pdd);
if (!offset) {
err = -ENOMEM;
goto err_unlock;
}
} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
if (args->size != PAGE_SIZE) {
err = -EINVAL;
@ -2173,6 +2181,8 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
return -EINVAL;
offset = kfd_get_process_doorbells(pdd);
if (!offset)
return -ENOMEM;
} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
/* MMIO BOs need remapped bus address */
if (bo_bucket->size != PAGE_SIZE) {
@ -2847,7 +2857,6 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
struct vm_area_struct *vma)
{
phys_addr_t address;
int ret;
if (vma->vm_end - vma->vm_start != PAGE_SIZE)
return -EINVAL;
@ -2867,12 +2876,11 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
process->pasid, (unsigned long long) vma->vm_start,
address, vma->vm_flags, PAGE_SIZE);
ret = io_remap_pfn_range(vma,
return io_remap_pfn_range(vma,
vma->vm_start,
address >> PAGE_SHIFT,
PAGE_SIZE,
vma->vm_page_prot);
return ret;
}

View File

@ -1522,6 +1522,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
pcache_info = cache_info;
num_of_cache_types =
kfd_fill_gpu_cache_info_from_gfx_config(kdev, pcache_info);

View File

@ -91,6 +91,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
kfd->device_info.num_sdma_queues_per_engine = 8;
break;
default:
@ -103,6 +104,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
switch (sdma_version) {
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
/* Reserve 1 for paging and 1 for gfx */
kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
/* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */
@ -150,6 +152,7 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
kfd->device_info.event_interrupt_class = &event_interrupt_class_v11;
break;
default:
@ -382,12 +385,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
f2g = &gfx_v10_3_kfd2kgd;
break;
case IP_VERSION(10, 3, 6):
gfx_target_version = 100306;
if (!vf)
f2g = &gfx_v10_3_kfd2kgd;
break;
case IP_VERSION(10, 3, 7):
gfx_target_version = 100307;
gfx_target_version = 100306;
if (!vf)
f2g = &gfx_v10_3_kfd2kgd;
break;
@ -403,6 +402,11 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
gfx_target_version = 110002;
f2g = &gfx_v11_kfd2kgd;
break;
case IP_VERSION(11, 0, 3):
/* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */
gfx_target_version = 110001;
f2g = &gfx_v11_kfd2kgd;
break;
default:
break;
}

View File

@ -157,6 +157,8 @@ int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
/* Calculate physical address of doorbell */
address = kfd_get_process_doorbells(pdd);
if (!address)
return -ENOMEM;
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
VM_DONTDUMP | VM_PFNMAP;
@ -275,6 +277,13 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
{
if (!pdd->doorbell_index) {
int r = kfd_alloc_process_doorbells(pdd->dev,
&pdd->doorbell_index);
if (r)
return 0;
}
return pdd->dev->doorbell_base +
pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
}

View File

@ -1499,11 +1499,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
if (!pdd)
return NULL;
if (kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
pr_err("Failed to alloc doorbell for pdd\n");
goto err_free_pdd;
}
if (init_doorbell_bitmap(&pdd->qpd, dev)) {
pr_err("Failed to init doorbell for process\n");
goto err_free_pdd;

View File

@ -1530,7 +1530,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
adev->dm.dc->debug.disable_dsc = true;
adev->dm.dc->debug.disable_dsc_edp = true;
}
if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING)
@ -5604,7 +5603,8 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
dc_dsc_policy_set_enable_dsc_when_not_needed(
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp &&
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP &&
!aconnector->dc_link->panel_config.dsc.disable_dsc_edp &&
dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) {
apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override);
@ -9304,6 +9304,7 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
/**
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
*
* @dev: The DRM device
* @state: The atomic state to commit
*
@ -9360,9 +9361,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
/* Skip connectors that are disabled or part of modeset already. */
if (!old_con_state->crtc && !new_con_state->crtc)
continue;
if (!new_con_state->crtc)
continue;
@ -9889,8 +9887,19 @@ static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
return valid_vsdb_found ? i : -ENODEV;
}
/**
* amdgpu_dm_update_freesync_caps - Update Freesync capabilities
*
* @connector: Connector to query.
* @edid: EDID from monitor
*
* Amdgpu supports Freesync in DP and HDMI displays, and it is required to keep
* track of some of the display information in the internal data struct used by
* amdgpu_dm. This function checks which type of connector we need to set the
* FreeSync parameters.
*/
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
struct edid *edid)
struct edid *edid)
{
int i = 0;
struct detailed_timing *timing;
@ -9903,8 +9912,8 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
bool freesync_capable = false;
struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
bool freesync_capable = false;
if (!connector->state) {
DRM_ERROR("%s - Connector has no state", __func__);
@ -9933,7 +9942,6 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
if (!adev->dm.freesync_module)
goto update;
if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT
|| sink->sink_signal == SIGNAL_TYPE_EDP) {
bool edid_check_required = false;

View File

@ -598,6 +598,10 @@ struct amdgpu_dm_connector {
* The 'current' sink is in dc_link->sink. */
struct dc_sink *dc_sink;
struct dc_link *dc_link;
/**
* @dc_em_sink: Reference to the emulated (virtual) sink.
*/
struct dc_sink *dc_em_sink;
/* DM only */
@ -610,7 +614,16 @@ struct amdgpu_dm_connector {
struct amdgpu_i2c_adapter *i2c;
/* Monitor range limits */
int min_vfreq ;
/**
* @min_vfreq: Minimal frequency supported by the display in Hz. This
* value is set to zero when there is no FreeSync support.
*/
int min_vfreq;
/**
* @max_vfreq: Maximum frequency supported by the display in Hz. This
* value is set to zero when there is no FreeSync support.
*/
int max_vfreq ;
int pixel_clock_mhz;
@ -705,11 +718,34 @@ struct dm_connector_state {
uint64_t pbn;
};
/**
* struct amdgpu_hdmi_vsdb_info - Keep track of the VSDB info
*
* AMDGPU supports FreeSync over HDMI by using the VSDB section, and this
* struct is useful to keep track of the display-specific information about
* FreeSync.
*/
struct amdgpu_hdmi_vsdb_info {
unsigned int amd_vsdb_version; /* VSDB version, should be used to determine which VSIF to send */
bool freesync_supported; /* FreeSync Supported */
unsigned int min_refresh_rate_hz; /* FreeSync Minimum Refresh Rate in Hz */
unsigned int max_refresh_rate_hz; /* FreeSync Maximum Refresh Rate in Hz */
/**
* @amd_vsdb_version: Vendor Specific Data Block Version, should be
* used to determine which Vendor Specific InfoFrame (VSIF) to send.
*/
unsigned int amd_vsdb_version;
/**
* @freesync_supported: FreeSync Supported.
*/
bool freesync_supported;
/**
* @min_refresh_rate_hz: FreeSync Minimum Refresh Rate in Hz.
*/
unsigned int min_refresh_rate_hz;
/**
* @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz
*/
unsigned int max_refresh_rate_hz;
};

View File

@ -29,7 +29,9 @@
#include "modules/color/color_gamma.h"
#include "basics/conversion.h"
/*
/**
* DOC: overview
*
* The DC interface to HW gives us the following color management blocks
* per pipe (surface):
*
@ -71,8 +73,8 @@
#define MAX_DRM_LUT_VALUE 0xFFFF
/*
* Initialize the color module.
/**
* amdgpu_dm_init_color_mod - Initialize the color module.
*
* We're not using the full color module, only certain components.
* Only call setup functions for components that we need.
@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void)
setup_x_points_distribution();
}
/* Extracts the DRM lut and lut size from a blob. */
/**
* __extract_blob_lut - Extracts the DRM lut and lut size from a blob.
* @blob: DRM color mgmt property blob
* @size: lut size
*
* Returns:
* DRM LUT or NULL
*/
static const struct drm_color_lut *
__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
{
@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
return blob ? (struct drm_color_lut *)blob->data : NULL;
}
/*
* Return true if the given lut is a linear mapping of values, i.e. it acts
* like a bypass LUT.
/**
* __is_lut_linear - check if the given lut is a linear mapping of values
* @lut: given lut to check values
* @size: lut size
*
* It is considered linear if the lut represents:
* f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in
* [0, MAX_COLOR_LUT_ENTRIES)
* f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0,
* MAX_COLOR_LUT_ENTRIES)
*
* Returns:
* True if the given lut is a linear mapping of values, i.e. it acts like a
* bypass LUT. Otherwise, false.
*/
static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
{
@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
return true;
}
/*
* Convert the drm_color_lut to dc_gamma. The conversion depends on the size
* of the lut - whether or not it's legacy.
/**
* __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma.
* @lut: DRM lookup table for color conversion
* @gamma: DC gamma to set entries
* @is_legacy: legacy or atomic gamma
*
* The conversion depends on the size of the lut - whether or not it's legacy.
*/
static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
struct dc_gamma *gamma, bool is_legacy)
@ -154,8 +172,11 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
}
}
/*
* Converts a DRM CTM to a DC CSC float matrix.
/**
* __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix
* @ctm: DRM color transformation matrix
* @matrix: DC CSC float matrix
*
* The matrix needs to be a 3x4 (12 entry) matrix.
*/
static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
@ -189,7 +210,18 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
}
}
/* Calculates the legacy transfer function - only for sRGB input space. */
/**
* __set_legacy_tf - Calculates the legacy transfer function
* @func: transfer function
* @lut: lookup table that defines the color space
* @lut_size: size of respective lut
* @has_rom: if ROM can be used for hardcoded curve
*
* Only for sRGB input space
*
* Returns:
* 0 in case of success, -ENOMEM if fails
*/
static int __set_legacy_tf(struct dc_transfer_func *func,
const struct drm_color_lut *lut, uint32_t lut_size,
bool has_rom)
@ -218,7 +250,16 @@ static int __set_legacy_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
}
/* Calculates the output transfer function based on expected input space. */
/**
* __set_output_tf - calculates the output transfer function based on expected input space.
* @func: transfer function
* @lut: lookup table that defines the color space
* @lut_size: size of respective lut
* @has_rom: if ROM can be used for hardcoded curve
*
* Returns:
* 0 in case of success. -ENOMEM if fails.
*/
static int __set_output_tf(struct dc_transfer_func *func,
const struct drm_color_lut *lut, uint32_t lut_size,
bool has_rom)
@ -262,7 +303,16 @@ static int __set_output_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
}
/* Caculates the input transfer function based on expected input space. */
/**
* __set_input_tf - calculates the input transfer function based on expected
* input space.
* @func: transfer function
* @lut: lookup table that defines the color space
* @lut_size: size of respective lut.
*
* Returns:
* 0 in case of success. -ENOMEM if fails.
*/
static int __set_input_tf(struct dc_transfer_func *func,
const struct drm_color_lut *lut, uint32_t lut_size)
{
@ -285,13 +335,14 @@ static int __set_input_tf(struct dc_transfer_func *func,
}
/**
* amdgpu_dm_verify_lut_sizes
* amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes
* @crtc_state: the DRM CRTC state
*
* Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
* the expected size.
* Verifies that the Degamma and Gamma LUTs attached to the &crtc_state
* are of the expected size.
*
* Returns 0 on success.
* Returns:
* 0 on success. -EINVAL if any lut sizes are invalid.
*/
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
{
@ -327,9 +378,9 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
* of the HW blocks as long as the CRTC CTM always comes before the
* CRTC RGM and after the CRTC DGM.
*
* The CRTC RGM block will be placed in the RGM LUT block if it is non-linear.
* The CRTC DGM block will be placed in the DGM LUT block if it is non-linear.
* The CRTC CTM will be placed in the gamut remap block if it is non-linear.
* - The CRTC RGM block will be placed in the RGM LUT block if it is non-linear.
* - The CRTC DGM block will be placed in the DGM LUT block if it is non-linear.
* - The CRTC CTM will be placed in the gamut remap block if it is non-linear.
*
* The RGM block is typically more fully featured and accurate across
* all ASICs - DCE can't support a custom non-linear CRTC DGM.
@ -338,7 +389,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
* management at once we have to either restrict the usage of CRTC properties
* or blend adjustments together.
*
* Returns 0 on success.
* Returns:
* 0 on success. Error code if setup fails.
*/
int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
{
@ -393,7 +445,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
if (r)
return r;
} else if (has_regamma) {
/* CRTC RGM goes into RGM LUT. */
/* If atomic regamma, CRTC RGM goes into RGM LUT. */
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
@ -450,9 +502,10 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
*
* Update the underlying dc_stream_state's input transfer function (ITF) in
* preparation for hardware commit. The transfer function used depends on
* the prepartion done on the stream for color management.
* the preparation done on the stream for color management.
*
* Returns 0 on success.
* Returns:
* 0 on success. -ENOMEM if mem allocation fails.
*/
int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
struct dc_plane_state *dc_plane_state)

View File

@ -3288,6 +3288,7 @@ void crtc_debugfs_init(struct drm_crtc *crtc)
&crc_win_y_end_fops);
debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
&crc_win_update_fops);
dput(dir);
#endif
debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry,
crtc, &amdgpu_current_bpc_fops);

View File

@ -691,8 +691,14 @@ bool dm_helpers_dp_write_dsc_enable(
const struct dc_stream_state *stream,
bool enable)
{
uint8_t enable_dsc = enable ? 1 : 0;
static const uint8_t DSC_DISABLE;
static const uint8_t DSC_DECODING = 0x01;
static const uint8_t DSC_PASSTHROUGH = 0x02;
struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_port *port;
uint8_t enable_dsc = enable ? DSC_DECODING : DSC_DISABLE;
uint8_t enable_passthrough = enable ? DSC_PASSTHROUGH : DSC_DISABLE;
uint8_t ret = 0;
if (!stream)
@ -712,8 +718,39 @@ bool dm_helpers_dp_write_dsc_enable(
aconnector->dsc_aux, stream, enable_dsc);
#endif
ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1);
DC_LOG_DC("Send DSC %s to MST RX\n", enable_dsc ? "enable" : "disable");
port = aconnector->port;
if (enable) {
if (port->passthrough_aux) {
ret = drm_dp_dpcd_write(port->passthrough_aux,
DP_DSC_ENABLE,
&enable_passthrough, 1);
DC_LOG_DC("Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
ret);
}
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
DC_LOG_DC("Sent DSC decoding enable to %s port, ret = %u\n",
(port->passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
} else {
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
DC_LOG_DC("Sent DSC decoding disable to %s port, ret = %u\n",
(port->passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
if (port->passthrough_aux) {
ret = drm_dp_dpcd_write(port->passthrough_aux,
DP_DSC_ENABLE,
&enable_passthrough, 1);
DC_LOG_DC("Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
ret);
}
}
}
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
@ -730,7 +767,7 @@ bool dm_helpers_dp_write_dsc_enable(
#endif
}
return (ret > 0);
return ret;
}
bool dm_helpers_is_dp_sink_present(struct dc_link *link)
@ -841,6 +878,25 @@ void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigne
//amdgpu_device_gpu_recover(dc_context->driver-context, NULL);
}
void dm_helpers_init_panel_settings(
struct dc_context *ctx,
struct dc_panel_config *panel_config)
{
// Feature DSC
panel_config->dsc.disable_dsc_edp = false;
panel_config->dsc.force_dsc_edp_policy = 0;
}
void dm_helpers_override_panel_settings(
struct dc_context *ctx,
struct dc_panel_config *panel_config)
{
// Feature DSC
if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
panel_config->dsc.disable_dsc_edp = true;
}
}
void *dm_helpers_allocate_gpu_mem(
struct dc_context *ctx,
enum dc_gpu_mem_alloc_type type,

View File

@ -36,6 +36,7 @@
#include "dm_helpers.h"
#include "dc_link_ddc.h"
#include "dc_link_dp.h"
#include "ddc_service_types.h"
#include "dpcd_defs.h"
@ -1351,19 +1352,90 @@ clean_exit:
return (ret == 0);
}
#endif
static unsigned int kbps_from_pbn(unsigned int pbn)
{
unsigned int kbps = pbn;
kbps *= (1000000 / PEAK_FACTOR_X1000);
kbps *= 8;
kbps *= 54;
kbps /= 64;
return kbps;
}
static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
struct dc_dsc_bw_range *bw_range)
{
struct dc_dsc_policy dsc_policy = {0};
dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy);
dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0],
stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
dsc_policy.min_target_bpp * 16,
dsc_policy.max_target_bpp * 16,
&stream->sink->dsc_caps.dsc_dec_caps,
&stream->timing, bw_range);
return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16;
}
#endif /* CONFIG_DRM_AMD_DC_DCN */
enum dc_status dm_dp_mst_is_port_support_mode(
struct amdgpu_dm_connector *aconnector,
struct dc_stream_state *stream)
{
int bpp, pbn, branch_max_throughput_mps = 0;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link_settings cur_link_settings;
unsigned int end_to_end_bw_in_kbps = 0;
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
unsigned int max_compressed_bw_in_kbps = 0;
struct dc_dsc_bw_range bw_range = {0};
/* check if mode could be supported within fUll_pbn */
bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
if (pbn > aconnector->port->full_pbn)
return DC_FAIL_BANDWIDTH_VALIDATE;
/*
* check if the mode could be supported if DSC pass-through is supported
* AND check if there enough bandwidth available to support the mode
* with DSC enabled.
*/
if (is_dsc_common_config_possible(stream, &bw_range) &&
aconnector->port->passthrough_aux) {
mutex_lock(&aconnector->mst_mgr.lock);
cur_link_settings = stream->link->verified_link_cap;
upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
&cur_link_settings
);
down_link_bw_in_kbps = kbps_from_pbn(aconnector->port->full_pbn);
/* pick the bottleneck */
end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
down_link_bw_in_kbps);
mutex_unlock(&aconnector->mst_mgr.lock);
/*
* use the maximum dsc compression bandwidth as the required
* bandwidth for the mode
*/
max_compressed_bw_in_kbps = bw_range.min_kbps;
if (end_to_end_bw_in_kbps < max_compressed_bw_in_kbps) {
DRM_DEBUG_DRIVER("Mode does not fit into DSC pass-through bandwidth validation\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
} else {
#endif
/* check if mode could be supported within full_pbn */
bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
if (pbn > aconnector->port->full_pbn)
return DC_FAIL_BANDWIDTH_VALIDATE;
#if defined(CONFIG_DRM_AMD_DC_DCN)
}
#endif
/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
switch (stream->timing.pixel_encoding) {

View File

@ -34,6 +34,7 @@
#include "dal_asic_id.h"
#include "amdgpu_display.h"
#include "amdgpu_dm_trace.h"
#include "amdgpu_dm_plane.h"
#include "gc/gc_11_0_0_offset.h"
#include "gc/gc_11_0_0_sh_mask.h"
@ -149,12 +150,12 @@ static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_
*size += 1;
}
bool modifier_has_dcc(uint64_t modifier)
static bool modifier_has_dcc(uint64_t modifier)
{
return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
}
unsigned modifier_gfx9_swizzle_mode(uint64_t modifier)
static unsigned modifier_gfx9_swizzle_mode(uint64_t modifier)
{
if (modifier == DRM_FORMAT_MOD_LINEAR)
return 0;

View File

@ -36,17 +36,9 @@ int fill_dc_scaling_info(struct amdgpu_device *adev,
const struct drm_plane_state *state,
struct dc_scaling_info *scaling_info);
void get_min_max_dc_plane_scaling(struct drm_device *dev,
struct drm_framebuffer *fb,
int *min_downscale, int *max_upscale);
int dm_plane_helper_check_state(struct drm_plane_state *state,
struct drm_crtc_state *new_crtc_state);
bool modifier_has_dcc(uint64_t modifier);
unsigned int modifier_gfx9_swizzle_mode(uint64_t modifier);
int fill_plane_buffer_attributes(struct amdgpu_device *adev,
const struct amdgpu_framebuffer *afb,
const enum surface_pixel_format format,

View File

@ -44,25 +44,6 @@
#include "bios_parser_common.h"
/* Temporarily add in defines until ObjectID.h patch is updated in a few days */
#ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
#define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05
#endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */
#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \
(GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */
#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \
(GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */
#define DC_LOGGER \
bp->base.ctx->logger

View File

@ -48,6 +48,11 @@
#include "dc_dmub_srv.h"
#include "logger_types.h"
#undef DC_LOGGER
#define DC_LOGGER \
clk_mgr->base.base.ctx->logger
#include "yellow_carp_offset.h"
#define regCLK1_CLK_PLL_REQ 0x0237
@ -737,8 +742,49 @@ void dcn31_clk_mgr_construct(
clk_mgr->base.base.bw_params = &dcn31_bw_params;
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
int i;
dcn31_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
"NumDispClkLevelsEnabled: %d\n"
"NumSocClkLevelsEnabled: %d\n"
"VcnClkLevelsEnabled: %d\n"
"NumDfPst atesEnabled: %d\n"
"MinGfxClk: %d\n"
"MaxGfxClk: %d\n",
smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
smu_dpm_clks.dpm_clks->MinGfxClk,
smu_dpm_clks.dpm_clks->MaxGfxClk);
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
i,
smu_dpm_clks.dpm_clks->DcfClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->DispClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocClocks[i]);
}
for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
}
if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
dcn31_clk_mgr_helper_populate_bw_params(
&clk_mgr->base,

View File

@ -51,6 +51,13 @@
#include "dc_link_dp.h"
#include "dcn314_smu.h"
#include "logger_types.h"
#undef DC_LOGGER
#define DC_LOGGER \
clk_mgr->base.base.ctx->logger
#define MAX_INSTANCE 7
#define MAX_SEGMENT 8
@ -614,7 +621,7 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
clock_table->DfPstateTable[min_pstate].WckRatio);
};
}
/* Make sure to include at least one entry at highest pstate */
if (max_pstate != min_pstate || i == 0) {
@ -775,7 +782,48 @@ void dcn314_clk_mgr_construct(
clk_mgr->base.base.bw_params = &dcn314_bw_params;
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
int i;
dcn314_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
"NumDispClkLevelsEnabled: %d\n"
"NumSocClkLevelsEnabled: %d\n"
"VcnClkLevelsEnabled: %d\n"
"NumDfPst atesEnabled: %d\n"
"MinGfxClk: %d\n"
"MaxGfxClk: %d\n",
smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
smu_dpm_clks.dpm_clks->MinGfxClk,
smu_dpm_clks.dpm_clks->MaxGfxClk);
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
i,
smu_dpm_clks.dpm_clks->DcfClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->DispClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocClocks[i]);
}
for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
}
if (ctx->dc_bios && ctx->dc_bios->integrated_info && ctx->dc->config.use_default_clock_table == false) {
dcn314_clk_mgr_helper_populate_bw_params(

View File

@ -41,6 +41,11 @@
#include "dc_dmub_srv.h"
#include "logger_types.h"
#undef DC_LOGGER
#define DC_LOGGER \
clk_mgr->base.base.ctx->logger
#include "dc_link_dp.h"
#define TO_CLK_MGR_DCN315(clk_mgr)\
@ -507,7 +512,7 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i];
bw_params->clk_table.entries[i].dppclk_mhz = clock_table->DppClocks[i];
bw_params->clk_table.entries[i].wck_ratio = 1;
};
}
/* Make sure to include at least one entry and highest pstate */
if (max_pstate != min_pstate || i == 0) {
@ -666,7 +671,48 @@ void dcn315_clk_mgr_construct(
clk_mgr->base.base.bw_params = &dcn315_bw_params;
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
int i;
dcn315_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
"NumDispClkLevelsEnabled: %d\n"
"NumSocClkLevelsEnabled: %d\n"
"VcnClkLevelsEnabled: %d\n"
"NumDfPst atesEnabled: %d\n"
"MinGfxClk: %d\n"
"MaxGfxClk: %d\n",
smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
smu_dpm_clks.dpm_clks->MinGfxClk,
smu_dpm_clks.dpm_clks->MaxGfxClk);
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
i,
smu_dpm_clks.dpm_clks->DcfClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->DispClocks[i]);
}
for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocClocks[i]);
}
for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
"smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
}
if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
dcn315_clk_mgr_helper_populate_bw_params(

View File

@ -638,14 +638,17 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
/**
* dc_stream_get_crc() - Get CRC values for the given stream.
* @dc: DC object
*
* @dc: DC object.
* @stream: The DC stream state of the stream to get CRCs from.
* @r_cr: CRC value for the first of the 3 channels stored here.
* @g_y: CRC value for the second of the 3 channels stored here.
* @b_cb: CRC value for the third of the 3 channels stored here.
* @r_cr: CRC value for the red component.
* @g_y: CRC value for the green component.
* @b_cb: CRC value for the blue component.
*
* dc_stream_configure_crc needs to be called beforehand to enable CRCs.
* Return false if stream is not found, or if CRCs are not enabled.
*
* Return:
* false if stream is not found, or if CRCs are not enabled.
*/
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
@ -1094,7 +1097,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
dc->current_state->stream_count != context->stream_count)
should_disable = true;
if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe) {
if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe &&
!dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe) {
struct pipe_ctx *old_pipe, *new_pipe;
old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
@ -1177,7 +1181,11 @@ static void disable_vbios_mode_if_required(
pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
if (pix_clk_100hz != requested_pix_clk_100hz) {
core_link_disable_stream(pipe);
if (dc->hwss.update_phy_state)
dc->hwss.update_phy_state(dc->current_state,
pipe, TX_OFF_SYMCLK_OFF);
else
core_link_disable_stream(pipe);
pipe->stream->dpms_off = false;
}
}
@ -3060,7 +3068,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (stream_update->dpms_off) {
if (*stream_update->dpms_off) {
core_link_disable_stream(pipe_ctx);
if (dc->hwss.update_phy_state)
dc->hwss.update_phy_state(dc->current_state,
pipe_ctx, TX_OFF_SYMCLK_ON);
else
core_link_disable_stream(pipe_ctx);
/* for dpms, keep acquired resources*/
if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
@ -3071,7 +3083,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (get_seamless_boot_stream_count(context) == 0)
dc->hwss.prepare_bandwidth(dc, dc->current_state);
core_link_enable_stream(dc->current_state, pipe_ctx);
if (dc->hwss.update_phy_state)
dc->hwss.update_phy_state(dc->current_state,
pipe_ctx, TX_ON_SYMCLK_ON);
else
core_link_enable_stream(dc->current_state, pipe_ctx);
}
}
@ -3098,11 +3114,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream)
{
if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
return true;
if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1 &&
dc->debug.enable_sw_cntl_psr)
if ((stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1
|| stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
&& stream->ctx->dce_version >= DCN_VERSION_3_1)
return true;
return false;
@ -3318,10 +3332,6 @@ static void commit_planes_for_stream(struct dc *dc,
if (dc->hwss.program_front_end_for_ctx)
dc->hwss.program_front_end_for_ctx(dc, context);
if (update_type != UPDATE_TYPE_FAST)
if (dc->hwss.commit_subvp_config)
dc->hwss.commit_subvp_config(dc, context);
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
dc->hwss.interdependent_update_lock(dc, context, false);
} else {
@ -3329,16 +3339,15 @@ static void commit_planes_for_stream(struct dc *dc,
}
dc->hwss.post_unlock_program_front_end(dc, context);
if (update_type != UPDATE_TYPE_FAST)
if (dc->hwss.commit_subvp_config)
dc->hwss.commit_subvp_config(dc, context);
/* Since phantom pipe programming is moved to post_unlock_program_front_end,
* move the SubVP lock to after the phantom pipes have been setup
*/
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
if (dc->hwss.subvp_pipe_control_lock)
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
} else {
if (dc->hwss.subvp_pipe_control_lock)
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
}
if (dc->hwss.subvp_pipe_control_lock)
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
return;
}
@ -3462,10 +3471,6 @@ static void commit_planes_for_stream(struct dc *dc,
}
if (update_type != UPDATE_TYPE_FAST)
if (dc->hwss.commit_subvp_config)
dc->hwss.commit_subvp_config(dc, context);
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
dc->hwss.interdependent_update_lock(dc, context, false);
} else {
@ -3503,6 +3508,10 @@ static void commit_planes_for_stream(struct dc *dc,
if (update_type != UPDATE_TYPE_FAST)
dc->hwss.post_unlock_program_front_end(dc, context);
if (update_type != UPDATE_TYPE_FAST)
if (dc->hwss.commit_subvp_config)
dc->hwss.commit_subvp_config(dc, context);
/* Since phantom pipe programming is moved to post_unlock_program_front_end,
* move the SubVP lock to after the phantom pipes have been setup
*/
@ -3543,8 +3552,10 @@ static bool commit_minimal_transition_state(struct dc *dc,
if (!transition_context)
return false;
tmp_policy = dc->debug.pipe_split_policy;
dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
if (!dc->config.is_vmin_only_asic) {
tmp_policy = dc->debug.pipe_split_policy;
dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
}
dc_resource_state_copy_construct(transition_base_context, transition_context);
@ -3570,7 +3581,8 @@ static bool commit_minimal_transition_state(struct dc *dc,
dc_release_state(transition_context);
//restore previous pipe split policy
dc->debug.pipe_split_policy = tmp_policy;
if (!dc->config.is_vmin_only_asic)
dc->debug.pipe_split_policy = tmp_policy;
if (ret != DC_OK) {
//this should never happen

View File

@ -402,6 +402,44 @@ void get_hdr_visual_confirm_color(
}
}
void get_subvp_visual_confirm_color(
struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct tg_color *color)
{
uint32_t color_value = MAX_TG_COLOR_VALUE;
bool enable_subvp = false;
int i;
if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx)
return;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->stream->mall_stream_config.paired_stream &&
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
/* SubVP enable - red */
color->color_r_cr = color_value;
enable_subvp = true;
if (pipe_ctx->stream == pipe->stream)
return;
break;
}
}
if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) {
color->color_r_cr = 0;
if (pipe_ctx->stream->ignore_msa_timing_param == 1)
/* SubVP enable and DRR on - green */
color->color_g_y = color_value;
else
/* SubVP enable and No DRR - blue */
color->color_b_cb = color_value;
}
}
void get_surface_tile_visual_confirm_color(
struct pipe_ctx *pipe_ctx,
struct tg_color *color)

View File

@ -1311,6 +1311,14 @@ static bool detect_link_and_local_sink(struct dc_link *link,
sink->edid_caps.audio_modes[i].sample_rate,
sink->edid_caps.audio_modes[i].sample_size);
}
if (link->connector_signal == SIGNAL_TYPE_EDP) {
// Init dc_panel_config
dm_helpers_init_panel_settings(dc_ctx, &link->panel_config);
// Override dc_panel_config if system has specific settings
dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
}
} else {
/* From Connected-to-Disconnected. */
link->type = dc_connection_none;
@ -2069,11 +2077,7 @@ static enum dc_status enable_link_edp(
struct dc_state *state,
struct pipe_ctx *pipe_ctx)
{
enum dc_status status;
status = enable_link_dp(state, pipe_ctx);
return status;
return enable_link_dp(state, pipe_ctx);
}
static enum dc_status enable_link_dp_mst(
@ -4295,18 +4299,6 @@ void core_link_enable_stream(
if (pipe_ctx->stream->dpms_off)
return;
/* Have to setup DSC before DIG FE and BE are connected (which happens before the
* link training). This is to make sure the bandwidth sent to DIG BE won't be
* bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
* will be automatically set at a later time when the video is enabled
* (DP_VID_STREAM_EN = 1).
*/
if (pipe_ctx->stream->timing.flags.DSC) {
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
dc_is_virtual_signal(pipe_ctx->stream->signal))
dp_set_dsc_enable(pipe_ctx, true);
}
status = enable_link(state, pipe_ctx);
if (status != DC_OK) {
@ -4736,7 +4728,7 @@ bool dc_link_should_enable_fec(const struct dc_link *link)
else if (link->connector_signal == SIGNAL_TYPE_EDP
&& (link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.
dsc_support.DSC_SUPPORT == false
|| link->dc->debug.disable_dsc_edp
|| link->panel_config.dsc.disable_dsc_edp
|| !link->dc->caps.edp_dsc_support))
force_disable = true;

View File

@ -3743,7 +3743,7 @@ static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
unsigned int policy = 0;
policy = link->ctx->dc->debug.force_dsc_edp_policy;
policy = link->panel_config.dsc.force_dsc_edp_policy;
if (max_link_rate == LINK_RATE_UNKNOWN)
max_link_rate = link->verified_link_cap.link_rate;
/*
@ -3909,7 +3909,7 @@ bool decide_link_settings(struct dc_stream_state *stream,
if (stream->timing.flags.DSC) {
enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
if (link->ctx->dc->debug.force_dsc_edp_policy) {
if (link->panel_config.dsc.force_dsc_edp_policy) {
/* calculate link max link rate cap*/
struct dc_link_settings tmp_link_setting;
struct dc_crtc_timing tmp_timing = stream->timing;
@ -4519,7 +4519,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
core_link_disable_stream(pipe_ctx);
if (link->dc->hwss.update_phy_state)
link->dc->hwss.update_phy_state(link->dc->current_state,
pipe_ctx, TX_OFF_SYMCLK_OFF);
else
core_link_disable_stream(pipe_ctx);
}
}
@ -4527,7 +4531,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
core_link_enable_stream(link->dc->current_state, pipe_ctx);
if (link->dc->hwss.update_phy_state)
link->dc->hwss.update_phy_state(link->dc->current_state,
pipe_ctx, TX_ON_SYMCLK_ON);
else
core_link_enable_stream(link->dc->current_state, pipe_ctx);
}
}
}
@ -5024,6 +5032,10 @@ static void determine_lttpr_mode(struct dc_link *link)
bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
if (link->ctx->dc->debug.lttpr_mode_override != 0) {
link->lttpr_mode = link->ctx->dc->debug.lttpr_mode_override;
return;
}
if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
@ -5267,6 +5279,7 @@ static bool retrieve_link_cap(struct dc_link *link)
union dp_downstream_port_present ds_port = { 0 };
enum dc_status status = DC_ERROR_UNEXPECTED;
uint32_t read_dpcd_retry_cnt = 3;
uint32_t aux_channel_retry_cnt = 0;
int i;
struct dp_sink_hw_fw_revision dp_hw_fw_revision;
const uint32_t post_oui_delay = 30; // 30ms
@ -5294,21 +5307,43 @@ static bool retrieve_link_cap(struct dc_link *link)
status = wa_try_to_wake_dprx(link, timeout_ms);
}
while (status != DC_OK && aux_channel_retry_cnt < 10) {
status = core_link_read_dpcd(link, DP_SET_POWER,
&dpcd_power_state, sizeof(dpcd_power_state));
/* Delay 1 ms if AUX CH is in power down state. Based on spec
* section 2.3.1.2, if AUX CH may be powered down due to
* write to DPCD 600h = 2. Sink AUX CH is monitoring differential
* signal and may need up to 1 ms before being able to reply.
*/
if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) {
udelay(1000);
aux_channel_retry_cnt++;
}
}
/* If aux channel is not active, return false and trigger another detect*/
if (status != DC_OK) {
dpcd_power_state = DP_SET_POWER_D0;
status = core_link_write_dpcd(
link,
DP_SET_POWER,
&dpcd_power_state,
sizeof(dpcd_power_state));
dpcd_power_state = DP_SET_POWER_D3;
status = core_link_write_dpcd(
link,
DP_SET_POWER,
&dpcd_power_state,
sizeof(dpcd_power_state));
return false;
}
is_lttpr_present = dp_retrieve_lttpr_cap(link);
/* Read DP tunneling information. */
status = dpcd_get_tunneling_device_data(link);
status = core_link_read_dpcd(link, DP_SET_POWER,
&dpcd_power_state, sizeof(dpcd_power_state));
/* Delay 1 ms if AUX CH is in power down state. Based on spec
* section 2.3.1.2, if AUX CH may be powered down due to
* write to DPCD 600h = 2. Sink AUX CH is monitoring differential
* signal and may need up to 1 ms before being able to reply.
*/
if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
udelay(1000);
dpcd_set_source_specific_data(link);
/* Sink may need to configure internals based on vendor, so allow some
* time before proceeding with possibly vendor specific transactions

View File

@ -1904,9 +1904,6 @@ bool dc_is_stream_unchanged(
if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0)
return false;
if (old_stream->odm_2to1_policy_applied != stream->odm_2to1_policy_applied)
return false;
return true;
}

View File

@ -47,7 +47,7 @@ struct aux_payload;
struct set_config_cmd_payload;
struct dmub_notification;
#define DC_VER "3.2.198"
#define DC_VER "3.2.201"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@ -118,7 +118,26 @@ struct dc_plane_cap {
uint32_t min_height;
};
// Color management caps (DPP and MPC)
/**
* DOC: color-management-caps
*
* **Color management caps (DPP and MPC)**
*
* Modules/color calculates various color operations which are translated to
* abstracted HW. DCE 5-12 had almost no important changes, but starting with
* DCN1, every new generation comes with fairly major differences in color
* pipeline. Therefore, we abstract color pipe capabilities so modules/DM can
* decide mapping to HW block based on logical capabilities.
*/
/**
* struct rom_curve_caps - predefined transfer function caps for degamma and regamma
* @srgb: RGB color space transfer func
* @bt2020: BT.2020 transfer func
* @gamma2_2: standard gamma
* @pq: perceptual quantizer transfer function
* @hlg: hybrid loggamma transfer function
*/
struct rom_curve_caps {
uint16_t srgb : 1;
uint16_t bt2020 : 1;
@ -127,36 +146,68 @@ struct rom_curve_caps {
uint16_t hlg : 1;
};
/**
* struct dpp_color_caps - color pipeline capabilities for display pipe and
* plane blocks
*
* @dcn_arch: all DCE generations treated the same
* @input_lut_shared: shared with DGAM. Input LUT is different than most LUTs,
* just plain 256-entry lookup
* @icsc: input color space conversion
* @dgam_ram: programmable degamma LUT
* @post_csc: post color space conversion, before gamut remap
* @gamma_corr: degamma correction
* @hw_3d_lut: 3D LUT support. It implies a shaper LUT before. It may be shared
* with MPC by setting mpc:shared_3d_lut flag
* @ogam_ram: programmable out/blend gamma LUT
* @ocsc: output color space conversion
* @dgam_rom_for_yuv: pre-defined degamma LUT for YUV planes
* @dgam_rom_caps: pre-definied curve caps for degamma 1D LUT
* @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT
*
* Note: hdr_mult and gamut remap (CTM) are always available in DPP (in that order)
*/
struct dpp_color_caps {
uint16_t dcn_arch : 1; // all DCE generations treated the same
// input lut is different than most LUTs, just plain 256-entry lookup
uint16_t input_lut_shared : 1; // shared with DGAM
uint16_t dcn_arch : 1;
uint16_t input_lut_shared : 1;
uint16_t icsc : 1;
uint16_t dgam_ram : 1;
uint16_t post_csc : 1; // before gamut remap
uint16_t post_csc : 1;
uint16_t gamma_corr : 1;
// hdr_mult and gamut remap always available in DPP (in that order)
// 3d lut implies shaper LUT,
// it may be shared with MPC - check MPC:shared_3d_lut flag
uint16_t hw_3d_lut : 1;
uint16_t ogam_ram : 1; // blnd gam
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t dgam_rom_for_yuv : 1;
struct rom_curve_caps dgam_rom_caps;
struct rom_curve_caps ogam_rom_caps;
};
/**
* struct mpc_color_caps - color pipeline capabilities for multiple pipe and
* plane combined blocks
*
* @gamut_remap: color transformation matrix
* @ogam_ram: programmable out gamma LUT
* @ocsc: output color space conversion matrix
* @num_3dluts: MPC 3D LUT; always assumes a preceding shaper LUT
* @shared_3d_lut: shared 3D LUT flag. Can be either DPP or MPC, but single
* instance
* @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT
*/
struct mpc_color_caps {
uint16_t gamut_remap : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT
uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance
uint16_t num_3dluts : 3;
uint16_t shared_3d_lut:1;
struct rom_curve_caps ogam_rom_caps;
};
/**
* struct dc_color_caps - color pipes capabilities for DPP and MPC hw blocks
* @dpp: color pipes caps for DPP
* @mpc: color pipes caps for MPC
*/
struct dc_color_caps {
struct dpp_color_caps dpp;
struct mpc_color_caps mpc;
@ -350,6 +401,7 @@ struct dc_config {
uint8_t vblank_alignment_max_frame_time_diff;
bool is_asymmetric_memory;
bool is_single_rank_dimm;
bool is_vmin_only_asic;
bool use_pipe_ctx_sync_logic;
bool ignore_dpref_ss;
bool enable_mipi_converter_optimization;
@ -365,6 +417,7 @@ enum visual_confirm {
VISUAL_CONFIRM_SWAPCHAIN = 6,
VISUAL_CONFIRM_FAMS = 7,
VISUAL_CONFIRM_SWIZZLE = 9,
VISUAL_CONFIRM_SUBVP = 14,
};
enum dc_psr_power_opts {
@ -386,9 +439,31 @@ enum dcc_option {
DCC_HALF_REQ_DISALBE = 2,
};
/**
* enum pipe_split_policy - Pipe split strategy supported by DCN
*
* This enum is used to define the pipe split policy supported by DCN. By
* default, DC favors MPC_SPLIT_DYNAMIC.
*/
enum pipe_split_policy {
/**
* @MPC_SPLIT_DYNAMIC: DC will automatically decide how to split the
* pipe in order to bring the best trade-off between performance and
* power consumption. This is the recommended option.
*/
MPC_SPLIT_DYNAMIC = 0,
/**
* @MPC_SPLIT_DYNAMIC: Avoid pipe split, which means that DC will not
* try any sort of split optimization.
*/
MPC_SPLIT_AVOID = 1,
/**
* @MPC_SPLIT_DYNAMIC: With this option, DC will only try to optimize
* the pipe utilization when using a single display; if the user
* connects to a second display, DC will avoid pipe split.
*/
MPC_SPLIT_AVOID_MULT_DISP = 2,
};
@ -623,6 +698,14 @@ struct dc_state;
struct resource_pool;
struct dce_hwseq;
/**
* struct dc_debug_options - DC debug struct
*
* This struct provides a simple mechanism for developers to change some
* configurations, enable/disable features, and activate extra debug options.
* This can be very handy to narrow down whether some specific feature is
* causing an issue or not.
*/
struct dc_debug_options {
bool native422_support;
bool disable_dsc;
@ -642,6 +725,11 @@ struct dc_debug_options {
bool disable_stutter;
bool use_max_lb;
enum dcc_option disable_dcc;
/**
* @pipe_split_policy: Define which pipe split policy is used by the
* display core.
*/
enum pipe_split_policy pipe_split_policy;
bool force_single_disp_pipe_split;
bool voltage_align_fclk;
@ -715,8 +803,6 @@ struct dc_debug_options {
bool validate_dml_output;
bool enable_dmcub_surface_flip;
bool usbc_combo_phy_reset_wa;
bool disable_dsc_edp;
unsigned int force_dsc_edp_policy;
bool enable_dram_clock_change_one_display_vactive;
/* TODO - remove once tested */
bool legacy_dp2_lt;
@ -740,7 +826,6 @@ struct dc_debug_options {
int crb_alloc_policy_min_disp_count;
bool disable_z10;
bool enable_z9_disable_interface;
bool enable_sw_cntl_psr;
union dpia_debug_options dpia_debug;
bool disable_fixed_vs_aux_timeout_wa;
bool force_disable_subvp;
@ -759,6 +844,7 @@ struct dc_debug_options {
bool exit_idle_opt_for_cursor_updates;
bool enable_single_display_2to1_odm_policy;
bool enable_dp_dig_pixel_rate_div_policy;
enum lttpr_mode lttpr_mode_override;
};
struct gpu_info_soc_bounding_box_v1_0;
@ -814,6 +900,17 @@ struct dc {
uint32_t *dcn_reg_offsets;
uint32_t *nbio_reg_offsets;
/* Scratch memory */
struct {
struct {
/*
* For matching clock_limits table in driver with table
* from PMFW.
*/
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
} update_bw_bounding_box;
} scratch;
};
enum frame_buffer_mode {
@ -1085,6 +1182,7 @@ struct dc_plane_state {
/* private to dc_surface.c */
enum dc_irq_source irq_source;
struct kref refcount;
struct tg_color visual_confirm_color;
};
struct dc_plane_info {

View File

@ -323,11 +323,13 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
int i = 0;
int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
uint8_t visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
uint8_t visual_confirm_enabled;
if (dc == NULL)
return false;
visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
// Format command.
cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL;
@ -387,6 +389,37 @@ void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub)
}
}
void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
union dmub_rb_cmd cmd = { 0 };
enum dmub_status status;
unsigned int panel_inst = 0;
dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst);
memset(&cmd, 0, sizeof(cmd));
// Prepare fw command
cmd.visual_confirm_color.header.type = DMUB_CMD__GET_VISUAL_CONFIRM_COLOR;
cmd.visual_confirm_color.header.sub_type = 0;
cmd.visual_confirm_color.header.ret_status = 1;
cmd.visual_confirm_color.header.payload_bytes = sizeof(struct dmub_cmd_visual_confirm_color_data);
cmd.visual_confirm_color.visual_confirm_color_data.visual_confirm_color.panel_inst = panel_inst;
// Send command to fw
status = dmub_srv_cmd_with_reply_data(dc->ctx->dmub_srv->dmub, &cmd);
ASSERT(status == DMUB_STATUS_OK);
// If command was processed, copy feature caps to dmub srv
if (status == DMUB_STATUS_OK &&
cmd.visual_confirm_color.header.ret_status == 0) {
memcpy(&dc->ctx->dmub_srv->dmub->visual_confirm_color,
&cmd.visual_confirm_color.visual_confirm_color_data,
sizeof(struct dmub_visual_confirm_color));
}
}
#ifdef CONFIG_DRM_AMD_DC_DCN
/**
* ***********************************************************************************************
@ -601,7 +634,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
&cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index];
struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing;
uint32_t out_num, out_den;
uint32_t out_num_stream, out_den_stream, out_num_plane, out_den_plane, out_num, out_den;
pipe_data->mode = SUBVP;
pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz;
@ -618,11 +651,16 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
/* Calculate the scaling factor from the src and dst height.
* e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2.
* Reduce the fraction 1080/2160 = 1/2 for the "scaling factor"
*
* Make sure to combine stream and plane scaling together.
*/
reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height, &out_num, &out_den);
// TODO: Uncomment below lines once DMCUB include headers are promoted
//pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num;
//pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den;
reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height,
&out_num_stream, &out_den_stream);
reduce_fraction(subvp_pipe->plane_state->src_rect.height, subvp_pipe->plane_state->dst_rect.height,
&out_num_plane, &out_den_plane);
reduce_fraction(out_num_stream * out_num_plane, out_den_stream * out_den_plane, &out_num, &out_den);
pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num;
pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den;
// Prefetch lines is equal to VACTIVE + BP + VSYNC
pipe_data->pipe_config.subvp_data.prefetch_lines =

Some files were not shown because too many files have changed in this diff Show More