amd-drm-next-6.20-2026-01-09:

amdgpu:
 - GPUVM updates
 - Initial support for larger GPU address spaces
 - Initial SMUIO 15.x support
 - Documentation updates
 - Initial PSP 15.x support
 - Initial IH 7.1 support
 - Initial IH 6.1.1 support
 - SMU 13.0.12 updates
 - RAS updates
 - Initial MMHUB 3.4 support
 - Initial MMHUB 4.2 support
 - Initial GC 12.1 support
 - Initial GC 11.5.4 support
 - HDMI fixes
 - Panel replay improvements
 - DML updates
 - DC FP fixes
 - Initial SDMA 6.1.4 support
 - Initial SDMA 7.1 support
 - Userq updates
 - DC HPD refactor
 - SwSMU cleanups and refactoring
 - TTM memory ops parallelization
 - DCN 3.5 fixes
 - DP audio fixes
 - Clang fixes
 - Misc spelling fixes and cleanups
 - Initial SDMA 7.11.4 support
 - Convert legacy DRM logging helpers to new drm logging helpers
 - Initial JPEG 5.3 support
 - Add support for changing UMA size via the driver
 - DC analog fixes
 - GC 9 gfx queue reset support
 - Initial SMU 15.x support
 
 amdkfd:
 - Reserved SDMA rework
 - Refactor SPM
 - Initial GC 12.1 support
 - Initial GC 11.5.4 support
 - Initial SDMA 7.1 support
 - Initial SDMA 6.1.4 support
 - Increase the kfd process hash table
 - Per context support
 - Topology fixes
 
 radeon:
 - Convert legacy DRM logging helpers to new drm logging helpers
 - Use devm for i2c adapters
 - Variable sized array fix
 - Misc cleanups
 
 UAPI:
 - KFD context support.  Proposed userspace:
   https://github.com/ROCm/rocm-systems/pull/1705
   https://github.com/ROCm/rocm-systems/pull/1701
 - Add userq metadata queries for more queue types.  Proposed userspace:
   https://gitlab.freedesktop.org/yogeshmohan/mesa/-/commits/userq_query
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaWEiMQAKCRC93/aFa7yZ
 2LXpAP4spIs5nStw1Q7SKhFAU1YSbNBIzrPJVjeQcudAebrgcAD/V9dEdeTPjXSj
 VmtJ9w0WO0vi+VGKPTWsukMB0kyVnwE=
 =HgYC
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-next-6.20-2026-01-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.20-2026-01-09:

amdgpu:
- GPUVM updates
- Initial support for larger GPU address spaces
- Initial SMUIO 15.x support
- Documentation updates
- Initial PSP 15.x support
- Initial IH 7.1 support
- Initial IH 6.1.1 support
- SMU 13.0.12 updates
- RAS updates
- Initial MMHUB 3.4 support
- Initial MMHUB 4.2 support
- Initial GC 12.1 support
- Initial GC 11.5.4 support
- HDMI fixes
- Panel replay improvements
- DML updates
- DC FP fixes
- Initial SDMA 6.1.4 support
- Initial SDMA 7.1 support
- Userq updates
- DC HPD refactor
- SwSMU cleanups and refactoring
- TTM memory ops parallelization
- DCN 3.5 fixes
- DP audio fixes
- Clang fixes
- Misc spelling fixes and cleanups
- Initial SDMA 7.11.4 support
- Convert legacy DRM logging helpers to new drm logging helpers
- Initial JPEG 5.3 support
- Add support for changing UMA size via the driver
- DC analog fixes
- GC 9 gfx queue reset support
- Initial SMU 15.x support

amdkfd:
- Reserved SDMA rework
- Refactor SPM
- Initial GC 12.1 support
- Initial GC 11.5.4 support
- Initial SDMA 7.1 support
- Initial SDMA 6.1.4 support
- Increase the kfd process hash table
- Per context support
- Topology fixes

radeon:
- Convert legacy DRM logging helpers to new drm logging helpers
- Use devm for i2c adapters
- Variable sized array fix
- Misc cleanups

UAPI:
- KFD context support.  Proposed userspace:
  https://github.com/ROCm/rocm-systems/pull/1705
  https://github.com/ROCm/rocm-systems/pull/1701
- Add userq metadata queries for more queue types.  Proposed userspace:
  https://gitlab.freedesktop.org/yogeshmohan/mesa/-/commits/userq_query

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260109154713.3242957-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2026-01-15 14:49:33 +10:00
commit 83dc0ba275
417 changed files with 120198 additions and 6972 deletions

View file

@ -0,0 +1,687 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="237.4014mm"
height="160.98259mm"
viewBox="0 0 237.4014 160.98259"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="amd_overview_block.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="2"
inkscape:cx="576.75"
inkscape:cy="313.25"
inkscape:window-width="3840"
inkscape:window-height="2083"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="ArrowWideHeavy"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, heavy arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path3" />
</marker>
<marker
style="overflow:visible"
id="ArrowWideRounded"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, rounded arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:round"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path2" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(9.9255824,-64.69615)">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999747"
id="rect5"
width="239.13895"
height="162.38739"
x="-10.311751"
y="63.871342" />
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0.79375"
id="rect1"
width="174.55814"
height="140.23256"
x="22.263056"
y="65.093025" />
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect8-5"
width="3.8659263"
height="4.2845292"
x="38.69939"
y="75.819946" />
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect9"
width="3.8659263"
height="4.2845292"
x="176.7458"
y="75.68573" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.9389px;font-family:'Linux Libertine O';-inkscape-font-specification:'Linux Libertine O';text-align:start;letter-spacing:4.91331px;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#00d400;stroke:#00d400;stroke-width:1;stroke-dasharray:none"
x="45.418606"
y="216.62791"
id="text12"><tspan
sodipodi:role="line"
id="tspan12"
style="stroke-width:1"
x="45.418606"
y="216.62791" /></text>
<g
id="g34">
<rect
style="fill:#ffffff;stroke:#008033;stroke-width:1;stroke-dasharray:none"
id="rect7"
width="19.539951"
height="6.9818101"
x="22.811832"
y="210.3201" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#008033;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="52.663685"
y="216.07796"
id="text68"><tspan
sodipodi:role="line"
x="52.663685"
y="216.07796"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#008033;stroke-width:0.0690111"
id="tspan68">UMC</tspan></text>
</g>
<g
id="g29"
transform="translate(-0.52916667)">
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect8"
width="3.8659263"
height="4.2845292"
x="22.782616"
y="220.36148" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="48.966854"
y="224.15474"
id="text13"><tspan
sodipodi:role="line"
x="48.966854"
y="224.15474"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#00ff00;stroke-width:0.0690111"
id="tspan13">Memory hub</tspan></text>
</g>
<g
id="g12"
transform="translate(-1.8520837,2.3812496)">
<g
id="g13">
<rect
style="fill:#ffffff;stroke:#ffd42a;stroke-width:1;stroke-dasharray:none"
id="rect15"
width="28.674419"
height="11.302325"
x="114.87544"
y="169.54433"
ry="2.6458333" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="129.06978"
y="177.46243"
id="text15"><tspan
sodipodi:role="line"
x="129.06978"
y="177.46243"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan15">PSP</tspan></text>
</g>
</g>
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 73.88372,201.92338 h 43.74419 V 184.5631"
id="path16"
sodipodi:nodetypes="ccc" />
<rect
style="fill:#ffffff;stroke:#00ccff;stroke-width:1;stroke-dasharray:none"
id="rect16"
width="40.220226"
height="11.1272"
x="150.82011"
y="193.07373" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="170.78101"
y="200.90428"
id="text16"><tspan
sodipodi:role="line"
x="170.78101"
y="200.90428"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan16">PCIe (NBIO)</tspan></text>
<g
id="g10"
transform="translate(-8.807217,1.0583333)">
<rect
style="fill:#ffffff;stroke:#ff6600;stroke-width:1;stroke-dasharray:none"
id="rect10"
width="50.551014"
height="10.992874"
x="65.641136"
y="122.93423" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="91.040474"
y="130.69762"
id="text10"><tspan
sodipodi:role="line"
x="91.040474"
y="130.69762"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan10">SMU</tspan></text>
</g>
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect14"
width="3.8659263"
height="4.2845292"
x="171.61417"
y="125.16281" />
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect18"
width="3.8659263"
height="4.2845292"
x="67.340591"
y="185.6201" />
<g
id="g25"
transform="translate(165.76146,89.164578)">
<g
id="g17"
transform="translate(-127.72192,-84.269792)">
<rect
style="fill:#ffffff;stroke:#ff00ff;stroke-width:1;stroke-dasharray:none"
id="rect17"
width="50.551014"
height="10.992874"
x="83.42868"
y="140.39673" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="108.55814"
y="148.16011"
id="text17"><tspan
sodipodi:role="line"
x="108.55814"
y="148.16011"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan17">SDMA</tspan></text>
</g>
<g
id="g24">
<rect
style="fill:#00d400;stroke:#00d400;stroke-width:0.348444;stroke-dasharray:none"
id="rect21"
width="3.8659263"
height="4.2845292"
x="9.0765572"
y="57.429478" />
</g>
</g>
<path
style="fill:none;stroke:#ff6600;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0;marker-end:url(#ArrowWideRounded)"
d="M 56.046208,126.07948 H 51.151416 V 110.60136"
id="path21"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#ff6600;stroke-width:1;stroke-dasharray:1,1;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 107.63996,129.38677 h 31.91723"
id="path22" />
<g
id="g26"
transform="translate(103.05521,-16.801041)">
<path
style="fill:none;stroke:#ff6600;stroke-width:0.684499;stroke-dasharray:0.684499, 0.684499;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="M 14.374335,237.26538 H 29.87027"
id="path23" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="41.690811"
y="239.50058"
id="text23"><tspan
sodipodi:role="line"
x="41.690811"
y="239.50058"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.0690111"
id="tspan23">Reset</tspan></text>
</g>
<path
style="fill:none;stroke:#ff6600;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0;marker-end:url(#ArrowWideRounded)"
d="m 56.046208,133.69217 h -4.894792 v 58.07604"
id="path24"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#ff6600;stroke-width:1;stroke-dasharray:1,1;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 95.977781,134.7651 v 15.92063 l 23.944789,0.007"
id="path25"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 116.34935,212.1162 h 16.22753"
id="path26"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="159.95955"
y="214.49745"
id="text26"><tspan
sodipodi:role="line"
x="159.95955"
y="214.49745"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffd42a;stroke-width:0.0690111"
id="tspan26">PSP Interaction</tspan></text>
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 142.93997,177.44941 12.78794,1e-5 0,-20.13841"
id="path27"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 154.31705,177.44941 24.03273,1e-5 v -46.34286 h -6.87917"
id="path28"
sodipodi:nodetypes="cccc" />
<rect
style="fill:#008033;stroke:#008033;stroke-width:1.12152;stroke-dasharray:none"
id="rect31"
width="28.449656"
height="23.148542"
x="-9.3648224"
y="152.25124" />
<rect
style="fill:#008033;stroke:#008033;stroke-width:1.12152;stroke-dasharray:none"
id="rect32"
width="28.449656"
height="23.148542"
x="-9.3648224"
y="71.817902" />
<rect
style="fill:#008033;stroke:#008033;stroke-width:1.12152;stroke-dasharray:none"
id="rect33"
width="28.449656"
height="23.148542"
x="198.46539"
y="152.25124" />
<rect
style="fill:#008033;stroke:#008033;stroke-width:1.12152;stroke-dasharray:none"
id="rect34"
width="28.449656"
height="23.148542"
x="198.46539"
y="71.817902" />
<path
style="fill:none;stroke:#00d455;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0"
d="m 69.17932,192.92241 0,-26.32924 H 34.403946"
id="path35"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#00d455;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0"
d="m 69.167488,192.92241 0,-26.32924 H 184.79581"
id="path36"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#00d455;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0"
d="m 33.58103,118.30671 147.61609,0 v 30.03021"
id="path37"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#00d455;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0"
d="m 169.94852,126.77338 15.61123,0"
id="path38"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#00d455;stroke-width:1;stroke-dasharray:1, 1;stroke-dashoffset:0"
d="m 172.24035,148.99838 13.3194,0"
id="path39"
sodipodi:nodetypes="cc" />
<g
id="g40"
transform="translate(0,1.8520834)">
<circle
style="fill:#ff8080;stroke:#ff2a2a;stroke-width:0.7;stroke-dasharray:none;stroke-dashoffset:0"
id="path40"
cx="7.2723336"
cy="194.07741"
r="10.186459" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="7.1728497"
y="195.6649"
id="text40"><tspan
sodipodi:role="line"
x="7.1728492"
y="195.6649"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan40">Firmware</tspan></text>
</g>
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 34.063928,177.71401 78.801482,0.26458"
id="path41"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="M 8.1347613,184.72547 27.537285,177.97859"
id="path42"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="4.5742564"
y="84.897125"
id="text42"><tspan
sodipodi:role="line"
x="4.5742559"
y="84.897125"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan42">Memory</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="4.5742564"
y="165.33046"
id="text43"><tspan
sodipodi:role="line"
x="4.5742559"
y="165.33046"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan43">Memory</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="212.40446"
y="165.33046"
id="text44"><tspan
sodipodi:role="line"
x="212.40446"
y="165.33046"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan44">Memory</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="212.40446"
y="84.897125"
id="text45"><tspan
sodipodi:role="line"
x="212.40446"
y="84.897125"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan45">Memory</tspan></text>
<path
style="fill:none;stroke:#00d455;stroke-width:0.882664;stroke-dasharray:0.882664, 0.882664;stroke-dashoffset:0"
d="m 174.12438,77.957755 h 10.9062"
id="path45"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#00d455;stroke-width:0.960226;stroke-dasharray:0.960226, 0.960226;stroke-dashoffset:0"
d="M 34.639355,77.957755 H 47.546469"
id="path46"
sodipodi:nodetypes="cc" />
<rect
style="fill:#ffffff;stroke:#008033;stroke-width:1;stroke-dasharray:none"
id="rect2"
width="5.0221987"
height="111.47456"
x="28.691442"
y="72.435623" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#008033;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="-127.03961"
y="32.94923"
id="text34"
transform="rotate(-90)"><tspan
sodipodi:role="line"
x="-127.03961"
y="32.94923"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#008033;stroke-width:0.0690111"
id="tspan34">UMC</tspan></text>
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 179.15481,177.45676 h 5.90877"
id="path1"
sodipodi:nodetypes="cc" />
<rect
style="fill:#ffffff;stroke:#008033;stroke-width:1;stroke-dasharray:none"
id="rect3"
width="5.0221987"
height="111.47456"
x="185.4259"
y="72.435623" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#008033;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="-127.03961"
y="189.71486"
id="text35"
transform="rotate(-90)"><tspan
sodipodi:role="line"
x="-127.03961"
y="189.71486"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#008033;stroke-width:0.0690111"
id="tspan35">UMC</tspan></text>
<path
style="fill:none;stroke:#ffd42a;stroke-width:1;stroke-dasharray:8, 1;stroke-dashoffset:0"
d="m 154.31705,177.44941 24.03273,1e-5 0,-85.765777 h -4.36563"
id="path4"
sodipodi:nodetypes="cccc" />
<g
id="g5"
transform="translate(0,5.8208336)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="110.18288"
y="73.872185"
id="text14-7"><tspan
sodipodi:role="line"
x="110.18288"
y="73.872185"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan14-7">Graphics &amp; Compute (GC)</tspan></text>
<g
id="g4"
transform="translate(10.583333)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="58.022533"
y="83.518799"
id="text14-7-5"><tspan
sodipodi:role="line"
x="58.022533"
y="83.518799"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan14-7-6">Shader</tspan><tspan
sodipodi:role="line"
x="58.022533"
y="90.574348"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan20">Engine(SE)</tspan><tspan
sodipodi:role="line"
x="58.022533"
y="97.629898"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan21">#1</tspan></text>
<rect
style="fill:none;stroke:#aa0000;stroke-width:1.01356;stroke-dasharray:none;stroke-dashoffset:0"
id="rect20"
width="31.954243"
height="22.038303"
x="42.18652"
y="77.410309" />
</g>
<g
id="g3"
transform="translate(14.287499,-0.66146851)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="97.020706"
y="91.105995"
id="text24"><tspan
sodipodi:role="line"
x="97.020706"
y="91.105995"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan24">SE #2</tspan></text>
<rect
style="fill:none;stroke:#aa0000;stroke-width:1.01356;stroke-dasharray:none;stroke-dashoffset:0"
id="rect24"
width="31.954243"
height="22.038303"
x="81.080269"
y="78.071777" />
</g>
<g
id="g2"
transform="translate(-3.96875)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="158.03574"
y="90.444527"
id="text30"><tspan
sodipodi:role="line"
x="158.03574"
y="90.444527"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan30">SE #N</tspan></text>
<rect
style="fill:none;stroke:#aa0000;stroke-width:1.01356;stroke-dasharray:none;stroke-dashoffset:0"
id="rect30"
width="31.954243"
height="22.038303"
x="141.93443"
y="77.410309" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="132.011"
y="88.873962"
id="text4"><tspan
sodipodi:role="line"
x="132.011"
y="88.873962"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan4">...</tspan></text>
<rect
style="fill:none;stroke:#ff8080;stroke-width:1;stroke-dasharray:none"
id="rect4"
width="126.7475"
height="35.863121"
x="46.912045"
y="68.129692" />
</g>
<g
id="g11"
transform="translate(-5.0270833,-8.8635417)">
<rect
style="fill:#ffffff;stroke:#5f5fd3;stroke-width:1;stroke-dasharray:none"
id="rect19"
width="28.674419"
height="11.302325"
x="146.1279"
y="132.70711" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="160.75085"
y="140.62521"
id="text19"><tspan
sodipodi:role="line"
x="160.75085"
y="140.62521"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan19">VCN</tspan></text>
</g>
<g
id="g6">
<rect
style="fill:#ffffff;stroke:#0000ff;stroke-width:1;stroke-dasharray:none"
id="rect13"
width="28.674419"
height="11.302325"
x="43.988369"
y="192.98618" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0690111"
x="58.325581"
y="200.90428"
id="text14"><tspan
sodipodi:role="line"
x="58.325581"
y="200.90428"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.0690111"
id="tspan14">DCN</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -30,6 +30,15 @@ we have a dedicated glossary for Display Core at
CP
Command Processor
CPC
Command Processor Compute
CPF
Command Processor Fetch
CPG
Command Processor Graphics
CPLIB
Content Protection Library
@ -78,6 +87,9 @@ we have a dedicated glossary for Display Core at
GMC
Graphic Memory Controller
GPR
General Purpose Register
GPUVM
GPU Virtual Memory. This is the GPU's MMU. The GPU supports multiple
virtual address spaces that can be in flight at any given time. These
@ -92,9 +104,15 @@ we have a dedicated glossary for Display Core at
table for use by the kernel driver or into per process GPUVM page tables
for application usage.
GWS
Global Wave Sync
IH
Interrupt Handler
IV
Interrupt Vector
HQD
Hardware Queue Descriptor
@ -143,15 +161,24 @@ we have a dedicated glossary for Display Core at
PA
Primitive Assembler / Physical Address
PDE
Page Directory Entry
PFP
Pre-Fetch Parser (Graphics)
PPLib
PowerPlay Library - PowerPlay is the power management component.
PRT
Partially Resident Texture (also known as sparse residency)
PSP
Platform Security Processor
PTE
Page Table Entry
RB
Render Backends. Some people called it ROPs.
@ -206,12 +233,33 @@ we have a dedicated glossary for Display Core at
TC
Texture Cache
TCP (AMDGPU)
Texture Cache per Pipe. Even though the name "Texture" is part of this
acronym, the TCP represents the path to memory shaders; i.e., it is not
related to texture. The name is a leftover from older designs where shader
stages had different cache designs; it refers to the L1 cache in older
architectures.
TMR
Trusted Memory Region
TMZ
Trusted Memory Zone
TOC
Table of Contents
UMC
Unified Memory Controller
UMSCH
User Mode Scheduler
UTC (AMDGPU)
Unified Translation Cache. UTC is equivalent to TLB. You might see a
variation of this acronym with L at the end, i.e., UTCL followed by a
number; L means the cache level (e.g., UTCL1 and UTCL2).
UVD
Unified Video Decoder

View file

@ -221,9 +221,6 @@ consider asking on the amd-gfx mailing list and update this page.
TMDS
Transition-Minimized Differential Signaling
TMZ
Trusted Memory Zone
TTU
Time to Underflow

View file

@ -77,6 +77,37 @@ VCN (Video Core Next)
decode. It's exposed to userspace for user mode drivers (VA-API,
OpenMAX, etc.)
It is important to note that these blocks can interact with each other. The
picture below illustrates some of the components and their interconnection:
.. kernel-figure:: amd_overview_block.svg
In the diagram, memory-related blocks are shown in green. Notice that specific
IPs have a green square that represents a small hardware block named 'hub',
which is responsible for interfacing with memory. All memory hubs are connected
in the UMCs, which in turn are connected to memory blocks. As a note,
pre-vega devices have a dedicated block for the Graphic Memory Controller
(GMC), which was replaced by UMC and hubs in new architectures. In the driver
code, you can identify this component by looking for the suffix hub, for
example: gfxhub, dchub, mmhub, vmhub, etc. Keep in mind that the component's
interaction with the memory block may vary across architectures. For example,
on Navi and newer, GC and SDMA are both attached to GCHUB; on pre-Navi, SDMA
goes through MMHUB; VCN, JPEG, and VPE go through MMHUB; DCN goes through
DCHUB.
There is some protection for certain memory elements, and the PSP plays an
essential role in this area. When a specific firmware is loaded into memory,
the PSP takes steps to ensure it has a valid signature. It also stores firmware
images in a protected memory area named Trusted Memory Area (TMR), so the OS or
driver can't corrupt them at runtime. Another use of PSP is to support Trusted
Applications (TA), which are basically small applications that run on the
trusted processor and handles a trusted operation (e.g., HDCP). PSP is also
used for encrypted memory for content protection via Trusted Memory Zone (TMZ).
Another critical IP is the SMU. It handles reset distribution, as well as
clock, thermal, and power management for all IPs on the SoC. SMU also helps to
balance performance and power consumption.
.. _pipes-and-queues-description:
GFX, Compute, and SDMA Overall Behavior

View file

@ -128,3 +128,29 @@ smartshift_bias
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: smartshift_bias
UMA Carveout
============
Some versions of Atom ROM expose available options for the VRAM carveout sizes,
and allow changes to the carveout size via the ATCS function code 0xA on supported
BIOS implementations.
For those platforms, users can use the following files under uma/ to set the
carveout size, in a way similar to what Windows users can do in the "Tuning"
tab in AMD Adrenalin.
Note that for BIOS implementations that don't support this, these files will not
be created at all.
uma/carveout_options
--------------------
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
:doc: uma/carveout_options
uma/carveout
--------------------
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
:doc: uma/carveout

View file

@ -0,0 +1,654 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="67.794067mm"
height="88.643349mm"
viewBox="0 0 67.794066 88.643348"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="enforce_isolation.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="3.5754724"
inkscape:cx="200.95247"
inkscape:cy="182.77305"
inkscape:window-width="3840"
inkscape:window-height="2083"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="ArrowWideHeavy"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, heavy arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path3" />
</marker>
<marker
style="overflow:visible"
id="Dot"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Dot"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 5,0 C 5,2.76 2.76,5 0,5 -2.76,5 -5,2.76 -5,0 c 0,-2.76 2.3,-5 5,-5 2.76,0 5,2.24 5,5 z"
sodipodi:nodetypes="sssss"
id="path98" />
</marker>
<marker
style="overflow:visible"
id="marker99"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Dot"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 5,0 C 5,2.76 2.76,5 0,5 -2.76,5 -5,2.76 -5,0 c 0,-2.76 2.3,-5 5,-5 2.76,0 5,2.24 5,5 z"
sodipodi:nodetypes="sssss"
id="path99" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(71.49059,-1.1271925)">
<g
id="g15"
transform="matrix(0.42247861,0,0,0.42247861,-70.575576,-25.242317)">
<path
id="path33"
style="fill:none;stroke:#000000;stroke-width:0.721067;stroke-dasharray:none"
d="M 30.278993,176.45537 A 22.905334,22.905334 0 0 0 7.3737955,199.36057 22.905334,22.905334 0 0 0 30.278993,222.26603 22.905334,22.905334 0 0 0 53.18445,199.36057 22.905334,22.905334 0 0 0 30.278993,176.45537 Z m 0,7.13274 a 15.772359,15.772359 0 0 1 15.77246,15.77246 15.772359,15.772359 0 0 1 -15.77246,15.77246 15.772359,15.772359 0 0 1 -15.772206,-15.77246 15.772359,15.772359 0 0 1 15.772206,-15.77246 z" />
<g
id="g14">
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 46.31405,200.72093 h 6.430134"
id="path34"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 7.6848605,200.72093 H 14.114993"
id="path35"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 30.103415,176.7326 v 6.43014"
id="path36"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 30.103415,215.50586 V 221.936"
id="path37"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,214.1052 3.21507,5.56866"
id="path38"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,184.66805 3.21507,-5.56866"
id="path39"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,184.66805 -3.21507,-5.56866"
id="path40"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,214.05288 -3.21507,5.56866"
id="path41"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,208.65101 4.546794,4.5468"
id="path42"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,189.96525 4.546794,-4.5468"
id="path43"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 17.202394,189.96525 12.6556,185.41845"
id="path44-1"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 16.940766,208.65101 -4.546794,4.5468"
id="path45-8"
sodipodi:nodetypes="cc" />
</g>
</g>
<rect
style="fill:#afe9c6;stroke:#16502d;stroke-width:0.257104;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
id="rect80"
width="25.076588"
height="10.493422"
x="-71.362038"
y="79.148567"
ry="1.4529352" />
<rect
style="fill:#80e5ff;stroke:#00aad4;stroke-width:0.257104;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
id="rect81"
width="32.714355"
height="10.436013"
x="-40.481403"
y="79.177269"
ry="1.4449863" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.53042px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-59.013123"
y="86.726654"
id="text14-7"><tspan
sodipodi:role="line"
x="-59.013123"
y="86.726654"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.53042px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan14-7">GFX</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.53042px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-24.387218"
y="85.975647"
id="text95"><tspan
sodipodi:role="line"
x="-24.387218"
y="85.975647"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.53042px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan95">Compute</tspan></text>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -58.079264,78.410023 V 69.962845"
id="path127"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.90242px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-61.752651"
y="3.1995225"
id="text112"><tspan
sodipodi:role="line"
x="-61.752651"
y="3.1995225"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.90242px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan112">Processes</tspan></text>
<rect
style="fill:none;stroke:#000000;stroke-width:0.247306;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:1.48383, 1.48383;stroke-dashoffset:0"
id="rect113"
width="64.703476"
height="19.562067"
x="-68.52655"
y="4.468956"
ry="1.6976216" />
<g
id="g84"
transform="matrix(0.25710378,0,0,0.25710378,0.68647434,8.7899633)">
<g
id="g83">
<circle
style="fill:#ffffff;stroke:#ff00ff;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle137"
cx="-225.65012"
cy="20.747513"
r="30.822298" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-225.65012"
y="26.8181"
id="text113"><tspan
sodipodi:role="line"
x="-225.65012"
y="26.8181"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.400612"
id="tspan113">A</tspan></text>
</g>
<g
id="g85"
transform="matrix(0.25710378,0,0,0.25710378,20.618429,8.7899633)">
<circle
style="fill:#ffffff;stroke:#ff9955;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle112"
cx="-207.94376"
cy="20.747513"
r="30.822298" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-208.25702"
y="26.792702"
id="text114"><tspan
sodipodi:role="line"
x="-208.25702"
y="26.792702"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.400612"
id="tspan114">B</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-56.126556"
y="51.72607"
id="text6"><tspan
sodipodi:role="line"
x="-56.126556"
y="51.72607"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan6">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.26752px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-57.861526"
y="58.416431"
id="text136"><tspan
sodipodi:role="line"
x="-57.861526"
y="58.416431"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan136">Ring</tspan><tspan
sodipodi:role="line"
x="-57.861526"
y="61.250832"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan137">Buffer</tspan></text>
<g
id="g80"
transform="matrix(0.42247861,0,0,0.42247861,-37.21188,-25.242317)">
<path
id="path67"
style="fill:none;stroke:#000000;stroke-width:0.721067;stroke-dasharray:none"
d="M 30.278993,176.45537 A 22.905334,22.905334 0 0 0 7.3737955,199.36057 22.905334,22.905334 0 0 0 30.278993,222.26603 22.905334,22.905334 0 0 0 53.18445,199.36057 22.905334,22.905334 0 0 0 30.278993,176.45537 Z m 0,7.13274 a 15.772359,15.772359 0 0 1 15.77246,15.77246 15.772359,15.772359 0 0 1 -15.77246,15.77246 15.772359,15.772359 0 0 1 -15.772206,-15.77246 15.772359,15.772359 0 0 1 15.772206,-15.77246 z" />
<g
id="g79">
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 46.31405,200.72093 h 6.430134"
id="path68"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 7.6848605,200.72093 H 14.114993"
id="path69"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 30.103415,176.7326 v 6.43014"
id="path70"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 30.103415,215.50586 V 221.936"
id="path71"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,214.1052 3.21507,5.56866"
id="path72"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,184.66805 3.21507,-5.56866"
id="path73"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,184.66805 -3.21507,-5.56866"
id="path74"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,214.05288 -3.21507,5.56866"
id="path75"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,208.65101 4.546794,4.5468"
id="path76"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,189.96525 4.546794,-4.5468"
id="path77"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 17.202394,189.96525 12.6556,185.41845"
id="path78"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 16.940766,208.65101 -4.546794,4.5468"
id="path79"
sodipodi:nodetypes="cc" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.26752px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-24.497828"
y="58.416431"
id="text81"><tspan
sodipodi:role="line"
x="-24.497828"
y="58.416431"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan80">Ring</tspan><tspan
sodipodi:role="line"
x="-24.497828"
y="61.250832"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan81">Buffer</tspan></text>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -24.338879,78.410023 V 69.962845"
id="path81"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-52.574932"
y="53.340443"
id="text82"><tspan
sodipodi:role="line"
x="-52.574932"
y="53.340443"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan82">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-50.045757"
y="57.376377"
id="text83"><tspan
sodipodi:role="line"
x="-50.045757"
y="57.376377"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83">A</tspan></text>
<g
id="g1"
transform="translate(0,-16.057901)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-12.593401"
y="57.349865"
id="text83-59"><tspan
sodipodi:role="line"
x="-12.593401"
y="57.349865"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-7">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-9.8666544"
y="57.349865"
id="text83-59-3"><tspan
sodipodi:role="line"
x="-9.8666544"
y="57.349865"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-7-6">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-24.724035"
y="57.3466"
id="text83-5-9"><tspan
sodipodi:role="line"
x="-24.724035"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-2">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-22.315107"
y="57.3466"
id="text83-5-9-9"><tspan
sodipodi:role="line"
x="-22.315107"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-2-5">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-19.937738"
y="57.3466"
id="text83-5-9-9-7"><tspan
sodipodi:role="line"
x="-19.937738"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2">B</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-17.56146"
y="57.3466"
id="text83-5-9-9-7-0"><tspan
sodipodi:role="line"
x="-17.56146"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2-6">B</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-15.185183"
y="57.3466"
id="text83-5-9-9-7-0-4"><tspan
sodipodi:role="line"
x="-15.185183"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2-6-9">B</tspan></text>
</g>
<g
id="g2"
transform="translate(0,-16.057901)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-46.032711"
y="57.349865"
id="text83-7"><tspan
sodipodi:role="line"
x="-46.032711"
y="57.349865"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-8">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-42.773308"
y="57.349865"
id="text83-7-4"><tspan
sodipodi:role="line"
x="-42.773308"
y="57.349865"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-8-3">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-55.041409"
y="57.3466"
id="text83-5"><tspan
sodipodi:role="line"
x="-55.041409"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-57.982994"
y="57.3466"
id="text83-5-3"><tspan
sodipodi:role="line"
x="-57.982994"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-5">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-52.099823"
y="57.3466"
id="text83-5-6"><tspan
sodipodi:role="line"
x="-52.099823"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-9">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-49.158237"
y="57.3466"
id="text83-5-6-5"><tspan
sodipodi:role="line"
x="-49.158237"
y="57.3466"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-9-2">C</tspan></text>
</g>
<g
id="g86"
transform="matrix(0.25710378,0,0,0.25710378,17.422136,8.7899633)">
<circle
style="fill:#ffffff;stroke:#ff0000;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle84"
cx="-121.9205"
cy="20.747513"
r="30.822298" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-122.11524"
y="26.792702"
id="text84"><tspan
sodipodi:role="line"
x="-122.11524"
y="26.792702"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.400612"
id="tspan84">C</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:2.17681px;font-family:'Linux Libertine O';-inkscape-font-specification:'Linux Libertine O';text-align:start;letter-spacing:1.26323px;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:none;stroke:#000000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
x="-140.03215"
y="26.074423"
id="text86"><tspan
sodipodi:role="line"
id="tspan86"
style="stroke-width:0.257104"
x="-140.03215"
y="26.074423" /></text>
<rect
style="fill:none;stroke:#000000;stroke-width:0.463569;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="rect89"
width="62.753353"
height="10.962811"
x="-68.911674"
y="32.218185" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.26751px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-37.552006"
y="35.595592"
id="text89"><tspan
sodipodi:role="line"
x="-37.552006"
y="35.595592"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26751px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan89">Enforce Isolation</tspan></text>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -57.807162,48.273529 V 44.392491"
id="path90"
sodipodi:nodetypes="cc" />
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -24.512426,48.273529 V 44.392491"
id="path91"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#ff00ff;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -57.329023,22.418572 v 9.208373"
id="path1" />
<path
style="fill:#ff00ff;stroke:#ff9955;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -32.844695,22.418572 v 9.208373"
id="path2" />
<path
style="fill:#ff00ff;stroke:#ff0000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -13.924085,22.418572 v 9.208373"
id="path4" />
<path
style="fill:none;stroke:#ff00ff;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -57.329023,22.418572 v 5.174952 h 20.852017 v 4.033421"
id="path5"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -13.924085,22.418572 v 3.652908 h -34.777483 v 5.555465"
id="path6"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -7,19 +7,21 @@
The relationship between the CPU and GPU can be described as the
producer-consumer problem, where the CPU fills out a buffer with operations
(producer) to be executed by the GPU (consumer). The requested operations in
the buffer are called Command Packets, which can be summarized as a compressed
way of transmitting command information to the graphics controller.
the buffer are called **Command Packets**, which can be summarized as a
compressed way of transmitting command information to the graphics controller.
The component that acts as the front end between the CPU and the GPU is called
the Command Processor (CP). This component is responsible for providing greater
flexibility to the GC since CP makes it possible to program various aspects of
the GPU pipeline. CP also coordinates the communication between the CPU and GPU
via a mechanism named **Ring Buffers**, where the CPU appends information to
the buffer while the GPU removes operations. It is relevant to highlight that a
CPU can add a pointer to the Ring Buffer that points to another region of
memory outside the Ring Buffer, and CP can handle it; this mechanism is called
**Indirect Buffer (IB)**. CP receives and parses the Command Streams (CS), and
writes the operations to the correct hardware blocks.
**Command Processor (CP)**. This component is responsible for providing greater
flexibility to the **Graphics and Compute (GC)** since CP makes it possible to
program various aspects of the GPU pipeline. CP also coordinates the
communication between the CPU and GPU via a mechanism named **Ring Buffers**,
where the CPU appends information to the buffer while the GPU removes
operations. CP is also responsible for handling **Indirect Buffers (IB)**.
For reference, internally the CP consists of several sub-blocks (CPC - CP
compute, CPG - CP graphics, and CPF - CP fetcher). Some of these acronyms
appear in register names, but this is more of an implementation detail and not
something that directly impacts driver programming or debugging.
Graphics (GFX) and Compute Microcontrollers
-------------------------------------------

View file

@ -0,0 +1,413 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="141.76276mm"
height="51.906979mm"
viewBox="0 0 141.76275 51.906979"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="gfx_pipeline_seq.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.2641204"
inkscape:cx="470.28748"
inkscape:cy="63.680643"
inkscape:window-width="3072"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="ArrowWideHeavy"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, heavy arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path3" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(23.062206,-30.75877)">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.694678;stroke-linecap:square;stroke-dasharray:4.16805, 4.16805"
id="rect1"
width="141.76276"
height="51.906979"
x="-23.062206"
y="30.75877" />
<g
id="g28"
transform="matrix(1.0835493,0,0,1.0835493,-30.079831,-159.17628)">
<path
id="path18"
style="fill:none;stroke:#000000;stroke-width:0.721067;stroke-dasharray:none"
d="M 30.278993,176.45537 A 22.905334,22.905334 0 0 0 7.3737955,199.36057 22.905334,22.905334 0 0 0 30.278993,222.26603 22.905334,22.905334 0 0 0 53.18445,199.36057 22.905334,22.905334 0 0 0 30.278993,176.45537 Z m 0,7.13274 a 15.772359,15.772359 0 0 1 15.77246,15.77246 15.772359,15.772359 0 0 1 -15.77246,15.77246 15.772359,15.772359 0 0 1 -15.772206,-15.77246 15.772359,15.772359 0 0 1 15.772206,-15.77246 z" />
<g
id="g27">
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 46.31405,200.72093 h 6.430134"
id="path19"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 7.6848605,200.72093 H 14.114993"
id="path20"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 30.103415,176.7326 v 6.43014"
id="path21"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 30.103415,215.50586 V 221.936"
id="path22"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,214.1052 3.21507,5.56866"
id="path23"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,184.66805 3.21507,-5.56866"
id="path24"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,184.66805 -3.21507,-5.56866"
id="path25"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,214.05288 -3.21507,5.56866"
id="path26"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,208.65101 4.546794,4.5468"
id="path27"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,189.96525 4.546794,-4.5468"
id="path28"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 17.202394,189.96525 12.6556,185.41845"
id="path29"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 16.940766,208.65101 -4.546794,4.5468"
id="path30"
sodipodi:nodetypes="cc" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.92107px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.434083"
x="23.133495"
y="52.750404"
id="text24"><tspan
sodipodi:role="line"
x="23.133495"
y="52.750404"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.92107px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.434083"
id="tspan24">IB<tspan
style="font-size:3.92107px;baseline-shift:sub;fill:#ff9955;stroke-width:0.434083"
id="tspan27">b</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.88054px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.434083"
x="2.4917324"
y="55.12072"
id="text139"><tspan
sodipodi:role="line"
x="2.4917324"
y="55.12072"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.88054px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.434083"
id="tspan138">Ring</tspan><tspan
sodipodi:role="line"
x="2.4917324"
y="63.721394"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.88054px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.434083"
id="tspan139">Buffer</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.92107px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.434083"
x="22.115709"
y="65.117416"
id="text18"><tspan
sodipodi:role="line"
x="22.115709"
y="65.117416"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.92107px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#87decd;stroke-width:0.434083"
id="tspan18">IB<tspan
style="font-size:3.92107px;baseline-shift:sub;fill:#87decd;stroke-width:0.434083"
id="tspan17">c</tspan></tspan></text>
<g
id="g62"
transform="matrix(0.69467788,0,0,0.69467788,-104.6214,-57.027324)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="221.50526"
y="173.96935"
id="text48"><tspan
sodipodi:role="line"
x="221.50526"
y="173.96935"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.400612"
id="tspan48">SX</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="238.1783"
y="173.96935"
id="text49"><tspan
sodipodi:role="line"
x="238.1783"
y="173.96935"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.400612"
id="tspan49">GE</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="255.66414"
y="173.96935"
id="text50"><tspan
sodipodi:role="line"
x="255.66414"
y="173.96935"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.400612"
id="tspan50">SPI</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="273.01663"
y="173.96935"
id="text51"><tspan
sodipodi:role="line"
x="273.01663"
y="173.96935"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.400612"
id="tspan51">SC</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="289.11816"
y="173.97888"
id="text52"><tspan
sodipodi:role="line"
x="289.11816"
y="173.97888"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.400612"
id="tspan52">PA</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="311.40778"
y="174.08365"
id="text53"><tspan
sodipodi:role="line"
x="311.40778"
y="174.08365"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.35px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff2a2a;stroke-width:0.400612"
id="tspan53">Cache</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 226.31089,171.70241 h 6.95598"
id="path53"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 242.81883,171.70241 h 6.95598"
id="path54"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 261.37781,171.70241 h 6.95598"
id="path55"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 277.50475,171.70241 h 6.95598"
id="path56"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 294.08254,171.70241 h 6.95598"
id="path57"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 189.90312,171.70241 h 26.34385"
id="path60"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 311.60514,176.14239 v 9.61994 H 184.98772"
id="path61"
sodipodi:nodetypes="ccc" />
</g>
<path
style="fill:#37c871;stroke:#00d455;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
d="m 40.698106,46.362333 4.844663,13.377322"
id="path62"
sodipodi:nodetypes="cc" />
<path
style="fill:#37c871;stroke:#00d455;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
d="m 52.62426,46.362333 4.844663,13.377322"
id="path63"
sodipodi:nodetypes="cc" />
<path
style="fill:#37c871;stroke:#00d455;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
d="m 64.55042,46.362333 4.844663,13.377322"
id="path64"
sodipodi:nodetypes="cc" />
<path
style="fill:#37c871;stroke:#00d455;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
d="m 75.962512,46.362333 4.844663,13.377322"
id="path65"
sodipodi:nodetypes="cc" />
<path
style="fill:#37c871;stroke:#00d455;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
d="m 87.580235,46.362333 4.844663,13.377322"
id="path66"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="37.018822"
y="45.730473"
id="text2"><tspan
sodipodi:role="line"
x="37.018822"
y="45.730473"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.278297"
id="tspan2">SX</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="48.601212"
y="45.730473"
id="text3"><tspan
sodipodi:role="line"
x="48.601212"
y="45.730473"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.278297"
id="tspan3">GE</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#37abc8;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="60.748234"
y="45.730473"
id="text4"><tspan
sodipodi:role="line"
x="60.748234"
y="45.730473"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#37abc8;stroke-width:0.278297"
id="tspan4">SPI</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="72.802635"
y="45.730473"
id="text11"><tspan
sodipodi:role="line"
x="72.802635"
y="45.730473"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.278297"
id="tspan11">SC</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="83.988014"
y="45.737099"
id="text13"><tspan
sodipodi:role="line"
x="83.988014"
y="45.737099"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.278297"
id="tspan13">PA</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.4112px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:0.278297"
x="99.472122"
y="45.809875"
id="text14"><tspan
sodipodi:role="line"
x="99.472122"
y="45.809875"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.4112px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff2a2a;stroke-width:0.278297"
id="tspan14">Cache</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 40.357179,44.155689 h 4.832165"
id="path44"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 51.82488,44.155689 h 4.832165"
id="path45"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 64.717393,44.155689 h 4.832165"
id="path46"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 75.920422,44.155689 h 4.832165"
id="path47"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 87.436645,44.155689 h 4.832166"
id="path48"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 24.215741,44.155689 h 7.813702"
id="path58"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.367601;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#ArrowWideHeavy)"
d="m 100.63732,46.931607 v 6.68276 H 29.848557"
id="path59"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -8,6 +8,7 @@ Next (GCN), Radeon DNA (RDNA), and Compute DNA (CDNA) architectures.
.. toctree::
driver-core
ring-buffer
amd-hardware-list-info
module-parameters
gc/index

View file

@ -0,0 +1,707 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="68.949203mm"
height="86.909332mm"
viewBox="0 0 68.949202 86.909332"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="enforce_isolation.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.7877362"
inkscape:cx="291.15034"
inkscape:cy="332.54347"
inkscape:window-width="3072"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g61" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="ArrowWideHeavy"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, heavy arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path3" />
</marker>
<marker
style="overflow:visible"
id="Dot"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Dot"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 5,0 C 5,2.76 2.76,5 0,5 -2.76,5 -5,2.76 -5,0 c 0,-2.76 2.3,-5 5,-5 2.76,0 5,2.24 5,5 z"
sodipodi:nodetypes="sssss"
id="path98" />
</marker>
<marker
style="overflow:visible"
id="marker99"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Dot"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 5,0 C 5,2.76 2.76,5 0,5 -2.76,5 -5,2.76 -5,0 c 0,-2.76 2.3,-5 5,-5 2.76,0 5,2.24 5,5 z"
sodipodi:nodetypes="sssss"
id="path99" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(72.009598,0.94510132)">
<g
id="g61">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.25654;stroke-linecap:square;stroke-dasharray:none"
id="rect6"
width="68.949203"
height="86.909332"
x="-72.009598"
y="-0.94510132" />
<g
id="g15"
transform="matrix(0.42247861,0,0,0.42247861,-70.575576,-29.756289)">
<path
id="path33"
style="fill:none;stroke:#000000;stroke-width:0.721067;stroke-dasharray:none"
d="M 30.278993,176.45537 A 22.905334,22.905334 0 0 0 7.3737955,199.36057 22.905334,22.905334 0 0 0 30.278993,222.26603 22.905334,22.905334 0 0 0 53.18445,199.36057 22.905334,22.905334 0 0 0 30.278993,176.45537 Z m 0,7.13274 a 15.772359,15.772359 0 0 1 15.77246,15.77246 15.772359,15.772359 0 0 1 -15.77246,15.77246 15.772359,15.772359 0 0 1 -15.772206,-15.77246 15.772359,15.772359 0 0 1 15.772206,-15.77246 z" />
<g
id="g14">
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 46.31405,200.72093 h 6.430134"
id="path34"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 7.6848605,200.72093 H 14.114993"
id="path35"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 30.103415,176.7326 v 6.43014"
id="path36"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 30.103415,215.50586 V 221.936"
id="path37"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,214.1052 3.21507,5.56866"
id="path38"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,184.66805 3.21507,-5.56866"
id="path39"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,184.66805 -3.21507,-5.56866"
id="path40"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,214.05288 -3.21507,5.56866"
id="path41"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,208.65101 4.546794,4.5468"
id="path42"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,189.96525 4.546794,-4.5468"
id="path43"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 17.202394,189.96525 12.6556,185.41845"
id="path44-1"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 16.940766,208.65101 -4.546794,4.5468"
id="path45-8"
sodipodi:nodetypes="cc" />
</g>
</g>
<rect
style="fill:#afe9c6;stroke:#16502d;stroke-width:0.257104;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
id="rect80"
width="25.076588"
height="10.493422"
x="-71.362038"
y="74.63459"
ry="1.4529352" />
<rect
style="fill:#80e5ff;stroke:#00aad4;stroke-width:0.257104;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
id="rect81"
width="32.714355"
height="10.436013"
x="-40.481403"
y="74.663292"
ry="1.4449863" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.53042px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-59.013123"
y="82.212669"
id="text14-7"><tspan
sodipodi:role="line"
x="-59.013123"
y="82.212669"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.53042px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan14-7">GFX</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.53042px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-24.387218"
y="81.46167"
id="text95"><tspan
sodipodi:role="line"
x="-24.387218"
y="81.46167"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.53042px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan95">Compute</tspan></text>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -58.079264,73.89605 V 65.448872"
id="path127"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.90242px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-61.752651"
y="3.1995225"
id="text112"><tspan
sodipodi:role="line"
x="-61.752651"
y="3.1995225"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.90242px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan112">Processes</tspan></text>
<rect
style="fill:none;stroke:#000000;stroke-width:0.247306;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:1.48383, 1.48383;stroke-dashoffset:0"
id="rect113"
width="64.703476"
height="19.562067"
x="-68.52655"
y="4.468956"
ry="1.6976216" />
<g
id="g84"
transform="matrix(0.25710378,0,0,0.25710378,0.68647434,8.7899633)">
<g
id="g83">
<circle
style="fill:#ffffff;stroke:#ff00ff;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle137"
cx="-225.65012"
cy="20.747513"
r="30.822298" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-225.65012"
y="26.8181"
id="text113"><tspan
sodipodi:role="line"
x="-225.65012"
y="26.8181"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.400612"
id="tspan113">A</tspan></text>
</g>
<g
id="g85"
transform="matrix(0.25710378,0,0,0.25710378,20.618429,8.7899633)">
<circle
style="fill:#ffffff;stroke:#ff9955;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle112"
cx="-207.94376"
cy="20.747513"
r="30.822298" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-208.25702"
y="26.792702"
id="text114"><tspan
sodipodi:role="line"
x="-208.25702"
y="26.792702"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.400612"
id="tspan114">B</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-56.126556"
y="47.212101"
id="text6"><tspan
sodipodi:role="line"
x="-56.126556"
y="47.212101"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan6">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.26752px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-57.861526"
y="53.902462"
id="text136"><tspan
sodipodi:role="line"
x="-57.861526"
y="53.902462"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan136">Ring</tspan><tspan
sodipodi:role="line"
x="-57.861526"
y="56.736862"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan137">Buffer</tspan></text>
<g
id="g80"
transform="matrix(0.42247861,0,0,0.42247861,-37.21188,-29.756289)">
<path
id="path67"
style="fill:none;stroke:#000000;stroke-width:0.721067;stroke-dasharray:none"
d="M 30.278993,176.45537 A 22.905334,22.905334 0 0 0 7.3737955,199.36057 22.905334,22.905334 0 0 0 30.278993,222.26603 22.905334,22.905334 0 0 0 53.18445,199.36057 22.905334,22.905334 0 0 0 30.278993,176.45537 Z m 0,7.13274 a 15.772359,15.772359 0 0 1 15.77246,15.77246 15.772359,15.772359 0 0 1 -15.77246,15.77246 15.772359,15.772359 0 0 1 -15.772206,-15.77246 15.772359,15.772359 0 0 1 15.772206,-15.77246 z" />
<g
id="g79">
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 46.31405,200.72093 h 6.430134"
id="path68"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 7.6848605,200.72093 H 14.114993"
id="path69"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 30.103415,176.7326 v 6.43014"
id="path70"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 30.103415,215.50586 V 221.936"
id="path71"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,214.1052 3.21507,5.56866"
id="path72"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 36.501694,184.66805 3.21507,-5.56866"
id="path73"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,184.66805 -3.21507,-5.56866"
id="path74"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 23.652811,214.05288 -3.21507,5.56866"
id="path75"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,208.65101 4.546794,4.5468"
id="path76"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 43.31839,189.96525 4.546794,-4.5468"
id="path77"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="M 17.202394,189.96525 12.6556,185.41845"
id="path78"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
d="m 16.940766,208.65101 -4.546794,4.5468"
id="path79"
sodipodi:nodetypes="cc" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.26752px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-24.497828"
y="53.902462"
id="text81"><tspan
sodipodi:role="line"
x="-24.497828"
y="53.902462"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan80">Ring</tspan><tspan
sodipodi:role="line"
x="-24.497828"
y="56.736862"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.26752px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.102999"
id="tspan81">Buffer</tspan></text>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -24.338879,73.89605 V 65.448872"
id="path81"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-52.574932"
y="48.826473"
id="text82"><tspan
sodipodi:role="line"
x="-52.574932"
y="48.826473"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan82">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-50.045757"
y="52.862404"
id="text83"><tspan
sodipodi:role="line"
x="-50.045757"
y="52.862404"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-31.907158"
y="58.226768"
id="text83-59"><tspan
sodipodi:role="line"
x="-31.907158"
y="58.226768"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-7">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-32.436516"
y="53.169308"
id="text83-59-3"><tspan
sodipodi:role="line"
x="-32.436516"
y="53.169308"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-7-6">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-65.422112"
y="57.972916"
id="text83-7"><tspan
sodipodi:role="line"
x="-65.422112"
y="57.972916"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-8">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-65.713165"
y="52.732723"
id="text83-7-4"><tspan
sodipodi:role="line"
x="-65.713165"
y="52.732723"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff00ff;stroke-width:0.102999"
id="tspan83-8-3">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-52.897129"
y="61.668709"
id="text83-5"><tspan
sodipodi:role="line"
x="-52.897129"
y="61.668709"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-19.174068"
y="49.045818"
id="text83-5-9"><tspan
sodipodi:role="line"
x="-19.174068"
y="49.045818"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-2">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-16.531792"
y="53.259804"
id="text83-5-9-9"><tspan
sodipodi:role="line"
x="-16.531792"
y="53.259804"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-2-5">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-19.325029"
y="61.488995"
id="text83-5-9-9-7"><tspan
sodipodi:role="line"
x="-19.325029"
y="61.488995"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2">B</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-22.869593"
y="63.231686"
id="text83-5-9-9-7-0"><tspan
sodipodi:role="line"
x="-22.869593"
y="63.231686"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2-6">B</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-26.235374"
y="63.331181"
id="text83-5-9-9-7-0-4"><tspan
sodipodi:role="line"
x="-26.235374"
y="63.331181"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff9955;stroke-width:0.102999"
id="tspan83-4-2-5-2-6-9">B</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-56.235538"
y="63.072704"
id="text83-5-6"><tspan
sodipodi:role="line"
x="-56.235538"
y="63.072704"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-9">C</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:2.17681px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.102999"
x="-59.697765"
y="63.066635"
id="text83-5-6-5"><tspan
sodipodi:role="line"
x="-59.697765"
y="63.066635"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.17681px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.102999"
id="tspan83-4-9-2">C</tspan></text>
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83"
cx="-50.145481"
cy="57.387428"
r="1.0712636" />
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83-7"
cx="-16.886913"
cy="57.596024"
r="1.0712636" />
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83-7-7"
cx="-29.53648"
cy="60.832634"
r="1.0712636" />
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83-7-7-9"
cx="-29.751556"
cy="48.260994"
r="1.0712636" />
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83-4"
cx="-63.051891"
cy="60.73439"
r="1.0712636" />
<circle
style="fill:#ffcc00;stroke:#00d455;stroke-width:0.213261;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="path83-4-2"
cx="-63.022129"
cy="48.24374"
r="1.0712636" />
<g
id="g86"
transform="matrix(0.25710378,0,0,0.25710378,17.422136,8.7899633)">
<circle
style="fill:#ffffff;stroke:#ff0000;stroke-width:1.62704;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0"
id="circle84"
cx="-121.9205"
cy="20.747513"
r="30.822298" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff9955;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-122.11524"
y="26.792702"
id="text84"><tspan
sodipodi:role="line"
x="-122.11524"
y="26.792702"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ff0000;stroke-width:0.400612"
id="tspan84">C</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:2.17681px;font-family:'Linux Libertine O';-inkscape-font-specification:'Linux Libertine O';text-align:start;letter-spacing:1.26323px;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:none;stroke:#000000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
x="-140.03215"
y="26.074423"
id="text86"><tspan
sodipodi:role="line"
id="tspan86"
style="stroke-width:0.257104"
x="-140.03215"
y="26.074423" /></text>
<g
id="g90"
transform="matrix(0.25710378,0,0,0.25710378,18.175509,7.82134)">
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="rect86"
width="92.604057"
height="26.883123"
x="-338.30258"
y="93.635468" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:8.81944px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-291.13989"
y="110.58046"
id="text88"><tspan
sodipodi:role="line"
x="-291.13989"
y="110.58046"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.81944px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.400612"
id="tspan88">Enforce Isolation</tspan></text>
</g>
<g
id="g89"
transform="matrix(0.25710378,0,0,0.25710378,18.606009,7.82134)">
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-dasharray:none;stroke-dashoffset:0"
id="rect89"
width="119.67937"
height="26.749132"
x="-219.35185"
y="93.702461" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:8.81944px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.400612"
x="-159.57832"
y="110.40636"
id="text89"><tspan
sodipodi:role="line"
x="-159.57832"
y="110.40636"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.81944px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#1c241c;stroke-width:0.400612"
id="tspan89">Enforce Isolation</tspan></text>
</g>
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -57.807162,43.759556 V 39.878518"
id="path90"
sodipodi:nodetypes="cc" />
<path
style="fill:#de8787;stroke:#000000;stroke-width:0.385656;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;marker-start:url(#Dot);marker-end:url(#marker99)"
d="M -24.512426,43.759556 V 39.878518"
id="path91"
sodipodi:nodetypes="cc" />
<path
style="fill:#ff00ff;stroke:#ff00ff;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -57.329023,22.418572 v 9.208373"
id="path1" />
<path
style="fill:#ff00ff;stroke:#ff9955;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -32.844695,22.418572 v 9.208373"
id="path2" />
<path
style="fill:#ff00ff;stroke:#ff0000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -13.924085,22.418572 v 9.208373"
id="path4" />
<path
style="fill:none;stroke:#ff00ff;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -57.329023,22.418572 v 5.174952 h 20.852017 v 4.033421"
id="path5"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.257104;stroke-linecap:square;stroke-dasharray:none;marker-end:url(#ArrowWideHeavy)"
d="m -13.924085,22.418572 v 3.652908 h -34.777483 v 5.555465"
id="path6"
sodipodi:nodetypes="cccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -1,3 +1,4 @@
.. _amdgpu-process-isolation:
.. SPDX-License-Identifier: GPL-2.0
=========================

View file

@ -0,0 +1,95 @@
=============
Ring Buffer
=============
To handle communication between user space and kernel space, AMD GPUs use a
ring buffer design to feed the engines (GFX, Compute, SDMA, UVD, VCE, VCN, VPE,
etc.). See the figure below that illustrates how this communication works:
.. kernel-figure:: ring_buffers.svg
Ring buffers in the amdgpu work as a producer-consumer model, where userspace
acts as the producer, constantly filling the ring buffer with GPU commands to
be executed. Meanwhile, the GPU retrieves the information from the ring, parses
it, and distributes the specific set of instructions between the different
amdgpu blocks.
Notice from the diagram that the ring has a Read Pointer (rptr), which
indicates where the engine is currently reading packets from the ring, and a
Write Pointer (wptr), which indicates how many packets software has added to
the ring. When the rptr and wptr are equal, the ring is idle. When software
adds packets to the ring, it updates the wptr, this causes the engine to start
fetching and processing packets. As the engine processes packets, the rptr gets
updates until the rptr catches up to the wptr and they are equal again.
Usually, ring buffers in the driver have a limited size (search for occurrences
of `amdgpu_ring_init()`). One of the reasons for the small ring buffer size is
that CP (Command Processor) is capable of following addresses inserted into the
ring; this is illustrated in the image by the reference to the IB (Indirect
Buffer). The IB gives userspace the possibility to have an area in memory that
CP can read and feed the hardware with extra instructions.
All ASICs pre-GFX11 use what is called a kernel queue, which means
the ring is allocated in kernel space and has some restrictions, such as not
being able to be :ref:`preempted directly by the scheduler<amdgpu-mes>`. GFX11
and newer support kernel queues, but also provide a new mechanism named
:ref:`user queues<amdgpu-userq>`, where the queue is moved to the user space
and can be mapped and unmapped via the scheduler. In practice, both queues
insert user-space-generated GPU commands from different jobs into the requested
component ring.
Enforce Isolation
=================
.. note:: After reading this section, you might want to check the
:ref:`Process Isolation<amdgpu-process-isolation>` page for more details.
Before examining the Enforce Isolation mechanism in the ring buffer context, it
is helpful to briefly discuss how instructions from the ring buffer are
processed in the graphics pipeline. Lets expand on this topic by checking the
diagram below that illustrates the graphics pipeline:
.. kernel-figure:: gfx_pipeline_seq.svg
In terms of executing instructions, the GFX pipeline follows the sequence:
Shader Export (SX), Geometry Engine (GE), Shader Process or Input (SPI), Scan
Converter (SC), Primitive Assembler (PA), and cache manipulation (which may
vary across ASICs). Another common way to describe the pipeline is to use Pixel
Shader (PS), raster, and Vertex Shader (VS) to symbolize the two shader stages.
Now, with this pipeline in mind, let's assume that Job B causes a hang issue,
but Job C's instruction might already be executing, leading developers to
incorrectly identify Job C as the problematic one. This problem can be
mitigated on multiple levels; the diagram below illustrates how to minimize
part of this problem:
.. kernel-figure:: no_enforce_isolation.svg
Note from the diagram that there is no guarantee of order or a clear separation
between instructions, which is not a problem most of the time, and is also good
for performance. Furthermore, notice some circles between jobs in the diagram
that represent a **fence wait** used to avoid overlapping work in the ring. At
the end of the fence, a cache flush occurs, ensuring that when the next job
starts, it begins in a clean state and, if issues arise, the developer can
pinpoint the problematic process more precisely.
To increase the level of isolation between jobs, there is the "Enforce
Isolation" method described in the picture below:
.. kernel-figure:: enforce_isolation.svg
As shown in the diagram, enforcing isolation introduces ordering between
submissions, since the access to GFX/Compute is serialized, think about it as
single process at a time mode for gfx/compute. Notice that this approach has a
significant performance impact, as it allows only one job to submit commands at
a time. However, this option can help pinpoint the job that caused the problem.
Although enforcing isolation improves the situation, it does not fully resolve
the issue of precisely pinpointing bad jobs, since isolation might mask the
problem. In summary, identifying which job caused the issue may not be precise,
but enforcing isolation might help with the debugging.
Ring Operations
===============
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
:internal:

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -1,3 +1,5 @@
.. _amdgpu-userq:
==================
User Mode Queues
==================

View file

@ -86,7 +86,7 @@ amdgpu-y += \
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o soc24.o \
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \
nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o nbif_v6_3_1.o \
cyan_skillfish_reg_init.o
cyan_skillfish_reg_init.o soc_v1_0.o
# add DF block
amdgpu-y += \
@ -104,7 +104,8 @@ amdgpu-y += \
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 gfxhub_v3_0_3.o gfxhub_v1_2.o mmhub_v1_8.o mmhub_v3_3.o \
gfxhub_v11_5_0.o mmhub_v4_1_0.o gfxhub_v12_0.o gmc_v12_0.o
gfxhub_v11_5_0.o mmhub_v4_1_0.o gfxhub_v12_0.o gmc_v12_0.o \
mmhub_v4_2_0.o gfxhub_v12_1.o gmc_v12_1.o
# add UMC block
amdgpu-y += \
@ -134,7 +135,9 @@ amdgpu-y += \
psp_v12_0.o \
psp_v13_0.o \
psp_v13_0_4.o \
psp_v14_0.o
psp_v14_0.o \
psp_v15_0.o \
psp_v15_0_8.o
# add DCE block
amdgpu-y += \
@ -156,7 +159,9 @@ amdgpu-y += \
gfx_v11_0_3.o \
imu_v11_0_3.o \
gfx_v12_0.o \
imu_v12_0.o
gfx_v12_1.o \
imu_v12_0.o \
imu_v12_1.o
# add async DMA block
amdgpu-y += \
@ -169,13 +174,15 @@ amdgpu-y += \
sdma_v5_0.o \
sdma_v5_2.o \
sdma_v6_0.o \
sdma_v7_0.o
sdma_v7_0.o \
sdma_v7_1.o
# add MES block
amdgpu-y += \
amdgpu_mes.o \
mes_v11_0.o \
mes_v12_0.o \
mes_v12_1.o
# add GFX userqueue support
amdgpu-y += mes_userqueue.o
@ -215,7 +222,8 @@ amdgpu-y += \
jpeg_v4_0_3.o \
jpeg_v4_0_5.o \
jpeg_v5_0_0.o \
jpeg_v5_0_1.o
jpeg_v5_0_1.o \
jpeg_v5_3_0.o
# add VPE block
amdgpu-y += \
@ -244,7 +252,9 @@ amdgpu-y += \
smuio_v13_0.o \
smuio_v13_0_3.o \
smuio_v13_0_6.o \
smuio_v14_0_2.o
smuio_v14_0_2.o \
smuio_v15_0_0.o \
smuio_v15_0_8.o
# add reset block
amdgpu-y += \
@ -275,7 +285,8 @@ amdgpu-y += \
amdgpu_amdkfd_gfx_v10.o \
amdgpu_amdkfd_gfx_v10_3.o \
amdgpu_amdkfd_gfx_v11.o \
amdgpu_amdkfd_gfx_v12.o
amdgpu_amdkfd_gfx_v12.o \
amdgpu_amdkfd_gfx_v12_1.o
ifneq ($(CONFIG_DRM_AMDGPU_CIK),)
amdgpu-y += amdgpu_amdkfd_gfx_v7.o

View file

@ -34,12 +34,6 @@
#define pr_fmt(fmt) "amdgpu: " fmt
#ifdef dev_fmt
#undef dev_fmt
#endif
#define dev_fmt(fmt) "amdgpu: " fmt
#include "amdgpu_ctx.h"
#include <linux/atomic.h>
@ -116,6 +110,7 @@
#include "amdgpu_reg_state.h"
#include "amdgpu_userq.h"
#include "amdgpu_eviction_fence.h"
#include "amdgpu_ip.h"
#if defined(CONFIG_DRM_AMD_ISP)
#include "amdgpu_isp.h"
#endif
@ -362,59 +357,6 @@ enum amdgpu_kiq_irq {
#define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */
#define MAX_KIQ_REG_TRY 1000
int amdgpu_device_ip_set_clockgating_state(void *dev,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state);
int amdgpu_device_ip_set_powergating_state(void *dev,
enum amd_ip_block_type block_type,
enum amd_powergating_state state);
void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags);
int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block);
int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block);
#define AMDGPU_MAX_IP_NUM AMD_IP_BLOCK_TYPE_NUM
struct amdgpu_ip_block_status {
bool valid;
bool sw;
bool hw;
bool late_initialized;
bool hang;
};
struct amdgpu_ip_block_version {
const enum amd_ip_block_type type;
const u32 major;
const u32 minor;
const u32 rev;
const struct amd_ip_funcs *funcs;
};
struct amdgpu_ip_block {
struct amdgpu_ip_block_status status;
const struct amdgpu_ip_block_version *version;
struct amdgpu_device *adev;
};
int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev,
enum amd_ip_block_type type,
u32 major, u32 minor);
struct amdgpu_ip_block *
amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev,
enum amd_ip_block_type type);
int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
const struct amdgpu_ip_block_version *ip_block_version);
/*
* BIOS.
*/
@ -757,71 +699,6 @@ struct amdgpu_mmio_remap {
struct amdgpu_bo *bo;
};
/* Define the HW IP blocks will be used in driver , add more if necessary */
enum amd_hw_ip_block_type {
GC_HWIP = 1,
HDP_HWIP,
SDMA0_HWIP,
SDMA1_HWIP,
SDMA2_HWIP,
SDMA3_HWIP,
SDMA4_HWIP,
SDMA5_HWIP,
SDMA6_HWIP,
SDMA7_HWIP,
LSDMA_HWIP,
MMHUB_HWIP,
ATHUB_HWIP,
NBIO_HWIP,
MP0_HWIP,
MP1_HWIP,
UVD_HWIP,
VCN_HWIP = UVD_HWIP,
JPEG_HWIP = VCN_HWIP,
VCN1_HWIP,
VCE_HWIP,
VPE_HWIP,
DF_HWIP,
DCE_HWIP,
OSSSYS_HWIP,
SMUIO_HWIP,
PWR_HWIP,
NBIF_HWIP,
THM_HWIP,
CLK_HWIP,
UMC_HWIP,
RSMU_HWIP,
XGMI_HWIP,
DCI_HWIP,
PCIE_HWIP,
ISP_HWIP,
MAX_HWIP
};
#define HWIP_MAX_INSTANCE 44
#define HW_ID_MAX 300
#define IP_VERSION_FULL(mj, mn, rv, var, srev) \
(((mj) << 24) | ((mn) << 16) | ((rv) << 8) | ((var) << 4) | (srev))
#define IP_VERSION(mj, mn, rv) IP_VERSION_FULL(mj, mn, rv, 0, 0)
#define IP_VERSION_MAJ(ver) ((ver) >> 24)
#define IP_VERSION_MIN(ver) (((ver) >> 16) & 0xFF)
#define IP_VERSION_REV(ver) (((ver) >> 8) & 0xFF)
#define IP_VERSION_VARIANT(ver) (((ver) >> 4) & 0xF)
#define IP_VERSION_SUBREV(ver) ((ver) & 0xF)
#define IP_VERSION_MAJ_MIN_REV(ver) ((ver) >> 8)
struct amdgpu_ip_map_info {
/* Map of logical to actual dev instances/mask */
uint32_t dev_inst[MAX_HWIP][HWIP_MAX_INSTANCE];
int8_t (*logical_to_dev_inst)(struct amdgpu_device *adev,
enum amd_hw_ip_block_type block,
int8_t inst);
uint32_t (*logical_to_dev_mask)(struct amdgpu_device *adev,
enum amd_hw_ip_block_type block,
uint32_t mask);
};
enum amdgpu_uid_type {
AMDGPU_UID_TYPE_XCD,
AMDGPU_UID_TYPE_AID,
@ -836,6 +713,38 @@ struct amdgpu_uid {
struct amdgpu_device *adev;
};
#define MAX_UMA_OPTION_NAME 28
#define MAX_UMA_OPTION_ENTRIES 19
#define AMDGPU_UMA_FLAG_AUTO BIT(1)
#define AMDGPU_UMA_FLAG_CUSTOM BIT(0)
/**
* struct amdgpu_uma_carveout_option - single UMA carveout option
* @name: Name of the carveout option
* @memory_carved_mb: Amount of memory carved in MB
* @flags: ATCS flags supported by this option
*/
struct amdgpu_uma_carveout_option {
char name[MAX_UMA_OPTION_NAME];
uint32_t memory_carved_mb;
uint8_t flags;
};
/**
* struct amdgpu_uma_carveout_info - table of available UMA carveout options
* @num_entries: Number of available options
* @uma_option_index: The index of the option currently applied
* @update_lock: Lock to serialize changes to the option
* @entries: The array of carveout options
*/
struct amdgpu_uma_carveout_info {
uint8_t num_entries;
uint8_t uma_option_index;
struct mutex update_lock;
struct amdgpu_uma_carveout_option entries[MAX_UMA_OPTION_ENTRIES];
};
struct amd_powerplay {
void *pp_handle;
const struct amd_pm_funcs *pp_funcs;
@ -891,6 +800,7 @@ struct amdgpu_mqd_prop {
uint64_t eop_gpu_addr;
uint32_t hqd_pipe_priority;
uint32_t hqd_queue_priority;
uint32_t mqd_stride_size;
bool allow_tunneling;
bool hqd_active;
uint64_t shadow_addr;
@ -1319,6 +1229,8 @@ struct amdgpu_device {
struct work_struct userq_reset_work;
struct amdgpu_uid *uid_info;
struct amdgpu_uma_carveout_info uma_info;
/* KFD
* Must be last --ends in a flexible-array member.
*/
@ -1545,8 +1457,13 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
#define amdgpu_asic_need_reset_on_init(adev) (adev)->asic_funcs->need_reset_on_init((adev))
#define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev)))
#define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev))
#define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev))
#define amdgpu_asic_supports_baco(adev) \
((adev)->asic_funcs->supports_baco ? (adev)->asic_funcs->supports_baco((adev)) : 0)
#define amdgpu_asic_pre_asic_init(adev) \
{ \
if ((adev)->asic_funcs && (adev)->asic_funcs->pre_asic_init) \
(adev)->asic_funcs->pre_asic_init((adev)); \
}
#define amdgpu_asic_update_umd_stable_pstate(adev, enter) \
((adev)->asic_funcs->update_umd_stable_pstate ? (adev)->asic_funcs->update_umd_stable_pstate((adev), (enter)) : 0)
#define amdgpu_asic_query_video_codecs(adev, e, c) (adev)->asic_funcs->query_video_codecs((adev), (e), (c))
@ -1686,12 +1603,14 @@ int amdgpu_acpi_init(struct amdgpu_device *adev);
void amdgpu_acpi_fini(struct amdgpu_device *adev);
bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev);
bool amdgpu_acpi_is_power_shift_control_supported(void);
bool amdgpu_acpi_is_set_uma_allocation_size_supported(void);
int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
u8 perf_req, bool advertise);
int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
u8 dev_state, bool drv_state);
int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
enum amdgpu_ss ss_state);
int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type);
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
u64 *tmr_size);
@ -1720,6 +1639,7 @@ static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { re
static inline void amdgpu_acpi_detect(void) { }
static inline void amdgpu_acpi_release(void) { }
static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
static inline bool amdgpu_acpi_is_set_uma_allocation_size_supported(void) { return false; }
static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
u8 dev_state, bool drv_state) { return 0; }
static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
@ -1727,6 +1647,10 @@ static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
{
return 0;
}
static inline int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type)
{
return -EINVAL;
}
static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps) { }
#endif

View file

@ -116,7 +116,9 @@ struct amdgpu_atcs_functions {
bool pcie_perf_req;
bool pcie_dev_rdy;
bool pcie_bus_width;
bool get_uma_size;
bool power_shift_control;
bool set_uma_allocation_size;
};
struct amdgpu_atcs {
@ -241,7 +243,8 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas
* (all asics).
* returns 0 on success, error on failure.
*/
static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
static noinline_for_stack
int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
{
union acpi_object *info;
struct atif_verify_interface output;
@ -286,7 +289,8 @@ out:
* where n is specified in the result if a notifier is used.
* Returns 0 on success, error on failure.
*/
static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
static noinline_for_stack
int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
{
union acpi_object *info;
struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
@ -354,7 +358,8 @@ out:
*
* Returns 0 on success, error on failure.
*/
static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
static noinline_for_stack
int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
{
union acpi_object *info;
struct atif_qbtc_output characteristics;
@ -587,7 +592,9 @@ static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mas
f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
f->get_uma_size = mask & ACPI_ATCS_GET_UMA_SIZE_SUPPORTED;
f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED;
f->set_uma_allocation_size = mask & ACPI_ATCS_SET_UMA_ALLOCATION_SIZE_SUPPORTED;
}
/**
@ -600,7 +607,8 @@ static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mas
* (all asics).
* returns 0 on success, error on failure.
*/
static int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs)
static noinline_for_stack
int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs)
{
union acpi_object *info;
struct atcs_verify_interface output;
@ -664,6 +672,11 @@ bool amdgpu_acpi_is_power_shift_control_supported(void)
return amdgpu_acpi_priv.atcs.functions.power_shift_control;
}
bool amdgpu_acpi_is_set_uma_allocation_size_supported(void)
{
return amdgpu_acpi_priv.atcs.functions.set_uma_allocation_size;
}
/**
* amdgpu_acpi_pcie_notify_device_ready
*
@ -740,7 +753,8 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
size = *(u16 *) info->buffer.pointer;
if (size < 3) {
DRM_INFO("ATCS buffer is too small: %zu\n", size);
drm_info(adev_to_drm(adev),
"ATCS buffer is too small: %zu\n", size);
kfree(info);
return -EINVAL;
}
@ -799,7 +813,7 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_POWER_SHIFT_CONTROL, &params);
if (!info) {
DRM_ERROR("ATCS PSC update failed\n");
drm_err(adev_to_drm(adev), "ATCS PSC call failed\n");
return -EIO;
}
@ -904,6 +918,44 @@ static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm)
}
#endif
/**
* amdgpu_acpi_set_uma_allocation_size - Set Unified Memory Architecture allocation size via ACPI
* @adev: Pointer to the amdgpu_device structure
* @index: Index specifying the UMA allocation
* @type: Type of UMA allocation
*
* This function configures the UMA allocation size for the specified device
* using ACPI methods. The allocation is determined by the provided index and type.
* Returns 0 on success or a negative error code on failure.
*/
int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type)
{
struct atcs_set_uma_allocation_size_input atcs_input;
struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
struct acpi_buffer params;
union acpi_object *info;
if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
return -EINVAL;
atcs_input.size = sizeof(struct atcs_set_uma_allocation_size_input);
atcs_input.uma_size_index = index;
atcs_input.uma_size_type = type;
params.length = sizeof(struct atcs_set_uma_allocation_size_input);
params.pointer = &atcs_input;
info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_SET_UMA_ALLOCATION_SIZE, &params);
if (!info) {
drm_err(adev_to_drm(adev), "ATCS UMA allocation size update failed\n");
return -EIO;
}
kfree(info);
return 0;
}
/**
* amdgpu_acpi_get_node_id - obtain the NUMA node id for corresponding amdgpu
* acpi device handle
@ -1089,7 +1141,8 @@ out:
return ret;
}
static int amdgpu_acpi_enumerate_xcc(void)
static noinline_for_stack
int amdgpu_acpi_enumerate_xcc(void)
{
struct amdgpu_acpi_dev_info *dev_info = NULL;
struct amdgpu_acpi_xcc_info *xcc_info;
@ -1108,17 +1161,15 @@ static int amdgpu_acpi_enumerate_xcc(void)
* one is not found, no need to check the rest.
*/
if (!acpi_dev) {
DRM_DEBUG_DRIVER("No matching acpi device found for %s",
DRM_DEBUG_DRIVER("No matching acpi device found for %s\n",
hid);
break;
}
xcc_info = kzalloc(sizeof(struct amdgpu_acpi_xcc_info),
GFP_KERNEL);
if (!xcc_info) {
DRM_ERROR("Failed to allocate memory for xcc info\n");
if (!xcc_info)
return -ENOMEM;
}
INIT_LIST_HEAD(&xcc_info->list);
xcc_info->handle = acpi_device_handle(acpi_dev);

View file

@ -683,7 +683,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
if (ret) {
DRM_ERROR("amdgpu: failed to schedule IB.\n");
drm_err(adev_to_drm(adev), "failed to schedule IB.\n");
goto err_ib_sched;
}

View file

@ -37,7 +37,7 @@
#include "amdgpu_sync.h"
#include "amdgpu_vm.h"
#include "amdgpu_xcp.h"
#include "kfd_topology.h"
extern uint64_t amdgpu_amdkfd_total_mem_size;
enum TLB_FLUSH_TYPE {
@ -98,6 +98,7 @@ struct amdgpu_amdkfd_fence {
spinlock_t lock;
char timeline_name[TASK_COMM_LEN];
struct svm_range_bo *svm_bo;
uint16_t context_id;
};
struct amdgpu_kfd_dev {
@ -148,6 +149,8 @@ struct amdkfd_process_info {
/* MMU-notifier related fields */
struct mutex notifier_lock;
uint32_t evicted_bos;
/* kfd context id */
u16 context_id;
struct delayed_work restore_userptr_work;
struct pid *pid;
bool block_mmu_notifications;
@ -188,7 +191,8 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
struct mm_struct *mm,
struct svm_range_bo *svm_bo);
struct svm_range_bo *svm_bo,
u16 context_id);
int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev);
#if defined(CONFIG_DEBUG_FS)
@ -407,7 +411,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
int kgd2kfd_quiesce_mm(struct mm_struct *mm, uint32_t trigger);
int kgd2kfd_resume_mm(struct mm_struct *mm);
int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
struct dma_fence *fence);
u16 context_id, struct dma_fence *fence);
#if IS_ENABLED(CONFIG_HSA_AMD)
int kgd2kfd_init(void);
void kgd2kfd_exit(void);

View file

@ -62,7 +62,8 @@ static atomic_t fence_seq = ATOMIC_INIT(0);
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
struct mm_struct *mm,
struct svm_range_bo *svm_bo)
struct svm_range_bo *svm_bo,
u16 context_id)
{
struct amdgpu_amdkfd_fence *fence;
@ -76,6 +77,7 @@ struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
get_task_comm(fence->timeline_name, current);
spin_lock_init(&fence->lock);
fence->svm_bo = svm_bo;
fence->context_id = context_id;
dma_fence_init(&fence->base, &amdkfd_fence_ops, &fence->lock,
context, atomic_inc_return(&fence_seq));
@ -126,8 +128,12 @@ static bool amdkfd_fence_enable_signaling(struct dma_fence *f)
if (dma_fence_is_signaled(f))
return true;
/* if fence->svm_bo is NULL, means this fence is created through
* init_kfd_vm() or amdgpu_amdkfd_gpuvm_restore_process_bos().
* Therefore, this fence is amdgpu_amdkfd_fence->eviction_fence.
*/
if (!fence->svm_bo) {
if (!kgd2kfd_schedule_evict_and_restore_process(fence->mm, f))
if (!kgd2kfd_schedule_evict_and_restore_process(fence->mm, fence->context_id, f))
return true;
} else {
if (!svm_range_schedule_evict_svm_bo(fence))

View file

@ -0,0 +1,387 @@
/*
* Copyright 2025 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_amdkfd.h"
#include "gc/gc_12_1_0_offset.h"
#include "gc/gc_12_1_0_sh_mask.h"
#include "soc_v1_0.h"
#include <uapi/linux/kfd_ioctl.h>
static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
uint32_t queue, uint32_t vmid, uint32_t inst)
{
mutex_lock(&adev->srbm_mutex);
amdgpu_gfx_select_me_pipe_q(adev, mec, pipe, queue, vmid, inst);
}
static void unlock_srbm(struct amdgpu_device *adev, uint32_t inst)
{
amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, inst);
mutex_unlock(&adev->srbm_mutex);
}
static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
uint32_t queue_id, uint32_t inst)
{
uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(adev, mec, pipe, queue_id, 0, inst);
}
static void release_queue(struct amdgpu_device *adev, uint32_t inst)
{
unlock_srbm(adev, inst);
}
static int init_interrupts_v12_1(struct amdgpu_device *adev, uint32_t pipe_id, uint32_t inst)
{
uint32_t mec;
uint32_t pipe;
mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(adev, mec, pipe, 0, 0, inst);
WREG32_SOC15(GC, GET_INST(GC, inst), regCPC_INT_CNTL,
CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
unlock_srbm(adev, inst);
return 0;
}
static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
unsigned int engine_id,
unsigned int queue_id)
{
uint32_t sdma_engine_reg_base = 0;
uint32_t sdma_rlc_reg_offset;
uint32_t dev_inst = GET_INST(SDMA0, engine_id);
switch (dev_inst % adev->sdma.num_inst_per_xcc) {
case 0:
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA0,
dev_inst / adev->sdma.num_inst_per_xcc,
regSDMA0_SDMA_QUEUE0_RB_CNTL) - regSDMA0_SDMA_QUEUE0_RB_CNTL;
break;
case 1:
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA1,
dev_inst / adev->sdma.num_inst_per_xcc,
regSDMA1_SDMA_QUEUE0_RB_CNTL) - regSDMA0_SDMA_QUEUE0_RB_CNTL;
break;
default:
BUG();
}
sdma_rlc_reg_offset = sdma_engine_reg_base
+ queue_id * (regSDMA0_SDMA_QUEUE1_RB_CNTL - regSDMA0_SDMA_QUEUE0_RB_CNTL);
pr_debug("RLC register offset for SDMA%d RLC%d: 0x%x\n", engine_id,
queue_id, sdma_rlc_reg_offset);
return sdma_rlc_reg_offset;
}
static int hqd_dump_v12_1(struct amdgpu_device *adev,
uint32_t pipe_id, uint32_t queue_id,
uint32_t (**dump)[2], uint32_t *n_regs, uint32_t inst)
{
uint32_t i = 0, reg;
#define HQD_N_REGS 56
#define DUMP_REG(addr) do { \
if (WARN_ON_ONCE(i >= HQD_N_REGS)) \
break; \
(*dump)[i][0] = (addr) << 2; \
(*dump)[i++][1] = RREG32(addr); \
} while (0)
*dump = kmalloc(HQD_N_REGS*2*sizeof(uint32_t), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
acquire_queue(adev, pipe_id, queue_id, inst);
for (reg = SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_MQD_BASE_ADDR);
reg <= SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_HI); reg++)
DUMP_REG(reg);
release_queue(adev, inst);
WARN_ON_ONCE(i != HQD_N_REGS);
*n_regs = i;
return 0;
}
static int hqd_sdma_dump_v12_1(struct amdgpu_device *adev,
uint32_t engine_id, uint32_t queue_id,
uint32_t (**dump)[2], uint32_t *n_regs)
{
uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
engine_id, queue_id);
uint32_t i = 0, reg;
const uint32_t first_reg = regSDMA0_SDMA_QUEUE0_RB_CNTL;
const uint32_t last_reg = regSDMA0_SDMA_QUEUE0_CONTEXT_STATUS;
#undef HQD_N_REGS
#define HQD_N_REGS (last_reg - first_reg + 1)
*dump = kmalloc(HQD_N_REGS*2*sizeof(uint32_t), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
for (reg = first_reg;
reg <= last_reg; reg++)
DUMP_REG(sdma_rlc_reg_offset + reg);
WARN_ON_ONCE(i != HQD_N_REGS);
*n_regs = i;
return 0;
}
static int wave_control_execute_v12_1(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd, uint32_t inst)
{
uint32_t data = 0;
mutex_lock(&adev->grbm_idx_mutex);
WREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regGRBM_GFX_INDEX), gfx_index_val);
WREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regSQ_CMD), sq_cmd);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
INSTANCE_BROADCAST_WRITES, 1);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
SA_BROADCAST_WRITES, 1);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
SE_BROADCAST_WRITES, 1);
WREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regGRBM_GFX_INDEX), data);
mutex_unlock(&adev->grbm_idx_mutex);
return 0;
}
/* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
static uint32_t kgd_gfx_v12_1_enable_debug_trap(struct amdgpu_device *adev,
bool restore_dbg_registers,
uint32_t vmid)
{
uint32_t data = 0;
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
return data;
}
/* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
static uint32_t kgd_gfx_v12_1_disable_debug_trap(struct amdgpu_device *adev,
bool keep_trap_enabled,
uint32_t vmid)
{
uint32_t data = 0;
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
return data;
}
static int kgd_gfx_v12_1_validate_trap_override_request(struct amdgpu_device *adev,
uint32_t trap_override,
uint32_t *trap_mask_supported)
{
*trap_mask_supported &= KFD_DBG_TRAP_MASK_FP_INVALID |
KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL |
KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO |
KFD_DBG_TRAP_MASK_FP_OVERFLOW |
KFD_DBG_TRAP_MASK_FP_UNDERFLOW |
KFD_DBG_TRAP_MASK_FP_INEXACT |
KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO |
KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH |
KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION |
KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START |
KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END;
if (trap_override != KFD_DBG_TRAP_OVERRIDE_OR &&
trap_override != KFD_DBG_TRAP_OVERRIDE_REPLACE)
return -EPERM;
return 0;
}
static uint32_t trap_mask_map_sw_to_hw(uint32_t mask)
{
uint32_t trap_on_start = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START) ? 1 : 0;
uint32_t trap_on_end = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END) ? 1 : 0;
uint32_t excp_en = mask & (KFD_DBG_TRAP_MASK_FP_INVALID |
KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL |
KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO |
KFD_DBG_TRAP_MASK_FP_OVERFLOW |
KFD_DBG_TRAP_MASK_FP_UNDERFLOW |
KFD_DBG_TRAP_MASK_FP_INEXACT |
KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO |
KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH |
KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION);
uint32_t ret;
ret = REG_SET_FIELD(0, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, excp_en);
ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START, trap_on_start);
ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END, trap_on_end);
return ret;
}
static uint32_t trap_mask_map_hw_to_sw(uint32_t mask)
{
uint32_t ret = REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, EXCP_EN);
if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START))
ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START;
if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END))
ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END;
return ret;
}
/* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
static uint32_t kgd_gfx_v12_1_set_wave_launch_trap_override(struct amdgpu_device *adev,
uint32_t vmid,
uint32_t trap_override,
uint32_t trap_mask_bits,
uint32_t trap_mask_request,
uint32_t *trap_mask_prev,
uint32_t kfd_dbg_trap_cntl_prev)
{
uint32_t data = 0;
*trap_mask_prev = trap_mask_map_hw_to_sw(kfd_dbg_trap_cntl_prev);
data = (trap_mask_bits & trap_mask_request) | (*trap_mask_prev & ~trap_mask_request);
data = trap_mask_map_sw_to_hw(data);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, trap_override);
return data;
}
/* returns STALL_VMID or LAUNCH_MODE. */
static uint32_t kgd_gfx_v12_1_set_wave_launch_mode(struct amdgpu_device *adev,
uint8_t wave_launch_mode,
uint32_t vmid)
{
uint32_t data = 0;
bool is_stall_mode = wave_launch_mode == 4;
if (is_stall_mode)
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, STALL_VMID,
1);
else
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, LAUNCH_MODE,
wave_launch_mode);
return data;
}
#define TCP_WATCH_STRIDE (regTCP_WATCH1_ADDR_H - regTCP_WATCH0_ADDR_H)
static uint32_t kgd_gfx_v12_1_set_address_watch(struct amdgpu_device *adev,
uint64_t watch_address,
uint32_t watch_address_mask,
uint32_t watch_id,
uint32_t watch_mode,
uint32_t debug_vmid,
uint32_t inst)
{
uint32_t watch_address_high;
uint32_t watch_address_low;
uint32_t watch_address_cntl;
watch_address_cntl = 0;
watch_address_low = lower_32_bits(watch_address);
watch_address_high = upper_32_bits(watch_address) & 0xffff;
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
TCP_WATCH0_CNTL,
MODE,
watch_mode);
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
TCP_WATCH0_CNTL,
MASK,
watch_address_mask >> 7);
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
TCP_WATCH0_CNTL,
VALID,
1);
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regTCP_WATCH0_ADDR_H) +
(watch_id * TCP_WATCH_STRIDE)),
watch_address_high, inst);
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regTCP_WATCH0_ADDR_L) +
(watch_id * TCP_WATCH_STRIDE)),
watch_address_low, inst);
return watch_address_cntl;
}
static uint32_t kgd_gfx_v12_1_clear_address_watch(struct amdgpu_device *adev,
uint32_t watch_id)
{
return 0;
}
static uint32_t kgd_gfx_v12_1_hqd_sdma_get_doorbell(struct amdgpu_device *adev,
int engine, int queue)
{
return 0;
}
const struct kfd2kgd_calls gfx_v12_1_kfd2kgd = {
.init_interrupts = init_interrupts_v12_1,
.hqd_dump = hqd_dump_v12_1,
.hqd_sdma_dump = hqd_sdma_dump_v12_1,
.wave_control_execute = wave_control_execute_v12_1,
.get_atc_vmid_pasid_mapping_info = NULL,
.enable_debug_trap = kgd_gfx_v12_1_enable_debug_trap,
.disable_debug_trap = kgd_gfx_v12_1_disable_debug_trap,
.validate_trap_override_request = kgd_gfx_v12_1_validate_trap_override_request,
.set_wave_launch_trap_override = kgd_gfx_v12_1_set_wave_launch_trap_override,
.set_wave_launch_mode = kgd_gfx_v12_1_set_wave_launch_mode,
.set_address_watch = kgd_gfx_v12_1_set_address_watch,
.clear_address_watch = kgd_gfx_v12_1_clear_address_watch,
.hqd_sdma_get_doorbell = kgd_gfx_v12_1_hqd_sdma_get_doorbell
};

View file

@ -1397,8 +1397,10 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
struct dma_fence **ef)
{
struct amdkfd_process_info *info = NULL;
struct kfd_process *process = NULL;
int ret;
process = container_of(process_info, struct kfd_process, kgd_process_info);
if (!*process_info) {
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@ -1414,7 +1416,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
info->eviction_fence =
amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1),
current->mm,
NULL);
NULL, process->context_id);
if (!info->eviction_fence) {
pr_err("Failed to create eviction fence\n");
ret = -ENOMEM;
@ -1425,6 +1427,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
INIT_DELAYED_WORK(&info->restore_userptr_work,
amdgpu_amdkfd_restore_userptr_worker);
info->context_id = process->context_id;
*process_info = info;
}
@ -1987,7 +1991,8 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
drm_gem_object_put(&mem->bo->tbo.base);
/*
* For kgd_mem allocated in amdgpu_amdkfd_gpuvm_import_dmabuf(),
* For kgd_mem allocated in import_obj_create() via
* amdgpu_amdkfd_gpuvm_import_dmabuf_fd(),
* explicitly free it here.
*/
if (!use_release_notifier)
@ -3066,7 +3071,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
amdgpu_amdkfd_fence_create(
process_info->eviction_fence->base.context,
process_info->eviction_fence->mm,
NULL);
NULL, process_info->context_id);
if (!new_fence) {
pr_err("Failed to create eviction fence\n");

View file

@ -296,6 +296,83 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
return vram_type;
}
static int amdgpu_atomfirmware_get_uma_carveout_info_v2_3(struct amdgpu_device *adev,
union igp_info *igp_info,
struct amdgpu_uma_carveout_info *uma_info)
{
struct uma_carveout_option *opts;
uint8_t nr_uma_options;
int i;
nr_uma_options = igp_info->v23.UMACarveoutIndexMax;
if (!nr_uma_options)
return -ENODEV;
if (nr_uma_options > MAX_UMA_OPTION_ENTRIES) {
drm_dbg(adev_to_drm(adev),
"Number of UMA options exceeds max table size. Options will not be parsed");
return -EINVAL;
}
uma_info->num_entries = nr_uma_options;
uma_info->uma_option_index = igp_info->v23.UMACarveoutIndex;
opts = igp_info->v23.UMASizeControlOption;
for (i = 0; i < nr_uma_options; i++) {
if (!opts[i].memoryCarvedGb)
uma_info->entries[i].memory_carved_mb = 512;
else
uma_info->entries[i].memory_carved_mb = (uint32_t)opts[i].memoryCarvedGb << 10;
uma_info->entries[i].flags = opts[i].uma_carveout_option_flags.all8;
strscpy(uma_info->entries[i].name, opts[i].optionName, MAX_UMA_OPTION_NAME);
}
return 0;
}
int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
struct amdgpu_uma_carveout_info *uma_info)
{
struct amdgpu_mode_info *mode_info = &adev->mode_info;
union igp_info *igp_info;
u16 data_offset, size;
u8 frev, crev;
int index;
if (!(adev->flags & AMD_IS_APU))
return -ENODEV;
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
integratedsysteminfo);
if (!amdgpu_atom_parse_data_header(mode_info->atom_context,
index, &size,
&frev, &crev, &data_offset)) {
return -EINVAL;
}
igp_info = (union igp_info *)
(mode_info->atom_context->bios + data_offset);
switch (frev) {
case 2:
switch (crev) {
case 3:
return amdgpu_atomfirmware_get_uma_carveout_info_v2_3(adev, igp_info, uma_info);
break;
default:
break;
}
break;
default:
break;
}
return -ENODEV;
}
int
amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
int *vram_width, int *vram_type,

View file

@ -32,6 +32,8 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
int *vram_width, int *vram_type, int *vram_vendor);
int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
struct amdgpu_uma_carveout_info *uma_info);
int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev);

View file

@ -37,9 +37,9 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
stime = ktime_get();
for (i = 0; i < n; i++) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
false, false, 0);
r = amdgpu_copy_buffer(adev, &adev->mman.default_entity,
saddr, daddr, size, NULL, &fence,
false, 0);
if (r)
goto exit_do_move;
r = dma_fence_wait(fence, false);
@ -66,7 +66,7 @@ static void amdgpu_benchmark_log_results(struct amdgpu_device *adev,
throughput = div64_s64(throughput, time_ms);
dev_info(adev->dev, "amdgpu: %s %u bo moves of %u kB from"
dev_info(adev->dev, " %s %u bo moves of %u kB from"
" %d to %d in %lld ms, throughput: %lld Mb/s or %lld MB/s\n",
kind, n, size >> 10, sdomain, ddomain, time_ms,
throughput * 8, throughput);

View file

@ -349,7 +349,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
strscpy(fw_name, "amdgpu/vega20_smc.bin");
break;
default:
DRM_ERROR("SMC firmware not supported\n");
drm_err(adev_to_drm(adev), "SMC firmware not supported\n");
return -EINVAL;
}
@ -357,7 +357,8 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
AMDGPU_UCODE_REQUIRED,
"%s", fw_name);
if (err) {
DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
drm_err(adev_to_drm(adev),
"Failed to load firmware \"%s\"\n", fw_name);
amdgpu_ucode_release(&adev->pm.fw);
return err;
}
@ -402,7 +403,7 @@ struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
kmalloc(sizeof(*cgs_device), GFP_KERNEL);
if (!cgs_device) {
DRM_ERROR("Couldn't allocate CGS device structure\n");
drm_err(adev_to_drm(adev), "Couldn't allocate CGS device structure\n");
return NULL;
}

View file

@ -877,8 +877,9 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
connector->name);
drm_err(connector->dev,
"%s: probed a monitor but no|invalid EDID\n",
connector->name);
ret = connector_status_connected;
} else {
amdgpu_connector->use_digital =
@ -1056,7 +1057,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
drm_err(adev_to_drm(adev), "%s: probed a monitor but no|invalid EDID\n",
connector->name);
ret = connector_status_connected;
broken_edid = true; /* defer use_digital to later */
@ -1667,7 +1668,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (router->ddc_valid || router->cd_valid) {
amdgpu_connector->router_bus = amdgpu_i2c_lookup(adev, &router->i2c_info);
if (!amdgpu_connector->router_bus)
DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"Failed to assign router i2c bus! Check dmesg for i2c errors.\n");
}
if (is_dp_bridge) {
@ -1681,7 +1683,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
has_aux = true;
ddc = &amdgpu_connector->ddc_bus->adapter;
} else {
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
}
switch (connector_type) {
@ -1775,7 +1778,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (i2c_bus->valid) {
amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
if (!amdgpu_connector->ddc_bus)
DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
else
ddc = &amdgpu_connector->ddc_bus->adapter;
}
@ -1800,7 +1804,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (i2c_bus->valid) {
amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
if (!amdgpu_connector->ddc_bus)
DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
else
ddc = &amdgpu_connector->ddc_bus->adapter;
}
@ -1830,7 +1835,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (i2c_bus->valid) {
amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
if (!amdgpu_connector->ddc_bus)
DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
else
ddc = &amdgpu_connector->ddc_bus->adapter;
}
@ -1886,7 +1892,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (i2c_bus->valid) {
amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
if (!amdgpu_connector->ddc_bus)
DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
else
ddc = &amdgpu_connector->ddc_bus->adapter;
}
@ -1937,7 +1944,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
has_aux = true;
ddc = &amdgpu_connector->ddc_bus->adapter;
} else {
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
}
drm_connector_init_with_ddc(dev, &amdgpu_connector->base,
@ -1985,7 +1993,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
has_aux = true;
ddc = &amdgpu_connector->ddc_bus->adapter;
} else {
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"eDP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
}
drm_connector_init_with_ddc(dev, &amdgpu_connector->base,
@ -2008,7 +2017,8 @@ amdgpu_connector_add(struct amdgpu_device *adev,
if (i2c_bus->valid) {
amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
if (!amdgpu_connector->ddc_bus)
DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
drm_err(adev_to_drm(adev),
"LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
else
ddc = &amdgpu_connector->ddc_bus->adapter;
}

View file

@ -23,6 +23,7 @@
*/
#include <linux/list.h>
#include "amdgpu.h"
#include "amdgpu_ras_mgr.h"
static const guid_t MCE = CPER_NOTIFY_MCE;
static const guid_t CMC = CPER_NOTIFY_CMC;
@ -559,7 +560,10 @@ int amdgpu_cper_init(struct amdgpu_device *adev)
{
int r;
if (!amdgpu_aca_is_enabled(adev) && !amdgpu_sriov_ras_cper_en(adev))
if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_ras_cper_en(adev))
return 0;
else if (!amdgpu_sriov_vf(adev) && !amdgpu_uniras_enabled(adev) &&
!amdgpu_aca_is_enabled(adev))
return 0;
r = amdgpu_cper_ring_init(adev);

View file

@ -1021,6 +1021,7 @@ static int amdgpu_cs_patch_ibs(struct amdgpu_cs_parser *p,
struct amdgpu_job *job)
{
struct amdgpu_ring *ring = amdgpu_job_ring(job);
struct amdgpu_device *adev = ring->adev;
unsigned int i;
int r;

View file

@ -76,7 +76,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
drm_exec_retry_on_contention(&exec);
if (unlikely(r)) {
DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
drm_err(adev_to_drm(adev),
"failed to reserve CSA,PD BOs: err=%d\n", r);
goto error;
}
}
@ -92,7 +93,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
AMDGPU_PTE_EXECUTABLE);
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
drm_err(adev_to_drm(adev),
"failed to do bo_map on static CSA, err=%d\n", r);
amdgpu_vm_bo_del(adev, *bo_va);
goto error;
}
@ -116,14 +118,16 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
drm_exec_retry_on_contention(&exec);
if (unlikely(r)) {
DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
drm_err(adev_to_drm(adev),
"failed to reserve CSA,PD BOs: err=%d\n", r);
goto error;
}
}
r = amdgpu_vm_bo_unmap(adev, bo_va, csa_addr);
if (r) {
DRM_ERROR("failed to do bo_unmap on static CSA, err=%d\n", r);
drm_err(adev_to_drm(adev),
"failed to do bo_unmap on static CSA, err=%d\n", r);
goto error;
}

View file

@ -438,18 +438,21 @@ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
struct drm_sched_entity *ctx_entity;
if (hw_ip >= AMDGPU_HW_IP_NUM) {
DRM_ERROR("unknown HW IP type: %d\n", hw_ip);
drm_err(adev_to_drm(ctx->mgr->adev),
"unknown HW IP type: %d\n", hw_ip);
return -EINVAL;
}
/* Right now all IPs have only one instance - multiple rings. */
if (instance != 0) {
DRM_DEBUG("invalid ip instance: %d\n", instance);
drm_dbg(adev_to_drm(ctx->mgr->adev),
"invalid ip instance: %d\n", instance);
return -EINVAL;
}
if (ring >= amdgpu_ctx_num_entities[hw_ip]) {
DRM_DEBUG("invalid ring: %d %d\n", hw_ip, ring);
drm_dbg(adev_to_drm(ctx->mgr->adev),
"invalid ring: %d %d\n", hw_ip, ring);
return -EINVAL;
}
@ -874,7 +877,8 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
r = dma_fence_wait(other, true);
if (r < 0 && r != -ERESTARTSYS)
DRM_ERROR("Error (%ld) waiting for fence!\n", r);
drm_err(adev_to_drm(ctx->mgr->adev),
"AMDGPU: Error waiting for fence in ctx %p\n", ctx);
dma_fence_put(other);
return r;
@ -929,7 +933,7 @@ static void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
idr_for_each_entry(idp, ctx, id) {
if (kref_read(&ctx->refcount) != 1) {
DRM_ERROR("ctx %p is still alive\n", ctx);
drm_err(adev_to_drm(mgr->adev), "ctx %p is still alive\n", ctx);
continue;
}

View file

@ -1921,7 +1921,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
/* preempt the IB */
r = amdgpu_ring_preempt_ib(ring);
if (r) {
DRM_WARN("failed to preempt ring %d\n", ring->idx);
drm_warn(adev_to_drm(adev), "failed to preempt ring %d\n", ring->idx);
goto failure;
}
@ -1929,7 +1929,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
if (atomic_read(&ring->fence_drv.last_seq) !=
ring->fence_drv.sync_seq) {
DRM_INFO("ring %d was preempted\n", ring->idx);
drm_info(adev_to_drm(adev), "ring %d was preempted\n", ring->idx);
amdgpu_ib_preempt_mark_partial_job(ring);
@ -2016,14 +2016,16 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
&fops_ib_preempt);
if (IS_ERR(ent)) {
DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
drm_err(adev_to_drm(adev),
"unable to create amdgpu_preempt_ib debugsfs file\n");
return PTR_ERR(ent);
}
ent = debugfs_create_file("amdgpu_force_sclk", 0200, root, adev,
&fops_sclk_set);
if (IS_ERR(ent)) {
DRM_ERROR("unable to create amdgpu_set_sclk debugsfs file\n");
drm_err(adev_to_drm(adev),
"unable to create amdgpu_set_sclk debugsfs file\n");
return PTR_ERR(ent);
}
@ -2036,7 +2038,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
r = amdgpu_debugfs_regs_init(adev);
if (r)
DRM_ERROR("registering register debugfs failed (%d).\n", r);
drm_err(adev_to_drm(adev), "registering register debugfs failed (%d).\n", r);
amdgpu_debugfs_firmware_init(adev);
amdgpu_ta_if_debugfs_init(adev);

View file

@ -333,11 +333,8 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
struct drm_sched_job *s_job;
coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT);
if (!coredump) {
DRM_ERROR("%s: failed to allocate memory for coredump\n", __func__);
if (!coredump)
return;
}
coredump->skip_vram_check = skip_vram_check;
coredump->reset_vram_lost = vram_lost;

View file

@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/pci-p2pdma.h>
#include <linux/apple-gmux.h>
#include <linux/nospec.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_client_event.h>
@ -313,42 +314,6 @@ void amdgpu_reg_state_sysfs_fini(struct amdgpu_device *adev)
sysfs_remove_bin_file(&adev->dev->kobj, &bin_attr_reg_state);
}
int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block)
{
int r;
if (ip_block->version->funcs->suspend) {
r = ip_block->version->funcs->suspend(ip_block);
if (r) {
dev_err(ip_block->adev->dev,
"suspend of IP block <%s> failed %d\n",
ip_block->version->funcs->name, r);
return r;
}
}
ip_block->status.hw = false;
return 0;
}
int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block)
{
int r;
if (ip_block->version->funcs->resume) {
r = ip_block->version->funcs->resume(ip_block);
if (r) {
dev_err(ip_block->adev->dev,
"resume of IP block <%s> failed %d\n",
ip_block->version->funcs->name, r);
return r;
}
}
ip_block->status.hw = true;
return 0;
}
/**
* DOC: board_info
*
@ -417,6 +382,175 @@ static const struct attribute_group amdgpu_board_attrs_group = {
.is_visible = amdgpu_board_attrs_is_visible
};
/**
* DOC: uma/carveout_options
*
* This is a read-only file that lists all available UMA allocation
* options and their corresponding indices. Example output::
*
* $ cat uma/carveout_options
* 0: Minimum (512 MB)
* 1: (1 GB)
* 2: (2 GB)
* 3: (4 GB)
* 4: (6 GB)
* 5: (8 GB)
* 6: (12 GB)
* 7: Medium (16 GB)
* 8: (24 GB)
* 9: High (32 GB)
*/
static ssize_t carveout_options_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
uint32_t memory_carved;
ssize_t size = 0;
if (!uma_info || !uma_info->num_entries)
return -ENODEV;
for (int i = 0; i < uma_info->num_entries; i++) {
memory_carved = uma_info->entries[i].memory_carved_mb;
if (memory_carved >= SZ_1G/SZ_1M) {
size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n",
i,
uma_info->entries[i].name,
memory_carved >> 10);
} else {
size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n",
i,
uma_info->entries[i].name,
memory_carved);
}
}
return size;
}
static DEVICE_ATTR_RO(carveout_options);
/**
* DOC: uma/carveout
*
* This file is both readable and writable. When read, it shows the
* index of the current setting. Writing a valid index to this file
* allows users to change the UMA carveout size to the selected option
* on the next boot.
*
* The available options and their corresponding indices can be read
* from the uma/carveout_options file.
*/
static ssize_t carveout_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index);
}
static ssize_t carveout_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
struct amdgpu_uma_carveout_option *opt;
unsigned long val;
uint8_t flags;
int r;
r = kstrtoul(buf, 10, &val);
if (r)
return r;
if (val >= uma_info->num_entries)
return -EINVAL;
val = array_index_nospec(val, uma_info->num_entries);
opt = &uma_info->entries[val];
if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) &&
!(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) {
drm_err_once(ddev, "Option %lu not supported due to lack of Custom/Auto flag", val);
return -EINVAL;
}
flags = opt->flags;
flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1);
guard(mutex)(&uma_info->update_lock);
r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags);
if (r)
return r;
uma_info->uma_option_index = val;
return count;
}
static DEVICE_ATTR_RW(carveout);
static struct attribute *amdgpu_uma_attrs[] = {
&dev_attr_carveout.attr,
&dev_attr_carveout_options.attr,
NULL
};
const struct attribute_group amdgpu_uma_attr_group = {
.name = "uma",
.attrs = amdgpu_uma_attrs
};
static void amdgpu_uma_sysfs_init(struct amdgpu_device *adev)
{
int rc;
if (!(adev->flags & AMD_IS_APU))
return;
if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
return;
rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev->uma_info);
if (rc) {
drm_dbg(adev_to_drm(adev),
"Failed to parse UMA carveout info from VBIOS: %d\n", rc);
goto out_info;
}
mutex_init(&adev->uma_info.update_lock);
rc = devm_device_add_group(adev->dev, &amdgpu_uma_attr_group);
if (rc) {
drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout sysfs interfaces %d\n", rc);
goto out_attr;
}
return;
out_attr:
mutex_destroy(&adev->uma_info.update_lock);
out_info:
return;
}
static void amdgpu_uma_sysfs_fini(struct amdgpu_device *adev)
{
struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
return;
mutex_destroy(&uma_info->update_lock);
uma_info->num_entries = 0;
}
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
/**
@ -2263,293 +2397,6 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
.can_switch = amdgpu_switcheroo_can_switch,
};
/**
* amdgpu_device_ip_set_clockgating_state - set the CG state
*
* @dev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: clockgating state (gate or ungate)
*
* Sets the requested clockgating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_clockgating_state(void *dev,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state)
{
struct amdgpu_device *adev = dev;
int i, r = 0;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type != block_type)
continue;
if (!adev->ip_blocks[i].version->funcs->set_clockgating_state)
continue;
r = adev->ip_blocks[i].version->funcs->set_clockgating_state(
&adev->ip_blocks[i], state);
if (r)
dev_err(adev->dev,
"set_clockgating_state of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
return r;
}
/**
* amdgpu_device_ip_set_powergating_state - set the PG state
*
* @dev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: powergating state (gate or ungate)
*
* Sets the requested powergating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_powergating_state(void *dev,
enum amd_ip_block_type block_type,
enum amd_powergating_state state)
{
struct amdgpu_device *adev = dev;
int i, r = 0;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type != block_type)
continue;
if (!adev->ip_blocks[i].version->funcs->set_powergating_state)
continue;
r = adev->ip_blocks[i].version->funcs->set_powergating_state(
&adev->ip_blocks[i], state);
if (r)
dev_err(adev->dev,
"set_powergating_state of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
return r;
}
/**
* amdgpu_device_ip_get_clockgating_state - get the CG state
*
* @adev: amdgpu_device pointer
* @flags: clockgating feature flags
*
* Walks the list of IPs on the device and updates the clockgating
* flags for each IP.
* Updates @flags with the feature flags for each hardware IP where
* clockgating is enabled.
*/
void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->funcs->get_clockgating_state)
adev->ip_blocks[i].version->funcs->get_clockgating_state(
&adev->ip_blocks[i], flags);
}
}
/**
* amdgpu_device_ip_wait_for_idle - wait for idle
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Waits for the request hardware IP to be idle.
* Returns 0 for success or a negative error code on failure.
*/
int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
int i, r;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type == block_type) {
if (adev->ip_blocks[i].version->funcs->wait_for_idle) {
r = adev->ip_blocks[i].version->funcs->wait_for_idle(
&adev->ip_blocks[i]);
if (r)
return r;
}
break;
}
}
return 0;
}
/**
* amdgpu_device_ip_is_hw - is the hardware IP enabled
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Check if the hardware IP is enable or not.
* Returns true if it the IP is enable, false if not.
*/
bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (adev->ip_blocks[i].version->type == block_type)
return adev->ip_blocks[i].status.hw;
}
return false;
}
/**
* amdgpu_device_ip_is_valid - is the hardware IP valid
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Check if the hardware IP is valid or not.
* Returns true if it the IP is valid, false if not.
*/
bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (adev->ip_blocks[i].version->type == block_type)
return adev->ip_blocks[i].status.valid;
}
return false;
}
/**
* amdgpu_device_ip_get_ip_block - get a hw IP pointer
*
* @adev: amdgpu_device pointer
* @type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Returns a pointer to the hardware IP block structure
* if it exists for the asic, otherwise NULL.
*/
struct amdgpu_ip_block *
amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev,
enum amd_ip_block_type type)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++)
if (adev->ip_blocks[i].version->type == type)
return &adev->ip_blocks[i];
return NULL;
}
/**
* amdgpu_device_ip_block_version_cmp
*
* @adev: amdgpu_device pointer
* @type: enum amd_ip_block_type
* @major: major version
* @minor: minor version
*
* return 0 if equal or greater
* return 1 if smaller or the ip_block doesn't exist
*/
int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev,
enum amd_ip_block_type type,
u32 major, u32 minor)
{
struct amdgpu_ip_block *ip_block = amdgpu_device_ip_get_ip_block(adev, type);
if (ip_block && ((ip_block->version->major > major) ||
((ip_block->version->major == major) &&
(ip_block->version->minor >= minor))))
return 0;
return 1;
}
static const char *ip_block_names[] = {
[AMD_IP_BLOCK_TYPE_COMMON] = "common",
[AMD_IP_BLOCK_TYPE_GMC] = "gmc",
[AMD_IP_BLOCK_TYPE_IH] = "ih",
[AMD_IP_BLOCK_TYPE_SMC] = "smu",
[AMD_IP_BLOCK_TYPE_PSP] = "psp",
[AMD_IP_BLOCK_TYPE_DCE] = "dce",
[AMD_IP_BLOCK_TYPE_GFX] = "gfx",
[AMD_IP_BLOCK_TYPE_SDMA] = "sdma",
[AMD_IP_BLOCK_TYPE_UVD] = "uvd",
[AMD_IP_BLOCK_TYPE_VCE] = "vce",
[AMD_IP_BLOCK_TYPE_ACP] = "acp",
[AMD_IP_BLOCK_TYPE_VCN] = "vcn",
[AMD_IP_BLOCK_TYPE_MES] = "mes",
[AMD_IP_BLOCK_TYPE_JPEG] = "jpeg",
[AMD_IP_BLOCK_TYPE_VPE] = "vpe",
[AMD_IP_BLOCK_TYPE_UMSCH_MM] = "umsch_mm",
[AMD_IP_BLOCK_TYPE_ISP] = "isp",
[AMD_IP_BLOCK_TYPE_RAS] = "ras",
};
static const char *ip_block_name(struct amdgpu_device *adev, enum amd_ip_block_type type)
{
int idx = (int)type;
return idx < ARRAY_SIZE(ip_block_names) ? ip_block_names[idx] : "unknown";
}
/**
* amdgpu_device_ip_block_add
*
* @adev: amdgpu_device pointer
* @ip_block_version: pointer to the IP to add
*
* Adds the IP block driver information to the collection of IPs
* on the asic.
*/
int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
const struct amdgpu_ip_block_version *ip_block_version)
{
if (!ip_block_version)
return -EINVAL;
switch (ip_block_version->type) {
case AMD_IP_BLOCK_TYPE_VCN:
if (adev->harvest_ip_mask & AMD_HARVEST_IP_VCN_MASK)
return 0;
break;
case AMD_IP_BLOCK_TYPE_JPEG:
if (adev->harvest_ip_mask & AMD_HARVEST_IP_JPEG_MASK)
return 0;
break;
default:
break;
}
dev_info(adev->dev, "detected ip block number %d <%s_v%d_%d_%d> (%s)\n",
adev->num_ip_blocks,
ip_block_name(adev, ip_block_version->type),
ip_block_version->major,
ip_block_version->minor,
ip_block_version->rev,
ip_block_version->funcs->name);
adev->ip_blocks[adev->num_ip_blocks].adev = adev;
adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version;
return 0;
}
/**
* amdgpu_device_enable_virtual_display - enable virtual display feature
*
@ -3309,19 +3156,18 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (r)
goto init_failed;
if (adev->mman.buffer_funcs_ring->sched.ready)
if (adev->mman.buffer_funcs_ring &&
adev->mman.buffer_funcs_ring->sched.ready)
amdgpu_ttm_set_buffer_funcs_status(adev, true);
/* Don't init kfd if whole hive need to be reset during init */
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
kgd2kfd_init_zone_device(adev);
amdgpu_amdkfd_device_init(adev);
}
amdgpu_fru_get_product_info(adev);
if (!amdgpu_sriov_vf(adev) || amdgpu_sriov_ras_cper_en(adev))
r = amdgpu_cper_init(adev);
r = amdgpu_cper_init(adev);
init_failed:
@ -4491,6 +4337,7 @@ static int amdgpu_device_sys_interface_init(struct amdgpu_device *adev)
amdgpu_fru_sysfs_init(adev);
amdgpu_reg_state_sysfs_init(adev);
amdgpu_xcp_sysfs_init(adev);
amdgpu_uma_sysfs_init(adev);
return r;
}
@ -4506,6 +4353,7 @@ static void amdgpu_device_sys_interface_fini(struct amdgpu_device *adev)
amdgpu_reg_state_sysfs_fini(adev);
amdgpu_xcp_sysfs_fini(adev);
amdgpu_uma_sysfs_fini(adev);
}
/**
@ -4931,8 +4779,15 @@ fence_driver_init:
flush_delayed_work(&adev->delayed_init_work);
}
/* Don't init kfd if whole hive need to be reset during init */
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
kgd2kfd_init_zone_device(adev);
kfd_update_svm_support_properties(adev);
}
if (adev->init_lvl->level == AMDGPU_INIT_LEVEL_MINIMAL_XGMI)
amdgpu_xgmi_reset_on_init(adev);
/*
* Place those sysfs registering after `late_init`. As some of those
* operations performed in `late_init` might affect the sysfs
@ -5030,7 +4885,7 @@ static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev)
*/
void amdgpu_device_fini_hw(struct amdgpu_device *adev)
{
dev_info(adev->dev, "amdgpu: finishing device.\n");
dev_info(adev->dev, "finishing device.\n");
flush_delayed_work(&adev->delayed_init_work);
if (adev->mman.initialized)
@ -5064,6 +4919,14 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
amdgpu_ttm_set_buffer_funcs_status(adev, false);
/*
* device went through surprise hotplug; we need to destroy topology
* before ip_fini_early to prevent kfd locking refcount issues by calling
* amdgpu_amdkfd_suspend()
*/
if (drm_dev_is_unplugged(adev_to_drm(adev)))
amdgpu_amdkfd_device_fini_sw(adev);
amdgpu_device_ip_fini_early(adev);
amdgpu_irq_fini_hw(adev);
@ -5867,6 +5730,9 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
if (ret)
goto mode1_reset_failed;
/* enable mmio access after mode 1 reset completed */
adev->no_hw_access = false;
amdgpu_device_load_pci_state(adev->pdev);
ret = amdgpu_psp_wait_for_bootloader(adev);
if (ret)
@ -6541,7 +6407,7 @@ static int amdgpu_device_sched_resume(struct list_head *device_list,
!amdgpu_ras_eeprom_check_err_threshold(tmp_adev))
dev_info(
tmp_adev->dev,
"GPU reset(%d) failed with error %d \n",
"GPU reset(%d) failed with error %d\n",
atomic_read(
&tmp_adev->gpu_reset_counter),
tmp_adev->asic_reset_res);
@ -6683,7 +6549,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
*
* job->base holds a reference to parent fence
*/
if (job && dma_fence_is_signaled(&job->hw_fence->base)) {
if (job && (dma_fence_get_status(&job->hw_fence->base) > 0)) {
job_signaled = true;
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
goto skip_hw_reset;

View file

@ -71,6 +71,7 @@
#include "nv.h"
#include "soc21.h"
#include "soc24.h"
#include "soc_v1_0.h"
#include "navi10_ih.h"
#include "ih_v6_0.h"
#include "ih_v6_1.h"
@ -78,10 +79,12 @@
#include "gfx_v10_0.h"
#include "gfx_v11_0.h"
#include "gfx_v12_0.h"
#include "gfx_v12_1.h"
#include "sdma_v5_0.h"
#include "sdma_v5_2.h"
#include "sdma_v6_0.h"
#include "sdma_v7_0.h"
#include "sdma_v7_1.h"
#include "lsdma_v6_0.h"
#include "lsdma_v7_0.h"
#include "vcn_v2_0.h"
@ -97,16 +100,21 @@
#include "amdgpu_vkms.h"
#include "mes_v11_0.h"
#include "mes_v12_0.h"
#include "mes_v12_1.h"
#include "smuio_v11_0.h"
#include "smuio_v11_0_6.h"
#include "smuio_v13_0.h"
#include "smuio_v13_0_3.h"
#include "smuio_v13_0_6.h"
#include "smuio_v14_0_2.h"
#include "smuio_v15_0_0.h"
#include "smuio_v15_0_8.h"
#include "vcn_v5_0_0.h"
#include "vcn_v5_0_1.h"
#include "jpeg_v5_0_0.h"
#include "jpeg_v5_0_1.h"
#include "jpeg_v5_3_0.h"
#include "amdgpu_ras_mgr.h"
#include "amdgpu_vpe.h"
@ -209,6 +217,8 @@ static const char *hw_id_names[HW_ID_MAX] = {
[XGBE_HWID] = "XGBE",
[MP0_HWID] = "MP0",
[VPE_HWID] = "VPE",
[ATU_HWID] = "ATU",
[AIGC_HWID] = "AIGC",
};
static int hw_id_map[MAX_HWIP] = {
@ -240,6 +250,7 @@ static int hw_id_map[MAX_HWIP] = {
[PCIE_HWIP] = PCIE_HWID,
[VPE_HWIP] = VPE_HWID,
[ISP_HWIP] = ISP_HWID,
[ATU_HWIP] = ATU_HWID,
};
static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev, uint8_t *binary)
@ -1980,12 +1991,16 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
amdgpu_device_ip_block_add(adev, &soc24_common_ip_block);
break;
case IP_VERSION(12, 1, 0):
amdgpu_device_ip_block_add(adev, &soc_v1_0_common_ip_block);
break;
default:
dev_err(adev->dev,
"Failed to add common ip block(GC_HWIP:0x%x)\n",
@ -2036,10 +2051,12 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
case IP_VERSION(12, 1, 0):
amdgpu_device_ip_block_add(adev, &gmc_v12_0_ip_block);
break;
default:
@ -2081,9 +2098,11 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &ih_v6_0_ip_block);
break;
case IP_VERSION(6, 1, 0):
case IP_VERSION(6, 1, 1):
amdgpu_device_ip_block_add(adev, &ih_v6_1_ip_block);
break;
case IP_VERSION(7, 0, 0):
case IP_VERSION(7, 1, 0):
amdgpu_device_ip_block_add(adev, &ih_v7_0_ip_block);
break;
default:
@ -2150,6 +2169,12 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(14, 0, 5):
amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);
break;
case IP_VERSION(15, 0, 0):
amdgpu_device_ip_block_add(adev, &psp_v15_0_ip_block);
break;
case IP_VERSION(15, 0, 8):
amdgpu_device_ip_block_add(adev, &psp_v15_0_8_ip_block);
break;
default:
dev_err(adev->dev,
"Failed to add psp ip block(MP0_HWIP:0x%x)\n",
@ -2213,6 +2238,9 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(14, 0, 5):
amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block);
break;
case IP_VERSION(15, 0, 0):
amdgpu_device_ip_block_add(adev, &smu_v15_0_ip_block);
break;
default:
dev_err(adev->dev,
"Failed to add smu ip block(MP1_HWIP:0x%x)\n",
@ -2342,12 +2370,16 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
amdgpu_device_ip_block_add(adev, &gfx_v12_0_ip_block);
break;
case IP_VERSION(12, 1, 0):
amdgpu_device_ip_block_add(adev, &gfx_v12_1_ip_block);
break;
default:
dev_err(adev->dev, "Failed to add gfx ip block(GC_HWIP:0x%x)\n",
amdgpu_ip_version(adev, GC_HWIP, 0));
@ -2398,12 +2430,16 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(6, 1, 1):
case IP_VERSION(6, 1, 2):
case IP_VERSION(6, 1, 3):
case IP_VERSION(6, 1, 4):
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
break;
case IP_VERSION(7, 0, 0):
case IP_VERSION(7, 0, 1):
amdgpu_device_ip_block_add(adev, &sdma_v7_0_ip_block);
break;
case IP_VERSION(7, 1, 0):
amdgpu_device_ip_block_add(adev, &sdma_v7_1_ip_block);
break;
default:
dev_err(adev->dev,
"Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n",
@ -2511,6 +2547,10 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &vcn_v5_0_0_ip_block);
amdgpu_device_ip_block_add(adev, &jpeg_v5_0_0_ip_block);
break;
case IP_VERSION(5, 3, 0):
amdgpu_device_ip_block_add(adev, &vcn_v5_0_0_ip_block);
amdgpu_device_ip_block_add(adev, &jpeg_v5_3_0_ip_block);
break;
case IP_VERSION(5, 0, 1):
amdgpu_device_ip_block_add(adev, &vcn_v5_0_1_ip_block);
amdgpu_device_ip_block_add(adev, &jpeg_v5_0_1_ip_block);
@ -2537,6 +2577,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
adev->enable_mes = true;
adev->enable_mes_kiq = true;
@ -2549,6 +2590,13 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
if (amdgpu_uni_mes)
adev->enable_uni_mes = true;
break;
case IP_VERSION(12, 1, 0):
amdgpu_device_ip_block_add(adev, &mes_v12_1_ip_block);
adev->enable_mes = true;
adev->enable_mes_kiq = true;
if (amdgpu_uni_mes)
adev->enable_uni_mes = true;
break;
default:
break;
}
@ -2563,6 +2611,9 @@ static void amdgpu_discovery_init_soc_config(struct amdgpu_device *adev)
case IP_VERSION(9, 5, 0):
aqua_vanjaram_init_soc_config(adev);
break;
case IP_VERSION(12, 1, 0):
soc_v1_0_init_soc_config(adev);
break;
default:
break;
}
@ -2929,10 +2980,12 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
adev->family = AMDGPU_FAMILY_GC_11_5_0;
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
case IP_VERSION(12, 1, 0):
adev->family = AMDGPU_FAMILY_GC_12_0_0;
break;
default:
@ -2955,6 +3008,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
adev->flags |= AMD_IS_APU;
break;
default:
@ -3025,6 +3079,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
adev->nbio.hdp_flush_reg = &nbio_v7_7_hdp_flush_reg;
break;
case IP_VERSION(6, 3, 1):
case IP_VERSION(7, 11, 4):
adev->nbio.funcs = &nbif_v6_3_1_funcs;
adev->nbio.hdp_flush_reg = &nbif_v6_3_1_hdp_flush_reg;
break;
@ -3059,6 +3114,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, 1, 0):
case IP_VERSION(6, 1, 1):
adev->hdp.funcs = &hdp_v6_0_funcs;
break;
case IP_VERSION(7, 0, 0):
@ -3140,6 +3196,12 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(14, 0, 2):
adev->smuio.funcs = &smuio_v14_0_2_funcs;
break;
case IP_VERSION(15, 0, 0):
adev->smuio.funcs = &smuio_v15_0_0_funcs;
break;
case IP_VERSION(15, 0, 8):
adev->smuio.funcs = &smuio_v15_0_8_funcs;
break;
default:
break;
}
@ -3210,8 +3272,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
return r;
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
!amdgpu_sriov_vf(adev)) ||
(adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO && amdgpu_dpm == 1)) {
!amdgpu_sriov_vf(adev) &&
amdgpu_dpm == 1) ||
(adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO &&
amdgpu_dpm == 1)) {
r = amdgpu_discovery_set_smu_ip_blocks(adev);
if (r)
return r;

View file

@ -415,15 +415,15 @@ void amdgpu_display_print_display_setup(struct drm_device *dev)
int i = 0;
drm_connector_list_iter_begin(dev, &iter);
DRM_INFO("AMDGPU Display Connectors\n");
drm_info(dev, "AMDGPU Display Connectors\n");
drm_for_each_connector_iter(connector, &iter) {
amdgpu_connector = to_amdgpu_connector(connector);
DRM_INFO("Connector %d:\n", i);
DRM_INFO(" %s\n", connector->name);
drm_info(dev, "Connector %d:\n", i);
drm_info(dev, " %s\n", connector->name);
if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE)
DRM_INFO(" %s\n", hpd_names[amdgpu_connector->hpd.hpd]);
drm_info(dev, " %s\n", hpd_names[amdgpu_connector->hpd.hpd]);
if (amdgpu_connector->ddc_bus) {
DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
drm_info(dev, " DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
amdgpu_connector->ddc_bus->rec.mask_clk_reg,
amdgpu_connector->ddc_bus->rec.mask_data_reg,
amdgpu_connector->ddc_bus->rec.a_clk_reg,
@ -433,11 +433,11 @@ void amdgpu_display_print_display_setup(struct drm_device *dev)
amdgpu_connector->ddc_bus->rec.y_clk_reg,
amdgpu_connector->ddc_bus->rec.y_data_reg);
if (amdgpu_connector->router.ddc_valid)
DRM_INFO(" DDC Router 0x%x/0x%x\n",
drm_info(dev, " DDC Router 0x%x/0x%x\n",
amdgpu_connector->router.ddc_mux_control_pin,
amdgpu_connector->router.ddc_mux_state);
if (amdgpu_connector->router.cd_valid)
DRM_INFO(" Clock/Data Router 0x%x/0x%x\n",
drm_info(dev, " Clock/Data Router 0x%x/0x%x\n",
amdgpu_connector->router.cd_mux_control_pin,
amdgpu_connector->router.cd_mux_state);
} else {
@ -447,35 +447,35 @@ void amdgpu_display_print_display_setup(struct drm_device *dev)
connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
drm_info(dev, " DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
}
DRM_INFO(" Encoders:\n");
drm_info(dev, " Encoders:\n");
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
amdgpu_encoder = to_amdgpu_encoder(encoder);
devices = amdgpu_encoder->devices & amdgpu_connector->devices;
if (devices) {
if (devices & ATOM_DEVICE_CRT1_SUPPORT)
DRM_INFO(" CRT1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " CRT1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_CRT2_SUPPORT)
DRM_INFO(" CRT2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " CRT2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_LCD1_SUPPORT)
DRM_INFO(" LCD1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " LCD1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP1_SUPPORT)
DRM_INFO(" DFP1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP2_SUPPORT)
DRM_INFO(" DFP2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP3_SUPPORT)
DRM_INFO(" DFP3: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP3: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP4_SUPPORT)
DRM_INFO(" DFP4: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP4: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP5_SUPPORT)
DRM_INFO(" DFP5: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP5: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_DFP6_SUPPORT)
DRM_INFO(" DFP6: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " DFP6: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_TV1_SUPPORT)
DRM_INFO(" TV1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " TV1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
if (devices & ATOM_DEVICE_CV_SUPPORT)
DRM_INFO(" CV: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
drm_info(dev, " CV: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
}
}
i++;
@ -1880,7 +1880,12 @@ int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
struct drm_scanout_buffer *sb)
{
struct amdgpu_bo *abo;
struct drm_framebuffer *fb = plane->state->fb;
struct drm_framebuffer *fb;
if (drm_drv_uses_atomic_modeset(plane->dev))
fb = plane->state->fb;
else
fb = plane->fb;
if (!fb)
return -EINVAL;

View file

@ -37,6 +37,7 @@
#include "amdgpu_dma_buf.h"
#include "amdgpu_xgmi.h"
#include "amdgpu_vm.h"
#include "amdgpu_ttm.h"
#include <drm/amdgpu_drm.h>
#include <drm/ttm/ttm_tt.h>
#include <linux/dma-buf.h>
@ -83,18 +84,6 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
int r;
/*
* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
* Such buffers cannot be safely accessed over P2P due to device-local
* compression metadata. Fallback to system-memory path instead.
* Device supports GFX12 (GC 12.x or newer)
* BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag
*
*/
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) &&
bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
attach->peer2peer = false;
/*
* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
* Such buffers cannot be safely accessed over P2P due to device-local
@ -241,6 +230,14 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
if (r)
return ERR_PTR(r);
break;
case AMDGPU_PL_MMIO_REMAP:
r = amdgpu_ttm_mmio_remap_alloc_sgt(adev, bo->tbo.resource,
attach->dev, dir, &sgt);
if (r)
return ERR_PTR(r);
break;
default:
return ERR_PTR(-EINVAL);
}
@ -266,6 +263,15 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
struct sg_table *sgt,
enum dma_data_direction dir)
{
struct drm_gem_object *obj = attach->dmabuf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
if (bo->tbo.resource &&
bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) {
amdgpu_ttm_mmio_remap_free_sgt(attach->dev, dir, sgt);
return;
}
if (sg_page(sgt->sgl)) {
dma_unmap_sgtable(attach->dev, sgt, dir, 0);
sg_free_table(sgt);

View file

@ -348,6 +348,36 @@ enum AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1 {
AMDGPU_DOORBELL_LAYOUT1_INVALID = 0xFFFF
};
enum AMDGPU_SOC_V1_0_DOORBELL_ASSIGNMENT {
/* KIQ/HIQ/DIQ */
AMDGPU_SOC_V1_0_DOORBELL_KIQ_START = 0x000,
AMDGPU_SOC_V1_0_DOORBELL_HIQ = 0x001,
AMDGPU_SOC_V1_0_DOORBELL_DIQ = 0x002,
/* Compute: 0x03 ~ 0x20 */
AMDGPU_SOC_V1_0_DOORBELL_MEC_RING_START = 0x003,
AMDGPU_SOC_V1_0_DOORBELL_MEC_RING_END = 0x00A,
AMDGPU_SOC_V1_0_DOORBELL_MES_RING0 = 0x00B,
AMDGPU_SOC_V1_0_DOORBELL_MES_RING1 = 0x00C,
AMDGPU_SOC_V1_0_DOORBELL_USERQUEUE_START = 0x00D,
AMDGPU_SOC_V1_0_DOORBELL_USERQUEUE_END = 0x01F,
AMDGPU_SOC_V1_0_DOORBELL_XCC_RANGE = 0x020,
/* SDMA: 0x100 ~ 0x19F */
AMDGPU_SOC_V1_0_DOORBELL_sDMA_ENGINE_START = 0x100,
AMDGPU_SOC_V1_0_DOORBELL_sDMA_ENGINE_END = 0x19F,
/* IH: 0x1A0 ~ 0x1AF */
AMDGPU_SOC_V1_0_DOORBELL_IH = 0x1A0,
/* VCN: 0x1B0 ~ 0x1EF */
AMDGPU_SOC_V1_0_DOORBELL_VCN_START = 0x1B0,
AMDGPU_SOC_V1_0_DOORBELL_VCN_END = 0x1EF,
AMDGPU_SOC_V1_0_DOORBELL_FIRST_NON_CP = AMDGPU_SOC_V1_0_DOORBELL_sDMA_ENGINE_START,
AMDGPU_SOC_V1_0_DOORBELL_LAST_NON_CP = AMDGPU_SOC_V1_0_DOORBELL_VCN_END,
AMDGPU_SOC_V1_0_DOORBELL_MAX_ASSIGNMENT = 0x1EF,
AMDGPU_SOC_V1_0_DOORBELL_INVALID = 0xFFFF
};
u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index);
void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);

View file

@ -129,7 +129,7 @@ uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
{
int db_bo_offset;
db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo);
db_bo_offset = amdgpu_bo_gpu_offset(db_bo);
/* doorbell index is 32 bit but doorbell's size can be 32 bit
* or 64 bit, so *db_size(in byte)/4 for alignment.

View file

@ -2402,7 +2402,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
supports_atomic = true;
if ((flags & AMD_EXP_HW_SUPPORT) && !amdgpu_exp_hw_support) {
DRM_INFO("This hardware requires experimental hardware support.\n"
dev_info(&pdev->dev, "This hardware requires experimental hardware support.\n"
"See modparam exp_hw_support\n");
return -ENODEV;
}
@ -2449,7 +2449,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
retry_init:
ret = drm_dev_register(ddev, flags);
if (ret == -EAGAIN && ++retry <= 3) {
DRM_INFO("retry init %d\n", retry);
drm_info(adev_to_drm(adev), "retry init %d\n", retry);
/* Don't request EX mode too frequently which is attacking */
msleep(5000);
goto retry_init;
@ -3164,7 +3164,6 @@ static int __init amdgpu_init(void)
if (r)
goto error_fence;
DRM_INFO("amdgpu kernel modesetting enabled.\n");
amdgpu_register_atpx_handler();
amdgpu_acpi_detect();

View file

@ -89,6 +89,16 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
return seq;
}
static void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af)
{
af->fence_wptr_start = af->ring->wptr;
}
static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af)
{
af->fence_wptr_end = af->ring->wptr;
}
/**
* amdgpu_fence_emit - emit a fence on the requested ring
*
@ -116,8 +126,10 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
&ring->fence_drv.lock,
adev->fence_context + ring->idx, seq);
amdgpu_fence_save_fence_wptr_start(af);
amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
seq, flags | AMDGPU_FENCE_FLAG_INT);
amdgpu_fence_save_fence_wptr_end(af);
amdgpu_fence_save_wptr(af);
pm_runtime_get_noresume(adev_to_drm(adev)->dev);
ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
@ -709,6 +721,7 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
struct amdgpu_ring *ring = af->ring;
unsigned long flags;
u32 seq, last_seq;
bool reemitted = false;
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
@ -726,7 +739,9 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {
fence = container_of(unprocessed, struct amdgpu_fence, base);
if (fence == af)
if (fence->reemitted > 1)
reemitted = true;
else if (fence == af)
dma_fence_set_error(&fence->base, -ETIME);
else if (fence->context == af->context)
dma_fence_set_error(&fence->base, -ECANCELED);
@ -734,9 +749,12 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
rcu_read_unlock();
} while (last_seq != seq);
spin_unlock_irqrestore(&ring->fence_drv.lock, flags);
/* signal the guilty fence */
amdgpu_fence_write(ring, (u32)af->base.seqno);
amdgpu_fence_process(ring);
if (reemitted) {
/* if we've already reemitted once then just cancel everything */
amdgpu_fence_driver_force_completion(af->ring);
af->ring->ring_backup_entries_to_copy = 0;
}
}
void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
@ -784,10 +802,18 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
/* save everything if the ring is not guilty, otherwise
* just save the content from other contexts.
*/
if (!guilty_fence || (fence->context != guilty_fence->context))
if (!fence->reemitted &&
(!guilty_fence || (fence->context != guilty_fence->context))) {
amdgpu_ring_backup_unprocessed_command(ring, wptr,
fence->wptr);
} else if (!fence->reemitted) {
/* always save the fence */
amdgpu_ring_backup_unprocessed_command(ring,
fence->fence_wptr_start,
fence->fence_wptr_end);
}
wptr = fence->wptr;
fence->reemitted++;
}
rcu_read_unlock();
} while (last_seq != seq);

View file

@ -62,17 +62,17 @@ static ssize_t amdgpu_fw_attestation_debugfs_read(struct file *f,
struct FW_ATT_RECORD fw_att_record = {0};
if (size < sizeof(struct FW_ATT_RECORD)) {
DRM_WARN("FW attestation input buffer not enough memory");
drm_warn(adev_to_drm(adev), "FW attestation input buffer not enough memory");
return -EINVAL;
}
if ((*pos + sizeof(struct FW_ATT_DB_HEADER)) >= FW_ATTESTATION_MAX_SIZE) {
DRM_WARN("FW attestation out of bounds");
drm_warn(adev_to_drm(adev), "FW attestation out of bounds");
return 0;
}
if (psp_get_fw_attestation_records_addr(&adev->psp, &records_addr)) {
DRM_WARN("Failed to get FW attestation record address");
drm_warn(adev_to_drm(adev), "Failed to get FW attestation record address");
return -EINVAL;
}
@ -86,11 +86,12 @@ static ssize_t amdgpu_fw_attestation_debugfs_read(struct file *f,
false);
if (fw_att_hdr.AttDbCookie != FW_ATTESTATION_DB_COOKIE) {
DRM_WARN("Invalid FW attestation cookie");
drm_warn(adev_to_drm(adev), "Invalid FW attestation cookie");
return -EINVAL;
}
DRM_INFO("FW attestation version = 0x%X", fw_att_hdr.AttDbVersion);
drm_info(adev_to_drm(adev), "FW attestation version = 0x%X",
fw_att_hdr.AttDbVersion);
}
amdgpu_device_vram_access(adev,

View file

@ -476,7 +476,7 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
/* Compute table size */
adev->gart.num_cpu_pages = adev->gmc.gart_size / PAGE_SIZE;
adev->gart.num_gpu_pages = adev->gmc.gart_size / AMDGPU_GPU_PAGE_SIZE;
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
drm_info(adev_to_drm(adev), "GART: num cpu pages %u, num gpu pages %u\n",
adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
return 0;

View file

@ -112,47 +112,6 @@ amdgpu_gem_update_timeline_node(struct drm_file *filp,
return 0;
}
static void
amdgpu_gem_update_bo_mapping(struct drm_file *filp,
struct amdgpu_bo_va *bo_va,
uint32_t operation,
uint64_t point,
struct dma_fence *fence,
struct drm_syncobj *syncobj,
struct dma_fence_chain *chain)
{
struct amdgpu_bo *bo = bo_va ? bo_va->base.bo : NULL;
struct amdgpu_fpriv *fpriv = filp->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
struct dma_fence *last_update;
if (!syncobj)
return;
/* Find the last update fence */
switch (operation) {
case AMDGPU_VA_OP_MAP:
case AMDGPU_VA_OP_REPLACE:
if (bo && (bo->tbo.base.resv == vm->root.bo->tbo.base.resv))
last_update = vm->last_update;
else
last_update = bo_va->last_pt_update;
break;
case AMDGPU_VA_OP_UNMAP:
case AMDGPU_VA_OP_CLEAR:
last_update = fence;
break;
default:
return;
}
/* Add fence to timeline */
if (!point)
drm_syncobj_replace_fence(syncobj, last_update);
else
drm_syncobj_add_point(syncobj, chain, last_update, point);
}
static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
{
struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
@ -378,7 +337,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
goto out_unlock;
r = amdgpu_vm_clear_freed(adev, vm, &fence);
if (unlikely(r < 0))
if (unlikely(r < 0) && !drm_dev_is_unplugged(adev_to_drm(adev)))
dev_err(adev->dev, "failed to clear page "
"tables on GEM object close (%ld)\n", r);
if (r || !fence)
@ -388,7 +347,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
dma_fence_put(fence);
out_unlock:
if (r)
if (r && !drm_dev_is_unplugged(adev_to_drm(adev)))
dev_err(adev->dev, "leaking bo va (%ld)\n", r);
drm_exec_fini(&exec);
}
@ -719,6 +678,15 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
if (unlikely(r != 0))
goto out;
/* Reject MMIO_REMAP BOs at IOCTL level: metadata/tiling does not apply. */
if (robj->tbo.resource &&
robj->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) {
DRM_WARN("metadata ioctl on MMIO_REMAP BO (handle %d)\n",
args->handle);
r = -EINVAL;
goto unreserve;
}
if (args->op == AMDGPU_GEM_METADATA_OP_GET_METADATA) {
amdgpu_bo_get_tiling_flags(robj, &args->data.tiling_info);
r = amdgpu_bo_get_metadata(robj, args->data.data,
@ -764,16 +732,19 @@ amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va,
uint32_t operation)
{
struct dma_fence *fence = dma_fence_get_stub();
struct dma_fence *clear_fence = dma_fence_get_stub();
struct dma_fence *last_update = NULL;
int r;
if (!amdgpu_vm_ready(vm))
return fence;
return clear_fence;
r = amdgpu_vm_clear_freed(adev, vm, &fence);
/* First clear freed BOs and get a fence for that work, if any. */
r = amdgpu_vm_clear_freed(adev, vm, &clear_fence);
if (r)
goto error;
/* For MAP/REPLACE we also need to update the BO mappings. */
if (operation == AMDGPU_VA_OP_MAP ||
operation == AMDGPU_VA_OP_REPLACE) {
r = amdgpu_vm_bo_update(adev, bo_va, false);
@ -781,13 +752,59 @@ amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
goto error;
}
/* Always update PDEs after we touched the mappings. */
r = amdgpu_vm_update_pdes(adev, vm, false);
if (r)
goto error;
/*
* Decide which fence represents the "last update" for this VM/BO:
*
* - For MAP/REPLACE we want the PT update fence, which is tracked as
* either vm->last_update (for always-valid BOs) or bo_va->last_pt_update
* (for per-BO updates).
*
* - For UNMAP/CLEAR we rely on the fence returned by
* amdgpu_vm_clear_freed(), which already covers the page table work
* for the removed mappings.
*/
switch (operation) {
case AMDGPU_VA_OP_MAP:
case AMDGPU_VA_OP_REPLACE:
if (bo_va && bo_va->base.bo) {
if (amdgpu_vm_is_bo_always_valid(vm, bo_va->base.bo)) {
if (vm->last_update)
last_update = dma_fence_get(vm->last_update);
} else {
if (bo_va->last_pt_update)
last_update = dma_fence_get(bo_va->last_pt_update);
}
}
break;
case AMDGPU_VA_OP_UNMAP:
case AMDGPU_VA_OP_CLEAR:
if (clear_fence)
last_update = dma_fence_get(clear_fence);
break;
default:
break;
}
error:
if (r && r != -ERESTARTSYS)
DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
return fence;
/*
* If we managed to pick a more specific last-update fence, prefer it
* over the generic clear_fence and drop the extra reference to the
* latter.
*/
if (last_update) {
dma_fence_put(clear_fence);
return last_update;
}
return clear_fence;
}
int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
@ -813,6 +830,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
uint64_t vm_size;
int r = 0;
/* Validate virtual address range against reserved regions. */
if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) {
dev_dbg(dev->dev,
"va_address 0x%llx is in reserved area 0x%llx\n",
@ -846,6 +864,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
/* Validate operation type. */
switch (args->operation) {
case AMDGPU_VA_OP_MAP:
case AMDGPU_VA_OP_UNMAP:
@ -869,6 +888,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
abo = NULL;
}
/* Add input syncobj fences (if any) for synchronization. */
r = amdgpu_gem_add_input_fence(filp,
args->input_fence_syncobj_handles,
args->num_syncobj_handles);
@ -891,6 +911,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
goto error;
}
/* Resolve the BO-VA mapping for this VM/BO combination. */
if (abo) {
bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo);
if (!bo_va) {
@ -903,6 +924,11 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
bo_va = NULL;
}
/*
* Prepare the timeline syncobj node if the user requested a VM
* timeline update. This only allocates/looks up the syncobj and
* chain node; the actual fence is attached later.
*/
r = amdgpu_gem_update_timeline_node(filp,
args->vm_timeline_syncobj_out,
args->vm_timeline_point,
@ -934,18 +960,30 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
default:
break;
}
/*
* Once the VA operation is done, update the VM and obtain the fence
* that represents the last relevant update for this mapping. This
* fence can then be exported to the user-visible VM timeline.
*/
if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !adev->debug_vm) {
fence = amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
args->operation);
if (timeline_syncobj)
amdgpu_gem_update_bo_mapping(filp, bo_va,
args->operation,
args->vm_timeline_point,
fence, timeline_syncobj,
timeline_chain);
else
dma_fence_put(fence);
if (timeline_syncobj && fence) {
if (!args->vm_timeline_point) {
/* Replace the existing fence when no point is given. */
drm_syncobj_replace_fence(timeline_syncobj,
fence);
} else {
/* Attach the last-update fence at a specific point. */
drm_syncobj_add_point(timeline_syncobj,
timeline_chain,
fence,
args->vm_timeline_point);
}
}
dma_fence_put(fence);
}

View file

@ -100,6 +100,7 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev,
/**
* amdgpu_gfx_parse_disable_cu - Parse the disable_cu module parameter
*
* @adev: amdgpu device pointer
* @mask: array in which the per-shader array disable masks will be stored
* @max_se: number of SEs
* @max_sh: number of SHs
@ -107,7 +108,8 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev,
* The bitmask of CUs to be disabled in the shader array determined by se and
* sh is stored in mask[se * max_sh + sh].
*/
void amdgpu_gfx_parse_disable_cu(unsigned int *mask, unsigned int max_se, unsigned int max_sh)
void amdgpu_gfx_parse_disable_cu(struct amdgpu_device *adev, unsigned int *mask,
unsigned int max_se, unsigned int max_sh)
{
unsigned int se, sh, cu;
const char *p;
@ -123,16 +125,16 @@ void amdgpu_gfx_parse_disable_cu(unsigned int *mask, unsigned int max_se, unsign
int ret = sscanf(p, "%u.%u.%u", &se, &sh, &cu);
if (ret < 3) {
DRM_ERROR("amdgpu: could not parse disable_cu\n");
drm_err(adev_to_drm(adev), "could not parse disable_cu\n");
return;
}
if (se < max_se && sh < max_sh && cu < 16) {
DRM_INFO("amdgpu: disabling CU %u.%u.%u\n", se, sh, cu);
drm_info(adev_to_drm(adev), "Disabling CU %u.%u.%u\n", se, sh, cu);
mask[se * max_sh + sh] |= 1u << cu;
} else {
DRM_ERROR("amdgpu: disable_cu %u.%u.%u is out of range\n",
se, sh, cu);
drm_err(adev_to_drm(adev), "disable_cu %u.%u.%u is out of range\n",
se, sh, cu);
}
next = strchr(p, ',');
@ -150,7 +152,7 @@ static bool amdgpu_gfx_is_graphics_multipipe_capable(struct amdgpu_device *adev)
static bool amdgpu_gfx_is_compute_multipipe_capable(struct amdgpu_device *adev)
{
if (amdgpu_compute_multipipe != -1) {
dev_info(adev->dev, "amdgpu: forcing compute pipe policy %d\n",
dev_info(adev->dev, " forcing compute pipe policy %d\n",
amdgpu_compute_multipipe);
return amdgpu_compute_multipipe == 1;
}
@ -511,7 +513,7 @@ int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
j = i + xcc_id * adev->gfx.num_compute_rings;
amdgpu_mes_unmap_legacy_queue(adev,
&adev->gfx.compute_ring[j],
RESET_QUEUES, 0, 0);
RESET_QUEUES, 0, 0, xcc_id);
}
return 0;
}
@ -562,7 +564,7 @@ int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id)
j = i + xcc_id * adev->gfx.num_gfx_rings;
amdgpu_mes_unmap_legacy_queue(adev,
&adev->gfx.gfx_ring[j],
PREEMPT_QUEUES, 0, 0);
PREEMPT_QUEUES, 0, 0, xcc_id);
}
}
return 0;
@ -644,7 +646,8 @@ static int amdgpu_gfx_mes_enable_kcq(struct amdgpu_device *adev, int xcc_id)
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
j = i + xcc_id * adev->gfx.num_compute_rings;
r = amdgpu_mes_map_legacy_queue(adev,
&adev->gfx.compute_ring[j]);
&adev->gfx.compute_ring[j],
xcc_id);
if (r) {
dev_err(adev->dev, "failed to map compute queue\n");
return r;
@ -733,7 +736,8 @@ int amdgpu_gfx_enable_kgq(struct amdgpu_device *adev, int xcc_id)
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
j = i + xcc_id * adev->gfx.num_gfx_rings;
r = amdgpu_mes_map_legacy_queue(adev,
&adev->gfx.gfx_ring[j]);
&adev->gfx.gfx_ring[j],
xcc_id);
if (r) {
dev_err(adev->dev, "failed to map gfx queue\n");
return r;
@ -1067,7 +1071,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_
return 0;
if (adev->mes.ring[0].sched.ready)
return amdgpu_mes_rreg(adev, reg);
return amdgpu_mes_rreg(adev, reg, xcc_id);
BUG_ON(!ring->funcs->emit_rreg);
@ -1143,7 +1147,7 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint3
return;
if (adev->mes.ring[0].sched.ready) {
amdgpu_mes_wreg(adev, reg, v);
amdgpu_mes_wreg(adev, reg, v, xcc_id);
return;
}
@ -1195,6 +1199,40 @@ failed_kiq_write:
dev_err(adev->dev, "failed to write reg:%x\n", reg);
}
void amdgpu_gfx_get_hdp_flush_mask(struct amdgpu_ring *ring,
uint32_t *hdp_flush_mask, uint32_t *reg_mem_engine)
{
if (!ring || !hdp_flush_mask || !reg_mem_engine) {
DRM_INFO("%s:invalid params\n", __func__);
return;
}
const struct nbio_hdp_flush_reg *nbio_hf_reg = ring->adev->nbio.hdp_flush_reg;
switch (ring->funcs->type) {
case AMDGPU_RING_TYPE_GFX:
*hdp_flush_mask = nbio_hf_reg->ref_and_mask_cp0 << ring->pipe;
*reg_mem_engine = 1; /* pfp */
break;
case AMDGPU_RING_TYPE_COMPUTE:
*hdp_flush_mask = nbio_hf_reg->ref_and_mask_cp2 << ring->pipe;
*reg_mem_engine = 0;
break;
case AMDGPU_RING_TYPE_MES:
*hdp_flush_mask = nbio_hf_reg->ref_and_mask_cp8;
*reg_mem_engine = 0;
break;
case AMDGPU_RING_TYPE_KIQ:
*hdp_flush_mask = nbio_hf_reg->ref_and_mask_cp9;
*reg_mem_engine = 0;
break;
default:
DRM_ERROR("%s:unsupported ring type %d\n", __func__, ring->funcs->type);
return;
}
}
int amdgpu_kiq_hdp_flush(struct amdgpu_device *adev)
{
signed long r, cnt = 0;

View file

@ -328,6 +328,8 @@ struct amdgpu_gfx_shadow_info {
u32 shadow_alignment;
u32 csa_size;
u32 csa_alignment;
u32 eop_size;
u32 eop_alignment;
};
struct amdgpu_gfx_funcs {
@ -356,6 +358,8 @@ struct amdgpu_gfx_funcs {
int num_xccs_per_xcp);
int (*ih_node_to_logical_xcc)(struct amdgpu_device *adev, int ih_node);
int (*get_xccs_per_xcp)(struct amdgpu_device *adev);
void (*get_hdp_flush_mask)(struct amdgpu_ring *ring,
uint32_t *ref_and_mask, uint32_t *reg_mem_engine);
};
struct sq_work {
@ -565,8 +569,8 @@ static inline u32 amdgpu_gfx_create_bitmask(u32 bit_width)
return (u32)((1ULL << bit_width) - 1);
}
void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se,
unsigned max_sh);
void amdgpu_gfx_parse_disable_cu(struct amdgpu_device *adev, unsigned int *mask,
unsigned int max_se, unsigned int max_sh);
int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, int xcc_id);
@ -615,6 +619,8 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry);
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id);
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id);
void amdgpu_gfx_get_hdp_flush_mask(struct amdgpu_ring *ring,
uint32_t *ref_and_mask, uint32_t *reg_mem_engine);
int amdgpu_kiq_hdp_flush(struct amdgpu_device *adev);
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id);

View file

@ -524,6 +524,54 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
} while (fault->timestamp < tmp);
}
int amdgpu_gmc_handle_retry_fault(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry,
u64 addr,
u32 cam_index,
u32 node_id,
bool write_fault)
{
int ret;
if (adev->irq.retry_cam_enabled) {
/* Delegate it to a different ring if the hardware hasn't
* already done it.
*/
if (entry->ih == &adev->irq.ih) {
amdgpu_irq_delegate(adev, entry, 8);
return 1;
}
ret = amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, node_id,
addr, entry->timestamp, write_fault);
WDOORBELL32(adev->irq.retry_cam_doorbell_index, cam_index);
if (ret)
return 1;
} else {
/* Process it only if it's the first fault for this address */
if (entry->ih != &adev->irq.ih_soft &&
amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
entry->timestamp))
return 1;
/* Delegate it to a different ring if the hardware hasn't
* already done it.
*/
if (entry->ih == &adev->irq.ih) {
amdgpu_irq_delegate(adev, entry, 8);
return 1;
}
/* Try to handle the recoverable page faults by filling page
* tables
*/
if (amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, node_id,
addr, entry->timestamp, write_fault))
return 1;
}
return 0;
}
int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev)
{
int r;
@ -690,7 +738,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
* itself at least for GART.
*/
mutex_lock(&adev->mman.gtt_window_lock);
r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.high_pr,
r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.default_entity.base,
AMDGPU_FENCE_OWNER_UNDEFINED,
16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
&job, AMDGPU_KERNEL_JOB_ID_FLUSH_GPU_TLB);
@ -811,9 +859,9 @@ void amdgpu_gmc_fw_reg_write_reg_wait(struct amdgpu_device *adev,
unsigned long flags;
uint32_t seq;
if (adev->mes.ring[0].sched.ready) {
if (adev->mes.ring[MES_PIPE_INST(xcc_inst, 0)].sched.ready) {
amdgpu_mes_reg_write_reg_wait(adev, reg0, reg1,
ref, mask);
ref, mask, xcc_inst);
return;
}
@ -901,6 +949,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
/* Don't enable it by default yet.
*/
if (amdgpu_tmz < 1) {

View file

@ -32,9 +32,11 @@
#include "amdgpu_xgmi.h"
#include "amdgpu_ras.h"
/* VA hole for 48bit addresses on Vega10 */
#define AMDGPU_GMC_HOLE_START 0x0000800000000000ULL
#define AMDGPU_GMC_HOLE_END 0xffff800000000000ULL
/* VA hole for 48bit and 57bit addresses */
#define AMDGPU_GMC_HOLE_START (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
0x0100000000000000ULL : 0x0000800000000000ULL)
#define AMDGPU_GMC_HOLE_END (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
0xff00000000000000ULL : 0xffff800000000000ULL)
/*
* Hardware is programmed as if the hole doesn't exists with start and end
@ -43,7 +45,8 @@
* This mask is used to remove the upper 16bits of the VA and so come up with
* the linear addr value.
*/
#define AMDGPU_GMC_HOLE_MASK 0x0000ffffffffffffULL
#define AMDGPU_GMC_HOLE_MASK (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
0x00ffffffffffffffULL : 0x0000ffffffffffffULL)
/*
* Ring size as power of two for the log of recent faults.
@ -353,6 +356,7 @@ struct amdgpu_gmc {
u64 MC_VM_MX_L1_TLB_CNTL;
u64 noretry_flags;
u64 init_pte_flags;
bool flush_tlb_needs_extra_type_0;
bool flush_tlb_needs_extra_type_2;
@ -394,13 +398,8 @@ static inline bool amdgpu_gmc_vram_full_visible(struct amdgpu_gmc *gmc)
*
* @addr: address to extend
*/
static inline uint64_t amdgpu_gmc_sign_extend(uint64_t addr)
{
if (addr >= AMDGPU_GMC_HOLE_START)
addr |= AMDGPU_GMC_HOLE_END;
return addr;
}
#define amdgpu_gmc_sign_extend(addr) ((addr) >= AMDGPU_GMC_HOLE_START ?\
((addr) | AMDGPU_GMC_HOLE_END) : (addr))
bool amdgpu_gmc_is_pdb0_enabled(struct amdgpu_device *adev);
int amdgpu_gmc_pdb0_alloc(struct amdgpu_device *adev);
@ -426,6 +425,12 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
uint16_t pasid, uint64_t timestamp);
void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
uint16_t pasid);
int amdgpu_gmc_handle_retry_fault(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry,
u64 addr,
u32 cam_index,
u32 node_id,
bool write_fault);
int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev);
int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);

View file

@ -26,6 +26,8 @@
#include "amdgpu.h"
#define GART_ENTRY_WITHOUT_BO_COLOR 1
static inline struct amdgpu_gtt_mgr *
to_gtt_mgr(struct ttm_resource_manager *man)
{
@ -180,6 +182,49 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
kfree(node);
}
/**
* amdgpu_gtt_mgr_alloc_entries - alloc GART entries without GTT bo
*
* @mgr: The GTT manager object
* @mm_node: The drm mm node to return the new allocation node information
* @num_pages: The number of pages for the new allocation
* @mode: The new allocation mode
*
* Helper to dynamic alloc GART entries to map memory not accociated with
* GTT BO, for example VRAM BO physical memory, remote physical memory.
*/
int amdgpu_gtt_mgr_alloc_entries(struct amdgpu_gtt_mgr *mgr,
struct drm_mm_node *mm_node,
u64 num_pages,
enum drm_mm_insert_mode mode)
{
struct amdgpu_device *adev = container_of(mgr, typeof(*adev), mman.gtt_mgr);
int r;
spin_lock(&mgr->lock);
r = drm_mm_insert_node_in_range(&mgr->mm, mm_node, num_pages,
0, GART_ENTRY_WITHOUT_BO_COLOR, 0,
adev->gmc.gart_size >> PAGE_SHIFT,
mode);
spin_unlock(&mgr->lock);
return r;
}
/**
* amdgpu_gtt_mgr_free_entries - free GART entries not accocaited with GTT bo
*
* @mgr: The GTT manager object
* @mm_node: The drm mm node to free
*/
void amdgpu_gtt_mgr_free_entries(struct amdgpu_gtt_mgr *mgr,
struct drm_mm_node *mm_node)
{
spin_lock(&mgr->lock);
if (drm_mm_node_allocated(mm_node))
drm_mm_remove_node(mm_node);
spin_unlock(&mgr->lock);
}
/**
* amdgpu_gtt_mgr_recover - re-init gart
*
@ -196,6 +241,9 @@ void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
adev = container_of(mgr, typeof(*adev), mman.gtt_mgr);
spin_lock(&mgr->lock);
drm_mm_for_each_node(mm_node, &mgr->mm) {
if (mm_node->color == GART_ENTRY_WITHOUT_BO_COLOR)
continue;
node = container_of(mm_node, typeof(*node), mm_nodes[0]);
amdgpu_ttm_recover_gart(node->base.bo);
}

View file

@ -36,6 +36,10 @@ struct amdgpu_imu_funcs {
int (*start_imu)(struct amdgpu_device *adev);
void (*program_rlc_ram)(struct amdgpu_device *adev);
int (*wait_for_reset_status)(struct amdgpu_device *adev);
int (*switch_compute_partition)(struct amdgpu_device *adev,
int num_xccs_per_xcp,
int compute_partition_mode);
void (*init_mcm_addr_lut)(struct amdgpu_device *adev);
};
struct imu_rlc_ram_golden {

View file

@ -94,3 +94,318 @@ void amdgpu_ip_map_init(struct amdgpu_device *adev)
adev->ip_map.logical_to_dev_inst = amdgpu_logical_to_dev_inst;
adev->ip_map.logical_to_dev_mask = amdgpu_logical_to_dev_mask;
}
int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block)
{
int r;
if (ip_block->version->funcs->suspend) {
r = ip_block->version->funcs->suspend(ip_block);
if (r) {
dev_err(ip_block->adev->dev,
"suspend of IP block <%s> failed %d\n",
ip_block->version->funcs->name, r);
return r;
}
}
ip_block->status.hw = false;
return 0;
}
int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block)
{
int r;
if (ip_block->version->funcs->resume) {
r = ip_block->version->funcs->resume(ip_block);
if (r) {
dev_err(ip_block->adev->dev,
"resume of IP block <%s> failed %d\n",
ip_block->version->funcs->name, r);
return r;
}
}
ip_block->status.hw = true;
return 0;
}
/**
* amdgpu_device_ip_get_ip_block - get a hw IP pointer
*
* @adev: amdgpu_device pointer
* @type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Returns a pointer to the hardware IP block structure
* if it exists for the asic, otherwise NULL.
*/
struct amdgpu_ip_block *
amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev,
enum amd_ip_block_type type)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++)
if (adev->ip_blocks[i].version->type == type)
return &adev->ip_blocks[i];
return NULL;
}
/**
* amdgpu_device_ip_block_version_cmp
*
* @adev: amdgpu_device pointer
* @type: enum amd_ip_block_type
* @major: major version
* @minor: minor version
*
* return 0 if equal or greater
* return 1 if smaller or the ip_block doesn't exist
*/
int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev,
enum amd_ip_block_type type, u32 major,
u32 minor)
{
struct amdgpu_ip_block *ip_block =
amdgpu_device_ip_get_ip_block(adev, type);
if (ip_block && ((ip_block->version->major > major) ||
((ip_block->version->major == major) &&
(ip_block->version->minor >= minor))))
return 0;
return 1;
}
static const char *const ip_block_names[] = {
[AMD_IP_BLOCK_TYPE_COMMON] = "common",
[AMD_IP_BLOCK_TYPE_GMC] = "gmc",
[AMD_IP_BLOCK_TYPE_IH] = "ih",
[AMD_IP_BLOCK_TYPE_SMC] = "smu",
[AMD_IP_BLOCK_TYPE_PSP] = "psp",
[AMD_IP_BLOCK_TYPE_DCE] = "dce",
[AMD_IP_BLOCK_TYPE_GFX] = "gfx",
[AMD_IP_BLOCK_TYPE_SDMA] = "sdma",
[AMD_IP_BLOCK_TYPE_UVD] = "uvd",
[AMD_IP_BLOCK_TYPE_VCE] = "vce",
[AMD_IP_BLOCK_TYPE_ACP] = "acp",
[AMD_IP_BLOCK_TYPE_VCN] = "vcn",
[AMD_IP_BLOCK_TYPE_MES] = "mes",
[AMD_IP_BLOCK_TYPE_JPEG] = "jpeg",
[AMD_IP_BLOCK_TYPE_VPE] = "vpe",
[AMD_IP_BLOCK_TYPE_UMSCH_MM] = "umsch_mm",
[AMD_IP_BLOCK_TYPE_ISP] = "isp",
[AMD_IP_BLOCK_TYPE_RAS] = "ras",
};
static const char *ip_block_name(struct amdgpu_device *adev,
enum amd_ip_block_type type)
{
int idx = (int)type;
return idx < ARRAY_SIZE(ip_block_names) ? ip_block_names[idx] :
"unknown";
}
/**
* amdgpu_device_ip_block_add
*
* @adev: amdgpu_device pointer
* @ip_block_version: pointer to the IP to add
*
* Adds the IP block driver information to the collection of IPs
* on the asic.
*/
int amdgpu_device_ip_block_add(
struct amdgpu_device *adev,
const struct amdgpu_ip_block_version *ip_block_version)
{
if (!ip_block_version)
return -EINVAL;
switch (ip_block_version->type) {
case AMD_IP_BLOCK_TYPE_VCN:
if (adev->harvest_ip_mask & AMD_HARVEST_IP_VCN_MASK)
return 0;
break;
case AMD_IP_BLOCK_TYPE_JPEG:
if (adev->harvest_ip_mask & AMD_HARVEST_IP_JPEG_MASK)
return 0;
break;
default:
break;
}
dev_info(adev->dev, "detected ip block number %d <%s_v%d_%d_%d> (%s)\n",
adev->num_ip_blocks,
ip_block_name(adev, ip_block_version->type),
ip_block_version->major, ip_block_version->minor,
ip_block_version->rev, ip_block_version->funcs->name);
adev->ip_blocks[adev->num_ip_blocks].adev = adev;
adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version;
return 0;
}
/**
* amdgpu_device_ip_set_clockgating_state - set the CG state
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: clockgating state (gate or ungate)
*
* Sets the requested clockgating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state)
{
int i, r = 0;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type != block_type)
continue;
if (!adev->ip_blocks[i].version->funcs->set_clockgating_state)
continue;
r = adev->ip_blocks[i].version->funcs->set_clockgating_state(
&adev->ip_blocks[i], state);
if (r)
dev_err(adev->dev,
"set_clockgating_state of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
return r;
}
/**
* amdgpu_device_ip_set_powergating_state - set the PG state
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: powergating state (gate or ungate)
*
* Sets the requested powergating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_powergating_state state)
{
int i, r = 0;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type != block_type)
continue;
if (!adev->ip_blocks[i].version->funcs->set_powergating_state)
continue;
r = adev->ip_blocks[i].version->funcs->set_powergating_state(
&adev->ip_blocks[i], state);
if (r)
dev_err(adev->dev,
"set_powergating_state of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
return r;
}
/**
* amdgpu_device_ip_get_clockgating_state - get the CG state
*
* @adev: amdgpu_device pointer
* @flags: clockgating feature flags
*
* Walks the list of IPs on the device and updates the clockgating
* flags for each IP.
* Updates @flags with the feature flags for each hardware IP where
* clockgating is enabled.
*/
void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->funcs->get_clockgating_state)
adev->ip_blocks[i].version->funcs->get_clockgating_state(
&adev->ip_blocks[i], flags);
}
}
/**
* amdgpu_device_ip_wait_for_idle - wait for idle
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Waits for the request hardware IP to be idle.
* Returns 0 for success or a negative error code on failure.
*/
int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
struct amdgpu_ip_block *ip_block;
ip_block = amdgpu_device_ip_get_ip_block(adev, block_type);
if (!ip_block || !ip_block->status.valid)
return 0;
if (ip_block->version->funcs->wait_for_idle)
return ip_block->version->funcs->wait_for_idle(ip_block);
return 0;
}
/**
* amdgpu_device_ip_is_hw - is the hardware IP enabled
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Check if the hardware IP is enable or not.
* Returns true if it the IP is enable, false if not.
*/
bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
struct amdgpu_ip_block *ip_block;
ip_block = amdgpu_device_ip_get_ip_block(adev, block_type);
if (ip_block)
return ip_block->status.hw;
return false;
}
/**
* amdgpu_device_ip_is_valid - is the hardware IP valid
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Check if the hardware IP is valid or not.
* Returns true if it the IP is valid, false if not.
*/
bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
struct amdgpu_ip_block *ip_block;
ip_block = amdgpu_device_ip_get_ip_block(adev, block_type);
if (ip_block)
return ip_block->status.valid;
return false;
}

View file

@ -24,6 +24,131 @@
#ifndef __AMDGPU_IP_H__
#define __AMDGPU_IP_H__
#include "amd_shared.h"
struct amdgpu_device;
/* Define the HW IP blocks will be used in driver , add more if necessary */
enum amd_hw_ip_block_type {
GC_HWIP = 1,
HDP_HWIP,
SDMA0_HWIP,
SDMA1_HWIP,
SDMA2_HWIP,
SDMA3_HWIP,
SDMA4_HWIP,
SDMA5_HWIP,
SDMA6_HWIP,
SDMA7_HWIP,
LSDMA_HWIP,
MMHUB_HWIP,
ATHUB_HWIP,
NBIO_HWIP,
MP0_HWIP,
MP1_HWIP,
UVD_HWIP,
VCN_HWIP = UVD_HWIP,
JPEG_HWIP = VCN_HWIP,
VCN1_HWIP,
VCE_HWIP,
VPE_HWIP,
DF_HWIP,
DCE_HWIP,
OSSSYS_HWIP,
SMUIO_HWIP,
PWR_HWIP,
NBIF_HWIP,
THM_HWIP,
CLK_HWIP,
UMC_HWIP,
RSMU_HWIP,
XGMI_HWIP,
DCI_HWIP,
PCIE_HWIP,
ISP_HWIP,
ATU_HWIP,
AIGC_HWIP,
MAX_HWIP
};
#define HWIP_MAX_INSTANCE 48
#define HW_ID_MAX 300
#define IP_VERSION_FULL(mj, mn, rv, var, srev) \
(((mj) << 24) | ((mn) << 16) | ((rv) << 8) | ((var) << 4) | (srev))
#define IP_VERSION(mj, mn, rv) IP_VERSION_FULL(mj, mn, rv, 0, 0)
#define IP_VERSION_MAJ(ver) ((ver) >> 24)
#define IP_VERSION_MIN(ver) (((ver) >> 16) & 0xFF)
#define IP_VERSION_REV(ver) (((ver) >> 8) & 0xFF)
#define IP_VERSION_VARIANT(ver) (((ver) >> 4) & 0xF)
#define IP_VERSION_SUBREV(ver) ((ver) & 0xF)
#define IP_VERSION_MAJ_MIN_REV(ver) ((ver) >> 8)
struct amdgpu_ip_map_info {
/* Map of logical to actual dev instances/mask */
uint32_t dev_inst[MAX_HWIP][HWIP_MAX_INSTANCE];
int8_t (*logical_to_dev_inst)(struct amdgpu_device *adev,
enum amd_hw_ip_block_type block,
int8_t inst);
uint32_t (*logical_to_dev_mask)(struct amdgpu_device *adev,
enum amd_hw_ip_block_type block,
uint32_t mask);
};
#define AMDGPU_MAX_IP_NUM AMD_IP_BLOCK_TYPE_NUM
struct amdgpu_ip_block_status {
bool valid;
bool sw;
bool hw;
bool late_initialized;
bool hang;
};
struct amdgpu_ip_block_version {
const enum amd_ip_block_type type;
const u32 major;
const u32 minor;
const u32 rev;
const struct amd_ip_funcs *funcs;
};
struct amdgpu_ip_block {
struct amdgpu_ip_block_status status;
const struct amdgpu_ip_block_version *version;
struct amdgpu_device *adev;
};
void amdgpu_ip_map_init(struct amdgpu_device *adev);
int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block);
int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block);
struct amdgpu_ip_block *
amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev,
enum amd_ip_block_type type);
int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev,
enum amd_ip_block_type type, u32 major,
u32 minor);
int amdgpu_device_ip_block_add(
struct amdgpu_device *adev,
const struct amdgpu_ip_block_version *ip_block_version);
int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state);
int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_powergating_state state);
void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags);
int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev,
enum amd_ip_block_type block_type);
#endif /* __AMDGPU_IP_H__ */

View file

@ -99,6 +99,41 @@ const char *soc15_ih_clientid_name[] = {
"MP1"
};
const char *soc_v1_0_ih_clientid_name[] = {
"IH",
"Reserved",
"ATHUB",
"BIF",
"Reserved",
"Reserved",
"Reserved",
"RLC",
"Reserved",
"Reserved",
"GFX",
"IMU",
"Reserved",
"Reserved",
"VCN1 or UVD1",
"THM",
"VCN or UVD",
"Reserved",
"VMC",
"Reserved",
"GRBM_CP",
"GC_AID",
"ROM_SMUIO",
"DF",
"Reserved",
"PWR",
"LSDMA",
"GC_UTCL2",
"nHT",
"Reserved",
"MP0",
"MP1",
};
const int node_id_to_phys_map[NODEID_MAX] = {
[AID0_NODEID] = 0,
[XCD0_NODEID] = 0,
@ -316,7 +351,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
adev->irq.irq = irq;
adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
dev_dbg(adev->dev, "amdgpu: irq initialized.\n");
dev_dbg(adev->dev, "irq initialized.\n");
return 0;
free_vectors:

View file

@ -26,6 +26,7 @@
#include <linux/irqdomain.h>
#include "soc15_ih_clientid.h"
#include "soc_v1_0_ih_clientid.h"
#include "amdgpu_ih.h"
#define AMDGPU_MAX_IRQ_SRC_ID 0x100

View file

@ -318,12 +318,36 @@ void isp_kernel_buffer_free(void **buf_obj, u64 *gpu_addr, void **cpu_addr)
}
EXPORT_SYMBOL(isp_kernel_buffer_free);
static int isp_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_isp *isp = &adev->isp;
if (isp->funcs->hw_resume)
return isp->funcs->hw_resume(isp);
return -ENODEV;
}
static int isp_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_isp *isp = &adev->isp;
if (isp->funcs->hw_suspend)
return isp->funcs->hw_suspend(isp);
return -ENODEV;
}
static const struct amd_ip_funcs isp_ip_funcs = {
.name = "isp_ip",
.early_init = isp_early_init,
.hw_init = isp_hw_init,
.hw_fini = isp_hw_fini,
.is_idle = isp_is_idle,
.suspend = isp_suspend,
.resume = isp_resume,
.set_clockgating_state = isp_set_clockgating_state,
.set_powergating_state = isp_set_powergating_state,
};

View file

@ -38,6 +38,8 @@ struct amdgpu_isp;
struct isp_funcs {
int (*hw_init)(struct amdgpu_isp *isp);
int (*hw_fini)(struct amdgpu_isp *isp);
int (*hw_suspend)(struct amdgpu_isp *isp);
int (*hw_resume)(struct amdgpu_isp *isp);
};
struct amdgpu_isp {

View file

@ -147,7 +147,8 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
dev_err(adev->dev, "Ring %s reset failed\n", ring->sched.name);
}
dma_fence_set_error(&s_job->s_fence->finished, -ETIME);
if (dma_fence_get_status(&s_job->s_fence->finished) == 0)
dma_fence_set_error(&s_job->s_fence->finished, -ETIME);
if (amdgpu_device_should_recover_gpu(ring->adev)) {
struct amdgpu_reset_context reset_context;

View file

@ -92,7 +92,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
return;
if (amdgpu_acpi_smart_shift_update(adev, AMDGPU_SS_DRV_UNLOAD))
DRM_WARN("smart shift update failed\n");
drm_warn(dev, "smart shift update failed\n");
amdgpu_acpi_fini(adev);
amdgpu_device_fini_hw(adev);
@ -105,7 +105,7 @@ void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
mutex_lock(&mgpu_info.mutex);
if (mgpu_info.num_gpu >= MAX_GPU_INSTANCE) {
DRM_ERROR("Cannot register more gpu instance\n");
drm_err(adev_to_drm(adev), "Cannot register more gpu instance\n");
mutex_unlock(&mgpu_info.mutex);
return;
}
@ -162,7 +162,7 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
dev_dbg(dev->dev, "Error during ACPI methods call\n");
if (amdgpu_acpi_smart_shift_update(adev, AMDGPU_SS_DRV_LOAD))
DRM_WARN("smart shift update failed\n");
drm_warn(dev, "smart shift update failed\n");
out:
if (r)
@ -201,6 +201,9 @@ static enum amd_ip_block_type
type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ?
AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN;
break;
case AMDGPU_HW_IP_VPE:
type = AMD_IP_BLOCK_TYPE_VPE;
break;
default:
type = AMD_IP_BLOCK_TYPE_NUM;
break;
@ -391,6 +394,42 @@ static int amdgpu_userq_metadata_info_gfx(struct amdgpu_device *adev,
return ret;
}
static int amdgpu_userq_metadata_info_compute(struct amdgpu_device *adev,
struct drm_amdgpu_info *info,
struct drm_amdgpu_info_uq_metadata_compute *meta)
{
int ret = -EOPNOTSUPP;
if (adev->gfx.funcs->get_gfx_shadow_info) {
struct amdgpu_gfx_shadow_info shadow = {};
adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow, true);
meta->eop_size = shadow.eop_size;
meta->eop_alignment = shadow.eop_alignment;
ret = 0;
}
return ret;
}
static int amdgpu_userq_metadata_info_sdma(struct amdgpu_device *adev,
struct drm_amdgpu_info *info,
struct drm_amdgpu_info_uq_metadata_sdma *meta)
{
int ret = -EOPNOTSUPP;
if (adev->sdma.get_csa_info) {
struct amdgpu_sdma_csa_info csa = {};
adev->sdma.get_csa_info(adev, &csa);
meta->csa_size = csa.size;
meta->csa_alignment = csa.alignment;
ret = 0;
}
return ret;
}
static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
struct drm_amdgpu_info *info,
struct drm_amdgpu_info_hw_ip *result)
@ -721,6 +760,9 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
case AMD_IP_BLOCK_TYPE_UVD:
count = adev->uvd.num_uvd_inst;
break;
case AMD_IP_BLOCK_TYPE_VPE:
count = adev->vpe.num_instances;
break;
/* For all other IP block types not listed in the switch statement
* the ip status is valid here and the instance count is one.
*/
@ -1360,6 +1402,22 @@ out:
if (ret)
return ret;
ret = copy_to_user(out, &meta_info,
min((size_t)size, sizeof(meta_info))) ? -EFAULT : 0;
return 0;
case AMDGPU_HW_IP_COMPUTE:
ret = amdgpu_userq_metadata_info_compute(adev, info, &meta_info.compute);
if (ret)
return ret;
ret = copy_to_user(out, &meta_info,
min((size_t)size, sizeof(meta_info))) ? -EFAULT : 0;
return 0;
case AMDGPU_HW_IP_DMA:
ret = amdgpu_userq_metadata_info_sdma(adev, info, &meta_info.sdma);
if (ret)
return ret;
ret = copy_to_user(out, &meta_info,
min((size_t)size, sizeof(meta_info))) ? -EFAULT : 0;
return 0;
@ -1450,7 +1508,9 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, file_priv, adev);
if (r)
DRM_WARN("Can't setup usermode queues, use legacy workload submission only\n");
drm_warn(adev_to_drm(adev),
"Failed to init usermode queue manager (%d), use legacy workload submission only\n",
r);
r = amdgpu_eviction_fence_init(&fpriv->evf_mgr);
if (r)

View file

@ -31,6 +31,7 @@
#define AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS 1024
#define AMDGPU_ONE_DOORBELL_SIZE 8
#define AMDGPU_MES_RESERVED_QUEUES 2
int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev)
{
@ -91,6 +92,9 @@ static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)
int amdgpu_mes_init(struct amdgpu_device *adev)
{
int i, r, num_pipes;
u32 total_vmid_mask, reserved_vmid_mask;
u32 queue_mask, reserved_queue_mask;
int num_xcc = adev->gfx.xcc_mask ? NUM_XCC(adev->gfx.xcc_mask) : 1;
adev->mes.adev = adev;
@ -101,12 +105,18 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
spin_lock_init(&adev->mes.queue_id_lock);
mutex_init(&adev->mes.mutex_hidden);
for (i = 0; i < AMDGPU_MAX_MES_PIPES; i++)
for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++)
spin_lock_init(&adev->mes.ring_lock[i]);
adev->mes.total_max_queue = AMDGPU_FENCE_MES_QUEUE_ID_MASK;
total_vmid_mask = (u32)((1UL << 16) - 1);
reserved_vmid_mask = (u32)((1UL << adev->vm_manager.first_kfd_vmid) - 1);
adev->mes.vmid_mask_mmhub = 0xFF00;
adev->mes.vmid_mask_gfxhub = adev->gfx.disable_kq ? 0xFFFE : 0xFF00;
adev->mes.vmid_mask_gfxhub = total_vmid_mask & ~reserved_vmid_mask;
queue_mask = (u32)(1UL << adev->gfx.mec.num_queue_per_pipe) - 1;
reserved_queue_mask = (u32)(1UL << AMDGPU_MES_RESERVED_QUEUES) - 1;
num_pipes = adev->gfx.me.num_pipe_per_me * adev->gfx.me.num_me;
if (num_pipes > AMDGPU_MES_MAX_GFX_PIPES)
@ -142,7 +152,8 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
for (i = 0; i < AMDGPU_MES_MAX_COMPUTE_PIPES; i++) {
if (i >= num_pipes)
break;
adev->mes.compute_hqd_mask[i] = adev->gfx.disable_kq ? 0xF : 0xC;
adev->mes.compute_hqd_mask[i] =
adev->gfx.disable_kq ? 0xF : (queue_mask & ~reserved_queue_mask);
}
num_pipes = adev->sdma.num_instances;
@ -156,7 +167,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
adev->mes.sdma_hqd_mask[i] = 0xfc;
}
for (i = 0; i < AMDGPU_MAX_MES_PIPES; i++) {
for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) {
r = amdgpu_device_wb_get(adev, &adev->mes.sch_ctx_offs[i]);
if (r) {
dev_err(adev->dev,
@ -192,16 +203,18 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
goto error_doorbell;
if (adev->mes.hung_queue_db_array_size) {
r = amdgpu_bo_create_kernel(adev,
adev->mes.hung_queue_db_array_size * sizeof(u32),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_GTT,
&adev->mes.hung_queue_db_array_gpu_obj,
&adev->mes.hung_queue_db_array_gpu_addr,
&adev->mes.hung_queue_db_array_cpu_addr);
if (r) {
dev_warn(adev->dev, "failed to create MES hung db array buffer (%d)", r);
goto error_doorbell;
for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) {
r = amdgpu_bo_create_kernel(adev,
adev->mes.hung_queue_db_array_size * sizeof(u32),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_GTT,
&adev->mes.hung_queue_db_array_gpu_obj[i],
&adev->mes.hung_queue_db_array_gpu_addr[i],
&adev->mes.hung_queue_db_array_cpu_addr[i]);
if (r) {
dev_warn(adev->dev, "failed to create MES hung db array buffer (%d)", r);
goto error_doorbell;
}
}
}
@ -210,12 +223,16 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
error_doorbell:
amdgpu_mes_doorbell_free(adev);
error:
for (i = 0; i < AMDGPU_MAX_MES_PIPES; i++) {
for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) {
if (adev->mes.sch_ctx_ptr[i])
amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs[i]);
if (adev->mes.query_status_fence_ptr[i])
amdgpu_device_wb_free(adev,
adev->mes.query_status_fence_offs[i]);
if (adev->mes.hung_queue_db_array_gpu_obj[i])
amdgpu_bo_free_kernel(&adev->mes.hung_queue_db_array_gpu_obj[i],
&adev->mes.hung_queue_db_array_gpu_addr[i],
&adev->mes.hung_queue_db_array_cpu_addr[i]);
}
idr_destroy(&adev->mes.pasid_idr);
@ -229,16 +246,17 @@ error:
void amdgpu_mes_fini(struct amdgpu_device *adev)
{
int i;
amdgpu_bo_free_kernel(&adev->mes.hung_queue_db_array_gpu_obj,
&adev->mes.hung_queue_db_array_gpu_addr,
&adev->mes.hung_queue_db_array_cpu_addr);
int num_xcc = adev->gfx.xcc_mask ? NUM_XCC(adev->gfx.xcc_mask) : 1;
amdgpu_bo_free_kernel(&adev->mes.event_log_gpu_obj,
&adev->mes.event_log_gpu_addr,
&adev->mes.event_log_cpu_addr);
for (i = 0; i < AMDGPU_MAX_MES_PIPES; i++) {
for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) {
amdgpu_bo_free_kernel(&adev->mes.hung_queue_db_array_gpu_obj[i],
&adev->mes.hung_queue_db_array_gpu_addr[i],
&adev->mes.hung_queue_db_array_cpu_addr[i]);
if (adev->mes.sch_ctx_ptr[i])
amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs[i]);
if (adev->mes.query_status_fence_ptr[i])
@ -304,13 +322,14 @@ int amdgpu_mes_resume(struct amdgpu_device *adev)
}
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring)
struct amdgpu_ring *ring, uint32_t xcc_id)
{
struct mes_map_legacy_queue_input queue_input;
int r;
memset(&queue_input, 0, sizeof(queue_input));
queue_input.xcc_id = xcc_id;
queue_input.queue_type = ring->funcs->type;
queue_input.doorbell_offset = ring->doorbell_index;
queue_input.pipe_id = ring->pipe;
@ -330,11 +349,12 @@ int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring,
enum amdgpu_unmap_queues_action action,
u64 gpu_addr, u64 seq)
u64 gpu_addr, u64 seq, uint32_t xcc_id)
{
struct mes_unmap_legacy_queue_input queue_input;
int r;
queue_input.xcc_id = xcc_id;
queue_input.action = action;
queue_input.queue_type = ring->funcs->type;
queue_input.doorbell_offset = ring->doorbell_index;
@ -355,13 +375,15 @@ int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring,
unsigned int vmid,
bool use_mmio)
bool use_mmio,
uint32_t xcc_id)
{
struct mes_reset_queue_input queue_input;
int r;
memset(&queue_input, 0, sizeof(queue_input));
queue_input.xcc_id = xcc_id;
queue_input.queue_type = ring->funcs->type;
queue_input.doorbell_offset = ring->doorbell_index;
queue_input.me_id = ring->me;
@ -393,11 +415,11 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
int queue_type,
bool detect_only,
unsigned int *hung_db_num,
u32 *hung_db_array)
u32 *hung_db_array,
uint32_t xcc_id)
{
struct mes_detect_and_reset_queue_input input;
u32 *db_array = adev->mes.hung_queue_db_array_cpu_addr;
u32 *db_array = adev->mes.hung_queue_db_array_cpu_addr[xcc_id];
int r, i;
if (!hung_db_num || !hung_db_array)
@ -409,7 +431,7 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
return -EINVAL;
/* Clear the doorbell array before detection */
memset(adev->mes.hung_queue_db_array_cpu_addr, AMDGPU_MES_INVALID_DB_OFFSET,
memset(adev->mes.hung_queue_db_array_cpu_addr[xcc_id], AMDGPU_MES_INVALID_DB_OFFSET,
adev->mes.hung_queue_db_array_size * sizeof(u32));
input.queue_type = queue_type;
input.detect_only = detect_only;
@ -436,7 +458,8 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
return r;
}
uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg)
uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t xcc_id)
{
struct mes_misc_op_input op_input;
int r, val = 0;
@ -450,6 +473,7 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg)
}
read_val_gpu_addr = adev->wb.gpu_addr + (addr_offset * 4);
read_val_ptr = (uint32_t *)&adev->wb.wb[addr_offset];
op_input.xcc_id = xcc_id;
op_input.op = MES_MISC_OP_READ_REG;
op_input.read_reg.reg_offset = reg;
op_input.read_reg.buffer_addr = read_val_gpu_addr;
@ -473,12 +497,13 @@ error:
return val;
}
int amdgpu_mes_wreg(struct amdgpu_device *adev,
uint32_t reg, uint32_t val)
int amdgpu_mes_wreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t val, uint32_t xcc_id)
{
struct mes_misc_op_input op_input;
int r;
op_input.xcc_id = xcc_id;
op_input.op = MES_MISC_OP_WRITE_REG;
op_input.write_reg.reg_offset = reg;
op_input.write_reg.reg_value = val;
@ -501,11 +526,13 @@ error:
int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev,
uint32_t reg0, uint32_t reg1,
uint32_t ref, uint32_t mask)
uint32_t ref, uint32_t mask,
uint32_t xcc_id)
{
struct mes_misc_op_input op_input;
int r;
op_input.xcc_id = xcc_id;
op_input.op = MES_MISC_OP_WRM_REG_WR_WAIT;
op_input.wrm_reg.reg0 = reg0;
op_input.wrm_reg.reg1 = reg1;
@ -530,14 +557,23 @@ error:
int amdgpu_mes_hdp_flush(struct amdgpu_device *adev)
{
uint32_t hdp_flush_req_offset, hdp_flush_done_offset, ref_and_mask;
uint32_t hdp_flush_req_offset, hdp_flush_done_offset;
struct amdgpu_ring *mes_ring;
uint32_t ref_and_mask = 0, reg_mem_engine = 0;
if (!adev->gfx.funcs->get_hdp_flush_mask) {
dev_err(adev->dev, "mes hdp flush is not supported.\n");
return -EINVAL;
}
mes_ring = &adev->mes.ring[0];
hdp_flush_req_offset = adev->nbio.funcs->get_hdp_flush_req_offset(adev);
hdp_flush_done_offset = adev->nbio.funcs->get_hdp_flush_done_offset(adev);
ref_and_mask = adev->nbio.hdp_flush_reg->ref_and_mask_cp0;
adev->gfx.funcs->get_hdp_flush_mask(mes_ring, &ref_and_mask, &reg_mem_engine);
return amdgpu_mes_reg_write_reg_wait(adev, hdp_flush_req_offset, hdp_flush_done_offset,
ref_and_mask, ref_and_mask);
ref_and_mask, ref_and_mask, 0);
}
int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
@ -545,7 +581,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
uint32_t spi_gdbg_per_vmid_cntl,
const uint32_t *tcp_watch_cntl,
uint32_t flags,
bool trap_en)
bool trap_en,
uint32_t xcc_id)
{
struct mes_misc_op_input op_input = {0};
int r;
@ -556,6 +593,7 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
return -EINVAL;
}
op_input.xcc_id = xcc_id;
op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;
op_input.set_shader_debugger.process_context_addr = process_context_addr;
op_input.set_shader_debugger.flags.u32all = flags;
@ -584,7 +622,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
}
int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev,
uint64_t process_context_addr)
uint64_t process_context_addr,
uint32_t xcc_id)
{
struct mes_misc_op_input op_input = {0};
int r;
@ -595,6 +634,7 @@ int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev,
return -EINVAL;
}
op_input.xcc_id = xcc_id;
op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;
op_input.set_shader_debugger.process_context_addr = process_context_addr;
op_input.set_shader_debugger.flags.process_ctx_flush = true;

View file

@ -58,11 +58,20 @@ enum amdgpu_mes_priority_level {
struct amdgpu_mes_funcs;
enum amdgpu_mes_pipe {
AMDGPU_MES_SCHED_PIPE = 0,
AMDGPU_MES_KIQ_PIPE,
AMDGPU_MES_PIPE_0 = 0,
AMDGPU_MES_PIPE_1,
AMDGPU_MAX_MES_PIPES = 2,
};
#define AMDGPU_MES_SCHED_PIPE AMDGPU_MES_PIPE_0
#define AMDGPU_MES_KIQ_PIPE AMDGPU_MES_PIPE_1
#define AMDGPU_MAX_MES_INST_PIPES \
(AMDGPU_MAX_MES_PIPES * AMDGPU_MAX_GC_INSTANCES)
#define MES_PIPE_INST(xcc_id, pipe_id) \
(xcc_id * AMDGPU_MAX_MES_PIPES + pipe_id)
struct amdgpu_mes {
struct amdgpu_device *adev;
@ -86,29 +95,29 @@ struct amdgpu_mes {
uint64_t default_process_quantum;
uint64_t default_gang_quantum;
struct amdgpu_ring ring[AMDGPU_MAX_MES_PIPES];
spinlock_t ring_lock[AMDGPU_MAX_MES_PIPES];
struct amdgpu_ring ring[AMDGPU_MAX_MES_INST_PIPES];
spinlock_t ring_lock[AMDGPU_MAX_MES_INST_PIPES];
const struct firmware *fw[AMDGPU_MAX_MES_PIPES];
/* mes ucode */
struct amdgpu_bo *ucode_fw_obj[AMDGPU_MAX_MES_PIPES];
uint64_t ucode_fw_gpu_addr[AMDGPU_MAX_MES_PIPES];
uint32_t *ucode_fw_ptr[AMDGPU_MAX_MES_PIPES];
struct amdgpu_bo *ucode_fw_obj[AMDGPU_MAX_MES_INST_PIPES];
uint64_t ucode_fw_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
uint32_t *ucode_fw_ptr[AMDGPU_MAX_MES_INST_PIPES];
uint64_t uc_start_addr[AMDGPU_MAX_MES_PIPES];
/* mes ucode data */
struct amdgpu_bo *data_fw_obj[AMDGPU_MAX_MES_PIPES];
uint64_t data_fw_gpu_addr[AMDGPU_MAX_MES_PIPES];
uint32_t *data_fw_ptr[AMDGPU_MAX_MES_PIPES];
struct amdgpu_bo *data_fw_obj[AMDGPU_MAX_MES_INST_PIPES];
uint64_t data_fw_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
uint32_t *data_fw_ptr[AMDGPU_MAX_MES_INST_PIPES];
uint64_t data_start_addr[AMDGPU_MAX_MES_PIPES];
/* eop gpu obj */
struct amdgpu_bo *eop_gpu_obj[AMDGPU_MAX_MES_PIPES];
uint64_t eop_gpu_addr[AMDGPU_MAX_MES_PIPES];
struct amdgpu_bo *eop_gpu_obj[AMDGPU_MAX_MES_INST_PIPES];
uint64_t eop_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
void *mqd_backup[AMDGPU_MAX_MES_PIPES];
struct amdgpu_irq_src irq[AMDGPU_MAX_MES_PIPES];
void *mqd_backup[AMDGPU_MAX_MES_INST_PIPES];
struct amdgpu_irq_src irq[AMDGPU_MAX_MES_INST_PIPES];
uint32_t vmid_mask_gfxhub;
uint32_t vmid_mask_mmhub;
@ -116,18 +125,21 @@ struct amdgpu_mes {
uint32_t compute_hqd_mask[AMDGPU_MES_MAX_COMPUTE_PIPES];
uint32_t sdma_hqd_mask[AMDGPU_MES_MAX_SDMA_PIPES];
uint32_t aggregated_doorbells[AMDGPU_MES_PRIORITY_NUM_LEVELS];
uint32_t sch_ctx_offs[AMDGPU_MAX_MES_PIPES];
uint64_t sch_ctx_gpu_addr[AMDGPU_MAX_MES_PIPES];
uint64_t *sch_ctx_ptr[AMDGPU_MAX_MES_PIPES];
uint32_t query_status_fence_offs[AMDGPU_MAX_MES_PIPES];
uint64_t query_status_fence_gpu_addr[AMDGPU_MAX_MES_PIPES];
uint64_t *query_status_fence_ptr[AMDGPU_MAX_MES_PIPES];
uint32_t sch_ctx_offs[AMDGPU_MAX_MES_INST_PIPES];
uint64_t sch_ctx_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
uint64_t *sch_ctx_ptr[AMDGPU_MAX_MES_INST_PIPES];
uint32_t query_status_fence_offs[AMDGPU_MAX_MES_INST_PIPES];
uint64_t query_status_fence_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
uint64_t *query_status_fence_ptr[AMDGPU_MAX_MES_INST_PIPES];
uint32_t saved_flags;
/* initialize kiq pipe */
int (*kiq_hw_init)(struct amdgpu_device *adev);
int (*kiq_hw_fini)(struct amdgpu_device *adev);
int (*kiq_hw_init)(struct amdgpu_device *adev,
uint32_t xcc_id);
int (*kiq_hw_fini)(struct amdgpu_device *adev,
uint32_t xcc_id);
/* MES doorbells */
uint32_t db_start_dw_offset;
@ -150,9 +162,15 @@ struct amdgpu_mes {
int hung_queue_db_array_size;
int hung_queue_hqd_info_offset;
struct amdgpu_bo *hung_queue_db_array_gpu_obj;
uint64_t hung_queue_db_array_gpu_addr;
void *hung_queue_db_array_cpu_addr;
struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_PIPES];
uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_PIPES];
void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_PIPES];
/* cooperative dispatch */
bool enable_coop_mode;
int master_xcc_ids[AMDGPU_MAX_MES_INST_PIPES];
struct amdgpu_bo *shared_cmd_buf_obj[AMDGPU_MAX_MES_INST_PIPES];
uint64_t shared_cmd_buf_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
};
struct amdgpu_mes_gang {
@ -208,6 +226,7 @@ struct amdgpu_mes_gang_properties {
};
struct mes_add_queue_input {
uint32_t xcc_id;
uint32_t process_id;
uint64_t page_table_base_addr;
uint64_t process_va_start;
@ -234,15 +253,19 @@ struct mes_add_queue_input {
uint32_t is_aql_queue;
uint32_t queue_size;
uint32_t exclusively_scheduled;
uint32_t sh_mem_config_data;
uint32_t vm_cntx_cntl;
};
struct mes_remove_queue_input {
uint32_t xcc_id;
uint32_t doorbell_offset;
uint64_t gang_context_addr;
bool remove_queue_after_reset;
};
struct mes_map_legacy_queue_input {
uint32_t xcc_id;
uint32_t queue_type;
uint32_t doorbell_offset;
uint32_t pipe_id;
@ -252,6 +275,7 @@ struct mes_map_legacy_queue_input {
};
struct mes_unmap_legacy_queue_input {
uint32_t xcc_id;
enum amdgpu_unmap_queues_action action;
uint32_t queue_type;
uint32_t doorbell_offset;
@ -262,6 +286,7 @@ struct mes_unmap_legacy_queue_input {
};
struct mes_suspend_gang_input {
uint32_t xcc_id;
bool suspend_all_gangs;
uint64_t gang_context_addr;
uint64_t suspend_fence_addr;
@ -269,11 +294,13 @@ struct mes_suspend_gang_input {
};
struct mes_resume_gang_input {
uint32_t xcc_id;
bool resume_all_gangs;
uint64_t gang_context_addr;
};
struct mes_reset_queue_input {
uint32_t xcc_id;
uint32_t queue_type;
uint32_t doorbell_offset;
bool use_mmio;
@ -309,7 +336,8 @@ enum mes_misc_opcode {
};
struct mes_misc_op_input {
enum mes_misc_opcode op;
uint32_t xcc_id;
enum mes_misc_opcode op;
union {
struct {
@ -395,8 +423,10 @@ struct amdgpu_mes_funcs {
struct mes_inv_tlbs_pasid_input *input);
};
#define amdgpu_mes_kiq_hw_init(adev) (adev)->mes.kiq_hw_init((adev))
#define amdgpu_mes_kiq_hw_fini(adev) (adev)->mes.kiq_hw_fini((adev))
#define amdgpu_mes_kiq_hw_init(adev, xcc_id) \
(adev)->mes.kiq_hw_init((adev), (xcc_id))
#define amdgpu_mes_kiq_hw_fini(adev, xcc_id) \
(adev)->mes.kiq_hw_fini((adev), (xcc_id))
int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe);
int amdgpu_mes_init(struct amdgpu_device *adev);
@ -406,38 +436,42 @@ int amdgpu_mes_suspend(struct amdgpu_device *adev);
int amdgpu_mes_resume(struct amdgpu_device *adev);
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
struct amdgpu_ring *ring, uint32_t xcc_id);
int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring,
enum amdgpu_unmap_queues_action action,
u64 gpu_addr, u64 seq);
u64 gpu_addr, u64 seq, uint32_t xcc_id);
int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring,
unsigned int vmid,
bool use_mmio);
bool use_mmio,
uint32_t xcc_id);
int amdgpu_mes_get_hung_queue_db_array_size(struct amdgpu_device *adev);
int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
int queue_type,
bool detect_only,
unsigned int *hung_db_num,
u32 *hung_db_array);
u32 *hung_db_array,
uint32_t xcc_id);
uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg);
uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t xcc_id);
int amdgpu_mes_wreg(struct amdgpu_device *adev,
uint32_t reg, uint32_t val);
uint32_t reg, uint32_t val, uint32_t xcc_id);
int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev,
uint32_t reg0, uint32_t reg1,
uint32_t ref, uint32_t mask);
uint32_t ref, uint32_t mask, uint32_t xcc_id);
int amdgpu_mes_hdp_flush(struct amdgpu_device *adev);
int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
uint64_t process_context_addr,
uint32_t spi_gdbg_per_vmid_cntl,
const uint32_t *tcp_watch_cntl,
uint32_t flags,
bool trap_en);
bool trap_en,
uint32_t xcc_id);
int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev,
uint64_t process_context_addr);
uint64_t process_context_addr, uint32_t xcc_id);
uint32_t amdgpu_mes_get_aggregated_doorbell_index(struct amdgpu_device *adev,
enum amdgpu_mes_priority_level prio);

View file

@ -1050,7 +1050,8 @@ static const char * const amdgpu_vram_names[] = {
"DDR5",
"LPDDR4",
"LPDDR5",
"HBM3E"
"HBM3E",
"HBM4"
};
/**
@ -1080,10 +1081,10 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
adev->gmc.aper_size);
}
DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
drm_info(adev_to_drm(adev), "Detected VRAM RAM=%lluM, BAR=%lluM\n",
adev->gmc.mc_vram_size >> 20,
(unsigned long long)adev->gmc.aper_size >> 20);
DRM_INFO("RAM width %dbits %s\n",
drm_info(adev_to_drm(adev), "RAM width %dbits %s\n",
adev->gmc.vram_width, amdgpu_vram_names[adev->gmc.vram_type]);
return amdgpu_ttm_init(adev);
}
@ -1125,6 +1126,10 @@ int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags)
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct amdgpu_bo_user *ubo;
/* MMIO_REMAP is BAR I/O space; tiling should never be used here. */
WARN_ON_ONCE(bo->tbo.resource &&
bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP);
BUG_ON(bo->tbo.type == ttm_bo_type_kernel);
if (adev->family <= AMDGPU_FAMILY_CZ &&
AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT) > 6)
@ -1147,6 +1152,13 @@ void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 *tiling_flags)
{
struct amdgpu_bo_user *ubo;
/*
* MMIO_REMAP BOs are not real VRAM/GTT memory but a fixed BAR I/O window.
* They should never go through GEM tiling helpers.
*/
WARN_ON_ONCE(bo->tbo.resource &&
bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP);
BUG_ON(bo->tbo.type == ttm_bo_type_kernel);
dma_resv_assert_held(bo->tbo.base.resv);
ubo = to_amdgpu_bo_user(bo);
@ -1321,8 +1333,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
if (r)
goto out;
r = amdgpu_fill_buffer(abo, 0, &bo->base._resv, &fence, true,
AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
r = amdgpu_fill_buffer(&adev->mman.clear_entity, abo, 0, &bo->base._resv,
&fence, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
if (WARN_ON(r))
goto out;

View file

@ -39,6 +39,8 @@
#include "psp_v13_0.h"
#include "psp_v13_0_4.h"
#include "psp_v14_0.h"
#include "psp_v15_0.h"
#include "psp_v15_0_8.h"
#include "amdgpu_ras.h"
#include "amdgpu_securedisplay.h"
@ -259,6 +261,13 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
psp_v14_0_set_psp_funcs(psp);
psp->boot_time_tmr = false;
break;
case IP_VERSION(15, 0, 0):
psp_v15_0_0_set_psp_funcs(psp);
psp->boot_time_tmr = false;
break;
case IP_VERSION(15, 0, 8):
psp_v15_0_8_set_psp_funcs(psp);
break;
default:
return -EINVAL;
}
@ -893,18 +902,12 @@ static int psp_tmr_init(struct psp_context *psp)
static bool psp_skip_tmr(struct psp_context *psp)
{
switch (amdgpu_ip_version(psp->adev, MP0_HWIP, 0)) {
case IP_VERSION(11, 0, 9):
case IP_VERSION(11, 0, 7):
case IP_VERSION(13, 0, 2):
case IP_VERSION(13, 0, 6):
case IP_VERSION(13, 0, 10):
case IP_VERSION(13, 0, 12):
case IP_VERSION(13, 0, 14):
return true;
default:
return false;
}
u32 ip_version = amdgpu_ip_version(psp->adev, MP0_HWIP, 0);
if (amdgpu_sriov_vf(psp->adev))
return (ip_version >= IP_VERSION(11, 0, 7)) ? true : false;
else
return (!psp->boot_time_tmr || !psp->autoload_supported) ? false : true;
}
static int psp_tmr_load(struct psp_context *psp)
@ -912,10 +915,7 @@ static int psp_tmr_load(struct psp_context *psp)
int ret;
struct psp_gfx_cmd_resp *cmd;
/* For Navi12 and CHIP_SIENNA_CICHLID SRIOV, do not set up TMR.
* Already set up by host driver.
*/
if (amdgpu_sriov_vf(psp->adev) && psp_skip_tmr(psp))
if (psp_skip_tmr(psp))
return 0;
cmd = acquire_psp_cmd_buf(psp);
@ -947,10 +947,7 @@ static int psp_tmr_unload(struct psp_context *psp)
int ret;
struct psp_gfx_cmd_resp *cmd;
/* skip TMR unload for Navi12 and CHIP_SIENNA_CICHLID SRIOV,
* as TMR is not loaded at all
*/
if (amdgpu_sriov_vf(psp->adev) && psp_skip_tmr(psp))
if (psp_skip_tmr(psp))
return 0;
cmd = acquire_psp_cmd_buf(psp);
@ -1995,6 +1992,7 @@ int psp_ras_initialize(struct psp_context *psp)
ras_cmd->ras_in_message.init_flags.nps_mode =
adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
ras_cmd->ras_in_message.init_flags.active_umc_mask = adev->umc.active_mask;
ras_cmd->ras_in_message.init_flags.vram_type = (uint8_t)adev->gmc.vram_type;
ret = psp_ta_load(psp, &psp->ras_context.context);
@ -2620,18 +2618,16 @@ skip_pin_bo:
return ret;
}
if (!psp->boot_time_tmr || !psp->autoload_supported) {
ret = psp_tmr_load(psp);
if (ret) {
dev_err(adev->dev, "PSP load tmr failed!\n");
return ret;
}
ret = psp_tmr_load(psp);
if (ret) {
dev_err(adev->dev, "PSP load tmr failed!\n");
return ret;
}
return 0;
}
static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
int amdgpu_psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type)
{
switch (ucode->ucode_id) {
@ -2719,6 +2715,12 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
case AMDGPU_UCODE_ID_RLC_DRAM:
*type = GFX_FW_TYPE_RLC_DRAM_BOOT;
break;
case AMDGPU_UCODE_ID_RLC_IRAM_1:
*type = GFX_FW_TYPE_RLX6_UCODE_CORE1;
break;
case AMDGPU_UCODE_ID_RLC_DRAM_1:
*type = GFX_FW_TYPE_RLX6_DRAM_BOOT_CORE1;
break;
case AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS:
*type = GFX_FW_TYPE_GLOBAL_TAP_DELAYS;
break;
@ -2887,6 +2889,8 @@ static void psp_print_fw_hdr(struct psp_context *psp,
amdgpu_ucode_print_gfx_hdr(hdr);
break;
case AMDGPU_UCODE_ID_RLC_G:
case AMDGPU_UCODE_ID_RLC_DRAM_1:
case AMDGPU_UCODE_ID_RLC_IRAM_1:
hdr = (struct common_firmware_header *)adev->gfx.rlc_fw->data;
amdgpu_ucode_print_rlc_hdr(hdr);
break;
@ -2911,10 +2915,9 @@ static int psp_prep_load_ip_fw_cmd_buf(struct psp_context *psp,
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
ret = psp_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
ret = psp_get_fw_type(psp, ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
if (ret)
dev_err(psp->adev->dev, "Unknown firmware type\n");
dev_err(psp->adev->dev, "Unknown firmware type %d\n", ucode->ucode_id);
return ret;
}
@ -3077,7 +3080,11 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(11, 0, 11) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(11, 0, 12)) &&
IP_VERSION(11, 0, 12) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 0) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8)) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 ||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3))
@ -4531,3 +4538,19 @@ const struct amdgpu_ip_block_version psp_v14_0_ip_block = {
.rev = 0,
.funcs = &psp_ip_funcs,
};
const struct amdgpu_ip_block_version psp_v15_0_ip_block = {
.type = AMD_IP_BLOCK_TYPE_PSP,
.major = 15,
.minor = 0,
.rev = 0,
.funcs = &psp_ip_funcs,
};
const struct amdgpu_ip_block_version psp_v15_0_8_ip_block = {
.type = AMD_IP_BLOCK_TYPE_PSP,
.major = 15,
.minor = 0,
.rev = 8,
.funcs = &psp_ip_funcs,
};

View file

@ -172,6 +172,8 @@ struct psp_funcs {
bool (*is_reload_needed)(struct psp_context *psp);
int (*reg_program_no_ring)(struct psp_context *psp, uint32_t val,
enum psp_reg_prog_id id);
int (*get_fw_type)(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type);
};
struct ta_funcs {
@ -524,6 +526,10 @@ struct amdgpu_psp_funcs {
((psp)->funcs->reg_program_no_ring ? \
(psp)->funcs->reg_program_no_ring((psp), val, id) : -EINVAL)
#define psp_get_fw_type(psp, ucode, type) \
((psp)->funcs->get_fw_type ? \
(psp)->funcs->get_fw_type(ucode, type):amdgpu_psp_get_fw_type(ucode, type))
extern const struct amd_ip_funcs psp_ip_funcs;
extern const struct amdgpu_ip_block_version psp_v3_1_ip_block;
@ -534,6 +540,8 @@ extern const struct amdgpu_ip_block_version psp_v12_0_ip_block;
extern const struct amdgpu_ip_block_version psp_v13_0_ip_block;
extern const struct amdgpu_ip_block_version psp_v13_0_4_ip_block;
extern const struct amdgpu_ip_block_version psp_v14_0_ip_block;
extern const struct amdgpu_ip_block_version psp_v15_0_ip_block;
extern const struct amdgpu_ip_block_version psp_v15_0_8_ip_block;
int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
uint32_t field_val, uint32_t mask, uint32_t flags);
@ -621,6 +629,8 @@ bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev);
int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val,
enum psp_reg_prog_id id);
void amdgpu_psp_debugfs_init(struct amdgpu_device *adev);
int amdgpu_psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type);
#endif

View file

@ -237,8 +237,13 @@ static int amdgpu_check_address_validity(struct amdgpu_device *adev,
(address >= RAS_UMC_INJECT_ADDR_LIMIT))
return -EFAULT;
count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
if (amdgpu_uniras_enabled(adev))
count = amdgpu_ras_mgr_lookup_bad_pages_in_a_row(adev, address,
page_pfns, ARRAY_SIZE(page_pfns));
else
count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
address, page_pfns, ARRAY_SIZE(page_pfns));
if (count <= 0)
return -EPERM;
@ -1917,8 +1922,6 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
for (i = 0; i < bps_count; i++) {
address = ((uint64_t)bps[i].bp) << AMDGPU_GPU_PAGE_SHIFT;
if (amdgpu_ras_check_critical_address(adev, address))
continue;
bps[i].size = AMDGPU_GPU_PAGE_SIZE;
@ -1931,6 +1934,10 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
else
bps[i].flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED;
if ((bps[i].flags != AMDGPU_RAS_RETIRE_PAGE_RESERVED) &&
amdgpu_ras_check_critical_address(adev, address))
bps[i].flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED;
s += scnprintf(&buf[s], element_size + 1,
"0x%08x : 0x%08x : %1s\n",
bps[i].bp,
@ -3076,6 +3083,11 @@ static int __amdgpu_ras_restore_bad_pages(struct amdgpu_device *adev,
struct ras_err_handler_data *data = con->eh_data;
for (j = 0; j < count; j++) {
if (!data->space_left &&
amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
return -ENOMEM;
}
if (amdgpu_ras_check_bad_page_unlock(con,
bps[j].retired_page << AMDGPU_GPU_PAGE_SHIFT)) {
data->count++;
@ -3083,11 +3095,6 @@ static int __amdgpu_ras_restore_bad_pages(struct amdgpu_device *adev,
continue;
}
if (!data->space_left &&
amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
return -ENOMEM;
}
amdgpu_ras_reserve_page(adev, bps[j].retired_page);
memcpy(&data->bps[data->count], &(bps[j]),
@ -3249,8 +3256,6 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
/* deal with retire_unit records a time */
ret = __amdgpu_ras_convert_rec_array_from_rom(adev,
&bps[i], &err_data, nps);
if (ret)
con->bad_page_num -= adev->umc.retire_unit;
i += (adev->umc.retire_unit - 1);
} else {
break;
@ -3263,8 +3268,6 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
for (; i < pages; i++) {
ret = __amdgpu_ras_convert_rec_from_rom(adev,
&bps[i], &err_data, nps);
if (ret)
con->bad_page_num -= adev->umc.retire_unit;
}
con->eh_data->count_saved = con->eh_data->count;
@ -4421,10 +4424,10 @@ static int amdgpu_persistent_edc_harvesting(struct amdgpu_device *adev,
return 0;
if (amdgpu_ras_query_error_status(adev, &info) != 0)
DRM_WARN("RAS init harvest failure");
drm_warn(adev_to_drm(adev), "RAS init query failure");
if (amdgpu_ras_reset_error_status(adev, ras_block->block) != 0)
DRM_WARN("RAS init harvest reset failure");
drm_warn(adev_to_drm(adev), "RAS init harvest reset failure");
return 0;
}

View file

@ -76,8 +76,12 @@ unsigned int amdgpu_ring_max_ibs(enum amdgpu_ring_type type)
* @ring: amdgpu_ring structure holding ring information
* @ndw: number of dwords to allocate in the ring buffer
*
* Allocate @ndw dwords in the ring buffer (all asics).
* Returns 0 on success, error on failure.
* Allocate @ndw dwords in the ring buffer. The number of dwords should be the
* sum of all commands written to the ring.
*
* Returns:
* 0 on success, otherwise -ENOMEM if it tries to allocate more than the
* maximum dword allowed for one submission.
*/
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw)
{
@ -123,7 +127,8 @@ static void amdgpu_ring_alloc_reemit(struct amdgpu_ring *ring, unsigned int ndw)
ring->funcs->begin_use(ring);
}
/** amdgpu_ring_insert_nop - insert NOP packets
/**
* amdgpu_ring_insert_nop - insert NOP packets
*
* @ring: amdgpu_ring structure holding ring information
* @count: the number of NOP packets to insert
@ -186,7 +191,7 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring)
uint32_t count;
if (ring->count_dw < 0)
DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
drm_err(adev_to_drm(ring->adev), "writing more dwords to the ring than expected!\n");
/* We pad to match fetch size */
count = ring->funcs->align_mask + 1 -

View file

@ -62,6 +62,8 @@ enum amdgpu_ring_priority_level {
#define AMDGPU_FENCE_FLAG_64BIT (1 << 0)
#define AMDGPU_FENCE_FLAG_INT (1 << 1)
#define AMDGPU_FENCE_FLAG_TC_WB_ONLY (1 << 2)
/* Ensure the execution in case of preemption or reset */
#define AMDGPU_FENCE_FLAG_EXEC (1 << 3)
#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched)
@ -144,10 +146,15 @@ struct amdgpu_fence {
struct amdgpu_ring *ring;
ktime_t start_timestamp;
/* wptr for the fence for resets */
/* wptr for the total submission for resets */
u64 wptr;
/* fence context for resets */
u64 context;
/* has this fence been reemitted */
unsigned int reemitted;
/* wptr for the fence for the submission */
u64 fence_wptr_start;
u64 fence_wptr_end;
};
extern const struct drm_sched_backend_ops amdgpu_sched_ops;

View file

@ -515,6 +515,40 @@ static void amdgpu_gfx_rlc_init_microcode_v2_4(struct amdgpu_device *adev)
}
}
static void amdgpu_gfx_rlc_init_microcode_v2_5(struct amdgpu_device *adev)
{
const struct rlc_firmware_header_v2_5 *rlc_hdr;
struct amdgpu_firmware_info *info;
rlc_hdr = (const struct rlc_firmware_header_v2_5 *)adev->gfx.rlc_fw->data;
adev->gfx.rlc.rlc_1_iram_ucode_size_bytes =
le32_to_cpu(rlc_hdr->rlc_1_iram_ucode_size_bytes);
adev->gfx.rlc.rlc_1_iram_ucode = (u8 *)rlc_hdr +
le32_to_cpu(rlc_hdr->rlc_1_iram_ucode_offset_bytes);
adev->gfx.rlc.rlc_1_dram_ucode_size_bytes =
le32_to_cpu(rlc_hdr->rlc_1_dram_ucode_size_bytes);
adev->gfx.rlc.rlc_1_dram_ucode = (u8 *)rlc_hdr +
le32_to_cpu(rlc_hdr->rlc_1_dram_ucode_offset_bytes);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
if (adev->gfx.rlc.rlc_1_iram_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_IRAM_1];
info->ucode_id = AMDGPU_UCODE_ID_RLC_IRAM_1;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.rlc_1_iram_ucode_size_bytes, PAGE_SIZE);
}
if (adev->gfx.rlc.rlc_1_dram_ucode_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_DRAM_1];
info->ucode_id = AMDGPU_UCODE_ID_RLC_DRAM_1;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.rlc_1_dram_ucode_size_bytes, PAGE_SIZE);
}
}
}
int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
uint16_t version_major,
uint16_t version_minor)
@ -545,6 +579,7 @@ int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
amdgpu_gfx_rlc_init_microcode_v2_3(adev);
if (version_minor == 4)
amdgpu_gfx_rlc_init_microcode_v2_4(adev);
if (version_minor == 5)
amdgpu_gfx_rlc_init_microcode_v2_5(adev);
return 0;
}

View file

@ -257,7 +257,8 @@ struct amdgpu_rlc_funcs {
void (*stop)(struct amdgpu_device *adev);
void (*reset)(struct amdgpu_device *adev);
void (*start)(struct amdgpu_device *adev);
void (*update_spm_vmid)(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned vmid);
void (*update_spm_vmid)(struct amdgpu_device *adev, int xcc_id,
struct amdgpu_ring *ring, unsigned vmid);
bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
};
@ -269,6 +270,15 @@ struct amdgpu_rlcg_reg_access_ctrl {
uint32_t grbm_cntl;
uint32_t grbm_idx;
uint32_t spare_int;
uint32_t vfi_cmd;
uint32_t vfi_stat;
uint32_t vfi_addr;
uint32_t vfi_data;
uint32_t vfi_grbm_cntl;
uint32_t vfi_grbm_idx;
uint32_t vfi_grbm_cntl_data;
uint32_t vfi_grbm_idx_data;
};
struct amdgpu_rlc {
@ -310,6 +320,8 @@ struct amdgpu_rlc {
u32 save_restore_list_srm_size_bytes;
u32 rlc_iram_ucode_size_bytes;
u32 rlc_dram_ucode_size_bytes;
u32 rlc_1_iram_ucode_size_bytes;
u32 rlc_1_dram_ucode_size_bytes;
u32 rlcp_ucode_size_bytes;
u32 rlcv_ucode_size_bytes;
u32 global_tap_delays_ucode_size_bytes;
@ -325,6 +337,8 @@ struct amdgpu_rlc {
u8 *save_restore_list_srm;
u8 *rlc_iram_ucode;
u8 *rlc_dram_ucode;
u8 *rlc_1_iram_ucode;
u8 *rlc_1_dram_ucode;
u8 *rlcp_ucode;
u8 *rlcv_ucode;
u8 *global_tap_delays_ucode;

View file

@ -50,6 +50,11 @@ enum amdgpu_sdma_irq {
#define NUM_SDMA(x) hweight32(x)
struct amdgpu_sdma_csa_info {
u32 size;
u32 alignment;
};
struct amdgpu_sdma_funcs {
int (*stop_kernel_queue)(struct amdgpu_ring *ring);
int (*start_kernel_queue)(struct amdgpu_ring *ring);
@ -65,7 +70,10 @@ struct amdgpu_sdma_instance {
struct amdgpu_ring ring;
struct amdgpu_ring page;
bool burst_nop;
uint32_t aid_id;
union {
uint32_t aid_id;
uint32_t xcc_id;
};
struct amdgpu_bo *sdma_fw_obj;
uint64_t sdma_fw_gpu_addr;
@ -123,7 +131,10 @@ struct amdgpu_sdma {
int num_instances;
uint32_t sdma_mask;
int num_inst_per_aid;
union {
int num_inst_per_aid;
int num_inst_per_xcc;
};
uint32_t srbm_soft_reset;
bool has_page_queue;
struct ras_common_if *ras_if;
@ -133,6 +144,8 @@ struct amdgpu_sdma {
struct list_head reset_callback_list;
bool no_user_submission;
bool disable_uq;
void (*get_csa_info)(struct amdgpu_device *adev,
struct amdgpu_sdma_csa_info *csa_info);
};
/*

View file

@ -27,6 +27,7 @@ enum amdgpu_pkg_type {
AMDGPU_PKG_TYPE_APU = 2,
AMDGPU_PKG_TYPE_CEM = 3,
AMDGPU_PKG_TYPE_OAM = 4,
AMDGPU_PKG_TYPE_BB = 5,
AMDGPU_PKG_TYPE_UNKNOWN,
};
@ -44,6 +45,8 @@ struct amdgpu_smuio_funcs {
u32 (*get_socket_id)(struct amdgpu_device *adev);
enum amdgpu_pkg_type (*get_pkg_type)(struct amdgpu_device *adev);
bool (*is_host_gpu_xgmi_supported)(struct amdgpu_device *adev);
bool (*is_connected_with_ethernet_switch)(struct amdgpu_device *adev);
bool (*is_custom_hbm_supported)(struct amdgpu_device *adev);
u64 (*get_gpu_clock_counter)(struct amdgpu_device *adev);
};

View file

@ -162,13 +162,25 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
*placement = abo->placement;
}
static struct dma_fence *
amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 num_dw)
{
struct amdgpu_ring *ring;
ring = adev->mman.buffer_funcs_ring;
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
return amdgpu_job_submit(job);
}
/**
* amdgpu_ttm_map_buffer - Map memory into the GART windows
* @entity: entity to run the window setup job
* @bo: buffer object to map
* @mem: memory object to map
* @mm_cur: range to map
* @window: which GART window to use
* @ring: DMA ring to use for the copy
* @tmz: if we should setup a TMZ enabled mapping
* @size: in number of bytes to map, out number of bytes mapped
* @addr: resulting address inside the MC address space
@ -176,13 +188,14 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
* Setup one of the GART windows to access a specific piece of memory or return
* the physical address for local memory.
*/
static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct ttm_buffer_object *bo,
struct ttm_resource *mem,
struct amdgpu_res_cursor *mm_cur,
unsigned int window, struct amdgpu_ring *ring,
unsigned int window,
bool tmz, uint64_t *size, uint64_t *addr)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
unsigned int offset, num_pages, num_dw, num_bytes;
uint64_t src_addr, dst_addr;
struct amdgpu_job *job;
@ -223,7 +236,7 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
num_bytes = num_pages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE;
r = amdgpu_job_alloc_with_ib(adev, &adev->mman.high_pr,
r = amdgpu_job_alloc_with_ib(adev, &entity->base,
AMDGPU_FENCE_OWNER_UNDEFINED,
num_dw * 4 + num_bytes,
AMDGPU_IB_POOL_DELAYED, &job,
@ -239,9 +252,6 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
dst_addr, num_bytes, 0);
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, mem);
if (tmz)
flags |= AMDGPU_PTE_TMZ;
@ -259,13 +269,14 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
amdgpu_gart_map_vram_range(adev, pa, 0, num_pages, flags, cpu_addr);
}
dma_fence_put(amdgpu_job_submit(job));
dma_fence_put(amdgpu_ttm_job_submit(adev, job, num_dw));
return 0;
}
/**
* amdgpu_ttm_copy_mem_to_mem - Helper function for copy
* @adev: amdgpu device
* @entity: entity to run the jobs
* @src: buffer/address where to read from
* @dst: buffer/address where to write to
* @size: number of bytes to copy
@ -280,13 +291,13 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
*/
__attribute__((nonnull))
static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
const struct amdgpu_copy_mem *src,
const struct amdgpu_copy_mem *dst,
uint64_t size, bool tmz,
struct dma_resv *resv,
struct dma_fence **f)
{
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_res_cursor src_mm, dst_mm;
struct dma_fence *fence = NULL;
int r = 0;
@ -312,13 +323,13 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
cur_size = min3(src_mm.size, dst_mm.size, 256ULL << 20);
/* Map src to window 0 and dst to window 1. */
r = amdgpu_ttm_map_buffer(src->bo, src->mem, &src_mm,
0, ring, tmz, &cur_size, &from);
r = amdgpu_ttm_map_buffer(entity, src->bo, src->mem, &src_mm,
0, tmz, &cur_size, &from);
if (r)
goto error;
r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, &dst_mm,
1, ring, tmz, &cur_size, &to);
r = amdgpu_ttm_map_buffer(entity, dst->bo, dst->mem, &dst_mm,
1, tmz, &cur_size, &to);
if (r)
goto error;
@ -345,8 +356,8 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
write_compress_disable));
}
r = amdgpu_copy_buffer(ring, from, to, cur_size, resv,
&next, false, true, copy_flags);
r = amdgpu_copy_buffer(adev, entity, from, to, cur_size, resv,
&next, true, copy_flags);
if (r)
goto error;
@ -386,7 +397,9 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
src.offset = 0;
dst.offset = 0;
r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst,
r = amdgpu_ttm_copy_mem_to_mem(adev,
&adev->mman.move_entity,
&src, &dst,
new_mem->size,
amdgpu_bo_encrypted(abo),
bo->base.resv, &fence);
@ -398,8 +411,9 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
struct dma_fence *wipe_fence = NULL;
r = amdgpu_fill_buffer(abo, 0, NULL, &wipe_fence,
false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
r = amdgpu_fill_buffer(&adev->mman.move_entity,
abo, 0, NULL, &wipe_fence,
AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
if (r) {
goto error;
} else if (wipe_fence) {
@ -1062,6 +1076,86 @@ static void amdgpu_ttm_backend_destroy(struct ttm_device *bdev,
kfree(gtt);
}
/**
* amdgpu_ttm_mmio_remap_alloc_sgt - build an sg_table for MMIO_REMAP I/O aperture
* @adev: amdgpu device providing the remap BAR base (adev->rmmio_remap.bus_addr)
* @res: TTM resource of the BO to export; expected to live in AMDGPU_PL_MMIO_REMAP
* @dev: importing device to map for (typically @attach->dev in dma-buf paths)
* @dir: DMA data direction for the importer (passed to dma_map_resource())
* @sgt: output; on success, set to a newly allocated sg_table describing the I/O span
*
* The HDP flush page (AMDGPU_PL_MMIO_REMAP) is a fixed hardware I/O window in a PCI
* BARthere are no struct pages to back it. Importers still need a DMA address list,
* so we synthesize a minimal sg_table and populate it from dma_map_resource(), not
* from pages. Using the common amdgpu_res_cursor walker keeps the offset/size math
* consistent with other TTM/manager users.
*
* - @res is assumed to be a small, contiguous I/O region (typically a single 4 KiB
* page) in AMDGPU_PL_MMIO_REMAP. Callers should validate placement before calling.
* - The sg entry is created with sg_set_page(sg, NULL, ) to reflect I/O space.
* - The mapping uses DMA_ATTR_SKIP_CPU_SYNC because this is MMIO, not cacheable RAM.
* - Peer reachability / p2pdma policy checks must be done by the caller.
*
* Return:
* * 0 on success, with *@sgt set to a valid table that must be freed via
* amdgpu_ttm_mmio_remap_free_sgt().
* * -ENOMEM if allocation of the sg_table fails.
* * -EIO if dma_map_resource() fails.
*
*/
int amdgpu_ttm_mmio_remap_alloc_sgt(struct amdgpu_device *adev,
struct ttm_resource *res,
struct device *dev,
enum dma_data_direction dir,
struct sg_table **sgt)
{
struct amdgpu_res_cursor cur;
dma_addr_t dma;
resource_size_t phys;
struct scatterlist *sg;
int r;
/* Walk the resource once; MMIO_REMAP is expected to be contiguous+small. */
amdgpu_res_first(res, 0, res->size, &cur);
/* Translate byte offset in the remap window into a host physical BAR address. */
phys = adev->rmmio_remap.bus_addr + cur.start;
/* Build a single-entry sg_table mapped as I/O (no struct page backing). */
*sgt = kzalloc(sizeof(**sgt), GFP_KERNEL);
if (!*sgt)
return -ENOMEM;
r = sg_alloc_table(*sgt, 1, GFP_KERNEL);
if (r) {
kfree(*sgt);
return r;
}
sg = (*sgt)->sgl;
sg_set_page(sg, NULL, cur.size, 0); /* WHY: I/O space → no pages */
dma = dma_map_resource(dev, phys, cur.size, dir, DMA_ATTR_SKIP_CPU_SYNC);
if (dma_mapping_error(dev, dma)) {
sg_free_table(*sgt);
kfree(*sgt);
return -EIO;
}
sg_dma_address(sg) = dma;
sg_dma_len(sg) = cur.size;
return 0;
}
void amdgpu_ttm_mmio_remap_free_sgt(struct device *dev,
enum dma_data_direction dir,
struct sg_table *sgt)
{
struct scatterlist *sg = sgt->sgl;
dma_unmap_resource(dev, sg_dma_address(sg), sg_dma_len(sg),
dir, DMA_ATTR_SKIP_CPU_SYNC);
sg_free_table(sgt);
kfree(sgt);
}
/**
* amdgpu_ttm_tt_create - Create a ttm_tt object for a given BO
*
@ -1478,7 +1572,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
memcpy(adev->mman.sdma_access_ptr, buf, len);
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
r = amdgpu_job_alloc_with_ib(adev, &adev->mman.high_pr,
r = amdgpu_job_alloc_with_ib(adev, &adev->mman.default_entity.base,
AMDGPU_FENCE_OWNER_UNDEFINED,
num_dw * 4, AMDGPU_IB_POOL_DELAYED,
&job,
@ -1497,10 +1591,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr,
PAGE_SIZE, 0);
amdgpu_ring_pad_ib(adev->mman.buffer_funcs_ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
fence = amdgpu_job_submit(job);
fence = amdgpu_ttm_job_submit(adev, job, num_dw);
mutex_unlock(&adev->mman.gtt_window_lock);
if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))
@ -1744,7 +1835,13 @@ static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev)
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)))
reserve_size = max(reserve_size, (uint32_t)280 << 20);
else if (!reserve_size)
else if (!adev->bios &&
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 1, 0)) {
if (hweight32(adev->aid_mask) == 1)
reserve_size = max(reserve_size, (uint32_t)128 << 20);
else
reserve_size = max(reserve_size, (uint32_t)144 << 20);
} else if (!reserve_size)
reserve_size = DISCOVERY_TMR_OFFSET;
if (mem_train_support) {
@ -1820,6 +1917,10 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device *adev)
* PAGE_SIZE is <= AMDGPU_GPU_PAGE_SIZE (4K). The BO is created as a regular
* GEM object (amdgpu_bo_create).
*
* The BO is created as a normal GEM object via amdgpu_bo_create(), then
* reserved and pinned at the TTM level (ttm_bo_pin()) so it can never be
* migrated or evicted. No CPU mapping is established here.
*
* Return:
* * 0 on success or intentional skip (feature not present/unsupported)
* * negative errno on allocation failure
@ -1848,7 +1949,26 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
if (r)
return r;
r = amdgpu_bo_reserve(adev->rmmio_remap.bo, true);
if (r)
goto err_unref;
/*
* MMIO_REMAP is a fixed I/O placement (AMDGPU_PL_MMIO_REMAP).
* Use TTM-level pin so the BO cannot be evicted/migrated,
* independent of GEM domains. This
* enforces the fixed I/O window
*/
ttm_bo_pin(&adev->rmmio_remap.bo->tbo);
amdgpu_bo_unreserve(adev->rmmio_remap.bo);
return 0;
err_unref:
if (adev->rmmio_remap.bo)
amdgpu_bo_unref(&adev->rmmio_remap.bo);
adev->rmmio_remap.bo = NULL;
return r;
}
/**
@ -1860,6 +1980,15 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
*/
static void amdgpu_ttm_mmio_remap_bo_fini(struct amdgpu_device *adev)
{
struct amdgpu_bo *bo = adev->rmmio_remap.bo;
if (!bo)
return; /* <-- safest early exit */
if (!amdgpu_bo_reserve(adev->rmmio_remap.bo, true)) {
ttm_bo_unpin(&adev->rmmio_remap.bo->tbo);
amdgpu_bo_unreserve(adev->rmmio_remap.bo);
}
amdgpu_bo_unref(&adev->rmmio_remap.bo);
adev->rmmio_remap.bo = NULL;
}
@ -1988,7 +2117,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
DRM_DEBUG_DRIVER("Skipped stolen memory reservation\n");
}
dev_info(adev->dev, "amdgpu: %uM of VRAM memory ready\n",
dev_info(adev->dev, " %uM of VRAM memory ready\n",
(unsigned int)(adev->gmc.real_vram_size / (1024 * 1024)));
/* Compute GTT size, either based on TTM limit
@ -2014,7 +2143,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
dev_err(adev->dev, "Failed initializing GTT heap.\n");
return r;
}
dev_info(adev->dev, "amdgpu: %uM of GTT memory ready.\n",
dev_info(adev->dev, " %uM of GTT memory ready.\n",
(unsigned int)(gtt_size / (1024 * 1024)));
if (adev->flags & AMD_IS_APU) {
@ -2077,7 +2206,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
AMDGPU_GEM_DOMAIN_GTT,
&adev->mman.sdma_access_bo, NULL,
&adev->mman.sdma_access_ptr))
DRM_WARN("Debug VRAM access will use slowpath MM access\n");
drm_warn(adev_to_drm(adev),
"Debug VRAM access will use slowpath MM access\n");
return 0;
}
@ -2137,7 +2267,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_MMIO_REMAP);
ttm_device_fini(&adev->mman.bdev);
adev->mman.initialized = false;
dev_info(adev->dev, "amdgpu: ttm finalized\n");
dev_info(adev->dev, " ttm finalized\n");
}
/**
@ -2165,7 +2295,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
ring = adev->mman.buffer_funcs_ring;
sched = &ring->sched;
r = drm_sched_entity_init(&adev->mman.high_pr,
r = drm_sched_entity_init(&adev->mman.default_entity.base,
DRM_SCHED_PRIORITY_KERNEL, &sched,
1, NULL);
if (r) {
@ -2175,18 +2305,30 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
return;
}
r = drm_sched_entity_init(&adev->mman.low_pr,
r = drm_sched_entity_init(&adev->mman.clear_entity.base,
DRM_SCHED_PRIORITY_NORMAL, &sched,
1, NULL);
if (r) {
dev_err(adev->dev,
"Failed setting up TTM BO clear entity (%d)\n",
r);
goto error_free_entity;
}
r = drm_sched_entity_init(&adev->mman.move_entity.base,
DRM_SCHED_PRIORITY_NORMAL, &sched,
1, NULL);
if (r) {
dev_err(adev->dev,
"Failed setting up TTM BO move entity (%d)\n",
r);
drm_sched_entity_destroy(&adev->mman.clear_entity.base);
goto error_free_entity;
}
} else {
drm_sched_entity_destroy(&adev->mman.high_pr);
drm_sched_entity_destroy(&adev->mman.low_pr);
drm_sched_entity_destroy(&adev->mman.default_entity.base);
drm_sched_entity_destroy(&adev->mman.clear_entity.base);
drm_sched_entity_destroy(&adev->mman.move_entity.base);
/* Drop all the old fences since re-creating the scheduler entities
* will allocate new contexts.
*/
@ -2204,24 +2346,20 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
return;
error_free_entity:
drm_sched_entity_destroy(&adev->mman.high_pr);
drm_sched_entity_destroy(&adev->mman.default_entity.base);
}
static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
bool direct_submit,
struct amdgpu_ttm_buffer_entity *entity,
unsigned int num_dw,
struct dma_resv *resv,
bool vm_needs_flush,
struct amdgpu_job **job,
bool delayed, u64 k_job_id)
u64 k_job_id)
{
enum amdgpu_ib_pool_type pool = direct_submit ?
AMDGPU_IB_POOL_DIRECT :
AMDGPU_IB_POOL_DELAYED;
enum amdgpu_ib_pool_type pool = AMDGPU_IB_POOL_DELAYED;
int r;
struct drm_sched_entity *entity = delayed ? &adev->mman.low_pr :
&adev->mman.high_pr;
r = amdgpu_job_alloc_with_ib(adev, entity,
r = amdgpu_job_alloc_with_ib(adev, &entity->base,
AMDGPU_FENCE_OWNER_UNDEFINED,
num_dw * 4, pool, job, k_job_id);
if (r)
@ -2240,20 +2378,24 @@ static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
DMA_RESV_USAGE_BOOKKEEP);
}
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
int amdgpu_copy_buffer(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit,
struct dma_fence **fence,
bool vm_needs_flush, uint32_t copy_flags)
{
struct amdgpu_device *adev = ring->adev;
unsigned int num_loops, num_dw;
struct amdgpu_ring *ring;
struct amdgpu_job *job;
uint32_t max_bytes;
unsigned int i;
int r;
if (!direct_submit && !ring->sched.ready) {
ring = adev->mman.buffer_funcs_ring;
if (!ring->sched.ready) {
dev_err(adev->dev,
"Trying to move memory with ring turned off.\n");
return -EINVAL;
@ -2262,11 +2404,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
max_bytes = adev->mman.buffer_funcs->copy_max_bytes;
num_loops = DIV_ROUND_UP(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
r = amdgpu_ttm_prepare_job(adev, direct_submit, num_dw,
resv, vm_needs_flush, &job, false,
r = amdgpu_ttm_prepare_job(adev, entity, num_dw,
resv, vm_needs_flush, &job,
AMDGPU_KERNEL_JOB_ID_TTM_COPY_BUFFER);
if (r)
return r;
goto error_free;
for (i = 0; i < num_loops; i++) {
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
@ -2278,16 +2420,9 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
byte_count -= cur_size_in_bytes;
}
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
if (direct_submit)
r = amdgpu_job_submit_direct(job, ring, fence);
else
*fence = amdgpu_job_submit(job);
if (r)
goto error_free;
*fence = amdgpu_ttm_job_submit(adev, job, num_dw);
return r;
return 0;
error_free:
amdgpu_job_free(job);
@ -2295,14 +2430,15 @@ error_free:
return r;
}
static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
uint32_t src_data,
uint64_t dst_addr, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence,
bool vm_needs_flush, bool delayed,
bool vm_needs_flush,
u64 k_job_id)
{
struct amdgpu_device *adev = ring->adev;
unsigned int num_loops, num_dw;
struct amdgpu_job *job;
uint32_t max_bytes;
@ -2312,8 +2448,8 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
num_loops = DIV_ROUND_UP_ULL(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->fill_num_dw, 8);
r = amdgpu_ttm_prepare_job(adev, false, num_dw, resv, vm_needs_flush,
&job, delayed, k_job_id);
r = amdgpu_ttm_prepare_job(adev, entity, num_dw, resv,
vm_needs_flush, &job, k_job_id);
if (r)
return r;
@ -2327,9 +2463,7 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
byte_count -= cur_size;
}
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
*fence = amdgpu_job_submit(job);
*fence = amdgpu_ttm_job_submit(adev, job, num_dw);
return 0;
}
@ -2349,7 +2483,6 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
struct dma_fence **fence)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_res_cursor cursor;
u64 addr;
int r = 0;
@ -2377,13 +2510,14 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
/* Never clear more than 256MiB at once to avoid timeouts */
size = min(cursor.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(&bo->tbo, bo->tbo.resource, &cursor,
1, ring, false, &size, &addr);
r = amdgpu_ttm_map_buffer(&adev->mman.clear_entity,
&bo->tbo, bo->tbo.resource, &cursor,
1, false, &size, &addr);
if (r)
goto err;
r = amdgpu_ttm_fill_mem(ring, 0, addr, size, resv,
&next, true, true,
r = amdgpu_ttm_fill_mem(adev, &adev->mman.clear_entity, 0, addr, size, resv,
&next, true,
AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
if (r)
goto err;
@ -2399,15 +2533,14 @@ err:
return r;
}
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **f,
bool delayed,
u64 k_job_id)
int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **f,
u64 k_job_id)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct dma_fence *fence = NULL;
struct amdgpu_res_cursor dst;
int r;
@ -2428,13 +2561,14 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
/* Never fill more than 256MiB at once to avoid timeouts */
cur_size = min(dst.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(&bo->tbo, bo->tbo.resource, &dst,
1, ring, false, &cur_size, &to);
r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
1, false, &cur_size, &to);
if (r)
goto error;
r = amdgpu_ttm_fill_mem(ring, src_data, to, cur_size, resv,
&next, true, delayed, k_job_id);
r = amdgpu_ttm_fill_mem(adev, entity,
src_data, to, cur_size, resv,
&next, true, k_job_id);
if (r)
goto error;

View file

@ -52,6 +52,10 @@ struct amdgpu_gtt_mgr {
spinlock_t lock;
};
struct amdgpu_ttm_buffer_entity {
struct drm_sched_entity base;
};
struct amdgpu_mman {
struct ttm_device bdev;
struct ttm_pool *ttm_pools;
@ -64,10 +68,10 @@ struct amdgpu_mman {
bool buffer_funcs_enabled;
struct mutex gtt_window_lock;
/* High priority scheduler entity for buffer moves */
struct drm_sched_entity high_pr;
/* Low priority scheduler entity for VRAM clearing */
struct drm_sched_entity low_pr;
struct amdgpu_ttm_buffer_entity default_entity;
struct amdgpu_ttm_buffer_entity clear_entity;
struct amdgpu_ttm_buffer_entity move_entity;
struct amdgpu_vram_mgr vram_mgr;
struct amdgpu_gtt_mgr gtt_mgr;
@ -137,6 +141,12 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev);
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem);
void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
int amdgpu_gtt_mgr_alloc_entries(struct amdgpu_gtt_mgr *mgr,
struct drm_mm_node *mm_node,
u64 num_pages,
enum drm_mm_insert_mode mode);
void amdgpu_gtt_mgr_free_entries(struct amdgpu_gtt_mgr *mgr,
struct drm_mm_node *mm_node);
uint64_t amdgpu_preempt_mgr_usage(struct ttm_resource_manager *man);
u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo);
@ -163,20 +173,22 @@ int amdgpu_ttm_init(struct amdgpu_device *adev);
void amdgpu_ttm_fini(struct amdgpu_device *adev);
void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
bool enable);
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
int amdgpu_copy_buffer(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit,
struct dma_fence **fence,
bool vm_needs_flush, uint32_t copy_flags);
int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
struct dma_resv *resv,
struct dma_fence **fence);
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **fence,
bool delayed,
u64 k_job_id);
int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **f,
u64 k_job_id);
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
@ -213,4 +225,13 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type);
void amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
int amdgpu_ttm_mmio_remap_alloc_sgt(struct amdgpu_device *adev,
struct ttm_resource *res,
struct device *dev,
enum dma_data_direction dir,
struct sg_table **sgt);
void amdgpu_ttm_mmio_remap_free_sgt(struct device *dev,
enum dma_data_direction dir,
struct sg_table *sgt);
#endif

View file

@ -166,6 +166,8 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_3, v2_2);
const struct rlc_firmware_header_v2_4 *rlc_hdr_v2_4 =
container_of(rlc_hdr_v2_3, struct rlc_firmware_header_v2_4, v2_3);
const struct rlc_firmware_header_v2_5 *rlc_hdr_v2_5 =
container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_5, v2_2);
switch (version_minor) {
case 0:
@ -287,6 +289,26 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
DRM_DEBUG("se3_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_offset_bytes));
break;
case 5:
/* rlc_hdr v2_5 */
DRM_INFO("rlc_iram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_size_bytes));
DRM_INFO("rlc_iram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_offset_bytes));
DRM_INFO("rlc_dram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_size_bytes));
DRM_INFO("rlc_dram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_offset_bytes));
/* rlc_hdr v2_5 */
DRM_INFO("rlc_1_iram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_size_bytes));
DRM_INFO("rlc_1_iram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_offset_bytes));
DRM_INFO("rlc_1_dram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_size_bytes));
DRM_INFO("rlc_1_dram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_offset_bytes));
break;
default:
DRM_ERROR("Unknown RLC v2 ucode: v2.%u\n", version_minor);
break;
@ -631,6 +653,10 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)
return "RLC_IRAM";
case AMDGPU_UCODE_ID_RLC_DRAM:
return "RLC_DRAM";
case AMDGPU_UCODE_ID_RLC_IRAM_1:
return "RLC_IRAM_1";
case AMDGPU_UCODE_ID_RLC_DRAM_1:
return "RLC_DRAM_1";
case AMDGPU_UCODE_ID_RLC_G:
return "RLC_G";
case AMDGPU_UCODE_ID_RLC_P:
@ -911,6 +937,14 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes;
ucode_addr = adev->gfx.rlc.rlc_dram_ucode;
break;
case AMDGPU_UCODE_ID_RLC_IRAM_1:
ucode->ucode_size = adev->gfx.rlc.rlc_1_iram_ucode_size_bytes;
ucode_addr = adev->gfx.rlc.rlc_1_iram_ucode;
break;
case AMDGPU_UCODE_ID_RLC_DRAM_1:
ucode->ucode_size = adev->gfx.rlc.rlc_1_dram_ucode_size_bytes;
ucode_addr = adev->gfx.rlc.rlc_1_dram_ucode;
break;
case AMDGPU_UCODE_ID_RLC_P:
ucode->ucode_size = adev->gfx.rlc.rlcp_ucode_size_bytes;
ucode_addr = adev->gfx.rlc.rlcp_ucode;

View file

@ -300,6 +300,15 @@ struct rlc_firmware_header_v2_4 {
uint32_t se3_tap_delays_ucode_offset_bytes;
};
/* version_major=2, version_minor=5 */
struct rlc_firmware_header_v2_5 {
struct rlc_firmware_header_v2_2 v2_2;
uint32_t rlc_1_iram_ucode_size_bytes;
uint32_t rlc_1_iram_ucode_offset_bytes;
uint32_t rlc_1_dram_ucode_size_bytes;
uint32_t rlc_1_dram_ucode_offset_bytes;
};
/* version_major=1, version_minor=0 */
struct sdma_firmware_header_v1_0 {
struct common_firmware_header header;
@ -449,6 +458,7 @@ union amdgpu_firmware_header {
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 rlc_firmware_header_v2_5 rlc_v2_5;
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;
@ -512,6 +522,8 @@ enum AMDGPU_UCODE_ID {
AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM,
AMDGPU_UCODE_ID_RLC_IRAM,
AMDGPU_UCODE_ID_RLC_DRAM,
AMDGPU_UCODE_ID_RLC_IRAM_1,
AMDGPU_UCODE_ID_RLC_DRAM_1,
AMDGPU_UCODE_ID_RLC_P,
AMDGPU_UCODE_ID_RLC_V,
AMDGPU_UCODE_ID_RLC_G,

View file

@ -166,7 +166,8 @@ static int amdgpu_userq_buffer_va_list_add(struct amdgpu_usermode_queue *queue,
return 0;
}
int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue,
int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
struct amdgpu_usermode_queue *queue,
u64 addr, u64 expected_size)
{
struct amdgpu_bo_va_mapping *va_map;
@ -271,10 +272,9 @@ err:
return r;
}
static int
amdgpu_userq_preempt_helper(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue)
static int amdgpu_userq_preempt_helper(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
const struct amdgpu_userq_funcs *userq_funcs =
adev->userq_funcs[queue->queue_type];
@ -282,7 +282,7 @@ amdgpu_userq_preempt_helper(struct amdgpu_userq_mgr *uq_mgr,
int r = 0;
if (queue->state == AMDGPU_USERQ_STATE_MAPPED) {
r = userq_funcs->preempt(uq_mgr, queue);
r = userq_funcs->preempt(queue);
if (r) {
queue->state = AMDGPU_USERQ_STATE_HUNG;
found_hung_queue = true;
@ -297,17 +297,16 @@ amdgpu_userq_preempt_helper(struct amdgpu_userq_mgr *uq_mgr,
return r;
}
static int
amdgpu_userq_restore_helper(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue)
static int amdgpu_userq_restore_helper(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
const struct amdgpu_userq_funcs *userq_funcs =
adev->userq_funcs[queue->queue_type];
int r = 0;
if (queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
r = userq_funcs->restore(uq_mgr, queue);
r = userq_funcs->restore(queue);
if (r) {
queue->state = AMDGPU_USERQ_STATE_HUNG;
} else {
@ -318,10 +317,9 @@ amdgpu_userq_restore_helper(struct amdgpu_userq_mgr *uq_mgr,
return r;
}
static int
amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue)
static int amdgpu_userq_unmap_helper(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
const struct amdgpu_userq_funcs *userq_funcs =
adev->userq_funcs[queue->queue_type];
@ -330,7 +328,7 @@ amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
if ((queue->state == AMDGPU_USERQ_STATE_MAPPED) ||
(queue->state == AMDGPU_USERQ_STATE_PREEMPTED)) {
r = userq_funcs->unmap(uq_mgr, queue);
r = userq_funcs->unmap(queue);
if (r) {
queue->state = AMDGPU_USERQ_STATE_HUNG;
found_hung_queue = true;
@ -345,17 +343,16 @@ amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
return r;
}
static int
amdgpu_userq_map_helper(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue)
static int amdgpu_userq_map_helper(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
const struct amdgpu_userq_funcs *userq_funcs =
adev->userq_funcs[queue->queue_type];
int r = 0;
if (queue->state == AMDGPU_USERQ_STATE_UNMAPPED) {
r = userq_funcs->map(uq_mgr, queue);
r = userq_funcs->map(queue);
if (r) {
queue->state = AMDGPU_USERQ_STATE_HUNG;
amdgpu_userq_detect_and_reset_queues(uq_mgr);
@ -367,10 +364,9 @@ amdgpu_userq_map_helper(struct amdgpu_userq_mgr *uq_mgr,
return r;
}
static int
amdgpu_userq_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue)
static int amdgpu_userq_wait_for_last_fence(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct dma_fence *f = queue->last_fence;
int ret = 0;
@ -387,11 +383,10 @@ amdgpu_userq_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr,
return ret;
}
static void
amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue,
int queue_id)
static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,
int queue_id)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
const struct amdgpu_userq_funcs *uq_funcs = adev->userq_funcs[queue->queue_type];
@ -400,10 +395,10 @@ amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr,
/* Drop the userq reference. */
amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
uq_funcs->mqd_destroy(uq_mgr, queue);
uq_funcs->mqd_destroy(queue);
amdgpu_userq_fence_driver_free(queue);
/* Use interrupt-safe locking since IRQ handlers may access these XArrays */
xa_erase_irq(&uq_mgr->userq_mgr_xa, (unsigned long)queue_id);
xa_erase_irq(&uq_mgr->userq_xa, (unsigned long)queue_id);
xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
queue->userq_mgr = NULL;
list_del(&queue->userq_va_list);
@ -415,7 +410,7 @@ amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr,
static struct amdgpu_usermode_queue *
amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
{
return xa_load(&uq_mgr->userq_mgr_xa, qid);
return xa_load(&uq_mgr->userq_xa, qid);
}
void
@ -584,25 +579,33 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id)
mutex_unlock(&uq_mgr->userq_mutex);
return -EINVAL;
}
amdgpu_userq_wait_for_last_fence(uq_mgr, queue);
amdgpu_userq_wait_for_last_fence(queue);
r = amdgpu_bo_reserve(queue->db_obj.obj, true);
if (!r) {
amdgpu_bo_unpin(queue->db_obj.obj);
amdgpu_bo_unreserve(queue->db_obj.obj);
}
amdgpu_bo_unref(&queue->db_obj.obj);
r = amdgpu_bo_reserve(queue->wptr_obj.obj, true);
if (!r) {
amdgpu_bo_unpin(queue->wptr_obj.obj);
amdgpu_bo_unreserve(queue->wptr_obj.obj);
}
amdgpu_bo_unref(&queue->wptr_obj.obj);
atomic_dec(&uq_mgr->userq_count[queue->queue_type]);
#if defined(CONFIG_DEBUG_FS)
debugfs_remove_recursive(queue->debugfs_queue);
#endif
amdgpu_userq_detect_and_reset_queues(uq_mgr);
r = amdgpu_userq_unmap_helper(uq_mgr, queue);
r = amdgpu_userq_unmap_helper(queue);
/*TODO: It requires a reset for userq hw unmap error*/
if (unlikely(r != AMDGPU_USERQ_STATE_UNMAPPED)) {
drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");
queue->state = AMDGPU_USERQ_STATE_HUNG;
}
amdgpu_userq_cleanup(uq_mgr, queue, queue_id);
amdgpu_userq_cleanup(queue, queue_id);
mutex_unlock(&uq_mgr->userq_mutex);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@ -729,10 +732,11 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
db_info.db_obj = &queue->db_obj;
db_info.doorbell_offset = args->in.doorbell_offset;
queue->userq_mgr = uq_mgr;
/* Validate the userq virtual address.*/
if (amdgpu_userq_input_va_validate(queue, args->in.queue_va, args->in.queue_size) ||
amdgpu_userq_input_va_validate(queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) ||
amdgpu_userq_input_va_validate(queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) {
if (amdgpu_userq_input_va_validate(adev, queue, args->in.queue_va, args->in.queue_size) ||
amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) ||
amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) {
r = -EINVAL;
kfree(queue);
goto unlock;
@ -755,7 +759,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
goto unlock;
}
r = uq_funcs->mqd_create(uq_mgr, &args->in, queue);
r = uq_funcs->mqd_create(queue, &args->in);
if (r) {
drm_file_err(uq_mgr->file, "Failed to create Queue\n");
amdgpu_userq_fence_driver_free(queue);
@ -772,18 +776,18 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
goto unlock;
}
r = xa_alloc(&uq_mgr->userq_mgr_xa, &qid, queue, XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
r = xa_alloc(&uq_mgr->userq_xa, &qid, queue,
XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
if (r) {
drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n");
amdgpu_userq_fence_driver_free(queue);
uq_funcs->mqd_destroy(uq_mgr, queue);
uq_funcs->mqd_destroy(queue);
kfree(queue);
r = -ENOMEM;
up_read(&adev->reset_domain->sem);
goto unlock;
}
up_read(&adev->reset_domain->sem);
queue->userq_mgr = uq_mgr;
/* don't map the queue if scheduling is halted */
if (adev->userq_halt_for_enforce_isolation &&
@ -793,12 +797,12 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
else
skip_map_queue = false;
if (!skip_map_queue) {
r = amdgpu_userq_map_helper(uq_mgr, queue);
r = amdgpu_userq_map_helper(queue);
if (r) {
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
xa_erase(&uq_mgr->userq_mgr_xa, qid);
xa_erase(&uq_mgr->userq_xa, qid);
amdgpu_userq_fence_driver_free(queue);
uq_funcs->mqd_destroy(uq_mgr, queue);
uq_funcs->mqd_destroy(queue);
kfree(queue);
goto unlock;
}
@ -923,8 +927,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
int ret = 0, r;
/* Resume all the queues for this process */
xa_for_each(&uq_mgr->userq_mgr_xa, queue_id, queue) {
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
if (!amdgpu_userq_buffer_vas_mapped(queue)) {
drm_file_err(uq_mgr->file,
"trying restore queue without va mapping\n");
@ -932,7 +935,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
continue;
}
r = amdgpu_userq_restore_helper(uq_mgr, queue);
r = amdgpu_userq_restore_helper(queue);
if (r)
ret = r;
}
@ -1167,8 +1170,8 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr)
amdgpu_userq_detect_and_reset_queues(uq_mgr);
/* Try to unmap all the queues in this process ctx */
xa_for_each(&uq_mgr->userq_mgr_xa, queue_id, queue) {
r = amdgpu_userq_preempt_helper(uq_mgr, queue);
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
r = amdgpu_userq_preempt_helper(queue);
if (r)
ret = r;
}
@ -1202,7 +1205,7 @@ amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr)
unsigned long queue_id;
int ret;
xa_for_each(&uq_mgr->userq_mgr_xa, queue_id, queue) {
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
struct dma_fence *f = queue->last_fence;
if (!f || dma_fence_is_signaled(f))
@ -1252,7 +1255,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *f
struct amdgpu_device *adev)
{
mutex_init(&userq_mgr->userq_mutex);
xa_init_flags(&userq_mgr->userq_mgr_xa, XA_FLAGS_ALLOC);
xa_init_flags(&userq_mgr->userq_xa, XA_FLAGS_ALLOC);
userq_mgr->adev = adev;
userq_mgr->file = file_priv;
@ -1269,13 +1272,13 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
mutex_lock(&userq_mgr->userq_mutex);
amdgpu_userq_detect_and_reset_queues(userq_mgr);
xa_for_each(&userq_mgr->userq_mgr_xa, queue_id, queue) {
amdgpu_userq_wait_for_last_fence(userq_mgr, queue);
amdgpu_userq_unmap_helper(userq_mgr, queue);
amdgpu_userq_cleanup(userq_mgr, queue, queue_id);
xa_for_each(&userq_mgr->userq_xa, queue_id, queue) {
amdgpu_userq_wait_for_last_fence(queue);
amdgpu_userq_unmap_helper(queue);
amdgpu_userq_cleanup(queue, queue_id);
}
xa_destroy(&userq_mgr->userq_mgr_xa);
xa_destroy(&userq_mgr->userq_xa);
mutex_unlock(&userq_mgr->userq_mutex);
mutex_destroy(&userq_mgr->userq_mutex);
}
@ -1297,9 +1300,9 @@ int amdgpu_userq_suspend(struct amdgpu_device *adev)
guard(mutex)(&uqm->userq_mutex);
amdgpu_userq_detect_and_reset_queues(uqm);
if (adev->in_s0ix)
r = amdgpu_userq_preempt_helper(uqm, queue);
r = amdgpu_userq_preempt_helper(queue);
else
r = amdgpu_userq_unmap_helper(uqm, queue);
r = amdgpu_userq_unmap_helper(queue);
if (r)
return r;
}
@ -1321,9 +1324,9 @@ int amdgpu_userq_resume(struct amdgpu_device *adev)
uqm = queue->userq_mgr;
guard(mutex)(&uqm->userq_mutex);
if (adev->in_s0ix)
r = amdgpu_userq_restore_helper(uqm, queue);
r = amdgpu_userq_restore_helper(queue);
else
r = amdgpu_userq_map_helper(uqm, queue);
r = amdgpu_userq_map_helper(queue);
if (r)
return r;
}
@ -1355,7 +1358,7 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev,
(queue->queue_type == AMDGPU_HW_IP_COMPUTE)) &&
(queue->xcp_id == idx)) {
amdgpu_userq_detect_and_reset_queues(uqm);
r = amdgpu_userq_preempt_helper(uqm, queue);
r = amdgpu_userq_preempt_helper(queue);
if (r)
ret = r;
}
@ -1387,9 +1390,9 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev,
if (((queue->queue_type == AMDGPU_HW_IP_GFX) ||
(queue->queue_type == AMDGPU_HW_IP_COMPUTE)) &&
(queue->xcp_id == idx)) {
r = amdgpu_userq_restore_helper(uqm, queue);
if (r)
ret = r;
r = amdgpu_userq_restore_helper(queue);
if (r)
ret = r;
}
mutex_unlock(&uqm->userq_mutex);
}
@ -1439,9 +1442,9 @@ void amdgpu_userq_pre_reset(struct amdgpu_device *adev)
uqm = queue->userq_mgr;
cancel_delayed_work_sync(&uqm->resume_work);
if (queue->state == AMDGPU_USERQ_STATE_MAPPED) {
amdgpu_userq_wait_for_last_fence(uqm, queue);
amdgpu_userq_wait_for_last_fence(queue);
userq_funcs = adev->userq_funcs[queue->queue_type];
userq_funcs->unmap(uqm, queue);
userq_funcs->unmap(queue);
/* just mark all queues as hung at this point.
* if unmap succeeds, we could map again
* in amdgpu_userq_post_reset() if vram is not lost
@ -1458,18 +1461,16 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost)
* at this point, we should be able to map it again
* and continue if vram is not lost.
*/
struct amdgpu_userq_mgr *uqm;
struct amdgpu_usermode_queue *queue;
const struct amdgpu_userq_funcs *userq_funcs;
unsigned long queue_id;
int r = 0;
xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) {
uqm = queue->userq_mgr;
if (queue->state == AMDGPU_USERQ_STATE_HUNG && !vram_lost) {
userq_funcs = adev->userq_funcs[queue->queue_type];
/* Re-map queue */
r = userq_funcs->map(uqm, queue);
r = userq_funcs->map(queue);
if (r) {
dev_err(adev->dev, "Failed to remap queue %ld\n", queue_id);
continue;

View file

@ -77,19 +77,13 @@ struct amdgpu_usermode_queue {
};
struct amdgpu_userq_funcs {
int (*mqd_create)(struct amdgpu_userq_mgr *uq_mgr,
struct drm_amdgpu_userq_in *args,
struct amdgpu_usermode_queue *queue);
void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *uq);
int (*unmap)(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue);
int (*map)(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue);
int (*preempt)(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue);
int (*restore)(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue);
int (*mqd_create)(struct amdgpu_usermode_queue *queue,
struct drm_amdgpu_userq_in *args);
void (*mqd_destroy)(struct amdgpu_usermode_queue *uq);
int (*unmap)(struct amdgpu_usermode_queue *queue);
int (*map)(struct amdgpu_usermode_queue *queue);
int (*preempt)(struct amdgpu_usermode_queue *queue);
int (*restore)(struct amdgpu_usermode_queue *queue);
int (*detect_and_reset)(struct amdgpu_device *adev,
int queue_type);
};
@ -97,11 +91,11 @@ struct amdgpu_userq_funcs {
/* Usermode queues for gfx */
struct amdgpu_userq_mgr {
/**
* @userq_mgr_xa: Per-process user queue map (queue ID queue)
* @userq_xa: Per-process user queue map (queue ID queue)
* Key: queue_id (unique ID within the process's userq manager)
* Value: struct amdgpu_usermode_queue
*/
struct xarray userq_mgr_xa;
struct xarray userq_xa;
struct mutex userq_mutex;
struct amdgpu_device *adev;
struct delayed_work resume_work;
@ -153,7 +147,8 @@ void amdgpu_userq_reset_work(struct work_struct *work);
void amdgpu_userq_pre_reset(struct amdgpu_device *adev);
int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost);
int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue,
int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
struct amdgpu_usermode_queue *queue,
u64 addr, u64 expected_size);
int amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *mapping,

View file

@ -352,6 +352,7 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops = {
/**
* amdgpu_userq_fence_read_wptr - Read the userq wptr value
*
* @adev: amdgpu_device pointer
* @queue: user mode queue structure pointer
* @wptr: write pointer value
*
@ -361,7 +362,8 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops = {
*
* Returns wptr value on success, error on failure.
*/
static int amdgpu_userq_fence_read_wptr(struct amdgpu_usermode_queue *queue,
static int amdgpu_userq_fence_read_wptr(struct amdgpu_device *adev,
struct amdgpu_usermode_queue *queue,
u64 *wptr)
{
struct amdgpu_bo_va_mapping *mapping;
@ -455,6 +457,7 @@ amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq)
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
struct amdgpu_device *adev = drm_to_adev(dev);
struct amdgpu_fpriv *fpriv = filp->driver_priv;
struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
struct drm_amdgpu_userq_signal *args = data;
@ -539,13 +542,13 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
}
/* Retrieve the user queue */
queue = xa_load(&userq_mgr->userq_mgr_xa, args->queue_id);
queue = xa_load(&userq_mgr->userq_xa, args->queue_id);
if (!queue) {
r = -ENOENT;
goto put_gobj_write;
}
r = amdgpu_userq_fence_read_wptr(queue, &wptr);
r = amdgpu_userq_fence_read_wptr(adev, queue, &wptr);
if (r)
goto put_gobj_write;
@ -901,7 +904,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
*/
num_fences = dma_fence_dedup_array(fences, num_fences);
waitq = xa_load(&userq_mgr->userq_mgr_xa, wait_info->waitq_id);
waitq = xa_load(&userq_mgr->userq_xa, wait_info->waitq_id);
if (!waitq) {
r = -EINVAL;
goto free_fences;

View file

@ -279,7 +279,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
DRM_INFO("Found UVD firmware Version: %u.%u Family ID: %u\n",
drm_info(adev_to_drm(adev), "Found UVD firmware Version: %u.%u Family ID: %u\n",
version_major, version_minor, family_id);
/*
@ -306,7 +306,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
dec_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
enc_minor = (le32_to_cpu(hdr->ucode_version) >> 24) & 0x3f;
enc_major = (le32_to_cpu(hdr->ucode_version) >> 30) & 0x3;
DRM_INFO("Found UVD firmware ENC: %u.%u DEC: .%u Family ID: %u\n",
drm_info(adev_to_drm(adev), "Found UVD firmware ENC: %u.%u DEC: .%u Family ID: %u\n",
enc_major, enc_minor, dec_minor, family_id);
adev->uvd.max_handles = AMDGPU_MAX_UVD_HANDLES;
@ -467,7 +467,8 @@ int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev)
int amdgpu_uvd_suspend(struct amdgpu_device *adev)
{
if (amdgpu_ras_intr_triggered())
DRM_WARN("UVD VCPU state may lost due to RAS ERREVENT_ATHUB_INTERRUPT\n");
drm_warn(adev_to_drm(adev),
"UVD VCPU state may lost due to RAS ERREVENT_ATHUB_INTERRUPT\n");
return 0;
}

View file

@ -63,6 +63,7 @@
#define FIRMWARE_VCN4_0_6_1 "amdgpu/vcn_4_0_6_1.bin"
#define FIRMWARE_VCN5_0_0 "amdgpu/vcn_5_0_0.bin"
#define FIRMWARE_VCN5_0_1 "amdgpu/vcn_5_0_1.bin"
#define FIRMWARE_VCN5_3_0 "amdgpu/vcn_5_3_0.bin"
MODULE_FIRMWARE(FIRMWARE_RAVEN);
MODULE_FIRMWARE(FIRMWARE_PICASSO);
@ -90,6 +91,7 @@ MODULE_FIRMWARE(FIRMWARE_VCN4_0_6);
MODULE_FIRMWARE(FIRMWARE_VCN4_0_6_1);
MODULE_FIRMWARE(FIRMWARE_VCN5_0_0);
MODULE_FIRMWARE(FIRMWARE_VCN5_0_1);
MODULE_FIRMWARE(FIRMWARE_VCN5_3_0);
static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
static void amdgpu_vcn_reg_dump_fini(struct amdgpu_device *adev);

View file

@ -37,6 +37,7 @@
#include "vi.h"
#include "soc15.h"
#include "nv.h"
#include "amdgpu_virt_ras_cmd.h"
#define POPULATE_UCODE_INFO(vf2pf_info, ucode, ver) \
do { \
@ -1337,6 +1338,133 @@ bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
return ret;
}
static u32 amdgpu_virt_rlcg_vfi_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
{
uint32_t timeout = 100;
uint32_t i;
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
void *vfi_cmd;
void *vfi_stat;
void *vfi_addr;
void *vfi_data;
void *vfi_grbm_cntl;
void *vfi_grbm_idx;
uint32_t cmd;
uint32_t stat;
uint32_t addr = offset;
uint32_t data;
uint32_t grbm_cntl_data;
uint32_t grbm_idx_data;
unsigned long flags;
bool is_err = true;
if (!adev->gfx.rlc.rlcg_reg_access_supported) {
dev_err(adev->dev, "VFi interface is not available\n");
return 0;
}
if (adev->gfx.xcc_mask && (((1 << xcc_id) & adev->gfx.xcc_mask) == 0)) {
dev_err(adev->dev, "VFi invalid XCC, xcc_id=0x%x\n", xcc_id);
return 0;
}
if (amdgpu_device_skip_hw_access(adev))
return 0;
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id];
vfi_cmd = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_cmd;
vfi_stat = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_stat;
vfi_addr = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_addr;
vfi_data = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_data;
vfi_grbm_cntl = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_grbm_cntl;
vfi_grbm_idx = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_grbm_idx;
grbm_cntl_data = reg_access_ctrl->vfi_grbm_cntl_data;
grbm_idx_data = reg_access_ctrl->vfi_grbm_idx_data;
if (flag == AMDGPU_RLCG_GC_WRITE) {
data = v;
cmd = AMDGPU_RLCG_VFI_CMD__WR;
// the GRBM_GFX_CNTL and GRBM_GFX_INDEX are protected by mutex outside this call
if (addr == reg_access_ctrl->grbm_cntl) {
reg_access_ctrl->vfi_grbm_cntl_data = data;
return 0;
} else if (addr == reg_access_ctrl->grbm_idx) {
reg_access_ctrl->vfi_grbm_idx_data = data;
return 0;
}
} else if (flag == AMDGPU_RLCG_GC_READ) {
data = 0;
cmd = AMDGPU_RLCG_VFI_CMD__RD;
// the GRBM_GFX_CNTL and GRBM_GFX_INDEX are protected by mutex outside this call
if (addr == reg_access_ctrl->grbm_cntl)
return grbm_cntl_data;
else if (addr == reg_access_ctrl->grbm_idx)
return grbm_idx_data;
} else {
dev_err(adev->dev, "VFi invalid access, flag=0x%x\n", flag);
return 0;
}
spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags);
writel(addr, vfi_addr);
writel(data, vfi_data);
writel(grbm_cntl_data, vfi_grbm_cntl);
writel(grbm_idx_data, vfi_grbm_idx);
writel(AMDGPU_RLCG_VFI_STAT__BUSY, vfi_stat);
writel(cmd, vfi_cmd);
for (i = 0; i < timeout; i++) {
stat = readl(vfi_stat);
if (stat != AMDGPU_RLCG_VFI_STAT__BUSY)
break;
udelay(10);
}
switch (stat) {
case AMDGPU_RLCG_VFI_STAT__DONE:
is_err = false;
if (cmd == AMDGPU_RLCG_VFI_CMD__RD)
data = readl(vfi_data);
break;
case AMDGPU_RLCG_VFI_STAT__BUSY:
dev_err(adev->dev, "VFi access timeout\n");
break;
case AMDGPU_RLCG_VFI_STAT__INV_CMD:
dev_err(adev->dev, "VFi invalid command\n");
break;
case AMDGPU_RLCG_VFI_STAT__INV_ADDR:
dev_err(adev->dev, "VFi invalid address\n");
break;
case AMDGPU_RLCG_VFI_STAT__ERR:
dev_err(adev->dev, "VFi unknown error\n");
break;
default:
dev_err(adev->dev, "VFi unknown status code\n");
break;
}
spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags);
if (is_err)
dev_err(adev->dev, "VFi: [grbm_cntl=0x%x grbm_idx=0x%x] addr=0x%x (byte addr 0x%x), data=0x%x, cmd=0x%x\n",
grbm_cntl_data, grbm_idx_data,
addr, addr * 4, data, cmd);
else
dev_dbg(adev->dev, "VFi: [grbm_cntl=0x%x grbm_idx=0x%x] addr=0x%x (byte addr 0x%x), data=0x%x, cmd=0x%x\n",
grbm_cntl_data, grbm_idx_data,
addr, addr * 4, data, cmd);
return data;
}
u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
{
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
@ -1350,6 +1478,9 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
void *spare_int;
unsigned long flags;
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0))
return amdgpu_virt_rlcg_vfi_reg_rw(adev, offset, v, flag, xcc_id);
if (!adev->gfx.rlc.rlcg_reg_access_supported) {
dev_err(adev->dev,
"indirect registers access through rlcg is not available\n");
@ -1533,6 +1664,9 @@ bool amdgpu_virt_get_ras_capability(struct amdgpu_device *adev)
if (adev->virt.ras_en_caps.bits.poison_propogation_mode)
con->poison_supported = true; /* Poison is handled by host */
if (adev->virt.ras_en_caps.bits.uniras_supported)
amdgpu_virt_ras_set_remote_uniras(adev, true);
return true;
}
@ -1845,3 +1979,28 @@ int amdgpu_virt_check_vf_critical_region(struct amdgpu_device *adev, u64 addr, b
return r;
}
static int req_remote_ras_cmd(struct amdgpu_device *adev,
u32 param1, u32 param2, u32 param3)
{
struct amdgpu_virt *virt = &adev->virt;
if (virt->ops && virt->ops->req_remote_ras_cmd)
return virt->ops->req_remote_ras_cmd(adev, param1, param2, param3);
return -ENOENT;
}
int amdgpu_virt_send_remote_ras_cmd(struct amdgpu_device *adev,
uint64_t buf, uint32_t buf_len)
{
uint64_t gpa = buf;
int ret = -EIO;
if (down_read_trylock(&adev->reset_domain->sem)) {
ret = req_remote_ras_cmd(adev,
lower_32_bits(gpa), upper_32_bits(gpa), buf_len);
up_read(&adev->reset_domain->sem);
}
return ret;
}

View file

@ -47,6 +47,15 @@
#define AMDGPU_RLCG_SCRATCH1_ADDRESS_MASK 0xFFFFF
#define AMDGPU_RLCG_SCRATCH1_ERROR_MASK 0xF000000
#define AMDGPU_RLCG_VFI_CMD__WR 0x0
#define AMDGPU_RLCG_VFI_CMD__RD 0x1
#define AMDGPU_RLCG_VFI_STAT__BUSY 0x0
#define AMDGPU_RLCG_VFI_STAT__DONE 0x1
#define AMDGPU_RLCG_VFI_STAT__INV_CMD 0x2
#define AMDGPU_RLCG_VFI_STAT__INV_ADDR 0x3
#define AMDGPU_RLCG_VFI_STAT__ERR 0xFF
/* all asic after AI use this offset */
#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
/* tonga/fiji use this offset */
@ -105,6 +114,8 @@ struct amdgpu_virt_ops {
int (*req_ras_cper_dump)(struct amdgpu_device *adev, u64 vf_rptr);
int (*req_bad_pages)(struct amdgpu_device *adev);
int (*req_ras_chk_criti)(struct amdgpu_device *adev, u64 addr);
int (*req_remote_ras_cmd)(struct amdgpu_device *adev,
u32 param1, u32 param2, u32 param3);
};
/*
@ -483,4 +494,6 @@ bool amdgpu_virt_ras_telemetry_block_en(struct amdgpu_device *adev,
enum amdgpu_ras_block block);
void amdgpu_virt_request_bad_pages(struct amdgpu_device *adev);
int amdgpu_virt_check_vf_critical_region(struct amdgpu_device *adev, u64 addr, bool *hit);
int amdgpu_virt_send_remote_ras_cmd(struct amdgpu_device *adev,
uint64_t buf, uint32_t buf_len);
#endif

View file

@ -53,7 +53,9 @@ static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
ret_overrun = hrtimer_forward_now(&amdgpu_crtc->vblank_timer,
output->period_ns);
if (ret_overrun != 1)
DRM_WARN("%s: vblank timer overrun\n", __func__);
drm_warn(amdgpu_crtc->base.dev,
"%s: vblank timer overrun count: %llu\n",
__func__, ret_overrun);
ret = drm_crtc_handle_vblank(crtc);
/* Don't queue timer again when vblank is disabled. */

View file

@ -834,7 +834,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid);
if (spm_update_needed && adev->gfx.rlc.funcs->update_spm_vmid)
adev->gfx.rlc.funcs->update_spm_vmid(adev, ring, job->vmid);
adev->gfx.rlc.funcs->update_spm_vmid(adev, ring->xcc_id, ring, job->vmid);
if (ring->funcs->emit_gds_switch &&
gds_switch_needed) {
@ -2362,9 +2362,26 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
unsigned max_bits)
{
unsigned int max_size = 1 << (max_bits - 30);
bool sys_5level_pgtable = false;
unsigned int vm_size;
uint64_t tmp;
#ifdef CONFIG_X86_64
/*
* Refer to function configure_5level_paging() for details.
*/
sys_5level_pgtable = (native_read_cr4() & X86_CR4_LA57);
#endif
/*
* If GPU supports 5-level page table, but system uses 4-level page table,
* then use 4-level page table on GPU
*/
if (max_level == 4 && !sys_5level_pgtable) {
min_vm_size = 256 * 1024;
max_level = 3;
}
/* adjust vm size first */
if (amdgpu_vm_size != -1) {
vm_size = amdgpu_vm_size;
@ -2407,6 +2424,9 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1;
adev->vm_manager.num_level = min_t(unsigned int, max_level, tmp);
switch (adev->vm_manager.num_level) {
case 4:
adev->vm_manager.root_level = AMDGPU_VM_PDB3;
break;
case 3:
adev->vm_manager.root_level = AMDGPU_VM_PDB2;
break;

View file

@ -129,6 +129,7 @@ struct amdgpu_bo_vm;
AMDGPU_PTE_MTYPE_GFX12_SHIFT(mtype))
#define AMDGPU_PTE_DCC (1ULL << 58)
#define AMDGPU_PTE_BUS_ATOMICS (1ULL << 59)
#define AMDGPU_PTE_IS_PTE (1ULL << 63)
/* PDE Block Fragment Size for gfx v12 */
@ -185,9 +186,10 @@ struct amdgpu_bo_vm;
#define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
/* VMPT level enumerate, and the hiberachy is:
* PDB2->PDB1->PDB0->PTB
* PDB3->PDB2->PDB1->PDB0->PTB
*/
enum amdgpu_vm_level {
AMDGPU_VM_PDB3,
AMDGPU_VM_PDB2,
AMDGPU_VM_PDB1,
AMDGPU_VM_PDB0,

View file

@ -51,6 +51,7 @@ static unsigned int amdgpu_vm_pt_level_shift(struct amdgpu_device *adev,
unsigned int level)
{
switch (level) {
case AMDGPU_VM_PDB3:
case AMDGPU_VM_PDB2:
case AMDGPU_VM_PDB1:
case AMDGPU_VM_PDB0:
@ -366,6 +367,7 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo *ancestor = &vmbo->bo;
unsigned int entries;
struct amdgpu_bo *bo = &vmbo->bo;
uint64_t value = 0, flags = 0;
uint64_t addr;
int r, idx;
@ -403,7 +405,6 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
addr = 0;
uint64_t value = 0, flags = 0;
if (adev->asic_type >= CHIP_VEGA10) {
if (level != AMDGPU_VM_PTB) {
/* Handle leaf PDEs as PTEs */
@ -412,7 +413,7 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
&value, &flags);
} else {
/* Workaround for fault priority problem on GMC9 */
flags = AMDGPU_PTE_EXECUTABLE;
flags = AMDGPU_PTE_EXECUTABLE | adev->gmc.init_pte_flags;
}
}

View file

@ -790,7 +790,7 @@ static int vpe_ring_test_ring(struct amdgpu_ring *ring)
ret = amdgpu_ring_alloc(ring, 4);
if (ret) {
dev_err(adev->dev, "amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, ret);
dev_err(adev->dev, "dma failed to lock ring %d (%d).\n", ring->idx, ret);
goto out;
}

View file

@ -540,6 +540,7 @@ static void amdgpu_set_xcp_id(struct amdgpu_device *adev,
case AMDGPU_HW_IP_GFX:
case AMDGPU_RING_TYPE_COMPUTE:
case AMDGPU_RING_TYPE_KIQ:
case AMDGPU_RING_TYPE_MES:
ip_blk = AMDGPU_XCP_GFX;
break;
case AMDGPU_RING_TYPE_SDMA:

View file

@ -41,6 +41,9 @@
#define AMDGPU_XCP_OPS_KFD (1 << 0)
#define XCP_INST_MASK(num_inst, xcp_id) \
(num_inst ? GENMASK(num_inst - 1, 0) << (xcp_id * num_inst) : 0)
struct amdgpu_fpriv;
enum AMDGPU_XCP_IP_BLOCK {

View file

@ -201,7 +201,8 @@ union amd_sriov_ras_caps {
uint64_t block_mpio : 1;
uint64_t block_mmsch : 1;
uint64_t poison_propogation_mode : 1;
uint64_t reserved : 43;
uint64_t uniras_supported : 1;
uint64_t reserved : 42;
} bits;
uint64_t all;
};

View file

@ -31,9 +31,6 @@
#include "sdma_v4_4_2.h"
#include "amdgpu_ip.h"
#define XCP_INST_MASK(num_inst, xcp_id) \
(num_inst ? GENMASK(num_inst - 1, 0) << (xcp_id * num_inst) : 0)
void aqua_vanjaram_doorbell_index_init(struct amdgpu_device *adev)
{
int i;

View file

@ -1463,7 +1463,7 @@ static void atom_get_vbios_pn(struct atom_context *ctx)
ctx->vbios_pn[count] = 0;
}
pr_info("ATOM BIOS: %s\n", ctx->vbios_pn);
drm_info(ctx->card->dev, "ATOM BIOS: %s\n", ctx->vbios_pn);
}
static void atom_get_vbios_version(struct atom_context *ctx)

View file

@ -218,7 +218,7 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode
bd->props.power = BACKLIGHT_POWER_ON;
backlight_update_status(bd);
DRM_INFO("amdgpu atom DIG backlight initialized\n");
drm_info(adev_to_drm(adev), "ATOM DIG backlight initialized\n");
return;
@ -256,7 +256,7 @@ amdgpu_atombios_encoder_fini_backlight(struct amdgpu_encoder *amdgpu_encoder)
backlight_device_unregister(bd);
kfree(pdata);
DRM_INFO("amdgpu atom LVDS backlight unloaded\n");
drm_info(adev_to_drm(adev), "ATOM LVDS backlight unloaded\n");
}
}
@ -1724,7 +1724,7 @@ amdgpu_atombios_encoder_dac_detect(struct drm_encoder *encoder,
uint32_t bios_0_scratch;
if (!amdgpu_atombios_encoder_dac_load_detect(encoder, connector)) {
DRM_DEBUG_KMS("detect returned false \n");
DRM_DEBUG_KMS("detect returned false\n");
return connector_status_unknown;
}

View file

@ -1552,16 +1552,16 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
if (current_data_rate == 2) {
DRM_INFO("PCIE gen 3 link speeds already enabled\n");
drm_info(adev_to_drm(adev), "PCIE gen 3 link speeds already enabled\n");
return;
}
DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
drm_info(adev_to_drm(adev), "enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
} else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
if (current_data_rate == 1) {
DRM_INFO("PCIE gen 2 link speeds already enabled\n");
drm_info(adev_to_drm(adev), "PCIE gen 2 link speeds already enabled\n");
return;
}
DRM_INFO("enabling PCIE gen 2 link speeds, disable with amdgpu.pcie_gen2=0\n");
drm_info(adev_to_drm(adev), "enabling PCIE gen 2 link speeds, disable with amdgpu.pcie_gen2=0\n");
}
if (!pci_is_pcie(root) || !pci_is_pcie(adev->pdev))
@ -1957,10 +1957,6 @@ static uint64_t cik_get_pcie_replay_count(struct amdgpu_device *adev)
return (nak_r + nak_g);
}
static void cik_pre_asic_init(struct amdgpu_device *adev)
{
}
static const struct amdgpu_asic_funcs cik_asic_funcs =
{
.read_disabled_bios = &cik_read_disabled_bios,
@ -1981,7 +1977,6 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
.need_reset_on_init = &cik_need_reset_on_init,
.get_pcie_replay_count = &cik_get_pcie_replay_count,
.supports_baco = &cik_asic_supports_baco,
.pre_asic_init = &cik_pre_asic_init,
.query_video_codecs = &cik_query_video_codecs,
};

View file

@ -4041,8 +4041,8 @@ static int gfx_v10_0_ring_test_ring(struct amdgpu_ring *ring)
WREG32(scratch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(ring, 3);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
ring->idx, r);
drm_err(adev_to_drm(adev), "cp failed to lock ring %d (%d).\n",
ring->idx, r);
return r;
}
@ -4090,7 +4090,7 @@ static int gfx_v10_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib);
if (r) {
DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
drm_err(adev_to_drm(adev), "failed to get ib (%ld).\n", r);
goto err1;
}
@ -4170,7 +4170,7 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
}
if (!adev->gfx.cp_fw_write_wait)
DRM_WARN_ONCE("CP firmware version too old, please update!");
drm_warn_once(adev_to_drm(adev), "CP firmware version too old, please update!");
}
static bool gfx_v10_0_navi10_gfxoff_should_enable(struct amdgpu_device *adev)
@ -4575,6 +4575,7 @@ static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v10_0_select_me_pipe_q,
.init_spm_golden = &gfx_v10_0_init_spm_golden_registers,
.update_perfmon_mgcg = &gfx_v10_0_update_perfmon_mgcg,
.get_hdp_flush_mask = &amdgpu_gfx_get_hdp_flush_mask,
};
static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
@ -6378,7 +6379,7 @@ static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev)
ring = &adev->gfx.gfx_ring[0];
r = amdgpu_ring_alloc(ring, gfx_v10_0_get_csb_size(adev) + 4);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(adev_to_drm(adev), "cp failed to lock ring (%d).\n", r);
return r;
}
@ -6428,7 +6429,7 @@ static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev)
ring = &adev->gfx.gfx_ring[1];
r = amdgpu_ring_alloc(ring, 2);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(adev_to_drm(adev), "cp failed to lock ring (%d).\n", r);
return r;
}
@ -8318,7 +8319,8 @@ static void gfx_v10_0_update_spm_vmid_internal(struct amdgpu_device *adev,
}
}
static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned int vmid)
static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, int xcc_id,
struct amdgpu_ring *ring, unsigned int vmid)
{
amdgpu_gfx_off_ctrl(adev, false);
@ -8613,25 +8615,13 @@ static void gfx_v10_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
u32 ref_and_mask, reg_mem_engine;
const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg;
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
switch (ring->me) {
case 1:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp2 << ring->pipe;
break;
case 2:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp6 << ring->pipe;
break;
default:
return;
}
reg_mem_engine = 0;
} else {
ref_and_mask = nbio_hf_reg->ref_and_mask_cp0 << ring->pipe;
reg_mem_engine = 1; /* pfp */
if (!adev->gfx.funcs->get_hdp_flush_mask) {
dev_err(adev->dev, "%s: gfx hdp flush is not supported.\n", __func__);
return;
}
adev->gfx.funcs->get_hdp_flush_mask(ring, &ref_and_mask, &reg_mem_engine);
gfx_v10_0_wait_reg_mem(ring, reg_mem_engine, 0, 1,
adev->nbio.funcs->get_hdp_flush_req_offset(adev),
adev->nbio.funcs->get_hdp_flush_done_offset(adev),
@ -9395,7 +9385,7 @@ static int gfx_v10_0_bad_op_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
DRM_ERROR("Illegal opcode in command stream \n");
DRM_ERROR("Illegal opcode in command stream\n");
gfx_v10_0_handle_priv_fault(adev, entry);
return 0;
}
@ -10124,7 +10114,7 @@ static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev,
if (!adev || !cu_info)
return -EINVAL;
amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
amdgpu_gfx_parse_disable_cu(adev, disable_masks, 4, 2);
mutex_lock(&adev->grbm_idx_mutex);
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {

View file

@ -120,6 +120,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_5_3_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_4_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_4_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_4_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_4_rlc.bin");
static const struct amdgpu_hwip_reg_entry gc_reg_list_11_0[] = {
SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS),
@ -416,7 +420,8 @@ static void gfx11_kiq_unmap_queues(struct amdgpu_ring *kiq_ring,
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
if (adev->enable_mes && !adev->gfx.kiq[0].ring.sched.ready) {
amdgpu_mes_unmap_legacy_queue(adev, ring, action, gpu_addr, seq);
amdgpu_mes_unmap_legacy_queue(adev, ring, action,
gpu_addr, seq, 0);
return;
}
@ -566,8 +571,8 @@ static int gfx_v11_0_ring_test_ring(struct amdgpu_ring *ring)
WREG32(scratch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(ring, 5);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
ring->idx, r);
drm_err(adev_to_drm(adev), "cp failed to lock ring %d (%d).\n",
ring->idx, r);
return r;
}
@ -623,7 +628,7 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib);
if (r) {
DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
drm_err(adev_to_drm(adev), "failed to get ib (%ld).\n", r);
goto err1;
}
@ -917,7 +922,7 @@ static int gfx_v11_0_rlc_init(struct amdgpu_device *adev)
/* init spm vmid with 0xf */
if (adev->gfx.rlc.funcs->update_spm_vmid)
adev->gfx.rlc.funcs->update_spm_vmid(adev, NULL, 0xf);
adev->gfx.rlc.funcs->update_spm_vmid(adev, 0, NULL, 0xf);
return 0;
}
@ -1052,10 +1057,14 @@ static void gfx_v11_0_select_me_pipe_q(struct amdgpu_device *adev,
static void gfx_v11_0_get_gfx_shadow_info_nocheck(struct amdgpu_device *adev,
struct amdgpu_gfx_shadow_info *shadow_info)
{
/* for gfx */
shadow_info->shadow_size = MQD_SHADOW_BASE_SIZE;
shadow_info->shadow_alignment = MQD_SHADOW_BASE_ALIGNMENT;
shadow_info->csa_size = MQD_FWWORKAREA_SIZE;
shadow_info->csa_alignment = MQD_FWWORKAREA_ALIGNMENT;
/* for compute */
shadow_info->eop_size = GFX11_MEC_HPD_SIZE;
shadow_info->eop_alignment = 256;
}
static int gfx_v11_0_get_gfx_shadow_info(struct amdgpu_device *adev,
@ -1080,6 +1089,7 @@ static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
.update_perfmon_mgcg = &gfx_v11_0_update_perf_clk,
.get_gfx_shadow_info = &gfx_v11_0_get_gfx_shadow_info,
.get_hdp_flush_mask = &amdgpu_gfx_get_hdp_flush_mask,
};
static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
@ -1107,6 +1117,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
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;
@ -1589,6 +1600,7 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 2;
@ -3046,7 +3058,8 @@ static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 0) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 1) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 2) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 3))
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 3) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 4))
bootload_status = RREG32_SOC15(GC, 0,
regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1);
else
@ -3617,7 +3630,7 @@ static int gfx_v11_0_cp_gfx_start(struct amdgpu_device *adev)
ring = &adev->gfx.gfx_ring[0];
r = amdgpu_ring_alloc(ring, gfx_v11_0_get_csb_size(adev));
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(&adev->ddev, "cp failed to lock ring (%d).\n", r);
return r;
}
@ -3662,7 +3675,7 @@ static int gfx_v11_0_cp_gfx_start(struct amdgpu_device *adev)
ring = &adev->gfx.gfx_ring[1];
r = amdgpu_ring_alloc(ring, 2);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(adev_to_drm(adev), "cp failed to lock ring (%d).\n", r);
return r;
}
@ -4593,7 +4606,7 @@ static int gfx_v11_0_cp_resume(struct amdgpu_device *adev)
}
if (adev->enable_mes_kiq && adev->mes.kiq_hw_init)
r = amdgpu_mes_kiq_hw_init(adev);
r = amdgpu_mes_kiq_hw_init(adev, 0);
else
r = gfx_v11_0_kiq_resume(adev);
if (r)
@ -4783,7 +4796,7 @@ static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
adev->gfx.is_poweron = true;
if(get_gb_addr_config(adev))
DRM_WARN("Invalid gb_addr_config !\n");
drm_warn(adev_to_drm(adev), "Invalid gb_addr_config !\n");
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
adev->gfx.rs64_enable)
@ -4901,7 +4914,7 @@ static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
if (amdgpu_gfx_disable_kcq(adev, 0))
DRM_ERROR("KCQ disable failed\n");
amdgpu_mes_kiq_hw_fini(adev);
amdgpu_mes_kiq_hw_fini(adev, 0);
}
if (amdgpu_sriov_vf(adev))
@ -5568,7 +5581,8 @@ static int gfx_v11_0_update_gfx_clock_gating(struct amdgpu_device *adev,
return 0;
}
static void gfx_v11_0_update_spm_vmid(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned vmid)
static void gfx_v11_0_update_spm_vmid(struct amdgpu_device *adev, int xcc_id,
struct amdgpu_ring *ring, unsigned vmid)
{
u32 reg, pre_data, data;
@ -5633,6 +5647,7 @@ static void gfx_v11_cntl_power_gating(struct amdgpu_device *adev, bool enable)
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
WREG32_SOC15(GC, 0, regRLC_PG_DELAY_3, RLC_PG_DELAY_3_DEFAULT_GC_11_0_1);
break;
default:
@ -5671,6 +5686,7 @@ static int gfx_v11_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
if (!enable)
amdgpu_gfx_off_ctrl(adev, false);
@ -5705,6 +5721,7 @@ static int gfx_v11_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
case IP_VERSION(11, 5, 1):
case IP_VERSION(11, 5, 2):
case IP_VERSION(11, 5, 3):
case IP_VERSION(11, 5, 4):
gfx_v11_0_update_gfx_clock_gating(adev,
state == AMD_CG_STATE_GATE);
break;
@ -5831,25 +5848,13 @@ static void gfx_v11_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
u32 ref_and_mask, reg_mem_engine;
const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg;
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
switch (ring->me) {
case 1:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp2 << ring->pipe;
break;
case 2:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp6 << ring->pipe;
break;
default:
return;
}
reg_mem_engine = 0;
} else {
ref_and_mask = nbio_hf_reg->ref_and_mask_cp0 << ring->pipe;
reg_mem_engine = 1; /* pfp */
if (!adev->gfx.funcs->get_hdp_flush_mask) {
dev_err(adev->dev, "%s: gfx hdp flush is not supported.\n", __func__);
return;
}
adev->gfx.funcs->get_hdp_flush_mask(ring, &ref_and_mask, &reg_mem_engine);
gfx_v11_0_wait_reg_mem(ring, reg_mem_engine, 0, 1,
adev->nbio.funcs->get_hdp_flush_req_offset(adev),
adev->nbio.funcs->get_hdp_flush_done_offset(adev),
@ -6664,7 +6669,7 @@ static int gfx_v11_0_bad_op_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
DRM_ERROR("Illegal opcode in command stream \n");
DRM_ERROR("Illegal opcode in command stream\n");
gfx_v11_0_handle_priv_fault(adev, entry);
return 0;
}
@ -6827,7 +6832,7 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring,
amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false, 0);
if (r) {
dev_warn(adev->dev, "reset via MES failed and try pipe reset %d\n", r);
@ -6842,7 +6847,7 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring,
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
if (r) {
dev_err(adev->dev, "failed to remap kgq\n");
return r;
@ -6990,7 +6995,7 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring,
amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true, 0);
if (r) {
dev_warn(adev->dev, "fail(%d) to reset kcq and try pipe reset\n", r);
r = gfx_v11_0_reset_compute_pipe(ring);
@ -7003,7 +7008,7 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring,
dev_err(adev->dev, "fail to init kcq\n");
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
if (r) {
dev_err(adev->dev, "failed to remap kcq\n");
return r;
@ -7477,7 +7482,7 @@ static int gfx_v11_0_get_cu_info(struct amdgpu_device *adev,
if (!adev || !cu_info)
return -EINVAL;
amdgpu_gfx_parse_disable_cu(disable_masks, 8, 2);
amdgpu_gfx_parse_disable_cu(adev, disable_masks, 8, 2);
mutex_lock(&adev->grbm_idx_mutex);
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {

View file

@ -356,7 +356,8 @@ static void gfx_v12_0_kiq_unmap_queues(struct amdgpu_ring *kiq_ring,
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
if (adev->enable_mes && !adev->gfx.kiq[0].ring.sched.ready) {
amdgpu_mes_unmap_legacy_queue(adev, ring, action, gpu_addr, seq);
amdgpu_mes_unmap_legacy_queue(adev, ring, action,
gpu_addr, seq, 0);
return;
}
@ -459,8 +460,8 @@ static int gfx_v12_0_ring_test_ring(struct amdgpu_ring *ring)
WREG32(scratch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(ring, 5);
if (r) {
dev_err(adev->dev,
"amdgpu: cp failed to lock ring %d (%d).\n",
drm_err(adev_to_drm(adev),
"cp failed to lock ring %d (%d).\n",
ring->idx, r);
return r;
}
@ -517,7 +518,7 @@ static int gfx_v12_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
r = amdgpu_ib_get(adev, NULL, 16, AMDGPU_IB_POOL_DIRECT, &ib);
if (r) {
dev_err(adev->dev, "amdgpu: failed to get ib (%ld).\n", r);
drm_err(adev_to_drm(adev), "failed to get ib (%ld).\n", r);
goto err1;
}
@ -761,7 +762,7 @@ static int gfx_v12_0_rlc_init(struct amdgpu_device *adev)
/* init spm vmid with 0xf */
if (adev->gfx.rlc.funcs->update_spm_vmid)
adev->gfx.rlc.funcs->update_spm_vmid(adev, NULL, 0xf);
adev->gfx.rlc.funcs->update_spm_vmid(adev, 0, NULL, 0xf);
return 0;
}
@ -909,10 +910,14 @@ static void gfx_v12_0_select_me_pipe_q(struct amdgpu_device *adev,
static void gfx_v12_0_get_gfx_shadow_info_nocheck(struct amdgpu_device *adev,
struct amdgpu_gfx_shadow_info *shadow_info)
{
/* for gfx */
shadow_info->shadow_size = MQD_SHADOW_BASE_SIZE;
shadow_info->shadow_alignment = MQD_SHADOW_BASE_ALIGNMENT;
shadow_info->csa_size = MQD_FWWORKAREA_SIZE;
shadow_info->csa_alignment = MQD_FWWORKAREA_ALIGNMENT;
/* for compute */
shadow_info->eop_size = GFX12_MEC_HPD_SIZE;
shadow_info->eop_alignment = 256;
}
static int gfx_v12_0_get_gfx_shadow_info(struct amdgpu_device *adev,
@ -937,6 +942,7 @@ static const struct amdgpu_gfx_funcs gfx_v12_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v12_0_select_me_pipe_q,
.update_perfmon_mgcg = &gfx_v12_0_update_perf_clk,
.get_gfx_shadow_info = &gfx_v12_0_get_gfx_shadow_info,
.get_hdp_flush_mask = &amdgpu_gfx_get_hdp_flush_mask,
};
static int gfx_v12_0_gpu_early_init(struct amdgpu_device *adev)
@ -3470,7 +3476,7 @@ static int gfx_v12_0_cp_resume(struct amdgpu_device *adev)
}
if (adev->enable_mes_kiq && adev->mes.kiq_hw_init)
r = amdgpu_mes_kiq_hw_init(adev);
r = amdgpu_mes_kiq_hw_init(adev, 0);
else
r = gfx_v12_0_kiq_resume(adev);
if (r)
@ -3651,7 +3657,7 @@ static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
adev->gfx.is_poweron = true;
if (get_gb_addr_config(adev))
DRM_WARN("Invalid gb_addr_config !\n");
drm_warn(adev_to_drm(adev), "Invalid gb_addr_config !\n");
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
gfx_v12_0_config_gfx_rs64(adev);
@ -3759,7 +3765,7 @@ static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
if (amdgpu_gfx_disable_kcq(adev, 0))
DRM_ERROR("KCQ disable failed\n");
amdgpu_mes_kiq_hw_fini(adev);
amdgpu_mes_kiq_hw_fini(adev, 0);
}
if (amdgpu_sriov_vf(adev)) {
@ -3956,6 +3962,7 @@ static void gfx_v12_0_update_perf_clk(struct amdgpu_device *adev,
}
static void gfx_v12_0_update_spm_vmid(struct amdgpu_device *adev,
int xcc_id,
struct amdgpu_ring *ring,
unsigned vmid)
{
@ -4387,25 +4394,13 @@ static void gfx_v12_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
u32 ref_and_mask, reg_mem_engine;
const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg;
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
switch (ring->me) {
case 1:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp2 << ring->pipe;
break;
case 2:
ref_and_mask = nbio_hf_reg->ref_and_mask_cp6 << ring->pipe;
break;
default:
return;
}
reg_mem_engine = 0;
} else {
ref_and_mask = nbio_hf_reg->ref_and_mask_cp0;
reg_mem_engine = 1; /* pfp */
if (!adev->gfx.funcs->get_hdp_flush_mask) {
dev_err(adev->dev, "%s: gfx hdp flush is not supported.\n", __func__);
return;
}
adev->gfx.funcs->get_hdp_flush_mask(ring, &ref_and_mask, &reg_mem_engine);
gfx_v12_0_wait_reg_mem(ring, reg_mem_engine, 0, 1,
adev->nbio.funcs->get_hdp_flush_req_offset(adev),
adev->nbio.funcs->get_hdp_flush_done_offset(adev),
@ -5051,7 +5046,7 @@ static int gfx_v12_0_bad_op_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
DRM_ERROR("Illegal opcode in command stream \n");
DRM_ERROR("Illegal opcode in command stream\n");
gfx_v12_0_handle_priv_fault(adev, entry);
return 0;
}
@ -5312,7 +5307,7 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring,
amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false, 0);
if (r) {
dev_warn(adev->dev, "reset via MES failed and try pipe reset %d\n", r);
r = gfx_v12_reset_gfx_pipe(ring);
@ -5326,7 +5321,7 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring,
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
if (r) {
dev_err(adev->dev, "failed to remap kgq\n");
return r;
@ -5427,7 +5422,7 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring,
amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true, 0);
if (r) {
dev_warn(adev->dev, "fail(%d) to reset kcq and try pipe reset\n", r);
r = gfx_v12_0_reset_compute_pipe(ring);
@ -5440,7 +5435,7 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring,
dev_err(adev->dev, "failed to init kcq\n");
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
if (r) {
dev_err(adev->dev, "failed to remap kcq\n");
return r;
@ -5733,7 +5728,7 @@ static int gfx_v12_0_get_cu_info(struct amdgpu_device *adev,
if (!adev || !cu_info)
return -EINVAL;
amdgpu_gfx_parse_disable_cu(disable_masks, 8, 2);
amdgpu_gfx_parse_disable_cu(adev, disable_masks, 8, 2);
mutex_lock(&adev->grbm_idx_mutex);
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
/*
* Copyright 2025 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 __GFX_V12_1_H__
#define __GFX_V12_1_H__
extern const struct amdgpu_ip_block_version gfx_v12_1_ip_block;
extern struct amdgpu_xcp_ip_funcs gfx_v12_1_xcp_funcs;
#endif

View file

@ -0,0 +1,475 @@
/*
* Copyright 2025 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 GFX_V12_1_PKT_H
#define GFX_V12_1_PKT_H
/**
* PM4 definitions
*/
#define PACKET_TYPE0 0
#define PACKET_TYPE1 1
#define PACKET_TYPE2 2
#define PACKET_TYPE3 3
#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
#define CP_PACKET0_GET_REG(h) ((h) & 0xFFFF)
#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
((reg) & 0xFFFF) | \
((n) & 0x3FFF) << 16)
#define CP_PACKET2 0x80000000
#define PACKET2_PAD_SHIFT 0
#define PACKET2_PAD_MASK (0x3fffffff << 0)
#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
(((op) & 0xFF) << 8) | \
((n) & 0x3FFF) << 16)
#define PACKET3_COMPUTE(op, n) (PACKET3(op, n) | 1 << 1)
/* Packet 3 types */
#define PACKET3_NOP 0x10
#define PACKET3_SET_BASE 0x11
#define PACKET3_BASE_INDEX(x) ((x) << 0)
#define CE_PARTITION_BASE 3
#define PACKET3_CLEAR_STATE 0x12
#define PACKET3_INDEX_BUFFER_SIZE 0x13
#define PACKET3_DISPATCH_DIRECT 0x15
#define PACKET3_DISPATCH_INDIRECT 0x16
#define PACKET3_INDIRECT_BUFFER_END 0x17
#define PACKET3_INDIRECT_BUFFER_CNST_END 0x19
#define PACKET3_ATOMIC_GDS 0x1D
#define PACKET3_ATOMIC_MEM 0x1E
#define PACKET3_OCCLUSION_QUERY 0x1F
#define PACKET3_SET_PREDICATION 0x20
#define PACKET3_REG_RMW 0x21
#define PACKET3_COND_EXEC 0x22
#define PACKET3_PRED_EXEC 0x23
#define PACKET3_DRAW_INDIRECT 0x24
#define PACKET3_DRAW_INDEX_INDIRECT 0x25
#define PACKET3_INDEX_BASE 0x26
#define PACKET3_DRAW_INDEX_2 0x27
#define PACKET3_CONTEXT_CONTROL 0x28
#define PACKET3_INDEX_TYPE 0x2A
#define PACKET3_DRAW_INDIRECT_MULTI 0x2C
#define PACKET3_DRAW_INDEX_AUTO 0x2D
#define PACKET3_NUM_INSTANCES 0x2F
#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30
#define PACKET3_INDIRECT_BUFFER_PRIV 0x32
#define PACKET3_INDIRECT_BUFFER_CNST 0x33
#define PACKET3_COND_INDIRECT_BUFFER_CNST 0x33
#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34
#define PACKET3_DRAW_INDEX_OFFSET_2 0x35
#define PACKET3_DRAW_PREAMBLE 0x36
#define PACKET3_WRITE_DATA 0x37
#define WRITE_DATA_DST_SEL(x) ((x) << 8)
/* 0 - register
* 1 - memory (sync - via GRBM)
* 2 - gl2
* 3 - gds
* 4 - reserved
* 5 - memory (async - direct)
*/
#define WR_ONE_ADDR (1 << 16)
#define WR_CONFIRM (1 << 20)
#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
/* 0 - LRU
* 1 - Stream
*/
#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
/* 0 - me
* 1 - pfp
* 2 - ce
*/
#define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38
#define PACKET3_MEM_SEMAPHORE 0x39
# define PACKET3_SEM_USE_MAILBOX (0x1 << 16)
# define PACKET3_SEM_SEL_SIGNAL_TYPE (0x1 << 20) /* 0 = increment, 1 = write 1 */
# define PACKET3_SEM_SEL_SIGNAL (0x6 << 29)
# define PACKET3_SEM_SEL_WAIT (0x7 << 29)
#define PACKET3_DRAW_INDEX_MULTI_INST 0x3A
#define PACKET3_COPY_DW 0x3B
#define PACKET3_WAIT_REG_MEM 0x3C
#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
/* 0 - always
* 1 - <
* 2 - <=
* 3 - ==
* 4 - !=
* 5 - >=
* 6 - >
*/
#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
/* 0 - reg
* 1 - mem
*/
#define WAIT_REG_MEM_OPERATION(x) ((x) << 6)
/* 0 - wait_reg_mem
* 1 - wr_wait_wr_reg
*/
#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
/* 0 - me
* 1 - pfp
*/
#define PACKET3_INDIRECT_BUFFER 0x3F
#define INDIRECT_BUFFER_VALID (1 << 23)
#define INDIRECT_BUFFER_CACHE_POLICY(x) ((x) << 28)
/* 0 - LRU
* 1 - Stream
* 2 - Bypass
*/
#define INDIRECT_BUFFER_PRE_ENB(x) ((x) << 21)
#define INDIRECT_BUFFER_PRE_RESUME(x) ((x) << 30)
#define PACKET3_COND_INDIRECT_BUFFER 0x3F
#define PACKET3_COPY_DATA 0x40
#define PACKET3_CP_DMA 0x41
#define PACKET3_PFP_SYNC_ME 0x42
#define PACKET3_SURFACE_SYNC 0x43
#define PACKET3_ME_INITIALIZE 0x44
#define PACKET3_COND_WRITE 0x45
#define PACKET3_EVENT_WRITE 0x46
#define EVENT_TYPE(x) ((x) << 0)
#define EVENT_INDEX(x) ((x) << 8)
/* 0 - any non-TS event
* 1 - ZPASS_DONE, PIXEL_PIPE_STAT_*
* 2 - SAMPLE_PIPELINESTAT
* 3 - SAMPLE_STREAMOUTSTAT*
* 4 - *S_PARTIAL_FLUSH
*/
#define PACKET3_EVENT_WRITE_EOP 0x47
#define PACKET3_EVENT_WRITE_EOS 0x48
#define PACKET3_RELEASE_MEM 0x49
#define PACKET3_RELEASE_MEM_EVENT_TYPE(x) ((x) << 0)
#define PACKET3_RELEASE_MEM_EVENT_INDEX(x) ((x) << 8)
#define PACKET3_RELEASE_MEM_GCR_GL2_SCOPE(x) ((x) << 12)
#define PACKET3_RELEASE_MEM_GCR_GLV_INV (1 << 14)
#define PACKET3_RELEASE_MEM_GCR_GL2_US (1 << 16)
#define PACKET3_RELEASE_MEM_GCR_GL2_RANGE(x) ((x) << 17)
#define PACKET3_RELEASE_MEM_GCR_GL2_DISCARD (1 << 19)
#define PACKET3_RELEASE_MEM_GCR_GL2_INV (1 << 20)
#define PACKET3_RELEASE_MEM_GCR_GL2_WB (1 << 21)
#define PACKET3_RELEASE_MEM_GCR_SEQ(x) ((x) << 22)
#define PACKET3_RELEASE_MEM_GCR_GLV_WB (1 << 24)
#define PACKET3_RELEASE_MEM_TEMPORAL(x) ((x) << 25)
/* 0 - temporal__release_mem__rt
* 1 - temporal__release_mem__nt
* 2 - temporal__release_mem__ht
* 3 - temporal__release_mem__lu
*/
#define PACKET3_RELEASE_MEM_EXECUTE (1 << 28)
#define PACKET3_RELEASE_MEM_DATA_SEL(x) ((x) << 29)
/* 0 - discard
* 1 - send low 32bit data
* 2 - send 64bit data
* 3 - send 64bit GPU counter value
* 4 - send 64bit sys counter value
*/
#define PACKET3_RELEASE_MEM_INT_SEL(x) ((x) << 24)
/* 0 - none
* 1 - interrupt only (DATA_SEL = 0)
* 2 - interrupt when data write is confirmed
*/
#define PACKET3_RELEASE_MEM_DST_SEL(x) ((x) << 16)
/* 0 - MC
* 1 - TC/L2
*/
#define PACKET3_PREAMBLE_CNTL 0x4A
# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28)
# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28)
#define PACKET3_DMA_DATA 0x50
/* 1. header
* 2. CONTROL
* 3. SRC_ADDR_LO or DATA [31:0]
* 4. SRC_ADDR_HI [31:0]
* 5. DST_ADDR_LO [31:0]
* 6. DST_ADDR_HI [7:0]
* 7. COMMAND [31:26] | BYTE_COUNT [25:0]
*/
/* CONTROL */
# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
/* 0 - ME
* 1 - PFP
*/
# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
/* 0 - LRU
* 1 - Stream
*/
# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
/* 0 - DST_ADDR using DAS
* 1 - GDS
* 3 - DST_ADDR using L2
*/
# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
/* 0 - LRU
* 1 - Stream
*/
# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
/* 0 - SRC_ADDR using SAS
* 1 - GDS
* 2 - DATA
* 3 - SRC_ADDR using L2
*/
# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
/* COMMAND */
# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
/* 0 - memory
* 1 - register
*/
# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
/* 0 - memory
* 1 - register
*/
# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
#define PACKET3_CONTEXT_REG_RMW 0x51
#define PACKET3_GFX_CNTX_UPDATE 0x52
#define PACKET3_BLK_CNTX_UPDATE 0x53
#define PACKET3_INCR_UPDT_STATE 0x55
#define PACKET3_ACQUIRE_MEM 0x58
/* 1. HEADER
* 2. COHER_CNTL [30:0]
* 2.1 ENGINE_SEL [31:31]
* 2. COHER_SIZE [31:0]
* 3. COHER_SIZE_HI [7:0]
* 4. COHER_BASE_LO [31:0]
* 5. COHER_BASE_HI [23:0]
* 7. POLL_INTERVAL [15:0]
* 8. GCR_CNTL [18:0]
*/
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GLI_INV(x) ((x) << 0)
/*
* 0:NOP
* 1:ALL
* 2:RANGE
* 3:FIRST_LAST
*/
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL1_RANGE(x) ((x) << 2)
/*
* 0:ALL
* 1:reserved
* 2:RANGE
* 3:FIRST_LAST
*/
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_SCOPE(x) ((x) << 4)
/*
* 0:Device scope
* 1:System scope
* 2:Force INV/WB all
* 3:Reserved
*/
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GLV_WB(x) ((x) << 6)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GLK_INV(x) ((x) << 7)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GLV_INV(x) ((x) << 8)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_US(x) ((x) << 10)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_RANGE(x) ((x) << 11)
/*
* 0:ALL
* 1:VOL
* 2:RANGE
* 3:FIRST_LAST
*/
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_DISCARD(x) ((x) << 13)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_INV(x) ((x) << 14)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_WB(x) ((x) << 15)
#define PACKET3_ACQUIRE_MEM_GCR_CNTL_SEQ(x) ((x) << 16)
/*
* 0: PARALLEL
* 1: FORWARD
* 2: REVERSE
*/
#define PACKET3_ACQUIRE_MEM_GCR_RANGE_IS_PA (1 << 18)
#define PACKET3_REWIND 0x59
#define PACKET3_INTERRUPT 0x5A
#define PACKET3_GEN_PDEPTE 0x5B
#define PACKET3_INDIRECT_BUFFER_PASID 0x5C
#define PACKET3_PRIME_UTCL2 0x5D
#define PACKET3_LOAD_UCONFIG_REG 0x5E
#define PACKET3_LOAD_SH_REG 0x5F
#define PACKET3_LOAD_CONFIG_REG 0x60
#define PACKET3_LOAD_CONTEXT_REG 0x61
#define PACKET3_LOAD_COMPUTE_STATE 0x62
#define PACKET3_LOAD_SH_REG_INDEX 0x63
#define PACKET3_SET_CONFIG_REG 0x68
#define PACKET3_SET_CONFIG_REG_START 0x00002000
#define PACKET3_SET_CONFIG_REG_END 0x00002c00
#define PACKET3_SET_CONTEXT_REG 0x69
#define PACKET3_SET_CONTEXT_REG_START 0x0000a000
#define PACKET3_SET_CONTEXT_REG_END 0x0000a400
#define PACKET3_SET_CONTEXT_REG_INDEX 0x6A
#define PACKET3_SET_VGPR_REG_DI_MULTI 0x71
#define PACKET3_SET_SH_REG_DI 0x72
#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73
#define PACKET3_SET_SH_REG_DI_MULTI 0x74
#define PACKET3_GFX_PIPE_LOCK 0x75
#define PACKET3_SET_SH_REG 0x76
#define PACKET3_SET_SH_REG_START 0x00002c00
#define PACKET3_SET_SH_REG_END 0x00003000
#define PACKET3_SET_SH_REG_OFFSET 0x77
#define PACKET3_SET_QUEUE_REG 0x78
#define PACKET3_SET_UCONFIG_REG 0x79
#define PACKET3_SET_UCONFIG_REG_START 0x0000c000
#define PACKET3_SET_UCONFIG_REG_END 0x0000c400
#define PACKET3_SET_UCONFIG_REG_INDEX 0x7A
#define PACKET3_FORWARD_HEADER 0x7C
#define PACKET3_SCRATCH_RAM_WRITE 0x7D
#define PACKET3_SCRATCH_RAM_READ 0x7E
#define PACKET3_LOAD_CONST_RAM 0x80
#define PACKET3_WRITE_CONST_RAM 0x81
#define PACKET3_DUMP_CONST_RAM 0x83
#define PACKET3_INCREMENT_CE_COUNTER 0x84
#define PACKET3_INCREMENT_DE_COUNTER 0x85
#define PACKET3_WAIT_ON_CE_COUNTER 0x86
#define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88
#define PACKET3_SWITCH_BUFFER 0x8B
#define PACKET3_DISPATCH_DRAW_PREAMBLE 0x8C
#define PACKET3_DISPATCH_DRAW_PREAMBLE_ACE 0x8C
#define PACKET3_DISPATCH_DRAW 0x8D
#define PACKET3_DISPATCH_DRAW_ACE 0x8D
#define PACKET3_GET_LOD_STATS 0x8E
#define PACKET3_DRAW_MULTI_PREAMBLE 0x8F
#define PACKET3_FRAME_CONTROL 0x90
# define FRAME_TMZ (1 << 0)
# define FRAME_CMD(x) ((x) << 28)
/*
* x=0: tmz_begin
* x=1: tmz_end
*/
#define PACKET3_INDEX_ATTRIBUTES_INDIRECT 0x91
#define PACKET3_WAIT_REG_MEM64 0x93
#define PACKET3_COND_PREEMPT 0x94
#define PACKET3_HDP_FLUSH 0x95
#define PACKET3_COPY_DATA_RB 0x96
#define PACKET3_INVALIDATE_TLBS 0x98
#define PACKET3_INVALIDATE_TLBS_DST_SEL(x) ((x) << 0)
#define PACKET3_INVALIDATE_TLBS_ALL_HUB(x) ((x) << 4)
#define PACKET3_INVALIDATE_TLBS_PASID(x) ((x) << 5)
#define PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(x) ((x) << 29)
#define PACKET3_AQL_PACKET 0x99
#define PACKET3_DMA_DATA_FILL_MULTI 0x9A
#define PACKET3_SET_SH_REG_INDEX 0x9B
#define PACKET3_DRAW_INDIRECT_COUNT_MULTI 0x9C
#define PACKET3_DRAW_INDEX_INDIRECT_COUNT_MULTI 0x9D
#define PACKET3_DUMP_CONST_RAM_OFFSET 0x9E
#define PACKET3_LOAD_CONTEXT_REG_INDEX 0x9F
#define PACKET3_SET_RESOURCES 0xA0
/* 1. header
* 2. CONTROL
* 3. QUEUE_MASK_LO [31:0]
* 4. QUEUE_MASK_HI [31:0]
* 5. GWS_MASK_LO [31:0]
* 6. GWS_MASK_HI [31:0]
* 7. OAC_MASK [15:0]
* 8. GDS_HEAP_SIZE [16:11] | GDS_HEAP_BASE [5:0]
*/
# define PACKET3_SET_RESOURCES_VMID_MASK(x) ((x) << 0)
# define PACKET3_SET_RESOURCES_UNMAP_LATENTY(x) ((x) << 16)
# define PACKET3_SET_RESOURCES_QUEUE_TYPE(x) ((x) << 29)
#define PACKET3_MAP_PROCESS 0xA1
#define PACKET3_MAP_QUEUES 0xA2
/* 1. header
* 2. CONTROL
* 3. CONTROL2
* 4. MQD_ADDR_LO [31:0]
* 5. MQD_ADDR_HI [31:0]
* 6. WPTR_ADDR_LO [31:0]
* 7. WPTR_ADDR_HI [31:0]
*/
/* CONTROL */
# define PACKET3_MAP_QUEUES_QUEUE_SEL(x) ((x) << 4)
# define PACKET3_MAP_QUEUES_VMID(x) ((x) << 8)
# define PACKET3_MAP_QUEUES_QUEUE(x) ((x) << 13)
# define PACKET3_MAP_QUEUES_PIPE(x) ((x) << 16)
# define PACKET3_MAP_QUEUES_ME(x) ((x) << 18)
# define PACKET3_MAP_QUEUES_QUEUE_TYPE(x) ((x) << 21)
# define PACKET3_MAP_QUEUES_ALLOC_FORMAT(x) ((x) << 24)
# define PACKET3_MAP_QUEUES_ENGINE_SEL(x) ((x) << 26)
# define PACKET3_MAP_QUEUES_NUM_QUEUES(x) ((x) << 29)
/* CONTROL2 */
# define PACKET3_MAP_QUEUES_CHECK_DISABLE(x) ((x) << 1)
# define PACKET3_MAP_QUEUES_DOORBELL_OFFSET(x) ((x) << 2)
#define PACKET3_UNMAP_QUEUES 0xA3
/* 1. header
* 2. CONTROL
* 3. CONTROL2
* 4. CONTROL3
* 5. CONTROL4
* 6. CONTROL5
*/
/* CONTROL */
# define PACKET3_UNMAP_QUEUES_ACTION(x) ((x) << 0)
/* 0 - PREEMPT_QUEUES
* 1 - RESET_QUEUES
* 2 - DISABLE_PROCESS_QUEUES
* 3 - PREEMPT_QUEUES_NO_UNMAP
*/
# define PACKET3_UNMAP_QUEUES_QUEUE_SEL(x) ((x) << 4)
# define PACKET3_UNMAP_QUEUES_ENGINE_SEL(x) ((x) << 26)
# define PACKET3_UNMAP_QUEUES_NUM_QUEUES(x) ((x) << 29)
/* CONTROL2a */
# define PACKET3_UNMAP_QUEUES_PASID(x) ((x) << 0)
/* CONTROL2b */
# define PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(x) ((x) << 2)
/* CONTROL3a */
# define PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET1(x) ((x) << 2)
/* CONTROL3b */
# define PACKET3_UNMAP_QUEUES_RB_WPTR(x) ((x) << 0)
/* CONTROL4 */
# define PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET2(x) ((x) << 2)
/* CONTROL5 */
# define PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET3(x) ((x) << 2)
#define PACKET3_QUERY_STATUS 0xA4
/* 1. header
* 2. CONTROL
* 3. CONTROL2
* 4. ADDR_LO [31:0]
* 5. ADDR_HI [31:0]
* 6. DATA_LO [31:0]
* 7. DATA_HI [31:0]
*/
/* CONTROL */
# define PACKET3_QUERY_STATUS_CONTEXT_ID(x) ((x) << 0)
# define PACKET3_QUERY_STATUS_INTERRUPT_SEL(x) ((x) << 28)
# define PACKET3_QUERY_STATUS_COMMAND(x) ((x) << 30)
/* CONTROL2a */
# define PACKET3_QUERY_STATUS_PASID(x) ((x) << 0)
/* CONTROL2b */
# define PACKET3_QUERY_STATUS_DOORBELL_OFFSET(x) ((x) << 2)
# define PACKET3_QUERY_STATUS_ENG_SEL(x) ((x) << 25)
#define PACKET3_RUN_LIST 0xA5
#define PACKET3_MAP_PROCESS_VM 0xA6
/* GFX11 */
#define PACKET3_SET_Q_PREEMPTION_MODE 0xF0
# define PACKET3_SET_Q_PREEMPTION_MODE_IB_VMID(x) ((x) << 0)
# define PACKET3_SET_Q_PREEMPTION_MODE_INIT_SHADOW_MEM (1 << 0)
#endif

View file

@ -2010,7 +2010,7 @@ static int gfx_v6_0_cp_gfx_start(struct amdgpu_device *adev)
r = amdgpu_ring_alloc(ring, 7 + 4);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(adev_to_drm(adev), "cp failed to lock ring (%d).\n", r);
return r;
}
amdgpu_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
@ -2031,7 +2031,7 @@ static int gfx_v6_0_cp_gfx_start(struct amdgpu_device *adev)
r = amdgpu_ring_alloc(ring, gfx_v6_0_get_csb_size(adev) + 10);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
drm_err(adev_to_drm(adev), "cp failed to lock ring (%d).\n", r);
return r;
}
@ -3002,7 +3002,7 @@ static void gfx_v6_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t xcc_id
static void gfx_v6_0_select_me_pipe_q(struct amdgpu_device *adev,
u32 me, u32 pipe, u32 q, u32 vm, u32 xcc_id)
{
DRM_INFO("Not implemented\n");
drm_info(adev_to_drm(adev), "Not implemented\n");
}
static const struct amdgpu_gfx_funcs gfx_v6_0_gfx_funcs = {
@ -3555,7 +3555,7 @@ static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev)
memset(cu_info, 0, sizeof(*cu_info));
amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
amdgpu_gfx_parse_disable_cu(adev, disable_masks, 4, 2);
mutex_lock(&adev->grbm_idx_mutex);
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {

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