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
8
Documentation/gpu/amdgpu/apu-asic-info-table.csv
Normal 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
|
|
24
Documentation/gpu/amdgpu/dgpu-asic-info-table.csv
Normal 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
|
|
@ -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
|
||||
|
@ -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
|
||||
-----------
|
||||
|
||||
|
1370
Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
Normal file
After Width: | Height: | Size: 56 KiB |
1529
Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg
Normal file
After Width: | Height: | Size: 63 KiB |
@ -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.
|
||||
|
@ -28,4 +28,5 @@ table of content:
|
||||
display-manager.rst
|
||||
dc-debug.rst
|
||||
dcn-overview.rst
|
||||
mpo-overview.rst
|
||||
dc-glossary.rst
|
||||
|
435
Documentation/gpu/amdgpu/display/mpo-cursor.svg
Normal 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 |
242
Documentation/gpu/amdgpu/display/mpo-overview.rst
Normal 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.
|
@ -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 |
171
Documentation/gpu/amdgpu/display/multi-display-hdcp-mpo.svg
Normal 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 |
958
Documentation/gpu/amdgpu/display/pipeline_4k_no_split.svg
Normal 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 |
1062
Documentation/gpu/amdgpu/display/pipeline_4k_split.svg
Normal file
After Width: | Height: | Size: 44 KiB |
@ -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 |
266
Documentation/gpu/amdgpu/display/single-display-mpo.svg
Normal 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 |
@ -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
|
||||
============================
|
||||
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
----------------------------
|
||||
|
||||
|
@ -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 += \
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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)))
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
511
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.c
Normal 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,
|
||||
};
|
29
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.h
Normal 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
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
144
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.c
Normal 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 = ®s[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));
|
||||
}
|
29
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.h
Normal 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
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
140
drivers/gpu/drm/amd/amdgpu/mmsch_v4_0.h
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
303
drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
Normal 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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 log–gamma 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 {
|
||||
|
@ -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 =
|
||||
|