mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:04:43 +01:00
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:
commit
83dc0ba275
417 changed files with 120198 additions and 6972 deletions
687
Documentation/gpu/amdgpu/amd_overview_block.svg
Normal file
687
Documentation/gpu/amdgpu/amd_overview_block.svg
Normal 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 & 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 |
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
654
Documentation/gpu/amdgpu/enforce_isolation.svg
Normal file
654
Documentation/gpu/amdgpu/enforce_isolation.svg
Normal 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 |
|
|
@ -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
|
||||
-------------------------------------------
|
||||
|
|
|
|||
413
Documentation/gpu/amdgpu/gfx_pipeline_seq.svg
Normal file
413
Documentation/gpu/amdgpu/gfx_pipeline_seq.svg
Normal 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 |
|
|
@ -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
|
||||
|
|
|
|||
707
Documentation/gpu/amdgpu/no_enforce_isolation.svg
Normal file
707
Documentation/gpu/amdgpu/no_enforce_isolation.svg
Normal 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 |
|
|
@ -1,3 +1,4 @@
|
|||
.. _amdgpu-process-isolation:
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=========================
|
||||
|
|
|
|||
95
Documentation/gpu/amdgpu/ring-buffer.rst
Normal file
95
Documentation/gpu/amdgpu/ring-buffer.rst
Normal 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. Let’s 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:
|
||||
|
||||
1633
Documentation/gpu/amdgpu/ring_buffers.svg
Normal file
1633
Documentation/gpu/amdgpu/ring_buffers.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 86 KiB |
|
|
@ -1,3 +1,5 @@
|
|||
.. _amdgpu-userq:
|
||||
|
||||
==================
|
||||
User Mode Queues
|
||||
==================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
387
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c
Normal file
387
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c
Normal 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
|
||||
};
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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, ®_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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 -
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* BAR—there 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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, ®_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++) {
|
||||
|
|
|
|||
|
|
@ -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, ®_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++) {
|
||||
|
|
|
|||
|
|
@ -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, ®_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++) {
|
||||
|
|
|
|||
4067
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
Normal file
4067
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
Normal file
File diff suppressed because it is too large
Load diff
31
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.h
Normal file
31
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.h
Normal 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
|
||||
475
drivers/gpu/drm/amd/amdgpu/gfx_v12_1_pkt.h
Normal file
475
drivers/gpu/drm/amd/amdgpu/gfx_v12_1_pkt.h
Normal 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
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue