amd-drm-next-6.13-2024-10-25:

amdgpu:
 - SDMA queue reset support
 - SMU 13.0.6 updates
 - Add debugfs interface to help limit jpeg queue scheduling for testing
 - JPEG 4.0.3 updates
 - Initial runtime repartitioning support
 - GFX9 fixes
 - Misc code cleanups
 - Rework IP structures to better handle multiple instances of an IP
 - DML updates
 - DSC fixes
 - HDR fixes
 - Brightness control updates
 - Runtime pm cleanup
 - DMCUB fixes
 - DCN 3.5 updates
 - Struct drm_edid cleanup
 - Fetch EDID from _DDC if available
 - Ring noop optimizations
 - MES logging fixes
 - 3DLUT fixes
 - DCN 4.x fixes
 - SMU 13.x fixes
 - Fixes for set_soft_freq_range()
 - ACPI fixes
 - SMU 14.x updates
 - PSR-SU fixes
 - fdinfo cleanup
 - DCN documentation updates
 
 amdkfd:
 - Misc code cleanups
 - Increase event FIFO size
 - Copy wave state fixes for SDMA
 
 radeon:
 - Fix possible overflow in packet3 check
 - Late init connector fix
 - Always set GEM function pointer
 
 Documentation:
 - Update drm-memory documentation
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZxua4QAKCRC93/aFa7yZ
 2C/TAQC3PZqI36hkKOPwdcbFq2ydK1r3xiG7Q60K0PxpTnsqKQEAuF1MEuTXfamv
 mVqZfJuqF3wWXzoqM190qf3947f0eQk=
 =MSZa
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-next-6.13-2024-10-25' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.13-2024-10-25:

amdgpu:
- SDMA queue reset support
- SMU 13.0.6 updates
- Add debugfs interface to help limit jpeg queue scheduling for testing
- JPEG 4.0.3 updates
- Initial runtime repartitioning support
- GFX9 fixes
- Misc code cleanups
- Rework IP structures to better handle multiple instances of an IP
- DML updates
- DSC fixes
- HDR fixes
- Brightness control updates
- Runtime pm cleanup
- DMCUB fixes
- DCN 3.5 updates
- Struct drm_edid cleanup
- Fetch EDID from _DDC if available
- Ring noop optimizations
- MES logging fixes
- 3DLUT fixes
- DCN 4.x fixes
- SMU 13.x fixes
- Fixes for set_soft_freq_range()
- ACPI fixes
- SMU 14.x updates
- PSR-SU fixes
- fdinfo cleanup
- DCN documentation updates

amdkfd:
- Misc code cleanups
- Increase event FIFO size
- Copy wave state fixes for SDMA

radeon:
- Fix possible overflow in packet3 check
- Late init connector fix
- Always set GEM function pointer

Documentation:
- Update drm-memory documentation

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241025132336.2416913-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2024-10-29 18:25:24 +10:00
commit e7103f8785
334 changed files with 9334 additions and 8899 deletions

View File

@ -0,0 +1,731 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1204.058"
height="510.57321"
viewBox="0 0 318.57366 135.08917"
version="1.1"
id="svg8"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="dc-arch-overview.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"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616"
style="fill:#aa00d4;fill-opacity:1;fill-rule:evenodd;stroke:#aa00d4;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Send"
orient="auto"
refY="0"
refX="0"
id="Arrow2Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8622"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8592"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8610"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-8"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-4"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-5"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-1"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-4"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1-0"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616-5"
style="fill:#00ffcc;fill-opacity:1;fill-rule:evenodd;stroke:#00ffcc;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-56"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-9"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="812.5"
inkscape:cy="315"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2083"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
showguides="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:snap-global="false"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(399.57097,11.171866)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
x="-297.75696"
y="109.44505"
id="text1063" />
<path
style="fill:#008000;stroke:#008000;stroke-width:0.463298;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.463298, 0.926596;stroke-dashoffset:0;stroke-opacity:1"
d="m -120.41395,84.001461 h -9.04766"
id="path1171-0-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.982225;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.982225, 1.96445;stroke-dashoffset:0;stroke-opacity:1"
d="m -129.96274,90.649221 h 8.66407"
id="path1171-7-1-3-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#3771c8;stroke-width:0.745037;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m -121.33167,97.283841 h -7.91265"
id="path7149-3-7-8"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
x="-115.55721"
y="85.330681"
id="text12079"><tspan
sodipodi:role="line"
id="tspan12077"
x="-115.55721"
y="85.330681"
style="font-size:4.80199px;stroke-width:0.163704">Board/Platform</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
x="-115.75885"
y="92.435066"
id="text12079-3"><tspan
sodipodi:role="line"
id="tspan12077-1"
x="-115.75885"
y="92.435066"
style="font-size:4.80199px;stroke-width:0.163704">SoC</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
x="-115.6041"
y="98.608604"
id="text12079-3-4"><tspan
sodipodi:role="line"
id="tspan12077-1-9"
x="-115.6041"
y="98.608604"
style="font-size:4.80199px;stroke-width:0.163704">Component</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-368.54205"
y="92.633011"
id="text1010-5"><tspan
sodipodi:role="line"
x="-368.54205"
y="92.633011"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan1057">DRAM</tspan></text>
<g
id="g730"
transform="translate(6.9386906,-2.5203356)">
<text
id="text838-5-2-6-2"
y="32.372173"
x="-372.97867"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan936-1-2-3"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="32.372173"
x="-372.97867"
sodipodi:role="line">dc_plane</tspan></text>
<rect
ry="6.9139691e-07"
y="18.717371"
x="-390.50565"
height="23.904575"
width="35.080177"
id="rect834-5-2-6-75"
style="fill:none;stroke:#000000;stroke-width:0.561714;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<g
id="g738"
transform="translate(6.9386906,31.346346)">
<text
id="text734"
y="32.372173"
x="-372.97867"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan732"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="32.372173"
x="-372.97867"
sodipodi:role="line">dc_plane</tspan></text>
<rect
ry="6.9139691e-07"
y="18.717371"
x="-390.50565"
height="23.904575"
width="35.080177"
id="rect736"
style="fill:none;stroke:#000000;stroke-width:0.561714;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<rect
ry="2.1256196e-06"
y="8.5983658"
x="-389.18051"
height="73.491852"
width="46.307304"
id="rect744"
style="fill:none;stroke:#3771c8;stroke-width:1.13159;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<g
id="g757"
transform="translate(-19.949528,-8.6078171)">
<text
id="text600"
y="56.289795"
x="-256.91336"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan598"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="56.289795"
x="-256.91336"
sodipodi:role="line">DC</tspan></text>
<rect
ry="1.7458606e-06"
y="23.771139"
x="-289.21854"
height="60.361938"
width="65.042557"
id="rect602"
style="fill:none;stroke:#000000;stroke-width:1.21541;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<rect
ry="2.3633565e-06"
y="4.4885707"
x="-316.43292"
height="81.711441"
width="79.57225"
id="rect787"
style="fill:none;stroke:#3771c8;stroke-width:1.5641;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<g
id="g765"
transform="translate(6.5577393,-7.020317)">
<text
id="text608"
y="31.942825"
x="-189.71797"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan606"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="31.942825"
x="-189.71797"
sodipodi:role="line">dc_link</tspan></text>
<rect
ry="6.8036792e-07"
y="18.197111"
x="-211.99069"
height="23.523254"
width="44.846642"
id="rect610"
style="fill:none;stroke:#000000;stroke-width:0.630025;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<rect
ry="1.0582555e-06"
y="4.3160448"
x="-210.69141"
height="36.588463"
width="55.543594"
id="rect794"
style="fill:none;stroke:#3771c8;stroke-width:0.874443;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<g
id="g781"
transform="translate(6.5577393,37.542802)">
<text
id="text777"
y="31.942825"
x="-189.71797"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan775"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="31.942825"
x="-189.71797"
sodipodi:role="line">dc_link</tspan></text>
<rect
ry="6.8036792e-07"
y="18.197111"
x="-211.99069"
height="23.523254"
width="44.846642"
id="rect779"
style="fill:none;stroke:#000000;stroke-width:0.630025;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<rect
ry="1.0582555e-06"
y="50.466679"
x="-210.69141"
height="36.588463"
width="55.543594"
id="rect796"
style="fill:none;stroke:#3771c8;stroke-width:0.874443;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<g
id="g2151"
transform="translate(2.1659807,-25.895798)">
<rect
ry="9.2671934e-07"
y="29.395185"
x="-132.25786"
height="32.040688"
width="44.742229"
id="rect618"
style="fill:none;stroke:#3771c8;stroke-width:0.734435;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<g
id="g838"
transform="translate(1.9073486e-6,0.26687336)">
<text
id="text616"
y="47.132744"
x="-110.03735"
style="font-style:normal;font-weight:normal;font-size:6.54814px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163704"
xml:space="preserve"><tspan
id="tspan614"
style="text-align:center;text-anchor:middle;stroke-width:0.163704"
y="47.132744"
x="-110.03735"
sodipodi:role="line">dc_link</tspan></text>
<rect
ry="5.7260945e-07"
y="35.249866"
x="-126.21788"
height="19.797579"
width="32.66227"
id="rect833"
style="fill:none;stroke:#000000;stroke-width:0.493257;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
</g>
<rect
ry="3.6076738e-06"
y="-9.4559708"
x="-397.85507"
height="124.73286"
width="250.94243"
id="rect1307"
style="fill:none;stroke:#008000;stroke-width:3.43179;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.86358, 3.43179;stroke-dashoffset:0" />
<rect
ry="2.9172609e-06"
y="-4.5401988"
x="-393.52301"
height="100.8623"
width="174.14117"
id="rect1990"
style="fill:none;stroke:#ff0000;stroke-width:2.57074;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:2.57074, 5.14148;stroke-dashoffset:0" />
<path
style="fill:none;stroke:#aa00d4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m -317.69814,47.452094 h -23.80954"
id="path2142" />
<path
style="fill:none;stroke:#aa00d4;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m -130.71642,19.101665 h -23.80954"
id="path2144" />
<g
aria-label="}"
transform="rotate(180,-59.876965,-0.22738225)"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#aa00d4;fill-opacity:1;stroke:none;stroke-width:0.264583"
id="text1003-5">
<path
d="m 92.00239,-21.748413 h 0.86816 c 0,0 15.81267,-0.177767 16.15994,-0.5333 0.35553,-0.355534 1.10026,-1.124479 1.10026,-2.306836 v -20.048953 c 0,-1.289844 0.18603,-2.228288 0.5581,-2.815332 0.37207,-0.587044 0.45004,-0.992187 1.36781,-1.215429 -0.91777,-0.206706 -0.99574,-0.603581 -1.36781,-1.190625 -0.37207,-0.587045 -0.5581,-1.529623 -0.5581,-2.827735 v -19.913761 c 0,-1.174088 -0.74473,-1.938899 -1.10026,-2.294433 -0.34727,-0.363802 -15.00239,-0.545703 -16.15994,-0.545703 h -0.86816 v -1.773536 h 0.78134 c 2.05879,0 17.33403,0.305924 18.02029,0.917774 0.69453,0.60358 1.0418,1.81901 1.0418,3.646289 v 19.814542 c 0,1.231966 0.22324,2.087728 0.66973,2.567285 0.44648,0.471289 1.25677,0.706934 2.43086,0.706934 h 0.76894 v 1.773535 h -0.76894 c -1.17409,0 -1.98438,0.239778 -2.43086,0.719336 -0.44649,0.479557 -0.66973,1.343587 -0.66973,2.59209 v 19.937331 c 0,1.827279 -0.34727,3.046842 -1.0418,3.658691 -0.68626,0.611849 -15.9615,0.917774 -18.02029,0.917774 h -0.78134 z"
style="font-size:25.4px;fill:#aa00d4;stroke-width:0.264583"
id="path1005-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccsscccsscsccscsscsccscsscscc" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-275.85803"
y="92.633011"
id="text2157"><tspan
sodipodi:role="line"
x="-275.85803"
y="92.633011"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan2155">DCN</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-279.29822"
y="110.19857"
id="text3141"><tspan
sodipodi:role="line"
x="-279.29822"
y="110.19857"
style="font-weight:bold;font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan3139">SoC</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-275.85803"
y="123.8538"
id="text3375"><tspan
sodipodi:role="line"
x="-275.85803"
y="123.8538"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan3373">Board/Platform</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-107.57491"
y="42.939579"
id="text3379"><tspan
sodipodi:role="line"
x="-107.57491"
y="42.939579"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan3377">Display</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-182.71582"
y="46.643749"
id="text3383"><tspan
sodipodi:role="line"
x="-182.71582"
y="46.643749"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan3381">Connector</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-182.71582"
y="93.210457"
id="text3387"><tspan
sodipodi:role="line"
x="-182.71582"
y="93.210457"
style="font-size:6.35px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan3385">Connector</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,732 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="533.42053"
height="631.18573"
viewBox="0 0 141.13418 167.00122"
version="1.1"
id="svg8"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="dc-components.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"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616"
style="fill:#aa00d4;fill-opacity:1;fill-rule:evenodd;stroke:#aa00d4;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Send"
orient="auto"
refY="0"
refX="0"
id="Arrow2Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8622"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8592"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8610"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-8"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-4"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-5"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-1"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-4"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1-0"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616-5"
style="fill:#00ffcc;fill-opacity:1;fill-rule:evenodd;stroke:#00ffcc;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-56"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-9"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="482.85714"
inkscape:cy="470"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2083"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
showguides="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:snap-global="false"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(384.1992,26.608359)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.0511px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.101278"
x="-330.72058"
y="57.56284"
id="text1063" />
<rect
ry="4.7572436e-07"
y="-26.142614"
x="-383.73346"
height="16.447845"
width="140.2027"
id="rect744"
style="fill:none;stroke:#3771c8;stroke-width:0.93149;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="1.0800992e-06"
y="-5.1415901"
x="-383.27942"
height="37.343693"
width="40.239418"
id="rect602"
style="fill:none;stroke:#000000;stroke-width:0.751929;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.476px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-363.2121"
y="17.270189"
id="text3379"><tspan
sodipodi:role="line"
x="-363.2121"
y="17.270189"
style="font-size:10.476px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan3377">Core</tspan></text>
<rect
ry="1.0800992e-06"
y="-5.1415901"
x="-331.06259"
height="37.343693"
width="40.239418"
id="rect526"
style="fill:none;stroke:#000000;stroke-width:0.751929;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4701343e-07"
y="-5.2654457"
x="-286.88507"
height="15.455184"
width="43.167706"
id="rect528"
style="fill:none;stroke:#000000;stroke-width:0.501024;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4701343e-07"
y="15.68337"
x="-286.88507"
height="15.455184"
width="43.167706"
id="rect530"
style="fill:none;stroke:#000000;stroke-width:0.501024;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4701343e-07"
y="36.959518"
x="-286.88507"
height="15.455184"
width="43.167706"
id="rect532"
style="fill:none;stroke:#000000;stroke-width:0.501024;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="1.6213723e-06"
y="60.089264"
x="-286.65378"
height="56.057846"
width="42.705132"
id="rect534"
style="fill:none;stroke:#000000;stroke-width:0.949072;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4031123e-07"
y="37.077362"
x="-382.96875"
height="15.223459"
width="92.225845"
id="rect536"
style="fill:none;stroke:#000000;stroke-width:0.726817;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4031123e-07"
y="59.989784"
x="-382.96875"
height="15.223459"
width="92.225845"
id="rect538"
style="fill:none;stroke:#000000;stroke-width:0.726817;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.4031123e-07"
y="80.283493"
x="-382.96875"
height="15.223459"
width="92.225845"
id="rect540"
style="fill:none;stroke:#000000;stroke-width:0.726817;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
ry="4.3543034e-07"
y="124.89404"
x="-382.88803"
height="15.054706"
width="139.2859"
id="rect554"
style="fill:none;stroke:#000000;stroke-width:0.888245;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:8.73001px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-311.29712"
y="-16.144287"
id="text660"><tspan
sodipodi:role="line"
x="-311.29712"
y="-16.144287"
style="font-size:8.73001px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan658">Display Core API (dc/dc.h)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.476px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-311.40384"
y="17.511137"
id="text664"><tspan
sodipodi:role="line"
x="-311.40384"
y="17.511137"
style="font-size:10.476px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan662">Link</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-336.97806"
y="43.095863"
id="text668"><tspan
sodipodi:role="line"
x="-336.97806"
y="43.095863"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan666">Hardware Sequencer API</tspan><tspan
sodipodi:role="line"
x="-336.97806"
y="48.552124"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan670">(dc/inc/hw_sequence.h)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-337.03479"
y="68.73642"
id="text750"><tspan
sodipodi:role="line"
x="-337.03479"
y="68.73642"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan748">Hardware Sequencer</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-336.98022"
y="89.209091"
id="text756"><tspan
sodipodi:role="line"
x="-336.98022"
y="89.209091"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan754">Block Level API (dc/inc/hw)</tspan></text>
<g
id="g1543"
transform="matrix(0.61866289,0,0,0.61866289,-146.50941,-10.146755)">
<rect
ry="7.3007396e-07"
y="180.25436"
x="-382.5336"
height="25.241808"
width="29.376135"
id="rect542"
style="fill:none;stroke:#000000;stroke-width:0.528201;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-367.99722"
y="195.3941"
id="text838"><tspan
sodipodi:role="line"
x="-367.99722"
y="195.3941"
style="font-size:7.05556px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan836">DCHUB</tspan></text>
</g>
<a
id="a1538"
transform="matrix(0.61866289,0,0,0.61866289,-154.037,-10.146755)">
<rect
ry="7.3027257e-07"
y="180.25093"
x="-339.82092"
height="25.248676"
width="28.609333"
id="rect546"
style="fill:none;stroke:#000000;stroke-width:0.521332;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-325.67853"
y="195.35883"
id="text842"><tspan
sodipodi:role="line"
x="-325.67853"
y="195.35883"
style="font-size:7.05556px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan840">HUBP</tspan></text>
</a>
<g
id="g1533"
transform="matrix(0.61866289,0,0,0.61866289,-154.69251,-10.146755)">
<rect
ry="7.3027257e-07"
y="180.25093"
x="-308.59961"
height="25.248676"
width="28.609333"
id="rect844"
style="fill:none;stroke:#000000;stroke-width:0.521332;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-294.45721"
y="195.3941"
id="text848"><tspan
sodipodi:role="line"
x="-294.45721"
y="195.3941"
style="font-size:7.05556px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan846">DPP</tspan></text>
</g>
<g
id="g1528"
transform="matrix(0.61866289,0,0,0.61866289,-155.67539,-10.146755)">
<rect
ry="7.3027257e-07"
y="180.25093"
x="-276.84912"
height="25.248676"
width="28.609333"
id="rect850"
style="fill:none;stroke:#000000;stroke-width:0.521332;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-262.77728"
y="195.3941"
id="text854"><tspan
sodipodi:role="line"
x="-262.77728"
y="195.3941"
style="font-size:7.05556px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan852">MPC</tspan></text>
</g>
<g
id="g1523"
transform="matrix(0.61866289,0,0,0.61866289,-157.64019,-10.146755)">
<rect
ry="7.3027257e-07"
y="180.25093"
x="-243.51147"
height="25.248676"
width="28.609333"
id="rect856"
style="fill:none;stroke:#000000;stroke-width:0.521332;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="-229.2068"
y="193.25275"
id="text860"><tspan
sodipodi:role="line"
x="-229.2068"
y="193.25275"
style="font-size:7.05556px;text-align:center;text-anchor:middle;stroke-width:0.264583"
id="tspan858">...</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-313.35858"
y="133.55629"
id="text951"><tspan
sodipodi:role="line"
x="-313.35858"
y="133.55629"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan949">Hardware Registers</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-265.39505"
y="86.926537"
id="text1044"><tspan
sodipodi:role="line"
x="-265.39505"
y="86.926537"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1042">DMUB</tspan><tspan
sodipodi:role="line"
x="-265.39505"
y="92.382797"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1046">Block</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-265.42343"
y="43.272846"
id="text1052"><tspan
sodipodi:role="line"
x="-265.42343"
y="43.272846"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1048">DMUB Hardware API</tspan><tspan
sodipodi:role="line"
x="-265.42343"
y="48.729107"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1050">(dmub/dmub_srv.h)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-265.40161"
y="24.997644"
id="text1058"><tspan
sodipodi:role="line"
x="-265.40161"
y="24.997644"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1056">DMUB Service</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.36501px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.163688"
x="-265.30121"
y="0.99768418"
id="text1064"><tspan
sodipodi:role="line"
x="-265.30121"
y="0.99768418"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1062">DMUB Service API</tspan><tspan
sodipodi:role="line"
x="-265.30121"
y="6.4539466"
style="font-size:4.36501px;text-align:center;text-anchor:middle;stroke-width:0.163688"
id="tspan1066">(dc/dc_dmub_srv.h)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -2,6 +2,181 @@
Display Core Debug tools
========================
In this section, you will find helpful information on debugging the amdgpu
driver from the display perspective. This page introduces debug mechanisms and
procedures to help you identify if some issues are related to display code.
Narrow down display issues
==========================
Since the display is the driver's visual component, it is common to see users
reporting issues as a display when another component causes the problem. This
section equips users to determine if a specific issue was caused by the display
component or another part of the driver.
DC dmesg important messages
---------------------------
The dmesg log is the first source of information to be checked, and amdgpu
takes advantage of this feature by logging some valuable information. When
looking for the issues associated with amdgpu, remember that each component of
the driver (e.g., smu, PSP, dm, etc.) is loaded one by one, and this
information can be found in the dmesg log. In this sense, look for the part of
the log that looks like the below log snippet::
[ 4.254295] [drm] initializing kernel modesetting (IP DISCOVERY 0x1002:0x744C 0x1002:0x0E3B 0xC8).
[ 4.254718] [drm] register mmio base: 0xFCB00000
[ 4.254918] [drm] register mmio size: 1048576
[ 4.260095] [drm] add ip block number 0 <soc21_common>
[ 4.260318] [drm] add ip block number 1 <gmc_v11_0>
[ 4.260510] [drm] add ip block number 2 <ih_v6_0>
[ 4.260696] [drm] add ip block number 3 <psp>
[ 4.260878] [drm] add ip block number 4 <smu>
[ 4.261057] [drm] add ip block number 5 <dm>
[ 4.261231] [drm] add ip block number 6 <gfx_v11_0>
[ 4.261402] [drm] add ip block number 7 <sdma_v6_0>
[ 4.261568] [drm] add ip block number 8 <vcn_v4_0>
[ 4.261729] [drm] add ip block number 9 <jpeg_v4_0>
[ 4.261887] [drm] add ip block number 10 <mes_v11_0>
From the above example, you can see the line that reports that `<dm>`,
(**Display Manager**), was loaded, which means that display can be part of the
issue. If you do not see that line, something else might have failed before
amdgpu loads the display component, indicating that we don't have a
display issue.
After you identified that the DM was loaded correctly, you can check for the
display version of the hardware in use, which can be retrieved from the dmesg
log with the command::
dmesg | grep -i 'display core'
This command shows a message that looks like this::
[ 4.655828] [drm] Display Core v3.2.285 initialized on DCN 3.2
This message has two key pieces of information:
* **The DC version (e.g., v3.2.285)**: Display developers release a new DC version
every week, and this information can be advantageous in a situation where a
user/developer must find a good point versus a bad point based on a tested
version of the display code. Remember from page :ref:`Display Core <amdgpu-display-core>`,
that every week the new patches for display are heavily tested with IGT and
manual tests.
* **The DCN version (e.g., DCN 3.2)**: The DCN block is associated with the
hardware generation, and the DCN version conveys the hardware generation that
the driver is currently running. This information helps to narrow down the
code debug area since each DCN version has its files in the DC folder per DCN
component (from the example, the developer might want to focus on
files/folders/functions/structs with the dcn32 label might be executed).
However, keep in mind that DC reuses code across different DCN versions; for
example, it is expected to have some callbacks set in one DCN that are the same
as those from another DCN. In summary, use the DCN version just as a guide.
From the dmesg file, it is also possible to get the ATOM bios code by using::
dmesg | grep -i 'ATOM BIOS'
Which generates an output that looks like this::
[ 4.274534] amdgpu: ATOM BIOS: 113-D7020100-102
This type of information is useful to be reported.
Avoid loading display core
--------------------------
Sometimes, it might be hard to figure out which part of the driver is causing
the issue; if you suspect that the display is not part of the problem and your
bug scenario is simple (e.g., some desktop configuration) you can try to remove
the display component from the equation. First, you need to identify `dm` ID
from the dmesg log; for example, search for the following log::
[ 4.254295] [drm] initializing kernel modesetting (IP DISCOVERY 0x1002:0x744C 0x1002:0x0E3B 0xC8).
[..]
[ 4.260095] [drm] add ip block number 0 <soc21_common>
[ 4.260318] [drm] add ip block number 1 <gmc_v11_0>
[..]
[ 4.261057] [drm] add ip block number 5 <dm>
Notice from the above example that the `dm` id is 5 for this specific hardware.
Next, you need to run the following binary operation to identify the IP block
mask::
0xffffffff & ~(1 << [DM ID])
From our example the IP mask is::
0xffffffff & ~(1 << 5) = 0xffffffdf
Finally, to disable DC, you just need to set the below parameter in your
bootloader::
amdgpu.ip_block_mask = 0xffffffdf
If you can boot your system with the DC disabled and still see the issue, it
means you can rule DC out of the equation. However, if the bug disappears, you
still need to consider the DC part of the problem and keep narrowing down the
issue. In some scenarios, disabling DC is impossible since it might be
necessary to use the display component to reproduce the issue (e.g., play a
game).
**Note: This will probably lead to the absence of a display output.**
Display flickering
------------------
Display flickering might have multiple causes; one is the lack of proper power
to the GPU or problems in the DPM switches. A good first generic verification
is to set the GPU to use high voltage::
bash -c "echo high > /sys/class/drm/card0/device/power_dpm_force_performance_level"
The above command sets the GPU/APU to use the maximum power allowed which
disables DPM switches. If forcing DPM levels high does not fix the issue, it
is less likely that the issue is related to power management. If the issue
disappears, there is a good chance that other components might be involved, and
the display should not be ignored since this could be a DPM issues. From the
display side, if the power increase fixes the issue, it is worth debugging the
clock configuration and the pipe split police used in the specific
configuration.
Display artifacts
-----------------
Users may see some screen artifacts that can be categorized into two different
types: localized artifacts and general artifacts. The localized artifacts
happen in some specific areas, such as around the UI window corners; if you see
this type of issue, there is a considerable chance that you have a userspace
problem, likely Mesa or similar. The general artifacts usually happen on the
entire screen. They might be caused by a misconfiguration at the driver level
of the display parameters, but the userspace might also cause this issue. One
way to identify the source of the problem is to take a screenshot or make a
desktop video capture when the problem happens; after checking the
screenshot/video recording, if you don't see any of the artifacts, it means
that the issue is likely on the the driver side. If you can still see the
problem in the data collected, it is an issue that probably happened during
rendering, and the display code just got the framebuffer already corrupted.
Disabling/Enabling specific features
====================================
DC has a struct named `dc_debug_options`, which is statically initialized by
all DCE/DCN components based on the specific hardware characteristic. This
structure usually facilitates the bring-up phase since developers can start
with many disabled features and enable them individually. This is also an
important debug feature since users can change it when debugging specific
issues.
For example, dGPU users sometimes see a problem where a horizontal fillet of
flickering happens in some specific part of the screen. This could be an
indication of Sub-Viewport issues; after the users identified the target DCN,
they can set the `force_disable_subvp` field to true in the statically
initialized version of `dc_debug_options` to see if the issue gets fixed. Along
the same lines, users/developers can also try to turn off `fams2_config` and
`enable_single_display_2to1_odm_policy`. In summary, the `dc_debug_options` is
an interesting form for identifying the problem.
DC Visual Confirmation
======================
@ -76,6 +251,18 @@ change in real-time by using something like::
When reporting a bug related to DC, consider attaching this log before and
after you reproduce the bug.
Collect Firmware information
============================
When reporting issues, it is important to have the firmware information since
it can be helpful for debugging purposes. To get all the firmware information,
use the command::
cat /sys/kernel/debug/dri/0/amdgpu_firmware_info
From the display perspective, pay attention to the firmware of the DMCU and
DMCUB.
DMUB Firmware Debug
===================

View File

@ -1,3 +1,5 @@
.. _dcn_blocks:
==========
DCN Blocks
==========

View File

@ -1,3 +1,5 @@
.. _dcn_overview:
=======================
Display Core Next (DCN)
=======================

View File

@ -90,6 +90,7 @@ table of content:
display-manager.rst
dcn-overview.rst
dcn-blocks.rst
programming-model-dcn.rst
mpo-overview.rst
dc-debug.rst
display-contributing.rst

View File

@ -0,0 +1,162 @@
====================
DC Programming Model
====================
In the :ref:`Display Core Next (DCN) <dcn_overview>` and :ref:`DCN Block
<dcn_blocks>` pages, you learned about the hardware components and how they
interact with each other. On this page, the focus is shifted to the display
code architecture. Hence, it is reasonable to remind the reader that the code
in DC is shared with other OSes; for this reason, DC provides a set of
abstractions and operations to connect different APIs with the hardware
configuration. See DC as a service available for a Display Manager (amdgpu_dm)
to access and configure DCN/DCE hardware (DCE is also part of DC, but for
simplicity's sake, this documentation only examines DCN).
.. note::
For this page, we will use the term GPU to refers to dGPU and APU.
Overview
========
From the display hardware perspective, it is plausible to expect that if a
problem is well-defined, it will probably be implemented at the hardware level.
On the other hand, when there are multiple ways of achieving something without
a very well-defined scope, the solution is usually implemented as a policy at
the DC level. In other words, some policies are defined in the DC core
(resource management, power optimization, image quality, etc.), and the others
implemented in hardware are enabled via DC configuration.
In terms of hardware management, DCN has multiple instances of the same block
(e.g., HUBP, DPP, MPC, etc), and during the driver execution, it might be
necessary to use some of these instances. The core has policies in place for
handling those instances. Regarding resource management, the DC objective is
quite simple: minimize the hardware shuffle when the driver performs some
actions. When the state changes from A to B, the transition is considered
easier to maneuver if the hardware resource is still used for the same set of
driver objects. Usually, adding and removing a resource to a `pipe_ctx` (more
details below) is not a problem; however, moving a resource from one `pipe_ctx`
to another should be avoided.
Another area of influence for DC is power optimization, which has a myriad of
arrangement possibilities. In some way, just displaying an image via DCN should
be relatively straightforward; however, showing it with the best power
footprint is more desirable, but it has many associated challenges.
Unfortunately, there is no straight-forward analytic way to determine if a
configuration is the best one for the context due to the enormous variety of
variables related to this problem (e.g., many different DCN/DCE hardware
versions, different displays configurations, etc.) for this reason DC
implements a dedicated library for trying some configuration and verify if it
is possible to support it or not. This type of policy is extremely complex to
create and maintain, and amdgpu driver relies on Display Mode Library (DML) to
generate the best decisions.
In summary, DC must deal with the complexity of handling multiple scenarios and
determine policies to manage them. All of the above information is conveyed to
give the reader some idea about the complexity of driving a display from the
driver's perspective. This page hopes to allow the reader to better navigate
over the amdgpu display code.
Display Driver Architecture Overview
====================================
The diagram below provides an overview of the display driver architecture;
notice it illustrates the software layers adopted by DC:
.. kernel-figure:: dc-components.svg
The first layer of the diagram is the high-level DC API represented by the
`dc.h` file; below it are two big blocks represented by Core and Link. Next is
the hardware configuration block; the main file describing it is
the`hw_sequencer.h`, where the implementation of the callbacks can be found in
the hardware sequencer folder. Almost at the end, you can see the block level
API (`dc/inc/hw`), which represents each DCN low-level block, such as HUBP,
DPP, MPC, OPTC, etc. Notice on the left side of the diagram that we have a
different set of layers representing the interaction with the DMUB
microcontroller.
Basic Objects
-------------
The below diagram outlines the basic display objects. In particular, pay
attention to the names in the boxes since they represent a data structure in
the driver:
.. kernel-figure:: dc-arch-overview.svg
Let's start with the central block in the image, `dc`. The `dc` struct is
initialized per GPU; for example, one GPU has one `dc` instance, two GPUs have
two `dc` instances, and so forth. In other words we have one 'dc' per 'amdgpu'
instance. In some ways, this object behaves like the `Singleton` pattern.
After the `dc` block in the diagram, you can see the `dc_link` component, which
is a low-level abstraction for the connector. One interesting aspect of the
image is that connectors are not part of the DCN block; they are defined by the
platform/board and not by the SoC. The `dc_link` struct is the high-level data
container with information such as connected sinks, connection status, signal
types, etc. After `dc_link`, there is the `dc_sink`, which is the object that
represents the connected display.
.. note::
For historical reasons, we used the name `dc_link`, which gives the
wrong impression that this abstraction only deals with physical connections
that the developer can easily manipulate. However, this also covers
conections like eDP or cases where the output is connected to other devices.
There are two structs that are not represented in the diagram since they were
elaborated in the DCN overview page (check the DCN block diagram :ref:`Display
Core Next (DCN) <dcn_overview>`); still, it is worth bringing back for this
overview which is `dc_stream` and `dc_state`. The `dc_stream` stores many
properties associated with the data transmission, but most importantly, it
represents the data flow from the connector to the display. Next we have
`dc_state`, which represents the logic state within the hardware at the moment;
`dc_state` is composed of `dc_stream` and `dc_plane`. The `dc_stream` is the DC
version of `drm_crtc` and represents the post-blending pipeline.
Speaking of the `dc_plane` data structure (first part of the diagram), you can
think about it as an abstraction similar to `drm_plane` that represents the
pre-blending portion of the pipeline. This image was probably processed by GFX
and is ready to be composited under a `dc_stream`. Normally, the driver may
have one or more `dc_plane` connected to the same `dc_stream`, which defines a
composition at the DC level.
Basic Operations
----------------
Now that we have covered the basic objects, it is time to examine some of the
basic hardware/software operations. Let's start with the `dc_create()`
function, which directly works with the `dc` data struct; this function behaves
like a constructor responsible for the basic software initialization and
preparing for enabling other parts of the API. It is important to highlight
that this operation does not touch any hardware configuration; it is only a
software initialization.
Next, we have the `dc_hardware_init()`, which also relies on the `dc` data
struct. Its main function is to put the hardware in a valid state. It is worth
highlighting that the hardware might initialize in an unknown state, and it is
a requirement to put it in a valid state; this function has multiple callbacks
for the hardware-specific initialization, whereas `dc_hardware_init` does the
hardware initialization and is the first point where we touch hardware.
The `dc_get_link_at_index` is an operation that depends on the `dc_link` data
structure. This function retrieves and enumerates all the `dc_links` available
on the device; this is required since this information is not part of the SoC
definition but depends on the board configuration. As soon as the `dc_link` is
initialized, it is useful to figure out if any of them are already connected to
the display by using the `dc_link_detect()` function. After the driver figures
out if any display is connected to the device, the challenging phase starts:
configuring the monitor to show something. Nonetheless, dealing with the ideal
configuration is not a DC task since this is the Display Manager (`amdgpu_dm`)
responsibility which in turn is responsible for dealing with the atomic
commits. The only interface DC provides to the configuration phase is the
function `dc_validate_with_context` that receives the configuration information
and, based on that, validates whether the hardware can support it or not. It is
important to add that even if the display supports some specific configuration,
it does not mean the DCN hardware can support it.
After the DM and DC agree upon the configuration, the stream configuration
phase starts. This task activates one or more `dc_stream` at this phase, and in
the best-case scenario, you might be able to turn the display on with a black
screen (it does not show anything yet since it does not have any plane
associated with it). The final step would be to call the
`dc_update_planes_and_stream,` which will add or remove planes.

View File

@ -149,7 +149,9 @@ Memory
Each possible memory type which can be used to store buffer objects by the
GPU in question shall be given a stable and unique name to be returned as the
string here. The name "memory" is reserved to refer to normal system memory.
string here.
The region name "memory" is reserved to refer to normal system memory.
Value shall reflect the amount of storage currently consumed by the buffer
objects belong to this client, in the respective memory region.
@ -157,6 +159,9 @@ objects belong to this client, in the respective memory region.
Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
indicating kibi- or mebi-bytes.
This key is deprecated and is an alias for drm-resident-<region>. Only one of
the two should be present in the output.
- drm-shared-<region>: <uint> [KiB|MiB]
The total size of buffers that are shared with another file (e.g., have more
@ -164,20 +169,34 @@ than a single handle).
- drm-total-<region>: <uint> [KiB|MiB]
The total size of buffers that including shared and private memory.
The total size of all created buffers including shared and private memory. The
backing store for the buffers does not have to be currently instantiated to be
counted under this category.
- drm-resident-<region>: <uint> [KiB|MiB]
The total size of buffers that are resident in the specified region.
The total size of buffers that are resident (have their backing store present or
instantiated) in the specified region.
This is an alias for drm-memory-<region> and only one of the two should be
present in the output.
- drm-purgeable-<region>: <uint> [KiB|MiB]
The total size of buffers that are purgeable.
For example drivers which implement a form of 'madvise' like functionality can
here count buffers which have instantiated backing store, but have been marked
with an equivalent of MADV_DONTNEED.
- drm-active-<region>: <uint> [KiB|MiB]
The total size of buffers that are active on one or more engines.
One practical example of this can be presence of unsignaled fences in an GEM
buffer reservation object. Therefore the active category is a subset of
resident.
Implementation Details
======================

View File

@ -85,16 +85,9 @@ static int aldebaran_mode2_suspend_ip(struct amdgpu_device *adev)
AMD_IP_BLOCK_TYPE_SDMA))
continue;
r = adev->ip_blocks[i].version->funcs->suspend(adev);
if (r) {
dev_err(adev->dev,
"suspend of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
if (r)
return r;
}
adev->ip_blocks[i].status.hw = false;
}
return 0;
@ -246,7 +239,7 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
dev_err(adev->dev, "Failed to get BIF handle\n");
return -EINVAL;
}
r = cmn_block->version->funcs->resume(adev);
r = amdgpu_ip_block_resume(cmn_block);
if (r)
return r;
@ -282,15 +275,10 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_SDMA))
continue;
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
dev_err(adev->dev,
"resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
adev->ip_blocks[i].status.hw = true;
r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
if (r)
return r;
}
for (i = 0; i < adev->num_ip_blocks; i++) {
@ -304,7 +292,7 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
if (adev->ip_blocks[i].version->funcs->late_init) {
r = adev->ip_blocks[i].version->funcs->late_init(
(void *)adev);
&adev->ip_blocks[i]);
if (r) {
dev_err(adev->dev,
"late_init of IP block <%s> failed %d after reset\n",
@ -417,6 +405,7 @@ static struct amdgpu_reset_handler aldebaran_mode2_handler = {
static struct amdgpu_reset_handler
*aldebaran_rst_handlers[AMDGPU_RESET_MAX_HANDLERS] = {
&aldebaran_mode2_handler,
&xgmi_reset_on_init_handler,
};
int aldebaran_reset_init(struct amdgpu_device *adev)

View File

@ -131,10 +131,6 @@ struct amdgpu_mgpu_info {
uint32_t num_gpu;
uint32_t num_dgpu;
uint32_t num_apu;
/* delayed reset_func for XGMI configuration if necessary */
struct delayed_work delayed_reset_work;
bool pending_reset;
};
enum amdgpu_ss {
@ -365,8 +361,11 @@ 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_idle(struct amdgpu_device *adev,
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 16
@ -389,6 +388,7 @@ struct amdgpu_ip_block_version {
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,
@ -563,6 +563,7 @@ enum amd_reset_method {
AMD_RESET_METHOD_MODE2,
AMD_RESET_METHOD_BACO,
AMD_RESET_METHOD_PCI,
AMD_RESET_METHOD_ON_INIT,
};
struct amdgpu_video_codec_info {
@ -821,6 +822,24 @@ struct amdgpu_mqd {
struct amdgpu_mqd_prop *p);
};
/*
* Custom Init levels could be defined for different situations where a full
* initialization of all hardware blocks are not expected. Sample cases are
* custom init sequences after resume after S0i3/S3, reset on initialization,
* partial reset of blocks etc. Presently, this defines only two levels. Levels
* are described in corresponding struct definitions - amdgpu_init_default,
* amdgpu_init_minimal_xgmi.
*/
enum amdgpu_init_lvl_id {
AMDGPU_INIT_LEVEL_DEFAULT,
AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
};
struct amdgpu_init_level {
enum amdgpu_init_lvl_id level;
uint32_t hwini_ip_block_mask;
};
#define AMDGPU_RESET_MAGIC_NUM 64
#define AMDGPU_MAX_DF_PERFMONS 4
struct amdgpu_reset_domain;
@ -1166,6 +1185,8 @@ struct amdgpu_device {
bool enforce_isolation[MAX_XCP];
/* Added this mutex for cleaner shader isolation between GFX and compute processes */
struct mutex enforce_isolation_mutex;
struct amdgpu_init_level *init_lvl;
};
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
@ -1261,6 +1282,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
struct amdgpu_reset_context *reset_context);
int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context);
int emu_soc_asic_init(struct amdgpu_device *adev);
/*
@ -1450,23 +1473,15 @@ void amdgpu_register_atpx_handler(void);
void amdgpu_unregister_atpx_handler(void);
bool amdgpu_has_atpx_dgpu_power_cntl(void);
bool amdgpu_is_atpx_hybrid(void);
bool amdgpu_atpx_dgpu_req_power_for_displays(void);
bool amdgpu_has_atpx(void);
#else
static inline void amdgpu_register_atpx_handler(void) {}
static inline void amdgpu_unregister_atpx_handler(void) {}
static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; }
static inline bool amdgpu_is_atpx_hybrid(void) { return false; }
static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false; }
static inline bool amdgpu_has_atpx(void) { return false; }
#endif
#if defined(CONFIG_VGA_SWITCHEROO) && defined(CONFIG_ACPI)
void *amdgpu_atpx_get_dhandle(void);
#else
static inline void *amdgpu_atpx_get_dhandle(void) { return NULL; }
#endif
/*
* KMS
*/
@ -1619,4 +1634,6 @@ extern const struct attribute_group amdgpu_vram_mgr_attr_group;
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
extern const struct attribute_group amdgpu_flash_attr_group;
void amdgpu_set_init_level(struct amdgpu_device *adev,
enum amdgpu_init_lvl_id lvl);
#endif

View File

@ -98,9 +98,9 @@ enum {
ACP_TILE_DSP2,
};
static int acp_sw_init(void *handle)
static int acp_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->acp.parent = adev->dev;
@ -112,9 +112,9 @@ static int acp_sw_init(void *handle)
return 0;
}
static int acp_sw_fini(void *handle)
static int acp_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (adev->acp.cgs_device)
amdgpu_cgs_destroy_device(adev->acp.cgs_device);
@ -219,10 +219,10 @@ static const struct dmi_system_id acp_quirk_table[] = {
/**
* acp_hw_init - start and test ACP block
*
* @handle: handle used to pass amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int acp_hw_init(void *handle)
static int acp_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
u64 acp_base;
@ -230,13 +230,7 @@ static int acp_hw_init(void *handle)
u32 count = 0;
struct i2s_platform_data *i2s_pdata = NULL;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
const struct amdgpu_ip_block *ip_block =
amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP);
if (!ip_block)
return -EINVAL;
struct amdgpu_device *adev = ip_block->adev;
r = amd_acp_hw_init(adev->acp.cgs_device,
ip_block->version->major, ip_block->version->minor);
@ -503,14 +497,14 @@ static int acp_hw_init(void *handle)
/**
* acp_hw_fini - stop the hardware block
*
* @handle: handle used to pass amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int acp_hw_fini(void *handle)
static int acp_hw_fini(struct amdgpu_ip_block *ip_block)
{
u32 val = 0;
u32 count = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* return early if no ACP */
if (!adev->acp.acp_genpd) {
@ -565,9 +559,9 @@ static int acp_hw_fini(void *handle)
return 0;
}
static int acp_suspend(void *handle)
static int acp_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* power up on suspend */
if (!adev->acp.acp_cell)
@ -575,9 +569,9 @@ static int acp_suspend(void *handle)
return 0;
}
static int acp_resume(void *handle)
static int acp_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* power down again on resume */
if (!adev->acp.acp_cell)
@ -585,26 +579,11 @@ static int acp_resume(void *handle)
return 0;
}
static int acp_early_init(void *handle)
{
return 0;
}
static bool acp_is_idle(void *handle)
{
return true;
}
static int acp_wait_for_idle(void *handle)
{
return 0;
}
static int acp_soft_reset(void *handle)
{
return 0;
}
static int acp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -624,8 +603,6 @@ static int acp_set_powergating_state(void *handle,
static const struct amd_ip_funcs acp_ip_funcs = {
.name = "acp_ip",
.early_init = acp_early_init,
.late_init = NULL,
.sw_init = acp_sw_init,
.sw_fini = acp_sw_fini,
.hw_init = acp_hw_init,
@ -633,12 +610,8 @@ static const struct amd_ip_funcs acp_ip_funcs = {
.suspend = acp_suspend,
.resume = acp_resume,
.is_idle = acp_is_idle,
.wait_for_idle = acp_wait_for_idle,
.soft_reset = acp_soft_reset,
.set_clockgating_state = acp_set_clockgating_state,
.set_powergating_state = acp_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
const struct amdgpu_ip_block_version acp_ip_block = {

View File

@ -147,6 +147,7 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
struct acpi_buffer *params)
{
acpi_status status;
union acpi_object *obj;
union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@ -169,16 +170,24 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
&buffer);
obj = (union acpi_object *)buffer.pointer;
/* Fail only if calling the method fails and ATIF is supported */
/* Fail if calling the method fails and ATIF is supported */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status));
kfree(buffer.pointer);
kfree(obj);
return NULL;
}
return buffer.pointer;
if (obj->type != ACPI_TYPE_BUFFER) {
DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
obj->type);
kfree(obj);
return NULL;
}
return obj;
}
/**
@ -791,6 +800,7 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
return -EIO;
}
kfree(info);
return 0;
}

View File

@ -889,3 +889,18 @@ int amdgpu_amdkfd_start_sched(struct amdgpu_device *adev, uint32_t node_id)
return kgd2kfd_start_sched(adev->kfd.dev, node_id);
}
/* Config CGTT_SQ_CLK_CTRL */
int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device *adev, uint32_t xcp_id,
bool core_override_enable, bool reg_override_enable, bool perfmon_override_enable)
{
int r;
if (!adev->kfd.init_complete)
return 0;
r = psp_config_sq_perfmon(&adev->psp, xcp_id, core_override_enable,
reg_override_enable, perfmon_override_enable);
return r;
}

View File

@ -266,6 +266,9 @@ int amdgpu_amdkfd_unmap_hiq(struct amdgpu_device *adev, u32 doorbell_off,
u32 inst);
int amdgpu_amdkfd_start_sched(struct amdgpu_device *adev, uint32_t node_id);
int amdgpu_amdkfd_stop_sched(struct amdgpu_device *adev, uint32_t node_id);
int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device *adev, uint32_t xcp_id,
bool core_override_enable, bool reg_override_enable, bool perfmon_override_enable);
/* Read user wptr from a specified user address space with page fault
* disabled. The memory must be pinned and mapped to the hardware when

View File

@ -944,9 +944,7 @@ static void unlock_spi_csq_mutexes(struct amdgpu_device *adev)
*
* @adev: Handle of device whose registers are to be read
* @queue_idx: Index of queue in the queue-map bit-field
* @wave_cnt: Output parameter updated with number of waves in flight
* @vmid: Output parameter updated with VMID of queue whose wave count
* is being collected
* @queue_cnt: Stores the wave count and doorbell offset for an active queue
* @inst: xcc's instance number on a multi-XCC setup
*/
static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
@ -1133,10 +1131,6 @@ uint64_t kgd_gfx_v9_hqd_get_pq_addr(struct amdgpu_device *adev,
uint32_t low, high;
uint64_t queue_addr = 0;
if (!adev->debug_exp_resets &&
!adev->gfx.num_gfx_rings)
return 0;
kgd_gfx_v9_acquire_queue(adev, pipe_id, queue_id, inst);
amdgpu_gfx_rlc_enter_safe_mode(adev, inst);

View File

@ -1439,8 +1439,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
list_add_tail(&vm->vm_list_node,
&(vm->process_info->vm_list_head));
vm->process_info->n_vms++;
*ef = dma_fence_get(&vm->process_info->eviction_fence->base);
if (ef)
*ef = dma_fence_get(&vm->process_info->eviction_fence->base);
mutex_unlock(&vm->process_info->lock);
return 0;
@ -2524,11 +2524,14 @@ int amdgpu_amdkfd_evict_userptr(struct mmu_interval_notifier *mni,
/* First eviction, stop the queues */
r = kgd2kfd_quiesce_mm(mni->mm,
KFD_QUEUE_EVICTION_TRIGGER_USERPTR);
if (r)
if (r && r != -ESRCH)
pr_err("Failed to quiesce KFD\n");
queue_delayed_work(system_freezable_wq,
&process_info->restore_userptr_work,
msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));
if (r != -ESRCH)
queue_delayed_work(system_freezable_wq,
&process_info->restore_userptr_work,
msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));
}
mutex_unlock(&process_info->notifier_lock);

View File

@ -1145,8 +1145,8 @@ int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
return 0;
}
void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
u32 eng_clock, u32 mem_clock)
int amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
u32 eng_clock, u32 mem_clock)
{
SET_ENGINE_CLOCK_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
@ -1161,8 +1161,8 @@ void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
if (mem_clock)
args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args,
sizeof(args));
return amdgpu_atom_execute_table(adev->mode_info.atom_context, index,
(uint32_t *)&args, sizeof(args));
}
void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,

View File

@ -163,8 +163,8 @@ int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
bool strobe_mode,
struct atom_mpll_param *mpll_param);
void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
u32 eng_clock, u32 mem_clock);
int amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
u32 eng_clock, u32 mem_clock);
bool
amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,

View File

@ -89,18 +89,6 @@ bool amdgpu_is_atpx_hybrid(void)
return amdgpu_atpx_priv.atpx.is_hybrid;
}
bool amdgpu_atpx_dgpu_req_power_for_displays(void)
{
return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays;
}
#if defined(CONFIG_ACPI)
void *amdgpu_atpx_get_dhandle(void)
{
return amdgpu_atpx_priv.dhandle;
}
#endif
/**
* amdgpu_atpx_call - call an ATPX method
*

View File

@ -265,7 +265,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
/* Only a single BO list is allowed to simplify handling. */
if (p->bo_list)
ret = -EINVAL;
goto free_partial_kdata;
ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata);
if (ret)

View File

@ -2095,6 +2095,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
if (amdgpu_umsch_mm & amdgpu_umsch_mm_fwlog)
amdgpu_debugfs_umsch_fwlog_init(adev, &adev->umsch_mm);
amdgpu_debugfs_jpeg_sched_mask_init(adev);
amdgpu_ras_debugfs_create_all(adev);
amdgpu_rap_debugfs_init(adev);
amdgpu_securedisplay_debugfs_init(adev);

View File

@ -203,6 +203,7 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
struct amdgpu_coredump_info *coredump = data;
struct drm_print_iterator iter;
struct amdgpu_vm_fault_info *fault_info;
struct amdgpu_ip_block *ip_block;
int ver;
iter.data = buffer;
@ -282,13 +283,10 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
/* dump the ip state for each ip */
drm_printf(&p, "IP Dump\n");
for (int i = 0; i < coredump->adev->num_ip_blocks; i++) {
if (coredump->adev->ip_blocks[i].version->funcs->print_ip_state) {
drm_printf(&p, "IP: %s\n",
coredump->adev->ip_blocks[i]
.version->funcs->name);
coredump->adev->ip_blocks[i]
.version->funcs->print_ip_state(
(void *)coredump->adev, &p);
ip_block = &coredump->adev->ip_blocks[i];
if (ip_block->version->funcs->print_ip_state) {
drm_printf(&p, "IP: %s\n", ip_block->version->funcs->name);
ip_block->version->funcs->print_ip_state(ip_block, &p);
drm_printf(&p, "\n");
}
}

View File

@ -145,6 +145,51 @@ const char *amdgpu_asic_name[] = {
"LAST",
};
#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)
/*
* Default init level where all blocks are expected to be initialized. This is
* the level of initialization expected by default and also after a full reset
* of the device.
*/
struct amdgpu_init_level amdgpu_init_default = {
.level = AMDGPU_INIT_LEVEL_DEFAULT,
.hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL,
};
/*
* Minimal blocks needed to be initialized before a XGMI hive can be reset. This
* is used for cases like reset on initialization where the entire hive needs to
* be reset before first use.
*/
struct amdgpu_init_level amdgpu_init_minimal_xgmi = {
.level = AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
.hwini_ip_block_mask =
BIT(AMD_IP_BLOCK_TYPE_GMC) | BIT(AMD_IP_BLOCK_TYPE_SMC) |
BIT(AMD_IP_BLOCK_TYPE_COMMON) | BIT(AMD_IP_BLOCK_TYPE_IH) |
BIT(AMD_IP_BLOCK_TYPE_PSP)
};
static inline bool amdgpu_ip_member_of_hwini(struct amdgpu_device *adev,
enum amd_ip_block_type block)
{
return (adev->init_lvl->hwini_ip_block_mask & (1U << block)) != 0;
}
void amdgpu_set_init_level(struct amdgpu_device *adev,
enum amdgpu_init_lvl_id lvl)
{
switch (lvl) {
case AMDGPU_INIT_LEVEL_MINIMAL_XGMI:
adev->init_lvl = &amdgpu_init_minimal_xgmi;
break;
case AMDGPU_INIT_LEVEL_DEFAULT:
fallthrough;
default:
adev->init_lvl = &amdgpu_init_default;
break;
}
}
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
/**
@ -228,6 +273,42 @@ 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
*
@ -1656,7 +1737,7 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)
}
/* Don't post if we need to reset whole hive on init */
if (adev->gmc.xgmi.pending_reset)
if (adev->init_lvl->level == AMDGPU_INIT_LEVEL_MINIMAL_XGMI)
return false;
if (adev->has_hw_reset) {
@ -2160,9 +2241,12 @@ int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type == block_type) {
r = adev->ip_blocks[i].version->funcs->wait_for_idle((void *)adev);
if (r)
return r;
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;
}
}
@ -2171,26 +2255,24 @@ int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
}
/**
* amdgpu_device_ip_is_idle - is the hardware IP idle
* amdgpu_device_ip_is_valid - 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 idle or not.
* Returns true if it the IP is idle, false if not.
* 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_idle(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 i;
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)
return adev->ip_blocks[i].version->funcs->is_idle((void *)adev);
return adev->ip_blocks[i].status.valid;
}
return true;
return false;
}
@ -2272,6 +2354,8 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
DRM_INFO("add ip block number %d <%s>\n", adev->num_ip_blocks,
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;
@ -2567,25 +2651,25 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
total = true;
for (i = 0; i < adev->num_ip_blocks; i++) {
ip_block = &adev->ip_blocks[i];
if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
DRM_WARN("disabled ip block: %d <%s>\n",
i, adev->ip_blocks[i].version->funcs->name);
adev->ip_blocks[i].status.valid = false;
} else {
if (adev->ip_blocks[i].version->funcs->early_init) {
r = adev->ip_blocks[i].version->funcs->early_init((void *)adev);
if (r == -ENOENT) {
adev->ip_blocks[i].status.valid = false;
} else if (r) {
DRM_ERROR("early_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
total = false;
} else {
adev->ip_blocks[i].status.valid = true;
}
} else if (ip_block->version->funcs->early_init) {
r = ip_block->version->funcs->early_init(ip_block);
if (r == -ENOENT) {
adev->ip_blocks[i].status.valid = false;
} else if (r) {
DRM_ERROR("early_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
total = false;
} else {
adev->ip_blocks[i].status.valid = true;
}
} else {
adev->ip_blocks[i].status.valid = true;
}
/* get the vbios after the asic_funcs are set up */
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
@ -2634,10 +2718,13 @@ static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].status.hw)
continue;
if (!amdgpu_ip_member_of_hwini(
adev, adev->ip_blocks[i].version->type))
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
(amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
@ -2659,7 +2746,10 @@ static int amdgpu_device_ip_hw_init_phase2(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].status.hw)
continue;
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
if (!amdgpu_ip_member_of_hwini(
adev, adev->ip_blocks[i].version->type))
continue;
r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
@ -2682,6 +2772,10 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
continue;
if (!amdgpu_ip_member_of_hwini(adev,
AMD_IP_BLOCK_TYPE_PSP))
break;
if (!adev->ip_blocks[i].status.sw)
continue;
@ -2690,22 +2784,18 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
break;
if (amdgpu_in_reset(adev) || adev->in_suspend) {
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
DRM_ERROR("resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
if (r)
return r;
}
} else {
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
adev->ip_blocks[i].status.hw = true;
}
adev->ip_blocks[i].status.hw = true;
break;
}
}
@ -2787,6 +2877,7 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
*/
static int amdgpu_device_ip_init(struct amdgpu_device *adev)
{
bool init_badpage;
int i, r;
r = amdgpu_ras_init(adev);
@ -2796,17 +2887,23 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
r = adev->ip_blocks[i].version->funcs->sw_init((void *)adev);
if (r) {
DRM_ERROR("sw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
goto init_failed;
if (adev->ip_blocks[i].version->funcs->sw_init) {
r = adev->ip_blocks[i].version->funcs->sw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("sw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
goto init_failed;
}
}
adev->ip_blocks[i].status.sw = true;
if (!amdgpu_ip_member_of_hwini(
adev, adev->ip_blocks[i].version->type))
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
/* need to do common hw init early so everything is set up for gmc */
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init %d failed %d\n", i, r);
goto init_failed;
@ -2823,7 +2920,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
DRM_ERROR("amdgpu_mem_scratch_init failed %d\n", r);
goto init_failed;
}
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init %d failed %d\n", i, r);
goto init_failed;
@ -2896,7 +2993,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
* Note: theoretically, this should be called before all vram allocations
* to protect retired page from abusing
*/
r = amdgpu_ras_recovery_init(adev);
init_badpage = (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI);
r = amdgpu_ras_recovery_init(adev, init_badpage);
if (r)
goto init_failed;
@ -2936,7 +3034,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
amdgpu_ttm_set_buffer_funcs_status(adev, true);
/* Don't init kfd if whole hive need to be reset during init */
if (!adev->gmc.xgmi.pending_reset) {
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
kgd2kfd_init_zone_device(adev);
amdgpu_amdkfd_device_init(adev);
}
@ -3136,7 +3234,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.hw)
continue;
if (adev->ip_blocks[i].version->funcs->late_init) {
r = adev->ip_blocks[i].version->funcs->late_init((void *)adev);
r = adev->ip_blocks[i].version->funcs->late_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("late_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
@ -3207,6 +3305,25 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
return 0;
}
static void amdgpu_ip_block_hw_fini(struct amdgpu_ip_block *ip_block)
{
int r;
if (!ip_block->version->funcs->hw_fini) {
DRM_ERROR("hw_fini of IP block <%s> not defined\n",
ip_block->version->funcs->name);
} else {
r = ip_block->version->funcs->hw_fini(ip_block);
/* XXX handle errors */
if (r) {
DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
ip_block->version->funcs->name, r);
}
}
ip_block->status.hw = false;
}
/**
* amdgpu_device_smu_fini_early - smu hw_fini wrapper
*
@ -3216,7 +3333,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
*/
static void amdgpu_device_smu_fini_early(struct amdgpu_device *adev)
{
int i, r;
int i;
if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(9, 0, 0))
return;
@ -3225,13 +3342,7 @@ static void amdgpu_device_smu_fini_early(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.hw)
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev);
/* XXX handle errors */
if (r) {
DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
adev->ip_blocks[i].status.hw = false;
amdgpu_ip_block_hw_fini(&adev->ip_blocks[i]);
break;
}
}
@ -3245,7 +3356,7 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].version->funcs->early_fini)
continue;
r = adev->ip_blocks[i].version->funcs->early_fini((void *)adev);
r = adev->ip_blocks[i].version->funcs->early_fini(&adev->ip_blocks[i]);
if (r) {
DRM_DEBUG("early_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
@ -3264,14 +3375,7 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.hw)
continue;
r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev);
/* XXX handle errors */
if (r) {
DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
adev->ip_blocks[i].status.hw = false;
amdgpu_ip_block_hw_fini(&adev->ip_blocks[i]);
}
if (amdgpu_sriov_vf(adev)) {
@ -3317,12 +3421,13 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
amdgpu_ib_pool_fini(adev);
amdgpu_seq64_fini(adev);
}
r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev);
/* XXX handle errors */
if (r) {
DRM_DEBUG("sw_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
if (adev->ip_blocks[i].version->funcs->sw_fini) {
r = adev->ip_blocks[i].version->funcs->sw_fini(&adev->ip_blocks[i]);
/* XXX handle errors */
if (r) {
DRM_DEBUG("sw_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
}
adev->ip_blocks[i].status.sw = false;
adev->ip_blocks[i].status.valid = false;
@ -3332,7 +3437,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.late_initialized)
continue;
if (adev->ip_blocks[i].version->funcs->late_fini)
adev->ip_blocks[i].version->funcs->late_fini((void *)adev);
adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]);
adev->ip_blocks[i].status.late_initialized = false;
}
@ -3404,15 +3509,9 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
continue;
/* XXX handle errors */
r = adev->ip_blocks[i].version->funcs->suspend(adev);
/* XXX handle errors */
if (r) {
DRM_ERROR("suspend of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
if (r)
return r;
}
adev->ip_blocks[i].status.hw = false;
}
return 0;
@ -3450,14 +3549,9 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
}
/* skip unnecessary suspend if we do not initialize them yet */
if (adev->gmc.xgmi.pending_reset &&
!(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH)) {
adev->ip_blocks[i].status.hw = false;
if (!amdgpu_ip_member_of_hwini(
adev, adev->ip_blocks[i].version->type))
continue;
}
/* skip suspend of gfx/mes and psp for S0ix
* gfx is in gfxoff state, so on resume it will exit gfxoff just
@ -3491,13 +3585,9 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
continue;
/* XXX handle errors */
r = adev->ip_blocks[i].version->funcs->suspend(adev);
/* XXX handle errors */
if (r) {
DRM_ERROR("suspend of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
adev->ip_blocks[i].status.hw = false;
/* handle putting the SMC in the appropriate state */
if (!amdgpu_sriov_vf(adev)) {
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
@ -3571,7 +3661,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
!block->status.valid)
continue;
r = block->version->funcs->hw_init(adev);
r = block->version->funcs->hw_init(&adev->ip_blocks[i]);
DRM_INFO("RE-INIT-early: %s %s\n", block->version->funcs->name, r?"failed":"succeeded");
if (r)
return r;
@ -3610,15 +3700,19 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
block->status.hw)
continue;
if (block->version->type == AMD_IP_BLOCK_TYPE_SMC)
r = block->version->funcs->resume(adev);
else
r = block->version->funcs->hw_init(adev);
DRM_INFO("RE-INIT-late: %s %s\n", block->version->funcs->name, r?"failed":"succeeded");
if (r)
return r;
block->status.hw = true;
if (block->version->type == AMD_IP_BLOCK_TYPE_SMC) {
r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
if (r)
return r;
} else {
r = block->version->funcs->hw_init(&adev->ip_blocks[i]);
if (r) {
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
return r;
}
block->status.hw = true;
}
}
}
@ -3649,13 +3743,9 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP && amdgpu_sriov_vf(adev))) {
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
DRM_ERROR("resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
if (r)
return r;
}
adev->ip_blocks[i].status.hw = true;
}
}
@ -3687,13 +3777,9 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)
continue;
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
DRM_ERROR("resume of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
if (r)
return r;
}
adev->ip_blocks[i].status.hw = true;
}
return 0;
@ -4194,6 +4280,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
amdgpu_device_set_mcbp(adev);
/*
* By default, use default mode where all blocks are expected to be
* initialized. At present a 'swinit' of blocks is required to be
* completed before the need for a different level is detected.
*/
amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_DEFAULT);
/* early init functions */
r = amdgpu_device_ip_early_init(adev);
if (r)
@ -4266,20 +4358,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (!amdgpu_sriov_vf(adev) && amdgpu_asic_need_reset_on_init(adev)) {
if (adev->gmc.xgmi.num_physical_nodes) {
dev_info(adev->dev, "Pending hive reset.\n");
adev->gmc.xgmi.pending_reset = true;
/* Only need to init necessary block for SMU to handle the reset */
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (!(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)) {
DRM_DEBUG("IP %s disabled for hw_init.\n",
adev->ip_blocks[i].version->funcs->name);
adev->ip_blocks[i].status.hw = true;
}
}
amdgpu_set_init_level(adev,
AMDGPU_INIT_LEVEL_MINIMAL_XGMI);
} else if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
!amdgpu_device_has_display_hardware(adev)) {
r = psp_gpu_reset(adev);
@ -4387,7 +4467,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
/* enable clockgating, etc. after ib tests, etc. since some blocks require
* explicit gating rather than handling it automatically.
*/
if (!adev->gmc.xgmi.pending_reset) {
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
r = amdgpu_device_ip_late_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_device_ip_late_init failed\n");
@ -4437,6 +4517,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
amdgpu_fru_sysfs_init(adev);
amdgpu_reg_state_sysfs_init(adev);
amdgpu_xcp_cfg_sysfs_init(adev);
if (IS_ENABLED(CONFIG_PERF_EVENTS))
r = amdgpu_pmu_init(adev);
@ -4464,9 +4545,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (px)
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
if (adev->gmc.xgmi.pending_reset)
queue_delayed_work(system_wq, &mgpu_info.delayed_reset_work,
msecs_to_jiffies(AMDGPU_RESUME_MS));
if (adev->init_lvl->level == AMDGPU_INIT_LEVEL_MINIMAL_XGMI)
amdgpu_xgmi_reset_on_init(adev);
amdgpu_device_check_iommu_direct_map(adev);
@ -4560,6 +4640,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
amdgpu_fru_sysfs_fini(adev);
amdgpu_reg_state_sysfs_fini(adev);
amdgpu_xcp_cfg_sysfs_fini(adev);
/* disable ras feature must before hw fini */
amdgpu_ras_pre_fini(adev);
@ -4695,7 +4776,7 @@ int amdgpu_device_prepare(struct drm_device *dev)
continue;
if (!adev->ip_blocks[i].version->funcs->prepare_suspend)
continue;
r = adev->ip_blocks[i].version->funcs->prepare_suspend((void *)adev);
r = adev->ip_blocks[i].version->funcs->prepare_suspend(&adev->ip_blocks[i]);
if (r)
goto unprepare;
}
@ -4899,7 +4980,8 @@ static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].version->funcs->check_soft_reset)
adev->ip_blocks[i].status.hang =
adev->ip_blocks[i].version->funcs->check_soft_reset(adev);
adev->ip_blocks[i].version->funcs->check_soft_reset(
&adev->ip_blocks[i]);
if (adev->ip_blocks[i].status.hang) {
dev_info(adev->dev, "IP block:%s is hung!\n", adev->ip_blocks[i].version->funcs->name);
asic_hang = true;
@ -4928,7 +5010,7 @@ static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].status.hang &&
adev->ip_blocks[i].version->funcs->pre_soft_reset) {
r = adev->ip_blocks[i].version->funcs->pre_soft_reset(adev);
r = adev->ip_blocks[i].version->funcs->pre_soft_reset(&adev->ip_blocks[i]);
if (r)
return r;
}
@ -4990,7 +5072,7 @@ static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].status.hang &&
adev->ip_blocks[i].version->funcs->soft_reset) {
r = adev->ip_blocks[i].version->funcs->soft_reset(adev);
r = adev->ip_blocks[i].version->funcs->soft_reset(&adev->ip_blocks[i]);
if (r)
return r;
}
@ -5019,7 +5101,7 @@ static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].status.hang &&
adev->ip_blocks[i].version->funcs->post_soft_reset)
r = adev->ip_blocks[i].version->funcs->post_soft_reset(adev);
r = adev->ip_blocks[i].version->funcs->post_soft_reset(&adev->ip_blocks[i]);
if (r)
return r;
}
@ -5310,7 +5392,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
for (i = 0; i < tmp_adev->num_ip_blocks; i++)
if (tmp_adev->ip_blocks[i].version->funcs->dump_ip_state)
tmp_adev->ip_blocks[i].version->funcs
->dump_ip_state((void *)tmp_adev);
->dump_ip_state((void *)&tmp_adev->ip_blocks[i]);
dev_info(tmp_adev->dev, "Dumping IP State Completed\n");
}
@ -5326,74 +5408,25 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
return r;
}
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
struct amdgpu_reset_context *reset_context)
int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context)
{
struct amdgpu_device *tmp_adev = NULL;
bool need_full_reset, skip_hw_reset, vram_lost = false;
int r = 0;
struct list_head *device_list_handle;
bool full_reset, vram_lost = false;
struct amdgpu_device *tmp_adev;
int r;
/* Try reset handler method first */
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
reset_list);
device_list_handle = reset_context->reset_device_list;
reset_context->reset_device_list = device_list_handle;
r = amdgpu_reset_perform_reset(tmp_adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -EOPNOTSUPP)
r = 0;
else
return r;
if (!device_list_handle)
return -EINVAL;
/* Reset handler not implemented, use the default method */
need_full_reset =
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
/*
* ASIC reset has to be done on all XGMI hive nodes ASAP
* to allow proper links negotiation in FW (within 1 sec)
*/
if (!skip_hw_reset && need_full_reset) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
tmp_adev->gmc.xgmi.pending_reset = false;
if (!queue_work(system_unbound_wq, &tmp_adev->xgmi_reset_work))
r = -EALREADY;
} else
r = amdgpu_asic_reset(tmp_adev);
if (r) {
dev_err(tmp_adev->dev, "ASIC reset failed with error, %d for drm dev, %s",
r, adev_to_drm(tmp_adev)->unique);
goto out;
}
}
/* For XGMI wait for all resets to complete before proceed */
if (!r) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
flush_work(&tmp_adev->xgmi_reset_work);
r = tmp_adev->asic_reset_res;
if (r)
break;
}
}
}
}
if (!r && amdgpu_ras_intr_triggered()) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
amdgpu_ras_reset_error_count(tmp_adev, AMDGPU_RAS_BLOCK__MMHUB);
}
amdgpu_ras_intr_cleared();
}
full_reset = test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
r = 0;
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
if (need_full_reset) {
/* After reset, it's default init level */
amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT);
if (full_reset) {
/* post card */
amdgpu_ras_set_fed(tmp_adev, false);
r = amdgpu_device_asic_init(tmp_adev);
@ -5483,7 +5516,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
r = amdgpu_ib_ring_tests(tmp_adev);
if (r) {
dev_err(tmp_adev->dev, "ib ring test failed (%d).\n", r);
need_full_reset = true;
r = -EAGAIN;
goto end;
}
@ -5494,10 +5526,85 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
}
end:
if (need_full_reset)
return r;
}
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
struct amdgpu_reset_context *reset_context)
{
struct amdgpu_device *tmp_adev = NULL;
bool need_full_reset, skip_hw_reset;
int r = 0;
/* Try reset handler method first */
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
reset_list);
reset_context->reset_device_list = device_list_handle;
r = amdgpu_reset_perform_reset(tmp_adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -EOPNOTSUPP)
r = 0;
else
return r;
/* Reset handler not implemented, use the default method */
need_full_reset =
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
/*
* ASIC reset has to be done on all XGMI hive nodes ASAP
* to allow proper links negotiation in FW (within 1 sec)
*/
if (!skip_hw_reset && need_full_reset) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
if (!queue_work(system_unbound_wq,
&tmp_adev->xgmi_reset_work))
r = -EALREADY;
} else
r = amdgpu_asic_reset(tmp_adev);
if (r) {
dev_err(tmp_adev->dev,
"ASIC reset failed with error, %d for drm dev, %s",
r, adev_to_drm(tmp_adev)->unique);
goto out;
}
}
/* For XGMI wait for all resets to complete before proceed */
if (!r) {
list_for_each_entry(tmp_adev, device_list_handle,
reset_list) {
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
flush_work(&tmp_adev->xgmi_reset_work);
r = tmp_adev->asic_reset_res;
if (r)
break;
}
}
}
}
if (!r && amdgpu_ras_intr_triggered()) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
amdgpu_ras_reset_error_count(tmp_adev,
AMDGPU_RAS_BLOCK__MMHUB);
}
amdgpu_ras_intr_cleared();
}
r = amdgpu_device_reinit_after_reset(reset_context);
if (r == -EAGAIN)
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
else
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
out:
return r;
}

View File

@ -1723,38 +1723,76 @@ union nps_info {
struct nps_info_v1_0 v1;
};
static int amdgpu_discovery_refresh_nps_info(struct amdgpu_device *adev,
union nps_info *nps_data)
{
uint64_t vram_size, pos, offset;
struct nps_info_header *nhdr;
struct binary_header bhdr;
uint16_t checksum;
vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
pos = vram_size - DISCOVERY_TMR_OFFSET;
amdgpu_device_vram_access(adev, pos, &bhdr, sizeof(bhdr), false);
offset = le16_to_cpu(bhdr.table_list[NPS_INFO].offset);
checksum = le16_to_cpu(bhdr.table_list[NPS_INFO].checksum);
amdgpu_device_vram_access(adev, (pos + offset), nps_data,
sizeof(*nps_data), false);
nhdr = (struct nps_info_header *)(nps_data);
if (!amdgpu_discovery_verify_checksum((uint8_t *)nps_data,
le32_to_cpu(nhdr->size_bytes),
checksum)) {
dev_err(adev->dev, "nps data refresh, checksum mismatch\n");
return -EINVAL;
}
return 0;
}
int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
uint32_t *nps_type,
struct amdgpu_gmc_memrange **ranges,
int *range_cnt)
int *range_cnt, bool refresh)
{
struct amdgpu_gmc_memrange *mem_ranges;
struct binary_header *bhdr;
union nps_info *nps_info;
union nps_info nps_data;
u16 offset;
int i;
int i, r;
if (!nps_type || !range_cnt || !ranges)
return -EINVAL;
if (!adev->mman.discovery_bin) {
dev_err(adev->dev,
"fetch mem range failed, ip discovery uninitialized\n");
return -EINVAL;
if (refresh) {
r = amdgpu_discovery_refresh_nps_info(adev, &nps_data);
if (r)
return r;
nps_info = &nps_data;
} else {
if (!adev->mman.discovery_bin) {
dev_err(adev->dev,
"fetch mem range failed, ip discovery uninitialized\n");
return -EINVAL;
}
bhdr = (struct binary_header *)adev->mman.discovery_bin;
offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset);
if (!offset)
return -ENOENT;
/* If verification fails, return as if NPS table doesn't exist */
if (amdgpu_discovery_verify_npsinfo(adev, bhdr))
return -ENOENT;
nps_info =
(union nps_info *)(adev->mman.discovery_bin + offset);
}
bhdr = (struct binary_header *)adev->mman.discovery_bin;
offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset);
if (!offset)
return -ENOENT;
/* If verification fails, return as if NPS table doesn't exist */
if (amdgpu_discovery_verify_npsinfo(adev, bhdr))
return -ENOENT;
nps_info = (union nps_info *)(adev->mman.discovery_bin + offset);
switch (le16_to_cpu(nps_info->v1.header.version_major)) {
case 1:
*nps_type = nps_info->v1.nps_type;
@ -2492,6 +2530,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 2);
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 1);
adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 1);
adev->ip_versions[ISP_HWIP][0] = IP_VERSION(2, 0, 0);
} else {
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 1, 0);
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 1, 0);
@ -2508,6 +2547,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 1, 0);
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 0);
adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 0);
adev->ip_versions[ISP_HWIP][0] = IP_VERSION(2, 0, 0);
}
break;
case CHIP_VEGA20:

View File

@ -33,6 +33,6 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev);
int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
uint32_t *nps_type,
struct amdgpu_gmc_memrange **ranges,
int *range_cnt);
int *range_cnt, bool refresh);
#endif /* __AMDGPU_DISCOVERY__ */

View File

@ -232,8 +232,6 @@ int amdgpu_wbrf = -1;
int amdgpu_damage_clips = -1; /* auto */
int amdgpu_umsch_mm_fwlog;
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
@ -248,9 +246,6 @@ DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
struct amdgpu_mgpu_info mgpu_info = {
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
.delayed_reset_work = __DELAYED_WORK_INITIALIZER(
mgpu_info.delayed_reset_work,
amdgpu_drv_delayed_reset_work_handler, 0),
};
int amdgpu_ras_enable = -1;
uint amdgpu_ras_mask = 0xffffffff;
@ -2439,6 +2434,7 @@ amdgpu_pci_remove(struct pci_dev *pdev)
struct amdgpu_device *adev = drm_to_adev(dev);
amdgpu_xcp_dev_unplug(adev);
amdgpu_gmc_prepare_nps_mode_change(adev);
drm_dev_unplug(dev);
if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
@ -2477,82 +2473,6 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
adev->mp1_state = PP_MP1_STATE_NONE;
}
/**
* amdgpu_drv_delayed_reset_work_handler - work handler for reset
*
* @work: work_struct.
*/
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work)
{
struct list_head device_list;
struct amdgpu_device *adev;
int i, r;
struct amdgpu_reset_context reset_context;
memset(&reset_context, 0, sizeof(reset_context));
mutex_lock(&mgpu_info.mutex);
if (mgpu_info.pending_reset == true) {
mutex_unlock(&mgpu_info.mutex);
return;
}
mgpu_info.pending_reset = true;
mutex_unlock(&mgpu_info.mutex);
/* Use a common context, just need to make sure full reset is done */
reset_context.method = AMD_RESET_METHOD_NONE;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
for (i = 0; i < mgpu_info.num_dgpu; i++) {
adev = mgpu_info.gpu_ins[i].adev;
reset_context.reset_req_dev = adev;
r = amdgpu_device_pre_asic_reset(adev, &reset_context);
if (r) {
dev_err(adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ",
r, adev_to_drm(adev)->unique);
}
if (!queue_work(system_unbound_wq, &adev->xgmi_reset_work))
r = -EALREADY;
}
for (i = 0; i < mgpu_info.num_dgpu; i++) {
adev = mgpu_info.gpu_ins[i].adev;
flush_work(&adev->xgmi_reset_work);
adev->gmc.xgmi.pending_reset = false;
}
/* reset function will rebuild the xgmi hive info , clear it now */
for (i = 0; i < mgpu_info.num_dgpu; i++)
amdgpu_xgmi_remove_device(mgpu_info.gpu_ins[i].adev);
INIT_LIST_HEAD(&device_list);
for (i = 0; i < mgpu_info.num_dgpu; i++)
list_add_tail(&mgpu_info.gpu_ins[i].adev->reset_list, &device_list);
/* unregister the GPU first, reset function will add them back */
list_for_each_entry(adev, &device_list, reset_list)
amdgpu_unregister_gpu_instance(adev);
/* Use a common context, just need to make sure full reset is done */
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
r = amdgpu_do_asic_reset(&device_list, &reset_context);
if (r) {
DRM_ERROR("reinit gpus failure");
return;
}
for (i = 0; i < mgpu_info.num_dgpu; i++) {
adev = mgpu_info.gpu_ins[i].adev;
if (!adev->kfd.init_complete) {
kgd2kfd_init_zone_device(adev);
amdgpu_amdkfd_device_init(adev);
amdgpu_amdkfd_drm_client_create(adev);
}
amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
}
static int amdgpu_pmops_prepare(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
@ -3075,6 +2995,12 @@ static int __init amdgpu_init(void)
/* Ignore KFD init failures. Normal when CONFIG_HSA_AMD is not set. */
amdgpu_amdkfd_init();
if (amdgpu_pp_feature_mask & PP_OVERDRIVE_MASK) {
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
pr_crit("Overdrive is enabled, please disable it before "
"reporting any bugs unrelated to overdrive.\n");
}
/* let modprobe override vga console setting */
return pci_register_driver(&amdgpu_kms_pci_driver);

View File

@ -59,18 +59,21 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_mem_stats stats;
struct amdgpu_mem_stats stats[__AMDGPU_PL_LAST + 1] = { };
ktime_t usage[AMDGPU_HW_IP_NUM];
unsigned int hw_ip;
const char *pl_name[] = {
[TTM_PL_VRAM] = "vram",
[TTM_PL_TT] = "gtt",
[TTM_PL_SYSTEM] = "cpu",
};
unsigned int hw_ip, i;
int ret;
memset(&stats, 0, sizeof(stats));
ret = amdgpu_bo_reserve(vm->root.bo, false);
if (ret)
return;
amdgpu_vm_get_memory(vm, &stats);
amdgpu_vm_get_memory(vm, stats, ARRAY_SIZE(stats));
amdgpu_bo_unreserve(vm->root.bo);
amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage);
@ -82,24 +85,35 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
*/
drm_printf(p, "pasid:\t%u\n", fpriv->vm.pasid);
drm_printf(p, "drm-memory-vram:\t%llu KiB\n", stats.vram/1024UL);
drm_printf(p, "drm-memory-gtt: \t%llu KiB\n", stats.gtt/1024UL);
drm_printf(p, "drm-memory-cpu: \t%llu KiB\n", stats.cpu/1024UL);
for (i = 0; i < TTM_PL_PRIV; i++)
drm_print_memory_stats(p,
&stats[i].drm,
DRM_GEM_OBJECT_RESIDENT |
DRM_GEM_OBJECT_PURGEABLE,
pl_name[i]);
/* Legacy amdgpu keys, alias to drm-resident-memory-: */
drm_printf(p, "drm-memory-vram:\t%llu KiB\n",
stats[TTM_PL_VRAM].total/1024UL);
drm_printf(p, "drm-memory-gtt: \t%llu KiB\n",
stats[TTM_PL_TT].total/1024UL);
drm_printf(p, "drm-memory-cpu: \t%llu KiB\n",
stats[TTM_PL_SYSTEM].total/1024UL);
/* Amdgpu specific memory accounting keys: */
drm_printf(p, "amd-memory-visible-vram:\t%llu KiB\n",
stats.visible_vram/1024UL);
stats[TTM_PL_VRAM].visible/1024UL);
drm_printf(p, "amd-evicted-vram:\t%llu KiB\n",
stats.evicted_vram/1024UL);
stats[TTM_PL_VRAM].evicted/1024UL);
drm_printf(p, "amd-evicted-visible-vram:\t%llu KiB\n",
stats.evicted_visible_vram/1024UL);
stats[TTM_PL_VRAM].evicted_visible/1024UL);
drm_printf(p, "amd-requested-vram:\t%llu KiB\n",
stats.requested_vram/1024UL);
stats[TTM_PL_VRAM].requested/1024UL);
drm_printf(p, "amd-requested-visible-vram:\t%llu KiB\n",
stats.requested_visible_vram/1024UL);
stats[TTM_PL_VRAM].requested_visible/1024UL);
drm_printf(p, "amd-requested-gtt:\t%llu KiB\n",
stats.requested_gtt/1024UL);
drm_printf(p, "drm-shared-vram:\t%llu KiB\n", stats.vram_shared/1024UL);
drm_printf(p, "drm-shared-gtt:\t%llu KiB\n", stats.gtt_shared/1024UL);
drm_printf(p, "drm-shared-cpu:\t%llu KiB\n", stats.cpu_shared/1024UL);
stats[TTM_PL_TT].requested/1024UL);
for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) {
if (!usage[hw_ip])

View File

@ -87,16 +87,6 @@ int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev,
return bit;
}
void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit,
int *me, int *pipe, int *queue)
{
*queue = bit % adev->gfx.me.num_queue_per_pipe;
*pipe = (bit / adev->gfx.me.num_queue_per_pipe)
% adev->gfx.me.num_pipe_per_me;
*me = (bit / adev->gfx.me.num_queue_per_pipe)
/ adev->gfx.me.num_pipe_per_me;
}
bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev,
int me, int pipe, int queue)
{
@ -415,7 +405,7 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
}
/* prepare MQD backup */
kiq->mqd_backup = kmalloc(mqd_size, GFP_KERNEL);
kiq->mqd_backup = kzalloc(mqd_size, GFP_KERNEL);
if (!kiq->mqd_backup) {
dev_warn(adev->dev,
"no memory to create MQD backup for ring %s\n", ring->name);
@ -438,7 +428,7 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
ring->mqd_size = mqd_size;
/* prepare MQD backup */
adev->gfx.me.mqd_backup[i] = kmalloc(mqd_size, GFP_KERNEL);
adev->gfx.me.mqd_backup[i] = kzalloc(mqd_size, GFP_KERNEL);
if (!adev->gfx.me.mqd_backup[i]) {
dev_warn(adev->dev, "no memory to create MQD backup for ring %s\n", ring->name);
return -ENOMEM;
@ -462,7 +452,7 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
ring->mqd_size = mqd_size;
/* prepare MQD backup */
adev->gfx.mec.mqd_backup[j] = kmalloc(mqd_size, GFP_KERNEL);
adev->gfx.mec.mqd_backup[j] = kzalloc(mqd_size, GFP_KERNEL);
if (!adev->gfx.mec.mqd_backup[j]) {
dev_warn(adev->dev, "no memory to create MQD backup for ring %s\n", ring->name);
return -ENOMEM;
@ -1363,35 +1353,35 @@ static ssize_t amdgpu_gfx_set_compute_partition(struct device *dev,
return count;
}
static const char *xcp_desc[] = {
[AMDGPU_SPX_PARTITION_MODE] = "SPX",
[AMDGPU_DPX_PARTITION_MODE] = "DPX",
[AMDGPU_TPX_PARTITION_MODE] = "TPX",
[AMDGPU_QPX_PARTITION_MODE] = "QPX",
[AMDGPU_CPX_PARTITION_MODE] = "CPX",
};
static ssize_t amdgpu_gfx_get_available_compute_partition(struct device *dev,
struct device_attribute *addr,
char *buf)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
char *supported_partition;
struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
int size = 0, mode;
char *sep = "";
/* TBD */
switch (NUM_XCC(adev->gfx.xcc_mask)) {
case 8:
supported_partition = "SPX, DPX, QPX, CPX";
break;
case 6:
supported_partition = "SPX, TPX, CPX";
break;
case 4:
supported_partition = "SPX, DPX, CPX";
break;
/* this seems only existing in emulation phase */
case 2:
supported_partition = "SPX, CPX";
break;
default:
supported_partition = "Not supported";
break;
if (!xcp_mgr || !xcp_mgr->avail_xcp_modes)
return sysfs_emit(buf, "Not supported\n");
for_each_inst(mode, xcp_mgr->avail_xcp_modes) {
size += sysfs_emit_at(buf, size, "%s%s", sep, xcp_desc[mode]);
sep = ", ";
}
return sysfs_emit(buf, "%s\n", supported_partition);
size += sysfs_emit_at(buf, size, "\n");
return size;
}
static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
@ -1614,32 +1604,55 @@ static DEVICE_ATTR(available_compute_partition, 0444,
int amdgpu_gfx_sysfs_init(struct amdgpu_device *adev)
{
struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
bool xcp_switch_supported;
int r;
if (!xcp_mgr)
return 0;
xcp_switch_supported =
(xcp_mgr->funcs && xcp_mgr->funcs->switch_partition_mode);
if (!xcp_switch_supported)
dev_attr_current_compute_partition.attr.mode &=
~(S_IWUSR | S_IWGRP | S_IWOTH);
r = device_create_file(adev->dev, &dev_attr_current_compute_partition);
if (r)
return r;
r = device_create_file(adev->dev, &dev_attr_available_compute_partition);
if (xcp_switch_supported)
r = device_create_file(adev->dev,
&dev_attr_available_compute_partition);
return r;
}
void amdgpu_gfx_sysfs_fini(struct amdgpu_device *adev)
{
struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
bool xcp_switch_supported;
if (!xcp_mgr)
return;
xcp_switch_supported =
(xcp_mgr->funcs && xcp_mgr->funcs->switch_partition_mode);
device_remove_file(adev->dev, &dev_attr_current_compute_partition);
device_remove_file(adev->dev, &dev_attr_available_compute_partition);
if (xcp_switch_supported)
device_remove_file(adev->dev,
&dev_attr_available_compute_partition);
}
int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev)
{
int r;
if (!amdgpu_sriov_vf(adev)) {
r = device_create_file(adev->dev, &dev_attr_enforce_isolation);
if (r)
return r;
}
r = device_create_file(adev->dev, &dev_attr_enforce_isolation);
if (r)
return r;
r = device_create_file(adev->dev, &dev_attr_run_cleaner_shader);
if (r)
@ -1650,8 +1663,7 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev)
void amdgpu_gfx_sysfs_isolation_shader_fini(struct amdgpu_device *adev)
{
if (!amdgpu_sriov_vf(adev))
device_remove_file(adev->dev, &dev_attr_enforce_isolation);
device_remove_file(adev->dev, &dev_attr_enforce_isolation);
device_remove_file(adev->dev, &dev_attr_run_cleaner_shader);
}

View File

@ -540,8 +540,6 @@ bool amdgpu_gfx_is_high_priority_graphics_queue(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me,
int pipe, int queue);
void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit,
int *me, int *pipe, int *queue);
bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
int pipe, int queue);
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);

View File

@ -1065,18 +1065,6 @@ uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo)
return amdgpu_gmc_vram_mc2pa(adev, amdgpu_bo_gpu_offset(bo));
}
/**
* amdgpu_gmc_vram_cpu_pa - calculate vram buffer object's physical address
* from CPU's view
*
* @adev: amdgpu_device pointer
* @bo: amdgpu buffer object
*/
uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo)
{
return amdgpu_bo_gpu_offset(bo) - adev->gmc.vram_start + adev->gmc.aper_base;
}
int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
{
struct amdgpu_bo *vram_bo = NULL;
@ -1130,6 +1118,79 @@ int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
return ret;
}
static const char *nps_desc[] = {
[AMDGPU_NPS1_PARTITION_MODE] = "NPS1",
[AMDGPU_NPS2_PARTITION_MODE] = "NPS2",
[AMDGPU_NPS3_PARTITION_MODE] = "NPS3",
[AMDGPU_NPS4_PARTITION_MODE] = "NPS4",
[AMDGPU_NPS6_PARTITION_MODE] = "NPS6",
[AMDGPU_NPS8_PARTITION_MODE] = "NPS8",
};
static ssize_t available_memory_partition_show(struct device *dev,
struct device_attribute *addr,
char *buf)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
int size = 0, mode;
char *sep = "";
for_each_inst(mode, adev->gmc.supported_nps_modes) {
size += sysfs_emit_at(buf, size, "%s%s", sep, nps_desc[mode]);
sep = ", ";
}
size += sysfs_emit_at(buf, size, "\n");
return size;
}
static ssize_t current_memory_partition_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);
enum amdgpu_memory_partition mode;
struct amdgpu_hive_info *hive;
int i;
mode = UNKNOWN_MEMORY_PARTITION_MODE;
for_each_inst(i, adev->gmc.supported_nps_modes) {
if (!strncasecmp(nps_desc[i], buf, strlen(nps_desc[i]))) {
mode = i;
break;
}
}
if (mode == UNKNOWN_MEMORY_PARTITION_MODE)
return -EINVAL;
if (mode == adev->gmc.gmc_funcs->query_mem_partition_mode(adev)) {
dev_info(
adev->dev,
"requested NPS mode is same as current NPS mode, skipping\n");
return count;
}
/* If device is part of hive, all devices in the hive should request the
* same mode. Hence store the requested mode in hive.
*/
hive = amdgpu_get_xgmi_hive(adev);
if (hive) {
atomic_set(&hive->requested_nps_mode, mode);
amdgpu_put_xgmi_hive(hive);
} else {
adev->gmc.requested_nps_mode = mode;
}
dev_info(
adev->dev,
"NPS mode change requested, please remove and reload the driver\n");
return count;
}
static ssize_t current_memory_partition_show(
struct device *dev, struct device_attribute *addr, char *buf)
{
@ -1138,53 +1199,65 @@ static ssize_t current_memory_partition_show(
enum amdgpu_memory_partition mode;
mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
switch (mode) {
case AMDGPU_NPS1_PARTITION_MODE:
return sysfs_emit(buf, "NPS1\n");
case AMDGPU_NPS2_PARTITION_MODE:
return sysfs_emit(buf, "NPS2\n");
case AMDGPU_NPS3_PARTITION_MODE:
return sysfs_emit(buf, "NPS3\n");
case AMDGPU_NPS4_PARTITION_MODE:
return sysfs_emit(buf, "NPS4\n");
case AMDGPU_NPS6_PARTITION_MODE:
return sysfs_emit(buf, "NPS6\n");
case AMDGPU_NPS8_PARTITION_MODE:
return sysfs_emit(buf, "NPS8\n");
default:
if ((mode >= ARRAY_SIZE(nps_desc)) ||
(BIT(mode) & AMDGPU_ALL_NPS_MASK) != BIT(mode))
return sysfs_emit(buf, "UNKNOWN\n");
}
return sysfs_emit(buf, "%s\n", nps_desc[mode]);
}
static DEVICE_ATTR_RO(current_memory_partition);
static DEVICE_ATTR_RW(current_memory_partition);
static DEVICE_ATTR_RO(available_memory_partition);
int amdgpu_gmc_sysfs_init(struct amdgpu_device *adev)
{
bool nps_switch_support;
int r = 0;
if (!adev->gmc.gmc_funcs->query_mem_partition_mode)
return 0;
nps_switch_support = (hweight32(adev->gmc.supported_nps_modes &
AMDGPU_ALL_NPS_MASK) > 1);
if (!nps_switch_support)
dev_attr_current_memory_partition.attr.mode &=
~(S_IWUSR | S_IWGRP | S_IWOTH);
else
r = device_create_file(adev->dev,
&dev_attr_available_memory_partition);
if (r)
return r;
return device_create_file(adev->dev,
&dev_attr_current_memory_partition);
}
void amdgpu_gmc_sysfs_fini(struct amdgpu_device *adev)
{
if (!adev->gmc.gmc_funcs->query_mem_partition_mode)
return;
device_remove_file(adev->dev, &dev_attr_current_memory_partition);
device_remove_file(adev->dev, &dev_attr_available_memory_partition);
}
int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
struct amdgpu_mem_partition_info *mem_ranges,
int exp_ranges)
uint8_t *exp_ranges)
{
struct amdgpu_gmc_memrange *ranges;
int range_cnt, ret, i, j;
uint32_t nps_type;
bool refresh;
if (!mem_ranges)
if (!mem_ranges || !exp_ranges)
return -EINVAL;
refresh = (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) &&
(adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS);
ret = amdgpu_discovery_get_nps_info(adev, &nps_type, &ranges,
&range_cnt);
&range_cnt, refresh);
if (ret)
return ret;
@ -1192,16 +1265,16 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
/* TODO: For now, expect ranges and partition count to be the same.
* Adjust if there are holes expected in any NPS domain.
*/
if (range_cnt != exp_ranges) {
if (*exp_ranges && (range_cnt != *exp_ranges)) {
dev_warn(
adev->dev,
"NPS config mismatch - expected ranges: %d discovery - nps mode: %d, nps ranges: %d",
exp_ranges, nps_type, range_cnt);
*exp_ranges, nps_type, range_cnt);
ret = -EINVAL;
goto err;
}
for (i = 0; i < exp_ranges; ++i) {
for (i = 0; i < range_cnt; ++i) {
if (ranges[i].base_address >= ranges[i].limit_address) {
dev_warn(
adev->dev,
@ -1242,8 +1315,81 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
ranges[i].limit_address - ranges[i].base_address + 1;
}
if (!*exp_ranges)
*exp_ranges = range_cnt;
err:
kfree(ranges);
return ret;
}
int amdgpu_gmc_request_memory_partition(struct amdgpu_device *adev,
int nps_mode)
{
/* Not supported on VF devices and APUs */
if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
return -EOPNOTSUPP;
if (!adev->psp.funcs) {
dev_err(adev->dev,
"PSP interface not available for nps mode change request");
return -EINVAL;
}
return psp_memory_partition(&adev->psp, nps_mode);
}
static inline bool amdgpu_gmc_need_nps_switch_req(struct amdgpu_device *adev,
int req_nps_mode,
int cur_nps_mode)
{
return (((BIT(req_nps_mode) & adev->gmc.supported_nps_modes) ==
BIT(req_nps_mode)) &&
req_nps_mode != cur_nps_mode);
}
void amdgpu_gmc_prepare_nps_mode_change(struct amdgpu_device *adev)
{
int req_nps_mode, cur_nps_mode, r;
struct amdgpu_hive_info *hive;
if (amdgpu_sriov_vf(adev) || !adev->gmc.supported_nps_modes ||
!adev->gmc.gmc_funcs->request_mem_partition_mode)
return;
cur_nps_mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
hive = amdgpu_get_xgmi_hive(adev);
if (hive) {
req_nps_mode = atomic_read(&hive->requested_nps_mode);
if (!amdgpu_gmc_need_nps_switch_req(adev, req_nps_mode,
cur_nps_mode)) {
amdgpu_put_xgmi_hive(hive);
return;
}
r = amdgpu_xgmi_request_nps_change(adev, hive, req_nps_mode);
amdgpu_put_xgmi_hive(hive);
goto out;
}
req_nps_mode = adev->gmc.requested_nps_mode;
if (!amdgpu_gmc_need_nps_switch_req(adev, req_nps_mode, cur_nps_mode))
return;
/* even if this fails, we should let driver unload w/o blocking */
r = adev->gmc.gmc_funcs->request_mem_partition_mode(adev, req_nps_mode);
out:
if (r)
dev_err(adev->dev, "NPS mode change request failed\n");
else
dev_info(
adev->dev,
"NPS mode change request done, reload driver to complete the change\n");
}
bool amdgpu_gmc_need_reset_on_init(struct amdgpu_device *adev)
{
if (adev->gmc.gmc_funcs->need_reset_on_init)
return adev->gmc.gmc_funcs->need_reset_on_init(adev);
return false;
}

View File

@ -73,6 +73,13 @@ enum amdgpu_memory_partition {
AMDGPU_NPS8_PARTITION_MODE = 8,
};
#define AMDGPU_ALL_NPS_MASK \
(BIT(AMDGPU_NPS1_PARTITION_MODE) | BIT(AMDGPU_NPS2_PARTITION_MODE) | \
BIT(AMDGPU_NPS3_PARTITION_MODE) | BIT(AMDGPU_NPS4_PARTITION_MODE) | \
BIT(AMDGPU_NPS6_PARTITION_MODE) | BIT(AMDGPU_NPS8_PARTITION_MODE))
#define AMDGPU_GMC_INIT_RESET_NPS BIT(0)
/*
* GMC page fault information
*/
@ -161,6 +168,10 @@ struct amdgpu_gmc_funcs {
enum amdgpu_memory_partition (*query_mem_partition_mode)(
struct amdgpu_device *adev);
/* Request NPS mode */
int (*request_mem_partition_mode)(struct amdgpu_device *adev,
int nps_mode);
bool (*need_reset_on_init)(struct amdgpu_device *adev);
};
struct amdgpu_xgmi_ras {
@ -182,7 +193,6 @@ struct amdgpu_xgmi {
bool supported;
struct ras_common_if *ras_if;
bool connected_to_cpu;
bool pending_reset;
struct amdgpu_xgmi_ras *ras;
};
@ -305,6 +315,9 @@ struct amdgpu_gmc {
struct amdgpu_mem_partition_info *mem_partitions;
uint8_t num_mem_partitions;
const struct amdgpu_gmc_funcs *gmc_funcs;
enum amdgpu_memory_partition requested_nps_mode;
uint32_t supported_nps_modes;
uint32_t reset_flags;
struct amdgpu_xgmi xgmi;
struct amdgpu_irq_src ecc_irq;
@ -447,13 +460,17 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev);
void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev);
uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr);
uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
int amdgpu_gmc_vram_checking(struct amdgpu_device *adev);
int amdgpu_gmc_sysfs_init(struct amdgpu_device *adev);
void amdgpu_gmc_sysfs_fini(struct amdgpu_device *adev);
int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
struct amdgpu_mem_partition_info *mem_ranges,
int exp_ranges);
uint8_t *exp_ranges);
int amdgpu_gmc_request_memory_partition(struct amdgpu_device *adev,
int nps_mode);
void amdgpu_gmc_prepare_nps_mode_change(struct amdgpu_device *adev);
bool amdgpu_gmc_need_reset_on_init(struct amdgpu_device *adev);
#endif

View File

@ -225,15 +225,6 @@ void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c)
kfree(i2c);
}
/* Add the default buses */
void amdgpu_i2c_init(struct amdgpu_device *adev)
{
if (amdgpu_hw_i2c)
DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n");
amdgpu_atombios_i2c_init(adev);
}
/* remove all the buses */
void amdgpu_i2c_fini(struct amdgpu_device *adev)
{
@ -247,22 +238,6 @@ void amdgpu_i2c_fini(struct amdgpu_device *adev)
}
}
/* Add additional buses */
void amdgpu_i2c_add(struct amdgpu_device *adev,
const struct amdgpu_i2c_bus_rec *rec,
const char *name)
{
struct drm_device *dev = adev_to_drm(adev);
int i;
for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) {
if (!adev->i2c_bus[i]) {
adev->i2c_bus[i] = amdgpu_i2c_create(dev, rec, name);
return;
}
}
}
/* looks up bus based on id */
struct amdgpu_i2c_chan *
amdgpu_i2c_lookup(struct amdgpu_device *adev,

View File

@ -28,11 +28,7 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
const struct amdgpu_i2c_bus_rec *rec,
const char *name);
void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c);
void amdgpu_i2c_init(struct amdgpu_device *adev);
void amdgpu_i2c_fini(struct amdgpu_device *adev);
void amdgpu_i2c_add(struct amdgpu_device *adev,
const struct amdgpu_i2c_bus_rec *rec,
const char *name);
struct amdgpu_i2c_chan *
amdgpu_i2c_lookup(struct amdgpu_device *adev,
const struct amdgpu_i2c_bus_rec *i2c_bus);

View File

@ -342,15 +342,13 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
* @ring: ring we want to submit job to
* @job: job who wants to use the VMID
* @id: resulting VMID
* @fence: fence to wait for if no id could be grabbed
*
* Try to reuse a VMID for this submission.
*/
static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
struct amdgpu_ring *ring,
struct amdgpu_job *job,
struct amdgpu_vmid **id,
struct dma_fence **fence)
struct amdgpu_vmid **id)
{
struct amdgpu_device *adev = ring->adev;
unsigned vmhub = ring->vm_hub;
@ -429,7 +427,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
if (r || !id)
goto error;
} else {
r = amdgpu_vmid_grab_used(vm, ring, job, &id, fence);
r = amdgpu_vmid_grab_used(vm, ring, job, &id);
if (r)
goto error;

View File

@ -33,33 +33,17 @@
#include "isp_v4_1_0.h"
#include "isp_v4_1_1.h"
static int isp_sw_init(void *handle)
{
return 0;
}
static int isp_sw_fini(void *handle)
{
return 0;
}
/**
* isp_hw_init - start and test isp block
*
* @handle: handle for amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int isp_hw_init(void *handle)
static int isp_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_isp *isp = &adev->isp;
const struct amdgpu_ip_block *ip_block =
amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ISP);
if (!ip_block)
return -EINVAL;
if (isp->funcs->hw_init != NULL)
return isp->funcs->hw_init(isp);
@ -69,13 +53,12 @@ static int isp_hw_init(void *handle)
/**
* isp_hw_fini - stop the hardware block
*
* @handle: handle for amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int isp_hw_fini(void *handle)
static int isp_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_isp *isp = &adev->isp;
struct amdgpu_isp *isp = &ip_block->adev->isp;
if (isp->funcs->hw_fini != NULL)
return isp->funcs->hw_fini(isp);
@ -83,16 +66,6 @@ static int isp_hw_fini(void *handle)
return -ENODEV;
}
static int isp_suspend(void *handle)
{
return 0;
}
static int isp_resume(void *handle)
{
return 0;
}
static int isp_load_fw_by_psp(struct amdgpu_device *adev)
{
const struct common_firmware_header *hdr;
@ -122,9 +95,10 @@ static int isp_load_fw_by_psp(struct amdgpu_device *adev)
return r;
}
static int isp_early_init(void *handle)
static int isp_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_isp *isp = &adev->isp;
switch (amdgpu_ip_version(adev, ISP_HWIP, 0)) {
@ -154,16 +128,6 @@ static bool isp_is_idle(void *handle)
return true;
}
static int isp_wait_for_idle(void *handle)
{
return 0;
}
static int isp_soft_reset(void *handle)
{
return 0;
}
static int isp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -179,16 +143,9 @@ static int isp_set_powergating_state(void *handle,
static const struct amd_ip_funcs isp_ip_funcs = {
.name = "isp_ip",
.early_init = isp_early_init,
.late_init = NULL,
.sw_init = isp_sw_init,
.sw_fini = isp_sw_fini,
.hw_init = isp_hw_init,
.hw_fini = isp_hw_fini,
.suspend = isp_suspend,
.resume = isp_resume,
.is_idle = isp_is_idle,
.wait_for_idle = isp_wait_for_idle,
.soft_reset = isp_soft_reset,
.set_clockgating_state = isp_set_clockgating_state,
.set_powergating_state = isp_set_powergating_state,
};

View File

@ -42,7 +42,7 @@ static void amdgpu_job_do_core_dump(struct amdgpu_device *adev,
for (i = 0; i < adev->num_ip_blocks; i++)
if (adev->ip_blocks[i].version->funcs->dump_ip_state)
adev->ip_blocks[i].version->funcs
->dump_ip_state((void *)adev);
->dump_ip_state((void *)&adev->ip_blocks[i]);
dev_info(adev->dev, "Dumping IP State Completed\n");
amdgpu_coredump(adev, true, false, job);
@ -356,10 +356,10 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job,
if (r)
goto error;
if (!fence && job->gang_submit)
if (job->gang_submit)
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
while (!fence && job->vm && !job->vmid) {
if (!fence && job->vm && !job->vmid) {
r = amdgpu_vmid_grab(job->vm, ring, job, &fence);
if (r) {
dev_err(ring->adev->dev, "Error getting VM ID (%d)\n", r);

View File

@ -342,3 +342,76 @@ int amdgpu_jpeg_psp_update_sram(struct amdgpu_device *adev, int inst_idx,
return psp_execute_ip_fw_load(&adev->psp, &ucode);
}
/*
* debugfs for to enable/disable jpeg job submission to specific core.
*/
#if defined(CONFIG_DEBUG_FS)
static int amdgpu_debugfs_jpeg_sched_mask_set(void *data, u64 val)
{
struct amdgpu_device *adev = (struct amdgpu_device *)data;
u32 i, j;
u64 mask = 0;
struct amdgpu_ring *ring;
if (!adev)
return -ENODEV;
mask = (1 << (adev->jpeg.num_jpeg_inst * adev->jpeg.num_jpeg_rings)) - 1;
if ((val & mask) == 0)
return -EINVAL;
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
ring = &adev->jpeg.inst[i].ring_dec[j];
if (val & (1 << ((i * adev->jpeg.num_jpeg_rings) + j)))
ring->sched.ready = true;
else
ring->sched.ready = false;
}
}
/* publish sched.ready flag update effective immediately across smp */
smp_rmb();
return 0;
}
static int amdgpu_debugfs_jpeg_sched_mask_get(void *data, u64 *val)
{
struct amdgpu_device *adev = (struct amdgpu_device *)data;
u32 i, j;
u64 mask = 0;
struct amdgpu_ring *ring;
if (!adev)
return -ENODEV;
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
ring = &adev->jpeg.inst[i].ring_dec[j];
if (ring->sched.ready)
mask |= 1 << ((i * adev->jpeg.num_jpeg_rings) + j);
}
}
*val = mask;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_debugfs_jpeg_sched_mask_fops,
amdgpu_debugfs_jpeg_sched_mask_get,
amdgpu_debugfs_jpeg_sched_mask_set, "%llx\n");
#endif
void amdgpu_debugfs_jpeg_sched_mask_init(struct amdgpu_device *adev)
{
#if defined(CONFIG_DEBUG_FS)
struct drm_minor *minor = adev_to_drm(adev)->primary;
struct dentry *root = minor->debugfs_root;
char name[32];
if (!(adev->jpeg.num_jpeg_inst > 1) && !(adev->jpeg.num_jpeg_rings > 1))
return;
sprintf(name, "amdgpu_jpeg_sched_mask");
debugfs_create_file(name, 0600, root, adev,
&amdgpu_debugfs_jpeg_sched_mask_fops);
#endif
}

View File

@ -149,5 +149,6 @@ int amdgpu_jpeg_ras_late_init(struct amdgpu_device *adev,
int amdgpu_jpeg_ras_sw_init(struct amdgpu_device *adev);
int amdgpu_jpeg_psp_update_sram(struct amdgpu_device *adev, int inst_idx,
enum AMDGPU_UCODE_ID ucode_id);
void amdgpu_debugfs_jpeg_sched_mask_init(struct amdgpu_device *adev);
#endif /*__AMDGPU_JPEG_H__*/

View File

@ -905,7 +905,7 @@ int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
queue_input.me_id = ring->me;
queue_input.pipe_id = ring->pipe;
queue_input.queue_id = ring->queue;
queue_input.mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
queue_input.mqd_addr = ring->mqd_obj ? amdgpu_bo_gpu_offset(ring->mqd_obj) : 0;
queue_input.wptr_addr = ring->wptr_gpu_addr;
queue_input.vmid = vmid;
queue_input.use_mmio = use_mmio;
@ -1203,8 +1203,10 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
r = amdgpu_ring_init(adev, ring, 1024, NULL, 0,
AMDGPU_RING_PRIO_DEFAULT, NULL);
if (r)
if (r) {
amdgpu_mes_unlock(&adev->mes);
goto clean_up_memory;
}
amdgpu_mes_ring_to_queue_props(adev, ring, &qprops);
@ -1237,7 +1239,6 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
amdgpu_ring_fini(ring);
clean_up_memory:
kfree(ring);
amdgpu_mes_unlock(&adev->mes);
return r;
}

View File

@ -101,6 +101,7 @@ struct amdgpu_nbio_funcs {
int (*get_compute_partition_mode)(struct amdgpu_device *adev);
u32 (*get_memory_partition_mode)(struct amdgpu_device *adev,
u32 *supp_modes);
bool (*is_nps_switch_requested)(struct amdgpu_device *adev);
u64 (*get_pcie_replay_count)(struct amdgpu_device *adev);
void (*set_reg_remap)(struct amdgpu_device *adev);
};

View File

@ -1170,54 +1170,92 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
}
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
struct amdgpu_mem_stats *stats)
struct amdgpu_mem_stats *stats,
unsigned int sz)
{
const unsigned int domain_to_pl[] = {
[ilog2(AMDGPU_GEM_DOMAIN_CPU)] = TTM_PL_SYSTEM,
[ilog2(AMDGPU_GEM_DOMAIN_GTT)] = TTM_PL_TT,
[ilog2(AMDGPU_GEM_DOMAIN_VRAM)] = TTM_PL_VRAM,
[ilog2(AMDGPU_GEM_DOMAIN_GDS)] = AMDGPU_PL_GDS,
[ilog2(AMDGPU_GEM_DOMAIN_GWS)] = AMDGPU_PL_GWS,
[ilog2(AMDGPU_GEM_DOMAIN_OA)] = AMDGPU_PL_OA,
[ilog2(AMDGPU_GEM_DOMAIN_DOORBELL)] = AMDGPU_PL_DOORBELL,
};
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct ttm_resource *res = bo->tbo.resource;
struct drm_gem_object *obj = &bo->tbo.base;
uint64_t size = amdgpu_bo_size(bo);
struct drm_gem_object *obj;
bool shared;
unsigned int type;
/* Abort if the BO doesn't currently have a backing store */
if (!res)
return;
if (!res) {
/*
* If no backing store use one of the preferred domain for basic
* stats. We take the MSB since that should give a reasonable
* view.
*/
BUILD_BUG_ON(TTM_PL_VRAM < TTM_PL_TT ||
TTM_PL_VRAM < TTM_PL_SYSTEM);
type = fls(bo->preferred_domains & AMDGPU_GEM_DOMAIN_MASK);
if (!type)
return;
type--;
if (drm_WARN_ON_ONCE(&adev->ddev,
type >= ARRAY_SIZE(domain_to_pl)))
return;
type = domain_to_pl[type];
} else {
type = res->mem_type;
}
obj = &bo->tbo.base;
shared = drm_gem_object_is_shared_for_memory_stats(obj);
switch (res->mem_type) {
/* Squash some into 'cpu' to keep the legacy userspace view. */
switch (type) {
case TTM_PL_VRAM:
stats->vram += size;
if (amdgpu_res_cpu_visible(adev, res))
stats->visible_vram += size;
if (shared)
stats->vram_shared += size;
break;
case TTM_PL_TT:
stats->gtt += size;
if (shared)
stats->gtt_shared += size;
break;
case TTM_PL_SYSTEM:
break;
default:
stats->cpu += size;
if (shared)
stats->cpu_shared += size;
type = TTM_PL_SYSTEM;
break;
}
if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) {
stats->requested_vram += size;
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
stats->requested_visible_vram += size;
if (drm_WARN_ON_ONCE(&adev->ddev, type >= sz))
return;
if (res->mem_type != TTM_PL_VRAM) {
stats->evicted_vram += size;
/* DRM stats common fields: */
stats[type].total += size;
if (drm_gem_object_is_shared_for_memory_stats(obj))
stats[type].drm.shared += size;
else
stats[type].drm.private += size;
if (res) {
stats[type].drm.resident += size;
if (!dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_BOOKKEEP))
stats[type].drm.active += size;
else if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE)
stats[type].drm.purgeable += size;
if (type == TTM_PL_VRAM && amdgpu_res_cpu_visible(adev, res))
stats[type].visible += size;
}
/* amdgpu specific stats: */
if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) {
stats[TTM_PL_VRAM].requested += size;
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
stats[TTM_PL_VRAM].requested_visible += size;
if (type != TTM_PL_VRAM) {
stats[TTM_PL_VRAM].evicted += size;
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
stats->evicted_visible_vram += size;
stats[TTM_PL_VRAM].evicted_visible += size;
}
} else if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_GTT) {
stats->requested_gtt += size;
stats[TTM_PL_TT].requested += size;
}
}

View File

@ -140,30 +140,14 @@ struct amdgpu_bo_vm {
};
struct amdgpu_mem_stats {
/* current VRAM usage, includes visible VRAM */
uint64_t vram;
/* current shared VRAM usage, includes visible VRAM */
uint64_t vram_shared;
/* current visible VRAM usage */
uint64_t visible_vram;
/* current GTT usage */
uint64_t gtt;
/* current shared GTT usage */
uint64_t gtt_shared;
/* current system memory usage */
uint64_t cpu;
/* current shared system memory usage */
uint64_t cpu_shared;
/* sum of evicted buffers, includes visible VRAM */
uint64_t evicted_vram;
/* sum of evicted buffers due to CPU access */
uint64_t evicted_visible_vram;
/* how much userspace asked for, includes vis.VRAM */
uint64_t requested_vram;
/* how much userspace asked for */
uint64_t requested_visible_vram;
/* how much userspace asked for */
uint64_t requested_gtt;
struct drm_memory_stats drm;
uint64_t total;
uint64_t visible;
uint64_t evicted;
uint64_t evicted_visible;
uint64_t requested;
uint64_t requested_visible;
};
static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo)
@ -328,7 +312,8 @@ int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
struct amdgpu_mem_stats *stats);
struct amdgpu_mem_stats *stats,
unsigned int size);
uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
uint32_t domain);

View File

@ -159,9 +159,9 @@ static int psp_init_sriov_microcode(struct psp_context *psp)
return ret;
}
static int psp_early_init(void *handle)
static int psp_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
psp->autoload_supported = true;
@ -421,9 +421,9 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
return ret;
}
static int psp_sw_init(void *handle)
static int psp_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
int ret;
struct psp_runtime_boot_cfg_entry boot_cfg_entry;
@ -527,9 +527,9 @@ static int psp_sw_init(void *handle)
return ret;
}
static int psp_sw_fini(void *handle)
static int psp_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
struct psp_gfx_cmd_resp *cmd = psp->cmd;
@ -639,6 +639,8 @@ static const char *psp_gfx_cmd_name(enum psp_gfx_cmd_id cmd_id)
return "AUTOLOAD_RLC";
case GFX_CMD_ID_BOOT_CFG:
return "BOOT_CFG";
case GFX_CMD_ID_CONFIG_SQ_PERFMON:
return "CONFIG_SQ_PERFMON";
default:
return "UNKNOWN CMD";
}
@ -1043,6 +1045,31 @@ static int psp_rl_load(struct amdgpu_device *adev)
return ret;
}
int psp_memory_partition(struct psp_context *psp, int mode)
{
struct psp_gfx_cmd_resp *cmd;
int ret;
if (amdgpu_sriov_vf(psp->adev))
return 0;
cmd = acquire_psp_cmd_buf(psp);
cmd->cmd_id = GFX_CMD_ID_FB_NPS_MODE;
cmd->cmd.cmd_memory_part.mode = mode;
dev_info(psp->adev->dev,
"Requesting %d memory partition change through PSP", mode);
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
if (ret)
dev_err(psp->adev->dev,
"PSP request failed to change to NPS%d mode\n", mode);
release_psp_cmd_buf(psp);
return ret;
}
int psp_spatial_partition(struct psp_context *psp, int mode)
{
struct psp_gfx_cmd_resp *cmd;
@ -2264,6 +2291,19 @@ bool amdgpu_psp_get_ras_capability(struct psp_context *psp)
}
}
bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev)
{
struct psp_context *psp = &adev->psp;
if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
return false;
if (psp->funcs && psp->funcs->is_reload_needed)
return psp->funcs->is_reload_needed(psp);
return false;
}
static int psp_hw_start(struct psp_context *psp)
{
struct amdgpu_device *adev = psp->adev;
@ -2958,10 +2998,10 @@ static int psp_load_fw(struct amdgpu_device *adev)
return ret;
}
static int psp_hw_init(void *handle)
static int psp_hw_init(struct amdgpu_ip_block *ip_block)
{
int ret;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
mutex_lock(&adev->firmware.mutex);
/*
@ -2987,9 +3027,9 @@ static int psp_hw_init(void *handle)
return -EINVAL;
}
static int psp_hw_fini(void *handle)
static int psp_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
if (psp->ta_fw) {
@ -3011,10 +3051,10 @@ static int psp_hw_fini(void *handle)
return 0;
}
static int psp_suspend(void *handle)
static int psp_suspend(struct amdgpu_ip_block *ip_block)
{
int ret = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
if (adev->gmc.xgmi.num_physical_nodes > 1 &&
@ -3074,10 +3114,10 @@ static int psp_suspend(void *handle)
return ret;
}
static int psp_resume(void *handle)
static int psp_resume(struct amdgpu_ip_block *ip_block)
{
int ret;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct psp_context *psp = &adev->psp;
dev_info(adev->dev, "PSP is resuming...\n");
@ -3736,8 +3776,44 @@ int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
return err;
}
int psp_config_sq_perfmon(struct psp_context *psp,
uint32_t xcp_id, bool core_override_enable,
bool reg_override_enable, bool perfmon_override_enable)
{
int ret;
if (amdgpu_sriov_vf(psp->adev))
return 0;
if (xcp_id > MAX_XCP) {
dev_err(psp->adev->dev, "invalid xcp_id %d\n", xcp_id);
return -EINVAL;
}
if (amdgpu_ip_version(psp->adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6)) {
dev_err(psp->adev->dev, "Unsupported MP0 version 0x%x for CONFIG_SQ_PERFMON command\n",
amdgpu_ip_version(psp->adev, MP0_HWIP, 0));
return -EINVAL;
}
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
cmd->cmd_id = GFX_CMD_ID_CONFIG_SQ_PERFMON;
cmd->cmd.config_sq_perfmon.gfx_xcp_mask = BIT_MASK(xcp_id);
cmd->cmd.config_sq_perfmon.core_override = core_override_enable;
cmd->cmd.config_sq_perfmon.reg_override = reg_override_enable;
cmd->cmd.config_sq_perfmon.perfmon_override = perfmon_override_enable;
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
if (ret)
dev_warn(psp->adev->dev, "PSP failed to config sq: xcp%d core%d reg%d perfmon%d\n",
xcp_id, core_override_enable, reg_override_enable, perfmon_override_enable);
release_psp_cmd_buf(psp);
return ret;
}
static int psp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
enum amd_clockgating_state state)
{
return 0;
}
@ -4019,17 +4095,12 @@ const struct attribute_group amdgpu_flash_attr_group = {
const struct amd_ip_funcs psp_ip_funcs = {
.name = "psp",
.early_init = psp_early_init,
.late_init = NULL,
.sw_init = psp_sw_init,
.sw_fini = psp_sw_fini,
.hw_init = psp_hw_init,
.hw_fini = psp_hw_fini,
.suspend = psp_suspend,
.resume = psp_resume,
.is_idle = NULL,
.check_soft_reset = NULL,
.wait_for_idle = NULL,
.soft_reset = NULL,
.set_clockgating_state = psp_set_clockgating_state,
.set_powergating_state = psp_set_powergating_state,
};

View File

@ -139,6 +139,7 @@ struct psp_funcs {
int (*fatal_error_recovery_quirk)(struct psp_context *psp);
bool (*get_ras_capability)(struct psp_context *psp);
bool (*is_aux_sos_load_required)(struct psp_context *psp);
bool (*is_reload_needed)(struct psp_context *psp);
};
struct ta_funcs {
@ -552,9 +553,15 @@ int psp_load_fw_list(struct psp_context *psp,
void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);
int psp_spatial_partition(struct psp_context *psp, int mode);
int psp_memory_partition(struct psp_context *psp, int mode);
int is_psp_fw_valid(struct psp_bin_desc bin);
int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev);
bool amdgpu_psp_get_ras_capability(struct psp_context *psp);
int psp_config_sq_perfmon(struct psp_context *psp, uint32_t xcp_id,
bool core_override_enable, bool reg_override_enable, bool perfmon_override_enable);
bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev);
#endif

View File

@ -3146,7 +3146,42 @@ static int amdgpu_ras_page_retirement_thread(void *param)
return 0;
}
int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev)
{
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
int ret;
if (!con || amdgpu_sriov_vf(adev))
return 0;
ret = amdgpu_ras_eeprom_init(&con->eeprom_control);
if (ret)
return ret;
/* HW not usable */
if (amdgpu_ras_is_rma(adev))
return -EHWPOISON;
if (con->eeprom_control.ras_num_recs) {
ret = amdgpu_ras_load_bad_pages(adev);
if (ret)
return ret;
amdgpu_dpm_send_hbm_bad_pages_num(
adev, con->eeprom_control.ras_num_recs);
if (con->update_channel_flag == true) {
amdgpu_dpm_send_hbm_bad_channel_flag(
adev, con->eeprom_control.bad_channel_bitmap);
con->update_channel_flag = false;
}
}
return ret;
}
int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info)
{
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
struct ras_err_handler_data **data;
@ -3181,31 +3216,10 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
max_eeprom_records_count = amdgpu_ras_eeprom_max_record_count(&con->eeprom_control);
amdgpu_ras_validate_threshold(adev, max_eeprom_records_count);
/* Todo: During test the SMU might fail to read the eeprom through I2C
* when the GPU is pending on XGMI reset during probe time
* (Mostly after second bus reset), skip it now
*/
if (adev->gmc.xgmi.pending_reset)
return 0;
ret = amdgpu_ras_eeprom_init(&con->eeprom_control);
/*
* This calling fails when is_rma is true or
* ret != 0.
*/
if (amdgpu_ras_is_rma(adev) || ret)
goto free;
if (con->eeprom_control.ras_num_recs) {
ret = amdgpu_ras_load_bad_pages(adev);
if (init_bp_info) {
ret = amdgpu_ras_init_badpage_info(adev);
if (ret)
goto free;
amdgpu_dpm_send_hbm_bad_pages_num(adev, con->eeprom_control.ras_num_recs);
if (con->update_channel_flag == true) {
amdgpu_dpm_send_hbm_bad_channel_flag(adev, con->eeprom_control.bad_channel_bitmap);
con->update_channel_flag = false;
}
}
mutex_init(&con->page_rsv_lock);
@ -4294,8 +4308,27 @@ int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
ras->gpu_reset_flags |= AMDGPU_RAS_GPU_RESET_MODE1_RESET;
}
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0) {
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
int hive_ras_recovery = 0;
if (hive) {
hive_ras_recovery = atomic_read(&hive->ras_recovery);
amdgpu_put_xgmi_hive(hive);
}
/* In the case of multiple GPUs, after a GPU has started
* resetting all GPUs on hive, other GPUs do not need to
* trigger GPU reset again.
*/
if (!hive_ras_recovery)
amdgpu_reset_domain_schedule(ras->adev->reset_domain, &ras->recovery_work);
else
atomic_set(&ras->in_recovery, 0);
} else {
flush_work(&ras->recovery_work);
amdgpu_reset_domain_schedule(ras->adev->reset_domain, &ras->recovery_work);
}
return 0;
}

View File

@ -736,8 +736,8 @@ struct amdgpu_ras_block_hw_ops {
* 8: feature disable
*/
int amdgpu_ras_recovery_init(struct amdgpu_device *adev);
int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev);
int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info);
void amdgpu_ras_resume(struct amdgpu_device *adev);
void amdgpu_ras_suspend(struct amdgpu_device *adev);

View File

@ -26,6 +26,156 @@
#include "sienna_cichlid.h"
#include "smu_v13_0_10.h"
static int amdgpu_reset_xgmi_reset_on_init_suspend(struct amdgpu_device *adev)
{
int i;
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (!adev->ip_blocks[i].status.hw)
continue;
/* displays are handled in phase1 */
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)
continue;
/* XXX handle errors */
amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
adev->ip_blocks[i].status.hw = false;
}
/* VCN FW shared region is in frambuffer, there are some flags
* initialized in that region during sw_init. Make sure the region is
* backed up.
*/
amdgpu_vcn_save_vcpu_bo(adev);
return 0;
}
static int amdgpu_reset_xgmi_reset_on_init_prep_hwctxt(
struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
struct list_head *reset_device_list = reset_context->reset_device_list;
struct amdgpu_device *tmp_adev;
int r;
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
amdgpu_unregister_gpu_instance(tmp_adev);
r = amdgpu_reset_xgmi_reset_on_init_suspend(tmp_adev);
if (r) {
dev_err(tmp_adev->dev,
"xgmi reset on init: prepare for reset failed");
return r;
}
}
return r;
}
static int amdgpu_reset_xgmi_reset_on_init_restore_hwctxt(
struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
struct list_head *reset_device_list = reset_context->reset_device_list;
struct amdgpu_device *tmp_adev = NULL;
int r;
r = amdgpu_device_reinit_after_reset(reset_context);
if (r)
return r;
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
if (!tmp_adev->kfd.init_complete) {
kgd2kfd_init_zone_device(tmp_adev);
amdgpu_amdkfd_device_init(tmp_adev);
amdgpu_amdkfd_drm_client_create(tmp_adev);
}
}
return r;
}
static int amdgpu_reset_xgmi_reset_on_init_perform_reset(
struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
struct list_head *reset_device_list = reset_context->reset_device_list;
struct amdgpu_device *tmp_adev = NULL;
int r;
dev_dbg(adev->dev, "xgmi roi - hw reset\n");
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
mutex_lock(&tmp_adev->reset_cntl->reset_lock);
tmp_adev->reset_cntl->active_reset =
amdgpu_asic_reset_method(adev);
}
r = 0;
/* Mode1 reset needs to be triggered on all devices together */
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (!queue_work(system_unbound_wq, &tmp_adev->xgmi_reset_work))
r = -EALREADY;
if (r) {
dev_err(tmp_adev->dev,
"xgmi reset on init: reset failed with error, %d",
r);
break;
}
}
/* For XGMI wait for all resets to complete before proceed */
if (!r) {
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
flush_work(&tmp_adev->xgmi_reset_work);
r = tmp_adev->asic_reset_res;
if (r)
break;
}
}
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
mutex_unlock(&tmp_adev->reset_cntl->reset_lock);
tmp_adev->reset_cntl->active_reset = AMD_RESET_METHOD_NONE;
}
return r;
}
int amdgpu_reset_do_xgmi_reset_on_init(
struct amdgpu_reset_context *reset_context)
{
struct list_head *reset_device_list = reset_context->reset_device_list;
struct amdgpu_device *adev;
int r;
if (!reset_device_list || list_empty(reset_device_list) ||
list_is_singular(reset_device_list))
return -EINVAL;
adev = list_first_entry(reset_device_list, struct amdgpu_device,
reset_list);
r = amdgpu_reset_prepare_hwcontext(adev, reset_context);
if (r)
return r;
r = amdgpu_reset_perform_reset(adev, reset_context);
return r;
}
struct amdgpu_reset_handler xgmi_reset_on_init_handler = {
.reset_method = AMD_RESET_METHOD_ON_INIT,
.prepare_env = NULL,
.prepare_hwcontext = amdgpu_reset_xgmi_reset_on_init_prep_hwctxt,
.perform_reset = amdgpu_reset_xgmi_reset_on_init_perform_reset,
.restore_hwcontext = amdgpu_reset_xgmi_reset_on_init_restore_hwctxt,
.restore_env = NULL,
.do_reset = NULL,
};
int amdgpu_reset_init(struct amdgpu_device *adev)
{
int ret = 0;

View File

@ -153,4 +153,9 @@ void amdgpu_reset_get_desc(struct amdgpu_reset_context *rst_ctxt, char *buf,
for (i = 0; (i < AMDGPU_RESET_MAX_HANDLERS) && \
(handler = (*reset_ctl->reset_handlers)[i]); \
++i)
extern struct amdgpu_reset_handler xgmi_reset_on_init_handler;
int amdgpu_reset_do_xgmi_reset_on_init(
struct amdgpu_reset_context *reset_context);
#endif

View File

@ -108,10 +108,26 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw)
*/
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
{
int i;
uint32_t occupied, chunk1, chunk2;
uint32_t *dst;
for (i = 0; i < count; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
occupied = ring->wptr & ring->buf_mask;
dst = (void *)&ring->ring[occupied];
chunk1 = ring->buf_mask + 1 - occupied;
chunk1 = (chunk1 >= count) ? count : chunk1;
chunk2 = count - chunk1;
if (chunk1)
memset32(dst, ring->funcs->nop, chunk1);
if (chunk2) {
dst = (void *)ring->ring;
memset32(dst, ring->funcs->nop, chunk2);
}
ring->wptr += count;
ring->wptr &= ring->ptr_mask;
ring->count_dw -= count;
}
/**
@ -141,6 +157,9 @@ 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");
/* We pad to match fetch size */
count = ring->funcs->align_mask + 1 -
(ring->wptr & ring->funcs->align_mask);

View File

@ -377,8 +377,6 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
{
if (ring->count_dw <= 0)
DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
ring->ring[ring->wptr++ & ring->buf_mask] = v;
ring->wptr &= ring->ptr_mask;
ring->count_dw--;
@ -390,9 +388,6 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring,
unsigned occupied, chunk1, chunk2;
void *dst;
if (unlikely(ring->count_dw < count_dw))
DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
occupied = ring->wptr & ring->buf_mask;
dst = (void *)&ring->ring[occupied];
chunk1 = ring->buf_mask + 1 - occupied;

View File

@ -812,7 +812,7 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_device *bdev,
/* Map SG to device */
r = dma_map_sgtable(adev->dev, ttm->sg, direction, 0);
if (r)
goto release_sg;
goto release_sg_table;
/* convert SG to linear array of pages and dma addresses */
drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address,
@ -820,6 +820,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_device *bdev,
return 0;
release_sg_table:
sg_free_table(ttm->sg);
release_sg:
kfree(ttm->sg);
ttm->sg = NULL;

View File

@ -34,6 +34,7 @@
#define AMDGPU_PL_OA (TTM_PL_PRIV + 2)
#define AMDGPU_PL_PREEMPT (TTM_PL_PRIV + 3)
#define AMDGPU_PL_DOORBELL (TTM_PL_PRIV + 4)
#define __AMDGPU_PL_LAST (TTM_PL_PRIV + 4)
#define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2

View File

@ -765,9 +765,9 @@ static int umsch_mm_init(struct amdgpu_device *adev)
}
static int umsch_mm_early_init(void *handle)
static int umsch_mm_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
case IP_VERSION(4, 0, 5):
@ -784,9 +784,9 @@ static int umsch_mm_early_init(void *handle)
return 0;
}
static int umsch_mm_late_init(void *handle)
static int umsch_mm_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend)
return 0;
@ -794,9 +794,9 @@ static int umsch_mm_late_init(void *handle)
return umsch_mm_test(adev);
}
static int umsch_mm_sw_init(void *handle)
static int umsch_mm_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = umsch_mm_init(adev);
@ -815,9 +815,9 @@ static int umsch_mm_sw_init(void *handle)
return 0;
}
static int umsch_mm_sw_fini(void *handle)
static int umsch_mm_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
release_firmware(adev->umsch_mm.fw);
adev->umsch_mm.fw = NULL;
@ -839,9 +839,9 @@ static int umsch_mm_sw_fini(void *handle)
return 0;
}
static int umsch_mm_hw_init(void *handle)
static int umsch_mm_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = umsch_mm_load_microcode(&adev->umsch_mm);
@ -857,9 +857,9 @@ static int umsch_mm_hw_init(void *handle)
return 0;
}
static int umsch_mm_hw_fini(void *handle)
static int umsch_mm_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
umsch_mm_ring_stop(&adev->umsch_mm);
@ -873,18 +873,14 @@ static int umsch_mm_hw_fini(void *handle)
return 0;
}
static int umsch_mm_suspend(void *handle)
static int umsch_mm_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return umsch_mm_hw_fini(adev);
return umsch_mm_hw_fini(ip_block);
}
static int umsch_mm_resume(void *handle)
static int umsch_mm_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return umsch_mm_hw_init(adev);
return umsch_mm_hw_init(ip_block);
}
void amdgpu_umsch_fwlog_init(struct amdgpu_umsch_mm *umsch_mm)
@ -997,8 +993,6 @@ static const struct amd_ip_funcs umsch_mm_v4_0_ip_funcs = {
.hw_fini = umsch_mm_hw_fini,
.suspend = umsch_mm_suspend,
.resume = umsch_mm_resume,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
const struct amdgpu_ip_block_version umsch_mm_v4_0_ip_block = {

View File

@ -294,21 +294,12 @@ bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type t
return ret;
}
int amdgpu_vcn_suspend(struct amdgpu_device *adev)
int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev)
{
unsigned int size;
void *ptr;
int i, idx;
bool in_ras_intr = amdgpu_ras_intr_triggered();
cancel_delayed_work_sync(&adev->vcn.idle_work);
/* err_event_athub will corrupt VCPU buffer, so we need to
* restore fw data and clear buffer in amdgpu_vcn_resume() */
if (in_ras_intr)
return 0;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
continue;
@ -327,9 +318,24 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
drm_dev_exit(idx);
}
}
return 0;
}
int amdgpu_vcn_suspend(struct amdgpu_device *adev)
{
bool in_ras_intr = amdgpu_ras_intr_triggered();
cancel_delayed_work_sync(&adev->vcn.idle_work);
/* err_event_athub will corrupt VCPU buffer, so we need to
* restore fw data and clear buffer in amdgpu_vcn_resume() */
if (in_ras_intr)
return 0;
return amdgpu_vcn_save_vcpu_bo(adev);
}
int amdgpu_vcn_resume(struct amdgpu_device *adev)
{
unsigned int size;

View File

@ -518,5 +518,6 @@ int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev);
int amdgpu_vcn_psp_update_sram(struct amdgpu_device *adev, int inst_idx,
enum AMDGPU_UCODE_ID ucode_id);
int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev);
#endif

View File

@ -493,10 +493,10 @@ const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
static int amdgpu_vkms_sw_init(void *handle)
static int amdgpu_vkms_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc,
sizeof(struct amdgpu_vkms_output), GFP_KERNEL);
@ -536,9 +536,9 @@ static int amdgpu_vkms_sw_init(void *handle)
return 0;
}
static int amdgpu_vkms_sw_fini(void *handle)
static int amdgpu_vkms_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i = 0;
for (i = 0; i < adev->mode_info.num_crtc; i++)
@ -555,9 +555,9 @@ static int amdgpu_vkms_sw_fini(void *handle)
return 0;
}
static int amdgpu_vkms_hw_init(void *handle)
static int amdgpu_vkms_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_SI
@ -600,31 +600,31 @@ static int amdgpu_vkms_hw_init(void *handle)
return 0;
}
static int amdgpu_vkms_hw_fini(void *handle)
static int amdgpu_vkms_hw_fini(struct amdgpu_ip_block *ip_block)
{
return 0;
}
static int amdgpu_vkms_suspend(void *handle)
static int amdgpu_vkms_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = drm_mode_config_helper_suspend(adev_to_drm(adev));
if (r)
return r;
return amdgpu_vkms_hw_fini(handle);
return 0;
}
static int amdgpu_vkms_resume(void *handle)
static int amdgpu_vkms_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = amdgpu_vkms_hw_init(handle);
r = amdgpu_vkms_hw_init(ip_block);
if (r)
return r;
return drm_mode_config_helper_resume(adev_to_drm(adev));
return drm_mode_config_helper_resume(adev_to_drm(ip_block->adev));
}
static bool amdgpu_vkms_is_idle(void *handle)
@ -632,16 +632,6 @@ static bool amdgpu_vkms_is_idle(void *handle)
return true;
}
static int amdgpu_vkms_wait_for_idle(void *handle)
{
return 0;
}
static int amdgpu_vkms_soft_reset(void *handle)
{
return 0;
}
static int amdgpu_vkms_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -656,8 +646,6 @@ static int amdgpu_vkms_set_powergating_state(void *handle,
static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
.name = "amdgpu_vkms",
.early_init = NULL,
.late_init = NULL,
.sw_init = amdgpu_vkms_sw_init,
.sw_fini = amdgpu_vkms_sw_fini,
.hw_init = amdgpu_vkms_hw_init,
@ -665,12 +653,8 @@ static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
.suspend = amdgpu_vkms_suspend,
.resume = amdgpu_vkms_resume,
.is_idle = amdgpu_vkms_is_idle,
.wait_for_idle = amdgpu_vkms_wait_for_idle,
.soft_reset = amdgpu_vkms_soft_reset,
.set_clockgating_state = amdgpu_vkms_set_clockgating_state,
.set_powergating_state = amdgpu_vkms_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
const struct amdgpu_ip_block_version amdgpu_vkms_ip_block = {

View File

@ -1083,7 +1083,8 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
}
static void amdgpu_vm_bo_get_memory(struct amdgpu_bo_va *bo_va,
struct amdgpu_mem_stats *stats)
struct amdgpu_mem_stats *stats,
unsigned int size)
{
struct amdgpu_vm *vm = bo_va->base.vm;
struct amdgpu_bo *bo = bo_va->base.bo;
@ -1099,34 +1100,35 @@ static void amdgpu_vm_bo_get_memory(struct amdgpu_bo_va *bo_va,
!dma_resv_trylock(bo->tbo.base.resv))
return;
amdgpu_bo_get_memory(bo, stats);
amdgpu_bo_get_memory(bo, stats, size);
if (!amdgpu_vm_is_bo_always_valid(vm, bo))
dma_resv_unlock(bo->tbo.base.resv);
}
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
struct amdgpu_mem_stats *stats)
struct amdgpu_mem_stats *stats,
unsigned int size)
{
struct amdgpu_bo_va *bo_va, *tmp;
spin_lock(&vm->status_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status)
amdgpu_vm_bo_get_memory(bo_va, stats);
amdgpu_vm_bo_get_memory(bo_va, stats, size);
spin_unlock(&vm->status_lock);
}

View File

@ -567,7 +567,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
struct amdgpu_vm *vm);
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
struct amdgpu_mem_stats *stats);
struct amdgpu_mem_stats *stats,
unsigned int size);
int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_vm *vmbo, bool immediate);

View File

@ -295,9 +295,9 @@ int amdgpu_vpe_ring_fini(struct amdgpu_vpe *vpe)
return 0;
}
static int vpe_early_init(void *handle)
static int vpe_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_vpe *vpe = &adev->vpe;
switch (amdgpu_ip_version(adev, VPE_HWIP, 0)) {
@ -356,9 +356,9 @@ static int vpe_common_init(struct amdgpu_vpe *vpe)
return 0;
}
static int vpe_sw_init(void *handle)
static int vpe_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_vpe *vpe = &adev->vpe;
int ret;
@ -381,9 +381,9 @@ static int vpe_sw_init(void *handle)
return ret;
}
static int vpe_sw_fini(void *handle)
static int vpe_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_vpe *vpe = &adev->vpe;
release_firmware(vpe->fw);
@ -398,9 +398,9 @@ static int vpe_sw_fini(void *handle)
return 0;
}
static int vpe_hw_init(void *handle)
static int vpe_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_vpe *vpe = &adev->vpe;
int ret;
@ -421,9 +421,9 @@ static int vpe_hw_init(void *handle)
return 0;
}
static int vpe_hw_fini(void *handle)
static int vpe_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_vpe *vpe = &adev->vpe;
vpe_ring_stop(vpe);
@ -434,20 +434,18 @@ static int vpe_hw_fini(void *handle)
return 0;
}
static int vpe_suspend(void *handle)
static int vpe_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
cancel_delayed_work_sync(&adev->vpe.idle_work);
return vpe_hw_fini(adev);
return vpe_hw_fini(ip_block);
}
static int vpe_resume(void *handle)
static int vpe_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return vpe_hw_init(adev);
return vpe_hw_init(ip_block);
}
static void vpe_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
@ -908,14 +906,12 @@ static void vpe_set_ring_funcs(struct amdgpu_device *adev)
const struct amd_ip_funcs vpe_ip_funcs = {
.name = "vpe_v6_1",
.early_init = vpe_early_init,
.late_init = NULL,
.sw_init = vpe_sw_init,
.sw_fini = vpe_sw_fini,
.hw_init = vpe_hw_init,
.hw_fini = vpe_hw_fini,
.suspend = vpe_suspend,
.resume = vpe_resume,
.soft_reset = NULL,
.set_clockgating_state = vpe_set_clockgating_state,
.set_powergating_state = vpe_set_powergating_state,
};

View File

@ -433,3 +433,246 @@ void amdgpu_xcp_release_sched(struct amdgpu_device *adev,
}
}
#define XCP_CFG_SYSFS_RES_ATTR_SHOW(_name) \
static ssize_t amdgpu_xcp_res_sysfs_##_name##_show( \
struct amdgpu_xcp_res_details *xcp_res, char *buf) \
{ \
return sysfs_emit(buf, "%d\n", xcp_res->_name); \
}
struct amdgpu_xcp_res_sysfs_attribute {
struct attribute attr;
ssize_t (*show)(struct amdgpu_xcp_res_details *xcp_res, char *buf);
};
#define XCP_CFG_SYSFS_RES_ATTR(_name) \
struct amdgpu_xcp_res_sysfs_attribute xcp_res_sysfs_attr_##_name = { \
.attr = { .name = __stringify(_name), .mode = 0400 }, \
.show = amdgpu_xcp_res_sysfs_##_name##_show, \
}
XCP_CFG_SYSFS_RES_ATTR_SHOW(num_inst)
XCP_CFG_SYSFS_RES_ATTR(num_inst);
XCP_CFG_SYSFS_RES_ATTR_SHOW(num_shared)
XCP_CFG_SYSFS_RES_ATTR(num_shared);
#define XCP_CFG_SYSFS_RES_ATTR_PTR(_name) xcp_res_sysfs_attr_##_name.attr
static struct attribute *xcp_cfg_res_sysfs_attrs[] = {
&XCP_CFG_SYSFS_RES_ATTR_PTR(num_inst),
&XCP_CFG_SYSFS_RES_ATTR_PTR(num_shared), NULL
};
static const char *xcp_desc[] = {
[AMDGPU_SPX_PARTITION_MODE] = "SPX",
[AMDGPU_DPX_PARTITION_MODE] = "DPX",
[AMDGPU_TPX_PARTITION_MODE] = "TPX",
[AMDGPU_QPX_PARTITION_MODE] = "QPX",
[AMDGPU_CPX_PARTITION_MODE] = "CPX",
};
ATTRIBUTE_GROUPS(xcp_cfg_res_sysfs);
#define to_xcp_attr(x) \
container_of(x, struct amdgpu_xcp_res_sysfs_attribute, attr)
#define to_xcp_res(x) container_of(x, struct amdgpu_xcp_res_details, kobj)
static ssize_t xcp_cfg_res_sysfs_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
struct amdgpu_xcp_res_sysfs_attribute *attribute;
struct amdgpu_xcp_res_details *xcp_res;
attribute = to_xcp_attr(attr);
xcp_res = to_xcp_res(kobj);
if (!attribute->show)
return -EIO;
return attribute->show(xcp_res, buf);
}
static const struct sysfs_ops xcp_cfg_res_sysfs_ops = {
.show = xcp_cfg_res_sysfs_attr_show,
};
static const struct kobj_type xcp_cfg_res_sysfs_ktype = {
.sysfs_ops = &xcp_cfg_res_sysfs_ops,
.default_groups = xcp_cfg_res_sysfs_groups,
};
const char *xcp_res_names[] = {
[AMDGPU_XCP_RES_XCC] = "xcc",
[AMDGPU_XCP_RES_DMA] = "dma",
[AMDGPU_XCP_RES_DEC] = "dec",
[AMDGPU_XCP_RES_JPEG] = "jpeg",
};
static int amdgpu_xcp_get_res_info(struct amdgpu_xcp_mgr *xcp_mgr,
int mode,
struct amdgpu_xcp_cfg *xcp_cfg)
{
if (xcp_mgr->funcs && xcp_mgr->funcs->get_xcp_res_info)
return xcp_mgr->funcs->get_xcp_res_info(xcp_mgr, mode, xcp_cfg);
return -EOPNOTSUPP;
}
#define to_xcp_cfg(x) container_of(x, struct amdgpu_xcp_cfg, kobj)
static ssize_t supported_xcp_configs_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct amdgpu_xcp_cfg *xcp_cfg = to_xcp_cfg(kobj);
struct amdgpu_xcp_mgr *xcp_mgr = xcp_cfg->xcp_mgr;
int size = 0, mode;
char *sep = "";
if (!xcp_mgr || !xcp_mgr->supp_xcp_modes)
return sysfs_emit(buf, "Not supported\n");
for_each_inst(mode, xcp_mgr->supp_xcp_modes) {
size += sysfs_emit_at(buf, size, "%s%s", sep, xcp_desc[mode]);
sep = ", ";
}
size += sysfs_emit_at(buf, size, "\n");
return size;
}
static ssize_t xcp_config_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct amdgpu_xcp_cfg *xcp_cfg = to_xcp_cfg(kobj);
return sysfs_emit(buf, "%s\n",
amdgpu_gfx_compute_mode_desc(xcp_cfg->mode));
}
static ssize_t xcp_config_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t size)
{
struct amdgpu_xcp_cfg *xcp_cfg = to_xcp_cfg(kobj);
int mode, r;
if (!strncasecmp("SPX", buf, strlen("SPX")))
mode = AMDGPU_SPX_PARTITION_MODE;
else if (!strncasecmp("DPX", buf, strlen("DPX")))
mode = AMDGPU_DPX_PARTITION_MODE;
else if (!strncasecmp("TPX", buf, strlen("TPX")))
mode = AMDGPU_TPX_PARTITION_MODE;
else if (!strncasecmp("QPX", buf, strlen("QPX")))
mode = AMDGPU_QPX_PARTITION_MODE;
else if (!strncasecmp("CPX", buf, strlen("CPX")))
mode = AMDGPU_CPX_PARTITION_MODE;
else
return -EINVAL;
r = amdgpu_xcp_get_res_info(xcp_cfg->xcp_mgr, mode, xcp_cfg);
if (r)
return r;
xcp_cfg->mode = mode;
return size;
}
static struct kobj_attribute xcp_cfg_sysfs_mode =
__ATTR_RW_MODE(xcp_config, 0644);
static void xcp_cfg_sysfs_release(struct kobject *kobj)
{
struct amdgpu_xcp_cfg *xcp_cfg = to_xcp_cfg(kobj);
kfree(xcp_cfg);
}
static const struct kobj_type xcp_cfg_sysfs_ktype = {
.release = xcp_cfg_sysfs_release,
.sysfs_ops = &kobj_sysfs_ops,
};
static struct kobj_attribute supp_part_sysfs_mode =
__ATTR_RO(supported_xcp_configs);
static const struct attribute *xcp_attrs[] = {
&supp_part_sysfs_mode.attr,
&xcp_cfg_sysfs_mode.attr,
NULL,
};
void amdgpu_xcp_cfg_sysfs_init(struct amdgpu_device *adev)
{
struct amdgpu_xcp_res_details *xcp_res;
struct amdgpu_xcp_cfg *xcp_cfg;
int i, r, j, rid, mode;
if (!adev->xcp_mgr)
return;
xcp_cfg = kzalloc(sizeof(*xcp_cfg), GFP_KERNEL);
if (!xcp_cfg)
return;
xcp_cfg->xcp_mgr = adev->xcp_mgr;
r = kobject_init_and_add(&xcp_cfg->kobj, &xcp_cfg_sysfs_ktype,
&adev->dev->kobj, "compute_partition_config");
if (r)
goto err1;
r = sysfs_create_files(&xcp_cfg->kobj, xcp_attrs);
if (r)
goto err1;
mode = (xcp_cfg->xcp_mgr->mode ==
AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) ?
AMDGPU_SPX_PARTITION_MODE :
xcp_cfg->xcp_mgr->mode;
r = amdgpu_xcp_get_res_info(xcp_cfg->xcp_mgr, mode, xcp_cfg);
if (r)
goto err1;
xcp_cfg->mode = mode;
for (i = 0; i < xcp_cfg->num_res; i++) {
xcp_res = &xcp_cfg->xcp_res[i];
rid = xcp_res->id;
r = kobject_init_and_add(&xcp_res->kobj,
&xcp_cfg_res_sysfs_ktype,
&xcp_cfg->kobj, "%s",
xcp_res_names[rid]);
if (r)
goto err;
}
adev->xcp_mgr->xcp_cfg = xcp_cfg;
return;
err:
for (j = 0; j < i; j++) {
xcp_res = &xcp_cfg->xcp_res[i];
kobject_put(&xcp_res->kobj);
}
sysfs_remove_files(&xcp_cfg->kobj, xcp_attrs);
err1:
kobject_put(&xcp_cfg->kobj);
}
void amdgpu_xcp_cfg_sysfs_fini(struct amdgpu_device *adev)
{
struct amdgpu_xcp_res_details *xcp_res;
struct amdgpu_xcp_cfg *xcp_cfg;
int i;
if (!adev->xcp_mgr)
return;
xcp_cfg = adev->xcp_mgr->xcp_cfg;
for (i = 0; i < xcp_cfg->num_res; i++) {
xcp_res = &xcp_cfg->xcp_res[i];
kobject_put(&xcp_res->kobj);
}
sysfs_remove_files(&xcp_cfg->kobj, xcp_attrs);
kobject_put(&xcp_cfg->kobj);
}

View File

@ -56,6 +56,29 @@ enum AMDGPU_XCP_STATE {
AMDGPU_XCP_RESUME,
};
enum amdgpu_xcp_res_id {
AMDGPU_XCP_RES_XCC,
AMDGPU_XCP_RES_DMA,
AMDGPU_XCP_RES_DEC,
AMDGPU_XCP_RES_JPEG,
AMDGPU_XCP_RES_MAX,
};
struct amdgpu_xcp_res_details {
enum amdgpu_xcp_res_id id;
u8 num_inst;
u8 num_shared;
struct kobject kobj;
};
struct amdgpu_xcp_cfg {
u8 mode;
struct amdgpu_xcp_res_details xcp_res[AMDGPU_XCP_RES_MAX];
u8 num_res;
struct amdgpu_xcp_mgr *xcp_mgr;
struct kobject kobj;
};
struct amdgpu_xcp_ip_funcs {
int (*prepare_suspend)(void *handle, uint32_t inst_mask);
int (*suspend)(void *handle, uint32_t inst_mask);
@ -97,6 +120,9 @@ struct amdgpu_xcp_mgr {
/* Used to determine KFD memory size limits per XCP */
unsigned int num_xcp_per_mem_partition;
struct amdgpu_xcp_cfg *xcp_cfg;
uint32_t supp_xcp_modes;
uint32_t avail_xcp_modes;
};
struct amdgpu_xcp_mgr_funcs {
@ -108,7 +134,9 @@ struct amdgpu_xcp_mgr_funcs {
struct amdgpu_xcp_ip *ip);
int (*get_xcp_mem_id)(struct amdgpu_xcp_mgr *xcp_mgr,
struct amdgpu_xcp *xcp, uint8_t *mem_id);
int (*get_xcp_res_info)(struct amdgpu_xcp_mgr *xcp_mgr,
int mode,
struct amdgpu_xcp_cfg *xcp_cfg);
int (*prepare_suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
int (*suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
int (*prepare_resume)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
@ -146,6 +174,9 @@ int amdgpu_xcp_open_device(struct amdgpu_device *adev,
void amdgpu_xcp_release_sched(struct amdgpu_device *adev,
struct amdgpu_ctx_entity *entity);
void amdgpu_xcp_cfg_sysfs_init(struct amdgpu_device *adev);
void amdgpu_xcp_cfg_sysfs_fini(struct amdgpu_device *adev);
#define amdgpu_xcp_select_scheds(adev, e, c, d, x, y) \
((adev)->xcp_mgr && (adev)->xcp_mgr->funcs && \
(adev)->xcp_mgr->funcs->select_scheds ? \

View File

@ -667,6 +667,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
task_barrier_init(&hive->tb);
hive->pstate = AMDGPU_XGMI_PSTATE_UNKNOWN;
hive->hi_req_gpu = NULL;
atomic_set(&hive->requested_nps_mode, UNKNOWN_MEMORY_PARTITION_MODE);
/*
* hive pstate on boot is high in vega20 so we have to go to low
@ -800,6 +801,23 @@ int amdgpu_xgmi_get_num_links(struct amdgpu_device *adev,
return -EINVAL;
}
bool amdgpu_xgmi_get_is_sharing_enabled(struct amdgpu_device *adev,
struct amdgpu_device *peer_adev)
{
struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info;
int i;
/* Sharing should always be enabled for non-SRIOV. */
if (!amdgpu_sriov_vf(adev))
return true;
for (i = 0 ; i < top->num_nodes; ++i)
if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id)
return !!top->nodes[i].is_sharing_enabled;
return false;
}
/*
* Devices that support extended data require the entire hive to initialize with
* the shared memory buffer flag set.
@ -860,8 +878,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
if (!adev->gmc.xgmi.supported)
return 0;
if (!adev->gmc.xgmi.pending_reset &&
amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
ret = psp_xgmi_initialize(&adev->psp, false, true);
if (ret) {
dev_err(adev->dev,
@ -907,8 +924,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
task_barrier_add_task(&hive->tb);
if (!adev->gmc.xgmi.pending_reset &&
amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
/* update node list for other device in the hive */
if (tmp_adev != adev) {
@ -985,7 +1001,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
}
}
if (!ret && !adev->gmc.xgmi.pending_reset)
if (!ret)
ret = amdgpu_xgmi_sysfs_add_dev_info(adev, hive);
exit_unlock:
@ -1500,3 +1516,117 @@ int amdgpu_xgmi_ras_sw_init(struct amdgpu_device *adev)
return 0;
}
static void amdgpu_xgmi_reset_on_init_work(struct work_struct *work)
{
struct amdgpu_hive_info *hive =
container_of(work, struct amdgpu_hive_info, reset_on_init_work);
struct amdgpu_reset_context reset_context;
struct amdgpu_device *tmp_adev;
struct list_head device_list;
int r;
mutex_lock(&hive->hive_lock);
INIT_LIST_HEAD(&device_list);
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
list_add_tail(&tmp_adev->reset_list, &device_list);
tmp_adev = list_first_entry(&device_list, struct amdgpu_device,
reset_list);
amdgpu_device_lock_reset_domain(tmp_adev->reset_domain);
reset_context.method = AMD_RESET_METHOD_ON_INIT;
reset_context.reset_req_dev = tmp_adev;
reset_context.hive = hive;
reset_context.reset_device_list = &device_list;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
amdgpu_reset_do_xgmi_reset_on_init(&reset_context);
mutex_unlock(&hive->hive_lock);
amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
r = amdgpu_ras_init_badpage_info(tmp_adev);
if (r && r != -EHWPOISON)
dev_err(tmp_adev->dev,
"error during bad page data initialization");
}
}
static void amdgpu_xgmi_schedule_reset_on_init(struct amdgpu_hive_info *hive)
{
INIT_WORK(&hive->reset_on_init_work, amdgpu_xgmi_reset_on_init_work);
amdgpu_reset_domain_schedule(hive->reset_domain,
&hive->reset_on_init_work);
}
int amdgpu_xgmi_reset_on_init(struct amdgpu_device *adev)
{
struct amdgpu_hive_info *hive;
bool reset_scheduled;
int num_devs;
hive = amdgpu_get_xgmi_hive(adev);
if (!hive)
return -EINVAL;
mutex_lock(&hive->hive_lock);
num_devs = atomic_read(&hive->number_devices);
reset_scheduled = false;
if (num_devs == adev->gmc.xgmi.num_physical_nodes) {
amdgpu_xgmi_schedule_reset_on_init(hive);
reset_scheduled = true;
}
mutex_unlock(&hive->hive_lock);
amdgpu_put_xgmi_hive(hive);
if (reset_scheduled)
flush_work(&hive->reset_on_init_work);
return 0;
}
int amdgpu_xgmi_request_nps_change(struct amdgpu_device *adev,
struct amdgpu_hive_info *hive,
int req_nps_mode)
{
struct amdgpu_device *tmp_adev;
int cur_nps_mode, r;
/* This is expected to be called only during unload of driver. The
* request needs to be placed only once for all devices in the hive. If
* one of them fail, revert the request for previous successful devices.
* After placing the request, make hive mode as UNKNOWN so that other
* devices don't request anymore.
*/
mutex_lock(&hive->hive_lock);
if (atomic_read(&hive->requested_nps_mode) ==
UNKNOWN_MEMORY_PARTITION_MODE) {
dev_dbg(adev->dev, "Unexpected entry for hive NPS change");
mutex_unlock(&hive->hive_lock);
return 0;
}
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
r = adev->gmc.gmc_funcs->request_mem_partition_mode(
tmp_adev, req_nps_mode);
if (r)
break;
}
if (r) {
/* Request back current mode if one of the requests failed */
cur_nps_mode =
adev->gmc.gmc_funcs->query_mem_partition_mode(tmp_adev);
list_for_each_entry_continue_reverse(
tmp_adev, &hive->device_list, gmc.xgmi.head)
adev->gmc.gmc_funcs->request_mem_partition_mode(
tmp_adev, cur_nps_mode);
}
/* Set to UNKNOWN so that other devices don't request anymore */
atomic_set(&hive->requested_nps_mode, UNKNOWN_MEMORY_PARTITION_MODE);
mutex_unlock(&hive->hive_lock);
return r;
}

View File

@ -45,6 +45,8 @@ struct amdgpu_hive_info {
struct amdgpu_reset_domain *reset_domain;
atomic_t ras_recovery;
struct ras_event_manager event_mgr;
struct work_struct reset_on_init_work;
atomic_t requested_nps_mode;
};
struct amdgpu_pcs_ras_field {
@ -64,6 +66,8 @@ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev,
struct amdgpu_device *peer_adev);
int amdgpu_xgmi_get_num_links(struct amdgpu_device *adev,
struct amdgpu_device *peer_adev);
bool amdgpu_xgmi_get_is_sharing_enabled(struct amdgpu_device *adev,
struct amdgpu_device *peer_adev);
uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
uint64_t addr);
static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
@ -75,5 +79,10 @@ static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
adev->gmc.xgmi.hive_id == bo_adev->gmc.xgmi.hive_id);
}
int amdgpu_xgmi_ras_sw_init(struct amdgpu_device *adev);
int amdgpu_xgmi_reset_on_init(struct amdgpu_device *adev);
int amdgpu_xgmi_request_nps_change(struct amdgpu_device *adev,
struct amdgpu_hive_info *hive,
int req_nps_mode);
#endif

View File

@ -447,6 +447,61 @@ static int __aqua_vanjaram_get_xcp_ip_info(struct amdgpu_xcp_mgr *xcp_mgr, int x
return 0;
}
static int aqua_vanjaram_get_xcp_res_info(struct amdgpu_xcp_mgr *xcp_mgr,
int mode,
struct amdgpu_xcp_cfg *xcp_cfg)
{
struct amdgpu_device *adev = xcp_mgr->adev;
int max_res[AMDGPU_XCP_RES_MAX] = {};
bool res_lt_xcp;
int num_xcp, i;
if (!(xcp_mgr->supp_xcp_modes & BIT(mode)))
return -EINVAL;
max_res[AMDGPU_XCP_RES_XCC] = NUM_XCC(adev->gfx.xcc_mask);
max_res[AMDGPU_XCP_RES_DMA] = adev->sdma.num_instances;
max_res[AMDGPU_XCP_RES_DEC] = adev->vcn.num_vcn_inst;
max_res[AMDGPU_XCP_RES_JPEG] = adev->jpeg.num_jpeg_inst;
switch (mode) {
case AMDGPU_SPX_PARTITION_MODE:
num_xcp = 1;
break;
case AMDGPU_DPX_PARTITION_MODE:
num_xcp = 2;
break;
case AMDGPU_TPX_PARTITION_MODE:
num_xcp = 3;
break;
case AMDGPU_QPX_PARTITION_MODE:
num_xcp = 4;
break;
case AMDGPU_CPX_PARTITION_MODE:
num_xcp = NUM_XCC(adev->gfx.xcc_mask);
break;
default:
return -EINVAL;
}
xcp_cfg->num_res = ARRAY_SIZE(max_res);
for (i = 0; i < xcp_cfg->num_res; i++) {
res_lt_xcp = max_res[i] < num_xcp;
xcp_cfg->xcp_res[i].id = i;
xcp_cfg->xcp_res[i].num_inst =
res_lt_xcp ? 1 : max_res[i] / num_xcp;
xcp_cfg->xcp_res[i].num_inst =
i == AMDGPU_XCP_RES_JPEG ?
xcp_cfg->xcp_res[i].num_inst *
adev->jpeg.num_jpeg_rings : xcp_cfg->xcp_res[i].num_inst;
xcp_cfg->xcp_res[i].num_shared =
res_lt_xcp ? num_xcp / max_res[i] : 1;
}
return 0;
}
static enum amdgpu_gfx_partition
__aqua_vanjaram_get_auto_mode(struct amdgpu_xcp_mgr *xcp_mgr)
{
@ -530,6 +585,57 @@ static int __aqua_vanjaram_post_partition_switch(struct amdgpu_xcp_mgr *xcp_mgr,
return ret;
}
static void
__aqua_vanjaram_update_supported_modes(struct amdgpu_xcp_mgr *xcp_mgr)
{
struct amdgpu_device *adev = xcp_mgr->adev;
xcp_mgr->supp_xcp_modes = 0;
switch (NUM_XCC(adev->gfx.xcc_mask)) {
case 8:
xcp_mgr->supp_xcp_modes = BIT(AMDGPU_SPX_PARTITION_MODE) |
BIT(AMDGPU_DPX_PARTITION_MODE) |
BIT(AMDGPU_QPX_PARTITION_MODE) |
BIT(AMDGPU_CPX_PARTITION_MODE);
break;
case 6:
xcp_mgr->supp_xcp_modes = BIT(AMDGPU_SPX_PARTITION_MODE) |
BIT(AMDGPU_TPX_PARTITION_MODE) |
BIT(AMDGPU_CPX_PARTITION_MODE);
break;
case 4:
xcp_mgr->supp_xcp_modes = BIT(AMDGPU_SPX_PARTITION_MODE) |
BIT(AMDGPU_DPX_PARTITION_MODE) |
BIT(AMDGPU_CPX_PARTITION_MODE);
break;
/* this seems only existing in emulation phase */
case 2:
xcp_mgr->supp_xcp_modes = BIT(AMDGPU_SPX_PARTITION_MODE) |
BIT(AMDGPU_CPX_PARTITION_MODE);
break;
case 1:
xcp_mgr->supp_xcp_modes = BIT(AMDGPU_SPX_PARTITION_MODE) |
BIT(AMDGPU_CPX_PARTITION_MODE);
break;
default:
break;
}
}
static void __aqua_vanjaram_update_available_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr)
{
int mode;
xcp_mgr->avail_xcp_modes = 0;
for_each_inst(mode, xcp_mgr->supp_xcp_modes) {
if (__aqua_vanjaram_is_valid_mode(xcp_mgr, mode))
xcp_mgr->avail_xcp_modes |= BIT(mode);
}
}
static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
int mode, int *num_xcps)
{
@ -578,6 +684,8 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
amdgpu_xcp_init(xcp_mgr, *num_xcps, mode);
ret = __aqua_vanjaram_post_partition_switch(xcp_mgr, flags);
if (!ret)
__aqua_vanjaram_update_available_partition_mode(xcp_mgr);
unlock:
if (flags & AMDGPU_XCP_OPS_KFD)
amdgpu_amdkfd_unlock_kfd(adev);
@ -656,9 +764,11 @@ struct amdgpu_xcp_mgr_funcs aqua_vanjaram_xcp_funcs = {
.switch_partition_mode = &aqua_vanjaram_switch_partition_mode,
.query_partition_mode = &aqua_vanjaram_query_partition_mode,
.get_ip_details = &aqua_vanjaram_get_xcp_ip_details,
.get_xcp_res_info = &aqua_vanjaram_get_xcp_res_info,
.get_xcp_mem_id = &aqua_vanjaram_get_xcp_mem_id,
.select_scheds = &aqua_vanjaram_select_scheds,
.update_partition_sched_list = &aqua_vanjaram_update_partition_sched_list
.update_partition_sched_list =
&aqua_vanjaram_update_partition_sched_list
};
static int aqua_vanjaram_xcp_mgr_init(struct amdgpu_device *adev)
@ -673,6 +783,7 @@ static int aqua_vanjaram_xcp_mgr_init(struct amdgpu_device *adev)
if (ret)
return ret;
__aqua_vanjaram_update_supported_modes(adev->xcp_mgr);
/* TODO: Default memory node affinity init */
return ret;

View File

@ -1985,9 +1985,9 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
.query_video_codecs = &cik_query_video_codecs,
};
static int cik_common_early_init(void *handle)
static int cik_common_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->smc_rreg = &cik_smc_rreg;
adev->smc_wreg = &cik_smc_wreg;
@ -2124,19 +2124,9 @@ static int cik_common_early_init(void *handle)
return 0;
}
static int cik_common_sw_init(void *handle)
static int cik_common_hw_init(struct amdgpu_ip_block *ip_block)
{
return 0;
}
static int cik_common_sw_fini(void *handle)
{
return 0;
}
static int cik_common_hw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* move the golden regs per IP block */
cik_init_golden_registers(adev);
@ -2148,23 +2138,14 @@ static int cik_common_hw_init(void *handle)
return 0;
}
static int cik_common_hw_fini(void *handle)
static int cik_common_hw_fini(struct amdgpu_ip_block *ip_block)
{
return 0;
}
static int cik_common_suspend(void *handle)
static int cik_common_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cik_common_hw_fini(adev);
}
static int cik_common_resume(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cik_common_hw_init(adev);
return cik_common_hw_init(ip_block);
}
static bool cik_common_is_idle(void *handle)
@ -2172,12 +2153,9 @@ static bool cik_common_is_idle(void *handle)
return true;
}
static int cik_common_wait_for_idle(void *handle)
{
return 0;
}
static int cik_common_soft_reset(void *handle)
static int cik_common_soft_reset(struct amdgpu_ip_block *ip_block)
{
/* XXX hard reset?? */
return 0;
@ -2198,20 +2176,13 @@ static int cik_common_set_powergating_state(void *handle,
static const struct amd_ip_funcs cik_common_ip_funcs = {
.name = "cik_common",
.early_init = cik_common_early_init,
.late_init = NULL,
.sw_init = cik_common_sw_init,
.sw_fini = cik_common_sw_fini,
.hw_init = cik_common_hw_init,
.hw_fini = cik_common_hw_fini,
.suspend = cik_common_suspend,
.resume = cik_common_resume,
.is_idle = cik_common_is_idle,
.wait_for_idle = cik_common_wait_for_idle,
.soft_reset = cik_common_soft_reset,
.set_clockgating_state = cik_common_set_clockgating_state,
.set_powergating_state = cik_common_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ip_block_version cik_common_ip_block =

View File

@ -283,9 +283,9 @@ static void cik_ih_set_rptr(struct amdgpu_device *adev,
WREG32(mmIH_RB_RPTR, ih->rptr);
}
static int cik_ih_early_init(void *handle)
static int cik_ih_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
ret = amdgpu_irq_add_domain(adev);
@ -297,10 +297,10 @@ static int cik_ih_early_init(void *handle)
return 0;
}
static int cik_ih_sw_init(void *handle)
static int cik_ih_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
if (r)
@ -311,9 +311,9 @@ static int cik_ih_sw_init(void *handle)
return r;
}
static int cik_ih_sw_fini(void *handle)
static int cik_ih_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
@ -321,34 +321,28 @@ static int cik_ih_sw_fini(void *handle)
return 0;
}
static int cik_ih_hw_init(void *handle)
static int cik_ih_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
return cik_ih_irq_init(adev);
}
static int cik_ih_hw_fini(void *handle)
static int cik_ih_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
cik_ih_irq_disable(adev);
cik_ih_irq_disable(ip_block->adev);
return 0;
}
static int cik_ih_suspend(void *handle)
static int cik_ih_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cik_ih_hw_fini(adev);
return cik_ih_hw_fini(ip_block);
}
static int cik_ih_resume(void *handle)
static int cik_ih_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cik_ih_hw_init(adev);
return cik_ih_hw_init(ip_block);
}
static bool cik_ih_is_idle(void *handle)
@ -362,11 +356,11 @@ static bool cik_ih_is_idle(void *handle)
return true;
}
static int cik_ih_wait_for_idle(void *handle)
static int cik_ih_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -378,9 +372,9 @@ static int cik_ih_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int cik_ih_soft_reset(void *handle)
static int cik_ih_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@ -423,7 +417,6 @@ static int cik_ih_set_powergating_state(void *handle,
static const struct amd_ip_funcs cik_ih_ip_funcs = {
.name = "cik_ih",
.early_init = cik_ih_early_init,
.late_init = NULL,
.sw_init = cik_ih_sw_init,
.sw_fini = cik_ih_sw_fini,
.hw_init = cik_ih_hw_init,
@ -435,8 +428,6 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = {
.soft_reset = cik_ih_soft_reset,
.set_clockgating_state = cik_ih_set_clockgating_state,
.set_powergating_state = cik_ih_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs cik_ih_funcs = {

View File

@ -54,7 +54,7 @@ static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev);
static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);
static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);
static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev);
static int cik_sdma_soft_reset(void *handle);
static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block);
MODULE_FIRMWARE("amdgpu/bonaire_sdma.bin");
MODULE_FIRMWARE("amdgpu/bonaire_sdma1.bin");
@ -918,9 +918,9 @@ static void cik_enable_sdma_mgls(struct amdgpu_device *adev,
}
}
static int cik_sdma_early_init(void *handle)
static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
adev->sdma.num_instances = SDMA_MAX_INSTANCE;
@ -937,10 +937,10 @@ static int cik_sdma_early_init(void *handle)
return 0;
}
static int cik_sdma_sw_init(void *handle)
static int cik_sdma_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r, i;
/* SDMA trap event */
@ -977,9 +977,9 @@ static int cik_sdma_sw_init(void *handle)
return r;
}
static int cik_sdma_sw_fini(void *handle)
static int cik_sdma_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i;
for (i = 0; i < adev->sdma.num_instances; i++)
@ -989,10 +989,10 @@ static int cik_sdma_sw_fini(void *handle)
return 0;
}
static int cik_sdma_hw_init(void *handle)
static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = cik_sdma_start(adev);
if (r)
@ -1001,9 +1001,9 @@ static int cik_sdma_hw_init(void *handle)
return r;
}
static int cik_sdma_hw_fini(void *handle)
static int cik_sdma_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
cik_ctx_switch_enable(adev, false);
cik_sdma_enable(adev, false);
@ -1011,20 +1011,16 @@ static int cik_sdma_hw_fini(void *handle)
return 0;
}
static int cik_sdma_suspend(void *handle)
static int cik_sdma_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cik_sdma_hw_fini(adev);
return cik_sdma_hw_fini(ip_block);
}
static int cik_sdma_resume(void *handle)
static int cik_sdma_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
cik_sdma_soft_reset(ip_block);
cik_sdma_soft_reset(handle);
return cik_sdma_hw_init(adev);
return cik_sdma_hw_init(ip_block);
}
static bool cik_sdma_is_idle(void *handle)
@ -1039,11 +1035,11 @@ static bool cik_sdma_is_idle(void *handle)
return true;
}
static int cik_sdma_wait_for_idle(void *handle)
static int cik_sdma_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(mmSRBM_STATUS2) & (SRBM_STATUS2__SDMA_BUSY_MASK |
@ -1056,10 +1052,10 @@ static int cik_sdma_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int cik_sdma_soft_reset(void *handle)
static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 tmp;
/* sdma0 */
@ -1217,7 +1213,6 @@ static int cik_sdma_set_powergating_state(void *handle,
static const struct amd_ip_funcs cik_sdma_ip_funcs = {
.name = "cik_sdma",
.early_init = cik_sdma_early_init,
.late_init = NULL,
.sw_init = cik_sdma_sw_init,
.sw_fini = cik_sdma_sw_fini,
.hw_init = cik_sdma_hw_init,
@ -1229,8 +1224,6 @@ static const struct amd_ip_funcs cik_sdma_ip_funcs = {
.soft_reset = cik_sdma_soft_reset,
.set_clockgating_state = cik_sdma_set_clockgating_state,
.set_powergating_state = cik_sdma_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs cik_sdma_ring_funcs = {

View File

@ -274,9 +274,9 @@ static void cz_ih_set_rptr(struct amdgpu_device *adev,
WREG32(mmIH_RB_RPTR, ih->rptr);
}
static int cz_ih_early_init(void *handle)
static int cz_ih_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
ret = amdgpu_irq_add_domain(adev);
@ -288,10 +288,10 @@ static int cz_ih_early_init(void *handle)
return 0;
}
static int cz_ih_sw_init(void *handle)
static int cz_ih_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
if (r)
@ -302,9 +302,9 @@ static int cz_ih_sw_init(void *handle)
return r;
}
static int cz_ih_sw_fini(void *handle)
static int cz_ih_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
@ -312,10 +312,10 @@ static int cz_ih_sw_fini(void *handle)
return 0;
}
static int cz_ih_hw_init(void *handle)
static int cz_ih_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = cz_ih_irq_init(adev);
if (r)
@ -324,27 +324,21 @@ static int cz_ih_hw_init(void *handle)
return 0;
}
static int cz_ih_hw_fini(void *handle)
static int cz_ih_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
cz_ih_irq_disable(adev);
cz_ih_irq_disable(ip_block->adev);
return 0;
}
static int cz_ih_suspend(void *handle)
static int cz_ih_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cz_ih_hw_fini(adev);
return cz_ih_hw_fini(ip_block);
}
static int cz_ih_resume(void *handle)
static int cz_ih_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return cz_ih_hw_init(adev);
return cz_ih_hw_init(ip_block);
}
static bool cz_ih_is_idle(void *handle)
@ -358,11 +352,11 @@ static bool cz_ih_is_idle(void *handle)
return true;
}
static int cz_ih_wait_for_idle(void *handle)
static int cz_ih_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -374,10 +368,10 @@ static int cz_ih_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int cz_ih_soft_reset(void *handle)
static int cz_ih_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__IH_BUSY_MASK)
@ -421,7 +415,6 @@ static int cz_ih_set_powergating_state(void *handle,
static const struct amd_ip_funcs cz_ih_ip_funcs = {
.name = "cz_ih",
.early_init = cz_ih_early_init,
.late_init = NULL,
.sw_init = cz_ih_sw_init,
.sw_fini = cz_ih_sw_fini,
.hw_init = cz_ih_hw_init,
@ -433,8 +426,6 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = {
.soft_reset = cz_ih_soft_reset,
.set_clockgating_state = cz_ih_set_clockgating_state,
.set_powergating_state = cz_ih_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs cz_ih_funcs = {

View File

@ -2738,9 +2738,9 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
return 0;
}
static int dce_v10_0_early_init(void *handle)
static int dce_v10_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->audio_endpt_rreg = &dce_v10_0_audio_endpt_rreg;
adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg;
@ -2765,10 +2765,10 @@ static int dce_v10_0_early_init(void *handle)
return 0;
}
static int dce_v10_0_sw_init(void *handle)
static int dce_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->mode_info.num_crtc; i++) {
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
@ -2844,9 +2844,9 @@ static int dce_v10_0_sw_init(void *handle)
return 0;
}
static int dce_v10_0_sw_fini(void *handle)
static int dce_v10_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
drm_edid_free(adev->mode_info.bios_hardcoded_edid);
@ -2862,10 +2862,10 @@ static int dce_v10_0_sw_fini(void *handle)
return 0;
}
static int dce_v10_0_hw_init(void *handle)
static int dce_v10_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v10_0_init_golden_registers(adev);
@ -2887,10 +2887,10 @@ static int dce_v10_0_hw_init(void *handle)
return 0;
}
static int dce_v10_0_hw_fini(void *handle)
static int dce_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v10_0_hpd_fini(adev);
@ -2905,9 +2905,9 @@ static int dce_v10_0_hw_fini(void *handle)
return 0;
}
static int dce_v10_0_suspend(void *handle)
static int dce_v10_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_display_suspend_helper(adev);
@ -2917,18 +2917,18 @@ static int dce_v10_0_suspend(void *handle)
adev->mode_info.bl_level =
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
return dce_v10_0_hw_fini(handle);
return dce_v10_0_hw_fini(ip_block);
}
static int dce_v10_0_resume(void *handle)
static int dce_v10_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
adev->mode_info.bl_level);
ret = dce_v10_0_hw_init(handle);
ret = dce_v10_0_hw_init(ip_block);
/* turn on the BL */
if (adev->mode_info.bl_encoder) {
@ -2948,22 +2948,17 @@ static bool dce_v10_0_is_idle(void *handle)
return true;
}
static int dce_v10_0_wait_for_idle(void *handle)
static bool dce_v10_0_check_soft_reset(struct amdgpu_ip_block *ip_block)
{
return 0;
}
static bool dce_v10_0_check_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
return dce_v10_0_is_display_hung(adev);
}
static int dce_v10_0_soft_reset(void *handle)
static int dce_v10_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0, tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (dce_v10_0_is_display_hung(adev))
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
@ -3322,7 +3317,6 @@ static int dce_v10_0_set_powergating_state(void *handle,
static const struct amd_ip_funcs dce_v10_0_ip_funcs = {
.name = "dce_v10_0",
.early_init = dce_v10_0_early_init,
.late_init = NULL,
.sw_init = dce_v10_0_sw_init,
.sw_fini = dce_v10_0_sw_fini,
.hw_init = dce_v10_0_hw_init,
@ -3330,13 +3324,10 @@ static const struct amd_ip_funcs dce_v10_0_ip_funcs = {
.suspend = dce_v10_0_suspend,
.resume = dce_v10_0_resume,
.is_idle = dce_v10_0_is_idle,
.wait_for_idle = dce_v10_0_wait_for_idle,
.check_soft_reset = dce_v10_0_check_soft_reset,
.soft_reset = dce_v10_0_soft_reset,
.set_clockgating_state = dce_v10_0_set_clockgating_state,
.set_powergating_state = dce_v10_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static void

View File

@ -2851,9 +2851,9 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
return 0;
}
static int dce_v11_0_early_init(void *handle)
static int dce_v11_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->audio_endpt_rreg = &dce_v11_0_audio_endpt_rreg;
adev->audio_endpt_wreg = &dce_v11_0_audio_endpt_wreg;
@ -2891,10 +2891,10 @@ static int dce_v11_0_early_init(void *handle)
return 0;
}
static int dce_v11_0_sw_init(void *handle)
static int dce_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->mode_info.num_crtc; i++) {
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
@ -2971,9 +2971,9 @@ static int dce_v11_0_sw_init(void *handle)
return 0;
}
static int dce_v11_0_sw_fini(void *handle)
static int dce_v11_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
drm_edid_free(adev->mode_info.bios_hardcoded_edid);
@ -2989,10 +2989,10 @@ static int dce_v11_0_sw_fini(void *handle)
return 0;
}
static int dce_v11_0_hw_init(void *handle)
static int dce_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v11_0_init_golden_registers(adev);
@ -3025,10 +3025,10 @@ static int dce_v11_0_hw_init(void *handle)
return 0;
}
static int dce_v11_0_hw_fini(void *handle)
static int dce_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v11_0_hpd_fini(adev);
@ -3043,9 +3043,9 @@ static int dce_v11_0_hw_fini(void *handle)
return 0;
}
static int dce_v11_0_suspend(void *handle)
static int dce_v11_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_display_suspend_helper(adev);
@ -3055,18 +3055,18 @@ static int dce_v11_0_suspend(void *handle)
adev->mode_info.bl_level =
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
return dce_v11_0_hw_fini(handle);
return dce_v11_0_hw_fini(ip_block);
}
static int dce_v11_0_resume(void *handle)
static int dce_v11_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
adev->mode_info.bl_level);
ret = dce_v11_0_hw_init(handle);
ret = dce_v11_0_hw_init(ip_block);
/* turn on the BL */
if (adev->mode_info.bl_encoder) {
@ -3086,15 +3086,10 @@ static bool dce_v11_0_is_idle(void *handle)
return true;
}
static int dce_v11_0_wait_for_idle(void *handle)
{
return 0;
}
static int dce_v11_0_soft_reset(void *handle)
static int dce_v11_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0, tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (dce_v11_0_is_display_hung(adev))
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
@ -3454,7 +3449,6 @@ static int dce_v11_0_set_powergating_state(void *handle,
static const struct amd_ip_funcs dce_v11_0_ip_funcs = {
.name = "dce_v11_0",
.early_init = dce_v11_0_early_init,
.late_init = NULL,
.sw_init = dce_v11_0_sw_init,
.sw_fini = dce_v11_0_sw_fini,
.hw_init = dce_v11_0_hw_init,
@ -3462,12 +3456,9 @@ static const struct amd_ip_funcs dce_v11_0_ip_funcs = {
.suspend = dce_v11_0_suspend,
.resume = dce_v11_0_resume,
.is_idle = dce_v11_0_is_idle,
.wait_for_idle = dce_v11_0_wait_for_idle,
.soft_reset = dce_v11_0_soft_reset,
.set_clockgating_state = dce_v11_0_set_clockgating_state,
.set_powergating_state = dce_v11_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static void

View File

@ -2633,9 +2633,9 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
return 0;
}
static int dce_v6_0_early_init(void *handle)
static int dce_v6_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->audio_endpt_rreg = &dce_v6_0_audio_endpt_rreg;
adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg;
@ -2664,11 +2664,11 @@ static int dce_v6_0_early_init(void *handle)
return 0;
}
static int dce_v6_0_sw_init(void *handle)
static int dce_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, i;
bool ret;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->mode_info.num_crtc; i++) {
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
@ -2743,9 +2743,9 @@ static int dce_v6_0_sw_init(void *handle)
return r;
}
static int dce_v6_0_sw_fini(void *handle)
static int dce_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
drm_edid_free(adev->mode_info.bios_hardcoded_edid);
@ -2760,10 +2760,10 @@ static int dce_v6_0_sw_fini(void *handle)
return 0;
}
static int dce_v6_0_hw_init(void *handle)
static int dce_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* disable vga render */
dce_v6_0_set_vga_render_state(adev, false);
@ -2783,10 +2783,10 @@ static int dce_v6_0_hw_init(void *handle)
return 0;
}
static int dce_v6_0_hw_fini(void *handle)
static int dce_v6_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v6_0_hpd_fini(adev);
@ -2801,9 +2801,9 @@ static int dce_v6_0_hw_fini(void *handle)
return 0;
}
static int dce_v6_0_suspend(void *handle)
static int dce_v6_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_display_suspend_helper(adev);
@ -2812,18 +2812,18 @@ static int dce_v6_0_suspend(void *handle)
adev->mode_info.bl_level =
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
return dce_v6_0_hw_fini(handle);
return dce_v6_0_hw_fini(ip_block);
}
static int dce_v6_0_resume(void *handle)
static int dce_v6_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
adev->mode_info.bl_level);
ret = dce_v6_0_hw_init(handle);
ret = dce_v6_0_hw_init(ip_block);
/* turn on the BL */
if (adev->mode_info.bl_encoder) {
@ -2843,12 +2843,7 @@ static bool dce_v6_0_is_idle(void *handle)
return true;
}
static int dce_v6_0_wait_for_idle(void *handle)
{
return 0;
}
static int dce_v6_0_soft_reset(void *handle)
static int dce_v6_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
DRM_INFO("xxxx: dce_v6_0_soft_reset --- no impl!!\n");
return 0;
@ -3144,7 +3139,6 @@ static int dce_v6_0_set_powergating_state(void *handle,
static const struct amd_ip_funcs dce_v6_0_ip_funcs = {
.name = "dce_v6_0",
.early_init = dce_v6_0_early_init,
.late_init = NULL,
.sw_init = dce_v6_0_sw_init,
.sw_fini = dce_v6_0_sw_fini,
.hw_init = dce_v6_0_hw_init,
@ -3152,12 +3146,9 @@ static const struct amd_ip_funcs dce_v6_0_ip_funcs = {
.suspend = dce_v6_0_suspend,
.resume = dce_v6_0_resume,
.is_idle = dce_v6_0_is_idle,
.wait_for_idle = dce_v6_0_wait_for_idle,
.soft_reset = dce_v6_0_soft_reset,
.set_clockgating_state = dce_v6_0_set_clockgating_state,
.set_powergating_state = dce_v6_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static void

View File

@ -2644,9 +2644,9 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
return 0;
}
static int dce_v8_0_early_init(void *handle)
static int dce_v8_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->audio_endpt_rreg = &dce_v8_0_audio_endpt_rreg;
adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg;
@ -2680,10 +2680,10 @@ static int dce_v8_0_early_init(void *handle)
return 0;
}
static int dce_v8_0_sw_init(void *handle)
static int dce_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->mode_info.num_crtc; i++) {
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
@ -2764,9 +2764,9 @@ static int dce_v8_0_sw_init(void *handle)
return 0;
}
static int dce_v8_0_sw_fini(void *handle)
static int dce_v8_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
drm_edid_free(adev->mode_info.bios_hardcoded_edid);
@ -2782,10 +2782,10 @@ static int dce_v8_0_sw_fini(void *handle)
return 0;
}
static int dce_v8_0_hw_init(void *handle)
static int dce_v8_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* disable vga render */
dce_v8_0_set_vga_render_state(adev, false);
@ -2805,10 +2805,10 @@ static int dce_v8_0_hw_init(void *handle)
return 0;
}
static int dce_v8_0_hw_fini(void *handle)
static int dce_v8_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
dce_v8_0_hpd_fini(adev);
@ -2823,9 +2823,9 @@ static int dce_v8_0_hw_fini(void *handle)
return 0;
}
static int dce_v8_0_suspend(void *handle)
static int dce_v8_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_display_suspend_helper(adev);
@ -2835,18 +2835,18 @@ static int dce_v8_0_suspend(void *handle)
adev->mode_info.bl_level =
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
return dce_v8_0_hw_fini(handle);
return dce_v8_0_hw_fini(ip_block);
}
static int dce_v8_0_resume(void *handle)
static int dce_v8_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
adev->mode_info.bl_level);
ret = dce_v8_0_hw_init(handle);
ret = dce_v8_0_hw_init(ip_block);
/* turn on the BL */
if (adev->mode_info.bl_encoder) {
@ -2866,15 +2866,10 @@ static bool dce_v8_0_is_idle(void *handle)
return true;
}
static int dce_v8_0_wait_for_idle(void *handle)
{
return 0;
}
static int dce_v8_0_soft_reset(void *handle)
static int dce_v8_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0, tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (dce_v8_0_is_display_hung(adev))
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
@ -3232,7 +3227,6 @@ static int dce_v8_0_set_powergating_state(void *handle,
static const struct amd_ip_funcs dce_v8_0_ip_funcs = {
.name = "dce_v8_0",
.early_init = dce_v8_0_early_init,
.late_init = NULL,
.sw_init = dce_v8_0_sw_init,
.sw_fini = dce_v8_0_sw_fini,
.hw_init = dce_v8_0_hw_init,
@ -3240,12 +3234,9 @@ static const struct amd_ip_funcs dce_v8_0_ip_funcs = {
.suspend = dce_v8_0_suspend,
.resume = dce_v8_0_resume,
.is_idle = dce_v8_0_is_idle,
.wait_for_idle = dce_v8_0_wait_for_idle,
.soft_reset = dce_v8_0_soft_reset,
.set_clockgating_state = dce_v8_0_set_clockgating_state,
.set_powergating_state = dce_v8_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static void

View File

@ -3677,13 +3677,19 @@ static int gfx_v10_0_set_powergating_state(void *handle,
enum amd_powergating_state state);
static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
{
struct amdgpu_device *adev = kiq_ring->adev;
u64 shader_mc_addr;
/* Cleaner shader MC address */
shader_mc_addr = adev->gfx.cleaner_shader_gpu_addr >> 8;
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) |
PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */
amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */
amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */
amdgpu_ring_write(kiq_ring, 0); /* gws mask lo */
amdgpu_ring_write(kiq_ring, 0); /* gws mask hi */
amdgpu_ring_write(kiq_ring, lower_32_bits(shader_mc_addr)); /* cleaner shader addr lo */
amdgpu_ring_write(kiq_ring, upper_32_bits(shader_mc_addr)); /* cleaner shader addr hi */
amdgpu_ring_write(kiq_ring, 0); /* oac mask */
amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */
}
@ -4683,11 +4689,11 @@ static void gfx_v10_0_alloc_ip_dump(struct amdgpu_device *adev)
}
}
static int gfx_v10_0_sw_init(void *handle)
static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id = 0;
int xcc_id = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(10, 1, 10):
@ -4726,6 +4732,11 @@ static int gfx_v10_0_sw_init(void *handle)
adev->gfx.mec.num_queue_per_pipe = 8;
break;
}
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
default:
adev->gfx.enable_cleaner_shader = false;
break;
}
/* KIQ event */
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP,
@ -4842,6 +4853,9 @@ static int gfx_v10_0_sw_init(void *handle)
gfx_v10_0_alloc_ip_dump(adev);
r = amdgpu_gfx_sysfs_isolation_shader_init(adev);
if (r)
return r;
return 0;
}
@ -4866,10 +4880,10 @@ static void gfx_v10_0_me_fini(struct amdgpu_device *adev)
(void **)&adev->gfx.me.me_fw_ptr);
}
static int gfx_v10_0_sw_fini(void *handle)
static int gfx_v10_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
@ -4881,6 +4895,8 @@ static int gfx_v10_0_sw_fini(void *handle)
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq[0].ring);
amdgpu_gfx_kiq_fini(adev, 0);
amdgpu_gfx_cleaner_shader_sw_fini(adev);
gfx_v10_0_pfp_fini(adev);
gfx_v10_0_ce_fini(adev);
gfx_v10_0_me_fini(adev);
@ -4891,6 +4907,7 @@ static int gfx_v10_0_sw_fini(void *handle)
gfx_v10_0_rlc_backdoor_autoload_buffer_fini(adev);
gfx_v10_0_free_microcode(adev);
amdgpu_gfx_sysfs_isolation_shader_fini(adev);
kfree(adev->gfx.ip_dump_core);
kfree(adev->gfx.ip_dump_compute_queues);
@ -6374,7 +6391,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, mmCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, mmCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, mmCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) &
@ -6412,7 +6429,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
ring->wptr = 0;
WREG32_SOC15(GC, 0, mmCP_RB1_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, mmCP_RB1_WPTR_HI, upper_32_bits(ring->wptr));
/* Set the wb address wether it's enabled or not */
/* Set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR_HI, upper_32_bits(rptr_addr) &
@ -7366,14 +7383,17 @@ static void gfx_v10_0_disable_gpa_mode(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, mmCPG_PSP_DEBUG, data);
}
static int gfx_v10_0_hw_init(void *handle)
static int gfx_v10_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (!amdgpu_emu_mode)
gfx_v10_0_init_golden_registers(adev);
amdgpu_gfx_cleaner_shader_init(adev, adev->gfx.cleaner_shader_size,
adev->gfx.cleaner_shader_ptr);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
/**
* For gfx 10, rlc firmware loading relies on smu firmware is
@ -7418,9 +7438,9 @@ static int gfx_v10_0_hw_init(void *handle)
return r;
}
static int gfx_v10_0_hw_fini(void *handle)
static int gfx_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
@ -7431,7 +7451,7 @@ static int gfx_v10_0_hw_fini(void *handle)
* otherwise the gfxoff disallowing will be failed to set.
*/
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(10, 3, 1))
gfx_v10_0_set_powergating_state(handle, AMD_PG_STATE_UNGATE);
gfx_v10_0_set_powergating_state(ip_block->adev, AMD_PG_STATE_UNGATE);
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring) {
@ -7456,14 +7476,14 @@ static int gfx_v10_0_hw_fini(void *handle)
return 0;
}
static int gfx_v10_0_suspend(void *handle)
static int gfx_v10_0_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v10_0_hw_fini(handle);
return gfx_v10_0_hw_fini(ip_block);
}
static int gfx_v10_0_resume(void *handle)
static int gfx_v10_0_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v10_0_hw_init(handle);
return gfx_v10_0_hw_init(ip_block);
}
static bool gfx_v10_0_is_idle(void *handle)
@ -7477,11 +7497,11 @@ static bool gfx_v10_0_is_idle(void *handle)
return true;
}
static int gfx_v10_0_wait_for_idle(void *handle)
static int gfx_v10_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned int i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -7495,11 +7515,11 @@ static int gfx_v10_0_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int gfx_v10_0_soft_reset(void *handle)
static int gfx_v10_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 grbm_soft_reset = 0;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* GRBM_STATUS */
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS);
@ -7678,9 +7698,9 @@ static void gfx_v10_0_ring_emit_gds_switch(struct amdgpu_ring *ring,
(1 << (oa_size + oa_base)) - (1 << oa_base));
}
static int gfx_v10_0_early_init(void *handle)
static int gfx_v10_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.funcs = &gfx_v10_0_gfx_funcs;
@ -7722,9 +7742,9 @@ static int gfx_v10_0_early_init(void *handle)
return gfx_v10_0_init_microcode(adev);
}
static int gfx_v10_0_late_init(void *handle)
static int gfx_v10_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -9402,8 +9422,6 @@ static void gfx_v10_0_emit_mem_sync(struct amdgpu_ring *ring)
static void gfx_v10_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
int i;
/* Header itself is a NOP packet */
if (num_nop == 1) {
amdgpu_ring_write(ring, ring->funcs->nop);
@ -9414,8 +9432,7 @@ static void gfx_v10_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));
/* Header is at index 0, followed by num_nops - 1 NOP packet's */
for (i = 1; i < num_nop; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
amdgpu_ring_insert_nop(ring, num_nop - 1);
}
static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
@ -9568,9 +9585,9 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
return amdgpu_ring_test_ring(ring);
}
static void gfx_v10_ip_print(void *handle, struct drm_printer *p)
static void gfx_v10_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_10_1);
@ -9632,9 +9649,9 @@ static void gfx_v10_ip_print(void *handle, struct drm_printer *p)
}
}
static void gfx_v10_ip_dump(void *handle)
static void gfx_v10_ip_dump(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_10_1);
@ -9699,6 +9716,13 @@ static void gfx_v10_ip_dump(void *handle)
amdgpu_gfx_off_ctrl(adev, true);
}
static void gfx_v10_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring)
{
/* Emit the cleaner shader */
amdgpu_ring_write(ring, PACKET3(PACKET3_RUN_CLEANER_SHADER, 0));
amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */
}
static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
.name = "gfx_v10_0",
.early_init = gfx_v10_0_early_init,
@ -9749,7 +9773,8 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
5 + /* HDP_INVL */
8 + 8 + /* FENCE x2 */
2 + /* SWITCH_BUFFER */
8, /* gfx_v10_0_emit_mem_sync */
8 + /* gfx_v10_0_emit_mem_sync */
2, /* gfx_v10_0_ring_emit_cleaner_shader */
.emit_ib_size = 4, /* gfx_v10_0_ring_emit_ib_gfx */
.emit_ib = gfx_v10_0_ring_emit_ib_gfx,
.emit_fence = gfx_v10_0_ring_emit_fence,
@ -9772,6 +9797,9 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
.soft_recovery = gfx_v10_0_ring_soft_recovery,
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
.reset = gfx_v10_0_reset_kgq,
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
@ -9791,7 +9819,8 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
2 + /* gfx_v10_0_ring_emit_vm_flush */
8 + 8 + 8 + /* gfx_v10_0_ring_emit_fence x3 for user fence, vm fence */
8, /* gfx_v10_0_emit_mem_sync */
8 + /* gfx_v10_0_emit_mem_sync */
2, /* gfx_v10_0_ring_emit_cleaner_shader */
.emit_ib_size = 7, /* gfx_v10_0_ring_emit_ib_compute */
.emit_ib = gfx_v10_0_ring_emit_ib_compute,
.emit_fence = gfx_v10_0_ring_emit_fence,
@ -9809,6 +9838,9 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
.soft_recovery = gfx_v10_0_ring_soft_recovery,
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
.reset = gfx_v10_0_reset_kcq,
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {

View File

@ -293,14 +293,20 @@ static void gfx_v11_0_update_perf_clk(struct amdgpu_device *adev,
static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
{
struct amdgpu_device *adev = kiq_ring->adev;
u64 shader_mc_addr;
/* Cleaner shader MC address */
shader_mc_addr = adev->gfx.cleaner_shader_gpu_addr >> 8;
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) |
PACKET3_SET_RESOURCES_UNMAP_LATENTY(0xa) | /* unmap_latency: 0xa (~ 1s) */
PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */
amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */
amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */
amdgpu_ring_write(kiq_ring, 0); /* gws mask lo */
amdgpu_ring_write(kiq_ring, 0); /* gws mask hi */
amdgpu_ring_write(kiq_ring, lower_32_bits(shader_mc_addr)); /* cleaner shader addr lo */
amdgpu_ring_write(kiq_ring, upper_32_bits(shader_mc_addr)); /* cleaner shader addr hi */
amdgpu_ring_write(kiq_ring, 0); /* oac mask */
amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */
}
@ -483,8 +489,6 @@ static void gfx_v11_0_wait_reg_mem(struct amdgpu_ring *ring, int eng_sel,
static void gfx_v11_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
int i;
/* Header itself is a NOP packet */
if (num_nop == 1) {
amdgpu_ring_write(ring, ring->funcs->nop);
@ -495,8 +499,7 @@ static void gfx_v11_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));
/* Header is at index 0, followed by num_nops - 1 NOP packet's */
for (i = 1; i < num_nop; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
amdgpu_ring_insert_nop(ring, num_nop - 1);
}
static int gfx_v11_0_ring_test_ring(struct amdgpu_ring *ring)
@ -1536,11 +1539,11 @@ static void gfx_v11_0_alloc_ip_dump(struct amdgpu_device *adev)
}
}
static int gfx_v11_0_sw_init(void *handle)
static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id = 0;
int xcc_id = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(11, 0, 0):
@ -1575,6 +1578,11 @@ static int gfx_v11_0_sw_init(void *handle)
break;
}
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
default:
adev->gfx.enable_cleaner_shader = false;
}
/* Enable CG flag in one VF mode for enabling RLC safe mode enter/exit */
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 0, 3) &&
amdgpu_sriov_is_pp_one_vf(adev))
@ -1700,6 +1708,10 @@ static int gfx_v11_0_sw_init(void *handle)
gfx_v11_0_alloc_ip_dump(adev);
r = amdgpu_gfx_sysfs_isolation_shader_init(adev);
if (r)
return r;
return 0;
}
@ -1732,10 +1744,10 @@ static void gfx_v11_0_rlc_autoload_buffer_fini(struct amdgpu_device *adev)
(void **)&adev->gfx.rlc.rlc_autoload_ptr);
}
static int gfx_v11_0_sw_fini(void *handle)
static int gfx_v11_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
@ -1749,6 +1761,8 @@ static int gfx_v11_0_sw_fini(void *handle)
amdgpu_gfx_kiq_fini(adev, 0);
}
amdgpu_gfx_cleaner_shader_sw_fini(adev);
gfx_v11_0_pfp_fini(adev);
gfx_v11_0_me_fini(adev);
gfx_v11_0_rlc_fini(adev);
@ -1759,6 +1773,8 @@ static int gfx_v11_0_sw_fini(void *handle)
gfx_v11_0_free_microcode(adev);
amdgpu_gfx_sysfs_isolation_shader_fini(adev);
kfree(adev->gfx.ip_dump_core);
kfree(adev->gfx.ip_dump_compute_queues);
kfree(adev->gfx.ip_dump_gfx_queues);
@ -1893,8 +1909,10 @@ static void gfx_v11_0_init_compute_vmid(struct amdgpu_device *adev)
soc21_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
/* Initialize all compute VMIDs to have no GDS, GWS, or OA
acccess. These should be enabled by FW for target VMIDs. */
/*
* Initialize all compute VMIDs to have no GDS, GWS, or OA
* access. These should be enabled by FW for target VMIDs.
*/
for (i = adev->vm_manager.first_kfd_vmid; i < AMDGPU_NUM_VMID; i++) {
WREG32_SOC15_OFFSET(GC, 0, regGDS_VMID0_BASE, 2 * i, 0);
WREG32_SOC15_OFFSET(GC, 0, regGDS_VMID0_SIZE, 2 * i, 0);
@ -3555,7 +3573,7 @@ static int gfx_v11_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCP_RB0_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, regCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, regCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) &
@ -3593,7 +3611,7 @@ static int gfx_v11_0_cp_gfx_resume(struct amdgpu_device *adev)
ring->wptr = 0;
WREG32_SOC15(GC, 0, regCP_RB1_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, regCP_RB1_WPTR_HI, upper_32_bits(ring->wptr));
/* Set the wb address wether it's enabled or not */
/* Set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, regCP_RB1_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, regCP_RB1_RPTR_ADDR_HI, upper_32_bits(rptr_addr) &
@ -4568,10 +4586,13 @@ static void gfx_v11_0_disable_gpa_mode(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCPG_PSP_DEBUG, data);
}
static int gfx_v11_0_hw_init(void *handle)
static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gfx_cleaner_shader_init(adev, adev->gfx.cleaner_shader_size,
adev->gfx.cleaner_shader_ptr);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
if (adev->gfx.imu.funcs) {
@ -4665,9 +4686,9 @@ static int gfx_v11_0_hw_init(void *handle)
return r;
}
static int gfx_v11_0_hw_fini(void *handle)
static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
@ -4703,14 +4724,14 @@ static int gfx_v11_0_hw_fini(void *handle)
return 0;
}
static int gfx_v11_0_suspend(void *handle)
static int gfx_v11_0_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v11_0_hw_fini(handle);
return gfx_v11_0_hw_fini(ip_block);
}
static int gfx_v11_0_resume(void *handle)
static int gfx_v11_0_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v11_0_hw_init(handle);
return gfx_v11_0_hw_init(ip_block);
}
static bool gfx_v11_0_is_idle(void *handle)
@ -4724,11 +4745,11 @@ static bool gfx_v11_0_is_idle(void *handle)
return true;
}
static int gfx_v11_0_wait_for_idle(void *handle)
static int gfx_v11_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -4774,12 +4795,12 @@ int gfx_v11_0_request_gfx_index_mutex(struct amdgpu_device *adev,
return 0;
}
static int gfx_v11_0_soft_reset(void *handle)
static int gfx_v11_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 grbm_soft_reset = 0;
u32 tmp;
int r, i, j, k;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
@ -4905,10 +4926,10 @@ static int gfx_v11_0_soft_reset(void *handle)
return gfx_v11_0_cp_resume(adev);
}
static bool gfx_v11_0_check_soft_reset(void *handle)
static bool gfx_v11_0_check_soft_reset(struct amdgpu_ip_block *ip_block)
{
int i, r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
long tmo = msecs_to_jiffies(1000);
@ -4929,12 +4950,13 @@ static bool gfx_v11_0_check_soft_reset(void *handle)
return false;
}
static int gfx_v11_0_post_soft_reset(void *handle)
static int gfx_v11_0_post_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
/**
* GFX soft reset will impact MES, need resume MES when do GFX soft reset
*/
return amdgpu_mes_resume((struct amdgpu_device *)handle);
return amdgpu_mes_resume(adev);
}
static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev)
@ -4995,9 +5017,9 @@ static void gfx_v11_0_ring_emit_gds_switch(struct amdgpu_ring *ring,
(1 << (oa_size + oa_base)) - (1 << oa_base));
}
static int gfx_v11_0_early_init(void *handle)
static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.funcs = &gfx_v11_0_gfx_funcs;
@ -5018,9 +5040,9 @@ static int gfx_v11_0_early_init(void *handle)
return gfx_v11_0_init_microcode(adev);
}
static int gfx_v11_0_late_init(void *handle)
static int gfx_v11_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -6639,9 +6661,9 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
return amdgpu_ring_test_ring(ring);
}
static void gfx_v11_ip_print(void *handle, struct drm_printer *p)
static void gfx_v11_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_11_0);
@ -6703,9 +6725,9 @@ static void gfx_v11_ip_print(void *handle, struct drm_printer *p)
}
}
static void gfx_v11_ip_dump(void *handle)
static void gfx_v11_ip_dump(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_11_0);
@ -6769,6 +6791,13 @@ static void gfx_v11_ip_dump(void *handle)
amdgpu_gfx_off_ctrl(adev, true);
}
static void gfx_v11_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring)
{
/* Emit the cleaner shader */
amdgpu_ring_write(ring, PACKET3(PACKET3_RUN_CLEANER_SHADER, 0));
amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */
}
static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
.name = "gfx_v11_0",
.early_init = gfx_v11_0_early_init,
@ -6818,7 +6847,8 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
5 + /* HDP_INVL */
22 + /* SET_Q_PREEMPTION_MODE */
8 + 8 + /* FENCE x2 */
8, /* gfx_v11_0_emit_mem_sync */
8 + /* gfx_v11_0_emit_mem_sync */
2, /* gfx_v11_0_ring_emit_cleaner_shader */
.emit_ib_size = 4, /* gfx_v11_0_ring_emit_ib_gfx */
.emit_ib = gfx_v11_0_ring_emit_ib_gfx,
.emit_fence = gfx_v11_0_ring_emit_fence,
@ -6841,6 +6871,9 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
.soft_recovery = gfx_v11_0_ring_soft_recovery,
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
.reset = gfx_v11_0_reset_kgq,
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
@ -6861,7 +6894,8 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
2 + /* gfx_v11_0_ring_emit_vm_flush */
8 + 8 + 8 + /* gfx_v11_0_ring_emit_fence x3 for user fence, vm fence */
8, /* gfx_v11_0_emit_mem_sync */
8 + /* gfx_v11_0_emit_mem_sync */
2, /* gfx_v11_0_ring_emit_cleaner_shader */
.emit_ib_size = 7, /* gfx_v11_0_ring_emit_ib_compute */
.emit_ib = gfx_v11_0_ring_emit_ib_compute,
.emit_fence = gfx_v11_0_ring_emit_fence,
@ -6879,6 +6913,9 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
.soft_recovery = gfx_v11_0_ring_soft_recovery,
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
.reset = gfx_v11_0_reset_kcq,
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_kiq = {

View File

@ -1319,12 +1319,12 @@ static void gfx_v12_0_alloc_ip_dump(struct amdgpu_device *adev)
}
}
static int gfx_v12_0_sw_init(void *handle)
static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id = 0;
unsigned num_compute_rings;
int xcc_id = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(12, 0, 0):
@ -1346,6 +1346,12 @@ static int gfx_v12_0_sw_init(void *handle)
break;
}
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
default:
adev->gfx.enable_cleaner_shader = false;
break;
}
/* recalculate compute rings to use based on hardware configuration */
num_compute_rings = (adev->gfx.mec.num_pipe_per_mec *
adev->gfx.mec.num_queue_per_pipe) / 2;
@ -1460,6 +1466,10 @@ static int gfx_v12_0_sw_init(void *handle)
gfx_v12_0_alloc_ip_dump(adev);
r = amdgpu_gfx_sysfs_isolation_shader_init(adev);
if (r)
return r;
return 0;
}
@ -1492,10 +1502,10 @@ static void gfx_v12_0_rlc_autoload_buffer_fini(struct amdgpu_device *adev)
(void **)&adev->gfx.rlc.rlc_autoload_ptr);
}
static int gfx_v12_0_sw_fini(void *handle)
static int gfx_v12_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
@ -1519,6 +1529,8 @@ static int gfx_v12_0_sw_fini(void *handle)
gfx_v12_0_free_microcode(adev);
amdgpu_gfx_sysfs_isolation_shader_fini(adev);
kfree(adev->gfx.ip_dump_core);
kfree(adev->gfx.ip_dump_compute_queues);
kfree(adev->gfx.ip_dump_gfx_queues);
@ -2601,7 +2613,7 @@ static int gfx_v12_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCP_RB0_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, regCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, regCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) &
@ -3513,10 +3525,10 @@ static void gfx_v12_0_init_golden_registers(struct amdgpu_device *adev)
}
}
static int gfx_v12_0_hw_init(void *handle)
static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
if (adev->gfx.imu.funcs && (amdgpu_dpm > 0)) {
@ -3603,9 +3615,9 @@ static int gfx_v12_0_hw_init(void *handle)
return r;
}
static int gfx_v12_0_hw_fini(void *handle)
static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t tmp;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
@ -3643,14 +3655,14 @@ static int gfx_v12_0_hw_fini(void *handle)
return 0;
}
static int gfx_v12_0_suspend(void *handle)
static int gfx_v12_0_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v12_0_hw_fini(handle);
return gfx_v12_0_hw_fini(ip_block);
}
static int gfx_v12_0_resume(void *handle)
static int gfx_v12_0_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v12_0_hw_init(handle);
return gfx_v12_0_hw_init(ip_block);
}
static bool gfx_v12_0_is_idle(void *handle)
@ -3664,11 +3676,11 @@ static bool gfx_v12_0_is_idle(void *handle)
return true;
}
static int gfx_v12_0_wait_for_idle(void *handle)
static int gfx_v12_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -3695,9 +3707,9 @@ static uint64_t gfx_v12_0_get_gpu_clock_counter(struct amdgpu_device *adev)
return clock;
}
static int gfx_v12_0_early_init(void *handle)
static int gfx_v12_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.funcs = &gfx_v12_0_gfx_funcs;
@ -3717,9 +3729,9 @@ static int gfx_v12_0_early_init(void *handle)
return gfx_v12_0_init_microcode(adev);
}
static int gfx_v12_0_late_init(void *handle)
static int gfx_v12_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -5022,8 +5034,6 @@ static void gfx_v12_0_emit_mem_sync(struct amdgpu_ring *ring)
static void gfx_v12_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
int i;
/* Header itself is a NOP packet */
if (num_nop == 1) {
amdgpu_ring_write(ring, ring->funcs->nop);
@ -5034,13 +5044,19 @@ static void gfx_v12_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));
/* Header is at index 0, followed by num_nops - 1 NOP packet's */
for (i = 1; i < num_nop; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
amdgpu_ring_insert_nop(ring, num_nop - 1);
}
static void gfx_v12_ip_print(void *handle, struct drm_printer *p)
static void gfx_v12_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* Emit the cleaner shader */
amdgpu_ring_write(ring, PACKET3(PACKET3_RUN_CLEANER_SHADER, 0));
amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */
}
static void gfx_v12_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
{
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_12_0);
@ -5102,9 +5118,9 @@ static void gfx_v12_ip_print(void *handle, struct drm_printer *p)
}
}
static void gfx_v12_ip_dump(void *handle)
static void gfx_v12_ip_dump(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_12_0);
@ -5297,7 +5313,8 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
3 + /* CNTX_CTRL */
5 + /* HDP_INVL */
8 + 8 + /* FENCE x2 */
8, /* gfx_v12_0_emit_mem_sync */
8 + /* gfx_v12_0_emit_mem_sync */
2, /* gfx_v12_0_ring_emit_cleaner_shader */
.emit_ib_size = 4, /* gfx_v12_0_ring_emit_ib_gfx */
.emit_ib = gfx_v12_0_ring_emit_ib_gfx,
.emit_fence = gfx_v12_0_ring_emit_fence,
@ -5318,6 +5335,9 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
.soft_recovery = gfx_v12_0_ring_soft_recovery,
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
.reset = gfx_v12_0_reset_kgq,
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
@ -5336,7 +5356,8 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
2 + /* gfx_v12_0_ring_emit_vm_flush */
8 + 8 + 8 + /* gfx_v12_0_ring_emit_fence x3 for user fence, vm fence */
8, /* gfx_v12_0_emit_mem_sync */
8 + /* gfx_v12_0_emit_mem_sync */
2, /* gfx_v12_0_ring_emit_cleaner_shader */
.emit_ib_size = 7, /* gfx_v12_0_ring_emit_ib_compute */
.emit_ib = gfx_v12_0_ring_emit_ib_compute,
.emit_fence = gfx_v12_0_ring_emit_fence,
@ -5353,6 +5374,9 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
.soft_recovery = gfx_v12_0_ring_soft_recovery,
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
.reset = gfx_v12_0_reset_kcq,
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
};
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_kiq = {

View File

@ -3023,9 +3023,9 @@ static const struct amdgpu_rlc_funcs gfx_v6_0_rlc_funcs = {
.start = gfx_v6_0_rlc_start
};
static int gfx_v6_0_early_init(void *handle)
static int gfx_v6_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.xcc_mask = 1;
adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS;
@ -3039,10 +3039,10 @@ static int gfx_v6_0_early_init(void *handle)
return 0;
}
static int gfx_v6_0_sw_init(void *handle)
static int gfx_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i, r;
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq);
@ -3107,10 +3107,10 @@ static int gfx_v6_0_sw_init(void *handle)
return r;
}
static int gfx_v6_0_sw_fini(void *handle)
static int gfx_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
@ -3122,10 +3122,10 @@ static int gfx_v6_0_sw_fini(void *handle)
return 0;
}
static int gfx_v6_0_hw_init(void *handle)
static int gfx_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gfx_v6_0_constants_init(adev);
@ -3142,9 +3142,9 @@ static int gfx_v6_0_hw_init(void *handle)
return r;
}
static int gfx_v6_0_hw_fini(void *handle)
static int gfx_v6_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gfx_v6_0_cp_enable(adev, false);
adev->gfx.rlc.funcs->stop(adev);
@ -3153,18 +3153,14 @@ static int gfx_v6_0_hw_fini(void *handle)
return 0;
}
static int gfx_v6_0_suspend(void *handle)
static int gfx_v6_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return gfx_v6_0_hw_fini(adev);
return gfx_v6_0_hw_fini(ip_block);
}
static int gfx_v6_0_resume(void *handle)
static int gfx_v6_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return gfx_v6_0_hw_init(adev);
return gfx_v6_0_hw_init(ip_block);
}
static bool gfx_v6_0_is_idle(void *handle)
@ -3177,24 +3173,19 @@ static bool gfx_v6_0_is_idle(void *handle)
return true;
}
static int gfx_v6_0_wait_for_idle(void *handle)
static int gfx_v6_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
if (gfx_v6_0_is_idle(handle))
if (gfx_v6_0_is_idle(adev))
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int gfx_v6_0_soft_reset(void *handle)
{
return 0;
}
static void gfx_v6_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
enum amdgpu_interrupt_state state)
{
@ -3444,7 +3435,6 @@ static void gfx_v6_0_emit_mem_sync(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v6_0_ip_funcs = {
.name = "gfx_v6_0",
.early_init = gfx_v6_0_early_init,
.late_init = NULL,
.sw_init = gfx_v6_0_sw_init,
.sw_fini = gfx_v6_0_sw_fini,
.hw_init = gfx_v6_0_hw_init,
@ -3453,11 +3443,8 @@ static const struct amd_ip_funcs gfx_v6_0_ip_funcs = {
.resume = gfx_v6_0_resume,
.is_idle = gfx_v6_0_is_idle,
.wait_for_idle = gfx_v6_0_wait_for_idle,
.soft_reset = gfx_v6_0_soft_reset,
.set_clockgating_state = gfx_v6_0_set_clockgating_state,
.set_powergating_state = gfx_v6_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs gfx_v6_0_ring_funcs_gfx = {

View File

@ -2559,7 +2559,7 @@ static int gfx_v7_0_cp_gfx_resume(struct amdgpu_device *adev)
ring->wptr = 0;
WREG32(mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32(mmCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32(mmCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & 0xFF);
@ -2876,7 +2876,7 @@ static void gfx_v7_0_mqd_init(struct amdgpu_device *adev,
mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffffffc;
mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff;
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
wb_gpu_addr = ring->rptr_gpu_addr;
mqd->cp_hqd_pq_rptr_report_addr_lo = wb_gpu_addr & 0xfffffffc;
mqd->cp_hqd_pq_rptr_report_addr_hi =
@ -4134,9 +4134,9 @@ static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = {
.update_spm_vmid = gfx_v7_0_update_spm_vmid
};
static int gfx_v7_0_early_init(void *handle)
static int gfx_v7_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.xcc_mask = 1;
adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS;
@ -4151,9 +4151,9 @@ static int gfx_v7_0_early_init(void *handle)
return 0;
}
static int gfx_v7_0_late_init(void *handle)
static int gfx_v7_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -4343,10 +4343,10 @@ static int gfx_v7_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
return 0;
}
static int gfx_v7_0_sw_init(void *handle)
static int gfx_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i, j, k, r, ring_id;
switch (adev->asic_type) {
@ -4439,9 +4439,9 @@ static int gfx_v7_0_sw_init(void *handle)
return r;
}
static int gfx_v7_0_sw_fini(void *handle)
static int gfx_v7_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
@ -4465,10 +4465,10 @@ static int gfx_v7_0_sw_fini(void *handle)
return 0;
}
static int gfx_v7_0_hw_init(void *handle)
static int gfx_v7_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gfx_v7_0_constants_init(adev);
@ -4486,9 +4486,9 @@ static int gfx_v7_0_hw_init(void *handle)
return r;
}
static int gfx_v7_0_hw_fini(void *handle)
static int gfx_v7_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
@ -4499,18 +4499,14 @@ static int gfx_v7_0_hw_fini(void *handle)
return 0;
}
static int gfx_v7_0_suspend(void *handle)
static int gfx_v7_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return gfx_v7_0_hw_fini(adev);
return gfx_v7_0_hw_fini(ip_block);
}
static int gfx_v7_0_resume(void *handle)
static int gfx_v7_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return gfx_v7_0_hw_init(adev);
return gfx_v7_0_hw_init(ip_block);
}
static bool gfx_v7_0_is_idle(void *handle)
@ -4523,11 +4519,11 @@ static bool gfx_v7_0_is_idle(void *handle)
return true;
}
static int gfx_v7_0_wait_for_idle(void *handle)
static int gfx_v7_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -4540,11 +4536,11 @@ static int gfx_v7_0_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int gfx_v7_0_soft_reset(void *handle)
static int gfx_v7_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* GRBM_STATUS */
tmp = RREG32(mmGRBM_STATUS);
@ -5009,8 +5005,6 @@ static const struct amd_ip_funcs gfx_v7_0_ip_funcs = {
.soft_reset = gfx_v7_0_soft_reset,
.set_clockgating_state = gfx_v7_0_set_clockgating_state,
.set_powergating_state = gfx_v7_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = {

View File

@ -1894,12 +1894,12 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
static void gfx_v8_0_sq_irq_work_func(struct work_struct *work);
static int gfx_v8_0_sw_init(void *handle)
static int gfx_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id;
int xcc_id = 0;
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (adev->asic_type) {
case CHIP_TONGA:
@ -2037,9 +2037,9 @@ static int gfx_v8_0_sw_init(void *handle)
return 0;
}
static int gfx_v8_0_sw_fini(void *handle)
static int gfx_v8_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i;
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
@ -4260,7 +4260,7 @@ static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev)
ring->wptr = 0;
WREG32(mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32(mmCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32(mmCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & 0xFF);
@ -4783,10 +4783,10 @@ static void gfx_v8_0_cp_enable(struct amdgpu_device *adev, bool enable)
gfx_v8_0_cp_compute_enable(adev, enable);
}
static int gfx_v8_0_hw_init(void *handle)
static int gfx_v8_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gfx_v8_0_init_golden_registers(adev);
gfx_v8_0_constants_init(adev);
@ -4865,13 +4865,13 @@ static int gfx_v8_0_wait_for_rlc_idle(void *handle)
return -ETIMEDOUT;
}
static int gfx_v8_0_wait_for_idle(void *handle)
static int gfx_v8_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
if (gfx_v8_0_is_idle(handle))
if (gfx_v8_0_is_idle(adev))
return 0;
udelay(1);
@ -4879,9 +4879,9 @@ static int gfx_v8_0_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int gfx_v8_0_hw_fini(void *handle)
static int gfx_v8_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
@ -4897,8 +4897,9 @@ static int gfx_v8_0_hw_fini(void *handle)
pr_debug("For SRIOV client, shouldn't do anything.\n");
return 0;
}
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
if (!gfx_v8_0_wait_for_idle(adev))
if (!gfx_v8_0_wait_for_idle(ip_block))
gfx_v8_0_cp_enable(adev, false);
else
pr_err("cp is busy, skip halt cp\n");
@ -4911,19 +4912,19 @@ static int gfx_v8_0_hw_fini(void *handle)
return 0;
}
static int gfx_v8_0_suspend(void *handle)
static int gfx_v8_0_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v8_0_hw_fini(handle);
return gfx_v8_0_hw_fini(ip_block);
}
static int gfx_v8_0_resume(void *handle)
static int gfx_v8_0_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v8_0_hw_init(handle);
return gfx_v8_0_hw_init(ip_block);
}
static bool gfx_v8_0_check_soft_reset(void *handle)
static bool gfx_v8_0_check_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
u32 tmp;
@ -4983,9 +4984,9 @@ static bool gfx_v8_0_check_soft_reset(void *handle)
}
}
static int gfx_v8_0_pre_soft_reset(void *handle)
static int gfx_v8_0_pre_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 grbm_soft_reset = 0;
if ((!adev->gfx.grbm_soft_reset) &&
@ -5024,9 +5025,9 @@ static int gfx_v8_0_pre_soft_reset(void *handle)
return 0;
}
static int gfx_v8_0_soft_reset(void *handle)
static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
u32 tmp;
@ -5086,9 +5087,9 @@ static int gfx_v8_0_soft_reset(void *handle)
return 0;
}
static int gfx_v8_0_post_soft_reset(void *handle)
static int gfx_v8_0_post_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 grbm_soft_reset = 0;
if ((!adev->gfx.grbm_soft_reset) &&
@ -5254,9 +5255,9 @@ static const struct amdgpu_gfx_funcs gfx_v8_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v8_0_select_me_pipe_q
};
static int gfx_v8_0_early_init(void *handle)
static int gfx_v8_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.xcc_mask = 1;
adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS;
@ -5271,9 +5272,9 @@ static int gfx_v8_0_early_init(void *handle)
return 0;
}
static int gfx_v8_0_late_init(void *handle)
static int gfx_v8_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -6947,8 +6948,6 @@ static const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
.set_clockgating_state = gfx_v8_0_set_clockgating_state,
.set_powergating_state = gfx_v8_0_set_powergating_state,
.get_clockgating_state = gfx_v8_0_get_clockgating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {

View File

@ -2198,12 +2198,12 @@ static void gfx_v9_0_alloc_ip_dump(struct amdgpu_device *adev)
}
}
static int gfx_v9_0_sw_init(void *handle)
static int gfx_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id;
int xcc_id = 0;
struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
unsigned int hw_prio;
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
@ -2223,6 +2223,18 @@ static int gfx_v9_0_sw_init(void *handle)
}
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(9, 4, 2):
adev->gfx.cleaner_shader_ptr = gfx_9_4_2_cleaner_shader_hex;
adev->gfx.cleaner_shader_size = sizeof(gfx_9_4_2_cleaner_shader_hex);
if (adev->gfx.mec_fw_version >= 88) {
adev->gfx.enable_cleaner_shader = true;
r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
if (r) {
adev->gfx.enable_cleaner_shader = false;
dev_err(adev->dev, "Failed to initialize cleaner shader\n");
}
}
break;
default:
adev->gfx.enable_cleaner_shader = false;
break;
@ -2398,10 +2410,10 @@ static int gfx_v9_0_sw_init(void *handle)
}
static int gfx_v9_0_sw_fini(void *handle)
static int gfx_v9_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (adev->gfx.mcbp && adev->gfx.num_gfx_rings) {
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++)
@ -2418,6 +2430,8 @@ static int gfx_v9_0_sw_fini(void *handle)
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq[0].ring);
amdgpu_gfx_kiq_fini(adev, 0);
amdgpu_gfx_cleaner_shader_sw_fini(adev);
gfx_v9_0_mec_fini(adev);
amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj,
&adev->gfx.rlc.clear_state_gpu_addr,
@ -3184,6 +3198,15 @@ static void gfx_v9_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
{
u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_INVALIDATE_ICACHE, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_INVALIDATE_ICACHE, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_INVALIDATE_ICACHE, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_PIPE0_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_PIPE1_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_PIPE0_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_PIPE1_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_PIPE0_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_PIPE1_RESET, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1);
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1);
@ -3346,7 +3369,7 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
WREG32_SOC15(GC, 0, mmCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
/* set the wb address wether it's enabled or not */
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
WREG32_SOC15(GC, 0, mmCP_RB0_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32_SOC15(GC, 0, mmCP_RB0_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & CP_RB_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK);
@ -3393,7 +3416,15 @@ static void gfx_v9_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL, 0);
} else {
WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL,
(CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
(CP_MEC_CNTL__MEC_INVALIDATE_ICACHE_MASK |
CP_MEC_CNTL__MEC_ME1_PIPE0_RESET_MASK |
CP_MEC_CNTL__MEC_ME1_PIPE1_RESET_MASK |
CP_MEC_CNTL__MEC_ME1_PIPE2_RESET_MASK |
CP_MEC_CNTL__MEC_ME1_PIPE3_RESET_MASK |
CP_MEC_CNTL__MEC_ME2_PIPE0_RESET_MASK |
CP_MEC_CNTL__MEC_ME2_PIPE1_RESET_MASK |
CP_MEC_CNTL__MEC_ME1_HALT_MASK |
CP_MEC_CNTL__MEC_ME2_HALT_MASK));
adev->gfx.kiq[0].ring.sched.ready = false;
}
udelay(50);
@ -3914,6 +3945,10 @@ static int gfx_v9_0_cp_resume(struct amdgpu_device *adev)
return r;
}
if (adev->gfx.num_gfx_rings)
gfx_v9_0_cp_gfx_enable(adev, false);
gfx_v9_0_cp_compute_enable(adev, false);
r = gfx_v9_0_kiq_resume(adev);
if (r)
return r;
@ -3970,10 +4005,10 @@ static void gfx_v9_0_cp_enable(struct amdgpu_device *adev, bool enable)
gfx_v9_0_cp_compute_enable(adev, enable);
}
static int gfx_v9_0_hw_init(void *handle)
static int gfx_v9_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gfx_cleaner_shader_init(adev, adev->gfx.cleaner_shader_size,
adev->gfx.cleaner_shader_ptr);
@ -3999,9 +4034,9 @@ static int gfx_v9_0_hw_init(void *handle)
return r;
}
static int gfx_v9_0_hw_fini(void *handle)
static int gfx_v9_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
@ -4051,14 +4086,14 @@ static int gfx_v9_0_hw_fini(void *handle)
return 0;
}
static int gfx_v9_0_suspend(void *handle)
static int gfx_v9_0_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v9_0_hw_fini(handle);
return gfx_v9_0_hw_fini(ip_block);
}
static int gfx_v9_0_resume(void *handle)
static int gfx_v9_0_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v9_0_hw_init(handle);
return gfx_v9_0_hw_init(ip_block);
}
static bool gfx_v9_0_is_idle(void *handle)
@ -4072,24 +4107,24 @@ static bool gfx_v9_0_is_idle(void *handle)
return true;
}
static int gfx_v9_0_wait_for_idle(void *handle)
static int gfx_v9_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
if (gfx_v9_0_is_idle(handle))
if (gfx_v9_0_is_idle(adev))
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int gfx_v9_0_soft_reset(void *handle)
static int gfx_v9_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 grbm_soft_reset = 0;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* GRBM_STATUS */
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS);
@ -4745,9 +4780,9 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
return r;
}
static int gfx_v9_0_early_init(void *handle)
static int gfx_v9_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.funcs = &gfx_v9_0_gfx_funcs;
@ -4771,9 +4806,9 @@ static int gfx_v9_0_early_init(void *handle)
return gfx_v9_0_init_microcode(adev);
}
static int gfx_v9_0_ecc_late_init(void *handle)
static int gfx_v9_0_ecc_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
/*
@ -4805,9 +4840,9 @@ static int gfx_v9_0_ecc_late_init(void *handle)
return 0;
}
static int gfx_v9_0_late_init(void *handle)
static int gfx_v9_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -4822,7 +4857,7 @@ static int gfx_v9_0_late_init(void *handle)
if (r)
return r;
r = gfx_v9_0_ecc_late_init(handle);
r = gfx_v9_0_ecc_late_init(ip_block);
if (r)
return r;
@ -7167,8 +7202,6 @@ static void gfx_v9_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable)
static void gfx_v9_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
int i;
/* Header itself is a NOP packet */
if (num_nop == 1) {
amdgpu_ring_write(ring, ring->funcs->nop);
@ -7179,8 +7212,7 @@ static void gfx_v9_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));
/* Header is at index 0, followed by num_nops - 1 NOP packet's */
for (i = 1; i < num_nop; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
amdgpu_ring_insert_nop(ring, num_nop - 1);
}
static int gfx_v9_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
@ -7237,10 +7269,6 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
unsigned long flags;
int i, r;
if (!adev->debug_exp_resets &&
!adev->gfx.num_gfx_rings)
return -EINVAL;
if (amdgpu_sriov_vf(adev))
return -EINVAL;
@ -7316,9 +7344,9 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
return amdgpu_ring_test_ring(ring);
}
static void gfx_v9_ip_print(void *handle, struct drm_printer *p)
static void gfx_v9_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_9);
@ -7356,9 +7384,9 @@ static void gfx_v9_ip_print(void *handle, struct drm_printer *p)
}
static void gfx_v9_ip_dump(void *handle)
static void gfx_v9_ip_dump(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k, reg, index = 0;
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_9);

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2018 Advanced Micro Devices, Inc.
* Copyright 2024 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"),
@ -24,3 +24,45 @@
static const u32 __maybe_unused gfx_9_0_cleaner_shader_hex[] = {
/* Add the cleaner shader code here */
};
/* Define the cleaner shader gfx_9_4_2 */
static const u32 gfx_9_4_2_cleaner_shader_hex[] = {
0xbf068100, 0xbf84003b,
0xbf8a0000, 0xb07c0000,
0xbe8200ff, 0x00000078,
0xbf110802, 0x7e000280,
0x7e020280, 0x7e040280,
0x7e060280, 0x7e080280,
0x7e0a0280, 0x7e0c0280,
0x7e0e0280, 0x80828802,
0xbe803202, 0xbf84fff5,
0xbf9c0000, 0xbe8200ff,
0x80000000, 0x86020102,
0xbf840011, 0xbefe00c1,
0xbeff00c1, 0xd28c0001,
0x0001007f, 0xd28d0001,
0x0002027e, 0x10020288,
0xbe8200bf, 0xbefc00c1,
0xd89c2000, 0x00020201,
0xd89c6040, 0x00040401,
0x320202ff, 0x00000400,
0x80828102, 0xbf84fff8,
0xbefc00ff, 0x0000005c,
0xbf800000, 0xbe802c80,
0xbe812c80, 0xbe822c80,
0xbe832c80, 0x80fc847c,
0xbf84fffa, 0xbee60080,
0xbee70080, 0xbeea0180,
0xbeec0180, 0xbeee0180,
0xbef00180, 0xbef20180,
0xbef40180, 0xbef60180,
0xbef80180, 0xbefa0180,
0xbf810000, 0xbf8d0001,
0xbefc00ff, 0x0000005c,
0xbf800000, 0xbe802c80,
0xbe812c80, 0xbe822c80,
0xbe832c80, 0x80fc847c,
0xbf84fffa, 0xbee60080,
0xbee70080, 0xbeea01ff,
0x000000ee, 0xbf810000,
};

View File

@ -0,0 +1,153 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2024 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.
*/
// This shader is to clean LDS, SGPRs and VGPRs. It is first 64 Dwords or 256 bytes of 192 Dwords cleaner shader.
//To turn this shader program on for complitaion change this to main and lower shader main to main_1
// MI200 : Clear SGPRs, VGPRs and LDS
// Uses two kernels launched separately:
// 1. Clean VGPRs, LDS, and lower SGPRs
// Launches one workgroup per CU, each workgroup with 4x wave64 per SIMD in the CU
// Waves are "wave64" and have 128 VGPRs each, which uses all 512 VGPRs per SIMD
// Waves in the workgroup share the 64KB of LDS
// Each wave clears SGPRs 0 - 95. Because there are 4 waves/SIMD, this is physical SGPRs 0-383
// Each wave clears 128 VGPRs, so all 512 in the SIMD
// The first wave of the workgroup clears its 64KB of LDS
// The shader starts with "S_BARRIER" to ensure SPI has launched all waves of the workgroup
// before any wave in the workgroup could end. Without this, it is possible not all SGPRs get cleared.
// 2. Clean remaining SGPRs
// Launches a workgroup with 24 waves per workgroup, yielding 6 waves per SIMD in each CU
// Waves are allocating 96 SGPRs
// CP sets up SPI_RESOURCE_RESERVE_* registers to prevent these waves from allocating SGPRs 0-223.
// As such, these 6 waves per SIMD are allocated physical SGPRs 224-799
// Barriers do not work for >16 waves per workgroup, so we cannot start with S_BARRIER
// Instead, the shader starts with an S_SETHALT 1. Once all waves are launched CP will send unhalt command
// The shader then clears all SGPRs allocated to it, cleaning out physical SGPRs 224-799
shader main
asic(MI200)
type(CS)
wave_size(64)
// Note: original source code from SQ team
// (theorhetical fastest = ~512clks vgpr + 1536 lds + ~128 sgpr = 2176 clks)
s_cmp_eq_u32 s0, 1 // Bit0 is set, sgpr0 is set then clear VGPRS and LDS as FW set COMPUTE_USER_DATA_3
s_cbranch_scc0 label_0023 // Clean VGPRs and LDS if sgpr0 of wave is set, scc = (s3 == 1)
S_BARRIER
s_movk_i32 m0, 0x0000
s_mov_b32 s2, 0x00000078 // Loop 128/8=16 times (loop unrolled for performance)
//
// CLEAR VGPRs
//
s_set_gpr_idx_on s2, 0x8 // enable Dest VGPR indexing
label_0005:
v_mov_b32 v0, 0
v_mov_b32 v1, 0
v_mov_b32 v2, 0
v_mov_b32 v3, 0
v_mov_b32 v4, 0
v_mov_b32 v5, 0
v_mov_b32 v6, 0
v_mov_b32 v7, 0
s_sub_u32 s2, s2, 8
s_set_gpr_idx_idx s2
s_cbranch_scc0 label_0005
s_set_gpr_idx_off
//
//
s_mov_b32 s2, 0x80000000 // Bit31 is first_wave
s_and_b32 s2, s2, s1 // sgpr0 has tg_size (first_wave) term as in ucode only COMPUTE_PGM_RSRC2.tg_size_en is set
s_cbranch_scc0 label_clean_sgpr_1 // Clean LDS if its first wave of ThreadGroup/WorkGroup
// CLEAR LDS
//
s_mov_b32 exec_lo, 0xffffffff
s_mov_b32 exec_hi, 0xffffffff
v_mbcnt_lo_u32_b32 v1, exec_hi, 0 // Set V1 to thread-ID (0..63)
v_mbcnt_hi_u32_b32 v1, exec_lo, v1 // Set V1 to thread-ID (0..63)
v_mul_u32_u24 v1, 0x00000008, v1 // * 8, so each thread is a double-dword address (8byte)
s_mov_b32 s2, 0x00000003f // 64 loop iterations
s_mov_b32 m0, 0xffffffff
// Clear all of LDS space
// Each FirstWave of WorkGroup clears 64kbyte block
label_001F:
ds_write2_b64 v1, v[2:3], v[2:3] offset1:32
ds_write2_b64 v1, v[4:5], v[4:5] offset0:64 offset1:96
v_add_co_u32 v1, vcc, 0x00000400, v1
s_sub_u32 s2, s2, 1
s_cbranch_scc0 label_001F
//
// CLEAR SGPRs
//
label_clean_sgpr_1:
s_mov_b32 m0, 0x0000005c // Loop 96/4=24 times (loop unrolled for performance)
s_nop 0
label_sgpr_loop:
s_movreld_b32 s0, 0
s_movreld_b32 s1, 0
s_movreld_b32 s2, 0
s_movreld_b32 s3, 0
s_sub_u32 m0, m0, 4
s_cbranch_scc0 label_sgpr_loop
//clear vcc, flat scratch
s_mov_b32 flat_scratch_lo, 0 //clear flat scratch lo SGPR
s_mov_b32 flat_scratch_hi, 0 //clear flat scratch hi SGPR
s_mov_b64 vcc, 0 //clear vcc
s_mov_b64 ttmp0, 0 //Clear ttmp0 and ttmp1
s_mov_b64 ttmp2, 0 //Clear ttmp2 and ttmp3
s_mov_b64 ttmp4, 0 //Clear ttmp4 and ttmp5
s_mov_b64 ttmp6, 0 //Clear ttmp6 and ttmp7
s_mov_b64 ttmp8, 0 //Clear ttmp8 and ttmp9
s_mov_b64 ttmp10, 0 //Clear ttmp10 and ttmp11
s_mov_b64 ttmp12, 0 //Clear ttmp12 and ttmp13
s_mov_b64 ttmp14, 0 //Clear ttmp14 and ttmp15
s_endpgm
label_0023:
s_sethalt 1
s_mov_b32 m0, 0x0000005c // Loop 96/4=24 times (loop unrolled for performance)
s_nop 0
label_sgpr_loop1:
s_movreld_b32 s0, 0
s_movreld_b32 s1, 0
s_movreld_b32 s2, 0
s_movreld_b32 s3, 0
s_sub_u32 m0, m0, 4
s_cbranch_scc0 label_sgpr_loop1
//clear vcc, flat scratch
s_mov_b32 flat_scratch_lo, 0 //clear flat scratch lo SGPR
s_mov_b32 flat_scratch_hi, 0 //clear flat scratch hi SGPR
s_mov_b64 vcc, 0xee //clear vcc
s_endpgm
end

View File

@ -1049,10 +1049,10 @@ static void gfx_v9_4_3_alloc_ip_dump(struct amdgpu_device *adev)
}
}
static int gfx_v9_4_3_sw_init(void *handle)
static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block *ip_block)
{
int i, j, k, r, ring_id, xcc_id, num_xcc;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(9, 4, 3):
@ -1165,12 +1165,9 @@ static int gfx_v9_4_3_sw_init(void *handle)
if (r)
return r;
if (!amdgpu_sriov_vf(adev)) {
r = amdgpu_gfx_sysfs_init(adev);
if (r)
return r;
}
r = amdgpu_gfx_sysfs_init(adev);
if (r)
return r;
gfx_v9_4_3_alloc_ip_dump(adev);
@ -1181,10 +1178,10 @@ static int gfx_v9_4_3_sw_init(void *handle)
return 0;
}
static int gfx_v9_4_3_sw_fini(void *handle)
static int gfx_v9_4_3_sw_fini(struct amdgpu_ip_block *ip_block)
{
int i, num_xcc;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
for (i = 0; i < adev->gfx.num_compute_rings * num_xcc; i++)
@ -1201,8 +1198,7 @@ static int gfx_v9_4_3_sw_fini(void *handle)
gfx_v9_4_3_mec_fini(adev);
amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
gfx_v9_4_3_free_microcode(adev);
if (!amdgpu_sriov_vf(adev))
amdgpu_gfx_sysfs_fini(adev);
amdgpu_gfx_sysfs_fini(adev);
amdgpu_gfx_sysfs_isolation_shader_fini(adev);
kfree(adev->gfx.ip_dump_core);
@ -1247,8 +1243,10 @@ static void gfx_v9_4_3_xcc_init_compute_vmid(struct amdgpu_device *adev,
soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, xcc_id));
mutex_unlock(&adev->srbm_mutex);
/* Initialize all compute VMIDs to have no GDS, GWS, or OA
acccess. These should be enabled by FW for target VMIDs. */
/*
* Initialize all compute VMIDs to have no GDS, GWS, or OA
* access. These should be enabled by FW for target VMIDs.
*/
for (i = adev->vm_manager.first_kfd_vmid; i < AMDGPU_NUM_VMID; i++) {
WREG32_SOC15_OFFSET(GC, GET_INST(GC, xcc_id), regGDS_VMID0_BASE, 2 * i, 0);
WREG32_SOC15_OFFSET(GC, GET_INST(GC, xcc_id), regGDS_VMID0_SIZE, 2 * i, 0);
@ -2343,10 +2341,10 @@ static void gfx_v9_4_3_xcc_fini(struct amdgpu_device *adev, int xcc_id)
gfx_v9_4_3_xcc_cp_compute_enable(adev, false, xcc_id);
}
static int gfx_v9_4_3_hw_init(void *handle)
static int gfx_v9_4_3_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gfx_cleaner_shader_init(adev, adev->gfx.cleaner_shader_size,
adev->gfx.cleaner_shader_ptr);
@ -2367,9 +2365,9 @@ static int gfx_v9_4_3_hw_init(void *handle)
return r;
}
static int gfx_v9_4_3_hw_fini(void *handle)
static int gfx_v9_4_3_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i, num_xcc;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
@ -2384,14 +2382,14 @@ static int gfx_v9_4_3_hw_fini(void *handle)
return 0;
}
static int gfx_v9_4_3_suspend(void *handle)
static int gfx_v9_4_3_suspend(struct amdgpu_ip_block *ip_block)
{
return gfx_v9_4_3_hw_fini(handle);
return gfx_v9_4_3_hw_fini(ip_block);
}
static int gfx_v9_4_3_resume(void *handle)
static int gfx_v9_4_3_resume(struct amdgpu_ip_block *ip_block)
{
return gfx_v9_4_3_hw_init(handle);
return gfx_v9_4_3_hw_init(ip_block);
}
static bool gfx_v9_4_3_is_idle(void *handle)
@ -2408,24 +2406,24 @@ static bool gfx_v9_4_3_is_idle(void *handle)
return true;
}
static int gfx_v9_4_3_wait_for_idle(void *handle)
static int gfx_v9_4_3_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
if (gfx_v9_4_3_is_idle(handle))
if (gfx_v9_4_3_is_idle(adev))
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int gfx_v9_4_3_soft_reset(void *handle)
static int gfx_v9_4_3_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 grbm_soft_reset = 0;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* GRBM_STATUS */
tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_STATUS);
@ -2509,9 +2507,9 @@ static void gfx_v9_4_3_ring_emit_gds_switch(struct amdgpu_ring *ring,
(1 << (oa_size + oa_base)) - (1 << oa_base));
}
static int gfx_v9_4_3_early_init(void *handle)
static int gfx_v9_4_3_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
AMDGPU_MAX_COMPUTE_RINGS);
@ -2527,9 +2525,9 @@ static int gfx_v9_4_3_early_init(void *handle)
return gfx_v9_4_3_init_microcode(adev);
}
static int gfx_v9_4_3_late_init(void *handle)
static int gfx_v9_4_3_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
@ -3056,9 +3054,6 @@ static void gfx_v9_4_3_ring_soft_recovery(struct amdgpu_ring *ring,
struct amdgpu_device *adev = ring->adev;
uint32_t value = 0;
if (!adev->debug_exp_resets)
return;
value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03);
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
@ -3574,9 +3569,6 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
unsigned long flags;
int r;
if (!adev->debug_exp_resets)
return -EINVAL;
if (amdgpu_sriov_vf(adev))
return -EINVAL;
@ -4567,8 +4559,6 @@ static void gfx_v9_4_3_enable_watchdog_timer(struct amdgpu_device *adev)
static void gfx_v9_4_3_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
int i;
/* Header itself is a NOP packet */
if (num_nop == 1) {
amdgpu_ring_write(ring, ring->funcs->nop);
@ -4579,13 +4569,12 @@ static void gfx_v9_4_3_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_no
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));
/* Header is at index 0, followed by num_nops - 1 NOP packet's */
for (i = 1; i < num_nop; i++)
amdgpu_ring_write(ring, ring->funcs->nop);
amdgpu_ring_insert_nop(ring, num_nop - 1);
}
static void gfx_v9_4_3_ip_print(void *handle, struct drm_printer *p)
static void gfx_v9_4_3_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k;
uint32_t xcc_id, xcc_offset, inst_offset;
uint32_t num_xcc, reg, num_inst;
@ -4643,9 +4632,9 @@ static void gfx_v9_4_3_ip_print(void *handle, struct drm_printer *p)
}
}
static void gfx_v9_4_3_ip_dump(void *handle)
static void gfx_v9_4_3_ip_dump(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
uint32_t i, j, k;
uint32_t num_xcc, reg, num_inst;
uint32_t xcc_id, xcc_offset, inst_offset;

View File

@ -175,7 +175,10 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
addr, entry->client_id,
soc15_ih_clientid_name[entry->client_id]);
if (!amdgpu_sriov_vf(adev))
/* Only print L2 fault status if the status register could be read and
* contains useful information
*/
if (status != 0)
hub->vmhub_funcs->print_l2_protection_fault_status(adev,
status);
@ -630,9 +633,9 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
}
static int gmc_v10_0_early_init(void *handle)
static int gmc_v10_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v10_0_set_mmhub_funcs(adev);
gmc_v10_0_set_gfxhub_funcs(adev);
@ -651,9 +654,9 @@ static int gmc_v10_0_early_init(void *handle)
return 0;
}
static int gmc_v10_0_late_init(void *handle)
static int gmc_v10_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_gmc_allocate_vm_inv_eng(adev);
@ -769,10 +772,10 @@ static int gmc_v10_0_gart_init(struct amdgpu_device *adev)
return amdgpu_gart_table_vram_alloc(adev);
}
static int gmc_v10_0_sw_init(void *handle)
static int gmc_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->gfxhub.funcs->init(adev);
@ -920,9 +923,9 @@ static void gmc_v10_0_gart_fini(struct amdgpu_device *adev)
amdgpu_gart_table_vram_free(adev);
}
static int gmc_v10_0_sw_fini(void *handle)
static int gmc_v10_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_vm_manager_fini(adev);
gmc_v10_0_gart_fini(adev);
@ -985,9 +988,9 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
return 0;
}
static int gmc_v10_0_hw_init(void *handle)
static int gmc_v10_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
@ -1032,9 +1035,9 @@ static void gmc_v10_0_gart_disable(struct amdgpu_device *adev)
adev->mmhub.funcs->gart_disable(adev);
}
static int gmc_v10_0_hw_fini(void *handle)
static int gmc_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v10_0_gart_disable(adev);
@ -1053,25 +1056,22 @@ static int gmc_v10_0_hw_fini(void *handle)
return 0;
}
static int gmc_v10_0_suspend(void *handle)
static int gmc_v10_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v10_0_hw_fini(adev);
gmc_v10_0_hw_fini(ip_block);
return 0;
}
static int gmc_v10_0_resume(void *handle)
static int gmc_v10_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v10_0_hw_init(adev);
r = gmc_v10_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -1082,17 +1082,12 @@ static bool gmc_v10_0_is_idle(void *handle)
return true;
}
static int gmc_v10_0_wait_for_idle(void *handle)
static int gmc_v10_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* There is no need to wait for MC idle in GMC v10.*/
return 0;
}
static int gmc_v10_0_soft_reset(void *handle)
{
return 0;
}
static int gmc_v10_0_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -1154,7 +1149,6 @@ const struct amd_ip_funcs gmc_v10_0_ip_funcs = {
.resume = gmc_v10_0_resume,
.is_idle = gmc_v10_0_is_idle,
.wait_for_idle = gmc_v10_0_wait_for_idle,
.soft_reset = gmc_v10_0_soft_reset,
.set_clockgating_state = gmc_v10_0_set_clockgating_state,
.set_powergating_state = gmc_v10_0_set_powergating_state,
.get_clockgating_state = gmc_v10_0_get_clockgating_state,

View File

@ -144,7 +144,10 @@ static int gmc_v11_0_process_interrupt(struct amdgpu_device *adev,
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
addr, entry->client_id);
if (!amdgpu_sriov_vf(adev))
/* Only print L2 fault status if the status register could be read and
* contains useful information
*/
if (status != 0)
hub->vmhub_funcs->print_l2_protection_fault_status(adev, status);
}
@ -601,9 +604,9 @@ static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
}
}
static int gmc_v11_0_early_init(void *handle)
static int gmc_v11_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v11_0_set_gfxhub_funcs(adev);
gmc_v11_0_set_mmhub_funcs(adev);
@ -622,9 +625,9 @@ static int gmc_v11_0_early_init(void *handle)
return 0;
}
static int gmc_v11_0_late_init(void *handle)
static int gmc_v11_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_gmc_allocate_vm_inv_eng(adev);
@ -729,10 +732,10 @@ static int gmc_v11_0_gart_init(struct amdgpu_device *adev)
return amdgpu_gart_table_vram_alloc(adev);
}
static int gmc_v11_0_sw_init(void *handle)
static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->mmhub.funcs->init(adev);
@ -849,9 +852,9 @@ static void gmc_v11_0_gart_fini(struct amdgpu_device *adev)
amdgpu_gart_table_vram_free(adev);
}
static int gmc_v11_0_sw_fini(void *handle)
static int gmc_v11_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_vm_manager_fini(adev);
gmc_v11_0_gart_fini(adev);
@ -908,9 +911,9 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device *adev)
return 0;
}
static int gmc_v11_0_hw_init(void *handle)
static int gmc_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
@ -940,9 +943,9 @@ static void gmc_v11_0_gart_disable(struct amdgpu_device *adev)
adev->mmhub.funcs->gart_disable(adev);
}
static int gmc_v11_0_hw_fini(void *handle)
static int gmc_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_sriov_vf(adev)) {
/* full access mode, so don't touch any GMC register */
@ -961,25 +964,22 @@ static int gmc_v11_0_hw_fini(void *handle)
return 0;
}
static int gmc_v11_0_suspend(void *handle)
static int gmc_v11_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v11_0_hw_fini(adev);
gmc_v11_0_hw_fini(ip_block);
return 0;
}
static int gmc_v11_0_resume(void *handle)
static int gmc_v11_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v11_0_hw_init(adev);
r = gmc_v11_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -990,17 +990,12 @@ static bool gmc_v11_0_is_idle(void *handle)
return true;
}
static int gmc_v11_0_wait_for_idle(void *handle)
static int gmc_v11_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* There is no need to wait for MC idle in GMC v11.*/
return 0;
}
static int gmc_v11_0_soft_reset(void *handle)
{
return 0;
}
static int gmc_v11_0_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -1041,7 +1036,6 @@ const struct amd_ip_funcs gmc_v11_0_ip_funcs = {
.resume = gmc_v11_0_resume,
.is_idle = gmc_v11_0_is_idle,
.wait_for_idle = gmc_v11_0_wait_for_idle,
.soft_reset = gmc_v11_0_soft_reset,
.set_clockgating_state = gmc_v11_0_set_clockgating_state,
.set_powergating_state = gmc_v11_0_set_powergating_state,
.get_clockgating_state = gmc_v11_0_get_clockgating_state,

View File

@ -137,7 +137,10 @@ static int gmc_v12_0_process_interrupt(struct amdgpu_device *adev,
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
addr, entry->client_id);
if (!amdgpu_sriov_vf(adev))
/* Only print L2 fault status if the status register could be read and
* contains useful information
*/
if (status != 0)
hub->vmhub_funcs->print_l2_protection_fault_status(adev, status);
}
@ -604,9 +607,9 @@ static void gmc_v12_0_set_gfxhub_funcs(struct amdgpu_device *adev)
}
}
static int gmc_v12_0_early_init(void *handle)
static int gmc_v12_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v12_0_set_gfxhub_funcs(adev);
gmc_v12_0_set_mmhub_funcs(adev);
@ -624,9 +627,9 @@ static int gmc_v12_0_early_init(void *handle)
return 0;
}
static int gmc_v12_0_late_init(void *handle)
static int gmc_v12_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_gmc_allocate_vm_inv_eng(adev);
@ -731,10 +734,10 @@ static int gmc_v12_0_gart_init(struct amdgpu_device *adev)
return amdgpu_gart_table_vram_alloc(adev);
}
static int gmc_v12_0_sw_init(void *handle)
static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->mmhub.funcs->init(adev);
@ -841,9 +844,9 @@ static void gmc_v12_0_gart_fini(struct amdgpu_device *adev)
amdgpu_gart_table_vram_free(adev);
}
static int gmc_v12_0_sw_fini(void *handle)
static int gmc_v12_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_vm_manager_fini(adev);
gmc_v12_0_gart_fini(adev);
@ -894,10 +897,10 @@ static int gmc_v12_0_gart_enable(struct amdgpu_device *adev)
return 0;
}
static int gmc_v12_0_hw_init(void *handle)
static int gmc_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
/* The sequence of these two function calls matters.*/
gmc_v12_0_init_golden_registers(adev);
@ -924,9 +927,9 @@ static void gmc_v12_0_gart_disable(struct amdgpu_device *adev)
adev->mmhub.funcs->gart_disable(adev);
}
static int gmc_v12_0_hw_fini(void *handle)
static int gmc_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_sriov_vf(adev)) {
/* full access mode, so don't touch any GMC register */
@ -945,25 +948,22 @@ static int gmc_v12_0_hw_fini(void *handle)
return 0;
}
static int gmc_v12_0_suspend(void *handle)
static int gmc_v12_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v12_0_hw_fini(adev);
gmc_v12_0_hw_fini(ip_block);
return 0;
}
static int gmc_v12_0_resume(void *handle)
static int gmc_v12_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v12_0_hw_init(adev);
r = gmc_v12_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -974,17 +974,12 @@ static bool gmc_v12_0_is_idle(void *handle)
return true;
}
static int gmc_v12_0_wait_for_idle(void *handle)
static int gmc_v12_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* There is no need to wait for MC idle in GMC v11.*/
return 0;
}
static int gmc_v12_0_soft_reset(void *handle)
{
return 0;
}
static int gmc_v12_0_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@ -1025,7 +1020,6 @@ const struct amd_ip_funcs gmc_v12_0_ip_funcs = {
.resume = gmc_v12_0_resume,
.is_idle = gmc_v12_0_is_idle,
.wait_for_idle = gmc_v12_0_wait_for_idle,
.soft_reset = gmc_v12_0_soft_reset,
.set_clockgating_state = gmc_v12_0_set_clockgating_state,
.set_powergating_state = gmc_v12_0_set_powergating_state,
.get_clockgating_state = gmc_v12_0_get_clockgating_state,

View File

@ -43,7 +43,7 @@
static void gmc_v6_0_set_gmc_funcs(struct amdgpu_device *adev);
static void gmc_v6_0_set_irq_funcs(struct amdgpu_device *adev);
static int gmc_v6_0_wait_for_idle(void *handle);
static int gmc_v6_0_wait_for_idle(struct amdgpu_ip_block *ip_block);
MODULE_FIRMWARE("amdgpu/tahiti_mc.bin");
MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin");
@ -64,8 +64,13 @@ MODULE_FIRMWARE("amdgpu/si58_mc.bin");
static void gmc_v6_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
struct amdgpu_ip_block *ip_block;
gmc_v6_0_wait_for_idle((void *)adev);
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC);
if (!ip_block)
return;
gmc_v6_0_wait_for_idle(ip_block);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) {
@ -213,6 +218,8 @@ static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
{
int i, j;
struct amdgpu_ip_block *ip_block;
/* Initialize HDP */
for (i = 0, j = 0; i < 32; i++, j += 0x6) {
@ -224,7 +231,11 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
if (gmc_v6_0_wait_for_idle((void *)adev))
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC);
if (!ip_block)
return;
if (gmc_v6_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
if (adev->mode_info.num_crtc) {
@ -251,7 +262,7 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
WREG32(mmMC_VM_AGP_TOP, adev->gmc.agp_end >> 22);
WREG32(mmMC_VM_AGP_BOT, adev->gmc.agp_start >> 22);
if (gmc_v6_0_wait_for_idle((void *)adev))
if (gmc_v6_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
@ -762,9 +773,9 @@ static int gmc_v6_0_convert_vram_type(int mc_seq_vram_type)
}
}
static int gmc_v6_0_early_init(void *handle)
static int gmc_v6_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v6_0_set_gmc_funcs(adev);
gmc_v6_0_set_irq_funcs(adev);
@ -772,9 +783,9 @@ static int gmc_v6_0_early_init(void *handle)
return 0;
}
static int gmc_v6_0_late_init(void *handle)
static int gmc_v6_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
@ -799,10 +810,10 @@ static unsigned int gmc_v6_0_get_vbios_fb_size(struct amdgpu_device *adev)
return size;
}
static int gmc_v6_0_sw_init(void *handle)
static int gmc_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
set_bit(AMDGPU_GFXHUB(0), adev->vmhubs_mask);
@ -876,9 +887,9 @@ static int gmc_v6_0_sw_init(void *handle)
return 0;
}
static int gmc_v6_0_sw_fini(void *handle)
static int gmc_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev);
@ -889,10 +900,10 @@ static int gmc_v6_0_sw_fini(void *handle)
return 0;
}
static int gmc_v6_0_hw_init(void *handle)
static int gmc_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v6_0_mc_program(adev);
@ -914,9 +925,9 @@ static int gmc_v6_0_hw_init(void *handle)
return 0;
}
static int gmc_v6_0_hw_fini(void *handle)
static int gmc_v6_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
gmc_v6_0_gart_disable(adev);
@ -924,21 +935,19 @@ static int gmc_v6_0_hw_fini(void *handle)
return 0;
}
static int gmc_v6_0_suspend(void *handle)
static int gmc_v6_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v6_0_hw_fini(adev);
gmc_v6_0_hw_fini(ip_block);
return 0;
}
static int gmc_v6_0_resume(void *handle)
static int gmc_v6_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = gmc_v6_0_hw_init(adev);
r = gmc_v6_0_hw_init(ip_block);
if (r)
return r;
@ -950,6 +959,7 @@ static int gmc_v6_0_resume(void *handle)
static bool gmc_v6_0_is_idle(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & (SRBM_STATUS__MCB_BUSY_MASK | SRBM_STATUS__MCB_NON_DISPLAY_BUSY_MASK |
@ -959,13 +969,13 @@ static bool gmc_v6_0_is_idle(void *handle)
return true;
}
static int gmc_v6_0_wait_for_idle(void *handle)
static int gmc_v6_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
if (gmc_v6_0_is_idle(handle))
if (gmc_v6_0_is_idle(adev))
return 0;
udelay(1);
}
@ -973,9 +983,10 @@ static int gmc_v6_0_wait_for_idle(void *handle)
}
static int gmc_v6_0_soft_reset(void *handle)
static int gmc_v6_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@ -992,7 +1003,8 @@ static int gmc_v6_0_soft_reset(void *handle)
if (srbm_soft_reset) {
gmc_v6_0_mc_stop(adev);
if (gmc_v6_0_wait_for_idle(adev))
if (gmc_v6_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
tmp = RREG32(mmSRBM_SOFT_RESET);
@ -1109,8 +1121,6 @@ static const struct amd_ip_funcs gmc_v6_0_ip_funcs = {
.soft_reset = gmc_v6_0_soft_reset,
.set_clockgating_state = gmc_v6_0_set_clockgating_state,
.set_powergating_state = gmc_v6_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_gmc_funcs gmc_v6_0_gmc_funcs = {

View File

@ -52,7 +52,7 @@
static void gmc_v7_0_set_gmc_funcs(struct amdgpu_device *adev);
static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev);
static int gmc_v7_0_wait_for_idle(void *handle);
static int gmc_v7_0_wait_for_idle(struct amdgpu_ip_block *ip_block);
MODULE_FIRMWARE("amdgpu/bonaire_mc.bin");
MODULE_FIRMWARE("amdgpu/hawaii_mc.bin");
@ -921,9 +921,9 @@ static int gmc_v7_0_convert_vram_type(int mc_seq_vram_type)
}
}
static int gmc_v7_0_early_init(void *handle)
static int gmc_v7_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v7_0_set_gmc_funcs(adev);
gmc_v7_0_set_irq_funcs(adev);
@ -940,9 +940,9 @@ static int gmc_v7_0_early_init(void *handle)
return 0;
}
static int gmc_v7_0_late_init(void *handle)
static int gmc_v7_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
@ -968,10 +968,10 @@ static unsigned int gmc_v7_0_get_vbios_fb_size(struct amdgpu_device *adev)
return size;
}
static int gmc_v7_0_sw_init(void *handle)
static int gmc_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
set_bit(AMDGPU_GFXHUB(0), adev->vmhubs_mask);
@ -1060,9 +1060,9 @@ static int gmc_v7_0_sw_init(void *handle)
return 0;
}
static int gmc_v7_0_sw_fini(void *handle)
static int gmc_v7_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev);
@ -1074,10 +1074,10 @@ static int gmc_v7_0_sw_fini(void *handle)
return 0;
}
static int gmc_v7_0_hw_init(void *handle)
static int gmc_v7_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v7_0_init_golden_registers(adev);
@ -1101,9 +1101,9 @@ static int gmc_v7_0_hw_init(void *handle)
return 0;
}
static int gmc_v7_0_hw_fini(void *handle)
static int gmc_v7_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
gmc_v7_0_gart_disable(adev);
@ -1111,25 +1111,22 @@ static int gmc_v7_0_hw_fini(void *handle)
return 0;
}
static int gmc_v7_0_suspend(void *handle)
static int gmc_v7_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v7_0_hw_fini(adev);
gmc_v7_0_hw_fini(ip_block);
return 0;
}
static int gmc_v7_0_resume(void *handle)
static int gmc_v7_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v7_0_hw_init(adev);
r = gmc_v7_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -1146,11 +1143,11 @@ static bool gmc_v7_0_is_idle(void *handle)
return true;
}
static int gmc_v7_0_wait_for_idle(void *handle)
static int gmc_v7_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned int i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -1167,9 +1164,9 @@ static int gmc_v7_0_wait_for_idle(void *handle)
}
static int gmc_v7_0_soft_reset(void *handle)
static int gmc_v7_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@ -1351,8 +1348,6 @@ static const struct amd_ip_funcs gmc_v7_0_ip_funcs = {
.soft_reset = gmc_v7_0_soft_reset,
.set_clockgating_state = gmc_v7_0_set_clockgating_state,
.set_powergating_state = gmc_v7_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_gmc_funcs gmc_v7_0_gmc_funcs = {

View File

@ -53,7 +53,7 @@
static void gmc_v8_0_set_gmc_funcs(struct amdgpu_device *adev);
static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev);
static int gmc_v8_0_wait_for_idle(void *handle);
static int gmc_v8_0_wait_for_idle(struct amdgpu_ip_block *ip_block);
MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
MODULE_FIRMWARE("amdgpu/polaris11_mc.bin");
@ -170,8 +170,13 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
static void gmc_v8_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
struct amdgpu_ip_block *ip_block;
gmc_v8_0_wait_for_idle(adev);
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC);
if (!ip_block)
return;
gmc_v8_0_wait_for_idle(ip_block);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) {
@ -426,6 +431,7 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
*/
static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
{
struct amdgpu_ip_block *ip_block;
u32 tmp;
int i, j;
@ -439,7 +445,11 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
if (gmc_v8_0_wait_for_idle((void *)adev))
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC);
if (!ip_block)
return;
if (gmc_v8_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
if (adev->mode_info.num_crtc) {
@ -474,7 +484,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, adev->gmc.agp_end >> 22);
WREG32(mmMC_VM_AGP_BOT, adev->gmc.agp_start >> 22);
if (gmc_v8_0_wait_for_idle((void *)adev))
if (gmc_v8_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
@ -1027,9 +1037,9 @@ static int gmc_v8_0_convert_vram_type(int mc_seq_vram_type)
}
}
static int gmc_v8_0_early_init(void *handle)
static int gmc_v8_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v8_0_set_gmc_funcs(adev);
gmc_v8_0_set_irq_funcs(adev);
@ -1046,9 +1056,9 @@ static int gmc_v8_0_early_init(void *handle)
return 0;
}
static int gmc_v8_0_late_init(void *handle)
static int gmc_v8_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
@ -1076,10 +1086,10 @@ static unsigned int gmc_v8_0_get_vbios_fb_size(struct amdgpu_device *adev)
#define mmMC_SEQ_MISC0_FIJI 0xA71
static int gmc_v8_0_sw_init(void *handle)
static int gmc_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
set_bit(AMDGPU_GFXHUB(0), adev->vmhubs_mask);
@ -1173,9 +1183,9 @@ static int gmc_v8_0_sw_init(void *handle)
return 0;
}
static int gmc_v8_0_sw_fini(void *handle)
static int gmc_v8_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev);
@ -1187,10 +1197,10 @@ static int gmc_v8_0_sw_fini(void *handle)
return 0;
}
static int gmc_v8_0_hw_init(void *handle)
static int gmc_v8_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v8_0_init_golden_registers(adev);
@ -1222,9 +1232,9 @@ static int gmc_v8_0_hw_init(void *handle)
return 0;
}
static int gmc_v8_0_hw_fini(void *handle)
static int gmc_v8_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
gmc_v8_0_gart_disable(adev);
@ -1232,25 +1242,22 @@ static int gmc_v8_0_hw_fini(void *handle)
return 0;
}
static int gmc_v8_0_suspend(void *handle)
static int gmc_v8_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v8_0_hw_fini(adev);
gmc_v8_0_hw_fini(ip_block);
return 0;
}
static int gmc_v8_0_resume(void *handle)
static int gmc_v8_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v8_0_hw_init(adev);
r = gmc_v8_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -1267,11 +1274,11 @@ static bool gmc_v8_0_is_idle(void *handle)
return true;
}
static int gmc_v8_0_wait_for_idle(void *handle)
static int gmc_v8_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned int i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -1289,10 +1296,10 @@ static int gmc_v8_0_wait_for_idle(void *handle)
}
static bool gmc_v8_0_check_soft_reset(void *handle)
static bool gmc_v8_0_check_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__VMC_BUSY_MASK)
@ -1316,23 +1323,23 @@ static bool gmc_v8_0_check_soft_reset(void *handle)
return false;
}
static int gmc_v8_0_pre_soft_reset(void *handle)
static int gmc_v8_0_pre_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (!adev->gmc.srbm_soft_reset)
return 0;
gmc_v8_0_mc_stop(adev);
if (gmc_v8_0_wait_for_idle(adev))
if (gmc_v8_0_wait_for_idle(ip_block))
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
return 0;
}
static int gmc_v8_0_soft_reset(void *handle)
static int gmc_v8_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 srbm_soft_reset;
if (!adev->gmc.srbm_soft_reset)
@ -1361,9 +1368,9 @@ static int gmc_v8_0_soft_reset(void *handle)
return 0;
}
static int gmc_v8_0_post_soft_reset(void *handle)
static int gmc_v8_0_post_soft_reset(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (!adev->gmc.srbm_soft_reset)
return 0;
@ -1715,8 +1722,6 @@ static const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
.set_clockgating_state = gmc_v8_0_set_clockgating_state,
.set_powergating_state = gmc_v8_0_set_powergating_state,
.get_clockgating_state = gmc_v8_0_get_clockgating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_gmc_funcs gmc_v8_0_gmc_funcs = {

View File

@ -672,6 +672,12 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
(amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2)))
return 0;
/* Only print L2 fault status if the status register could be read and
* contains useful information
*/
if (!status)
return 0;
if (!amdgpu_sriov_vf(adev))
WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
@ -1386,15 +1392,45 @@ gmc_v9_0_get_memory_partition(struct amdgpu_device *adev, u32 *supp_modes)
return mode;
}
static enum amdgpu_memory_partition
gmc_v9_0_query_vf_memory_partition(struct amdgpu_device *adev)
{
switch (adev->gmc.num_mem_partitions) {
case 0:
return UNKNOWN_MEMORY_PARTITION_MODE;
case 1:
return AMDGPU_NPS1_PARTITION_MODE;
case 2:
return AMDGPU_NPS2_PARTITION_MODE;
case 4:
return AMDGPU_NPS4_PARTITION_MODE;
default:
return AMDGPU_NPS1_PARTITION_MODE;
}
return AMDGPU_NPS1_PARTITION_MODE;
}
static enum amdgpu_memory_partition
gmc_v9_0_query_memory_partition(struct amdgpu_device *adev)
{
if (amdgpu_sriov_vf(adev))
return AMDGPU_NPS1_PARTITION_MODE;
return gmc_v9_0_query_vf_memory_partition(adev);
return gmc_v9_0_get_memory_partition(adev, NULL);
}
static bool gmc_v9_0_need_reset_on_init(struct amdgpu_device *adev)
{
if (adev->nbio.funcs && adev->nbio.funcs->is_nps_switch_requested &&
adev->nbio.funcs->is_nps_switch_requested(adev)) {
adev->gmc.reset_flags |= AMDGPU_GMC_INIT_RESET_NPS;
return true;
}
return false;
}
static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
.flush_gpu_tlb = gmc_v9_0_flush_gpu_tlb,
.flush_gpu_tlb_pasid = gmc_v9_0_flush_gpu_tlb_pasid,
@ -1406,6 +1442,8 @@ static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
.override_vm_pte_flags = gmc_v9_0_override_vm_pte_flags,
.get_vbios_fb_size = gmc_v9_0_get_vbios_fb_size,
.query_mem_partition_mode = &gmc_v9_0_query_memory_partition,
.request_mem_partition_mode = &amdgpu_gmc_request_memory_partition,
.need_reset_on_init = &gmc_v9_0_need_reset_on_init,
};
static void gmc_v9_0_set_gmc_funcs(struct amdgpu_device *adev)
@ -1545,9 +1583,31 @@ static void gmc_v9_0_set_xgmi_ras_funcs(struct amdgpu_device *adev)
adev->gmc.xgmi.ras = &xgmi_ras;
}
static int gmc_v9_0_early_init(void *handle)
static void gmc_v9_0_init_nps_details(struct amdgpu_device *adev)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->gmc.supported_nps_modes = 0;
if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
return;
/*TODO: Check PSP version also which supports NPS switch. Otherwise keep
* supported modes as 0.
*/
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(9, 4, 3):
case IP_VERSION(9, 4, 4):
adev->gmc.supported_nps_modes =
BIT(AMDGPU_NPS1_PARTITION_MODE) |
BIT(AMDGPU_NPS4_PARTITION_MODE);
break;
default:
break;
}
}
static int gmc_v9_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
/*
* 9.4.0, 9.4.1 and 9.4.3 don't have XGMI defined
@ -1601,9 +1661,9 @@ static int gmc_v9_0_early_init(void *handle)
return 0;
}
static int gmc_v9_0_late_init(void *handle)
static int gmc_v9_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_gmc_allocate_vm_inv_eng(adev);
@ -1900,6 +1960,8 @@ gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev,
switch (mode) {
case UNKNOWN_MEMORY_PARTITION_MODE:
adev->gmc.num_mem_partitions = 0;
break;
case AMDGPU_NPS1_PARTITION_MODE:
adev->gmc.num_mem_partitions = 1;
break;
@ -1919,7 +1981,7 @@ gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev,
/* Use NPS range info, if populated */
r = amdgpu_gmc_get_nps_memranges(adev, mem_ranges,
adev->gmc.num_mem_partitions);
&adev->gmc.num_mem_partitions);
if (!r) {
l = 0;
for (i = 1; i < adev->gmc.num_mem_partitions; ++i) {
@ -1929,6 +1991,11 @@ gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev,
}
} else {
if (!adev->gmc.num_mem_partitions) {
dev_err(adev->dev,
"Not able to detect NPS mode, fall back to NPS1");
adev->gmc.num_mem_partitions = 1;
}
/* Fallback to sw based calculation */
size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
size /= adev->gmc.num_mem_partitions;
@ -1987,10 +2054,10 @@ static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev)
adev->gmc.vram_width = 128 * 64;
}
static int gmc_v9_0_sw_init(void *handle)
static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, vram_width = 0, vram_type = 0, vram_vendor = 0, dma_addr_bits;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
unsigned long inst_mask = adev->aid_mask;
adev->gfxhub.funcs->init(adev);
@ -2165,6 +2232,7 @@ static int gmc_v9_0_sw_init(void *handle)
if (r)
return r;
gmc_v9_0_init_nps_details(adev);
/*
* number of VMs
* VMID 0 is reserved for System
@ -2198,9 +2266,9 @@ static int gmc_v9_0_sw_init(void *handle)
return 0;
}
static int gmc_v9_0_sw_fini(void *handle)
static int gmc_v9_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4))
@ -2308,9 +2376,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
return 0;
}
static int gmc_v9_0_hw_init(void *handle)
static int gmc_v9_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
bool value;
int i, r;
@ -2393,9 +2461,9 @@ static void gmc_v9_0_gart_disable(struct amdgpu_device *adev)
adev->mmhub.funcs->gart_disable(adev);
}
static int gmc_v9_0_hw_fini(void *handle)
static int gmc_v9_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
gmc_v9_0_gart_disable(adev);
@ -2413,32 +2481,44 @@ static int gmc_v9_0_hw_fini(void *handle)
if (adev->mmhub.funcs->update_power_gating)
adev->mmhub.funcs->update_power_gating(adev, false);
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
/*
* For minimal init, late_init is not called, hence VM fault/RAS irqs
* are not enabled.
*/
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
if (adev->gmc.ecc_irq.funcs &&
amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC))
amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0);
if (adev->gmc.ecc_irq.funcs &&
amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC))
amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0);
}
return 0;
}
static int gmc_v9_0_suspend(void *handle)
static int gmc_v9_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return gmc_v9_0_hw_fini(adev);
return gmc_v9_0_hw_fini(ip_block);
}
static int gmc_v9_0_resume(void *handle)
static int gmc_v9_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = gmc_v9_0_hw_init(adev);
/* If a reset is done for NPS mode switch, read the memory range
* information again.
*/
if (adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS) {
gmc_v9_0_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
adev->gmc.reset_flags &= ~AMDGPU_GMC_INIT_RESET_NPS;
}
r = gmc_v9_0_hw_init(ip_block);
if (r)
return r;
amdgpu_vmid_reset_all(adev);
amdgpu_vmid_reset_all(ip_block->adev);
return 0;
}
@ -2449,13 +2529,13 @@ static bool gmc_v9_0_is_idle(void *handle)
return true;
}
static int gmc_v9_0_wait_for_idle(void *handle)
static int gmc_v9_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* There is no need to wait for MC idle in GMC v9.*/
return 0;
}
static int gmc_v9_0_soft_reset(void *handle)
static int gmc_v9_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
/* XXX for emulation.*/
return 0;

View File

@ -273,9 +273,9 @@ static void iceland_ih_set_rptr(struct amdgpu_device *adev,
WREG32(mmIH_RB_RPTR, ih->rptr);
}
static int iceland_ih_early_init(void *handle)
static int iceland_ih_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
ret = amdgpu_irq_add_domain(adev);
@ -287,10 +287,10 @@ static int iceland_ih_early_init(void *handle)
return 0;
}
static int iceland_ih_sw_init(void *handle)
static int iceland_ih_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
if (r)
@ -301,9 +301,9 @@ static int iceland_ih_sw_init(void *handle)
return r;
}
static int iceland_ih_sw_fini(void *handle)
static int iceland_ih_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
@ -311,34 +311,28 @@ static int iceland_ih_sw_fini(void *handle)
return 0;
}
static int iceland_ih_hw_init(void *handle)
static int iceland_ih_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
return iceland_ih_irq_init(adev);
}
static int iceland_ih_hw_fini(void *handle)
static int iceland_ih_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
iceland_ih_irq_disable(adev);
iceland_ih_irq_disable(ip_block->adev);
return 0;
}
static int iceland_ih_suspend(void *handle)
static int iceland_ih_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return iceland_ih_hw_fini(adev);
return iceland_ih_hw_fini(ip_block);
}
static int iceland_ih_resume(void *handle)
static int iceland_ih_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return iceland_ih_hw_init(adev);
return iceland_ih_hw_init(ip_block);
}
static bool iceland_ih_is_idle(void *handle)
@ -352,11 +346,11 @@ static bool iceland_ih_is_idle(void *handle)
return true;
}
static int iceland_ih_wait_for_idle(void *handle)
static int iceland_ih_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
unsigned i;
u32 tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
@ -368,10 +362,10 @@ static int iceland_ih_wait_for_idle(void *handle)
return -ETIMEDOUT;
}
static int iceland_ih_soft_reset(void *handle)
static int iceland_ih_soft_reset(struct amdgpu_ip_block *ip_block)
{
u32 srbm_soft_reset = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__IH_BUSY_MASK)
@ -413,7 +407,6 @@ static int iceland_ih_set_powergating_state(void *handle,
static const struct amd_ip_funcs iceland_ih_ip_funcs = {
.name = "iceland_ih",
.early_init = iceland_ih_early_init,
.late_init = NULL,
.sw_init = iceland_ih_sw_init,
.sw_fini = iceland_ih_sw_fini,
.hw_init = iceland_ih_hw_init,
@ -425,8 +418,6 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = {
.soft_reset = iceland_ih_soft_reset,
.set_clockgating_state = iceland_ih_set_clockgating_state,
.set_powergating_state = iceland_ih_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs iceland_ih_funcs = {

View File

@ -559,19 +559,19 @@ static void ih_v6_0_set_self_irq_funcs(struct amdgpu_device *adev)
adev->irq.self_irq.funcs = &ih_v6_0_self_irq_funcs;
}
static int ih_v6_0_early_init(void *handle)
static int ih_v6_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
ih_v6_0_set_interrupt_funcs(adev);
ih_v6_0_set_self_irq_funcs(adev);
return 0;
}
static int ih_v6_0_sw_init(void *handle)
static int ih_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
bool use_bus_addr;
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_IH, 0,
@ -614,19 +614,19 @@ static int ih_v6_0_sw_init(void *handle)
return r;
}
static int ih_v6_0_sw_fini(void *handle)
static int ih_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
return 0;
}
static int ih_v6_0_hw_init(void *handle)
static int ih_v6_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = ih_v6_0_irq_init(adev);
if (r)
@ -635,27 +635,21 @@ static int ih_v6_0_hw_init(void *handle)
return 0;
}
static int ih_v6_0_hw_fini(void *handle)
static int ih_v6_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
ih_v6_0_irq_disable(adev);
ih_v6_0_irq_disable(ip_block->adev);
return 0;
}
static int ih_v6_0_suspend(void *handle)
static int ih_v6_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v6_0_hw_fini(adev);
return ih_v6_0_hw_fini(ip_block);
}
static int ih_v6_0_resume(void *handle)
static int ih_v6_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v6_0_hw_init(adev);
return ih_v6_0_hw_init(ip_block);
}
static bool ih_v6_0_is_idle(void *handle)
@ -664,13 +658,13 @@ static bool ih_v6_0_is_idle(void *handle)
return true;
}
static int ih_v6_0_wait_for_idle(void *handle)
static int ih_v6_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* todo */
return -ETIMEDOUT;
}
static int ih_v6_0_soft_reset(void *handle)
static int ih_v6_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
/* todo */
return 0;
@ -785,7 +779,6 @@ static void ih_v6_0_get_clockgating_state(void *handle, u64 *flags)
static const struct amd_ip_funcs ih_v6_0_ip_funcs = {
.name = "ih_v6_0",
.early_init = ih_v6_0_early_init,
.late_init = NULL,
.sw_init = ih_v6_0_sw_init,
.sw_fini = ih_v6_0_sw_fini,
.hw_init = ih_v6_0_hw_init,
@ -798,8 +791,6 @@ static const struct amd_ip_funcs ih_v6_0_ip_funcs = {
.set_clockgating_state = ih_v6_0_set_clockgating_state,
.set_powergating_state = ih_v6_0_set_powergating_state,
.get_clockgating_state = ih_v6_0_get_clockgating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs ih_v6_0_funcs = {

View File

@ -532,9 +532,9 @@ static void ih_v6_1_set_self_irq_funcs(struct amdgpu_device *adev)
adev->irq.self_irq.funcs = &ih_v6_1_self_irq_funcs;
}
static int ih_v6_1_early_init(void *handle)
static int ih_v6_1_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
ret = amdgpu_irq_add_domain(adev);
@ -547,10 +547,10 @@ static int ih_v6_1_early_init(void *handle)
return 0;
}
static int ih_v6_1_sw_init(void *handle)
static int ih_v6_1_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
bool use_bus_addr;
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_IH, 0,
@ -593,19 +593,19 @@ static int ih_v6_1_sw_init(void *handle)
return r;
}
static int ih_v6_1_sw_fini(void *handle)
static int ih_v6_1_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
return 0;
}
static int ih_v6_1_hw_init(void *handle)
static int ih_v6_1_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = ih_v6_1_irq_init(adev);
if (r)
@ -614,27 +614,21 @@ static int ih_v6_1_hw_init(void *handle)
return 0;
}
static int ih_v6_1_hw_fini(void *handle)
static int ih_v6_1_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
ih_v6_1_irq_disable(adev);
ih_v6_1_irq_disable(ip_block->adev);
return 0;
}
static int ih_v6_1_suspend(void *handle)
static int ih_v6_1_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v6_1_hw_fini(adev);
return ih_v6_1_hw_fini(ip_block);
}
static int ih_v6_1_resume(void *handle)
static int ih_v6_1_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v6_1_hw_init(adev);
return ih_v6_1_hw_init(ip_block);
}
static bool ih_v6_1_is_idle(void *handle)
@ -643,13 +637,13 @@ static bool ih_v6_1_is_idle(void *handle)
return true;
}
static int ih_v6_1_wait_for_idle(void *handle)
static int ih_v6_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* todo */
return -ETIMEDOUT;
}
static int ih_v6_1_soft_reset(void *handle)
static int ih_v6_1_soft_reset(struct amdgpu_ip_block *ip_block)
{
/* todo */
return 0;
@ -768,7 +762,6 @@ static void ih_v6_1_get_clockgating_state(void *handle, u64 *flags)
static const struct amd_ip_funcs ih_v6_1_ip_funcs = {
.name = "ih_v6_1",
.early_init = ih_v6_1_early_init,
.late_init = NULL,
.sw_init = ih_v6_1_sw_init,
.sw_fini = ih_v6_1_sw_fini,
.hw_init = ih_v6_1_hw_init,
@ -781,8 +774,6 @@ static const struct amd_ip_funcs ih_v6_1_ip_funcs = {
.set_clockgating_state = ih_v6_1_set_clockgating_state,
.set_powergating_state = ih_v6_1_set_powergating_state,
.get_clockgating_state = ih_v6_1_get_clockgating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs ih_v6_1_funcs = {

View File

@ -528,19 +528,19 @@ static void ih_v7_0_set_self_irq_funcs(struct amdgpu_device *adev)
adev->irq.self_irq.funcs = &ih_v7_0_self_irq_funcs;
}
static int ih_v7_0_early_init(void *handle)
static int ih_v7_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
ih_v7_0_set_interrupt_funcs(adev);
ih_v7_0_set_self_irq_funcs(adev);
return 0;
}
static int ih_v7_0_sw_init(void *handle)
static int ih_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
bool use_bus_addr;
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_IH, 0,
@ -583,19 +583,19 @@ static int ih_v7_0_sw_init(void *handle)
return r;
}
static int ih_v7_0_sw_fini(void *handle)
static int ih_v7_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_fini_sw(adev);
return 0;
}
static int ih_v7_0_hw_init(void *handle)
static int ih_v7_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = ih_v7_0_irq_init(adev);
if (r)
@ -604,27 +604,21 @@ static int ih_v7_0_hw_init(void *handle)
return 0;
}
static int ih_v7_0_hw_fini(void *handle)
static int ih_v7_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
ih_v7_0_irq_disable(adev);
ih_v7_0_irq_disable(ip_block->adev);
return 0;
}
static int ih_v7_0_suspend(void *handle)
static int ih_v7_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v7_0_hw_fini(adev);
return ih_v7_0_hw_fini(ip_block);
}
static int ih_v7_0_resume(void *handle)
static int ih_v7_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
return ih_v7_0_hw_init(adev);
return ih_v7_0_hw_init(ip_block);
}
static bool ih_v7_0_is_idle(void *handle)
@ -633,13 +627,13 @@ static bool ih_v7_0_is_idle(void *handle)
return true;
}
static int ih_v7_0_wait_for_idle(void *handle)
static int ih_v7_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
/* todo */
return -ETIMEDOUT;
}
static int ih_v7_0_soft_reset(void *handle)
static int ih_v7_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
/* todo */
return 0;
@ -758,7 +752,6 @@ static void ih_v7_0_get_clockgating_state(void *handle, u64 *flags)
static const struct amd_ip_funcs ih_v7_0_ip_funcs = {
.name = "ih_v7_0",
.early_init = ih_v7_0_early_init,
.late_init = NULL,
.sw_init = ih_v7_0_sw_init,
.sw_fini = ih_v7_0_sw_fini,
.hw_init = ih_v7_0_hw_init,
@ -771,8 +764,6 @@ static const struct amd_ip_funcs ih_v7_0_ip_funcs = {
.set_clockgating_state = ih_v7_0_set_clockgating_state,
.set_powergating_state = ih_v7_0_set_powergating_state,
.get_clockgating_state = ih_v7_0_get_clockgating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ih_funcs ih_v7_0_funcs = {

View File

@ -458,13 +458,13 @@ static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,
/**
* jpeg_v1_0_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
int jpeg_v1_0_early_init(void *handle)
int jpeg_v1_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->jpeg.num_jpeg_inst = 1;
adev->jpeg.num_jpeg_rings = 1;
@ -478,12 +478,12 @@ int jpeg_v1_0_early_init(void *handle)
/**
* jpeg_v1_0_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
int jpeg_v1_0_sw_init(void *handle)
int jpeg_v1_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int r;
@ -509,13 +509,13 @@ int jpeg_v1_0_sw_init(void *handle)
/**
* jpeg_v1_0_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG free up sw allocation
*/
void jpeg_v1_0_sw_fini(void *handle)
void jpeg_v1_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
amdgpu_ring_fini(adev->jpeg.inst->ring_dec);
}

View File

@ -24,9 +24,9 @@
#ifndef __JPEG_V1_0_H__
#define __JPEG_V1_0_H__
int jpeg_v1_0_early_init(void *handle);
int jpeg_v1_0_sw_init(void *handle);
void jpeg_v1_0_sw_fini(void *handle);
int jpeg_v1_0_early_init(struct amdgpu_ip_block *ip_block);
int jpeg_v1_0_sw_init(struct amdgpu_ip_block *ip_block);
void jpeg_v1_0_sw_fini(struct amdgpu_ip_block *ip_block);
void jpeg_v1_0_start(struct amdgpu_device *adev, int mode);
#define JPEG_V1_REG_RANGE_START 0x8000

View File

@ -41,13 +41,13 @@ static int jpeg_v2_0_set_powergating_state(void *handle,
/**
* jpeg_v2_0_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
static int jpeg_v2_0_early_init(void *handle)
static int jpeg_v2_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->jpeg.num_jpeg_inst = 1;
adev->jpeg.num_jpeg_rings = 1;
@ -61,13 +61,13 @@ static int jpeg_v2_0_early_init(void *handle)
/**
* jpeg_v2_0_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Load firmware and sw initialization
*/
static int jpeg_v2_0_sw_init(void *handle)
static int jpeg_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int r;
@ -104,14 +104,14 @@ static int jpeg_v2_0_sw_init(void *handle)
/**
* jpeg_v2_0_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG suspend and free up sw allocation
*/
static int jpeg_v2_0_sw_fini(void *handle)
static int jpeg_v2_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = amdgpu_jpeg_suspend(adev);
if (r)
@ -125,12 +125,12 @@ static int jpeg_v2_0_sw_fini(void *handle)
/**
* jpeg_v2_0_hw_init - start and test JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int jpeg_v2_0_hw_init(void *handle)
static int jpeg_v2_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
@ -142,13 +142,13 @@ static int jpeg_v2_0_hw_init(void *handle)
/**
* jpeg_v2_0_hw_fini - stop the hardware block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Stop the JPEG block, mark ring as not ready any more
*/
static int jpeg_v2_0_hw_fini(void *handle)
static int jpeg_v2_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
cancel_delayed_work_sync(&adev->vcn.idle_work);
@ -162,20 +162,19 @@ static int jpeg_v2_0_hw_fini(void *handle)
/**
* jpeg_v2_0_suspend - suspend JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* HW fini and suspend JPEG block
*/
static int jpeg_v2_0_suspend(void *handle)
static int jpeg_v2_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = jpeg_v2_0_hw_fini(adev);
r = jpeg_v2_0_hw_fini(ip_block);
if (r)
return r;
r = amdgpu_jpeg_suspend(adev);
r = amdgpu_jpeg_suspend(ip_block->adev);
return r;
}
@ -183,20 +182,19 @@ static int jpeg_v2_0_suspend(void *handle)
/**
* jpeg_v2_0_resume - resume JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Resume firmware and hw init JPEG block
*/
static int jpeg_v2_0_resume(void *handle)
static int jpeg_v2_0_resume(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = amdgpu_jpeg_resume(adev);
r = amdgpu_jpeg_resume(ip_block->adev);
if (r)
return r;
r = jpeg_v2_0_hw_init(adev);
r = jpeg_v2_0_hw_init(ip_block);
return r;
}
@ -666,9 +664,9 @@ static bool jpeg_v2_0_is_idle(void *handle)
UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
}
static int jpeg_v2_0_wait_for_idle(void *handle)
static int jpeg_v2_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret;
ret = SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS, UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
@ -744,7 +742,6 @@ static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev,
static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
.name = "jpeg_v2_0",
.early_init = jpeg_v2_0_early_init,
.late_init = NULL,
.sw_init = jpeg_v2_0_sw_init,
.sw_fini = jpeg_v2_0_sw_fini,
.hw_init = jpeg_v2_0_hw_init,
@ -753,14 +750,8 @@ static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
.resume = jpeg_v2_0_resume,
.is_idle = jpeg_v2_0_is_idle,
.wait_for_idle = jpeg_v2_0_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v2_0_set_clockgating_state,
.set_powergating_state = jpeg_v2_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {

View File

@ -50,13 +50,13 @@ static int amdgpu_ih_clientid_jpeg[] = {
/**
* jpeg_v2_5_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
static int jpeg_v2_5_early_init(void *handle)
static int jpeg_v2_5_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 harvest;
int i;
@ -81,15 +81,15 @@ static int jpeg_v2_5_early_init(void *handle)
/**
* jpeg_v2_5_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Load firmware and sw initialization
*/
static int jpeg_v2_5_sw_init(void *handle)
static int jpeg_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_ring *ring;
int i, r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
if (adev->jpeg.harvest_config & (1 << i))
@ -153,14 +153,14 @@ static int jpeg_v2_5_sw_init(void *handle)
/**
* jpeg_v2_5_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG suspend and free up sw allocation
*/
static int jpeg_v2_5_sw_fini(void *handle)
static int jpeg_v2_5_sw_fini(struct amdgpu_ip_block *ip_block)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
r = amdgpu_jpeg_suspend(adev);
if (r)
@ -174,12 +174,12 @@ static int jpeg_v2_5_sw_fini(void *handle)
/**
* jpeg_v2_5_hw_init - start and test JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int jpeg_v2_5_hw_init(void *handle)
static int jpeg_v2_5_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int i, r;
@ -202,13 +202,13 @@ static int jpeg_v2_5_hw_init(void *handle)
/**
* jpeg_v2_5_hw_fini - stop the hardware block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Stop the JPEG block, mark ring as not ready any more
*/
static int jpeg_v2_5_hw_fini(void *handle)
static int jpeg_v2_5_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i;
cancel_delayed_work_sync(&adev->vcn.idle_work);
@ -231,20 +231,19 @@ static int jpeg_v2_5_hw_fini(void *handle)
/**
* jpeg_v2_5_suspend - suspend JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* HW fini and suspend JPEG block
*/
static int jpeg_v2_5_suspend(void *handle)
static int jpeg_v2_5_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = jpeg_v2_5_hw_fini(adev);
r = jpeg_v2_5_hw_fini(ip_block);
if (r)
return r;
r = amdgpu_jpeg_suspend(adev);
r = amdgpu_jpeg_suspend(ip_block->adev);
return r;
}
@ -252,20 +251,19 @@ static int jpeg_v2_5_suspend(void *handle)
/**
* jpeg_v2_5_resume - resume JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Resume firmware and hw init JPEG block
*/
static int jpeg_v2_5_resume(void *handle)
static int jpeg_v2_5_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = amdgpu_jpeg_resume(adev);
r = amdgpu_jpeg_resume(ip_block->adev);
if (r)
return r;
r = jpeg_v2_5_hw_init(adev);
r = jpeg_v2_5_hw_init(ip_block);
return r;
}
@ -501,9 +499,9 @@ static bool jpeg_v2_5_is_idle(void *handle)
return ret;
}
static int jpeg_v2_5_wait_for_idle(void *handle)
static int jpeg_v2_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int i, ret;
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
@ -615,7 +613,6 @@ static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev,
static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
.name = "jpeg_v2_5",
.early_init = jpeg_v2_5_early_init,
.late_init = NULL,
.sw_init = jpeg_v2_5_sw_init,
.sw_fini = jpeg_v2_5_sw_fini,
.hw_init = jpeg_v2_5_hw_init,
@ -624,20 +621,13 @@ static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
.resume = jpeg_v2_5_resume,
.is_idle = jpeg_v2_5_is_idle,
.wait_for_idle = jpeg_v2_5_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
.set_powergating_state = jpeg_v2_5_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
.name = "jpeg_v2_6",
.early_init = jpeg_v2_5_early_init,
.late_init = NULL,
.sw_init = jpeg_v2_5_sw_init,
.sw_fini = jpeg_v2_5_sw_fini,
.hw_init = jpeg_v2_5_hw_init,
@ -646,14 +636,8 @@ static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
.resume = jpeg_v2_5_resume,
.is_idle = jpeg_v2_5_is_idle,
.wait_for_idle = jpeg_v2_5_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
.set_powergating_state = jpeg_v2_5_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {

View File

@ -42,13 +42,13 @@ static int jpeg_v3_0_set_powergating_state(void *handle,
/**
* jpeg_v3_0_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
static int jpeg_v3_0_early_init(void *handle)
static int jpeg_v3_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
u32 harvest;
@ -75,13 +75,13 @@ static int jpeg_v3_0_early_init(void *handle)
/**
* jpeg_v3_0_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Load firmware and sw initialization
*/
static int jpeg_v3_0_sw_init(void *handle)
static int jpeg_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int r;
@ -118,13 +118,13 @@ static int jpeg_v3_0_sw_init(void *handle)
/**
* jpeg_v3_0_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG suspend and free up sw allocation
*/
static int jpeg_v3_0_sw_fini(void *handle)
static int jpeg_v3_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_jpeg_suspend(adev);
@ -139,12 +139,12 @@ static int jpeg_v3_0_sw_fini(void *handle)
/**
* jpeg_v3_0_hw_init - start and test JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int jpeg_v3_0_hw_init(void *handle)
static int jpeg_v3_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
@ -156,13 +156,13 @@ static int jpeg_v3_0_hw_init(void *handle)
/**
* jpeg_v3_0_hw_fini - stop the hardware block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Stop the JPEG block, mark ring as not ready any more
*/
static int jpeg_v3_0_hw_fini(void *handle)
static int jpeg_v3_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
cancel_delayed_work_sync(&adev->vcn.idle_work);
@ -176,20 +176,19 @@ static int jpeg_v3_0_hw_fini(void *handle)
/**
* jpeg_v3_0_suspend - suspend JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* HW fini and suspend JPEG block
*/
static int jpeg_v3_0_suspend(void *handle)
static int jpeg_v3_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = jpeg_v3_0_hw_fini(adev);
r = jpeg_v3_0_hw_fini(ip_block);
if (r)
return r;
r = amdgpu_jpeg_suspend(adev);
r = amdgpu_jpeg_suspend(ip_block->adev);
return r;
}
@ -197,20 +196,19 @@ static int jpeg_v3_0_suspend(void *handle)
/**
* jpeg_v3_0_resume - resume JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Resume firmware and hw init JPEG block
*/
static int jpeg_v3_0_resume(void *handle)
static int jpeg_v3_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = amdgpu_jpeg_resume(adev);
r = amdgpu_jpeg_resume(ip_block->adev);
if (r)
return r;
r = jpeg_v3_0_hw_init(adev);
r = jpeg_v3_0_hw_init(ip_block);
return r;
}
@ -459,9 +457,9 @@ static bool jpeg_v3_0_is_idle(void *handle)
return ret;
}
static int jpeg_v3_0_wait_for_idle(void *handle)
static int jpeg_v3_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
return SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS,
UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
@ -535,7 +533,6 @@ static int jpeg_v3_0_process_interrupt(struct amdgpu_device *adev,
static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
.name = "jpeg_v3_0",
.early_init = jpeg_v3_0_early_init,
.late_init = NULL,
.sw_init = jpeg_v3_0_sw_init,
.sw_fini = jpeg_v3_0_sw_fini,
.hw_init = jpeg_v3_0_hw_init,
@ -544,14 +541,8 @@ static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
.resume = jpeg_v3_0_resume,
.is_idle = jpeg_v3_0_is_idle,
.wait_for_idle = jpeg_v3_0_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v3_0_set_clockgating_state,
.set_powergating_state = jpeg_v3_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = {

View File

@ -48,13 +48,13 @@ static void jpeg_v4_0_dec_ring_set_wptr(struct amdgpu_ring *ring);
/**
* jpeg_v4_0_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
static int jpeg_v4_0_early_init(void *handle)
static int jpeg_v4_0_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->jpeg.num_jpeg_inst = 1;
@ -70,13 +70,13 @@ static int jpeg_v4_0_early_init(void *handle)
/**
* jpeg_v4_0_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Load firmware and sw initialization
*/
static int jpeg_v4_0_sw_init(void *handle)
static int jpeg_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int r;
@ -130,13 +130,13 @@ static int jpeg_v4_0_sw_init(void *handle)
/**
* jpeg_v4_0_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG suspend and free up sw allocation
*/
static int jpeg_v4_0_sw_fini(void *handle)
static int jpeg_v4_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_jpeg_suspend(adev);
@ -151,12 +151,12 @@ static int jpeg_v4_0_sw_fini(void *handle)
/**
* jpeg_v4_0_hw_init - start and test JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int jpeg_v4_0_hw_init(void *handle)
static int jpeg_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
int r;
@ -187,13 +187,13 @@ static int jpeg_v4_0_hw_init(void *handle)
/**
* jpeg_v4_0_hw_fini - stop the hardware block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Stop the JPEG block, mark ring as not ready any more
*/
static int jpeg_v4_0_hw_fini(void *handle)
static int jpeg_v4_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
cancel_delayed_work_sync(&adev->vcn.idle_work);
if (!amdgpu_sriov_vf(adev)) {
@ -210,20 +210,19 @@ static int jpeg_v4_0_hw_fini(void *handle)
/**
* jpeg_v4_0_suspend - suspend JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* HW fini and suspend JPEG block
*/
static int jpeg_v4_0_suspend(void *handle)
static int jpeg_v4_0_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = jpeg_v4_0_hw_fini(adev);
r = jpeg_v4_0_hw_fini(ip_block);
if (r)
return r;
r = amdgpu_jpeg_suspend(adev);
r = amdgpu_jpeg_suspend(ip_block->adev);
return r;
}
@ -231,20 +230,19 @@ static int jpeg_v4_0_suspend(void *handle)
/**
* jpeg_v4_0_resume - resume JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Resume firmware and hw init JPEG block
*/
static int jpeg_v4_0_resume(void *handle)
static int jpeg_v4_0_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = amdgpu_jpeg_resume(adev);
r = amdgpu_jpeg_resume(ip_block->adev);
if (r)
return r;
r = jpeg_v4_0_hw_init(adev);
r = jpeg_v4_0_hw_init(ip_block);
return r;
}
@ -621,9 +619,9 @@ static bool jpeg_v4_0_is_idle(void *handle)
return ret;
}
static int jpeg_v4_0_wait_for_idle(void *handle)
static int jpeg_v4_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS,
UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
@ -702,7 +700,6 @@ static int jpeg_v4_0_process_interrupt(struct amdgpu_device *adev,
static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
.name = "jpeg_v4_0",
.early_init = jpeg_v4_0_early_init,
.late_init = NULL,
.sw_init = jpeg_v4_0_sw_init,
.sw_fini = jpeg_v4_0_sw_fini,
.hw_init = jpeg_v4_0_hw_init,
@ -711,14 +708,8 @@ static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
.resume = jpeg_v4_0_resume,
.is_idle = jpeg_v4_0_is_idle,
.wait_for_idle = jpeg_v4_0_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v4_0_set_clockgating_state,
.set_powergating_state = jpeg_v4_0_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {

View File

@ -68,13 +68,13 @@ static inline bool jpeg_v4_0_3_normalizn_reqd(struct amdgpu_device *adev)
/**
* jpeg_v4_0_3_early_init - set function pointers
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Set ring and irq function pointers
*/
static int jpeg_v4_0_3_early_init(void *handle)
static int jpeg_v4_0_3_early_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS;
@ -88,13 +88,13 @@ static int jpeg_v4_0_3_early_init(void *handle)
/**
* jpeg_v4_0_3_sw_init - sw init for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Load firmware and sw initialization
*/
static int jpeg_v4_0_3_sw_init(void *handle)
static int jpeg_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int i, j, r, jpeg_inst;
@ -165,13 +165,13 @@ static int jpeg_v4_0_3_sw_init(void *handle)
/**
* jpeg_v4_0_3_sw_fini - sw fini for JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* JPEG suspend and free up sw allocation
*/
static int jpeg_v4_0_3_sw_fini(void *handle)
static int jpeg_v4_0_3_sw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_jpeg_suspend(adev);
@ -299,12 +299,12 @@ static int jpeg_v4_0_3_start_sriov(struct amdgpu_device *adev)
/**
* jpeg_v4_0_3_hw_init - start and test JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
*/
static int jpeg_v4_0_3_hw_init(void *handle)
static int jpeg_v4_0_3_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
struct amdgpu_ring *ring;
int i, j, r, jpeg_inst;
@ -358,13 +358,13 @@ static int jpeg_v4_0_3_hw_init(void *handle)
/**
* jpeg_v4_0_3_hw_fini - stop the hardware block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Stop the JPEG block, mark ring as not ready any more
*/
static int jpeg_v4_0_3_hw_fini(void *handle)
static int jpeg_v4_0_3_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret = 0;
cancel_delayed_work_sync(&adev->jpeg.idle_work);
@ -380,20 +380,19 @@ static int jpeg_v4_0_3_hw_fini(void *handle)
/**
* jpeg_v4_0_3_suspend - suspend JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* HW fini and suspend JPEG block
*/
static int jpeg_v4_0_3_suspend(void *handle)
static int jpeg_v4_0_3_suspend(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = jpeg_v4_0_3_hw_fini(adev);
r = jpeg_v4_0_3_hw_fini(ip_block);
if (r)
return r;
r = amdgpu_jpeg_suspend(adev);
r = amdgpu_jpeg_suspend(ip_block->adev);
return r;
}
@ -401,20 +400,19 @@ static int jpeg_v4_0_3_suspend(void *handle)
/**
* jpeg_v4_0_3_resume - resume JPEG block
*
* @handle: amdgpu_device pointer
* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
*
* Resume firmware and hw init JPEG block
*/
static int jpeg_v4_0_3_resume(void *handle)
static int jpeg_v4_0_3_resume(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
r = amdgpu_jpeg_resume(adev);
r = amdgpu_jpeg_resume(ip_block->adev);
if (r)
return r;
r = jpeg_v4_0_3_hw_init(adev);
r = jpeg_v4_0_3_hw_init(ip_block);
return r;
}
@ -674,11 +672,12 @@ void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
}
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x80004000);
amdgpu_ring_write(ring,
PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x80004000);
}
}
/**
@ -694,11 +693,12 @@ void jpeg_v4_0_3_dec_ring_insert_end(struct amdgpu_ring *ring)
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x62a04);
}
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x00004000);
amdgpu_ring_write(ring,
PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x00004000);
}
}
/**
@ -743,14 +743,6 @@ void jpeg_v4_0_3_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq
amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x3fbc);
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
0, 0, PACKETJ_TYPE0));
amdgpu_ring_write(ring, 0x1);
amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
amdgpu_ring_write(ring, 0);
@ -929,9 +921,9 @@ static bool jpeg_v4_0_3_is_idle(void *handle)
return ret;
}
static int jpeg_v4_0_3_wait_for_idle(void *handle)
static int jpeg_v4_0_3_wait_for_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amdgpu_device *adev = ip_block->adev;
int ret = 0;
int i, j;
@ -1058,7 +1050,6 @@ static int jpeg_v4_0_3_process_interrupt(struct amdgpu_device *adev,
static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
.name = "jpeg_v4_0_3",
.early_init = jpeg_v4_0_3_early_init,
.late_init = NULL,
.sw_init = jpeg_v4_0_3_sw_init,
.sw_fini = jpeg_v4_0_3_sw_fini,
.hw_init = jpeg_v4_0_3_hw_init,
@ -1067,14 +1058,8 @@ static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
.resume = jpeg_v4_0_3_resume,
.is_idle = jpeg_v4_0_3_is_idle,
.wait_for_idle = jpeg_v4_0_3_wait_for_idle,
.check_soft_reset = NULL,
.pre_soft_reset = NULL,
.soft_reset = NULL,
.post_soft_reset = NULL,
.set_clockgating_state = jpeg_v4_0_3_set_clockgating_state,
.set_powergating_state = jpeg_v4_0_3_set_powergating_state,
.dump_ip_state = NULL,
.print_ip_state = NULL,
};
static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
@ -1088,7 +1073,7 @@ static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
8 + /* jpeg_v4_0_3_dec_ring_emit_vm_flush */
22 + 22 + /* jpeg_v4_0_3_dec_ring_emit_fence x2 vm fence */
18 + 18 + /* jpeg_v4_0_3_dec_ring_emit_fence x2 vm fence */
8 + 16,
.emit_ib_size = 22, /* jpeg_v4_0_3_dec_ring_emit_ib */
.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,

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