Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'amd-drm-next-6.18-2025-08-29' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.18-2025-08-29:

amdgpu:
- Replay fixes
- RAS updates
- VCN SRAM load fixes
- EDID read fixes
- eDP ALPM support
- AUX fixes
- Documenation updates
- Rework how PTE flags are generated
- DCE6 fixes
- VCN devcoredump cleanup
- MMHUB client id fixes
- SR-IOV fixes
- VRR fixes
- VCN 5.0.1 RAS support
- Backlight fixes
- UserQ fixes
- Misc code cleanups
- SMU 13.0.12 updates
- Expanded PCIe DPC support
- Expanded VCN reset support
- SMU 13.0.x Updates
- VPE per queue reset support
- Cusor rotation fix
- DSC fixes
- GC 12 MES TLB invalidation update
- Cursor fixes
- Non-DC TMDS clock validation fix

amdkfd:
- debugfs fixes
- Misc code cleanups
- Page migration fixes
- Partition fixes
- SVM fixes

radeon:
- Misc code cleanups

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20250829190848.1921648-1-alexander.deucher@amd.com

+4889 -2438
+2 -2
Documentation/gpu/amdgpu/amd-hardware-list-info.rst
··· 10 10 11 11 .. csv-table:: 12 12 :header-rows: 1 13 - :widths: 3, 2, 2, 1, 1, 1, 1 13 + :widths: 3, 2, 2, 1, 1, 1, 1, 1 14 14 :file: ./apu-asic-info-table.csv 15 15 16 16 Discrete GPU Info ··· 18 18 19 19 .. csv-table:: 20 20 :header-rows: 1 21 - :widths: 3, 2, 2, 1, 1, 1 21 + :widths: 3, 2, 2, 1, 1, 1, 1, 1 22 22 :file: ./dgpu-asic-info-table.csv 23 23
+17 -17
Documentation/gpu/amdgpu/apu-asic-info-table.csv
··· 1 - Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version, MP0 version 2 - Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3, n/a 3 - Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0, 10.0.0 4 - Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2, 11.0.3 5 - Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1, 10.0.1 6 - SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1, 11.5.0 7 - Ryzen 5000 series / Ryzen 7x30 series, GREEN SARDINE / Cezanne / Barcelo / Barcelo-R, DCN 2.1, 9.3, VCN 2.2, 4.1.1, 12.0.1 8 - Ryzen 6000 series / Ryzen 7x35 series / Ryzen 7x36 series, YELLOW CARP / Rembrandt / Rembrandt-R, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3 9 - Ryzen 7000 series (AM5), Raphael, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 10 - Ryzen 9000 series (AM5), Granite Ridge, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 11 - Ryzen 7x45 series (FL1), Dragon Range, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 12 - Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8 13 - Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11 14 - Ryzen 8x40 series, Hawk Point, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11 15 - Ryzen AI 300 series, Strix Point, 3.5.0, 11.5.0, 4.0.5, 6.1.0, 14.0.0 16 - Ryzen AI 350 series, Krackan Point, 3.5.0, 11.5.2, 4.0.5, 6.1.2, 14.0.4 17 - Ryzen AI Max 300 series, Strix Halo, 3.5.1, 11.5.1, 4.0.6, 6.1.1, 14.0.1 1 + Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version, MP0 version, MP1 version 2 + Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3, n/a, 8 3 + Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0, 10.0.0, 10.0.0 4 + Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2, 11.0.3, 12.0.1 5 + Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1, 10.0.1, 10.0.1 6 + SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1, 11.5.0, 11.5.0 7 + Ryzen 5000 series / Ryzen 7x30 series, GREEN SARDINE / Cezanne / Barcelo / Barcelo-R, DCN 2.1, 9.3, VCN 2.2, 4.1.1, 12.0.1, 12.0.1 8 + Ryzen 6000 series / Ryzen 7x35 series / Ryzen 7x36 series, YELLOW CARP / Rembrandt / Rembrandt-R, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3, 13.0.3 9 + Ryzen 7000 series (AM5), Raphael, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 10 + Ryzen 9000 series (AM5), Granite Ridge, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 11 + Ryzen 7x45 series (FL1), Dragon Range, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 12 + Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8, 13.0.8 13 + Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11, 13.0.4 / 13.0.11 14 + Ryzen 8x40 series, Hawk Point, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11, 13.0.4 / 13.0.11 15 + Ryzen AI 300 series, Strix Point, 3.5.0, 11.5.0, 4.0.5, 6.1.0, 14.0.0, 14.0.0 16 + Ryzen AI 350 series, Krackan Point, 3.5.0, 11.5.2, 4.0.5, 6.1.2, 14.0.4, 14.0.4 17 + Ryzen AI Max 300 series, Strix Halo, 3.5.1, 11.5.1, 4.0.6, 6.1.1, 14.0.1, 14.0.1
+2 -2
Documentation/gpu/amdgpu/debugfs.rst
··· 94 94 ------------------- 95 95 96 96 Provides an interface to set an error code on the dma fences associated with 97 - ring <name>. The error code specified is propogated to all fences associated 97 + ring <name>. The error code specified is propagated to all fences associated 98 98 with the ring. Use this to inject a fence error into a ring. 99 99 100 100 amdgpu_pm_info ··· 165 165 amdgpu_regs_* 166 166 ------------- 167 167 168 - Provides direct access to various register aperatures on the GPU. Used 168 + Provides direct access to various register apertures on the GPU. Used 169 169 by tools like UMR to access GPU registers. 170 170 171 171 amdgpu_regs2
+30 -28
Documentation/gpu/amdgpu/dgpu-asic-info-table.csv
··· 1 - Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version 2 - AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, -- 3 - AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, -- 4 - AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, -- 5 - AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, -- 6 - AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, -- 7 - AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1 8 - AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1 9 - AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2 10 - AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3 11 - AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3 12 - Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 13 - Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 14 - Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 15 - Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0 16 - AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0 17 - MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2 18 - MI200 Series, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0 19 - MI300 Series, AQUA_VANJARAM, *, 9.4.3, VCN 4.0.3, 4.4.2 20 - AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0 21 - AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2 22 - AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0 23 - AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2 24 - AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4 25 - AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5 26 - AMD Radeon RX 7900 XT /XTX, , DCN 3.2.0, 11.0.0, VCN 4.0.0, 6.0.0 27 - AMD Radeon RX 7800 XT, , DCN 3.2.0, 11.0.3, VCN 4.0.0, 6.0.3 28 - AMD Radeon RX 7600M (XT) /7700S /7600S, , DCN 3.2.1, 11.0.2, VCN 4.0.4, 6.0.2 1 + Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version, MP0 version, MP1 version 2 + AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, --, --, 6 3 + AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 4 + AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, -- / UVD 3, --, --, 6 5 + AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 6 + AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 7 + AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1, --, 7 8 + AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1, --, 7 9 + AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2, n/a, 7 10 + AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3, n/a, 7 11 + AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3, n/a, 7 12 + Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 13 + Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 14 + Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 15 + Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0, 9.0.0, 9.0.0 16 + AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0, 11.0.2, 11.0.2 17 + MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2, 11.0.4, 11.0.2 18 + MI200 Series, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0, 13.0.2, 13.0.2 19 + MI300 Series, AQUA_VANJARAM, *, 9.4.3, VCN 4.0.3, 4.4.2, 13.0.6, 13.0.6 20 + AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0, 11.0.0, 11.0.0 21 + AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2, 11.0.5, 11.0.5 22 + AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0, 11.0.7, 11.0.7 23 + AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2, 11.0.11, 11.0.11 24 + AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4, 11.0.12, 11.0.12 25 + AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5, 11.0.13, 11.0.13 26 + AMD Radeon RX 7900 XT /XTX, , DCN 3.2.0, 11.0.0, VCN 4.0.0, 6.0.0, 13.0.0, 13.0.0 27 + AMD Radeon RX 7800 XT, , DCN 3.2.0, 11.0.3, VCN 4.0.0, 6.0.3, 13.0.10, 13.0.10 28 + AMD Radeon RX 7600M (XT) /7700S /7600S, , DCN 3.2.1, 11.0.2, VCN 4.0.4, 6.0.2, 13.0.7, 13.0.7 29 + AMD Radeon RX 9070 (XT), , DCN 4.0.1, 12.0.1, VCN 5.0.0, 7.0.1, 14.0.3, 14.0.3 30 + AMD Radeon RX 9060 XT, , DCN 4.0.1, 12.0.0, VCN 5.0.0, 7.0.0, 14.0.2, 14.0.2
+1 -1
Documentation/gpu/amdgpu/display/dc-glossary.rst
··· 5 5 On this page, we try to keep track of acronyms related to the display 6 6 component. If you do not find what you are looking for, look at the 7 7 'Documentation/gpu/amdgpu/amdgpu-glossary.rst'; if you cannot find it anywhere, 8 - consider asking in the amdgfx and update this page. 8 + consider asking on the amd-gfx mailing list and update this page. 9 9 10 10 .. glossary:: 11 11
+2 -2
Documentation/gpu/amdgpu/display/display-contributing.rst
··· 9 9 10 10 This page summarizes some of the issues you can help with; keep in mind that 11 11 this is a static page, and it is always a good idea to try to reach developers 12 - in the amdgfx or some of the maintainers. Finally, this page follows the DRM 13 - way of creating a TODO list; for more information, check 12 + on the amd-gfx mailing list or some of the maintainers. Finally, this page 13 + follows the DRM way of creating a TODO list; for more information, check 14 14 'Documentation/gpu/todo.rst'. 15 15 16 16 Gitlab issues
+1 -1
Documentation/gpu/amdgpu/display/programming-model-dcn.rst
··· 100 100 For historical reasons, we used the name `dc_link`, which gives the 101 101 wrong impression that this abstraction only deals with physical connections 102 102 that the developer can easily manipulate. However, this also covers 103 - conections like eDP or cases where the output is connected to other devices. 103 + connections like eDP or cases where the output is connected to other devices. 104 104 105 105 There are two structs that are not represented in the diagram since they were 106 106 elaborated in the DCN overview page (check the DCN block diagram :ref:`Display
+1 -1
Documentation/gpu/amdgpu/driver-core.rst
··· 65 65 66 66 GC (Graphics and Compute) 67 67 This is the graphics and compute engine, i.e., the block that 68 - encompasses the 3D pipeline and and shader blocks. This is by far the 68 + encompasses the 3D pipeline and shader blocks. This is by far the 69 69 largest block on the GPU. The 3D pipeline has tons of sub-blocks. In 70 70 addition to that, it also contains the CP microcontrollers (ME, PFP, CE, 71 71 MEC) and the RLC microcontroller. It's exposed to userspace for user mode
+1 -1
Documentation/gpu/amdgpu/process-isolation.rst
··· 26 26 $ cat /sys/class/drm/card0/device/enforce_isolation 27 27 1 0 1 0 28 28 29 - The output indicates that enforce isolation is enabled on zeroth and second parition and disabled on first and fourth parition. 29 + The output indicates that enforce isolation is enabled on zeroth and second partition and disabled on first and third partition. 30 30 31 31 For devices with a single partition or those that do not support partitions, there will be only one element: 32 32
+23 -6
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 819 819 uint32_t mask); 820 820 }; 821 821 822 + enum amdgpu_uid_type { 823 + AMDGPU_UID_TYPE_XCD, 824 + AMDGPU_UID_TYPE_AID, 825 + AMDGPU_UID_TYPE_SOC, 826 + AMDGPU_UID_TYPE_MAX 827 + }; 828 + 829 + #define AMDGPU_UID_INST_MAX 8 /* max number of instances for each UID type */ 830 + 831 + struct amdgpu_uid { 832 + uint64_t uid[AMDGPU_UID_TYPE_MAX][AMDGPU_UID_INST_MAX]; 833 + struct amdgpu_device *adev; 834 + }; 835 + 822 836 struct amd_powerplay { 823 837 void *pp_handle; 824 838 const struct amd_pm_funcs *pp_funcs; ··· 910 896 bool in_link_reset; 911 897 bool occurs_dpc; 912 898 bool audio_suspended; 899 + struct pci_dev *swus; 900 + struct pci_saved_state *swus_pcistate; 901 + struct pci_saved_state *swds_pcistate; 913 902 }; 914 903 915 904 /* ··· 945 928 AMDGPU_ENFORCE_ISOLATION_ENABLE_LEGACY = 2, 946 929 AMDGPU_ENFORCE_ISOLATION_NO_CLEANER_SHADER = 3, 947 930 }; 948 - 949 - 950 - /* 951 - * Non-zero (true) if the GPU has VRAM. Zero (false) otherwise. 952 - */ 953 - #define AMDGPU_HAS_VRAM(_adev) ((_adev)->gmc.real_vram_size) 954 931 955 932 struct amdgpu_device { 956 933 struct device *dev; ··· 1313 1302 struct list_head userq_mgr_list; 1314 1303 struct mutex userq_mutex; 1315 1304 bool userq_halt_for_enforce_isolation; 1305 + struct amdgpu_uid *uid_info; 1316 1306 }; 1317 1307 1318 1308 static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev, ··· 1797 1785 return 0; 1798 1786 } 1799 1787 1788 + void amdgpu_device_set_uid(struct amdgpu_uid *uid_info, 1789 + enum amdgpu_uid_type type, uint8_t inst, 1790 + uint64_t uid); 1791 + uint64_t amdgpu_device_get_uid(struct amdgpu_uid *uid_info, 1792 + enum amdgpu_uid_type type, uint8_t inst); 1800 1793 #endif
+32 -21
drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c
··· 76 76 list_for_each_entry_safe(node, tmp, &banks->list, node) { 77 77 list_del(&node->node); 78 78 kvfree(node); 79 + banks->nr_banks--; 79 80 } 80 81 } 81 82 ··· 131 130 RAS_EVENT_LOG(adev, event_id, HW_ERR "hardware error logged by the scrubber\n"); 132 131 } 133 132 133 + static bool aca_bank_hwip_is_matched(struct aca_bank *bank, enum aca_hwip_type type) 134 + { 135 + 136 + struct aca_hwip *hwip; 137 + int hwid, mcatype; 138 + u64 ipid; 139 + 140 + if (!bank || type == ACA_HWIP_TYPE_UNKNOW) 141 + return false; 142 + 143 + hwip = &aca_hwid_mcatypes[type]; 144 + if (!hwip->hwid) 145 + return false; 146 + 147 + ipid = bank->regs[ACA_REG_IDX_IPID]; 148 + hwid = ACA_REG__IPID__HARDWAREID(ipid); 149 + mcatype = ACA_REG__IPID__MCATYPE(ipid); 150 + 151 + return hwip->hwid == hwid && hwip->mcatype == mcatype; 152 + } 153 + 134 154 static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_type type, 135 155 int start, int count, 136 156 struct aca_banks *banks, struct ras_query_context *qctx) ··· 190 168 191 169 bank.smu_err_type = type; 192 170 171 + /* 172 + * Poison being consumed when injecting a UE while running background workloads, 173 + * which are unexpected. 174 + */ 175 + if (type == ACA_SMU_TYPE_UE && 176 + ACA_REG__STATUS__POISON(bank.regs[ACA_REG_IDX_STATUS]) && 177 + !aca_bank_hwip_is_matched(&bank, ACA_HWIP_TYPE_UMC)) 178 + continue; 179 + 193 180 aca_smu_bank_dump(adev, i, count, &bank, qctx); 194 181 195 182 ret = aca_banks_add_bank(banks, &bank); ··· 207 176 } 208 177 209 178 return 0; 210 - } 211 - 212 - static bool aca_bank_hwip_is_matched(struct aca_bank *bank, enum aca_hwip_type type) 213 - { 214 - 215 - struct aca_hwip *hwip; 216 - int hwid, mcatype; 217 - u64 ipid; 218 - 219 - if (!bank || type == ACA_HWIP_TYPE_UNKNOW) 220 - return false; 221 - 222 - hwip = &aca_hwid_mcatypes[type]; 223 - if (!hwip->hwid) 224 - return false; 225 - 226 - ipid = bank->regs[ACA_REG_IDX_IPID]; 227 - hwid = ACA_REG__IPID__HARDWAREID(ipid); 228 - mcatype = ACA_REG__IPID__MCATYPE(ipid); 229 - 230 - return hwip->hwid == hwid && hwip->mcatype == mcatype; 231 179 } 232 180 233 181 static bool aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, enum aca_smu_type type) ··· 239 229 240 230 mutex_lock(&aerr->lock); 241 231 list_add_tail(&bank_error->node, &aerr->list); 232 + aerr->nr_errors++; 242 233 mutex_unlock(&aerr->lock); 243 234 244 235 return bank_error;
+18 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
··· 494 494 return amdgpu_sync_fence(sync, vm->last_update, GFP_KERNEL); 495 495 } 496 496 497 - static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem) 497 + static uint64_t get_pte_flags(struct amdgpu_device *adev, struct amdgpu_vm *vm, 498 + struct kgd_mem *mem) 498 499 { 499 500 uint32_t mapping_flags = AMDGPU_VM_PAGE_READABLE | 500 501 AMDGPU_VM_MTYPE_DEFAULT; ··· 505 504 if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE) 506 505 mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE; 507 506 508 - return amdgpu_gem_va_map_flags(adev, mapping_flags); 507 + return mapping_flags; 509 508 } 510 509 511 510 /** ··· 962 961 goto unwind; 963 962 } 964 963 attachment[i]->va = va; 965 - attachment[i]->pte_flags = get_pte_flags(adev, mem); 964 + attachment[i]->pte_flags = get_pte_flags(adev, vm, mem); 966 965 attachment[i]->adev = adev; 967 966 list_add(&attachment[i]->list, &mem->attachments); 968 967 ··· 2970 2969 struct amdgpu_device *adev = amdgpu_ttm_adev( 2971 2970 peer_vm->root.bo->tbo.bdev); 2972 2971 2972 + struct amdgpu_fpriv *fpriv = 2973 + container_of(peer_vm, struct amdgpu_fpriv, vm); 2974 + 2975 + ret = amdgpu_vm_bo_update(adev, fpriv->prt_va, false); 2976 + if (ret) { 2977 + dev_dbg(adev->dev, 2978 + "Memory eviction: handle PRT moved failed, pid %8d. Try again.\n", 2979 + pid_nr(process_info->pid)); 2980 + goto validate_map_fail; 2981 + } 2982 + 2973 2983 ret = amdgpu_vm_handle_moved(adev, peer_vm, &exec.ticket); 2974 2984 if (ret) { 2975 - pr_debug("Memory eviction: handle moved failed. Try again\n"); 2985 + dev_dbg(adev->dev, 2986 + "Memory eviction: handle moved failed, pid %8d. Try again.\n", 2987 + pid_nr(process_info->pid)); 2976 2988 goto validate_map_fail; 2977 2989 } 2978 2990 }
+44 -13
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
··· 1195 1195 amdgpu_connector->use_digital = true; 1196 1196 } 1197 1197 1198 + /** 1199 + * Returns the maximum supported HDMI (TMDS) pixel clock in KHz. 1200 + */ 1201 + static int amdgpu_max_hdmi_pixel_clock(const struct amdgpu_device *adev) 1202 + { 1203 + if (adev->asic_type >= CHIP_POLARIS10) 1204 + return 600000; 1205 + else if (adev->asic_type >= CHIP_TONGA) 1206 + return 300000; 1207 + else 1208 + return 297000; 1209 + } 1210 + 1211 + /** 1212 + * Validates the given display mode on DVI and HDMI connectors, 1213 + * including analog signals on DVI-I. 1214 + */ 1198 1215 static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connector *connector, 1199 1216 const struct drm_display_mode *mode) 1200 1217 { 1201 1218 struct drm_device *dev = connector->dev; 1202 1219 struct amdgpu_device *adev = drm_to_adev(dev); 1203 1220 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); 1221 + const int max_hdmi_pixel_clock = amdgpu_max_hdmi_pixel_clock(adev); 1222 + const int max_dvi_single_link_pixel_clock = 165000; 1223 + int max_digital_pixel_clock_khz; 1204 1224 1205 1225 /* XXX check mode bandwidth */ 1206 1226 1207 - if (amdgpu_connector->use_digital && (mode->clock > 165000)) { 1208 - if ((amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || 1209 - (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || 1210 - (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) { 1211 - return MODE_OK; 1212 - } else if (connector->display_info.is_hdmi) { 1213 - /* HDMI 1.3+ supports max clock of 340 Mhz */ 1214 - if (mode->clock > 340000) 1215 - return MODE_CLOCK_HIGH; 1216 - else 1217 - return MODE_OK; 1218 - } else { 1219 - return MODE_CLOCK_HIGH; 1227 + if (amdgpu_connector->use_digital) { 1228 + switch (amdgpu_connector->connector_object_id) { 1229 + case CONNECTOR_OBJECT_ID_HDMI_TYPE_A: 1230 + max_digital_pixel_clock_khz = max_hdmi_pixel_clock; 1231 + break; 1232 + case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I: 1233 + case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D: 1234 + max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock; 1235 + break; 1236 + case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I: 1237 + case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D: 1238 + case CONNECTOR_OBJECT_ID_HDMI_TYPE_B: 1239 + max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock * 2; 1240 + break; 1220 1241 } 1242 + 1243 + /* When the display EDID claims that it's an HDMI display, 1244 + * we use the HDMI encoder mode of the display HW, 1245 + * so we should verify against the max HDMI clock here. 1246 + */ 1247 + if (connector->display_info.is_hdmi) 1248 + max_digital_pixel_clock_khz = max_hdmi_pixel_clock; 1249 + 1250 + if (mode->clock > max_digital_pixel_clock_khz) 1251 + return MODE_CLOCK_HIGH; 1221 1252 } 1222 1253 1223 1254 /* check against the max pixel clock */
+6 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
··· 206 206 { 207 207 struct cper_sec_desc *section_desc; 208 208 struct cper_sec_nonstd_err *section; 209 + uint32_t socket_id; 209 210 210 211 section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx)); 211 212 section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr + ··· 225 224 section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump); 226 225 227 226 /* Hardcoded Reg dump for bad page threshold CPER */ 227 + socket_id = (adev->smuio.funcs && adev->smuio.funcs->get_socket_id) ? 228 + adev->smuio.funcs->get_socket_id(adev) : 229 + 0; 228 230 section->ctx.reg_dump[CPER_ACA_REG_CTL_LO] = 0x1; 229 231 section->ctx.reg_dump[CPER_ACA_REG_CTL_HI] = 0x0; 230 232 section->ctx.reg_dump[CPER_ACA_REG_STATUS_LO] = 0x137; ··· 238 234 section->ctx.reg_dump[CPER_ACA_REG_MISC0_HI] = 0x0; 239 235 section->ctx.reg_dump[CPER_ACA_REG_CONFIG_LO] = 0x2; 240 236 section->ctx.reg_dump[CPER_ACA_REG_CONFIG_HI] = 0x1ff; 241 - section->ctx.reg_dump[CPER_ACA_REG_IPID_LO] = 0x0; 242 - section->ctx.reg_dump[CPER_ACA_REG_IPID_HI] = 0x96; 237 + section->ctx.reg_dump[CPER_ACA_REG_IPID_LO] = (socket_id / 4) & 0x01; 238 + section->ctx.reg_dump[CPER_ACA_REG_IPID_HI] = 0x096 | (((socket_id % 4) & 0x3) << 12); 243 239 section->ctx.reg_dump[CPER_ACA_REG_SYND_LO] = 0x0; 244 240 section->ctx.reg_dump[CPER_ACA_REG_SYND_HI] = 0x0; 245 241
+10 -10
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 396 396 chunk_ib->ib_bytes : 0, 397 397 AMDGPU_IB_POOL_DELAYED, ib); 398 398 if (r) { 399 - DRM_ERROR("Failed to get ib !\n"); 399 + drm_err(adev_to_drm(p->adev), "Failed to get ib !\n"); 400 400 return r; 401 401 } 402 402 ··· 468 468 469 469 r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence); 470 470 if (r) { 471 - DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n", 471 + drm_err(adev_to_drm(p->adev), "syncobj %u failed to find fence @ %llu (%d)!\n", 472 472 handle, point, r); 473 473 return r; 474 474 } ··· 902 902 sizeof(struct page *), 903 903 GFP_KERNEL); 904 904 if (!e->user_pages) { 905 - DRM_ERROR("kvmalloc_array failure\n"); 905 + drm_err(adev_to_drm(p->adev), "kvmalloc_array failure\n"); 906 906 r = -ENOMEM; 907 907 goto out_free_user_pages; 908 908 } ··· 983 983 r = amdgpu_vm_validate(p->adev, &fpriv->vm, NULL, 984 984 amdgpu_cs_bo_validate, p); 985 985 if (r) { 986 - DRM_ERROR("amdgpu_vm_validate() failed.\n"); 986 + drm_err(adev_to_drm(p->adev), "amdgpu_vm_validate() failed.\n"); 987 987 goto out_free_user_pages; 988 988 } 989 989 ··· 1061 1061 va_start = ib->gpu_addr & AMDGPU_GMC_HOLE_MASK; 1062 1062 r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m); 1063 1063 if (r) { 1064 - DRM_ERROR("IB va_start is invalid\n"); 1064 + drm_err(adev_to_drm(p->adev), "IB va_start is invalid\n"); 1065 1065 return r; 1066 1066 } 1067 1067 1068 1068 if ((va_start + ib->length_dw * 4) > 1069 1069 (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { 1070 - DRM_ERROR("IB va_start+ib_bytes is invalid\n"); 1070 + drm_err(adev_to_drm(p->adev), "IB va_start+ib_bytes is invalid\n"); 1071 1071 return -EINVAL; 1072 1072 } 1073 1073 ··· 1238 1238 r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]); 1239 1239 if (r) { 1240 1240 if (r != -ERESTARTSYS) 1241 - DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n"); 1241 + drm_err(adev_to_drm(p->adev), "amdgpu_ctx_wait_prev_fence failed.\n"); 1242 1242 return r; 1243 1243 } 1244 1244 ··· 1451 1451 1452 1452 r = amdgpu_cs_parser_init(&parser, adev, filp, data); 1453 1453 if (r) { 1454 - DRM_ERROR_RATELIMITED("Failed to initialize parser %d!\n", r); 1454 + drm_err_ratelimited(dev, "Failed to initialize parser %d!\n", r); 1455 1455 return r; 1456 1456 } 1457 1457 ··· 1466 1466 r = amdgpu_cs_parser_bos(&parser, data); 1467 1467 if (r) { 1468 1468 if (r == -ENOMEM) 1469 - DRM_ERROR("Not enough memory for command submission!\n"); 1469 + drm_err(dev, "Not enough memory for command submission!\n"); 1470 1470 else if (r != -ERESTARTSYS && r != -EAGAIN) 1471 - DRM_DEBUG("Failed to process the buffer list %d!\n", r); 1471 + drm_dbg(dev, "Failed to process the buffer list %d!\n", r); 1472 1472 goto error_fini; 1473 1473 } 1474 1474
+216 -44
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 178 178 BIT(AMD_IP_BLOCK_TYPE_PSP) 179 179 }; 180 180 181 + static void amdgpu_device_load_switch_state(struct amdgpu_device *adev); 182 + 181 183 static inline bool amdgpu_ip_member_of_hwini(struct amdgpu_device *adev, 182 184 enum amd_ip_block_type block) 183 185 { ··· 2447 2445 return 1; 2448 2446 } 2449 2447 2448 + static const char *ip_block_names[] = { 2449 + [AMD_IP_BLOCK_TYPE_COMMON] = "common", 2450 + [AMD_IP_BLOCK_TYPE_GMC] = "gmc", 2451 + [AMD_IP_BLOCK_TYPE_IH] = "ih", 2452 + [AMD_IP_BLOCK_TYPE_SMC] = "smu", 2453 + [AMD_IP_BLOCK_TYPE_PSP] = "psp", 2454 + [AMD_IP_BLOCK_TYPE_DCE] = "dce", 2455 + [AMD_IP_BLOCK_TYPE_GFX] = "gfx", 2456 + [AMD_IP_BLOCK_TYPE_SDMA] = "sdma", 2457 + [AMD_IP_BLOCK_TYPE_UVD] = "uvd", 2458 + [AMD_IP_BLOCK_TYPE_VCE] = "vce", 2459 + [AMD_IP_BLOCK_TYPE_ACP] = "acp", 2460 + [AMD_IP_BLOCK_TYPE_VCN] = "vcn", 2461 + [AMD_IP_BLOCK_TYPE_MES] = "mes", 2462 + [AMD_IP_BLOCK_TYPE_JPEG] = "jpeg", 2463 + [AMD_IP_BLOCK_TYPE_VPE] = "vpe", 2464 + [AMD_IP_BLOCK_TYPE_UMSCH_MM] = "umsch_mm", 2465 + [AMD_IP_BLOCK_TYPE_ISP] = "isp", 2466 + }; 2467 + 2468 + static const char *ip_block_name(struct amdgpu_device *adev, enum amd_ip_block_type type) 2469 + { 2470 + int idx = (int)type; 2471 + 2472 + return idx < ARRAY_SIZE(ip_block_names) ? ip_block_names[idx] : "unknown"; 2473 + } 2474 + 2450 2475 /** 2451 2476 * amdgpu_device_ip_block_add 2452 2477 * ··· 2502 2473 break; 2503 2474 } 2504 2475 2505 - dev_info(adev->dev, "detected ip block number %d <%s>\n", 2506 - adev->num_ip_blocks, ip_block_version->funcs->name); 2476 + dev_info(adev->dev, "detected ip block number %d <%s_v%d_%d_%d> (%s)\n", 2477 + adev->num_ip_blocks, 2478 + ip_block_name(adev, ip_block_version->type), 2479 + ip_block_version->major, 2480 + ip_block_version->minor, 2481 + ip_block_version->rev, 2482 + ip_block_version->funcs->name); 2507 2483 2508 2484 adev->ip_blocks[adev->num_ip_blocks].adev = adev; 2509 2485 ··· 2708 2674 return err; 2709 2675 } 2710 2676 2677 + static void amdgpu_uid_init(struct amdgpu_device *adev) 2678 + { 2679 + /* Initialize the UID for the device */ 2680 + adev->uid_info = kzalloc(sizeof(struct amdgpu_uid), GFP_KERNEL); 2681 + if (!adev->uid_info) { 2682 + dev_warn(adev->dev, "Failed to allocate memory for UID\n"); 2683 + return; 2684 + } 2685 + adev->uid_info->adev = adev; 2686 + } 2687 + 2688 + static void amdgpu_uid_fini(struct amdgpu_device *adev) 2689 + { 2690 + /* Free the UID memory */ 2691 + kfree(adev->uid_info); 2692 + adev->uid_info = NULL; 2693 + } 2694 + 2711 2695 /** 2712 2696 * amdgpu_device_ip_early_init - run early init for hardware IPs 2713 2697 * ··· 2909 2857 if (adev->gmc.xgmi.supported) 2910 2858 amdgpu_xgmi_early_init(adev); 2911 2859 2860 + if (amdgpu_is_multi_aid(adev)) 2861 + amdgpu_uid_init(adev); 2912 2862 ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); 2913 2863 if (ip_block->status.valid != false) 2914 2864 amdgpu_amdkfd_device_probe(adev); ··· 3443 3389 for (i = 0; i < mgpu_info.num_dgpu; i++) { 3444 3390 gpu_ins = &(mgpu_info.gpu_ins[i]); 3445 3391 adev = gpu_ins->adev; 3446 - if (!(adev->flags & AMD_IS_APU) && 3392 + if (!(adev->flags & AMD_IS_APU || amdgpu_sriov_multi_vf_mode(adev)) && 3447 3393 !gpu_ins->mgpu_fan_enabled) { 3448 3394 ret = amdgpu_dpm_enable_mgpu_fan_boost(adev); 3449 3395 if (ret) ··· 3702 3648 } 3703 3649 3704 3650 amdgpu_ras_fini(adev); 3651 + amdgpu_uid_fini(adev); 3705 3652 3706 3653 return 0; 3707 3654 } ··· 5047 4992 adev->reset_domain = NULL; 5048 4993 5049 4994 kfree(adev->pci_state); 5050 - 4995 + kfree(adev->pcie_reset_ctx.swds_pcistate); 4996 + kfree(adev->pcie_reset_ctx.swus_pcistate); 5051 4997 } 5052 4998 5053 4999 /** ··· 5757 5701 5758 5702 dev_info(adev->dev, "GPU link reset\n"); 5759 5703 5760 - if (!adev->pcie_reset_ctx.occurs_dpc) 5704 + if (!amdgpu_reset_in_dpc(adev)) 5761 5705 ret = amdgpu_dpm_link_reset(adev); 5762 5706 5763 5707 if (ret) ··· 5886 5830 amdgpu_set_init_level(tmp_adev, init_level); 5887 5831 if (full_reset) { 5888 5832 /* post card */ 5833 + amdgpu_reset_set_dpc_status(tmp_adev, false); 5889 5834 amdgpu_ras_clear_err_state(tmp_adev); 5890 5835 r = amdgpu_device_asic_init(tmp_adev); 5891 5836 if (r) { ··· 6193 6136 return ret; 6194 6137 } 6195 6138 6196 - static int amdgpu_device_recovery_prepare(struct amdgpu_device *adev, 6139 + static void amdgpu_device_recovery_prepare(struct amdgpu_device *adev, 6197 6140 struct list_head *device_list, 6198 6141 struct amdgpu_hive_info *hive) 6199 6142 { 6200 6143 struct amdgpu_device *tmp_adev = NULL; 6201 - int r; 6202 6144 6203 6145 /* 6204 6146 * Build list of devices to reset. ··· 6209 6153 list_add_tail(&tmp_adev->reset_list, device_list); 6210 6154 if (adev->shutdown) 6211 6155 tmp_adev->shutdown = true; 6212 - if (adev->pcie_reset_ctx.occurs_dpc) 6156 + if (amdgpu_reset_in_dpc(adev)) 6213 6157 tmp_adev->pcie_reset_ctx.in_link_reset = true; 6214 6158 } 6215 6159 if (!list_is_first(&adev->reset_list, device_list)) ··· 6217 6161 } else { 6218 6162 list_add_tail(&adev->reset_list, device_list); 6219 6163 } 6220 - 6221 - if (!amdgpu_sriov_vf(adev) && (!adev->pcie_reset_ctx.occurs_dpc)) { 6222 - r = amdgpu_device_health_check(device_list); 6223 - if (r) 6224 - return r; 6225 - } 6226 - 6227 - return 0; 6228 6164 } 6229 6165 6230 6166 static void amdgpu_device_recovery_get_reset_lock(struct amdgpu_device *adev, ··· 6285 6237 drm_client_dev_suspend(adev_to_drm(tmp_adev), false); 6286 6238 6287 6239 /* disable ras on ALL IPs */ 6288 - if (!need_emergency_restart && 6289 - (!adev->pcie_reset_ctx.occurs_dpc) && 6290 - amdgpu_device_ip_need_full_reset(tmp_adev)) 6240 + if (!need_emergency_restart && !amdgpu_reset_in_dpc(adev) && 6241 + amdgpu_device_ip_need_full_reset(tmp_adev)) 6291 6242 amdgpu_ras_suspend(tmp_adev); 6292 6243 6293 6244 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { ··· 6314 6267 6315 6268 retry: /* Rest of adevs pre asic reset from XGMI hive. */ 6316 6269 list_for_each_entry(tmp_adev, device_list, reset_list) { 6317 - if (adev->pcie_reset_ctx.occurs_dpc) 6318 - tmp_adev->no_hw_access = true; 6319 6270 r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context); 6320 - if (adev->pcie_reset_ctx.occurs_dpc) 6321 - tmp_adev->no_hw_access = false; 6322 6271 /*TODO Should we stop ?*/ 6323 6272 if (r) { 6324 6273 dev_err(tmp_adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ", ··· 6492 6449 emergency_restart(); 6493 6450 } 6494 6451 6495 - dev_info(adev->dev, "GPU %s begin!\n", 6496 - need_emergency_restart ? "jobs stop":"reset"); 6452 + dev_info(adev->dev, "GPU %s begin!. Source: %d\n", 6453 + need_emergency_restart ? "jobs stop" : "reset", 6454 + reset_context->src); 6497 6455 6498 6456 if (!amdgpu_sriov_vf(adev)) 6499 6457 hive = amdgpu_get_xgmi_hive(adev); ··· 6505 6461 reset_context->hive = hive; 6506 6462 INIT_LIST_HEAD(&device_list); 6507 6463 6508 - if (amdgpu_device_recovery_prepare(adev, &device_list, hive)) 6509 - goto end_reset; 6464 + amdgpu_device_recovery_prepare(adev, &device_list, hive); 6465 + 6466 + if (!amdgpu_sriov_vf(adev)) { 6467 + r = amdgpu_device_health_check(&device_list); 6468 + if (r) 6469 + goto end_reset; 6470 + } 6510 6471 6511 6472 /* We need to lock reset domain only once both for XGMI and single device */ 6512 6473 amdgpu_device_recovery_get_reset_lock(adev, &device_list); ··· 6939 6890 6940 6891 dev_info(adev->dev, "PCI error: detected callback!!\n"); 6941 6892 6942 - if (!amdgpu_dpm_is_link_reset_supported(adev)) { 6943 - dev_warn(adev->dev, "No support for XGMI hive yet...\n"); 6944 - return PCI_ERS_RESULT_DISCONNECT; 6945 - } 6946 - 6947 6893 adev->pci_channel_state = state; 6948 6894 6949 6895 switch (state) { ··· 6948 6904 case pci_channel_io_frozen: 6949 6905 /* Fatal error, prepare for slot reset */ 6950 6906 dev_info(adev->dev, "pci_channel_io_frozen: state(%d)!!\n", state); 6907 + if (hive) { 6908 + /* Hive devices should be able to support FW based 6909 + * link reset on other devices, if not return. 6910 + */ 6911 + if (!amdgpu_dpm_is_link_reset_supported(adev)) { 6912 + dev_warn(adev->dev, 6913 + "No support for XGMI hive yet...\n"); 6914 + return PCI_ERS_RESULT_DISCONNECT; 6915 + } 6916 + /* Set dpc status only if device is part of hive 6917 + * Non-hive devices should be able to recover after 6918 + * link reset. 6919 + */ 6920 + amdgpu_reset_set_dpc_status(adev, true); 6951 6921 6952 - if (hive) 6953 6922 mutex_lock(&hive->hive_lock); 6954 - adev->pcie_reset_ctx.occurs_dpc = true; 6923 + } 6955 6924 memset(&reset_context, 0, sizeof(reset_context)); 6956 6925 INIT_LIST_HEAD(&device_list); 6957 6926 ··· 7023 6966 struct amdgpu_device *tmp_adev; 7024 6967 struct amdgpu_hive_info *hive; 7025 6968 struct list_head device_list; 7026 - int r = 0, i; 6969 + struct pci_dev *link_dev; 6970 + int r = 0, i, timeout; 7027 6971 u32 memsize; 7028 - 7029 - /* PCI error slot reset should be skipped During RAS recovery */ 7030 - if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) || 7031 - amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4)) && 7032 - amdgpu_ras_in_recovery(adev)) 7033 - return PCI_ERS_RESULT_RECOVERED; 6972 + u16 status; 7034 6973 7035 6974 dev_info(adev->dev, "PCI error: slot reset callback!!\n"); 7036 6975 7037 6976 memset(&reset_context, 0, sizeof(reset_context)); 7038 6977 7039 - /* wait for asic to come out of reset */ 7040 - msleep(700); 6978 + if (adev->pcie_reset_ctx.swus) 6979 + link_dev = adev->pcie_reset_ctx.swus; 6980 + else 6981 + link_dev = adev->pdev; 6982 + /* wait for asic to come out of reset, timeout = 10s */ 6983 + timeout = 10000; 6984 + do { 6985 + usleep_range(10000, 10500); 6986 + r = pci_read_config_word(link_dev, PCI_VENDOR_ID, &status); 6987 + timeout -= 10; 6988 + } while (timeout > 0 && (status != PCI_VENDOR_ID_ATI) && 6989 + (status != PCI_VENDOR_ID_AMD)); 7041 6990 6991 + if ((status != PCI_VENDOR_ID_ATI) && (status != PCI_VENDOR_ID_AMD)) { 6992 + r = -ETIME; 6993 + goto out; 6994 + } 6995 + 6996 + amdgpu_device_load_switch_state(adev); 7042 6997 /* Restore PCI confspace */ 7043 6998 amdgpu_device_load_pci_state(pdev); 7044 6999 ··· 7145 7076 amdgpu_device_sched_resume(&device_list, NULL, NULL); 7146 7077 amdgpu_device_gpu_resume(adev, &device_list, false); 7147 7078 amdgpu_device_recovery_put_reset_lock(adev, &device_list); 7148 - adev->pcie_reset_ctx.occurs_dpc = false; 7149 7079 7150 7080 if (hive) { 7151 7081 mutex_unlock(&hive->hive_lock); 7152 7082 amdgpu_put_xgmi_hive(hive); 7153 7083 } 7084 + } 7085 + 7086 + static void amdgpu_device_cache_switch_state(struct amdgpu_device *adev) 7087 + { 7088 + struct pci_dev *parent = pci_upstream_bridge(adev->pdev); 7089 + int r; 7090 + 7091 + if (parent->vendor != PCI_VENDOR_ID_ATI) 7092 + return; 7093 + 7094 + /* If already saved, return */ 7095 + if (adev->pcie_reset_ctx.swus) 7096 + return; 7097 + /* Upstream bridge is ATI, assume it's SWUS/DS architecture */ 7098 + r = pci_save_state(parent); 7099 + if (r) 7100 + return; 7101 + adev->pcie_reset_ctx.swds_pcistate = pci_store_saved_state(parent); 7102 + 7103 + parent = pci_upstream_bridge(parent); 7104 + r = pci_save_state(parent); 7105 + if (r) 7106 + return; 7107 + adev->pcie_reset_ctx.swus_pcistate = pci_store_saved_state(parent); 7108 + 7109 + adev->pcie_reset_ctx.swus = parent; 7110 + } 7111 + 7112 + static void amdgpu_device_load_switch_state(struct amdgpu_device *adev) 7113 + { 7114 + struct pci_dev *pdev; 7115 + int r; 7116 + 7117 + if (!adev->pcie_reset_ctx.swds_pcistate || 7118 + !adev->pcie_reset_ctx.swus_pcistate) 7119 + return; 7120 + 7121 + pdev = adev->pcie_reset_ctx.swus; 7122 + r = pci_load_saved_state(pdev, adev->pcie_reset_ctx.swus_pcistate); 7123 + if (!r) { 7124 + pci_restore_state(pdev); 7125 + } else { 7126 + dev_warn(adev->dev, "Failed to load SWUS state, err:%d\n", r); 7127 + return; 7128 + } 7129 + 7130 + pdev = pci_upstream_bridge(adev->pdev); 7131 + r = pci_load_saved_state(pdev, adev->pcie_reset_ctx.swds_pcistate); 7132 + if (!r) 7133 + pci_restore_state(pdev); 7134 + else 7135 + dev_warn(adev->dev, "Failed to load SWDS state, err:%d\n", r); 7154 7136 } 7155 7137 7156 7138 bool amdgpu_device_cache_pci_state(struct pci_dev *pdev) ··· 7227 7107 dev_warn(adev->dev, "Failed to save PCI state, err:%d\n", r); 7228 7108 return false; 7229 7109 } 7110 + 7111 + amdgpu_device_cache_switch_state(adev); 7230 7112 7231 7113 return true; 7232 7114 } ··· 7615 7493 7616 7494 size += sysfs_emit_at(buf, size, "\n"); 7617 7495 return size; 7496 + } 7497 + 7498 + void amdgpu_device_set_uid(struct amdgpu_uid *uid_info, 7499 + enum amdgpu_uid_type type, uint8_t inst, 7500 + uint64_t uid) 7501 + { 7502 + if (!uid_info) 7503 + return; 7504 + 7505 + if (type >= AMDGPU_UID_TYPE_MAX) { 7506 + dev_err_once(uid_info->adev->dev, "Invalid UID type %d\n", 7507 + type); 7508 + return; 7509 + } 7510 + 7511 + if (inst >= AMDGPU_UID_INST_MAX) { 7512 + dev_err_once(uid_info->adev->dev, "Invalid UID instance %d\n", 7513 + inst); 7514 + return; 7515 + } 7516 + 7517 + if (uid_info->uid[type][inst] != 0) { 7518 + dev_warn_once( 7519 + uid_info->adev->dev, 7520 + "Overwriting existing UID %llu for type %d instance %d\n", 7521 + uid_info->uid[type][inst], type, inst); 7522 + } 7523 + 7524 + uid_info->uid[type][inst] = uid; 7525 + } 7526 + 7527 + u64 amdgpu_device_get_uid(struct amdgpu_uid *uid_info, 7528 + enum amdgpu_uid_type type, uint8_t inst) 7529 + { 7530 + if (!uid_info) 7531 + return 0; 7532 + 7533 + if (type >= AMDGPU_UID_TYPE_MAX) { 7534 + dev_err_once(uid_info->adev->dev, "Invalid UID type %d\n", 7535 + type); 7536 + return 0; 7537 + } 7538 + 7539 + if (inst >= AMDGPU_UID_INST_MAX) { 7540 + dev_err_once(uid_info->adev->dev, "Invalid UID instance %d\n", 7541 + inst); 7542 + return 0; 7543 + } 7544 + 7545 + return uid_info->uid[type][inst]; 7618 7546 }
+19 -12
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 886 886 887 887 /** 888 888 * DOC: dcdebugmask (uint) 889 - * Override display features enabled. See enum DC_DEBUG_MASK in drivers/gpu/drm/amd/include/amd_shared.h. 889 + * Display debug options. See enum DC_DEBUG_MASK in drivers/gpu/drm/amd/include/amd_shared.h. 890 890 */ 891 891 MODULE_PARM_DESC(dcdebugmask, "all debug options disabled (default))"); 892 892 module_param_named(dcdebugmask, amdgpu_dc_debug_mask, uint, 0444); ··· 2597 2597 else if (amdgpu_acpi_is_s3_active(adev)) 2598 2598 adev->in_s3 = true; 2599 2599 if (!adev->in_s0ix && !adev->in_s3) { 2600 + #if IS_ENABLED(CONFIG_SUSPEND) 2600 2601 /* don't allow going deep first time followed by s2idle the next time */ 2601 2602 if (adev->last_suspend_state != PM_SUSPEND_ON && 2602 2603 adev->last_suspend_state != pm_suspend_target_state) { ··· 2605 2604 pm_suspend_target_state); 2606 2605 return -EINVAL; 2607 2606 } 2607 + #endif 2608 2608 return 0; 2609 2609 } 2610 2610 2611 + #if IS_ENABLED(CONFIG_SUSPEND) 2611 2612 /* cache the state last used for suspend */ 2612 2613 adev->last_suspend_state = pm_suspend_target_state; 2614 + #endif 2613 2615 2614 2616 return amdgpu_device_suspend(drm_dev, true); 2615 2617 } ··· 2937 2933 { 2938 2934 struct drm_file *file_priv = filp->private_data; 2939 2935 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 2936 + struct drm_device *dev = file_priv->minor->dev; 2937 + int idx; 2940 2938 2941 - if (fpriv) { 2939 + if (fpriv && drm_dev_enter(dev, &idx)) { 2942 2940 fpriv->evf_mgr.fd_closing = true; 2943 2941 amdgpu_eviction_fence_destroy(&fpriv->evf_mgr); 2944 2942 amdgpu_userq_mgr_fini(&fpriv->userq_mgr); 2943 + drm_dev_exit(idx); 2945 2944 } 2946 2945 2947 2946 return drm_release(inode, filp); ··· 2971 2964 } 2972 2965 2973 2966 static const struct dev_pm_ops amdgpu_pm_ops = { 2974 - .prepare = amdgpu_pmops_prepare, 2975 - .complete = amdgpu_pmops_complete, 2976 - .suspend = amdgpu_pmops_suspend, 2977 - .suspend_noirq = amdgpu_pmops_suspend_noirq, 2978 - .resume = amdgpu_pmops_resume, 2979 - .freeze = amdgpu_pmops_freeze, 2980 - .thaw = amdgpu_pmops_thaw, 2981 - .poweroff = amdgpu_pmops_poweroff, 2982 - .restore = amdgpu_pmops_restore, 2967 + .prepare = pm_sleep_ptr(amdgpu_pmops_prepare), 2968 + .complete = pm_sleep_ptr(amdgpu_pmops_complete), 2969 + .suspend = pm_sleep_ptr(amdgpu_pmops_suspend), 2970 + .suspend_noirq = pm_sleep_ptr(amdgpu_pmops_suspend_noirq), 2971 + .resume = pm_sleep_ptr(amdgpu_pmops_resume), 2972 + .freeze = pm_sleep_ptr(amdgpu_pmops_freeze), 2973 + .thaw = pm_sleep_ptr(amdgpu_pmops_thaw), 2974 + .poweroff = pm_sleep_ptr(amdgpu_pmops_poweroff), 2975 + .restore = pm_sleep_ptr(amdgpu_pmops_restore), 2983 2976 .runtime_suspend = amdgpu_pmops_runtime_suspend, 2984 2977 .runtime_resume = amdgpu_pmops_runtime_resume, 2985 2978 .runtime_idle = amdgpu_pmops_runtime_idle, ··· 3124 3117 .probe = amdgpu_pci_probe, 3125 3118 .remove = amdgpu_pci_remove, 3126 3119 .shutdown = amdgpu_pci_shutdown, 3127 - .driver.pm = &amdgpu_pm_ops, 3120 + .driver.pm = pm_ptr(&amdgpu_pm_ops), 3128 3121 .err_handler = &amdgpu_pci_err_handler, 3129 3122 .dev_groups = amdgpu_sysfs_groups, 3130 3123 };
+1 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
··· 120 120 am_fence = kzalloc(sizeof(*am_fence), GFP_KERNEL); 121 121 if (!am_fence) 122 122 return -ENOMEM; 123 - am_fence->context = 0; 124 123 } else { 125 124 am_fence = af; 126 125 } ··· 737 738 } 738 739 739 740 740 - /** 741 + /* 741 742 * Kernel queue reset handling 742 743 * 743 744 * The driver can reset individual queues for most engines, but those queues
+2 -35
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 790 790 return fence; 791 791 } 792 792 793 - /** 794 - * amdgpu_gem_va_map_flags - map GEM UAPI flags into hardware flags 795 - * 796 - * @adev: amdgpu_device pointer 797 - * @flags: GEM UAPI flags 798 - * 799 - * Returns the GEM UAPI flags mapped into hardware for the ASIC. 800 - */ 801 - uint64_t amdgpu_gem_va_map_flags(struct amdgpu_device *adev, uint32_t flags) 802 - { 803 - uint64_t pte_flag = 0; 804 - 805 - if (flags & AMDGPU_VM_PAGE_EXECUTABLE) 806 - pte_flag |= AMDGPU_PTE_EXECUTABLE; 807 - if (flags & AMDGPU_VM_PAGE_READABLE) 808 - pte_flag |= AMDGPU_PTE_READABLE; 809 - if (flags & AMDGPU_VM_PAGE_WRITEABLE) 810 - pte_flag |= AMDGPU_PTE_WRITEABLE; 811 - if (flags & AMDGPU_VM_PAGE_PRT) 812 - pte_flag |= AMDGPU_PTE_PRT_FLAG(adev); 813 - if (flags & AMDGPU_VM_PAGE_NOALLOC) 814 - pte_flag |= AMDGPU_PTE_NOALLOC; 815 - 816 - if (adev->gmc.gmc_funcs->map_mtype) 817 - pte_flag |= amdgpu_gmc_map_mtype(adev, 818 - flags & AMDGPU_VM_MTYPE_MASK); 819 - 820 - return pte_flag; 821 - } 822 - 823 793 int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 824 794 struct drm_file *filp) 825 795 { ··· 810 840 struct dma_fence_chain *timeline_chain = NULL; 811 841 struct dma_fence *fence; 812 842 struct drm_exec exec; 813 - uint64_t va_flags; 814 843 uint64_t vm_size; 815 844 int r = 0; 816 845 ··· 913 944 914 945 switch (args->operation) { 915 946 case AMDGPU_VA_OP_MAP: 916 - va_flags = amdgpu_gem_va_map_flags(adev, args->flags); 917 947 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, 918 948 args->offset_in_bo, args->map_size, 919 - va_flags); 949 + args->flags); 920 950 break; 921 951 case AMDGPU_VA_OP_UNMAP: 922 952 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); ··· 927 959 args->map_size); 928 960 break; 929 961 case AMDGPU_VA_OP_REPLACE: 930 - va_flags = amdgpu_gem_va_map_flags(adev, args->flags); 931 962 r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address, 932 963 args->offset_in_bo, args->map_size, 933 - va_flags); 964 + args->flags); 934 965 break; 935 966 default: 936 967 break;
-1
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
··· 63 63 struct drm_file *filp); 64 64 int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data, 65 65 struct drm_file *filp); 66 - uint64_t amdgpu_gem_va_map_flags(struct amdgpu_device *adev, uint32_t flags); 67 66 int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 68 67 struct drm_file *filp); 69 68 int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
+8 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
··· 154 154 unsigned pasid); 155 155 /* enable/disable PRT support */ 156 156 void (*set_prt)(struct amdgpu_device *adev, bool enable); 157 - /* map mtype to hardware flags */ 158 - uint64_t (*map_mtype)(struct amdgpu_device *adev, uint32_t flags); 159 157 /* get the pde for a given mc addr */ 160 158 void (*get_vm_pde)(struct amdgpu_device *adev, int level, 161 159 u64 *dst, u64 *flags); 162 - /* get the pte flags to use for a BO VA mapping */ 160 + /* get the pte flags to use for PTEs */ 163 161 void (*get_vm_pte)(struct amdgpu_device *adev, 164 - struct amdgpu_bo_va_mapping *mapping, 165 - uint64_t *flags); 162 + struct amdgpu_vm *vm, 163 + struct amdgpu_bo *bo, 164 + uint32_t vm_flags, 165 + uint64_t *pte_flags); 166 166 /* override per-page pte flags */ 167 167 void (*override_vm_pte_flags)(struct amdgpu_device *dev, 168 168 struct amdgpu_vm *vm, ··· 356 356 357 357 #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr)) 358 358 #define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid)) 359 - #define amdgpu_gmc_map_mtype(adev, flags) (adev)->gmc.gmc_funcs->map_mtype((adev),(flags)) 360 359 #define amdgpu_gmc_get_vm_pde(adev, level, dst, flags) (adev)->gmc.gmc_funcs->get_vm_pde((adev), (level), (dst), (flags)) 361 - #define amdgpu_gmc_get_vm_pte(adev, mapping, flags) (adev)->gmc.gmc_funcs->get_vm_pte((adev), (mapping), (flags)) 360 + #define amdgpu_gmc_get_vm_pte(adev, vm, bo, vm_flags, pte_flags) \ 361 + ((adev)->gmc.gmc_funcs->get_vm_pte((adev), (vm), (bo), (vm_flags), \ 362 + (pte_flags))) 362 363 #define amdgpu_gmc_override_vm_pte_flags(adev, vm, addr, pte_flags) \ 363 364 (adev)->gmc.gmc_funcs->override_vm_pte_flags \ 364 365 ((adev), (vm), (addr), (pte_flags))
+5 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
··· 121 121 fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec[j]); 122 122 } 123 123 124 - if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt)) 124 + if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt)) { 125 + mutex_lock(&adev->jpeg.jpeg_pg_lock); 125 126 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 126 127 AMD_PG_STATE_GATE); 127 - else 128 + mutex_unlock(&adev->jpeg.jpeg_pg_lock); 129 + } else 128 130 schedule_delayed_work(&adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT); 129 131 } 130 132 ··· 370 368 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 371 369 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 372 370 ring = &adev->jpeg.inst[i].ring_dec[j]; 373 - if (val & (1 << ((i * adev->jpeg.num_jpeg_rings) + j))) 371 + if (val & (BIT_ULL(1) << ((i * adev->jpeg.num_jpeg_rings) + j))) 374 372 ring->sched.ready = true; 375 373 else 376 374 ring->sched.ready = false;
+10
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
··· 280 280 bool is_kq; 281 281 }; 282 282 283 + struct mes_inv_tlbs_pasid_input { 284 + uint32_t xcc_id; 285 + uint16_t pasid; 286 + uint8_t hub_id; 287 + uint8_t flush_type; 288 + }; 289 + 283 290 enum mes_misc_opcode { 284 291 MES_MISC_OP_WRITE_REG, 285 292 MES_MISC_OP_READ_REG, ··· 374 367 375 368 int (*reset_hw_queue)(struct amdgpu_mes *mes, 376 369 struct mes_reset_queue_input *input); 370 + 371 + int (*invalidate_tlbs_pasid)(struct amdgpu_mes *mes, 372 + struct mes_inv_tlbs_pasid_input *input); 377 373 }; 378 374 379 375 #define amdgpu_mes_kiq_hw_init(adev) (adev)->mes.kiq_hw_init((adev))
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
··· 69 69 uint64_t last; 70 70 uint64_t __subtree_last; 71 71 uint64_t offset; 72 - uint64_t flags; 72 + uint32_t flags; 73 73 }; 74 74 75 75 /* User space allocated BO in a VM */
+6 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 506 506 } 507 507 508 508 ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, 509 - (amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ? 510 - AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, 509 + AMDGPU_GEM_DOMAIN_VRAM, 511 510 &psp->fw_pri_bo, 512 511 &psp->fw_pri_mc_addr, 513 512 &psp->fw_pri_buf); ··· 665 666 return "FB_FW_RESERV_ADDR"; 666 667 case GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR: 667 668 return "FB_FW_RESERV_EXT_ADDR"; 669 + case GFX_CMD_ID_SRIOV_SPATIAL_PART: 670 + return "SPATIAL_PARTITION"; 671 + case GFX_CMD_ID_FB_NPS_MODE: 672 + return "NPS_MODE_CHANGE"; 668 673 default: 669 674 return "UNKNOWN CMD"; 670 675 } ··· 880 877 pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; 881 878 ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, 882 879 PSP_TMR_ALIGNMENT, 883 - AMDGPU_HAS_VRAM(psp->adev) ? 884 - AMDGPU_GEM_DOMAIN_VRAM : 885 - AMDGPU_GEM_DOMAIN_GTT, 880 + AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM, 886 881 &psp->tmr_bo, &psp->tmr_mc_addr, 887 882 pptr); 888 883 }
+250 -85
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
··· 122 122 /* typical ECC bad page rate is 1 bad page per 100MB VRAM */ 123 123 #define RAS_BAD_PAGE_COVER (100 * 1024 * 1024ULL) 124 124 125 - #define MAX_UMC_POISON_POLLING_TIME_ASYNC 300 //ms 125 + #define MAX_UMC_POISON_POLLING_TIME_ASYNC 10 126 126 127 127 #define AMDGPU_RAS_RETIRE_PAGE_INTERVAL 100 //ms 128 128 129 129 #define MAX_FLUSH_RETIRE_DWORK_TIMES 100 130 + 131 + #define BYPASS_ALLOCATED_ADDRESS 0x0 132 + #define BYPASS_INITIALIZATION_ADDRESS 0x1 130 133 131 134 enum amdgpu_ras_retire_page_reservation { 132 135 AMDGPU_RAS_RETIRE_PAGE_RESERVED, ··· 139 136 140 137 atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0); 141 138 142 - static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, 139 + static int amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, 143 140 uint64_t addr); 144 - static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, 141 + static int amdgpu_ras_check_bad_page(struct amdgpu_device *adev, 145 142 uint64_t addr); 143 + 144 + static void amdgpu_ras_critical_region_init(struct amdgpu_device *adev); 145 + static void amdgpu_ras_critical_region_fini(struct amdgpu_device *adev); 146 + 146 147 #ifdef CONFIG_X86_MCE_AMD 147 148 static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev); 148 149 struct mce_notifier_adev_list { ··· 176 169 struct eeprom_table_record err_rec; 177 170 int ret; 178 171 179 - if ((address >= adev->gmc.mc_vram_size) || 180 - (address >= RAS_UMC_INJECT_ADDR_LIMIT)) { 172 + ret = amdgpu_ras_check_bad_page(adev, address); 173 + if (ret == -EINVAL) { 181 174 dev_warn(adev->dev, 182 - "RAS WARN: input address 0x%llx is invalid.\n", 183 - address); 175 + "RAS WARN: input address 0x%llx is invalid.\n", 176 + address); 184 177 return -EINVAL; 185 - } 186 - 187 - if (amdgpu_ras_check_bad_page(adev, address)) { 178 + } else if (ret == 1) { 188 179 dev_warn(adev->dev, 189 - "RAS WARN: 0x%llx has already been marked as bad page!\n", 190 - address); 180 + "RAS WARN: 0x%llx has already been marked as bad page!\n", 181 + address); 191 182 return 0; 192 183 } 193 184 ··· 208 203 dev_warn(adev->dev, "WARNING: THIS IS ONLY FOR TEST PURPOSES AND WILL CORRUPT RAS EEPROM\n"); 209 204 dev_warn(adev->dev, "Clear EEPROM:\n"); 210 205 dev_warn(adev->dev, " echo 1 > /sys/kernel/debug/dri/0/ras/ras_eeprom_reset\n"); 206 + 207 + return 0; 208 + } 209 + 210 + static int amdgpu_check_address_validity(struct amdgpu_device *adev, 211 + uint64_t address, uint64_t flags) 212 + { 213 + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 214 + struct amdgpu_vram_block_info blk_info; 215 + uint64_t page_pfns[32] = {0}; 216 + int i, ret, count; 217 + 218 + if (amdgpu_ip_version(adev, UMC_HWIP, 0) < IP_VERSION(12, 0, 0)) 219 + return 0; 220 + 221 + if ((address >= adev->gmc.mc_vram_size) || 222 + (address >= RAS_UMC_INJECT_ADDR_LIMIT)) 223 + return -EFAULT; 224 + 225 + count = amdgpu_umc_lookup_bad_pages_in_a_row(adev, 226 + address, page_pfns, ARRAY_SIZE(page_pfns)); 227 + if (count <= 0) 228 + return -EPERM; 229 + 230 + for (i = 0; i < count; i++) { 231 + memset(&blk_info, 0, sizeof(blk_info)); 232 + ret = amdgpu_vram_mgr_query_address_block_info(&adev->mman.vram_mgr, 233 + page_pfns[i] << AMDGPU_GPU_PAGE_SHIFT, &blk_info); 234 + if (!ret) { 235 + /* The input address that needs to be checked is allocated by 236 + * current calling process, so it is necessary to exclude 237 + * the calling process. 238 + */ 239 + if ((flags == BYPASS_ALLOCATED_ADDRESS) && 240 + ((blk_info.task.pid != task_pid_nr(current)) || 241 + strncmp(blk_info.task.comm, current->comm, TASK_COMM_LEN))) 242 + return -EACCES; 243 + else if ((flags == BYPASS_INITIALIZATION_ADDRESS) && 244 + (blk_info.task.pid == con->init_task_pid) && 245 + !strncmp(blk_info.task.comm, con->init_task_comm, TASK_COMM_LEN)) 246 + return -EACCES; 247 + } 248 + } 211 249 212 250 return 0; 213 251 } ··· 345 297 op = 2; 346 298 else if (strstr(str, "retire_page") != NULL) 347 299 op = 3; 300 + else if (strstr(str, "check_address") != NULL) 301 + op = 4; 348 302 else if (str[0] && str[1] && str[2] && str[3]) 349 303 /* ascii string, but commands are not matched. */ 350 304 return -EINVAL; ··· 360 310 data->op = op; 361 311 data->inject.address = address; 362 312 313 + return 0; 314 + } else if (op == 4) { 315 + if (sscanf(str, "%*s 0x%llx 0x%llx", &address, &value) != 2 && 316 + sscanf(str, "%*s %llu %llu", &address, &value) != 2) 317 + return -EINVAL; 318 + 319 + data->op = op; 320 + data->inject.address = address; 321 + data->inject.value = value; 363 322 return 0; 364 323 } 365 324 ··· 559 500 return size; 560 501 else 561 502 return ret; 503 + } else if (data.op == 4) { 504 + ret = amdgpu_check_address_validity(adev, data.inject.address, data.inject.value); 505 + return ret ? ret : size; 562 506 } 563 507 564 508 if (!amdgpu_ras_is_supported(adev, data.head.block)) ··· 575 513 ret = amdgpu_ras_feature_enable(adev, &data.head, 1); 576 514 break; 577 515 case 2: 578 - if ((data.inject.address >= adev->gmc.mc_vram_size && 579 - adev->gmc.mc_vram_size) || 580 - (data.inject.address >= RAS_UMC_INJECT_ADDR_LIMIT)) { 581 - dev_warn(adev->dev, "RAS WARN: input address " 582 - "0x%llx is invalid.", 583 - data.inject.address); 584 - ret = -EINVAL; 585 - break; 586 - } 587 - 588 516 /* umc ce/ue error injection for a bad page is not allowed */ 589 - if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) && 590 - amdgpu_ras_check_bad_page(adev, data.inject.address)) { 591 - dev_warn(adev->dev, "RAS WARN: inject: 0x%llx has " 592 - "already been marked as bad!\n", 593 - data.inject.address); 517 + if (data.head.block == AMDGPU_RAS_BLOCK__UMC) 518 + ret = amdgpu_ras_check_bad_page(adev, data.inject.address); 519 + if (ret == -EINVAL) { 520 + dev_warn(adev->dev, "RAS WARN: input address 0x%llx is invalid.", 521 + data.inject.address); 522 + break; 523 + } else if (ret == 1) { 524 + dev_warn(adev->dev, "RAS WARN: inject: 0x%llx has already been marked as bad!\n", 525 + data.inject.address); 594 526 break; 595 527 } 596 528 ··· 2622 2566 goto out; 2623 2567 } 2624 2568 2625 - *bps = kmalloc(sizeof(struct ras_badpage) * data->count, GFP_KERNEL); 2569 + *bps = kmalloc_array(data->count, sizeof(struct ras_badpage), GFP_KERNEL); 2626 2570 if (!*bps) { 2627 2571 ret = -ENOMEM; 2628 2572 goto out; 2629 2573 } 2630 2574 2631 2575 for (; i < data->count; i++) { 2576 + if (!data->bps[i].ts) 2577 + continue; 2578 + 2632 2579 (*bps)[i] = (struct ras_badpage){ 2633 2580 .bp = data->bps[i].retired_page, 2634 2581 .size = AMDGPU_GPU_PAGE_SIZE, 2635 2582 .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, 2636 2583 }; 2584 + 2585 + if (amdgpu_ras_check_critical_address(adev, 2586 + data->bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT)) 2587 + continue; 2588 + 2637 2589 status = amdgpu_vram_mgr_query_page_status(&adev->mman.vram_mgr, 2638 2590 data->bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT); 2639 2591 if (status == -EBUSY) ··· 2650 2586 (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; 2651 2587 } 2652 2588 2653 - *count = data->count; 2589 + *count = con->bad_page_num; 2654 2590 out: 2655 2591 mutex_unlock(&con->recovery_lock); 2656 2592 return ret; ··· 2786 2722 unsigned int old_space = data->count + data->space_left; 2787 2723 unsigned int new_space = old_space + pages; 2788 2724 unsigned int align_space = ALIGN(new_space, 512); 2789 - void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL); 2725 + void *bps = kmalloc_array(align_space, sizeof(*data->bps), GFP_KERNEL); 2790 2726 2791 2727 if (!bps) { 2792 2728 return -ENOMEM; ··· 2878 2814 2879 2815 for (j = 0; j < count; j++) { 2880 2816 if (amdgpu_ras_check_bad_page_unlock(con, 2881 - bps[j].retired_page << AMDGPU_GPU_PAGE_SHIFT)) 2817 + bps[j].retired_page << AMDGPU_GPU_PAGE_SHIFT)) { 2818 + data->count++; 2819 + data->space_left--; 2882 2820 continue; 2821 + } 2883 2822 2884 2823 if (!data->space_left && 2885 2824 amdgpu_ras_realloc_eh_data_space(adev, data, 256)) { ··· 2895 2828 sizeof(struct eeprom_table_record)); 2896 2829 data->count++; 2897 2830 data->space_left--; 2831 + con->bad_page_num++; 2898 2832 } 2899 2833 2900 2834 return 0; ··· 3042 2974 ret = __amdgpu_ras_convert_rec_array_from_rom(adev, 3043 2975 &bps[i], &err_data, nps); 3044 2976 if (ret) 3045 - control->ras_num_bad_pages -= adev->umc.retire_unit; 2977 + con->bad_page_num -= adev->umc.retire_unit; 3046 2978 i += (adev->umc.retire_unit - 1); 3047 2979 } else { 3048 2980 break; ··· 3056 2988 ret = __amdgpu_ras_convert_rec_from_rom(adev, 3057 2989 &bps[i], &err_data, nps); 3058 2990 if (ret) 3059 - control->ras_num_bad_pages -= adev->umc.retire_unit; 2991 + con->bad_page_num -= adev->umc.retire_unit; 3060 2992 } 2993 + 2994 + con->eh_data->count_saved = con->eh_data->count; 3061 2995 } else { 3062 2996 ret = __amdgpu_ras_restore_bad_pages(adev, bps, pages); 3063 2997 } ··· 3082 3012 struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 3083 3013 struct ras_err_handler_data *data; 3084 3014 struct amdgpu_ras_eeprom_control *control; 3085 - int save_count, unit_num, bad_page_num, i; 3015 + int save_count, unit_num, i; 3086 3016 3087 3017 if (!con || !con->eh_data) { 3088 3018 if (new_cnt) ··· 3103 3033 mutex_lock(&con->recovery_lock); 3104 3034 control = &con->eeprom_control; 3105 3035 data = con->eh_data; 3106 - bad_page_num = control->ras_num_bad_pages; 3107 - save_count = data->count - bad_page_num; 3036 + unit_num = data->count / adev->umc.retire_unit - control->ras_num_recs; 3037 + save_count = con->bad_page_num - control->ras_num_bad_pages; 3108 3038 mutex_unlock(&con->recovery_lock); 3109 3039 3110 - unit_num = save_count / adev->umc.retire_unit; 3111 3040 if (new_cnt) 3112 3041 *new_cnt = unit_num; 3113 3042 3114 3043 /* only new entries are saved */ 3115 - if (save_count > 0) { 3044 + if (unit_num > 0) { 3116 3045 /*old asics only save pa to eeprom like before*/ 3117 3046 if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) < 12) { 3118 3047 if (amdgpu_ras_eeprom_append(control, 3119 - &data->bps[bad_page_num], save_count)) { 3048 + &data->bps[data->count_saved], unit_num)) { 3120 3049 dev_err(adev->dev, "Failed to save EEPROM table data!"); 3121 3050 return -EIO; 3122 3051 } 3123 3052 } else { 3124 3053 for (i = 0; i < unit_num; i++) { 3125 3054 if (amdgpu_ras_eeprom_append(control, 3126 - &data->bps[bad_page_num + 3055 + &data->bps[data->count_saved + 3127 3056 i * adev->umc.retire_unit], 1)) { 3128 3057 dev_err(adev->dev, "Failed to save EEPROM table data!"); 3129 3058 return -EIO; ··· 3131 3062 } 3132 3063 3133 3064 dev_info(adev->dev, "Saved %d pages to EEPROM table.\n", save_count); 3065 + data->count_saved = data->count; 3134 3066 } 3135 3067 3136 3068 return 0; ··· 3186 3116 } 3187 3117 } 3188 3118 3119 + ret = amdgpu_ras_add_bad_pages(adev, bps, control->ras_num_recs, true); 3120 + if (ret) 3121 + goto out; 3122 + 3189 3123 ret = amdgpu_ras_eeprom_check(control); 3190 3124 if (ret) 3191 3125 goto out; 3192 3126 3193 3127 /* HW not usable */ 3194 - if (amdgpu_ras_is_rma(adev)) { 3128 + if (amdgpu_ras_is_rma(adev)) 3195 3129 ret = -EHWPOISON; 3196 - goto out; 3197 - } 3198 - 3199 - ret = amdgpu_ras_add_bad_pages(adev, bps, control->ras_num_recs, true); 3200 3130 } 3201 3131 3202 3132 out: ··· 3204 3134 return ret; 3205 3135 } 3206 3136 3207 - static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, 3137 + static int amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, 3208 3138 uint64_t addr) 3209 3139 { 3210 3140 struct ras_err_handler_data *data = con->eh_data; 3141 + struct amdgpu_device *adev = con->adev; 3211 3142 int i; 3143 + 3144 + if ((addr >= adev->gmc.mc_vram_size && 3145 + adev->gmc.mc_vram_size) || 3146 + (addr >= RAS_UMC_INJECT_ADDR_LIMIT)) 3147 + return -EINVAL; 3212 3148 3213 3149 addr >>= AMDGPU_GPU_PAGE_SHIFT; 3214 3150 for (i = 0; i < data->count; i++) 3215 3151 if (addr == data->bps[i].retired_page) 3216 - return true; 3152 + return 1; 3217 3153 3218 - return false; 3154 + return 0; 3219 3155 } 3220 3156 3221 3157 /* ··· 3229 3153 * 3230 3154 * Note: this check is only for umc block 3231 3155 */ 3232 - static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, 3156 + static int amdgpu_ras_check_bad_page(struct amdgpu_device *adev, 3233 3157 uint64_t addr) 3234 3158 { 3235 3159 struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 3236 - bool ret = false; 3160 + int ret = 0; 3237 3161 3238 3162 if (!con || !con->eh_data) 3239 3163 return ret; ··· 3317 3241 3318 3242 INIT_RADIX_TREE(&ecc_log->de_page_tree, GFP_KERNEL); 3319 3243 ecc_log->de_queried_count = 0; 3320 - ecc_log->prev_de_queried_count = 0; 3244 + ecc_log->consumption_q_count = 0; 3321 3245 } 3322 3246 3323 3247 static void amdgpu_ras_ecc_log_fini(struct ras_ecc_log_info *ecc_log) ··· 3337 3261 3338 3262 mutex_destroy(&ecc_log->lock); 3339 3263 ecc_log->de_queried_count = 0; 3340 - ecc_log->prev_de_queried_count = 0; 3264 + ecc_log->consumption_q_count = 0; 3341 3265 } 3342 3266 3343 3267 static bool amdgpu_ras_schedule_retirement_dwork(struct amdgpu_ras *con, ··· 3363 3287 page_retirement_dwork.work); 3364 3288 struct amdgpu_device *adev = con->adev; 3365 3289 struct ras_err_data err_data; 3366 - unsigned long err_cnt; 3367 3290 3368 3291 /* If gpu reset is ongoing, delay retiring the bad pages */ 3369 3292 if (amdgpu_in_reset(adev) || amdgpu_ras_in_recovery(adev)) { ··· 3374 3299 amdgpu_ras_error_data_init(&err_data); 3375 3300 3376 3301 amdgpu_umc_handle_bad_pages(adev, &err_data); 3377 - err_cnt = err_data.err_addr_cnt; 3378 3302 3379 3303 amdgpu_ras_error_data_fini(&err_data); 3380 - 3381 - if (err_cnt && amdgpu_ras_is_rma(adev)) 3382 - amdgpu_ras_reset_gpu(adev); 3383 3304 3384 3305 amdgpu_ras_schedule_retirement_dwork(con, 3385 3306 AMDGPU_RAS_RETIRE_PAGE_INTERVAL); ··· 3387 3316 int ret = 0; 3388 3317 struct ras_ecc_log_info *ecc_log; 3389 3318 struct ras_query_if info; 3390 - uint32_t timeout = 0; 3319 + u32 timeout = MAX_UMC_POISON_POLLING_TIME_ASYNC; 3391 3320 struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 3392 - uint64_t de_queried_count; 3393 - uint32_t new_detect_count, total_detect_count; 3394 - uint32_t need_query_count = poison_creation_count; 3321 + u64 de_queried_count; 3322 + u64 consumption_q_count; 3395 3323 enum ras_event_type type = RAS_EVENT_TYPE_POISON_CREATION; 3396 3324 3397 3325 memset(&info, 0, sizeof(info)); 3398 3326 info.head.block = AMDGPU_RAS_BLOCK__UMC; 3399 3327 3400 3328 ecc_log = &ras->umc_ecc_log; 3401 - total_detect_count = 0; 3329 + ecc_log->de_queried_count = 0; 3330 + ecc_log->consumption_q_count = 0; 3331 + 3402 3332 do { 3403 3333 ret = amdgpu_ras_query_error_status_with_event(adev, &info, type); 3404 3334 if (ret) 3405 3335 return ret; 3406 3336 3407 3337 de_queried_count = ecc_log->de_queried_count; 3408 - if (de_queried_count > ecc_log->prev_de_queried_count) { 3409 - new_detect_count = de_queried_count - ecc_log->prev_de_queried_count; 3410 - ecc_log->prev_de_queried_count = de_queried_count; 3411 - timeout = 0; 3412 - } else { 3413 - new_detect_count = 0; 3414 - } 3338 + consumption_q_count = ecc_log->consumption_q_count; 3415 3339 3416 - if (new_detect_count) { 3417 - total_detect_count += new_detect_count; 3418 - } else { 3419 - if (!timeout && need_query_count) 3420 - timeout = MAX_UMC_POISON_POLLING_TIME_ASYNC; 3340 + if (de_queried_count && consumption_q_count) 3341 + break; 3421 3342 3422 - if (timeout) { 3423 - if (!--timeout) 3424 - break; 3425 - msleep(1); 3426 - } 3427 - } 3428 - } while (total_detect_count < need_query_count); 3343 + msleep(100); 3344 + } while (--timeout); 3429 3345 3430 - if (total_detect_count) 3346 + if (de_queried_count) 3431 3347 schedule_delayed_work(&ras->page_retirement_dwork, 0); 3348 + 3349 + if (amdgpu_ras_is_rma(adev) && atomic_cmpxchg(&ras->rma_in_recovery, 0, 1) == 0) 3350 + amdgpu_ras_reset_gpu(adev); 3432 3351 3433 3352 return 0; 3434 3353 } ··· 3455 3394 reset_flags |= msg.reset; 3456 3395 } 3457 3396 3397 + /* 3398 + * Try to ensure poison creation handler is completed first 3399 + * to set rma if bad page exceed threshold. 3400 + */ 3401 + flush_delayed_work(&con->page_retirement_dwork); 3402 + 3458 3403 /* for RMA, amdgpu_ras_poison_creation_handler will trigger gpu reset */ 3459 3404 if (reset_flags && !amdgpu_ras_is_rma(adev)) { 3460 3405 if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) ··· 3469 3402 reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET; 3470 3403 else 3471 3404 reset = reset_flags; 3472 - 3473 - flush_delayed_work(&con->page_retirement_dwork); 3474 3405 3475 3406 con->gpu_reset_flags |= reset; 3476 3407 amdgpu_ras_reset_gpu(adev); ··· 3499 3434 if (kthread_should_stop()) 3500 3435 break; 3501 3436 3437 + mutex_lock(&con->poison_lock); 3502 3438 gpu_reset = 0; 3503 3439 3504 3440 do { ··· 3512 3446 atomic_sub(poison_creation_count, &con->poison_creation_count); 3513 3447 atomic_sub(poison_creation_count, &con->page_retirement_req_cnt); 3514 3448 } 3515 - } while (atomic_read(&con->poison_creation_count)); 3449 + } while (atomic_read(&con->poison_creation_count) && 3450 + !atomic_read(&con->poison_consumption_count)); 3516 3451 3517 3452 if (ret != -EIO) { 3518 3453 msg_count = kfifo_len(&con->poison_fifo); ··· 3530 3463 /* gpu mode-1 reset is ongoing or just completed ras mode-1 reset */ 3531 3464 /* Clear poison creation request */ 3532 3465 atomic_set(&con->poison_creation_count, 0); 3466 + atomic_set(&con->poison_consumption_count, 0); 3533 3467 3534 3468 /* Clear poison fifo */ 3535 3469 amdgpu_ras_clear_poison_fifo(adev); ··· 3555 3487 atomic_sub(msg_count, &con->page_retirement_req_cnt); 3556 3488 } 3557 3489 3490 + atomic_set(&con->poison_consumption_count, 0); 3491 + 3558 3492 /* Wake up work to save bad pages to eeprom */ 3559 3493 schedule_delayed_work(&con->page_retirement_dwork, 0); 3560 3494 } 3495 + mutex_unlock(&con->poison_lock); 3561 3496 } 3562 3497 3563 3498 return 0; ··· 3641 3570 } 3642 3571 3643 3572 mutex_init(&con->recovery_lock); 3573 + mutex_init(&con->poison_lock); 3644 3574 INIT_WORK(&con->recovery_work, amdgpu_ras_do_recovery); 3645 3575 atomic_set(&con->in_recovery, 0); 3576 + atomic_set(&con->rma_in_recovery, 0); 3646 3577 con->eeprom_control.bad_channel_bitmap = 0; 3647 3578 3648 3579 max_eeprom_records_count = amdgpu_ras_eeprom_max_record_count(&con->eeprom_control); ··· 3662 3589 init_waitqueue_head(&con->page_retirement_wq); 3663 3590 atomic_set(&con->page_retirement_req_cnt, 0); 3664 3591 atomic_set(&con->poison_creation_count, 0); 3592 + atomic_set(&con->poison_consumption_count, 0); 3665 3593 con->page_retirement_thread = 3666 3594 kthread_run(amdgpu_ras_page_retirement_thread, adev, "umc_page_retirement"); 3667 3595 if (IS_ERR(con->page_retirement_thread)) { ··· 3734 3660 kfree(data->bps); 3735 3661 kfree(data); 3736 3662 mutex_unlock(&con->recovery_lock); 3663 + 3664 + amdgpu_ras_critical_region_init(adev); 3737 3665 3738 3666 return 0; 3739 3667 } ··· 4163 4087 goto release_con; 4164 4088 } 4165 4089 4090 + con->init_task_pid = task_pid_nr(current); 4091 + get_task_comm(con->init_task_comm, current); 4092 + 4093 + mutex_init(&con->critical_region_lock); 4094 + INIT_LIST_HEAD(&con->critical_region_head); 4095 + 4166 4096 dev_info(adev->dev, "RAS INFO: ras initialized successfully, " 4167 4097 "hardware ability[%x] ras_mask[%x]\n", 4168 4098 adev->ras_hw_enabled, adev->ras_enabled); ··· 4447 4365 4448 4366 if (!adev->ras_enabled || !con) 4449 4367 return 0; 4368 + 4369 + amdgpu_ras_critical_region_fini(adev); 4370 + mutex_destroy(&con->critical_region_lock); 4450 4371 4451 4372 list_for_each_entry_safe(ras_node, tmp, &adev->ras_list, node) { 4452 4373 if (ras_node->ras_obj) { ··· 5359 5274 uint64_t start = pfn << AMDGPU_GPU_PAGE_SHIFT; 5360 5275 int ret = 0; 5361 5276 5277 + if (amdgpu_ras_check_critical_address(adev, start)) 5278 + return 0; 5279 + 5362 5280 mutex_lock(&con->page_rsv_lock); 5363 5281 ret = amdgpu_vram_mgr_query_page_status(mgr, start); 5364 5282 if (ret == -ENOENT) ··· 5397 5309 return false; 5398 5310 5399 5311 return con->is_rma; 5312 + } 5313 + 5314 + int amdgpu_ras_add_critical_region(struct amdgpu_device *adev, 5315 + struct amdgpu_bo *bo) 5316 + { 5317 + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 5318 + struct amdgpu_vram_mgr_resource *vres; 5319 + struct ras_critical_region *region; 5320 + struct drm_buddy_block *block; 5321 + int ret = 0; 5322 + 5323 + if (!bo || !bo->tbo.resource) 5324 + return -EINVAL; 5325 + 5326 + vres = to_amdgpu_vram_mgr_resource(bo->tbo.resource); 5327 + 5328 + mutex_lock(&con->critical_region_lock); 5329 + 5330 + /* Check if the bo had been recorded */ 5331 + list_for_each_entry(region, &con->critical_region_head, node) 5332 + if (region->bo == bo) 5333 + goto out; 5334 + 5335 + /* Record new critical amdgpu bo */ 5336 + list_for_each_entry(block, &vres->blocks, link) { 5337 + region = kzalloc(sizeof(*region), GFP_KERNEL); 5338 + if (!region) { 5339 + ret = -ENOMEM; 5340 + goto out; 5341 + } 5342 + region->bo = bo; 5343 + region->start = amdgpu_vram_mgr_block_start(block); 5344 + region->size = amdgpu_vram_mgr_block_size(block); 5345 + list_add_tail(&region->node, &con->critical_region_head); 5346 + } 5347 + 5348 + out: 5349 + mutex_unlock(&con->critical_region_lock); 5350 + 5351 + return ret; 5352 + } 5353 + 5354 + static void amdgpu_ras_critical_region_init(struct amdgpu_device *adev) 5355 + { 5356 + amdgpu_ras_add_critical_region(adev, adev->mman.fw_reserved_memory); 5357 + } 5358 + 5359 + static void amdgpu_ras_critical_region_fini(struct amdgpu_device *adev) 5360 + { 5361 + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 5362 + struct ras_critical_region *region, *tmp; 5363 + 5364 + mutex_lock(&con->critical_region_lock); 5365 + list_for_each_entry_safe(region, tmp, &con->critical_region_head, node) { 5366 + list_del(&region->node); 5367 + kfree(region); 5368 + } 5369 + mutex_unlock(&con->critical_region_lock); 5370 + } 5371 + 5372 + bool amdgpu_ras_check_critical_address(struct amdgpu_device *adev, uint64_t addr) 5373 + { 5374 + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 5375 + struct ras_critical_region *region; 5376 + bool ret = false; 5377 + 5378 + mutex_lock(&con->critical_region_lock); 5379 + list_for_each_entry(region, &con->critical_region_head, node) { 5380 + if ((region->start <= addr) && 5381 + (addr < (region->start + region->size))) { 5382 + ret = true; 5383 + break; 5384 + } 5385 + } 5386 + mutex_unlock(&con->critical_region_lock); 5387 + 5388 + return ret; 5400 5389 }
+26 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
··· 492 492 struct ras_ecc_log_info { 493 493 struct mutex lock; 494 494 struct radix_tree_root de_page_tree; 495 - uint64_t de_queried_count; 496 - uint64_t prev_de_queried_count; 495 + uint64_t de_queried_count; 496 + uint64_t consumption_q_count; 497 + }; 498 + 499 + struct ras_critical_region { 500 + struct list_head node; 501 + struct amdgpu_bo *bo; 502 + uint64_t start; 503 + uint64_t size; 497 504 }; 498 505 499 506 struct amdgpu_ras { ··· 522 515 /* gpu recovery */ 523 516 struct work_struct recovery_work; 524 517 atomic_t in_recovery; 518 + atomic_t rma_in_recovery; 525 519 struct amdgpu_device *adev; 526 520 /* error handler data */ 527 521 struct ras_err_handler_data *eh_data; ··· 565 557 struct mutex page_retirement_lock; 566 558 atomic_t page_retirement_req_cnt; 567 559 atomic_t poison_creation_count; 560 + atomic_t poison_consumption_count; 568 561 struct mutex page_rsv_lock; 569 562 DECLARE_KFIFO(poison_fifo, struct ras_poison_msg, 128); 570 563 struct ras_ecc_log_info umc_ecc_log; ··· 579 570 struct ras_event_manager *event_mgr; 580 571 581 572 uint64_t reserved_pages_in_bytes; 573 + 574 + pid_t init_task_pid; 575 + char init_task_comm[TASK_COMM_LEN]; 576 + 577 + int bad_page_num; 578 + 579 + struct list_head critical_region_head; 580 + struct mutex critical_region_lock; 581 + 582 + /* Protect poison injection */ 583 + struct mutex poison_lock; 582 584 }; 583 585 584 586 struct ras_fs_data { ··· 628 608 struct eeprom_table_record *bps; 629 609 /* the count of entries */ 630 610 int count; 611 + int count_saved; 631 612 /* the space can place new entries */ 632 613 int space_left; 633 614 }; ··· 993 972 const void *caller); 994 973 995 974 int amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn); 975 + 976 + int amdgpu_ras_add_critical_region(struct amdgpu_device *adev, struct amdgpu_bo *bo); 977 + bool amdgpu_ras_check_critical_address(struct amdgpu_device *adev, uint64_t addr); 996 978 997 979 int amdgpu_ras_put_poison_req(struct amdgpu_device *adev, 998 980 enum amdgpu_ras_block block, uint16_t pasid,
+9 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
··· 743 743 else 744 744 control->ras_num_mca_recs += num; 745 745 746 - control->ras_num_bad_pages = control->ras_num_pa_recs + 747 - control->ras_num_mca_recs * adev->umc.retire_unit; 746 + control->ras_num_bad_pages = con->bad_page_num; 748 747 Out: 749 748 kfree(buf); 750 749 return res; ··· 765 766 dev_warn(adev->dev, 766 767 "Saved bad pages %d reaches threshold value %d\n", 767 768 control->ras_num_bad_pages, ras->bad_page_cnt_threshold); 769 + 770 + if (adev->cper.enabled && amdgpu_cper_generate_bp_threshold_record(adev)) 771 + dev_warn(adev->dev, "fail to generate bad page threshold cper records\n"); 772 + 768 773 if ((amdgpu_bad_page_threshold != -1) && 769 774 (amdgpu_bad_page_threshold != -2)) { 770 775 control->tbl_hdr.header = RAS_TABLE_HDR_BAD; ··· 777 774 control->tbl_rai.health_percent = 0; 778 775 } 779 776 ras->is_rma = true; 780 - /* ignore the -ENOTSUPP return value */ 781 - amdgpu_dpm_send_rma_reason(adev); 782 777 } 778 + 779 + /* ignore the -ENOTSUPP return value */ 780 + amdgpu_dpm_send_rma_reason(adev); 783 781 } 784 782 785 783 if (control->tbl_hdr.version >= RAS_TABLE_VER_V2_1) ··· 1461 1457 if (!__get_eeprom_i2c_addr(adev, control)) 1462 1458 return -EINVAL; 1463 1459 1464 - control->ras_num_bad_pages = control->ras_num_pa_recs + 1465 - control->ras_num_mca_recs * adev->umc.retire_unit; 1460 + control->ras_num_bad_pages = ras->bad_page_num; 1466 1461 1467 1462 if (hdr->header == RAS_TABLE_HDR_VAL) { 1468 1463 dev_dbg(adev->dev,
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
··· 160 160 161 161 bool amdgpu_reset_in_recovery(struct amdgpu_device *adev); 162 162 163 + static inline void amdgpu_reset_set_dpc_status(struct amdgpu_device *adev, 164 + bool status) 165 + { 166 + adev->pcie_reset_ctx.occurs_dpc = status; 167 + adev->no_hw_access = status; 168 + } 169 + 170 + static inline bool amdgpu_reset_in_dpc(struct amdgpu_device *adev) 171 + { 172 + return adev->pcie_reset_ctx.occurs_dpc; 173 + } 174 + 163 175 #endif
+4 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
··· 67 67 int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, 68 68 struct amdgpu_bo_va **bo_va) 69 69 { 70 - u64 seq64_addr, va_flags; 71 70 struct amdgpu_bo *bo; 72 71 struct drm_exec exec; 72 + u64 seq64_addr; 73 73 int r; 74 74 75 75 bo = adev->seq64.sbo; ··· 94 94 95 95 seq64_addr = amdgpu_seq64_get_va_base(adev) & AMDGPU_GMC_HOLE_MASK; 96 96 97 - va_flags = amdgpu_gem_va_map_flags(adev, AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC); 98 - r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE, 99 - va_flags); 97 + r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, 98 + AMDGPU_VA_RESERVED_SEQ64_SIZE, 99 + AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC); 100 100 if (r) { 101 101 DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r); 102 102 amdgpu_vm_bo_del(adev, *bo_va);
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
··· 252 252 block, pasid, pasid_fn, data, reset); 253 253 if (!ret) { 254 254 atomic_inc(&con->page_retirement_req_cnt); 255 + atomic_inc(&con->poison_consumption_count); 255 256 wake_up(&con->page_retirement_wq); 256 257 } 257 258 }
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 471 471 if (index == (uint64_t)-EINVAL) { 472 472 drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n"); 473 473 kfree(queue); 474 + r = -EINVAL; 474 475 goto unlock; 475 476 } 476 477 ··· 567 566 args->in.queue_va || 568 567 args->in.queue_size || 569 568 args->in.rptr_va || 570 - args->in.wptr_va || 571 569 args->in.wptr_va || 572 570 args->in.mqd || 573 571 args->in.mqd_size)
+145 -35
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
··· 92 92 MODULE_FIRMWARE(FIRMWARE_VCN5_0_1); 93 93 94 94 static void amdgpu_vcn_idle_work_handler(struct work_struct *work); 95 + static void amdgpu_vcn_reg_dump_fini(struct amdgpu_device *adev); 95 96 96 97 int amdgpu_vcn_early_init(struct amdgpu_device *adev, int i) 97 98 { ··· 185 184 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf; 186 185 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf; 187 186 dev_info(adev->dev, 188 - "Found VCN firmware Version ENC: %u.%u DEC: %u VEP: %u Revision: %u\n", 189 - enc_major, enc_minor, dec_ver, vep, fw_rev); 187 + "[VCN instance %d] Found VCN firmware Version ENC: %u.%u DEC: %u VEP: %u Revision: %u\n", 188 + i, enc_major, enc_minor, dec_ver, vep, fw_rev); 190 189 } else { 191 190 unsigned int version_major, version_minor, family_id; 192 191 193 192 family_id = le32_to_cpu(hdr->ucode_version) & 0xff; 194 193 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; 195 194 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 196 - dev_info(adev->dev, "Found VCN firmware Version: %u.%u Family ID: %u\n", 197 - version_major, version_minor, family_id); 195 + dev_info(adev->dev, "[VCN instance %d] Found VCN firmware Version: %u.%u Family ID: %u\n", 196 + i, version_major, version_minor, family_id); 198 197 } 199 198 200 199 bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE; ··· 286 285 amdgpu_ucode_release(&adev->vcn.inst[0].fw); 287 286 adev->vcn.inst[i].fw = NULL; 288 287 } 288 + 289 + if (adev->vcn.reg_list) 290 + amdgpu_vcn_reg_dump_fini(adev); 291 + 289 292 mutex_destroy(&adev->vcn.inst[i].vcn_pg_lock); 290 293 mutex_destroy(&adev->vcn.inst[i].vcn1_jpeg1_workaround); 291 294 ··· 357 352 if (adev->vcn.harvest_config & (1 << i)) 358 353 return 0; 359 354 360 - cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work); 361 - 362 355 /* err_event_athub and dpc recovery will corrupt VCPU buffer, so we need to 363 356 * restore fw data and clear buffer in amdgpu_vcn_resume() */ 364 357 if (in_ras_intr || adev->pcie_reset_ctx.in_link_reset) ··· 408 405 return 0; 409 406 } 410 407 408 + void amdgpu_vcn_get_profile(struct amdgpu_device *adev) 409 + { 410 + int r; 411 + 412 + mutex_lock(&adev->vcn.workload_profile_mutex); 413 + 414 + if (adev->vcn.workload_profile_active) { 415 + mutex_unlock(&adev->vcn.workload_profile_mutex); 416 + return; 417 + } 418 + r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 419 + true); 420 + if (r) 421 + dev_warn(adev->dev, 422 + "(%d) failed to enable video power profile mode\n", r); 423 + else 424 + adev->vcn.workload_profile_active = true; 425 + mutex_unlock(&adev->vcn.workload_profile_mutex); 426 + } 427 + 428 + void amdgpu_vcn_put_profile(struct amdgpu_device *adev) 429 + { 430 + bool pg = true; 431 + int r, i; 432 + 433 + mutex_lock(&adev->vcn.workload_profile_mutex); 434 + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 435 + if (adev->vcn.inst[i].cur_state != AMD_PG_STATE_GATE) { 436 + pg = false; 437 + break; 438 + } 439 + } 440 + 441 + if (pg) { 442 + r = amdgpu_dpm_switch_power_profile( 443 + adev, PP_SMC_POWER_PROFILE_VIDEO, false); 444 + if (r) 445 + dev_warn( 446 + adev->dev, 447 + "(%d) failed to disable video power profile mode\n", 448 + r); 449 + else 450 + adev->vcn.workload_profile_active = false; 451 + } 452 + 453 + mutex_unlock(&adev->vcn.workload_profile_mutex); 454 + } 455 + 411 456 static void amdgpu_vcn_idle_work_handler(struct work_struct *work) 412 457 { 413 458 struct amdgpu_vcn_inst *vcn_inst = ··· 463 412 struct amdgpu_device *adev = vcn_inst->adev; 464 413 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; 465 414 unsigned int i = vcn_inst->inst, j; 466 - int r = 0; 467 415 468 416 if (adev->vcn.harvest_config & (1 << i)) 469 417 return; ··· 488 438 fences += fence[i]; 489 439 490 440 if (!fences && !atomic_read(&vcn_inst->total_submission_cnt)) { 441 + mutex_lock(&vcn_inst->vcn_pg_lock); 491 442 vcn_inst->set_pg_state(vcn_inst, AMD_PG_STATE_GATE); 492 - mutex_lock(&adev->vcn.workload_profile_mutex); 493 - if (adev->vcn.workload_profile_active) { 494 - r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 495 - false); 496 - if (r) 497 - dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r); 498 - adev->vcn.workload_profile_active = false; 499 - } 500 - mutex_unlock(&adev->vcn.workload_profile_mutex); 443 + mutex_unlock(&vcn_inst->vcn_pg_lock); 444 + amdgpu_vcn_put_profile(adev); 445 + 501 446 } else { 502 447 schedule_delayed_work(&vcn_inst->idle_work, VCN_IDLE_TIMEOUT); 503 448 } ··· 502 457 { 503 458 struct amdgpu_device *adev = ring->adev; 504 459 struct amdgpu_vcn_inst *vcn_inst = &adev->vcn.inst[ring->me]; 505 - int r = 0; 506 460 507 461 atomic_inc(&vcn_inst->total_submission_cnt); 508 462 509 463 cancel_delayed_work_sync(&vcn_inst->idle_work); 510 464 511 - /* We can safely return early here because we've cancelled the 512 - * the delayed work so there is no one else to set it to false 513 - * and we don't care if someone else sets it to true. 514 - */ 515 - if (adev->vcn.workload_profile_active) 516 - goto pg_lock; 517 - 518 - mutex_lock(&adev->vcn.workload_profile_mutex); 519 - if (!adev->vcn.workload_profile_active) { 520 - r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 521 - true); 522 - if (r) 523 - dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r); 524 - adev->vcn.workload_profile_active = true; 525 - } 526 - mutex_unlock(&adev->vcn.workload_profile_mutex); 527 - 528 - pg_lock: 529 465 mutex_lock(&vcn_inst->vcn_pg_lock); 530 466 vcn_inst->set_pg_state(vcn_inst, AMD_PG_STATE_UNGATE); 531 467 ··· 534 508 vcn_inst->pause_dpg_mode(vcn_inst, &new_state); 535 509 } 536 510 mutex_unlock(&vcn_inst->vcn_pg_lock); 511 + amdgpu_vcn_get_profile(adev); 537 512 } 538 513 539 514 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) ··· 1553 1526 return -EINVAL; 1554 1527 1555 1528 return amdgpu_vcn_reset_engine(adev, ring->me); 1529 + } 1530 + 1531 + int amdgpu_vcn_reg_dump_init(struct amdgpu_device *adev, 1532 + const struct amdgpu_hwip_reg_entry *reg, u32 count) 1533 + { 1534 + adev->vcn.ip_dump = kcalloc(adev->vcn.num_vcn_inst * count, 1535 + sizeof(uint32_t), GFP_KERNEL); 1536 + if (!adev->vcn.ip_dump) 1537 + return -ENOMEM; 1538 + adev->vcn.reg_list = reg; 1539 + adev->vcn.reg_count = count; 1540 + 1541 + return 0; 1542 + } 1543 + 1544 + static void amdgpu_vcn_reg_dump_fini(struct amdgpu_device *adev) 1545 + { 1546 + kfree(adev->vcn.ip_dump); 1547 + adev->vcn.ip_dump = NULL; 1548 + adev->vcn.reg_list = NULL; 1549 + adev->vcn.reg_count = 0; 1550 + } 1551 + 1552 + void amdgpu_vcn_dump_ip_state(struct amdgpu_ip_block *ip_block) 1553 + { 1554 + struct amdgpu_device *adev = ip_block->adev; 1555 + int i, j; 1556 + bool is_powered; 1557 + u32 inst_off; 1558 + 1559 + if (!adev->vcn.ip_dump) 1560 + return; 1561 + 1562 + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1563 + if (adev->vcn.harvest_config & (1 << i)) 1564 + continue; 1565 + 1566 + inst_off = i * adev->vcn.reg_count; 1567 + /* mmUVD_POWER_STATUS is always readable and is the first in reg_list */ 1568 + adev->vcn.ip_dump[inst_off] = 1569 + RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->vcn.reg_list[0], i)); 1570 + is_powered = (adev->vcn.ip_dump[inst_off] & 1571 + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF) != 1572 + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; 1573 + 1574 + if (is_powered) 1575 + for (j = 1; j < adev->vcn.reg_count; j++) 1576 + adev->vcn.ip_dump[inst_off + j] = 1577 + RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->vcn.reg_list[j], i)); 1578 + } 1579 + } 1580 + 1581 + void amdgpu_vcn_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1582 + { 1583 + struct amdgpu_device *adev = ip_block->adev; 1584 + int i, j; 1585 + bool is_powered; 1586 + u32 inst_off; 1587 + 1588 + if (!adev->vcn.ip_dump) 1589 + return; 1590 + 1591 + drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1592 + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1593 + if (adev->vcn.harvest_config & (1 << i)) { 1594 + drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1595 + continue; 1596 + } 1597 + 1598 + inst_off = i * adev->vcn.reg_count; 1599 + is_powered = (adev->vcn.ip_dump[inst_off] & 1600 + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF) != 1601 + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; 1602 + 1603 + if (is_powered) { 1604 + drm_printf(p, "\nActive Instance:VCN%d\n", i); 1605 + for (j = 0; j < adev->vcn.reg_count; j++) 1606 + drm_printf(p, "%-50s \t 0x%08x\n", adev->vcn.reg_list[j].reg_name, 1607 + adev->vcn.ip_dump[inst_off + j]); 1608 + } else { 1609 + drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1610 + } 1611 + } 1556 1612 }
+11
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
··· 237 237 238 238 #define AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING 2 239 239 240 + struct amdgpu_hwip_reg_entry; 241 + 240 242 enum amdgpu_vcn_caps { 241 243 AMDGPU_VCN_RRMT_ENABLED, 242 244 }; ··· 364 362 365 363 bool workload_profile_active; 366 364 struct mutex workload_profile_mutex; 365 + u32 reg_count; 366 + const struct amdgpu_hwip_reg_entry *reg_list; 367 367 }; 368 368 369 369 struct amdgpu_fw_shared_rb_ptrs_struct { ··· 561 557 int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring, 562 558 unsigned int vmid, 563 559 struct amdgpu_fence *guilty_fence); 560 + int amdgpu_vcn_reg_dump_init(struct amdgpu_device *adev, 561 + const struct amdgpu_hwip_reg_entry *reg, u32 count); 562 + void amdgpu_vcn_dump_ip_state(struct amdgpu_ip_block *ip_block); 563 + void amdgpu_vcn_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p); 564 + void amdgpu_vcn_get_profile(struct amdgpu_device *adev); 565 + void amdgpu_vcn_put_profile(struct amdgpu_device *adev); 566 + 564 567 #endif
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
··· 267 267 struct amdgpu_irq_src rcv_irq; 268 268 269 269 struct work_struct flr_work; 270 - struct work_struct bad_pages_work; 270 + struct work_struct req_bad_pages_work; 271 + struct work_struct handle_bad_pages_work; 271 272 272 273 struct amdgpu_mm_table mm_table; 273 274 const struct amdgpu_virt_ops *ops;
+9 -8
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 1339 1339 /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here 1340 1340 * but in case of something, we filter the flags in first place 1341 1341 */ 1342 - if (!(mapping->flags & AMDGPU_PTE_READABLE)) 1342 + if (!(mapping->flags & AMDGPU_VM_PAGE_READABLE)) 1343 1343 update_flags &= ~AMDGPU_PTE_READABLE; 1344 - if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) 1344 + if (!(mapping->flags & AMDGPU_VM_PAGE_WRITEABLE)) 1345 1345 update_flags &= ~AMDGPU_PTE_WRITEABLE; 1346 1346 1347 1347 /* Apply ASIC specific mapping flags */ 1348 - amdgpu_gmc_get_vm_pte(adev, mapping, &update_flags); 1348 + amdgpu_gmc_get_vm_pte(adev, vm, bo, mapping->flags, 1349 + &update_flags); 1349 1350 1350 1351 trace_amdgpu_vm_bo_update(mapping); 1351 1352 ··· 1487 1486 struct amdgpu_bo_va_mapping *mapping, 1488 1487 struct dma_fence *fence) 1489 1488 { 1490 - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev)) 1489 + if (mapping->flags & AMDGPU_VM_PAGE_PRT) 1491 1490 amdgpu_vm_add_prt_cb(adev, fence); 1492 1491 kfree(mapping); 1493 1492 } ··· 1766 1765 list_add(&mapping->list, &bo_va->invalids); 1767 1766 amdgpu_vm_it_insert(mapping, &vm->va); 1768 1767 1769 - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev)) 1768 + if (mapping->flags & AMDGPU_VM_PAGE_PRT) 1770 1769 amdgpu_vm_prt_get(adev); 1771 1770 1772 1771 if (amdgpu_vm_is_bo_always_valid(vm, bo) && !bo_va->base.moved) ··· 1826 1825 int amdgpu_vm_bo_map(struct amdgpu_device *adev, 1827 1826 struct amdgpu_bo_va *bo_va, 1828 1827 uint64_t saddr, uint64_t offset, 1829 - uint64_t size, uint64_t flags) 1828 + uint64_t size, uint32_t flags) 1830 1829 { 1831 1830 struct amdgpu_bo_va_mapping *mapping, *tmp; 1832 1831 struct amdgpu_bo *bo = bo_va->base.bo; ··· 1885 1884 int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, 1886 1885 struct amdgpu_bo_va *bo_va, 1887 1886 uint64_t saddr, uint64_t offset, 1888 - uint64_t size, uint64_t flags) 1887 + uint64_t size, uint32_t flags) 1889 1888 { 1890 1889 struct amdgpu_bo_va_mapping *mapping; 1891 1890 struct amdgpu_bo *bo = bo_va->base.bo; ··· 2742 2741 dma_fence_put(vm->last_tlb_flush); 2743 2742 2744 2743 list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { 2745 - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev) && prt_fini_needed) { 2744 + if (mapping->flags & AMDGPU_VM_PAGE_PRT && prt_fini_needed) { 2746 2745 amdgpu_vm_prt_fini(adev, vm); 2747 2746 prt_fini_needed = false; 2748 2747 }
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 538 538 int amdgpu_vm_bo_map(struct amdgpu_device *adev, 539 539 struct amdgpu_bo_va *bo_va, 540 540 uint64_t addr, uint64_t offset, 541 - uint64_t size, uint64_t flags); 541 + uint64_t size, uint32_t flags); 542 542 int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, 543 543 struct amdgpu_bo_va *bo_va, 544 544 uint64_t addr, uint64_t offset, 545 - uint64_t size, uint64_t flags); 545 + uint64_t size, uint32_t flags); 546 546 int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, 547 547 struct amdgpu_bo_va *bo_va, 548 548 uint64_t addr);
+26 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
··· 379 379 if (ret) 380 380 goto out; 381 381 382 - /* TODO: Add queue reset mask when FW fully supports it */ 383 382 adev->vpe.supported_reset = 384 383 amdgpu_get_soft_full_reset_mask(&adev->vpe.ring); 384 + if (!amdgpu_sriov_vf(adev)) 385 + adev->vpe.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 385 386 ret = amdgpu_vpe_sysfs_reset_mask_init(adev); 386 387 if (ret) 387 388 goto out; ··· 436 435 struct amdgpu_device *adev = ip_block->adev; 437 436 struct amdgpu_vpe *vpe = &adev->vpe; 438 437 438 + cancel_delayed_work_sync(&adev->vpe.idle_work); 439 + 439 440 vpe_ring_stop(vpe); 440 441 441 442 /* Power off VPE */ ··· 448 445 449 446 static int vpe_suspend(struct amdgpu_ip_block *ip_block) 450 447 { 451 - struct amdgpu_device *adev = ip_block->adev; 452 - 453 - cancel_delayed_work_sync(&adev->vpe.idle_work); 454 - 455 448 return vpe_hw_fini(ip_block); 456 449 } 457 450 ··· 873 874 schedule_delayed_work(&adev->vpe.idle_work, VPE_IDLE_TIMEOUT); 874 875 } 875 876 877 + static int vpe_ring_reset(struct amdgpu_ring *ring, 878 + unsigned int vmid, 879 + struct amdgpu_fence *timedout_fence) 880 + { 881 + struct amdgpu_device *adev = ring->adev; 882 + int r; 883 + 884 + amdgpu_ring_reset_helper_begin(ring, timedout_fence); 885 + 886 + r = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, 887 + AMD_PG_STATE_GATE); 888 + if (r) 889 + return r; 890 + r = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, 891 + AMD_PG_STATE_UNGATE); 892 + if (r) 893 + return r; 894 + 895 + return amdgpu_ring_reset_helper_end(ring, timedout_fence); 896 + } 897 + 876 898 static ssize_t amdgpu_get_vpe_reset_mask(struct device *dev, 877 899 struct device_attribute *attr, 878 900 char *buf) ··· 962 942 .preempt_ib = vpe_ring_preempt_ib, 963 943 .begin_use = vpe_ring_begin_use, 964 944 .end_use = vpe_ring_end_use, 945 + .reset = vpe_ring_reset, 965 946 }; 966 947 967 948 static void vpe_set_ring_funcs(struct amdgpu_device *adev)
+38
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
··· 396 396 return ret; 397 397 } 398 398 399 + int amdgpu_vram_mgr_query_address_block_info(struct amdgpu_vram_mgr *mgr, 400 + uint64_t address, struct amdgpu_vram_block_info *info) 401 + { 402 + struct amdgpu_vram_mgr_resource *vres; 403 + struct drm_buddy_block *block; 404 + u64 start, size; 405 + int ret = -ENOENT; 406 + 407 + mutex_lock(&mgr->lock); 408 + list_for_each_entry(vres, &mgr->allocated_vres_list, vres_node) { 409 + list_for_each_entry(block, &vres->blocks, link) { 410 + start = amdgpu_vram_mgr_block_start(block); 411 + size = amdgpu_vram_mgr_block_size(block); 412 + if ((start <= address) && (address < (start + size))) { 413 + info->start = start; 414 + info->size = size; 415 + memcpy(&info->task, &vres->task, sizeof(vres->task)); 416 + ret = 0; 417 + goto out; 418 + } 419 + } 420 + } 421 + 422 + out: 423 + mutex_unlock(&mgr->lock); 424 + 425 + return ret; 426 + } 427 + 399 428 static void amdgpu_dummy_vram_mgr_debug(struct ttm_resource_manager *man, 400 429 struct drm_printer *printer) 401 430 { ··· 597 568 remaining_size -= size; 598 569 } 599 570 571 + vres->task.pid = task_pid_nr(current); 572 + get_task_comm(vres->task.comm, current); 573 + list_add_tail(&vres->vres_node, &mgr->allocated_vres_list); 574 + 600 575 if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS && adjust_dcc_size) { 601 576 struct drm_buddy_block *dcc_block; 602 577 unsigned long dcc_start; ··· 678 645 uint64_t vis_usage = 0; 679 646 680 647 mutex_lock(&mgr->lock); 648 + 649 + list_del(&vres->vres_node); 650 + memset(&vres->task, 0, sizeof(vres->task)); 651 + 681 652 list_for_each_entry(block, &vres->blocks, link) 682 653 vis_usage += amdgpu_vram_mgr_vis_size(adev, block); 683 654 ··· 970 933 mutex_init(&mgr->lock); 971 934 INIT_LIST_HEAD(&mgr->reservations_pending); 972 935 INIT_LIST_HEAD(&mgr->reserved_pages); 936 + INIT_LIST_HEAD(&mgr->allocated_vres_list); 973 937 mgr->default_page_size = PAGE_SIZE; 974 938 975 939 if (!adev->gmc.is_app_apu) {
+17
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
··· 35 35 struct list_head reserved_pages; 36 36 atomic64_t vis_usage; 37 37 u64 default_page_size; 38 + struct list_head allocated_vres_list; 39 + }; 40 + 41 + struct amdgpu_vres_task { 42 + pid_t pid; 43 + char comm[TASK_COMM_LEN]; 44 + }; 45 + 46 + struct amdgpu_vram_block_info { 47 + u64 start; 48 + u64 size; 49 + struct amdgpu_vres_task task; 38 50 }; 39 51 40 52 struct amdgpu_vram_mgr_resource { 41 53 struct ttm_resource base; 42 54 struct list_head blocks; 43 55 unsigned long flags; 56 + struct list_head vres_node; 57 + struct amdgpu_vres_task task; 44 58 }; 45 59 46 60 static inline u64 amdgpu_vram_mgr_block_start(struct drm_buddy_block *block) ··· 85 71 WARN_ON(ares->flags & DRM_BUDDY_CLEARED); 86 72 ares->flags |= DRM_BUDDY_CLEARED; 87 73 } 74 + 75 + int amdgpu_vram_mgr_query_address_block_info(struct amdgpu_vram_mgr *mgr, 76 + uint64_t address, struct amdgpu_vram_block_info *info); 88 77 89 78 #endif
+21
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
··· 120 120 xcp->valid = true; 121 121 } 122 122 123 + static void __amdgpu_xcp_set_unique_id(struct amdgpu_xcp_mgr *xcp_mgr, 124 + int xcp_id) 125 + { 126 + struct amdgpu_xcp *xcp = &xcp_mgr->xcp[xcp_id]; 127 + struct amdgpu_device *adev = xcp_mgr->adev; 128 + uint32_t inst_mask; 129 + uint64_t uid; 130 + int i; 131 + 132 + if (!amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask) && 133 + inst_mask) { 134 + i = GET_INST(GC, (ffs(inst_mask) - 1)); 135 + uid = amdgpu_device_get_uid(xcp_mgr->adev->uid_info, 136 + AMDGPU_UID_TYPE_XCD, i); 137 + if (uid) 138 + xcp->unique_id = uid; 139 + } 140 + } 141 + 123 142 int amdgpu_xcp_init(struct amdgpu_xcp_mgr *xcp_mgr, int num_xcps, int mode) 124 143 { 125 144 struct amdgpu_device *adev = xcp_mgr->adev; ··· 177 158 else 178 159 xcp_mgr->xcp[i].mem_id = mem_id; 179 160 } 161 + __amdgpu_xcp_set_unique_id(xcp_mgr, i); 180 162 } 181 163 182 164 xcp_mgr->num_xcps = num_xcps; ··· 426 406 p_ddev->primary->dev = adev->xcp_mgr->xcp[i].pdev; 427 407 p_ddev->driver = adev->xcp_mgr->xcp[i].driver; 428 408 p_ddev->vma_offset_manager = adev->xcp_mgr->xcp[i].vma_offset_manager; 409 + amdgpu_xcp_drm_dev_free(p_ddev); 429 410 } 430 411 } 431 412
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
··· 112 112 struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX]; 113 113 struct amdgpu_xcp_mgr *xcp_mgr; 114 114 struct kobject kobj; 115 + uint64_t unique_id; 115 116 }; 116 117 117 118 struct amdgpu_xcp_mgr {
-5
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
··· 1462 1462 1463 1463 static void dce_v10_0_audio_fini(struct amdgpu_device *adev) 1464 1464 { 1465 - int i; 1466 - 1467 1465 if (!amdgpu_audio) 1468 1466 return; 1469 1467 1470 1468 if (!adev->mode_info.audio.enabled) 1471 1469 return; 1472 - 1473 - for (i = 0; i < adev->mode_info.audio.num_pins; i++) 1474 - dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); 1475 1470 1476 1471 adev->mode_info.audio.enabled = false; 1477 1472 }
-5
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
··· 1511 1511 1512 1512 static void dce_v11_0_audio_fini(struct amdgpu_device *adev) 1513 1513 { 1514 - int i; 1515 - 1516 1514 if (!amdgpu_audio) 1517 1515 return; 1518 1516 1519 1517 if (!adev->mode_info.audio.enabled) 1520 1518 return; 1521 - 1522 - for (i = 0; i < adev->mode_info.audio.num_pins; i++) 1523 - dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); 1524 1519 1525 1520 adev->mode_info.audio.enabled = false; 1526 1521 }
-5
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
··· 1451 1451 1452 1452 static void dce_v6_0_audio_fini(struct amdgpu_device *adev) 1453 1453 { 1454 - int i; 1455 - 1456 1454 if (!amdgpu_audio) 1457 1455 return; 1458 1456 1459 1457 if (!adev->mode_info.audio.enabled) 1460 1458 return; 1461 - 1462 - for (i = 0; i < adev->mode_info.audio.num_pins; i++) 1463 - dce_v6_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); 1464 1459 1465 1460 adev->mode_info.audio.enabled = false; 1466 1461 }
-5
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
··· 1443 1443 1444 1444 static void dce_v8_0_audio_fini(struct amdgpu_device *adev) 1445 1445 { 1446 - int i; 1447 - 1448 1446 if (!amdgpu_audio) 1449 1447 return; 1450 1448 1451 1449 if (!adev->mode_info.audio.enabled) 1452 1450 return; 1453 - 1454 - for (i = 0; i < adev->mode_info.audio.num_pins; i++) 1455 - dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); 1456 1451 1457 1452 adev->mode_info.audio.enabled = false; 1458 1453 }
+9 -11
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
··· 7668 7668 /* Disable MEC parsing/prefetching */ 7669 7669 gfx_v10_0_cp_compute_enable(adev, false); 7670 7670 7671 - if (grbm_soft_reset) { 7672 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7673 - tmp |= grbm_soft_reset; 7674 - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 7675 - WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 7676 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7671 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7672 + tmp |= grbm_soft_reset; 7673 + dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 7674 + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 7675 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7677 7676 7678 - udelay(50); 7677 + udelay(50); 7679 7678 7680 - tmp &= ~grbm_soft_reset; 7681 - WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 7682 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7683 - } 7679 + tmp &= ~grbm_soft_reset; 7680 + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 7681 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 7684 7682 7685 7683 /* Wait a little for things to settle down */ 7686 7684 udelay(50);
+9 -5
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
··· 1612 1612 case IP_VERSION(11, 0, 2): 1613 1613 case IP_VERSION(11, 0, 3): 1614 1614 if (!adev->gfx.disable_uq && 1615 - adev->gfx.me_fw_version >= 2390 && 1616 - adev->gfx.pfp_fw_version >= 2530 && 1617 - adev->gfx.mec_fw_version >= 2600 && 1615 + adev->gfx.me_fw_version >= 2420 && 1616 + adev->gfx.pfp_fw_version >= 2580 && 1617 + adev->gfx.mec_fw_version >= 2650 && 1618 1618 adev->mes.fw_version[0] >= 120) { 1619 1619 adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs; 1620 1620 adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs; ··· 4129 4129 #endif 4130 4130 if (prop->tmz_queue) 4131 4131 tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, TMZ_MATCH, 1); 4132 + if (!prop->kernel_queue) 4133 + tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_NON_PRIV, 1); 4132 4134 mqd->cp_gfx_hqd_cntl = tmp; 4133 4135 4134 4136 /* set up cp_doorbell_control */ ··· 4283 4281 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); 4284 4282 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 4285 4283 prop->allow_tunneling); 4286 - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); 4287 - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); 4284 + if (prop->kernel_queue) { 4285 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); 4286 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); 4287 + } 4288 4288 if (prop->tmz_queue) 4289 4289 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TMZ, 1); 4290 4290 mqd->cp_hqd_pq_control = tmp;
+6 -2
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
··· 3026 3026 #endif 3027 3027 if (prop->tmz_queue) 3028 3028 tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, TMZ_MATCH, 1); 3029 + if (!prop->kernel_queue) 3030 + tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_NON_PRIV, 1); 3029 3031 mqd->cp_gfx_hqd_cntl = tmp; 3030 3032 3031 3033 /* set up cp_doorbell_control */ ··· 3177 3175 (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); 3178 3176 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); 3179 3177 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); 3180 - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); 3181 - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); 3178 + if (prop->kernel_queue) { 3179 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); 3180 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); 3181 + } 3182 3182 if (prop->tmz_queue) 3183 3183 tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TMZ, 1); 3184 3184 mqd->cp_hqd_pq_control = tmp;
+12 -11
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 2650 2650 !READ_ONCE(adev->barrier_has_auto_waitcnt)); 2651 2651 WREG32_SOC15(GC, 0, mmSQ_CONFIG, tmp); 2652 2652 break; 2653 + case IP_VERSION(9, 4, 2): 2654 + gfx_v9_4_2_init_sq(adev); 2655 + break; 2653 2656 default: 2654 2657 break; 2655 2658 } ··· 4175 4172 /* Disable MEC parsing/prefetching */ 4176 4173 gfx_v9_0_cp_compute_enable(adev, false); 4177 4174 4178 - if (grbm_soft_reset) { 4179 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4180 - tmp |= grbm_soft_reset; 4181 - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 4182 - WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 4183 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4175 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4176 + tmp |= grbm_soft_reset; 4177 + dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 4178 + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 4179 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4184 4180 4185 - udelay(50); 4181 + udelay(50); 4186 4182 4187 - tmp &= ~grbm_soft_reset; 4188 - WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 4189 - tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4190 - } 4183 + tmp &= ~grbm_soft_reset; 4184 + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); 4185 + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); 4191 4186 4192 4187 /* Wait a little for things to settle down */ 4193 4188 udelay(50);
+12
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
··· 748 748 } 749 749 } 750 750 751 + void gfx_v9_4_2_init_sq(struct amdgpu_device *adev) 752 + { 753 + uint32_t data; 754 + 755 + if (adev->gfx.mec_fw_version >= 98) { 756 + adev->gmc.xnack_flags |= AMDGPU_GMC_XNACK_FLAG_CHAIN; 757 + data = RREG32_SOC15(GC, 0, regSQ_CONFIG1); 758 + data = REG_SET_FIELD(data, SQ_CONFIG1, DISABLE_XNACK_CHECK_IN_RETRY_DISABLE, 1); 759 + WREG32_SOC15(GC, 0, regSQ_CONFIG1, data); 760 + } 761 + } 762 + 751 763 void gfx_v9_4_2_debug_trap_config_init(struct amdgpu_device *adev, 752 764 uint32_t first_vmid, 753 765 uint32_t last_vmid)
+1
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
··· 28 28 uint32_t first_vmid, uint32_t last_vmid); 29 29 void gfx_v9_4_2_init_golden_registers(struct amdgpu_device *adev, 30 30 uint32_t die_id); 31 + void gfx_v9_4_2_init_sq(struct amdgpu_device *adev); 31 32 void gfx_v9_4_2_set_power_brake_sequence(struct amdgpu_device *adev); 32 33 int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev); 33 34
+9 -11
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
··· 2461 2461 /* Disable MEC parsing/prefetching */ 2462 2462 gfx_v9_4_3_xcc_cp_compute_enable(adev, false, 0); 2463 2463 2464 - if (grbm_soft_reset) { 2465 - tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2466 - tmp |= grbm_soft_reset; 2467 - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 2468 - WREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET, tmp); 2469 - tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2464 + tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2465 + tmp |= grbm_soft_reset; 2466 + dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 2467 + WREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET, tmp); 2468 + tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2470 2469 2471 - udelay(50); 2470 + udelay(50); 2472 2471 2473 - tmp &= ~grbm_soft_reset; 2474 - WREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET, tmp); 2475 - tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2476 - } 2472 + tmp &= ~grbm_soft_reset; 2473 + WREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET, tmp); 2474 + tmp = RREG32_SOC15(GC, GET_INST(GC, 0), regGRBM_SOFT_RESET); 2477 2475 2478 2476 /* Wait a little for things to settle down */ 2479 2477 udelay(50);
+28 -29
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
··· 466 466 * 0 valid 467 467 */ 468 468 469 - static uint64_t gmc_v10_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) 470 - { 471 - switch (flags) { 472 - case AMDGPU_VM_MTYPE_DEFAULT: 473 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 474 - case AMDGPU_VM_MTYPE_NC: 475 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 476 - case AMDGPU_VM_MTYPE_WC: 477 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_WC); 478 - case AMDGPU_VM_MTYPE_CC: 479 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_CC); 480 - case AMDGPU_VM_MTYPE_UC: 481 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_UC); 482 - default: 483 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 484 - } 485 - } 486 - 487 469 static void gmc_v10_0_get_vm_pde(struct amdgpu_device *adev, int level, 488 470 uint64_t *addr, uint64_t *flags) 489 471 { ··· 490 508 } 491 509 492 510 static void gmc_v10_0_get_vm_pte(struct amdgpu_device *adev, 493 - struct amdgpu_bo_va_mapping *mapping, 511 + struct amdgpu_vm *vm, 512 + struct amdgpu_bo *bo, 513 + uint32_t vm_flags, 494 514 uint64_t *flags) 495 515 { 496 - struct amdgpu_bo *bo = mapping->bo_va->base.bo; 516 + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) 517 + *flags |= AMDGPU_PTE_EXECUTABLE; 518 + else 519 + *flags &= ~AMDGPU_PTE_EXECUTABLE; 497 520 498 - *flags &= ~AMDGPU_PTE_EXECUTABLE; 499 - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; 521 + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { 522 + case AMDGPU_VM_MTYPE_DEFAULT: 523 + case AMDGPU_VM_MTYPE_NC: 524 + default: 525 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_NC); 526 + break; 527 + case AMDGPU_VM_MTYPE_WC: 528 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_WC); 529 + break; 530 + case AMDGPU_VM_MTYPE_CC: 531 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_CC); 532 + break; 533 + case AMDGPU_VM_MTYPE_UC: 534 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_UC); 535 + break; 536 + } 500 537 501 - *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK; 502 - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK); 538 + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) 539 + *flags |= AMDGPU_PTE_NOALLOC; 540 + else 541 + *flags &= ~AMDGPU_PTE_NOALLOC; 503 542 504 - *flags &= ~AMDGPU_PTE_NOALLOC; 505 - *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC); 506 - 507 - if (mapping->flags & AMDGPU_PTE_PRT) { 543 + if (vm_flags & AMDGPU_VM_PAGE_PRT) { 508 544 *flags |= AMDGPU_PTE_PRT; 509 545 *flags |= AMDGPU_PTE_SNOOPED; 510 546 *flags |= AMDGPU_PTE_LOG; ··· 563 563 .flush_gpu_tlb_pasid = gmc_v10_0_flush_gpu_tlb_pasid, 564 564 .emit_flush_gpu_tlb = gmc_v10_0_emit_flush_gpu_tlb, 565 565 .emit_pasid_mapping = gmc_v10_0_emit_pasid_mapping, 566 - .map_mtype = gmc_v10_0_map_mtype, 567 566 .get_vm_pde = gmc_v10_0_get_vm_pde, 568 567 .get_vm_pte = gmc_v10_0_get_vm_pte, 569 568 .get_vbios_fb_size = gmc_v10_0_get_vbios_fb_size,
+28 -29
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
··· 430 430 * 0 valid 431 431 */ 432 432 433 - static uint64_t gmc_v11_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) 434 - { 435 - switch (flags) { 436 - case AMDGPU_VM_MTYPE_DEFAULT: 437 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 438 - case AMDGPU_VM_MTYPE_NC: 439 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 440 - case AMDGPU_VM_MTYPE_WC: 441 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_WC); 442 - case AMDGPU_VM_MTYPE_CC: 443 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_CC); 444 - case AMDGPU_VM_MTYPE_UC: 445 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_UC); 446 - default: 447 - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); 448 - } 449 - } 450 - 451 433 static void gmc_v11_0_get_vm_pde(struct amdgpu_device *adev, int level, 452 434 uint64_t *addr, uint64_t *flags) 453 435 { ··· 454 472 } 455 473 456 474 static void gmc_v11_0_get_vm_pte(struct amdgpu_device *adev, 457 - struct amdgpu_bo_va_mapping *mapping, 475 + struct amdgpu_vm *vm, 476 + struct amdgpu_bo *bo, 477 + uint32_t vm_flags, 458 478 uint64_t *flags) 459 479 { 460 - struct amdgpu_bo *bo = mapping->bo_va->base.bo; 480 + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) 481 + *flags |= AMDGPU_PTE_EXECUTABLE; 482 + else 483 + *flags &= ~AMDGPU_PTE_EXECUTABLE; 461 484 462 - *flags &= ~AMDGPU_PTE_EXECUTABLE; 463 - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; 485 + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { 486 + case AMDGPU_VM_MTYPE_DEFAULT: 487 + case AMDGPU_VM_MTYPE_NC: 488 + default: 489 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_NC); 490 + break; 491 + case AMDGPU_VM_MTYPE_WC: 492 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_WC); 493 + break; 494 + case AMDGPU_VM_MTYPE_CC: 495 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_CC); 496 + break; 497 + case AMDGPU_VM_MTYPE_UC: 498 + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_UC); 499 + break; 500 + } 464 501 465 - *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK; 466 - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK); 502 + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) 503 + *flags |= AMDGPU_PTE_NOALLOC; 504 + else 505 + *flags &= ~AMDGPU_PTE_NOALLOC; 467 506 468 - *flags &= ~AMDGPU_PTE_NOALLOC; 469 - *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC); 470 - 471 - if (mapping->flags & AMDGPU_PTE_PRT) { 507 + if (vm_flags & AMDGPU_VM_PAGE_PRT) { 472 508 *flags |= AMDGPU_PTE_PRT; 473 509 *flags |= AMDGPU_PTE_SNOOPED; 474 510 *flags |= AMDGPU_PTE_LOG; ··· 527 527 .flush_gpu_tlb_pasid = gmc_v11_0_flush_gpu_tlb_pasid, 528 528 .emit_flush_gpu_tlb = gmc_v11_0_emit_flush_gpu_tlb, 529 529 .emit_pasid_mapping = gmc_v11_0_emit_pasid_mapping, 530 - .map_mtype = gmc_v11_0_map_mtype, 531 530 .get_vm_pde = gmc_v11_0_get_vm_pde, 532 531 .get_vm_pte = gmc_v11_0_get_vm_pte, 533 532 .get_vbios_fb_size = gmc_v11_0_get_vbios_fb_size,
+40 -23
drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
··· 336 336 uint16_t queried; 337 337 int vmid, i; 338 338 339 + if (adev->enable_uni_mes && adev->mes.ring[AMDGPU_MES_SCHED_PIPE].sched.ready && 340 + (adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x81) { 341 + struct mes_inv_tlbs_pasid_input input = {0}; 342 + input.pasid = pasid; 343 + input.flush_type = flush_type; 344 + input.hub_id = AMDGPU_GFXHUB(0); 345 + /* MES will invalidate all gc_hub for the device from master */ 346 + adev->mes.funcs->invalidate_tlbs_pasid(&adev->mes, &input); 347 + if (all_hub) { 348 + /* Only need to invalidate mm_hub now, gfx12 only support one mmhub */ 349 + input.hub_id = AMDGPU_MMHUB0(0); 350 + adev->mes.funcs->invalidate_tlbs_pasid(&adev->mes, &input); 351 + } 352 + return; 353 + } 354 + 339 355 for (vmid = 1; vmid < 16; vmid++) { 340 356 bool valid; 341 357 ··· 469 453 * 0 valid 470 454 */ 471 455 472 - static uint64_t gmc_v12_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) 473 - { 474 - switch (flags) { 475 - case AMDGPU_VM_MTYPE_DEFAULT: 476 - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); 477 - case AMDGPU_VM_MTYPE_NC: 478 - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); 479 - case AMDGPU_VM_MTYPE_UC: 480 - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_UC); 481 - default: 482 - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); 483 - } 484 - } 485 - 486 456 static void gmc_v12_0_get_vm_pde(struct amdgpu_device *adev, int level, 487 457 uint64_t *addr, uint64_t *flags) 488 458 { ··· 492 490 } 493 491 494 492 static void gmc_v12_0_get_vm_pte(struct amdgpu_device *adev, 495 - struct amdgpu_bo_va_mapping *mapping, 493 + struct amdgpu_vm *vm, 494 + struct amdgpu_bo *bo, 495 + uint32_t vm_flags, 496 496 uint64_t *flags) 497 497 { 498 - struct amdgpu_bo *bo = mapping->bo_va->base.bo; 498 + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) 499 + *flags |= AMDGPU_PTE_EXECUTABLE; 500 + else 501 + *flags &= ~AMDGPU_PTE_EXECUTABLE; 499 502 500 - *flags &= ~AMDGPU_PTE_EXECUTABLE; 501 - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; 503 + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { 504 + case AMDGPU_VM_MTYPE_DEFAULT: 505 + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_NC); 506 + break; 507 + case AMDGPU_VM_MTYPE_NC: 508 + default: 509 + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_NC); 510 + break; 511 + case AMDGPU_VM_MTYPE_UC: 512 + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_UC); 513 + break; 514 + } 502 515 503 - *flags &= ~AMDGPU_PTE_MTYPE_GFX12_MASK; 504 - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_GFX12_MASK); 516 + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) 517 + *flags |= AMDGPU_PTE_NOALLOC; 518 + else 519 + *flags &= ~AMDGPU_PTE_NOALLOC; 505 520 506 - if (mapping->flags & AMDGPU_PTE_PRT_GFX12) { 507 - *flags |= AMDGPU_PTE_PRT_GFX12; 521 + if (vm_flags & AMDGPU_VM_PAGE_PRT) { 508 522 *flags |= AMDGPU_PTE_SNOOPED; 509 523 *flags |= AMDGPU_PTE_SYSTEM; 510 524 *flags |= AMDGPU_PTE_IS_PTE; ··· 561 543 .flush_gpu_tlb_pasid = gmc_v12_0_flush_gpu_tlb_pasid, 562 544 .emit_flush_gpu_tlb = gmc_v12_0_emit_flush_gpu_tlb, 563 545 .emit_pasid_mapping = gmc_v12_0_emit_pasid_mapping, 564 - .map_mtype = gmc_v12_0_map_mtype, 565 546 .get_vm_pde = gmc_v12_0_get_vm_pde, 566 547 .get_vm_pte = gmc_v12_0_get_vm_pte, 567 548 .get_vbios_fb_size = gmc_v12_0_get_vbios_fb_size,
+3 -1
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
··· 382 382 } 383 383 384 384 static void gmc_v6_0_get_vm_pte(struct amdgpu_device *adev, 385 - struct amdgpu_bo_va_mapping *mapping, 385 + struct amdgpu_vm *vm, 386 + struct amdgpu_bo *bo, 387 + uint32_t vm_flags, 386 388 uint64_t *flags) 387 389 { 388 390 *flags &= ~AMDGPU_PTE_EXECUTABLE;
+3 -1
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
··· 504 504 } 505 505 506 506 static void gmc_v7_0_get_vm_pte(struct amdgpu_device *adev, 507 - struct amdgpu_bo_va_mapping *mapping, 507 + struct amdgpu_vm *vm, 508 + struct amdgpu_bo *bo, 509 + uint32_t vm_flags, 508 510 uint64_t *flags) 509 511 { 510 512 *flags &= ~AMDGPU_PTE_EXECUTABLE;
+7 -3
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
··· 716 716 } 717 717 718 718 static void gmc_v8_0_get_vm_pte(struct amdgpu_device *adev, 719 - struct amdgpu_bo_va_mapping *mapping, 719 + struct amdgpu_vm *vm, 720 + struct amdgpu_bo *bo, 721 + uint32_t vm_flags, 720 722 uint64_t *flags) 721 723 { 722 - *flags &= ~AMDGPU_PTE_EXECUTABLE; 723 - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; 724 + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) 725 + *flags |= AMDGPU_PTE_EXECUTABLE; 726 + else 727 + *flags &= ~AMDGPU_PTE_EXECUTABLE; 724 728 *flags &= ~AMDGPU_PTE_PRT; 725 729 } 726 730
+29 -32
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
··· 1073 1073 * 0 valid 1074 1074 */ 1075 1075 1076 - static uint64_t gmc_v9_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) 1077 - 1078 - { 1079 - switch (flags) { 1080 - case AMDGPU_VM_MTYPE_DEFAULT: 1081 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); 1082 - case AMDGPU_VM_MTYPE_NC: 1083 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); 1084 - case AMDGPU_VM_MTYPE_WC: 1085 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_WC); 1086 - case AMDGPU_VM_MTYPE_RW: 1087 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_RW); 1088 - case AMDGPU_VM_MTYPE_CC: 1089 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_CC); 1090 - case AMDGPU_VM_MTYPE_UC: 1091 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_UC); 1092 - default: 1093 - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); 1094 - } 1095 - } 1096 - 1097 1076 static void gmc_v9_0_get_vm_pde(struct amdgpu_device *adev, int level, 1098 1077 uint64_t *addr, uint64_t *flags) 1099 1078 { ··· 1102 1123 static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev, 1103 1124 struct amdgpu_vm *vm, 1104 1125 struct amdgpu_bo *bo, 1126 + uint32_t vm_flags, 1105 1127 uint64_t *flags) 1106 1128 { 1107 1129 struct amdgpu_device *bo_adev = amdgpu_ttm_adev(bo->tbo.bdev); ··· 1216 1236 } 1217 1237 1218 1238 static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev, 1219 - struct amdgpu_bo_va_mapping *mapping, 1239 + struct amdgpu_vm *vm, 1240 + struct amdgpu_bo *bo, 1241 + uint32_t vm_flags, 1220 1242 uint64_t *flags) 1221 1243 { 1222 - struct amdgpu_bo *bo = mapping->bo_va->base.bo; 1244 + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) 1245 + *flags |= AMDGPU_PTE_EXECUTABLE; 1246 + else 1247 + *flags &= ~AMDGPU_PTE_EXECUTABLE; 1223 1248 1224 - *flags &= ~AMDGPU_PTE_EXECUTABLE; 1225 - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; 1249 + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { 1250 + case AMDGPU_VM_MTYPE_DEFAULT: 1251 + case AMDGPU_VM_MTYPE_NC: 1252 + default: 1253 + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_NC); 1254 + break; 1255 + case AMDGPU_VM_MTYPE_WC: 1256 + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC); 1257 + break; 1258 + case AMDGPU_VM_MTYPE_RW: 1259 + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW); 1260 + break; 1261 + case AMDGPU_VM_MTYPE_CC: 1262 + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC); 1263 + break; 1264 + case AMDGPU_VM_MTYPE_UC: 1265 + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC); 1266 + break; 1267 + } 1226 1268 1227 - *flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK; 1228 - *flags |= mapping->flags & AMDGPU_PTE_MTYPE_VG10_MASK; 1229 - 1230 - if (mapping->flags & AMDGPU_PTE_PRT) { 1269 + if (vm_flags & AMDGPU_VM_PAGE_PRT) { 1231 1270 *flags |= AMDGPU_PTE_PRT; 1232 1271 *flags &= ~AMDGPU_PTE_VALID; 1233 1272 } 1234 1273 1235 1274 if ((*flags & AMDGPU_PTE_VALID) && bo) 1236 - gmc_v9_0_get_coherence_flags(adev, mapping->bo_va->base.vm, bo, 1237 - flags); 1275 + gmc_v9_0_get_coherence_flags(adev, vm, bo, vm_flags, flags); 1238 1276 } 1239 1277 1240 1278 static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev, ··· 1389 1391 .flush_gpu_tlb_pasid = gmc_v9_0_flush_gpu_tlb_pasid, 1390 1392 .emit_flush_gpu_tlb = gmc_v9_0_emit_flush_gpu_tlb, 1391 1393 .emit_pasid_mapping = gmc_v9_0_emit_pasid_mapping, 1392 - .map_mtype = gmc_v9_0_map_mtype, 1393 1394 .get_vm_pde = gmc_v9_0_get_vm_pde, 1394 1395 .get_vm_pte = gmc_v9_0_get_vm_pte, 1395 1396 .override_vm_pte_flags = gmc_v9_0_override_vm_pte_flags,
+1 -1
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
··· 444 444 ret = jpeg_v4_0_3_set_powergating_state(ip_block, AMD_PG_STATE_GATE); 445 445 } 446 446 447 - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG)) 447 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG) && !amdgpu_sriov_vf(adev)) 448 448 amdgpu_irq_put(adev, &adev->jpeg.inst->ras_poison_irq, 0); 449 449 450 450 return ret;
+17 -8
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
··· 196 196 } 197 197 } 198 198 199 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG)) { 200 + r = amdgpu_jpeg_ras_sw_init(adev); 201 + if (r) { 202 + dev_err(adev->dev, "Failed to initialize jpeg ras block!\n"); 203 + return r; 204 + } 205 + } 206 + 199 207 r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_1, ARRAY_SIZE(jpeg_reg_list_5_0_1)); 200 208 if (r) 201 209 return r; ··· 315 307 ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE); 316 308 } 317 309 318 - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG)) 310 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG) && !amdgpu_sriov_vf(adev)) 319 311 amdgpu_irq_put(adev, &adev->jpeg.inst->ras_poison_irq, 0); 320 312 321 313 return ret; ··· 1024 1016 1025 1017 /* reference to smu driver if header file */ 1026 1018 static int jpeg_v5_0_1_err_codes[] = { 1027 - 16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-7][S|D] */ 1028 - 24, 25, 26, 27, 28, 29, 30, 31 1019 + 16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-9][S|D] */ 1020 + 24, 25, 26, 27, 28, 29, 30, 31, 1021 + 48, 49, 50, 51, 1029 1022 }; 1030 1023 1031 1024 static bool jpeg_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, ··· 1067 1058 if (r) 1068 1059 return r; 1069 1060 1061 + r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__JPEG, 1062 + &jpeg_v5_0_1_aca_info, NULL); 1063 + if (r) 1064 + goto late_fini; 1065 + 1070 1066 if (amdgpu_ras_is_supported(adev, ras_block->block) && 1071 1067 adev->jpeg.inst->ras_poison_irq.funcs) { 1072 1068 r = amdgpu_irq_get(adev, &adev->jpeg.inst->ras_poison_irq, 0); 1073 1069 if (r) 1074 1070 goto late_fini; 1075 1071 } 1076 - 1077 - r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__JPEG, 1078 - &jpeg_v5_0_1_aca_info, NULL); 1079 - if (r) 1080 - goto late_fini; 1081 1072 1082 1073 return 0; 1083 1074
+3 -2
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
··· 641 641 break; 642 642 case MES_MISC_OP_CHANGE_CONFIG: 643 643 if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) < 0x63) { 644 - dev_err(mes->adev->dev, "MES FW version must be larger than 0x63 to support limit single process feature.\n"); 645 - return -EINVAL; 644 + dev_warn_once(mes->adev->dev, 645 + "MES FW version must be larger than 0x63 to support limit single process feature.\n"); 646 + return 0; 646 647 } 647 648 misc_pkt.opcode = MESAPI_MISC__CHANGE_CONFIG; 648 649 misc_pkt.change_config.opcode =
+42
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
··· 108 108 "SET_SE_MODE", 109 109 "SET_GANG_SUBMIT", 110 110 "SET_HW_RSRC_1", 111 + "INVALIDATE_TLBS", 111 112 }; 112 113 113 114 static const char *mes_v12_0_misc_opcodes[] = { ··· 880 879 offsetof(union MESAPI__RESET, api_status)); 881 880 } 882 881 882 + static int mes_v12_inv_tlb_convert_hub_id(uint8_t id) 883 + { 884 + /* 885 + * MES doesn't support invalidate gc_hub on slave xcc individually 886 + * master xcc will invalidate all gc_hub for the partition 887 + */ 888 + if (AMDGPU_IS_GFXHUB(id)) 889 + return 0; 890 + else if (AMDGPU_IS_MMHUB0(id)) 891 + return 1; 892 + else 893 + return -EINVAL; 894 + 895 + } 896 + 897 + static int mes_v12_0_inv_tlbs_pasid(struct amdgpu_mes *mes, 898 + struct mes_inv_tlbs_pasid_input *input) 899 + { 900 + union MESAPI__INV_TLBS mes_inv_tlbs; 901 + 902 + memset(&mes_inv_tlbs, 0, sizeof(mes_inv_tlbs)); 903 + 904 + mes_inv_tlbs.header.type = MES_API_TYPE_SCHEDULER; 905 + mes_inv_tlbs.header.opcode = MES_SCH_API_INV_TLBS; 906 + mes_inv_tlbs.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 907 + 908 + mes_inv_tlbs.invalidate_tlbs.inv_sel = 0; 909 + mes_inv_tlbs.invalidate_tlbs.flush_type = input->flush_type; 910 + mes_inv_tlbs.invalidate_tlbs.inv_sel_id = input->pasid; 911 + 912 + /*convert amdgpu_mes_hub_id to mes expected hub_id */ 913 + mes_inv_tlbs.invalidate_tlbs.hub_id = mes_v12_inv_tlb_convert_hub_id(input->hub_id); 914 + if (mes_inv_tlbs.invalidate_tlbs.hub_id < 0) 915 + return -EINVAL; 916 + return mes_v12_0_submit_pkt_and_poll_completion(mes, AMDGPU_MES_KIQ_PIPE, 917 + &mes_inv_tlbs, sizeof(mes_inv_tlbs), 918 + offsetof(union MESAPI__INV_TLBS, api_status)); 919 + 920 + } 921 + 883 922 static const struct amdgpu_mes_funcs mes_v12_0_funcs = { 884 923 .add_hw_queue = mes_v12_0_add_hw_queue, 885 924 .remove_hw_queue = mes_v12_0_remove_hw_queue, ··· 929 888 .resume_gang = mes_v12_0_resume_gang, 930 889 .misc_op = mes_v12_0_misc_op, 931 890 .reset_hw_queue = mes_v12_0_reset_hw_queue, 891 + .invalidate_tlbs_pasid = mes_v12_0_inv_tlbs_pasid, 932 892 }; 933 893 934 894 static int mes_v12_0_allocate_ucode_buffer(struct amdgpu_device *adev,
+28 -4
drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
··· 292 292 } 293 293 } 294 294 295 - static void xgpu_ai_mailbox_bad_pages_work(struct work_struct *work) 295 + static void xgpu_ai_mailbox_req_bad_pages_work(struct work_struct *work) 296 296 { 297 - struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, bad_pages_work); 297 + struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, req_bad_pages_work); 298 298 struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); 299 299 300 300 if (down_read_trylock(&adev->reset_domain->sem)) { 301 301 amdgpu_virt_fini_data_exchange(adev); 302 302 amdgpu_virt_request_bad_pages(adev); 303 + up_read(&adev->reset_domain->sem); 304 + } 305 + } 306 + 307 + /** 308 + * xgpu_ai_mailbox_handle_bad_pages_work - Reinitialize the data exchange region to get fresh bad page information 309 + * @work: pointer to the work_struct 310 + * 311 + * This work handler is triggered when bad pages are ready, and it reinitializes 312 + * the data exchange region to retrieve updated bad page information from the host. 313 + */ 314 + static void xgpu_ai_mailbox_handle_bad_pages_work(struct work_struct *work) 315 + { 316 + struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, handle_bad_pages_work); 317 + struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); 318 + 319 + if (down_read_trylock(&adev->reset_domain->sem)) { 320 + amdgpu_virt_fini_data_exchange(adev); 303 321 amdgpu_virt_init_data_exchange(adev); 304 322 up_read(&adev->reset_domain->sem); 305 323 } ··· 345 327 struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 346 328 347 329 switch (event) { 330 + case IDH_RAS_BAD_PAGES_READY: 331 + xgpu_ai_mailbox_send_ack(adev); 332 + if (amdgpu_sriov_runtime(adev)) 333 + schedule_work(&adev->virt.handle_bad_pages_work); 334 + break; 348 335 case IDH_RAS_BAD_PAGES_NOTIFICATION: 349 336 xgpu_ai_mailbox_send_ack(adev); 350 337 if (amdgpu_sriov_runtime(adev)) 351 - schedule_work(&adev->virt.bad_pages_work); 338 + schedule_work(&adev->virt.req_bad_pages_work); 352 339 break; 353 340 case IDH_UNRECOV_ERR_NOTIFICATION: 354 341 xgpu_ai_mailbox_send_ack(adev); ··· 438 415 } 439 416 440 417 INIT_WORK(&adev->virt.flr_work, xgpu_ai_mailbox_flr_work); 441 - INIT_WORK(&adev->virt.bad_pages_work, xgpu_ai_mailbox_bad_pages_work); 418 + INIT_WORK(&adev->virt.req_bad_pages_work, xgpu_ai_mailbox_req_bad_pages_work); 419 + INIT_WORK(&adev->virt.handle_bad_pages_work, xgpu_ai_mailbox_handle_bad_pages_work); 442 420 443 421 return 0; 444 422 }
+28 -7
drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
··· 202 202 case IDH_REQ_RAS_CPER_DUMP: 203 203 event = IDH_RAS_CPER_DUMP_READY; 204 204 break; 205 - case IDH_REQ_RAS_BAD_PAGES: 206 - event = IDH_RAS_BAD_PAGES_READY; 207 - break; 208 205 default: 209 206 break; 210 207 } ··· 356 359 } 357 360 } 358 361 359 - static void xgpu_nv_mailbox_bad_pages_work(struct work_struct *work) 362 + static void xgpu_nv_mailbox_req_bad_pages_work(struct work_struct *work) 360 363 { 361 - struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, bad_pages_work); 364 + struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, req_bad_pages_work); 362 365 struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); 363 366 364 367 if (down_read_trylock(&adev->reset_domain->sem)) { 365 368 amdgpu_virt_fini_data_exchange(adev); 366 369 amdgpu_virt_request_bad_pages(adev); 370 + up_read(&adev->reset_domain->sem); 371 + } 372 + } 373 + 374 + /** 375 + * xgpu_nv_mailbox_handle_bad_pages_work - Reinitialize the data exchange region to get fresh bad page information 376 + * @work: pointer to the work_struct 377 + * 378 + * This work handler is triggered when bad pages are ready, and it reinitializes 379 + * the data exchange region to retrieve updated bad page information from the host. 380 + */ 381 + static void xgpu_nv_mailbox_handle_bad_pages_work(struct work_struct *work) 382 + { 383 + struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, handle_bad_pages_work); 384 + struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); 385 + 386 + if (down_read_trylock(&adev->reset_domain->sem)) { 387 + amdgpu_virt_fini_data_exchange(adev); 367 388 amdgpu_virt_init_data_exchange(adev); 368 389 up_read(&adev->reset_domain->sem); 369 390 } ··· 412 397 struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 413 398 414 399 switch (event) { 400 + case IDH_RAS_BAD_PAGES_READY: 401 + xgpu_nv_mailbox_send_ack(adev); 402 + if (amdgpu_sriov_runtime(adev)) 403 + schedule_work(&adev->virt.handle_bad_pages_work); 404 + break; 415 405 case IDH_RAS_BAD_PAGES_NOTIFICATION: 416 406 xgpu_nv_mailbox_send_ack(adev); 417 407 if (amdgpu_sriov_runtime(adev)) 418 - schedule_work(&adev->virt.bad_pages_work); 408 + schedule_work(&adev->virt.req_bad_pages_work); 419 409 break; 420 410 case IDH_UNRECOV_ERR_NOTIFICATION: 421 411 xgpu_nv_mailbox_send_ack(adev); ··· 505 485 } 506 486 507 487 INIT_WORK(&adev->virt.flr_work, xgpu_nv_mailbox_flr_work); 508 - INIT_WORK(&adev->virt.bad_pages_work, xgpu_nv_mailbox_bad_pages_work); 488 + INIT_WORK(&adev->virt.req_bad_pages_work, xgpu_nv_mailbox_req_bad_pages_work); 489 + INIT_WORK(&adev->virt.handle_bad_pages_work, xgpu_nv_mailbox_handle_bad_pages_work); 509 490 510 491 return 0; 511 492 }
+3 -3
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
··· 151 151 * BIF_SDMA0_DOORBELL_RANGE: 0x3bc0 152 152 * BIF_SDMA1_DOORBELL_RANGE: 0x3bc4 153 153 * BIF_SDMA2_DOORBELL_RANGE: 0x3bd8 154 - + * BIF_SDMA4_DOORBELL_RANGE: 155 - + * ARCTURUS: 0x3be0 156 - + * ALDEBARAN: 0x3be4 154 + * BIF_SDMA4_DOORBELL_RANGE: 155 + * ARCTURUS: 0x3be0 156 + * ALDEBARAN: 0x3be4 157 157 */ 158 158 if (adev->asic_type == CHIP_ALDEBARAN && instance == 4) 159 159 reg = instance + 0x4 + 0x1 +
+4 -15
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
··· 149 149 int ret; 150 150 int retry_loop; 151 151 152 - for (retry_loop = 0; retry_loop < 10; retry_loop++) { 152 + for (retry_loop = 0; retry_loop < 20; retry_loop++) { 153 153 /* Wait for bootloader to signify that is 154 154 ready having bit 31 of C2PMSG_35 set to 1 */ 155 155 ret = psp_wait_for( 156 156 psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), 157 - 0x80000000, 0x80000000, PSP_WAITREG_NOVERBOSE); 157 + 0x80000000, 0x8000FFFF, PSP_WAITREG_NOVERBOSE); 158 158 159 159 if (ret == 0) 160 160 return 0; ··· 396 396 WREG32(offset, GFX_CTRL_CMD_ID_MODE1_RST); 397 397 398 398 msleep(500); 399 - 400 - offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33); 401 - 402 - ret = psp_wait_for(psp, offset, MBOX_TOS_RESP_FLAG, MBOX_TOS_RESP_MASK, 403 - 0); 404 - 405 - if (ret) { 406 - DRM_INFO("psp mode 1 reset failed!\n"); 407 - return -EINVAL; 408 - } 409 - 410 - DRM_INFO("psp mode1 reset succeed \n"); 411 399 412 400 return 0; 413 401 } ··· 653 665 .ring_get_wptr = psp_v11_0_ring_get_wptr, 654 666 .ring_set_wptr = psp_v11_0_ring_set_wptr, 655 667 .load_usbc_pd_fw = psp_v11_0_load_usbc_pd_fw, 656 - .read_usbc_pd_fw = psp_v11_0_read_usbc_pd_fw 668 + .read_usbc_pd_fw = psp_v11_0_read_usbc_pd_fw, 669 + .wait_for_bootloader = psp_v11_0_wait_for_bootloader 657 670 }; 658 671 659 672 void psp_v11_0_set_psp_funcs(struct psp_context *psp)
+3 -3
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
··· 1377 1377 1378 1378 switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { 1379 1379 case IP_VERSION(6, 0, 0): 1380 - if ((adev->sdma.instance[0].fw_version >= 24) && !adev->sdma.disable_uq) 1380 + if ((adev->sdma.instance[0].fw_version >= 27) && !adev->sdma.disable_uq) 1381 1381 adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1382 1382 break; 1383 1383 case IP_VERSION(6, 0, 1): ··· 1385 1385 adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1386 1386 break; 1387 1387 case IP_VERSION(6, 0, 2): 1388 - if ((adev->sdma.instance[0].fw_version >= 21) && !adev->sdma.disable_uq) 1388 + if ((adev->sdma.instance[0].fw_version >= 23) && !adev->sdma.disable_uq) 1389 1389 adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1390 1390 break; 1391 1391 case IP_VERSION(6, 0, 3): 1392 - if ((adev->sdma.instance[0].fw_version >= 25) && !adev->sdma.disable_uq) 1392 + if ((adev->sdma.instance[0].fw_version >= 27) && !adev->sdma.disable_uq) 1393 1393 adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1394 1394 break; 1395 1395 case IP_VERSION(6, 1, 0):
-1
drivers/gpu/drm/amd/amdgpu/soc15.c
··· 741 741 void soc15_set_virt_ops(struct amdgpu_device *adev) 742 742 { 743 743 adev->virt.ops = &xgpu_ai_virt_ops; 744 - 745 744 /* init soc15 reg base early enough so we can 746 745 * request request full access for sriov before 747 746 * set_ip_blocks. */
+4 -1
drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
··· 536 536 hwid = REG_GET_FIELD(ipid, MCMP1_IPIDT0, HardwareID); 537 537 mcatype = REG_GET_FIELD(ipid, MCMP1_IPIDT0, McaType); 538 538 539 - if ((hwid != MCA_UMC_HWID_V12_0) || (mcatype != MCA_UMC_MCATYPE_V12_0)) 539 + /* The IP block decode of consumption is SMU */ 540 + if (hwid != MCA_UMC_HWID_V12_0 || mcatype != MCA_UMC_MCATYPE_V12_0) { 541 + con->umc_ecc_log.consumption_q_count++; 540 542 return 0; 543 + } 541 544 542 545 if (!status) 543 546 return 0;
-2
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
··· 1338 1338 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); 1339 1339 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 1340 1340 1341 - ring = &adev->vcn.inst->ring_dec; 1342 1341 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, 1343 1342 RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); 1344 1343 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, ··· 1398 1399 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, 1399 1400 UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); 1400 1401 1401 - ring = &adev->vcn.inst->ring_dec; 1402 1402 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, 1403 1403 RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); 1404 1404 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
+13 -76
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
··· 136 136 { 137 137 struct amdgpu_ring *ring; 138 138 int i, r; 139 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); 140 - uint32_t *ptr; 141 139 struct amdgpu_device *adev = ip_block->adev; 142 140 volatile struct amdgpu_fw_shared *fw_shared; 143 141 ··· 230 232 if (amdgpu_vcnfw_log) 231 233 amdgpu_vcn_fwlog_init(adev->vcn.inst); 232 234 233 - /* Allocate memory for VCN IP Dump buffer */ 234 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 235 - if (!ptr) { 236 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 237 - adev->vcn.ip_dump = NULL; 238 - } else { 239 - adev->vcn.ip_dump = ptr; 240 - } 235 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_2_0, ARRAY_SIZE(vcn_reg_list_2_0)); 236 + if (r) 237 + return r; 241 238 242 239 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 243 240 if (r) ··· 268 275 amdgpu_vcn_sysfs_reset_mask_fini(adev); 269 276 270 277 r = amdgpu_vcn_sw_fini(adev, 0); 271 - 272 - kfree(adev->vcn.ip_dump); 273 278 274 279 return r; 275 280 } ··· 856 865 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 857 866 struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; 858 867 uint32_t rb_bufsz, tmp; 868 + int ret; 859 869 860 870 vcn_v2_0_enable_static_power_gating(vinst); 861 871 ··· 940 948 UVD, 0, mmUVD_MASTINT_EN), 941 949 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 942 950 943 - if (indirect) 944 - amdgpu_vcn_psp_update_sram(adev, 0, 0); 951 + if (indirect) { 952 + ret = amdgpu_vcn_psp_update_sram(adev, 0, 0); 953 + if (ret) { 954 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 955 + return ret; 956 + } 957 + } 945 958 946 959 /* force RBC into idle state */ 947 960 rb_bufsz = order_base_2(ring->ring_size); ··· 2092 2095 return vcn_v2_0_start_mmsch(adev, &adev->virt.mm_table); 2093 2096 } 2094 2097 2095 - static void vcn_v2_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 2096 - { 2097 - struct amdgpu_device *adev = ip_block->adev; 2098 - int i, j; 2099 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); 2100 - uint32_t inst_off, is_powered; 2101 - 2102 - if (!adev->vcn.ip_dump) 2103 - return; 2104 - 2105 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 2106 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2107 - if (adev->vcn.harvest_config & (1 << i)) { 2108 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 2109 - continue; 2110 - } 2111 - 2112 - inst_off = i * reg_count; 2113 - is_powered = (adev->vcn.ip_dump[inst_off] & 2114 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2115 - 2116 - if (is_powered) { 2117 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 2118 - for (j = 0; j < reg_count; j++) 2119 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_0[j].reg_name, 2120 - adev->vcn.ip_dump[inst_off + j]); 2121 - } else { 2122 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 2123 - } 2124 - } 2125 - } 2126 - 2127 - static void vcn_v2_0_dump_ip_state(struct amdgpu_ip_block *ip_block) 2128 - { 2129 - struct amdgpu_device *adev = ip_block->adev; 2130 - int i, j; 2131 - bool is_powered; 2132 - uint32_t inst_off; 2133 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); 2134 - 2135 - if (!adev->vcn.ip_dump) 2136 - return; 2137 - 2138 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2139 - if (adev->vcn.harvest_config & (1 << i)) 2140 - continue; 2141 - 2142 - inst_off = i * reg_count; 2143 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 2144 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); 2145 - is_powered = (adev->vcn.ip_dump[inst_off] & 2146 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2147 - 2148 - if (is_powered) 2149 - for (j = 1; j < reg_count; j++) 2150 - adev->vcn.ip_dump[inst_off + j] = 2151 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_0[j], i)); 2152 - } 2153 - } 2154 - 2155 2098 static const struct amd_ip_funcs vcn_v2_0_ip_funcs = { 2156 2099 .name = "vcn_v2_0", 2157 2100 .early_init = vcn_v2_0_early_init, ··· 2105 2168 .wait_for_idle = vcn_v2_0_wait_for_idle, 2106 2169 .set_clockgating_state = vcn_v2_0_set_clockgating_state, 2107 2170 .set_powergating_state = vcn_set_powergating_state, 2108 - .dump_ip_state = vcn_v2_0_dump_ip_state, 2109 - .print_ip_state = vcn_v2_0_print_ip_state, 2171 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 2172 + .print_ip_state = amdgpu_vcn_print_ip_state, 2110 2173 }; 2111 2174 2112 2175 static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
+17 -103
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
··· 116 116 struct amdgpu_device *adev = vcn_inst->adev; 117 117 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; 118 118 unsigned int i, j; 119 - int r = 0; 120 119 121 120 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 122 121 struct amdgpu_vcn_inst *v = &adev->vcn.inst[i]; ··· 148 149 if (!fences && !atomic_read(&adev->vcn.inst[0].total_submission_cnt)) { 149 150 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 150 151 AMD_PG_STATE_GATE); 151 - mutex_lock(&adev->vcn.workload_profile_mutex); 152 - if (adev->vcn.workload_profile_active) { 153 - r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 154 - false); 155 - if (r) 156 - dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r); 157 - adev->vcn.workload_profile_active = false; 158 - } 159 - mutex_unlock(&adev->vcn.workload_profile_mutex); 152 + amdgpu_vcn_put_profile(adev); 160 153 } else { 161 154 schedule_delayed_work(&adev->vcn.inst[0].idle_work, VCN_IDLE_TIMEOUT); 162 155 } ··· 158 167 { 159 168 struct amdgpu_device *adev = ring->adev; 160 169 struct amdgpu_vcn_inst *v = &adev->vcn.inst[ring->me]; 161 - int r = 0; 162 170 163 171 atomic_inc(&adev->vcn.inst[0].total_submission_cnt); 164 172 ··· 167 177 * the delayed work so there is no one else to set it to false 168 178 * and we don't care if someone else sets it to true. 169 179 */ 170 - if (adev->vcn.workload_profile_active) 171 - goto pg_lock; 172 - 173 - mutex_lock(&adev->vcn.workload_profile_mutex); 174 - if (!adev->vcn.workload_profile_active) { 175 - r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 176 - true); 177 - if (r) 178 - dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r); 179 - adev->vcn.workload_profile_active = true; 180 - } 181 - mutex_unlock(&adev->vcn.workload_profile_mutex); 182 - 183 - pg_lock: 184 180 mutex_lock(&adev->vcn.inst[0].vcn_pg_lock); 185 181 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 186 182 AMD_PG_STATE_UNGATE); ··· 194 218 v->pause_dpg_mode(v, &new_state); 195 219 } 196 220 mutex_unlock(&adev->vcn.inst[0].vcn_pg_lock); 221 + amdgpu_vcn_get_profile(adev); 197 222 } 198 223 199 224 static void vcn_v2_5_ring_end_use(struct amdgpu_ring *ring) ··· 274 297 { 275 298 struct amdgpu_ring *ring; 276 299 int i, j, r; 277 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 278 - uint32_t *ptr; 279 300 struct amdgpu_device *adev = ip_block->adev; 280 301 281 302 for (j = 0; j < adev->vcn.num_vcn_inst; j++) { ··· 398 423 if (r) 399 424 return r; 400 425 401 - /* Allocate memory for VCN IP Dump buffer */ 402 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 403 - if (!ptr) { 404 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 405 - adev->vcn.ip_dump = NULL; 406 - } else { 407 - adev->vcn.ip_dump = ptr; 408 - } 426 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_2_5, ARRAY_SIZE(vcn_reg_list_2_5)); 427 + if (r) 428 + return r; 409 429 410 430 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 411 431 if (r) ··· 446 476 if (r) 447 477 return r; 448 478 } 449 - 450 - kfree(adev->vcn.ip_dump); 451 479 452 480 return 0; 453 481 } ··· 1003 1035 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1004 1036 struct amdgpu_ring *ring; 1005 1037 uint32_t rb_bufsz, tmp; 1038 + int ret; 1006 1039 1007 1040 /* disable register anti-hang mechanism */ 1008 1041 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1, ··· 1094 1125 VCN, 0, mmUVD_MASTINT_EN), 1095 1126 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 1096 1127 1097 - if (indirect) 1098 - amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1128 + if (indirect) { 1129 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1130 + if (ret) { 1131 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 1132 + return ret; 1133 + } 1134 + } 1099 1135 1100 1136 ring = &adev->vcn.inst[inst_idx].ring_dec; 1101 1137 /* force RBC into idle state */ ··· 2101 2127 } 2102 2128 } 2103 2129 2104 - static void vcn_v2_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 2105 - { 2106 - struct amdgpu_device *adev = ip_block->adev; 2107 - int i, j; 2108 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 2109 - uint32_t inst_off, is_powered; 2110 - 2111 - if (!adev->vcn.ip_dump) 2112 - return; 2113 - 2114 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 2115 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2116 - if (adev->vcn.harvest_config & (1 << i)) { 2117 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 2118 - continue; 2119 - } 2120 - 2121 - inst_off = i * reg_count; 2122 - is_powered = (adev->vcn.ip_dump[inst_off] & 2123 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2124 - 2125 - if (is_powered) { 2126 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 2127 - for (j = 0; j < reg_count; j++) 2128 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_5[j].reg_name, 2129 - adev->vcn.ip_dump[inst_off + j]); 2130 - } else { 2131 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 2132 - } 2133 - } 2134 - } 2135 - 2136 - static void vcn_v2_5_dump_ip_state(struct amdgpu_ip_block *ip_block) 2137 - { 2138 - struct amdgpu_device *adev = ip_block->adev; 2139 - int i, j; 2140 - bool is_powered; 2141 - uint32_t inst_off; 2142 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 2143 - 2144 - if (!adev->vcn.ip_dump) 2145 - return; 2146 - 2147 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2148 - if (adev->vcn.harvest_config & (1 << i)) 2149 - continue; 2150 - 2151 - inst_off = i * reg_count; 2152 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 2153 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); 2154 - is_powered = (adev->vcn.ip_dump[inst_off] & 2155 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2156 - 2157 - if (is_powered) 2158 - for (j = 1; j < reg_count; j++) 2159 - adev->vcn.ip_dump[inst_off + j] = 2160 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_5[j], i)); 2161 - } 2162 - } 2163 - 2164 2130 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = { 2165 2131 .name = "vcn_v2_5", 2166 2132 .early_init = vcn_v2_5_early_init, ··· 2114 2200 .wait_for_idle = vcn_v2_5_wait_for_idle, 2115 2201 .set_clockgating_state = vcn_v2_5_set_clockgating_state, 2116 2202 .set_powergating_state = vcn_set_powergating_state, 2117 - .dump_ip_state = vcn_v2_5_dump_ip_state, 2118 - .print_ip_state = vcn_v2_5_print_ip_state, 2203 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 2204 + .print_ip_state = amdgpu_vcn_print_ip_state, 2119 2205 }; 2120 2206 2121 2207 static const struct amd_ip_funcs vcn_v2_6_ip_funcs = { ··· 2131 2217 .wait_for_idle = vcn_v2_5_wait_for_idle, 2132 2218 .set_clockgating_state = vcn_v2_5_set_clockgating_state, 2133 2219 .set_powergating_state = vcn_set_powergating_state, 2134 - .dump_ip_state = vcn_v2_5_dump_ip_state, 2135 - .print_ip_state = vcn_v2_5_print_ip_state, 2220 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 2221 + .print_ip_state = amdgpu_vcn_print_ip_state, 2136 2222 }; 2137 2223 2138 2224 const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
+13 -76
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
··· 175 175 struct amdgpu_ring *ring; 176 176 int i, j, r; 177 177 int vcn_doorbell_index = 0; 178 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); 179 - uint32_t *ptr; 180 178 struct amdgpu_device *adev = ip_block->adev; 181 179 182 180 /* ··· 302 304 return r; 303 305 } 304 306 305 - /* Allocate memory for VCN IP Dump buffer */ 306 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 307 - if (ptr == NULL) { 308 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 309 - adev->vcn.ip_dump = NULL; 310 - } else { 311 - adev->vcn.ip_dump = ptr; 312 - } 307 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_3_0, ARRAY_SIZE(vcn_reg_list_3_0)); 308 + if (r) 309 + return r; 313 310 314 311 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 315 312 if (r) ··· 354 361 return r; 355 362 } 356 363 357 - kfree(adev->vcn.ip_dump); 358 364 return 0; 359 365 } 360 366 ··· 1034 1042 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1035 1043 struct amdgpu_ring *ring; 1036 1044 uint32_t rb_bufsz, tmp; 1045 + int ret; 1037 1046 1038 1047 /* disable register anti-hang mechanism */ 1039 1048 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1, ··· 1127 1134 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1128 1135 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect); 1129 1136 1130 - if (indirect) 1131 - amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1137 + if (indirect) { 1138 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1139 + if (ret) { 1140 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 1141 + return ret; 1142 + } 1143 + } 1132 1144 1133 1145 ring = &adev->vcn.inst[inst_idx].ring_dec; 1134 1146 /* force RBC into idle state */ ··· 2340 2342 } 2341 2343 } 2342 2344 2343 - static void vcn_v3_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 2344 - { 2345 - struct amdgpu_device *adev = ip_block->adev; 2346 - int i, j; 2347 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); 2348 - uint32_t inst_off; 2349 - bool is_powered; 2350 - 2351 - if (!adev->vcn.ip_dump) 2352 - return; 2353 - 2354 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 2355 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2356 - if (adev->vcn.harvest_config & (1 << i)) { 2357 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 2358 - continue; 2359 - } 2360 - 2361 - inst_off = i * reg_count; 2362 - is_powered = (adev->vcn.ip_dump[inst_off] & 2363 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2364 - 2365 - if (is_powered) { 2366 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 2367 - for (j = 0; j < reg_count; j++) 2368 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_3_0[j].reg_name, 2369 - adev->vcn.ip_dump[inst_off + j]); 2370 - } else { 2371 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 2372 - } 2373 - } 2374 - } 2375 - 2376 - static void vcn_v3_0_dump_ip_state(struct amdgpu_ip_block *ip_block) 2377 - { 2378 - struct amdgpu_device *adev = ip_block->adev; 2379 - int i, j; 2380 - bool is_powered; 2381 - uint32_t inst_off; 2382 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); 2383 - 2384 - if (!adev->vcn.ip_dump) 2385 - return; 2386 - 2387 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2388 - if (adev->vcn.harvest_config & (1 << i)) 2389 - continue; 2390 - 2391 - inst_off = i * reg_count; 2392 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 2393 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); 2394 - is_powered = (adev->vcn.ip_dump[inst_off] & 2395 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2396 - 2397 - if (is_powered) 2398 - for (j = 1; j < reg_count; j++) 2399 - adev->vcn.ip_dump[inst_off + j] = 2400 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_3_0[j], i)); 2401 - } 2402 - } 2403 - 2404 2345 static const struct amd_ip_funcs vcn_v3_0_ip_funcs = { 2405 2346 .name = "vcn_v3_0", 2406 2347 .early_init = vcn_v3_0_early_init, ··· 2353 2416 .wait_for_idle = vcn_v3_0_wait_for_idle, 2354 2417 .set_clockgating_state = vcn_v3_0_set_clockgating_state, 2355 2418 .set_powergating_state = vcn_set_powergating_state, 2356 - .dump_ip_state = vcn_v3_0_dump_ip_state, 2357 - .print_ip_state = vcn_v3_0_print_ip_state, 2419 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 2420 + .print_ip_state = amdgpu_vcn_print_ip_state, 2358 2421 }; 2359 2422 2360 2423 const struct amdgpu_ip_block_version vcn_v3_0_ip_block = {
+13 -78
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
··· 183 183 struct amdgpu_ring *ring; 184 184 struct amdgpu_device *adev = ip_block->adev; 185 185 int i, r; 186 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); 187 - uint32_t *ptr; 188 186 189 187 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 190 188 if (adev->vcn.harvest_config & (1 << i)) ··· 253 255 if (r) 254 256 return r; 255 257 256 - /* Allocate memory for VCN IP Dump buffer */ 257 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 258 - if (!ptr) { 259 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 260 - adev->vcn.ip_dump = NULL; 261 - } else { 262 - adev->vcn.ip_dump = ptr; 263 - } 258 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0, ARRAY_SIZE(vcn_reg_list_4_0)); 259 + if (r) 260 + return r; 264 261 265 262 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 266 263 if (r) ··· 307 314 if (r) 308 315 return r; 309 316 } 310 - 311 - kfree(adev->vcn.ip_dump); 312 317 313 318 return 0; 314 319 } ··· 1003 1012 volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1004 1013 struct amdgpu_ring *ring; 1005 1014 uint32_t tmp; 1015 + int ret; 1006 1016 1007 1017 /* disable register anti-hang mechanism */ 1008 1018 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1, ··· 1086 1094 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 1087 1095 1088 1096 1089 - if (indirect) 1090 - amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1097 + if (indirect) { 1098 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1099 + if (ret) { 1100 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 1101 + return ret; 1102 + } 1103 + } 1091 1104 1092 1105 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 1093 1106 ··· 1621 1624 1622 1625 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1623 1626 vcn_v4_0_stop_dpg_mode(vinst); 1624 - r = 0; 1625 1627 goto done; 1626 1628 } 1627 1629 ··· 2242 2246 } 2243 2247 } 2244 2248 2245 - static void vcn_v4_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 2246 - { 2247 - struct amdgpu_device *adev = ip_block->adev; 2248 - int i, j; 2249 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); 2250 - uint32_t inst_off, is_powered; 2251 - 2252 - if (!adev->vcn.ip_dump) 2253 - return; 2254 - 2255 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 2256 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2257 - if (adev->vcn.harvest_config & (1 << i)) { 2258 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 2259 - continue; 2260 - } 2261 - 2262 - inst_off = i * reg_count; 2263 - is_powered = (adev->vcn.ip_dump[inst_off] & 2264 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2265 - 2266 - if (is_powered) { 2267 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 2268 - for (j = 0; j < reg_count; j++) 2269 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0[j].reg_name, 2270 - adev->vcn.ip_dump[inst_off + j]); 2271 - } else { 2272 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 2273 - } 2274 - } 2275 - } 2276 - 2277 - static void vcn_v4_0_dump_ip_state(struct amdgpu_ip_block *ip_block) 2278 - { 2279 - struct amdgpu_device *adev = ip_block->adev; 2280 - int i, j; 2281 - bool is_powered; 2282 - uint32_t inst_off; 2283 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); 2284 - 2285 - if (!adev->vcn.ip_dump) 2286 - return; 2287 - 2288 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2289 - if (adev->vcn.harvest_config & (1 << i)) 2290 - continue; 2291 - 2292 - inst_off = i * reg_count; 2293 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 2294 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); 2295 - is_powered = (adev->vcn.ip_dump[inst_off] & 2296 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2297 - 2298 - if (is_powered) 2299 - for (j = 1; j < reg_count; j++) 2300 - adev->vcn.ip_dump[inst_off + j] = 2301 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0[j], 2302 - i)); 2303 - } 2304 - } 2305 - 2306 2249 static const struct amd_ip_funcs vcn_v4_0_ip_funcs = { 2307 2250 .name = "vcn_v4_0", 2308 2251 .early_init = vcn_v4_0_early_init, ··· 2255 2320 .wait_for_idle = vcn_v4_0_wait_for_idle, 2256 2321 .set_clockgating_state = vcn_v4_0_set_clockgating_state, 2257 2322 .set_powergating_state = vcn_set_powergating_state, 2258 - .dump_ip_state = vcn_v4_0_dump_ip_state, 2259 - .print_ip_state = vcn_v4_0_print_ip_state, 2323 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 2324 + .print_ip_state = amdgpu_vcn_print_ip_state, 2260 2325 }; 2261 2326 2262 2327 const struct amdgpu_ip_block_version vcn_v4_0_ip_block = {
+27 -87
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
··· 134 134 return 0; 135 135 } 136 136 137 + static int vcn_v4_0_3_late_init(struct amdgpu_ip_block *ip_block) 138 + { 139 + struct amdgpu_device *adev = ip_block->adev; 140 + 141 + adev->vcn.supported_reset = 142 + amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); 143 + 144 + if (amdgpu_dpm_reset_vcn_is_supported(adev)) 145 + adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 146 + 147 + return 0; 148 + } 149 + 137 150 static int vcn_v4_0_3_fw_shared_init(struct amdgpu_device *adev, int inst_idx) 138 151 { 139 152 struct amdgpu_vcn4_fw_shared *fw_shared; ··· 173 160 struct amdgpu_device *adev = ip_block->adev; 174 161 struct amdgpu_ring *ring; 175 162 int i, r, vcn_inst; 176 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 177 - uint32_t *ptr; 178 163 179 164 /* VCN DEC TRAP */ 180 165 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, ··· 224 213 adev->vcn.inst[i].pause_dpg_mode = vcn_v4_0_3_pause_dpg_mode; 225 214 } 226 215 227 - /* TODO: Add queue reset mask when FW fully supports it */ 228 - adev->vcn.supported_reset = 229 - amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); 230 - 231 216 if (amdgpu_sriov_vf(adev)) { 232 217 r = amdgpu_virt_alloc_mm_table(adev); 233 218 if (r) ··· 238 231 } 239 232 } 240 233 241 - /* Allocate memory for VCN IP Dump buffer */ 242 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 243 - if (!ptr) { 244 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 245 - adev->vcn.ip_dump = NULL; 246 - } else { 247 - adev->vcn.ip_dump = ptr; 248 - } 249 - 250 - r = amdgpu_vcn_sysfs_reset_mask_init(adev); 234 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0_3, ARRAY_SIZE(vcn_reg_list_4_0_3)); 251 235 if (r) 252 236 return r; 253 237 254 - return 0; 238 + return amdgpu_vcn_sysfs_reset_mask_init(adev); 255 239 } 256 240 257 241 /** ··· 284 286 if (r) 285 287 return r; 286 288 } 287 - 288 - kfree(adev->vcn.ip_dump); 289 289 290 290 return 0; 291 291 } ··· 387 391 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); 388 392 } 389 393 390 - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 394 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN) && !amdgpu_sriov_vf(adev)) 391 395 amdgpu_irq_put(adev, &adev->vcn.inst->ras_poison_irq, 0); 392 396 393 397 return 0; ··· 847 851 volatile struct amdgpu_vcn4_fw_shared *fw_shared = 848 852 adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 849 853 struct amdgpu_ring *ring; 850 - int vcn_inst; 854 + int vcn_inst, ret; 851 855 uint32_t tmp; 852 856 853 857 vcn_inst = GET_INST(VCN, inst_idx); ··· 940 944 VCN, 0, regUVD_MASTINT_EN), 941 945 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 942 946 943 - if (indirect) 944 - amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 947 + if (indirect) { 948 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 949 + if (ret) { 950 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 951 + return ret; 952 + } 953 + } 945 954 946 955 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 947 956 ··· 1873 1872 adev->vcn.inst->ras_poison_irq.funcs = &vcn_v4_0_3_ras_irq_funcs; 1874 1873 } 1875 1874 1876 - static void vcn_v4_0_3_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1877 - { 1878 - struct amdgpu_device *adev = ip_block->adev; 1879 - int i, j; 1880 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 1881 - uint32_t inst_off, is_powered; 1882 - 1883 - if (!adev->vcn.ip_dump) 1884 - return; 1885 - 1886 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1887 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1888 - if (adev->vcn.harvest_config & (1 << i)) { 1889 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1890 - continue; 1891 - } 1892 - 1893 - inst_off = i * reg_count; 1894 - is_powered = (adev->vcn.ip_dump[inst_off] & 1895 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1896 - 1897 - if (is_powered) { 1898 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 1899 - for (j = 0; j < reg_count; j++) 1900 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_3[j].reg_name, 1901 - adev->vcn.ip_dump[inst_off + j]); 1902 - } else { 1903 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1904 - } 1905 - } 1906 - } 1907 - 1908 - static void vcn_v4_0_3_dump_ip_state(struct amdgpu_ip_block *ip_block) 1909 - { 1910 - struct amdgpu_device *adev = ip_block->adev; 1911 - int i, j; 1912 - bool is_powered; 1913 - uint32_t inst_off, inst_id; 1914 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 1915 - 1916 - if (!adev->vcn.ip_dump) 1917 - return; 1918 - 1919 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1920 - if (adev->vcn.harvest_config & (1 << i)) 1921 - continue; 1922 - 1923 - inst_id = GET_INST(VCN, i); 1924 - inst_off = i * reg_count; 1925 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1926 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, inst_id, regUVD_POWER_STATUS); 1927 - is_powered = (adev->vcn.ip_dump[inst_off] & 1928 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1929 - 1930 - if (is_powered) 1931 - for (j = 1; j < reg_count; j++) 1932 - adev->vcn.ip_dump[inst_off + j] = 1933 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_3[j], 1934 - inst_id)); 1935 - } 1936 - } 1937 - 1938 1875 static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = { 1939 1876 .name = "vcn_v4_0_3", 1940 1877 .early_init = vcn_v4_0_3_early_init, 1878 + .late_init = vcn_v4_0_3_late_init, 1941 1879 .sw_init = vcn_v4_0_3_sw_init, 1942 1880 .sw_fini = vcn_v4_0_3_sw_fini, 1943 1881 .hw_init = vcn_v4_0_3_hw_init, ··· 1887 1947 .wait_for_idle = vcn_v4_0_3_wait_for_idle, 1888 1948 .set_clockgating_state = vcn_v4_0_3_set_clockgating_state, 1889 1949 .set_powergating_state = vcn_set_powergating_state, 1890 - .dump_ip_state = vcn_v4_0_3_dump_ip_state, 1891 - .print_ip_state = vcn_v4_0_3_print_ip_state, 1950 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 1951 + .print_ip_state = amdgpu_vcn_print_ip_state, 1892 1952 }; 1893 1953 1894 1954 const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block = {
+13 -79
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
··· 147 147 struct amdgpu_ring *ring; 148 148 struct amdgpu_device *adev = ip_block->adev; 149 149 int i, r; 150 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 151 - uint32_t *ptr; 152 - 153 150 154 151 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 155 152 volatile struct amdgpu_vcn4_fw_shared *fw_shared; ··· 230 233 return r; 231 234 } 232 235 233 - /* Allocate memory for VCN IP Dump buffer */ 234 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 235 - if (!ptr) { 236 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 237 - adev->vcn.ip_dump = NULL; 238 - } else { 239 - adev->vcn.ip_dump = ptr; 240 - } 241 - return 0; 236 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0_5, ARRAY_SIZE(vcn_reg_list_4_0_5)); 237 + 238 + return r; 242 239 } 243 240 244 241 /** ··· 274 283 if (r) 275 284 return r; 276 285 } 277 - 278 - kfree(adev->vcn.ip_dump); 279 286 280 287 return 0; 281 288 } ··· 915 926 volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 916 927 struct amdgpu_ring *ring; 917 928 uint32_t tmp; 929 + int ret; 918 930 919 931 /* disable register anti-hang mechanism */ 920 932 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1, ··· 996 1006 VCN, inst_idx, regUVD_MASTINT_EN), 997 1007 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 998 1008 999 - if (indirect) 1000 - amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1009 + if (indirect) { 1010 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1011 + if (ret) { 1012 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 1013 + return ret; 1014 + } 1015 + } 1001 1016 1002 1017 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 1003 1018 ··· 1699 1704 } 1700 1705 } 1701 1706 1702 - static void vcn_v4_0_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1703 - { 1704 - struct amdgpu_device *adev = ip_block->adev; 1705 - int i, j; 1706 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1707 - uint32_t inst_off, is_powered; 1708 - 1709 - if (!adev->vcn.ip_dump) 1710 - return; 1711 - 1712 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1713 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1714 - if (adev->vcn.harvest_config & (1 << i)) { 1715 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1716 - continue; 1717 - } 1718 - 1719 - inst_off = i * reg_count; 1720 - is_powered = (adev->vcn.ip_dump[inst_off] & 1721 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1722 - 1723 - if (is_powered) { 1724 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 1725 - for (j = 0; j < reg_count; j++) 1726 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_5[j].reg_name, 1727 - adev->vcn.ip_dump[inst_off + j]); 1728 - } else { 1729 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1730 - } 1731 - } 1732 - } 1733 - 1734 - static void vcn_v4_0_5_dump_ip_state(struct amdgpu_ip_block *ip_block) 1735 - { 1736 - struct amdgpu_device *adev = ip_block->adev; 1737 - int i, j; 1738 - bool is_powered; 1739 - uint32_t inst_off; 1740 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1741 - 1742 - if (!adev->vcn.ip_dump) 1743 - return; 1744 - 1745 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1746 - if (adev->vcn.harvest_config & (1 << i)) 1747 - continue; 1748 - 1749 - inst_off = i * reg_count; 1750 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1751 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); 1752 - is_powered = (adev->vcn.ip_dump[inst_off] & 1753 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1754 - 1755 - if (is_powered) 1756 - for (j = 1; j < reg_count; j++) 1757 - adev->vcn.ip_dump[inst_off + j] = 1758 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_5[j], 1759 - i)); 1760 - } 1761 - } 1762 - 1763 1707 static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = { 1764 1708 .name = "vcn_v4_0_5", 1765 1709 .early_init = vcn_v4_0_5_early_init, ··· 1712 1778 .wait_for_idle = vcn_v4_0_5_wait_for_idle, 1713 1779 .set_clockgating_state = vcn_v4_0_5_set_clockgating_state, 1714 1780 .set_powergating_state = vcn_set_powergating_state, 1715 - .dump_ip_state = vcn_v4_0_5_dump_ip_state, 1716 - .print_ip_state = vcn_v4_0_5_print_ip_state, 1781 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 1782 + .print_ip_state = amdgpu_vcn_print_ip_state, 1717 1783 }; 1718 1784 1719 1785 const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = {
+13 -83
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
··· 115 115 return 0; 116 116 } 117 117 118 - void vcn_v5_0_0_alloc_ip_dump(struct amdgpu_device *adev) 119 - { 120 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); 121 - uint32_t *ptr; 122 - 123 - /* Allocate memory for VCN IP Dump buffer */ 124 - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 125 - if (!ptr) { 126 - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 127 - adev->vcn.ip_dump = NULL; 128 - } else { 129 - adev->vcn.ip_dump = ptr; 130 - } 131 - } 132 - 133 118 /** 134 119 * vcn_v5_0_0_sw_init - sw init for VCN block 135 120 * ··· 186 201 if (!amdgpu_sriov_vf(adev)) 187 202 adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 188 203 189 - vcn_v5_0_0_alloc_ip_dump(adev); 204 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0, ARRAY_SIZE(vcn_reg_list_5_0)); 205 + if (r) 206 + return r; 190 207 191 208 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 192 209 if (r) ··· 237 250 if (r) 238 251 return r; 239 252 } 240 - 241 - kfree(adev->vcn.ip_dump); 242 253 243 254 return 0; 244 255 } ··· 698 713 volatile struct amdgpu_vcn5_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 699 714 struct amdgpu_ring *ring; 700 715 uint32_t tmp; 716 + int ret; 701 717 702 718 /* disable register anti-hang mechanism */ 703 719 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1, ··· 752 766 VCN, inst_idx, regUVD_MASTINT_EN), 753 767 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 754 768 755 - if (indirect) 756 - amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 769 + if (indirect) { 770 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 771 + if (ret) { 772 + dev_err(adev->dev, "%s: vcn sram load failed %d\n", __func__, ret); 773 + return ret; 774 + } 775 + } 757 776 758 777 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 759 778 ··· 1419 1428 } 1420 1429 } 1421 1430 1422 - void vcn_v5_0_0_print_ip_state(struct amdgpu_ip_block *ip_block, 1423 - struct drm_printer *p) 1424 - { 1425 - struct amdgpu_device *adev = ip_block->adev; 1426 - int i, j; 1427 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); 1428 - uint32_t inst_off, is_powered; 1429 - 1430 - if (!adev->vcn.ip_dump) 1431 - return; 1432 - 1433 - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1434 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1435 - if (adev->vcn.harvest_config & (1 << i)) { 1436 - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1437 - continue; 1438 - } 1439 - 1440 - inst_off = i * reg_count; 1441 - is_powered = (adev->vcn.ip_dump[inst_off] & 1442 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1443 - 1444 - if (is_powered) { 1445 - drm_printf(p, "\nActive Instance:VCN%d\n", i); 1446 - for (j = 0; j < reg_count; j++) 1447 - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_5_0[j].reg_name, 1448 - adev->vcn.ip_dump[inst_off + j]); 1449 - } else { 1450 - drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1451 - } 1452 - } 1453 - } 1454 - 1455 - void vcn_v5_0_0_dump_ip_state(struct amdgpu_ip_block *ip_block) 1456 - { 1457 - struct amdgpu_device *adev = ip_block->adev; 1458 - int i, j; 1459 - bool is_powered; 1460 - uint32_t inst_off; 1461 - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); 1462 - 1463 - if (!adev->vcn.ip_dump) 1464 - return; 1465 - 1466 - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1467 - if (adev->vcn.harvest_config & (1 << i)) 1468 - continue; 1469 - 1470 - inst_off = i * reg_count; 1471 - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1472 - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); 1473 - is_powered = (adev->vcn.ip_dump[inst_off] & 1474 - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1475 - 1476 - if (is_powered) 1477 - for (j = 1; j < reg_count; j++) 1478 - adev->vcn.ip_dump[inst_off + j] = 1479 - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_5_0[j], i)); 1480 - } 1481 - } 1482 - 1483 1431 static const struct amd_ip_funcs vcn_v5_0_0_ip_funcs = { 1484 1432 .name = "vcn_v5_0_0", 1485 1433 .early_init = vcn_v5_0_0_early_init, ··· 1432 1502 .wait_for_idle = vcn_v5_0_0_wait_for_idle, 1433 1503 .set_clockgating_state = vcn_v5_0_0_set_clockgating_state, 1434 1504 .set_powergating_state = vcn_set_powergating_state, 1435 - .dump_ip_state = vcn_v5_0_0_dump_ip_state, 1436 - .print_ip_state = vcn_v5_0_0_print_ip_state, 1505 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 1506 + .print_ip_state = amdgpu_vcn_print_ip_state, 1437 1507 }; 1438 1508 1439 1509 const struct amdgpu_ip_block_version vcn_v5_0_0_ip_block = {
-5
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h
··· 32 32 #define VCN_VID_IP_ADDRESS 0x0 33 33 #define VCN_AON_IP_ADDRESS 0x30000 34 34 35 - void vcn_v5_0_0_alloc_ip_dump(struct amdgpu_device *adev); 36 - void vcn_v5_0_0_print_ip_state(struct amdgpu_ip_block *ip_block, 37 - struct drm_printer *p); 38 - void vcn_v5_0_0_dump_ip_state(struct amdgpu_ip_block *ip_block); 39 - 40 35 extern const struct amdgpu_ip_block_version vcn_v5_0_0_ip_block; 41 36 42 37 #endif /* __VCN_V5_0_0_H__ */
+64 -10
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
··· 40 40 41 41 #include <drm/drm_drv.h> 42 42 43 + static const struct amdgpu_hwip_reg_entry vcn_reg_list_5_0_1[] = { 44 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), 45 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), 46 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), 47 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), 48 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), 49 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), 50 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), 51 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), 52 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), 53 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), 54 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), 55 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), 56 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), 57 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), 58 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), 59 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), 60 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), 61 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), 62 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), 63 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), 64 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), 65 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), 66 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), 67 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), 68 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), 69 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), 70 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), 71 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), 72 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), 73 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), 74 + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) 75 + }; 76 + 43 77 static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev); 44 78 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev); 45 79 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); ··· 197 163 return r; 198 164 } 199 165 200 - vcn_v5_0_0_alloc_ip_dump(adev); 166 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { 167 + r = amdgpu_vcn_ras_sw_init(adev); 168 + if (r) { 169 + dev_err(adev->dev, "Failed to initialize vcn ras block!\n"); 170 + return r; 171 + } 172 + } 173 + 174 + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0_1, ARRAY_SIZE(vcn_reg_list_5_0_1)); 175 + if (r) 176 + return r; 201 177 202 178 return amdgpu_vcn_sysfs_reset_mask_init(adev); 203 179 } ··· 252 208 } 253 209 254 210 amdgpu_vcn_sysfs_reset_mask_fini(adev); 255 - 256 - kfree(adev->vcn.ip_dump); 257 211 258 212 return 0; 259 213 } ··· 326 284 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); 327 285 } 328 286 329 - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 287 + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN) && !amdgpu_sriov_vf(adev)) 330 288 amdgpu_irq_put(adev, &adev->vcn.inst->ras_poison_irq, 0); 331 289 332 290 return 0; ··· 647 605 adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 648 606 struct amdgpu_ring *ring; 649 607 struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE}; 650 - int vcn_inst; 608 + int vcn_inst, ret; 651 609 uint32_t tmp; 652 610 653 611 vcn_inst = GET_INST(VCN, inst_idx); ··· 708 666 VCN, 0, regUVD_MASTINT_EN), 709 667 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 710 668 711 - if (indirect) 712 - amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 669 + if (indirect) { 670 + ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 671 + if (ret) { 672 + dev_err(adev->dev, "vcn sram load failed %d\n", ret); 673 + return ret; 674 + } 675 + } 713 676 714 677 /* resetting ring, fw should not check RB ring */ 715 678 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; ··· 1522 1475 .post_soft_reset = NULL, 1523 1476 .set_clockgating_state = vcn_v5_0_1_set_clockgating_state, 1524 1477 .set_powergating_state = vcn_set_powergating_state, 1525 - .dump_ip_state = vcn_v5_0_0_dump_ip_state, 1526 - .print_ip_state = vcn_v5_0_0_print_ip_state, 1478 + .dump_ip_state = amdgpu_vcn_dump_ip_state, 1479 + .print_ip_state = amdgpu_vcn_print_ip_state, 1527 1480 }; 1528 1481 1529 1482 const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = { ··· 1604 1557 1605 1558 /* reference to smu driver if header file */ 1606 1559 static int vcn_v5_0_1_err_codes[] = { 1607 - 14, 15, /* VCN */ 1560 + 14, 15, 47, /* VCN [D|V|S] */ 1608 1561 }; 1609 1562 1610 1563 static bool vcn_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, ··· 1649 1602 &vcn_v5_0_1_aca_info, NULL); 1650 1603 if (r) 1651 1604 goto late_fini; 1605 + 1606 + if (amdgpu_ras_is_supported(adev, ras_block->block) && 1607 + adev->vcn.inst->ras_poison_irq.funcs) { 1608 + r = amdgpu_irq_get(adev, &adev->vcn.inst->ras_poison_irq, 0); 1609 + if (r) 1610 + goto late_fini; 1611 + } 1652 1612 1653 1613 return 0; 1654 1614
+12 -3
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 1070 1070 svm_range_list_lock_and_flush_work(&p->svms, current->mm); 1071 1071 mutex_lock(&p->svms.lock); 1072 1072 mmap_write_unlock(current->mm); 1073 - if (interval_tree_iter_first(&p->svms.objects, 1073 + 1074 + /* Skip a special case that allocates VRAM without VA, 1075 + * VA will be invalid of 0. 1076 + */ 1077 + if (!(!args->va_addr && (flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM)) && 1078 + interval_tree_iter_first(&p->svms.objects, 1074 1079 args->va_addr >> PAGE_SHIFT, 1075 1080 (args->va_addr + args->size - 1) >> PAGE_SHIFT)) { 1076 1081 pr_err("Address: 0x%llx already allocated by SVM\n", ··· 3257 3252 int retcode = -EINVAL; 3258 3253 bool ptrace_attached = false; 3259 3254 3260 - if (nr >= AMDKFD_CORE_IOCTL_COUNT) 3255 + if (nr >= AMDKFD_CORE_IOCTL_COUNT) { 3256 + retcode = -ENOTTY; 3261 3257 goto err_i1; 3258 + } 3262 3259 3263 3260 if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { 3264 3261 u32 amdkfd_size; ··· 3273 3266 asize = amdkfd_size; 3274 3267 3275 3268 cmd = ioctl->cmd; 3276 - } else 3269 + } else { 3270 + retcode = -ENOTTY; 3277 3271 goto err_i1; 3272 + } 3278 3273 3279 3274 dev_dbg(kfd_device, "ioctl cmd 0x%x (#0x%x), arg 0x%lx\n", cmd, nr, arg); 3280 3275
+2 -5
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
··· 46 46 int retval; 47 47 union PM4_MES_TYPE_3_HEADER nop; 48 48 49 - if (WARN_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ)) 50 - return false; 51 - 52 - pr_debug("Initializing queue type %d size %d\n", KFD_QUEUE_TYPE_HIQ, 53 - queue_size); 49 + pr_debug("Initializing queue type %d size %d\n", type, queue_size); 54 50 55 51 memset(&prop, 0, sizeof(prop)); 56 52 memset(&nop, 0, sizeof(nop)); ··· 65 69 kq->mqd_mgr = dev->dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]; 66 70 break; 67 71 default: 72 + WARN(1, "Invalid queue type %d\n", type); 68 73 dev_err(dev->adev->dev, "Invalid queue type %d\n", type); 69 74 return false; 70 75 }
+36 -37
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
··· 260 260 put_page(page); 261 261 } 262 262 263 - static unsigned long svm_migrate_unsuccessful_pages(struct migrate_vma *migrate) 264 - { 265 - unsigned long upages = 0; 266 - unsigned long i; 267 - 268 - for (i = 0; i < migrate->npages; i++) { 269 - if (migrate->src[i] & MIGRATE_PFN_VALID && 270 - !(migrate->src[i] & MIGRATE_PFN_MIGRATE)) 271 - upages++; 272 - } 273 - return upages; 274 - } 275 - 276 - static int 263 + static long 277 264 svm_migrate_copy_to_vram(struct kfd_node *node, struct svm_range *prange, 278 265 struct migrate_vma *migrate, struct dma_fence **mfence, 279 266 dma_addr_t *scratch, uint64_t ttm_res_offset) ··· 269 282 struct amdgpu_device *adev = node->adev; 270 283 struct device *dev = adev->dev; 271 284 struct amdgpu_res_cursor cursor; 272 - uint64_t mpages = 0; 285 + long mpages; 273 286 dma_addr_t *src; 274 287 uint64_t *dst; 275 288 uint64_t i, j; ··· 283 296 284 297 amdgpu_res_first(prange->ttm_res, ttm_res_offset, 285 298 npages << PAGE_SHIFT, &cursor); 299 + mpages = 0; 286 300 for (i = j = 0; (i < npages) && (mpages < migrate->cpages); i++) { 287 301 struct page *spage; 288 302 ··· 344 356 out_free_vram_pages: 345 357 if (r) { 346 358 pr_debug("failed %d to copy memory to vram\n", r); 347 - for (i = 0; i < npages && mpages; i++) { 359 + while (i-- && mpages) { 348 360 if (!dst[i]) 349 361 continue; 350 362 svm_migrate_put_vram_page(adev, dst[i]); 351 363 migrate->dst[i] = 0; 352 364 mpages--; 353 365 } 366 + mpages = r; 354 367 } 355 368 356 369 #ifdef DEBUG_FORCE_MIXED_DOMAINS ··· 369 380 } 370 381 #endif 371 382 372 - return r; 383 + return mpages; 373 384 } 374 385 375 386 static long ··· 384 395 struct dma_fence *mfence = NULL; 385 396 struct migrate_vma migrate = { 0 }; 386 397 unsigned long cpages = 0; 387 - unsigned long mpages = 0; 398 + long mpages = 0; 388 399 dma_addr_t *scratch; 389 400 void *buf; 390 401 int r = -ENOMEM; ··· 430 441 else 431 442 pr_debug("0x%lx pages collected\n", cpages); 432 443 433 - r = svm_migrate_copy_to_vram(node, prange, &migrate, &mfence, scratch, ttm_res_offset); 444 + mpages = svm_migrate_copy_to_vram(node, prange, &migrate, &mfence, scratch, ttm_res_offset); 434 445 migrate_vma_pages(&migrate); 435 446 436 447 svm_migrate_copy_done(adev, mfence); 437 448 migrate_vma_finalize(&migrate); 438 449 439 - mpages = cpages - svm_migrate_unsuccessful_pages(&migrate); 440 - pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n", 450 + if (mpages >= 0) 451 + pr_debug("migrated/collected/requested 0x%lx/0x%lx/0x%lx\n", 441 452 mpages, cpages, migrate.npages); 453 + else 454 + r = mpages; 442 455 443 456 svm_range_dma_unmap_dev(adev->dev, scratch, 0, npages); 444 457 ··· 450 459 start >> PAGE_SHIFT, end >> PAGE_SHIFT, 451 460 0, node->id, trigger, r); 452 461 out: 453 - if (!r && mpages) { 462 + if (!r && mpages > 0) { 454 463 pdd = svm_range_get_pdd_by_node(prange, node); 455 464 if (pdd) 456 465 WRITE_ONCE(pdd->page_in, pdd->page_in + mpages); 457 - 458 - return mpages; 459 466 } 460 - return r; 467 + 468 + return r ? r : mpages; 461 469 } 462 470 463 471 /** ··· 567 577 } 568 578 } 569 579 570 - static int 580 + static long 571 581 svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, 572 582 struct migrate_vma *migrate, struct dma_fence **mfence, 573 583 dma_addr_t *scratch, uint64_t npages) ··· 576 586 uint64_t *src; 577 587 dma_addr_t *dst; 578 588 struct page *dpage; 589 + long mpages; 579 590 uint64_t i = 0, j; 580 591 uint64_t addr; 581 592 int r = 0; ··· 589 598 src = (uint64_t *)(scratch + npages); 590 599 dst = scratch; 591 600 601 + mpages = 0; 592 602 for (i = 0, j = 0; i < npages; i++, addr += PAGE_SIZE) { 593 603 struct page *spage; 594 604 ··· 638 646 dst[i] >> PAGE_SHIFT, page_to_pfn(dpage)); 639 647 640 648 migrate->dst[i] = migrate_pfn(page_to_pfn(dpage)); 649 + mpages++; 641 650 j++; 642 651 } 643 652 ··· 648 655 out_oom: 649 656 if (r) { 650 657 pr_debug("failed %d copy to ram\n", r); 651 - while (i--) { 658 + while (i-- && mpages) { 659 + if (!migrate->dst[i]) 660 + continue; 652 661 svm_migrate_put_sys_page(dst[i]); 653 662 migrate->dst[i] = 0; 663 + mpages--; 654 664 } 665 + mpages = r; 655 666 } 656 667 657 - return r; 668 + return mpages; 658 669 } 659 670 660 671 /** ··· 685 688 { 686 689 struct kfd_process *p = container_of(prange->svms, struct kfd_process, svms); 687 690 uint64_t npages = (end - start) >> PAGE_SHIFT; 688 - unsigned long upages = npages; 689 691 unsigned long cpages = 0; 690 - unsigned long mpages = 0; 692 + long mpages = 0; 691 693 struct amdgpu_device *adev = node->adev; 692 694 struct kfd_process_device *pdd; 693 695 struct dma_fence *mfence = NULL; ··· 732 736 if (!cpages) { 733 737 pr_debug("failed collect migrate device pages [0x%lx 0x%lx]\n", 734 738 prange->start, prange->last); 735 - upages = svm_migrate_unsuccessful_pages(&migrate); 736 739 goto out_free; 737 740 } 738 741 if (cpages != npages) ··· 740 745 else 741 746 pr_debug("0x%lx pages collected\n", cpages); 742 747 743 - r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence, 748 + mpages = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence, 744 749 scratch, npages); 745 750 migrate_vma_pages(&migrate); 746 751 747 - upages = svm_migrate_unsuccessful_pages(&migrate); 748 - pr_debug("unsuccessful/cpages/npages 0x%lx/0x%lx/0x%lx\n", 749 - upages, cpages, migrate.npages); 752 + if (mpages >= 0) 753 + pr_debug("migrated/collected/requested 0x%lx/0x%lx/0x%lx\n", 754 + mpages, cpages, migrate.npages); 755 + else 756 + r = mpages; 750 757 751 758 svm_migrate_copy_done(adev, mfence); 752 759 migrate_vma_finalize(&migrate); ··· 761 764 start >> PAGE_SHIFT, end >> PAGE_SHIFT, 762 765 node->id, 0, trigger, r); 763 766 out: 764 - if (!r && cpages) { 765 - mpages = cpages - upages; 767 + if (!r && mpages > 0) { 766 768 pdd = svm_range_get_pdd_by_node(prange, node); 767 769 if (pdd) 768 770 WRITE_ONCE(pdd->page_out, pdd->page_out + mpages); ··· 844 848 } 845 849 846 850 if (r >= 0) { 851 + WARN_ONCE(prange->vram_pages < mpages, 852 + "Recorded vram pages(0x%llx) should not be less than migration pages(0x%lx).", 853 + prange->vram_pages, mpages); 847 854 prange->vram_pages -= mpages; 848 855 849 856 /* prange does not have vram page set its actual_loc to system
+8 -1
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 111 111 112 112 #define KFD_KERNEL_QUEUE_SIZE 2048 113 113 114 - #define KFD_UNMAP_LATENCY_MS (4000) 114 + /* KFD_UNMAP_LATENCY_MS is the timeout CP waiting for SDMA preemption. One XCC 115 + * can be associated to 2 SDMA engines. queue_preemption_timeout_ms is the time 116 + * driver waiting for CP returning the UNMAP_QUEUE fence. Thus the math is 117 + * queue_preemption_timeout_ms = sdma_preemption_time * 2 + cp workload 118 + * The format here makes CP workload 10% of total timeout 119 + */ 120 + #define KFD_UNMAP_LATENCY_MS \ 121 + ((queue_preemption_timeout_ms - queue_preemption_timeout_ms / 10) >> 1) 115 122 116 123 #define KFD_MAX_SDMA_QUEUES 128 117 124
+29 -7
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
··· 1189 1189 } 1190 1190 1191 1191 static uint64_t 1192 - svm_range_get_pte_flags(struct kfd_node *node, 1192 + svm_range_get_pte_flags(struct kfd_node *node, struct amdgpu_vm *vm, 1193 1193 struct svm_range *prange, int domain) 1194 1194 { 1195 1195 struct kfd_node *bo_node; ··· 1292 1292 AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC; 1293 1293 } 1294 1294 1295 - mapping_flags |= AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE; 1296 - 1297 - if (flags & KFD_IOCTL_SVM_FLAG_GPU_RO) 1298 - mapping_flags &= ~AMDGPU_VM_PAGE_WRITEABLE; 1299 1295 if (flags & KFD_IOCTL_SVM_FLAG_GPU_EXEC) 1300 1296 mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE; 1301 1297 ··· 1301 1305 if (gc_ip_version >= IP_VERSION(12, 0, 0)) 1302 1306 pte_flags |= AMDGPU_PTE_IS_PTE; 1303 1307 1304 - pte_flags |= amdgpu_gem_va_map_flags(node->adev, mapping_flags); 1308 + amdgpu_gmc_get_vm_pte(node->adev, vm, NULL, mapping_flags, &pte_flags); 1309 + pte_flags |= AMDGPU_PTE_READABLE; 1310 + if (!(flags & KFD_IOCTL_SVM_FLAG_GPU_RO)) 1311 + pte_flags |= AMDGPU_PTE_WRITEABLE; 1305 1312 return pte_flags; 1306 1313 } 1307 1314 ··· 1411 1412 pr_debug("Mapping range [0x%lx 0x%llx] on domain: %s\n", 1412 1413 last_start, prange->start + i, last_domain ? "GPU" : "CPU"); 1413 1414 1414 - pte_flags = svm_range_get_pte_flags(pdd->dev, prange, last_domain); 1415 + pte_flags = svm_range_get_pte_flags(pdd->dev, vm, prange, last_domain); 1415 1416 if (readonly) 1416 1417 pte_flags &= ~AMDGPU_PTE_WRITEABLE; 1417 1418 ··· 1713 1714 1714 1715 next = min(vma->vm_end, end); 1715 1716 npages = (next - addr) >> PAGE_SHIFT; 1717 + /* HMM requires at least READ permissions. If provided with PROT_NONE, 1718 + * unmap the memory. If it's not already mapped, this is a no-op 1719 + * If PROT_WRITE is provided without READ, warn first then unmap 1720 + */ 1721 + if (!(vma->vm_flags & VM_READ)) { 1722 + unsigned long e, s; 1723 + 1724 + svm_range_lock(prange); 1725 + if (vma->vm_flags & VM_WRITE) 1726 + pr_debug("VM_WRITE without VM_READ is not supported"); 1727 + s = max(start, prange->start); 1728 + e = min(end, prange->last); 1729 + if (e >= s) 1730 + r = svm_range_unmap_from_gpus(prange, s, e, 1731 + KFD_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU); 1732 + svm_range_unlock(prange); 1733 + /* If unmap returns non-zero, we'll bail on the next for loop 1734 + * iteration, so just leave r and continue 1735 + */ 1736 + addr = next; 1737 + continue; 1738 + } 1739 + 1716 1740 WRITE_ONCE(p->svms.faulting_task, current); 1717 1741 r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages, 1718 1742 readonly, owner, NULL,
+2
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
··· 530 530 sysfs_show_32bit_prop(buffer, offs, "sdma_fw_version", 531 531 dev->gpu->kfd->sdma_fw_version); 532 532 sysfs_show_64bit_prop(buffer, offs, "unique_id", 533 + dev->gpu->xcp ? 534 + dev->gpu->xcp->unique_id : 533 535 dev->gpu->adev->unique_id); 534 536 sysfs_show_32bit_prop(buffer, offs, "num_xcc", 535 537 NUM_XCC(dev->gpu->xcc_mask));
+47 -9
drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c
··· 46 46 47 47 static int8_t pdev_num; 48 48 static struct xcp_device *xcp_dev[MAX_XCP_PLATFORM_DEVICE]; 49 + static DEFINE_MUTEX(xcp_mutex); 49 50 50 51 int amdgpu_xcp_drm_dev_alloc(struct drm_device **ddev) 51 52 { 52 53 struct platform_device *pdev; 53 54 struct xcp_device *pxcp_dev; 54 55 char dev_name[20]; 55 - int ret; 56 + int ret, i; 57 + 58 + guard(mutex)(&xcp_mutex); 56 59 57 60 if (pdev_num >= MAX_XCP_PLATFORM_DEVICE) 58 61 return -ENODEV; 59 62 60 - snprintf(dev_name, sizeof(dev_name), "amdgpu_xcp_%d", pdev_num); 63 + for (i = 0; i < MAX_XCP_PLATFORM_DEVICE; i++) { 64 + if (!xcp_dev[i]) 65 + break; 66 + } 67 + 68 + if (i >= MAX_XCP_PLATFORM_DEVICE) 69 + return -ENODEV; 70 + 71 + snprintf(dev_name, sizeof(dev_name), "amdgpu_xcp_%d", i); 61 72 pdev = platform_device_register_simple(dev_name, -1, NULL, 0); 62 73 if (IS_ERR(pdev)) 63 74 return PTR_ERR(pdev); ··· 84 73 goto out_devres; 85 74 } 86 75 87 - xcp_dev[pdev_num] = pxcp_dev; 88 - xcp_dev[pdev_num]->pdev = pdev; 76 + xcp_dev[i] = pxcp_dev; 77 + xcp_dev[i]->pdev = pdev; 89 78 *ddev = &pxcp_dev->drm; 90 79 pdev_num++; 91 80 ··· 100 89 } 101 90 EXPORT_SYMBOL(amdgpu_xcp_drm_dev_alloc); 102 91 103 - void amdgpu_xcp_drv_release(void) 92 + static void free_xcp_dev(int8_t index) 104 93 { 105 - for (--pdev_num; pdev_num >= 0; --pdev_num) { 106 - struct platform_device *pdev = xcp_dev[pdev_num]->pdev; 94 + if ((index < MAX_XCP_PLATFORM_DEVICE) && (xcp_dev[index])) { 95 + struct platform_device *pdev = xcp_dev[index]->pdev; 107 96 108 97 devres_release_group(&pdev->dev, NULL); 109 98 platform_device_unregister(pdev); 110 - xcp_dev[pdev_num] = NULL; 99 + 100 + xcp_dev[index] = NULL; 101 + pdev_num--; 111 102 } 112 - pdev_num = 0; 103 + } 104 + 105 + void amdgpu_xcp_drm_dev_free(struct drm_device *ddev) 106 + { 107 + int8_t i; 108 + 109 + guard(mutex)(&xcp_mutex); 110 + 111 + for (i = 0; i < MAX_XCP_PLATFORM_DEVICE; i++) { 112 + if ((xcp_dev[i]) && (&xcp_dev[i]->drm == ddev)) { 113 + free_xcp_dev(i); 114 + break; 115 + } 116 + } 117 + } 118 + EXPORT_SYMBOL(amdgpu_xcp_drm_dev_free); 119 + 120 + void amdgpu_xcp_drv_release(void) 121 + { 122 + int8_t i; 123 + 124 + guard(mutex)(&xcp_mutex); 125 + 126 + for (i = 0; pdev_num && i < MAX_XCP_PLATFORM_DEVICE; i++) { 127 + free_xcp_dev(i); 128 + } 113 129 } 114 130 EXPORT_SYMBOL(amdgpu_xcp_drv_release); 115 131
+1
drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h
··· 25 25 #define _AMDGPU_XCP_DRV_H_ 26 26 27 27 int amdgpu_xcp_drm_dev_alloc(struct drm_device **ddev); 28 + void amdgpu_xcp_drm_dev_free(struct drm_device *ddev); 28 29 void amdgpu_xcp_drv_release(void); 29 30 #endif /* _AMDGPU_XCP_DRV_H_ */
+1
drivers/gpu/drm/amd/display/Makefile
··· 44 44 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/mpc 45 45 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/opp 46 46 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/pg 47 + subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/soc_and_ip_translator 47 48 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc 48 49 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync 49 50 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/color
+194 -119
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 * ··· 40 39 #include "dc/dc_stat.h" 41 40 #include "dc/dc_state.h" 42 41 #include "amdgpu_dm_trace.h" 43 - #include "dpcd_defs.h" 44 42 #include "link/protocols/link_dpcd.h" 45 43 #include "link_service_types.h" 46 44 #include "link/protocols/link_dp_capability.h" 47 45 #include "link/protocols/link_ddc.h" 48 46 49 - #include "vid.h" 50 47 #include "amdgpu.h" 51 48 #include "amdgpu_display.h" 52 49 #include "amdgpu_ucode.h" ··· 55 56 #include "amdgpu_dm_hdcp.h" 56 57 #include <drm/display/drm_hdcp_helper.h> 57 58 #include "amdgpu_dm_wb.h" 58 - #include "amdgpu_pm.h" 59 59 #include "amdgpu_atombios.h" 60 60 61 61 #include "amd_shared.h" ··· 80 82 #include <linux/component.h> 81 83 #include <linux/sort.h> 82 84 85 + #include <drm/drm_privacy_screen_consumer.h> 83 86 #include <drm/display/drm_dp_mst_helper.h> 84 87 #include <drm/display/drm_hdmi_helper.h> 85 88 #include <drm/drm_atomic.h> ··· 100 101 #include <acpi/video.h> 101 102 102 103 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" 103 - 104 - #include "dcn/dcn_1_0_offset.h" 105 - #include "dcn/dcn_1_0_sh_mask.h" 106 - #include "soc15_hw_ip.h" 107 - #include "soc15_common.h" 108 - #include "vega10_ip_offset.h" 109 - 110 - #include "gc/gc_11_0_0_offset.h" 111 - #include "gc/gc_11_0_0_sh_mask.h" 112 104 113 105 #include "modules/inc/mod_freesync.h" 114 106 #include "modules/power/power_helpers.h" ··· 531 541 amdgpu_crtc->crtc_id, amdgpu_crtc, vrr_active, (int)!e); 532 542 } 533 543 544 + static void dm_handle_vmin_vmax_update(struct work_struct *offload_work) 545 + { 546 + struct vupdate_offload_work *work = container_of(offload_work, struct vupdate_offload_work, work); 547 + struct amdgpu_device *adev = work->adev; 548 + struct dc_stream_state *stream = work->stream; 549 + struct dc_crtc_timing_adjust *adjust = work->adjust; 550 + 551 + mutex_lock(&adev->dm.dc_lock); 552 + dc_stream_adjust_vmin_vmax(adev->dm.dc, stream, adjust); 553 + mutex_unlock(&adev->dm.dc_lock); 554 + 555 + dc_stream_release(stream); 556 + kfree(work->adjust); 557 + kfree(work); 558 + } 559 + 560 + static void schedule_dc_vmin_vmax(struct amdgpu_device *adev, 561 + struct dc_stream_state *stream, 562 + struct dc_crtc_timing_adjust *adjust) 563 + { 564 + struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL); 565 + if (!offload_work) { 566 + drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n"); 567 + return; 568 + } 569 + 570 + struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_KERNEL); 571 + if (!adjust_copy) { 572 + drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n"); 573 + kfree(offload_work); 574 + return; 575 + } 576 + 577 + dc_stream_retain(stream); 578 + memcpy(adjust_copy, adjust, sizeof(*adjust_copy)); 579 + 580 + INIT_WORK(&offload_work->work, dm_handle_vmin_vmax_update); 581 + offload_work->adev = adev; 582 + offload_work->stream = stream; 583 + offload_work->adjust = adjust_copy; 584 + 585 + queue_work(system_wq, &offload_work->work); 586 + } 587 + 534 588 static void dm_vupdate_high_irq(void *interrupt_params) 535 589 { 536 590 struct common_irq_params *irq_params = interrupt_params; ··· 612 578 * page-flip completion events that have been queued to us 613 579 * if a pageflip happened inside front-porch. 614 580 */ 615 - if (vrr_active) { 581 + if (vrr_active && acrtc->dm_irq_params.stream) { 582 + bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; 583 + bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; 584 + bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state 585 + == VRR_STATE_ACTIVE_VARIABLE; 586 + 616 587 amdgpu_dm_crtc_handle_vblank(acrtc); 617 588 618 589 /* BTR processing for pre-DCE12 ASICs */ 619 - if (acrtc->dm_irq_params.stream && 620 - adev->family < AMDGPU_FAMILY_AI) { 590 + if (adev->family < AMDGPU_FAMILY_AI) { 621 591 spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); 622 592 mod_freesync_handle_v_update( 623 593 adev->dm.freesync_module, 624 594 acrtc->dm_irq_params.stream, 625 595 &acrtc->dm_irq_params.vrr_params); 626 596 627 - dc_stream_adjust_vmin_vmax( 628 - adev->dm.dc, 629 - acrtc->dm_irq_params.stream, 630 - &acrtc->dm_irq_params.vrr_params.adjust); 597 + if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { 598 + schedule_dc_vmin_vmax(adev, 599 + acrtc->dm_irq_params.stream, 600 + &acrtc->dm_irq_params.vrr_params.adjust); 601 + } 631 602 spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); 632 603 } 633 604 } ··· 715 676 spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); 716 677 717 678 if (acrtc->dm_irq_params.stream && 718 - acrtc->dm_irq_params.vrr_params.supported && 719 - acrtc->dm_irq_params.freesync_config.state == 720 - VRR_STATE_ACTIVE_VARIABLE) { 679 + acrtc->dm_irq_params.vrr_params.supported) { 680 + bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; 681 + bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; 682 + bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state == VRR_STATE_ACTIVE_VARIABLE; 683 + 721 684 mod_freesync_handle_v_update(adev->dm.freesync_module, 722 685 acrtc->dm_irq_params.stream, 723 686 &acrtc->dm_irq_params.vrr_params); 724 687 725 - dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream, 726 - &acrtc->dm_irq_params.vrr_params.adjust); 688 + /* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */ 689 + if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { 690 + schedule_dc_vmin_vmax(adev, acrtc->dm_irq_params.stream, 691 + &acrtc->dm_irq_params.vrr_params.adjust); 692 + } 727 693 } 728 694 729 695 /* ··· 4817 4773 uint32_t *user_brightness) 4818 4774 { 4819 4775 u32 brightness = scale_input_to_fw(min, max, *user_brightness); 4820 - u8 prev_signal = 0, prev_lum = 0; 4821 - int i = 0; 4776 + u8 lower_signal, upper_signal, upper_lum, lower_lum, lum; 4777 + int left, right; 4822 4778 4823 4779 if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE) 4824 4780 return; ··· 4826 4782 if (!caps->data_points) 4827 4783 return; 4828 4784 4829 - /* choose start to run less interpolation steps */ 4830 - if (caps->luminance_data[caps->data_points/2].input_signal > brightness) 4831 - i = caps->data_points/2; 4832 - do { 4833 - u8 signal = caps->luminance_data[i].input_signal; 4834 - u8 lum = caps->luminance_data[i].luminance; 4785 + left = 0; 4786 + right = caps->data_points - 1; 4787 + while (left <= right) { 4788 + int mid = left + (right - left) / 2; 4789 + u8 signal = caps->luminance_data[mid].input_signal; 4835 4790 4836 - /* 4837 - * brightness == signal: luminance is percent numerator 4838 - * brightness < signal: interpolate between previous and current luminance numerator 4839 - * brightness > signal: find next data point 4840 - */ 4841 - if (brightness > signal) { 4842 - prev_signal = signal; 4843 - prev_lum = lum; 4844 - i++; 4845 - continue; 4791 + /* Exact match found */ 4792 + if (signal == brightness) { 4793 + lum = caps->luminance_data[mid].luminance; 4794 + goto scale; 4846 4795 } 4847 - if (brightness < signal) 4848 - lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) * 4849 - (brightness - prev_signal), 4850 - signal - prev_signal); 4851 - *user_brightness = scale_fw_to_input(min, max, 4852 - DIV_ROUND_CLOSEST(lum * brightness, 101)); 4853 - return; 4854 - } while (i < caps->data_points); 4796 + 4797 + if (signal < brightness) 4798 + left = mid + 1; 4799 + else 4800 + right = mid - 1; 4801 + } 4802 + 4803 + /* verify bound */ 4804 + if (left >= caps->data_points) 4805 + left = caps->data_points - 1; 4806 + 4807 + /* At this point, left > right */ 4808 + lower_signal = caps->luminance_data[right].input_signal; 4809 + upper_signal = caps->luminance_data[left].input_signal; 4810 + lower_lum = caps->luminance_data[right].luminance; 4811 + upper_lum = caps->luminance_data[left].luminance; 4812 + 4813 + /* interpolate */ 4814 + if (right == left || !lower_lum) 4815 + lum = upper_lum; 4816 + else 4817 + lum = lower_lum + DIV_ROUND_CLOSEST((upper_lum - lower_lum) * 4818 + (brightness - lower_signal), 4819 + upper_signal - lower_signal); 4820 + scale: 4821 + *user_brightness = scale_fw_to_input(min, max, 4822 + DIV_ROUND_CLOSEST(lum * brightness, 101)); 4855 4823 } 4856 4824 4857 4825 static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps, ··· 4982 4926 4983 4927 if (caps.aux_support) { 4984 4928 u32 avg, peak; 4985 - bool rc; 4986 4929 4987 - rc = dc_link_get_backlight_level_nits(link, &avg, &peak); 4988 - if (!rc) 4930 + if (!dc_link_get_backlight_level_nits(link, &avg, &peak)) 4989 4931 return dm->brightness[bl_idx]; 4990 4932 return convert_brightness_to_user(&caps, avg); 4991 4933 } ··· 6444 6390 (struct drm_connector *)connector, 6445 6391 mode_in); 6446 6392 if (err < 0) 6447 - drm_warn_once(connector->dev, "Failed to setup avi infoframe on connector %s: %zd \n", connector->name, err); 6393 + drm_warn_once(connector->dev, "Failed to setup avi infoframe on connector %s: %zd\n", 6394 + connector->name, err); 6448 6395 timing_out->vic = avi_frame.video_code; 6449 6396 err = drm_hdmi_vendor_infoframe_from_display_mode(&hv_frame, 6450 6397 (struct drm_connector *)connector, 6451 6398 mode_in); 6452 6399 if (err < 0) 6453 - drm_warn_once(connector->dev, "Failed to setup vendor infoframe on connector %s: %zd \n", connector->name, err); 6400 + drm_warn_once(connector->dev, "Failed to setup vendor infoframe on connector %s: %zd\n", 6401 + connector->name, err); 6454 6402 timing_out->hdmi_vic = hv_frame.vic; 6455 6403 } 6456 6404 ··· 7848 7792 struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn); 7849 7793 int ret; 7850 7794 7795 + if (WARN_ON(unlikely(!old_con_state || !new_con_state))) 7796 + return -EINVAL; 7797 + 7851 7798 trace_amdgpu_dm_connector_atomic_check(new_con_state); 7852 7799 7853 7800 if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { ··· 7861 7802 7862 7803 if (!crtc) 7863 7804 return 0; 7805 + 7806 + if (new_con_state->privacy_screen_sw_state != old_con_state->privacy_screen_sw_state) { 7807 + new_crtc_state = drm_atomic_get_crtc_state(state, crtc); 7808 + if (IS_ERR(new_crtc_state)) 7809 + return PTR_ERR(new_crtc_state); 7810 + 7811 + new_crtc_state->mode_changed = true; 7812 + } 7864 7813 7865 7814 if (new_con_state->colorspace != old_con_state->colorspace) { 7866 7815 new_crtc_state = drm_atomic_get_crtc_state(state, crtc); ··· 8445 8378 drm_add_modes_noedid(connector, 1920, 1080); 8446 8379 } else { 8447 8380 amdgpu_dm_connector_ddc_get_modes(connector, drm_edid); 8448 - if (encoder && (connector->connector_type != DRM_MODE_CONNECTOR_eDP) && 8449 - (connector->connector_type != DRM_MODE_CONNECTOR_LVDS)) 8381 + if (encoder) 8450 8382 amdgpu_dm_connector_add_common_modes(encoder, connector); 8451 8383 amdgpu_dm_connector_add_freesync_modes(connector, drm_edid); 8452 8384 } ··· 8563 8497 8564 8498 if (adev->dm.hdcp_workqueue) 8565 8499 drm_connector_attach_content_protection_property(&aconnector->base, true); 8500 + } 8501 + 8502 + if (connector_type == DRM_MODE_CONNECTOR_eDP) { 8503 + struct drm_privacy_screen *privacy_screen; 8504 + 8505 + privacy_screen = drm_privacy_screen_get(adev_to_drm(adev)->dev, NULL); 8506 + if (!IS_ERR(privacy_screen)) { 8507 + drm_connector_attach_privacy_screen_provider(&aconnector->base, 8508 + privacy_screen); 8509 + } else if (PTR_ERR(privacy_screen) != -ENODEV) { 8510 + drm_warn(adev_to_drm(adev), "Error getting privacy-screen\n"); 8511 + } 8566 8512 } 8567 8513 } 8568 8514 ··· 10164 10086 drm_writeback_queue_job(wb_conn, new_con_state); 10165 10087 } 10166 10088 10167 - /** 10168 - * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation. 10169 - * @state: The atomic state to commit 10170 - * 10171 - * This will tell DC to commit the constructed DC state from atomic_check, 10172 - * programming the hardware. Any failures here implies a hardware failure, since 10173 - * atomic check should have filtered anything non-kosher. 10174 - */ 10175 - static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) 10089 + static void amdgpu_dm_update_hdcp(struct drm_atomic_state *state) 10176 10090 { 10177 - struct drm_device *dev = state->dev; 10178 - struct amdgpu_device *adev = drm_to_adev(dev); 10179 - struct amdgpu_display_manager *dm = &adev->dm; 10180 - struct dm_atomic_state *dm_state; 10181 - struct dc_state *dc_state = NULL; 10182 - u32 i, j; 10183 - struct drm_crtc *crtc; 10184 - struct drm_crtc_state *old_crtc_state, *new_crtc_state; 10185 - unsigned long flags; 10186 - bool wait_for_vblank = true; 10187 - struct drm_connector *connector; 10188 10091 struct drm_connector_state *old_con_state, *new_con_state; 10189 - struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; 10190 - int crtc_disable_count = 0; 10092 + struct drm_device *dev = state->dev; 10093 + struct drm_connector *connector; 10094 + struct amdgpu_device *adev = drm_to_adev(dev); 10095 + int i; 10191 10096 10192 - trace_amdgpu_dm_atomic_commit_tail_begin(state); 10193 - 10194 - drm_atomic_helper_update_legacy_modeset_state(dev, state); 10195 - drm_dp_mst_atomic_wait_for_dependencies(state); 10196 - 10197 - dm_state = dm_atomic_get_new_state(state); 10198 - if (dm_state && dm_state->context) { 10199 - dc_state = dm_state->context; 10200 - amdgpu_dm_commit_streams(state, dc_state); 10201 - } 10097 + if (!adev->dm.hdcp_workqueue) 10098 + return; 10202 10099 10203 10100 for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { 10204 10101 struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); 10205 10102 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 10103 + struct drm_crtc_state *old_crtc_state, *new_crtc_state; 10104 + struct dm_crtc_state *dm_new_crtc_state; 10206 10105 struct amdgpu_dm_connector *aconnector; 10207 10106 10208 - if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) 10107 + if (!connector || connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) 10209 10108 continue; 10210 10109 10211 10110 aconnector = to_amdgpu_dm_connector(connector); 10212 10111 10213 - if (!adev->dm.hdcp_workqueue) 10214 - continue; 10112 + drm_dbg(dev, "[HDCP_DM] -------------- i : %x ----------\n", i); 10215 10113 10216 - pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i); 10217 - 10218 - if (!connector) 10219 - continue; 10220 - 10221 - pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", 10114 + drm_dbg(dev, "[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", 10222 10115 connector->index, connector->status, connector->dpms); 10223 - pr_debug("[HDCP_DM] state protection old: %x new: %x\n", 10116 + drm_dbg(dev, "[HDCP_DM] state protection old: %x new: %x\n", 10224 10117 old_con_state->content_protection, new_con_state->content_protection); 10225 10118 10226 10119 if (aconnector->dc_sink) { 10227 10120 if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL && 10228 10121 aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) { 10229 - pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n", 10122 + drm_dbg(dev, "[HDCP_DM] pipe_ctx dispname=%s\n", 10230 10123 aconnector->dc_sink->edid_caps.display_name); 10231 10124 } 10232 10125 } ··· 10211 10162 } 10212 10163 10213 10164 if (old_crtc_state) 10214 - pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", 10165 + drm_dbg(dev, "old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", 10215 10166 old_crtc_state->enable, 10216 10167 old_crtc_state->active, 10217 10168 old_crtc_state->mode_changed, ··· 10219 10170 old_crtc_state->connectors_changed); 10220 10171 10221 10172 if (new_crtc_state) 10222 - pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", 10173 + drm_dbg(dev, "NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", 10223 10174 new_crtc_state->enable, 10224 10175 new_crtc_state->active, 10225 10176 new_crtc_state->mode_changed, 10226 10177 new_crtc_state->active_changed, 10227 10178 new_crtc_state->connectors_changed); 10228 - } 10229 10179 10230 - for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { 10231 - struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); 10232 - struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 10233 - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 10234 - 10235 - if (!adev->dm.hdcp_workqueue) 10236 - continue; 10237 - 10238 - new_crtc_state = NULL; 10239 - old_crtc_state = NULL; 10240 - 10241 - if (acrtc) { 10242 - new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); 10243 - old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); 10244 - } 10245 10180 10246 10181 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 10247 10182 ··· 10269 10236 new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) 10270 10237 enable_encryption = true; 10271 10238 10272 - drm_info(adev_to_drm(adev), "[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption); 10239 + drm_info(dev, "[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption); 10273 10240 10274 10241 if (aconnector->dc_link) 10275 10242 hdcp_update_display( ··· 10277 10244 new_con_state->hdcp_content_type, enable_encryption); 10278 10245 } 10279 10246 } 10247 + } 10248 + 10249 + /** 10250 + * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation. 10251 + * @state: The atomic state to commit 10252 + * 10253 + * This will tell DC to commit the constructed DC state from atomic_check, 10254 + * programming the hardware. Any failures here implies a hardware failure, since 10255 + * atomic check should have filtered anything non-kosher. 10256 + */ 10257 + static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) 10258 + { 10259 + struct drm_device *dev = state->dev; 10260 + struct amdgpu_device *adev = drm_to_adev(dev); 10261 + struct amdgpu_display_manager *dm = &adev->dm; 10262 + struct dm_atomic_state *dm_state; 10263 + struct dc_state *dc_state = NULL; 10264 + u32 i, j; 10265 + struct drm_crtc *crtc; 10266 + struct drm_crtc_state *old_crtc_state, *new_crtc_state; 10267 + unsigned long flags; 10268 + bool wait_for_vblank = true; 10269 + struct drm_connector *connector; 10270 + struct drm_connector_state *old_con_state = NULL, *new_con_state = NULL; 10271 + struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; 10272 + int crtc_disable_count = 0; 10273 + 10274 + trace_amdgpu_dm_atomic_commit_tail_begin(state); 10275 + 10276 + drm_atomic_helper_update_legacy_modeset_state(dev, state); 10277 + drm_dp_mst_atomic_wait_for_dependencies(state); 10278 + 10279 + dm_state = dm_atomic_get_new_state(state); 10280 + if (dm_state && dm_state->context) { 10281 + dc_state = dm_state->context; 10282 + amdgpu_dm_commit_streams(state, dc_state); 10283 + } 10284 + 10285 + amdgpu_dm_update_hdcp(state); 10280 10286 10281 10287 /* Handle connector state changes */ 10282 10288 for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { ··· 10418 10346 &stream_update); 10419 10347 mutex_unlock(&dm->dc_lock); 10420 10348 kfree(dummy_updates); 10349 + 10350 + drm_connector_update_privacy_screen(new_con_state); 10421 10351 } 10422 10352 10423 10353 /** ··· 10471 10397 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 10472 10398 if (amdgpu_dm_crc_window_is_activated(crtc)) { 10473 10399 uint8_t cnt; 10400 + 10474 10401 spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); 10475 10402 for (cnt = 0; cnt < MAX_CRC_WINDOW_NUM; cnt++) { 10476 10403 if (acrtc->dm_irq_params.window_param[cnt].enable) {
+18
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright (C) 2015-2020 Advanced Micro Devices, Inc. All rights reserved. 3 4 * ··· 151 150 struct amdgpu_display_manager *dm; 152 151 bool enable; 153 152 bool running; 153 + }; 154 + 155 + /** 156 + * struct vupdate_offload_work - Work data for offloading task from vupdate handler 157 + * @work: Kernel work data for the work event 158 + * @adev: amdgpu_device back pointer 159 + * @stream: DC stream associated with the crtc 160 + * @adjust: DC CRTC timing adjust to be applied to the crtc 161 + */ 162 + struct vupdate_offload_work { 163 + struct work_struct work; 164 + struct amdgpu_device *adev; 165 + struct dc_stream_state *stream; 166 + struct dc_crtc_timing_adjust *adjust; 154 167 }; 155 168 156 169 #define MAX_LUMINANCE_DATA_POINTS 99 ··· 767 752 uint32_t mst_local_bw; 768 753 uint16_t vc_full_pbn; 769 754 struct mutex handle_mst_msg_ready; 755 + 756 + /* branch device specific data */ 757 + uint32_t branch_ieee_oui; 770 758 771 759 /* TODO see if we can merge with ddc_bus or make a dm_connector */ 772 760 struct amdgpu_i2c_adapter *i2c;
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2018 Advanced Micro Devices, Inc. 3 4 * ··· 28 27 #include "amdgpu_dm.h" 29 28 #include "dc.h" 30 29 #include "modules/color/color_gamma.h" 31 - #include "basics/conversion.h" 32 30 33 31 /** 34 32 * DOC: overview
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2019 Advanced Micro Devices, Inc. 3 4 *
+19
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
··· 299 299 irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id); 300 300 301 301 if (enable) { 302 + struct dc *dc = adev->dm.dc; 303 + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc); 304 + struct psr_settings *psr = &acrtc_state->stream->link->psr_settings; 305 + struct replay_settings *pr = &acrtc_state->stream->link->replay_settings; 306 + bool sr_supported = (psr->psr_version != DC_PSR_VERSION_UNSUPPORTED) || 307 + pr->config.replay_supported; 308 + 309 + /* 310 + * IPS & self-refresh feature can cause vblank counter resets between 311 + * vblank disable and enable. 312 + * It may cause system stuck due to waiting for the vblank counter. 313 + * Call this function to estimate missed vblanks by using timestamps and 314 + * update the vblank counter in DRM. 315 + */ 316 + if (dc->caps.ips_support && 317 + dc->config.disable_ips != DMUB_IPS_DISABLE_ALL && 318 + sr_supported && vblank->config.disable_immediate) 319 + drm_crtc_vblank_restore(crtc); 320 + 302 321 /* vblank irq on -> Only need vupdate irq in vrr mode */ 303 322 if (amdgpu_dm_crtc_vrr_active(acrtc_state)) 304 323 rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true);
+34 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2018 Advanced Micro Devices, Inc. 3 4 * ··· 3107 3106 } 3108 3107 3109 3108 /* 3109 + * Start / Stop capture Replay residency 3110 + */ 3111 + static int replay_set_residency(void *data, u64 val) 3112 + { 3113 + struct amdgpu_dm_connector *connector = data; 3114 + struct dc_link *link = connector->dc_link; 3115 + bool is_start = (val != 0); 3116 + u32 residency = 0; 3117 + 3118 + link->dc->link_srv->edp_replay_residency(link, &residency, is_start, PR_RESIDENCY_MODE_PHY); 3119 + return 0; 3120 + } 3121 + 3122 + /* 3123 + * Read Replay residency 3124 + */ 3125 + static int replay_get_residency(void *data, u64 *val) 3126 + { 3127 + struct amdgpu_dm_connector *connector = data; 3128 + struct dc_link *link = connector->dc_link; 3129 + u32 residency = 0; 3130 + 3131 + link->dc->link_srv->edp_replay_residency(link, &residency, false, PR_RESIDENCY_MODE_PHY); 3132 + *val = (u64)residency; 3133 + 3134 + return 0; 3135 + } 3136 + 3137 + /* 3110 3138 * Read PSR state 3111 3139 */ 3112 3140 static int psr_get(void *data, u64 *val) ··· 3354 3324 dmcub_trace_event_state_set, "%llu\n"); 3355 3325 3356 3326 DEFINE_DEBUGFS_ATTRIBUTE(replay_state_fops, replay_get_state, NULL, "%llu\n"); 3357 - 3327 + DEFINE_DEBUGFS_ATTRIBUTE(replay_residency_fops, replay_get_residency, replay_set_residency, 3328 + "%llu\n"); 3358 3329 DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n"); 3359 3330 DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL, 3360 3331 "%llu\n"); ··· 3533 3502 debugfs_create_file("replay_capability", 0444, dir, connector, 3534 3503 &replay_capability_fops); 3535 3504 debugfs_create_file("replay_state", 0444, dir, connector, &replay_state_fops); 3505 + debugfs_create_file_unsafe("replay_residency", 0444, dir, 3506 + connector, &replay_residency_fops); 3536 3507 debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops); 3537 3508 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops); 3538 3509 debugfs_create_file_unsafe("psr_residency", 0444, dir,
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2018 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2019 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2019 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2020 Advanced Micro Devices, Inc. 3 4 *
+45 -5
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 4 * ··· 326 325 aconnector->mst_downstream_port_present = ds_port_present; 327 326 DRM_INFO("Downstream port present %d, type %d\n", 328 327 ds_port_present.fields.PORT_PRESENT, ds_port_present.fields.PORT_TYPE); 328 + 329 + return true; 330 + } 331 + 332 + static bool retrieve_branch_specific_data(struct amdgpu_dm_connector *aconnector) 333 + { 334 + struct drm_connector *connector = &aconnector->base; 335 + struct drm_dp_mst_port *port = aconnector->mst_output_port; 336 + struct drm_dp_mst_port *port_parent; 337 + struct drm_dp_aux *immediate_upstream_aux; 338 + struct drm_dp_desc branch_desc; 339 + 340 + if (!port->parent) 341 + return false; 342 + 343 + port_parent = port->parent->port_parent; 344 + 345 + immediate_upstream_aux = port_parent ? &port_parent->aux : port->mgr->aux; 346 + 347 + if (drm_dp_read_desc(immediate_upstream_aux, &branch_desc, true)) 348 + return false; 349 + 350 + aconnector->branch_ieee_oui = (branch_desc.ident.oui[0] << 16) + 351 + (branch_desc.ident.oui[1] << 8) + 352 + (branch_desc.ident.oui[2]); 353 + 354 + drm_dbg_dp(port->aux.drm_dev, "MST branch oui 0x%x detected at %s\n", 355 + aconnector->branch_ieee_oui, connector->name); 329 356 330 357 return true; 331 358 } ··· 696 667 drm_connector_attach_colorspace_property(connector); 697 668 698 669 drm_connector_set_path_property(connector, pathprop); 670 + 671 + if (!retrieve_branch_specific_data(aconnector)) 672 + aconnector->branch_ieee_oui = 0; 699 673 700 674 /* 701 675 * Initialize connector state before adding the connectror to drm and ··· 1794 1762 union lane_count_set lane_count; 1795 1763 u8 dp_link_encoding; 1796 1764 u8 link_bw_set = 0; 1765 + u8 data[16] = {0}; 1797 1766 1798 1767 *cur_link_bw = 0; 1799 1768 1800 - if (drm_dp_dpcd_read(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, &dp_link_encoding, 1) != 1 || 1801 - drm_dp_dpcd_read(aux, DP_LANE_COUNT_SET, &lane_count.raw, 1) != 1 || 1802 - drm_dp_dpcd_read(aux, DP_LINK_BW_SET, &link_bw_set, 1) != 1) 1769 + if (drm_dp_dpcd_read(aux, DP_LINK_BW_SET, data, 16) != 16) 1803 1770 return false; 1771 + 1772 + dp_link_encoding = data[DP_MAIN_LINK_CHANNEL_CODING_SET - DP_LINK_BW_SET]; 1773 + link_bw_set = data[DP_LINK_BW_SET - DP_LINK_BW_SET]; 1774 + lane_count.raw = data[DP_LANE_COUNT_SET - DP_LINK_BW_SET]; 1775 + 1776 + drm_dbg_dp(aux->drm_dev, "MST_DSC downlink setting: %d, 0x%x x %d\n", 1777 + dp_link_encoding, link_bw_set, lane_count.bits.LANE_COUNT_SET); 1804 1778 1805 1779 switch (dp_link_encoding) { 1806 1780 case DP_8b_10b_ENCODING: ··· 1904 1866 end_link_bw = aconnector->mst_local_bw; 1905 1867 } 1906 1868 1907 - if (end_link_bw > 0 && stream_kbps > end_link_bw) { 1908 - DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link." 1869 + if (end_link_bw > 0 && 1870 + stream_kbps > end_link_bw && 1871 + aconnector->branch_ieee_oui != DP_BRANCH_DEVICE_ID_90CC24) { 1872 + DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link. " 1909 1873 "Mode required bw can't fit into last link\n"); 1910 1874 return DC_FAIL_BANDWIDTH_VALIDATE; 1911 1875 }
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2018 Advanced Micro Devices, Inc. 3 4 *
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2021 Advanced Micro Devices, Inc. 3 4 * ··· 27 26 #include "amdgpu_dm_psr.h" 28 27 #include "dc_dmub_srv.h" 29 28 #include "dc.h" 30 - #include "dm_helpers.h" 31 29 #include "amdgpu_dm.h" 32 30 #include "modules/power/power_helpers.h" 33 31
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2021 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c
··· 1 + // SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2023 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h
··· 1 + /* SPDX-License-Identifier: MIT */ 1 2 /* 2 3 * Copyright 2021 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
··· 1 + //SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2015 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
··· 1 + //SPDX-License-Identifier: MIT 1 2 /* 2 3 * Copyright 2018 Advanced Micro Devices, Inc. 3 4 *
+1
drivers/gpu/drm/amd/display/dc/Makefile
··· 37 37 DC_LIBS += dcn31 38 38 DC_LIBS += dml 39 39 DC_LIBS += dml2 40 + DC_LIBS += soc_and_ip_translator 40 41 endif 41 42 42 43 DC_LIBS += dce120
+1 -1
drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c
··· 1136 1136 } 1137 1137 } 1138 1138 } 1139 - data->total_dmifmc_urgent_trips = bw_ceil2(bw_div(data->total_requests_for_adjusted_dmif_size, (bw_add(dceip->dmif_request_buffer_size, bw_int_to_fixed(vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel * data->number_of_dram_channels)))), bw_int_to_fixed(1)); 1139 + data->total_dmifmc_urgent_trips = bw_ceil2(bw_div(data->total_requests_for_adjusted_dmif_size, (bw_add(dceip->dmif_request_buffer_size, bw_int_to_fixed((uint64_t)vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel * data->number_of_dram_channels)))), bw_int_to_fixed(1)); 1140 1140 data->total_dmifmc_urgent_latency = bw_mul(vbios->dmifmc_urgent_latency, data->total_dmifmc_urgent_trips); 1141 1141 data->total_display_reads_required_data = bw_int_to_fixed(0); 1142 1142 data->total_display_reads_required_dram_access_data = bw_int_to_fixed(0);
+1 -1
drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
··· 284 284 dc_fixpt_mul( 285 285 square, 286 286 res), 287 - n * (n - 1))); 287 + (long long)n * (n - 1))); 288 288 289 289 n -= 2; 290 290 } while (n != 0);
+3 -3
drivers/gpu/drm/amd/display/dc/basics/vector.c
··· 170 170 memmove( 171 171 vector->container + (index * vector->struct_size), 172 172 vector->container + ((index + 1) * vector->struct_size), 173 - (vector->count - index - 1) * vector->struct_size); 173 + (size_t)(vector->count - index - 1) * vector->struct_size); 174 174 vector->count -= 1; 175 175 176 176 return true; ··· 219 219 memmove( 220 220 insert_address + vector->struct_size, 221 221 insert_address, 222 - vector->struct_size * (vector->count - position)); 222 + (size_t)vector->struct_size * (vector->count - position)); 223 223 224 224 memmove( 225 225 insert_address, ··· 271 271 272 272 /* copy vector's data */ 273 273 memmove(vec_cloned->container, vector->container, 274 - vec_cloned->struct_size * vec_cloned->capacity); 274 + (size_t)vec_cloned->struct_size * vec_cloned->capacity); 275 275 276 276 return vec_cloned; 277 277 }
+1 -4
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
··· 174 174 return object_id; 175 175 } 176 176 177 - if (tbl->ucNumberOfObjects <= i) { 178 - dm_error("Can't find connector id %d in connector table of size %d.\n", 179 - i, tbl->ucNumberOfObjects); 177 + if (tbl->ucNumberOfObjects <= i) 180 178 return object_id; 181 - } 182 179 183 180 id = le16_to_cpu(tbl->asObjects[i].usObjectID); 184 181 object_id = object_id_from_bios_object_id(id);
+1 -1
drivers/gpu/drm/amd/display/dc/bios/command_table.c
··· 993 993 allocation.sPCLKInput.usFbDiv = 994 994 cpu_to_le16((uint16_t)bp_params->feedback_divider); 995 995 allocation.sPCLKInput.ucFracFbDiv = 996 - (uint8_t)bp_params->fractional_feedback_divider; 996 + (uint8_t)(bp_params->fractional_feedback_divider / 100000); 997 997 allocation.sPCLKInput.ucPostDiv = 998 998 (uint8_t)bp_params->pixel_clock_post_divider; 999 999
+5 -9
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
··· 72 72 /* ClocksStateLow */ 73 73 { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, 74 74 /* ClocksStateNominal */ 75 - { .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, 75 + { .display_clk_khz = 625000, .pixel_clk_khz = 400000 }, 76 76 /* ClocksStatePerformance */ 77 - { .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; 77 + { .display_clk_khz = 625000, .pixel_clk_khz = 400000 } }; 78 78 79 79 int dentist_get_divider_from_did(int did) 80 80 { ··· 391 391 { 392 392 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 393 393 394 - pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); 395 - 396 394 dce110_fill_display_configs(context, pp_display_cfg); 397 395 398 396 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) ··· 403 405 { 404 406 struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); 405 407 struct dm_pp_power_level_change_request level_change_req; 406 - int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 407 - 408 - /*TODO: W/A for dal3 linux, investigate why this works */ 409 - if (!clk_mgr_dce->dfs_bypass_active) 410 - patched_disp_clk = patched_disp_clk * 115 / 100; 408 + const int max_disp_clk = 409 + clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz; 410 + int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); 411 411 412 412 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); 413 413 /* get max clock state from PPLIB */
+23 -17
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
··· 120 120 const struct dc_state *context, 121 121 struct dm_pp_display_configuration *pp_display_cfg) 122 122 { 123 + struct dc *dc = context->clk_mgr->ctx->dc; 123 124 int j; 124 125 int num_cfgs = 0; 126 + 127 + pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); 128 + pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; 129 + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 130 + pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; 125 131 126 132 for (j = 0; j < context->stream_count; j++) { 127 133 int k; ··· 170 164 cfg->v_refresh /= stream->timing.h_total; 171 165 cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) 172 166 / stream->timing.v_total; 167 + 168 + /* Find first CRTC index and calculate its line time. 169 + * This is necessary for DPM on SI GPUs. 170 + */ 171 + if (cfg->pipe_idx < pp_display_cfg->crtc_index) { 172 + const struct dc_crtc_timing *timing = 173 + &context->streams[0]->timing; 174 + 175 + pp_display_cfg->crtc_index = cfg->pipe_idx; 176 + pp_display_cfg->line_time_in_us = 177 + timing->h_total * 10000 / timing->pix_clk_100hz; 178 + } 179 + } 180 + 181 + if (!num_cfgs) { 182 + pp_display_cfg->crtc_index = 0; 183 + pp_display_cfg->line_time_in_us = 0; 173 184 } 174 185 175 186 pp_display_cfg->display_count = num_cfgs; ··· 246 223 pp_display_cfg->min_engine_clock_deep_sleep_khz 247 224 = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; 248 225 249 - pp_display_cfg->avail_mclk_switch_time_us = 250 - dce110_get_min_vblank_time_us(context); 251 - /* TODO: dce11.2*/ 252 - pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 253 - 254 - pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; 255 - 256 226 dce110_fill_display_configs(context, pp_display_cfg); 257 - 258 - /* TODO: is this still applicable?*/ 259 - if (pp_display_cfg->display_count == 1) { 260 - const struct dc_crtc_timing *timing = 261 - &context->streams[0]->timing; 262 - 263 - pp_display_cfg->crtc_index = 264 - pp_display_cfg->disp_configs[0].pipe_idx; 265 - pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz; 266 - } 267 227 268 228 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) 269 229 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
+9 -22
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c
··· 83 83 static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base) 84 84 { 85 85 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 86 - int dprefclk_wdivider; 87 - int dp_ref_clk_khz; 88 - int target_div; 86 + struct dc_context *ctx = clk_mgr_base->ctx; 87 + int dp_ref_clk_khz = 0; 89 88 90 - /* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ 91 - 92 - /* Read the mmDENTIST_DISPCLK_CNTL to get the currently 93 - * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ 94 - REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); 95 - 96 - /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ 97 - target_div = dentist_get_divider_from_did(dprefclk_wdivider); 98 - 99 - /* Calculate the current DFS clock, in kHz.*/ 100 - dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR 101 - * clk_mgr->base.dentist_vco_freq_khz) / target_div; 89 + if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev)) 90 + dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; 91 + else 92 + dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz; 102 93 103 94 return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz); 104 95 } ··· 99 108 struct dc_state *context) 100 109 { 101 110 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 102 - 103 - pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); 104 111 105 112 dce110_fill_display_configs(context, pp_display_cfg); 106 113 ··· 112 123 { 113 124 struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); 114 125 struct dm_pp_power_level_change_request level_change_req; 115 - int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; 116 - 117 - /*TODO: W/A for dal3 linux, investigate why this works */ 118 - if (!clk_mgr_dce->dfs_bypass_active) 119 - patched_disp_clk = patched_disp_clk * 115 / 100; 126 + const int max_disp_clk = 127 + clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz; 128 + int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); 120 129 121 130 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); 122 131 /* get max clock state from PPLIB */
+16
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
··· 563 563 { 564 564 int i, j; 565 565 struct clk_bw_params *bw_params = clk_mgr->base.bw_params; 566 + uint32_t max_dispclk = 0, max_dppclk = 0; 566 567 567 568 j = -1; 568 569 ··· 585 584 return; 586 585 } 587 586 587 + /* dispclk and dppclk can be max at any voltage, same number of levels for both */ 588 + if (clock_table->NumDispClkLevelsEnabled <= VG_NUM_DISPCLK_DPM_LEVELS && 589 + clock_table->NumDispClkLevelsEnabled <= VG_NUM_DPPCLK_DPM_LEVELS) { 590 + max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled); 591 + max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled); 592 + } else { 593 + ASSERT(0); 594 + } 595 + 588 596 bw_params->clk_table.num_entries = j + 1; 589 597 590 598 for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) { ··· 601 591 bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; 602 592 bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; 603 593 bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage); 594 + 595 + /* Now update clocks we do read */ 596 + bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; 597 + bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; 604 598 } 605 599 bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; 606 600 bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; 607 601 bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; 608 602 bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS); 603 + bw_params->clk_table.entries[i].dispclk_mhz = find_max_clk_value(clock_table->DispClocks, VG_NUM_DISPCLK_DPM_LEVELS); 604 + bw_params->clk_table.entries[i].dppclk_mhz = find_max_clk_value(clock_table->DppClocks, VG_NUM_DPPCLK_DPM_LEVELS); 609 605 610 606 bw_params->vram_type = bios_info->memory_type; 611 607 bw_params->num_channels = bios_info->ma_channel_number;
+2 -5
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
··· 1047 1047 &num_entries_per_clk->num_fclk_levels); 1048 1048 clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_FCLK); 1049 1049 1050 - if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) { 1051 - num_levels = num_entries_per_clk->num_memclk_levels; 1052 - } else { 1053 - num_levels = num_entries_per_clk->num_fclk_levels; 1054 - } 1050 + num_levels = max(num_entries_per_clk->num_memclk_levels, num_entries_per_clk->num_fclk_levels); 1051 + 1055 1052 clk_mgr_base->bw_params->max_memclk_mhz = 1056 1053 clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_memclk_levels - 1].memclk_mhz; 1057 1054 clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1;
+1 -5
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
··· 1404 1404 clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_fclk_levels - 1].fclk_mhz) 1405 1405 clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz = 0; 1406 1406 1407 - if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) { 1408 - num_levels = num_entries_per_clk->num_memclk_levels; 1409 - } else { 1410 - num_levels = num_entries_per_clk->num_fclk_levels; 1411 - } 1407 + num_levels = max(num_entries_per_clk->num_memclk_levels, num_entries_per_clk->num_fclk_levels); 1412 1408 1413 1409 clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1; 1414 1410
+57 -131
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 84 84 85 85 #if defined(CONFIG_DRM_AMD_DC_FP) 86 86 #include "dml2/dml2_internal_types.h" 87 + #include "soc_and_ip_translator.h" 87 88 #endif 88 89 89 90 #include "dce/dmub_outbox.h" ··· 218 217 connectors_num, 219 218 num_virtual_links); 220 219 221 - // condition loop on link_count to allow skipping invalid indices 220 + /* When getting the number of connectors, the VBIOS reports the number of valid indices, 221 + * but it doesn't say which indices are valid, and not every index has an actual connector. 222 + * So, if we don't find a connector on an index, that is not an error. 223 + * 224 + * - There is no guarantee that the first N indices will be valid 225 + * - VBIOS may report a higher amount of valid indices than there are actual connectors 226 + * - Some VBIOS have valid configurations for more connectors than there actually are 227 + * on the card. This may be because the manufacturer used the same VBIOS for different 228 + * variants of the same card. 229 + */ 222 230 for (i = 0; dc->link_count < connectors_num && i < MAX_LINKS; i++) { 231 + struct graphics_object_id connector_id = bios->funcs->get_connector_id(bios, i); 223 232 struct link_init_data link_init_params = {0}; 224 233 struct dc_link *link; 234 + 235 + if (connector_id.id == CONNECTOR_ID_UNKNOWN) 236 + continue; 225 237 226 238 DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count); 227 239 ··· 460 446 * avoid conflicting with firmware updates. 461 447 */ 462 448 if (dc->ctx->dce_version > DCE_VERSION_MAX) { 463 - if (dc->optimized_required || dc->wm_optimized_required) { 449 + if ((dc->optimized_required || dc->wm_optimized_required) && 450 + (stream->adjust.v_total_max != adjust->v_total_max || 451 + stream->adjust.v_total_min != adjust->v_total_min)) { 464 452 stream->adjust.timing_adjust_pending = true; 465 453 return false; 466 454 } ··· 950 934 } 951 935 952 936 dc_destroy_resource_pool(dc); 953 - 937 + #ifdef CONFIG_DRM_AMD_DC_FP 938 + dc_destroy_soc_and_ip_translator(&dc->soc_and_ip_translator); 939 + #endif 954 940 if (dc->link_srv) 955 941 link_destroy_link_service(&dc->link_srv); 956 942 ··· 1156 1138 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 1157 1139 DC_FP_END(); 1158 1140 } 1141 + dc->soc_and_ip_translator = dc_create_soc_and_ip_translator(dc_ctx->dce_version); 1142 + if (!dc->soc_and_ip_translator) 1143 + goto fail; 1159 1144 #endif 1160 1145 1161 1146 if (!create_links(dc, init_params->num_virtual_links)) ··· 2419 2398 goto fail; 2420 2399 } 2421 2400 2401 + /* 2402 + * If not already seamless, make transition seamless by inserting intermediate minimal transition 2403 + */ 2404 + if (dc->hwss.is_pipe_topology_transition_seamless && 2405 + !dc->hwss.is_pipe_topology_transition_seamless(dc, dc->current_state, context)) { 2406 + res = commit_minimal_transition_state(dc, context); 2407 + if (res != DC_OK) { 2408 + BREAK_TO_DEBUGGER(); 2409 + goto fail; 2410 + } 2411 + } 2412 + 2422 2413 res = dc_commit_state_no_check(dc, context); 2423 2414 2424 2415 for (i = 0; i < params->stream_count; i++) { ··· 3410 3377 int surface_count, 3411 3378 struct dc_stream_state *stream) 3412 3379 { 3413 - if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { 3380 + if (get_seamless_boot_stream_count(context) > 0 && (surface_count > 0 || stream->dpms_off)) { 3414 3381 /* Optimize seamless boot flag keeps clocks and watermarks high until 3415 3382 * first flip. After first flip, optimization is required to lower 3416 3383 * bandwidth. Important to note that it is expected UEFI will ··· 5122 5089 && !full_update_required(dc, srf_updates, surface_count, stream_update, stream); 5123 5090 } 5124 5091 5125 - static bool update_planes_and_stream_v1(struct dc *dc, 5126 - struct dc_surface_update *srf_updates, int surface_count, 5127 - struct dc_stream_state *stream, 5128 - struct dc_stream_update *stream_update, 5129 - struct dc_state *state) 5130 - { 5131 - const struct dc_stream_status *stream_status; 5132 - enum surface_update_type update_type; 5133 - struct dc_state *context; 5134 - struct dc_context *dc_ctx = dc->ctx; 5135 - int i, j; 5136 - struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 5137 - 5138 - dc_exit_ips_for_hw_access(dc); 5139 - 5140 - populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); 5141 - stream_status = dc_stream_get_status(stream); 5142 - context = dc->current_state; 5143 - 5144 - update_type = dc_check_update_surfaces_for_stream( 5145 - dc, srf_updates, surface_count, stream_update, stream_status); 5146 - /* It is possible to receive a flip for one plane while there are multiple flip_immediate planes in the same stream. 5147 - * E.g. Desktop and MPO plane are flip_immediate but only the MPO plane received a flip 5148 - * Force the other flip_immediate planes to flip so GSL doesn't wait for a flip that won't come. 5149 - */ 5150 - force_immediate_gsl_plane_flip(dc, srf_updates, surface_count); 5151 - 5152 - if (update_type >= UPDATE_TYPE_FULL) { 5153 - 5154 - /* initialize scratch memory for building context */ 5155 - context = dc_state_create_copy(state); 5156 - if (context == NULL) { 5157 - DC_ERROR("Failed to allocate new validate context!\n"); 5158 - return false; 5159 - } 5160 - 5161 - for (i = 0; i < dc->res_pool->pipe_count; i++) { 5162 - struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; 5163 - struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 5164 - 5165 - if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) 5166 - new_pipe->plane_state->force_full_update = true; 5167 - } 5168 - } else if (update_type == UPDATE_TYPE_FAST) { 5169 - /* 5170 - * Previous frame finished and HW is ready for optimization. 5171 - */ 5172 - dc_post_update_surfaces_to_stream(dc); 5173 - } 5174 - 5175 - for (i = 0; i < surface_count; i++) { 5176 - struct dc_plane_state *surface = srf_updates[i].surface; 5177 - 5178 - copy_surface_update_to_plane(surface, &srf_updates[i]); 5179 - 5180 - if (update_type >= UPDATE_TYPE_MED) { 5181 - for (j = 0; j < dc->res_pool->pipe_count; j++) { 5182 - struct pipe_ctx *pipe_ctx = 5183 - &context->res_ctx.pipe_ctx[j]; 5184 - 5185 - if (pipe_ctx->plane_state != surface) 5186 - continue; 5187 - 5188 - resource_build_scaling_params(pipe_ctx); 5189 - } 5190 - } 5191 - } 5192 - 5193 - copy_stream_update_to_stream(dc, context, stream, stream_update); 5194 - 5195 - if (update_type >= UPDATE_TYPE_FULL) { 5196 - if (dc->res_pool->funcs->validate_bandwidth(dc, context, DC_VALIDATE_MODE_AND_PROGRAMMING) != DC_OK) { 5197 - DC_ERROR("Mode validation failed for stream update!\n"); 5198 - dc_state_release(context); 5199 - return false; 5200 - } 5201 - } 5202 - 5203 - TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); 5204 - 5205 - if (fast_update_only(dc, fast_update, srf_updates, surface_count, stream_update, stream) && 5206 - !dc->debug.enable_legacy_fast_update) { 5207 - commit_planes_for_stream_fast(dc, 5208 - srf_updates, 5209 - surface_count, 5210 - stream, 5211 - stream_update, 5212 - update_type, 5213 - context); 5214 - } else { 5215 - commit_planes_for_stream( 5216 - dc, 5217 - srf_updates, 5218 - surface_count, 5219 - stream, 5220 - stream_update, 5221 - update_type, 5222 - context); 5223 - } 5224 - /*update current_State*/ 5225 - if (dc->current_state != context) { 5226 - 5227 - struct dc_state *old = dc->current_state; 5228 - 5229 - dc->current_state = context; 5230 - dc_state_release(old); 5231 - 5232 - for (i = 0; i < dc->res_pool->pipe_count; i++) { 5233 - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 5234 - 5235 - if (pipe_ctx->plane_state && pipe_ctx->stream == stream) 5236 - pipe_ctx->plane_state->force_full_update = false; 5237 - } 5238 - } 5239 - 5240 - /* Legacy optimization path for DCE. */ 5241 - if (update_type >= UPDATE_TYPE_FULL && dc_ctx->dce_version < DCE_VERSION_MAX) { 5242 - dc_post_update_surfaces_to_stream(dc); 5243 - TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); 5244 - } 5245 - return true; 5246 - } 5247 - 5248 5092 static bool update_planes_and_stream_v2(struct dc *dc, 5249 5093 struct dc_surface_update *srf_updates, int surface_count, 5250 5094 struct dc_stream_state *stream, ··· 5379 5469 if (dc->ctx->dce_version >= DCN_VERSION_4_01) { 5380 5470 ret = update_planes_and_stream_v3(dc, srf_updates, surface_count, 5381 5471 stream, stream_update); 5382 - } else if (dc->ctx->dce_version >= DCN_VERSION_3_2) { 5472 + } else { 5383 5473 ret = update_planes_and_stream_v2(dc, srf_updates, surface_count, 5384 5474 stream, stream_update); 5385 - } else 5386 - ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream, 5387 - stream_update, state); 5475 + } 5388 5476 5389 5477 if (ret && dc->ctx->dce_version >= DCN_VERSION_3_2) 5390 5478 clear_update_flags(srf_updates, surface_count, stream); ··· 6357 6449 } 6358 6450 6359 6451 return false; 6452 + } 6453 + 6454 + void dc_get_underflow_debug_data_for_otg(struct dc *dc, int primary_otg_inst, 6455 + struct dc_underflow_debug_data *out_data) 6456 + { 6457 + struct timing_generator *tg = NULL; 6458 + 6459 + for (int i = 0; i < MAX_PIPES; i++) { 6460 + if (dc->res_pool->timing_generators[i] && 6461 + dc->res_pool->timing_generators[i]->inst == primary_otg_inst) { 6462 + tg = dc->res_pool->timing_generators[i]; 6463 + break; 6464 + } 6465 + } 6466 + 6467 + dc_exit_ips_for_hw_access(dc); 6468 + if (dc->hwss.get_underflow_debug_data) 6469 + dc->hwss.get_underflow_debug_data(dc, tg, out_data); 6360 6470 }
+2
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
··· 1177 1177 tg = otg_master->stream_res.tg; 1178 1178 if (tg->funcs->wait_odm_doublebuffer_pending_clear) 1179 1179 tg->funcs->wait_odm_doublebuffer_pending_clear(tg); 1180 + if (tg->funcs->wait_otg_disable) 1181 + tg->funcs->wait_otg_disable(tg); 1180 1182 } 1181 1183 1182 1184 /* ODM update may require to reprogram blank pattern for each OPP */
+7 -1
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 165 165 166 166 case FAMILY_NV: 167 167 dc_version = DCN_VERSION_2_0; 168 - if (asic_id.chip_id == DEVICE_ID_NV_13FE || asic_id.chip_id == DEVICE_ID_NV_143F) { 168 + if (asic_id.chip_id == DEVICE_ID_NV_13FE || 169 + asic_id.chip_id == DEVICE_ID_NV_143F || 170 + asic_id.chip_id == DEVICE_ID_NV_13F9 || 171 + asic_id.chip_id == DEVICE_ID_NV_13FA || 172 + asic_id.chip_id == DEVICE_ID_NV_13FB || 173 + asic_id.chip_id == DEVICE_ID_NV_13FC || 174 + asic_id.chip_id == DEVICE_ID_NV_13DB) { 169 175 dc_version = DCN_VERSION_2_01; 170 176 break; 171 177 }
+1 -1
drivers/gpu/drm/amd/display/dc/core/dc_stat.c
··· 65 65 notify->type == DMUB_NOTIFICATION_DPIA_NOTIFICATION || 66 66 notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) { 67 67 notify->link_index = 68 - get_link_index_from_dpia_port_index(dc, notify->link_index); 68 + get_link_index_from_dpia_port_index(dc, notify->instance); 69 69 } 70 70 } 71 71
+7 -1
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
··· 316 316 { 317 317 bool result = false; 318 318 319 + if (!stream) 320 + return false; 321 + 319 322 if (dc_stream_check_cursor_attributes(stream, stream->ctx->dc->current_state, attributes)) { 320 323 stream->cursor_attributes = *attributes; 321 324 result = true; ··· 334 331 struct dc *dc; 335 332 bool reset_idle_optimizations = false; 336 333 337 - dc = stream ? stream->ctx->dc : NULL; 334 + if (!stream) 335 + return false; 336 + 337 + dc = stream->ctx->dc; 338 338 339 339 if (dc_stream_set_cursor_attributes(stream, attributes)) { 340 340 dc_z10_restore(dc);
+82 -5
drivers/gpu/drm/amd/display/dc/dc.h
··· 55 55 struct set_config_cmd_payload; 56 56 struct dmub_notification; 57 57 58 - #define DC_VER "3.2.340" 58 + #define DC_VER "3.2.348" 59 59 60 60 /** 61 61 * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC ··· 234 234 * @ogam_ram: programmable out gamma LUT 235 235 * @ocsc: output color space conversion matrix 236 236 * @num_3dluts: MPC 3D LUT; always assumes a preceding shaper LUT 237 + * @num_rmcm_3dluts: number of RMCM 3D LUTS; always assumes a preceding shaper LUT 237 238 * @shared_3d_lut: shared 3D LUT flag. Can be either DPP or MPC, but single 238 239 * instance 239 240 * @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT ··· 695 694 int idle_fclk_khz; 696 695 int subvp_prefetch_dramclk_khz; 697 696 int subvp_prefetch_fclk_khz; 697 + 698 + /* Stutter efficiency is technically not clock values 699 + * but stored here so the values are part of the update_clocks call similar to num_ways 700 + * Efficiencies are stored as percentage (0-100) 701 + */ 702 + struct { 703 + uint8_t base_efficiency; //LP1 704 + uint8_t low_power_efficiency; //LP2 705 + } stutter_efficiency; 698 706 }; 699 707 700 708 struct dc_bw_validation_profile { ··· 849 839 uint32_t enable_force_tbt3_work_around:1; /* bit 4 */ 850 840 uint32_t disable_usb4_pm_support:1; /* bit 5 */ 851 841 uint32_t enable_usb4_bw_zero_alloc_patch:1; /* bit 6 */ 852 - uint32_t reserved:25; 842 + uint32_t enable_bw_allocation_mode:1; /* bit 7 */ 843 + uint32_t reserved:24; 853 844 } bits; 854 845 uint32_t raw; 855 846 }; ··· 1083 1072 unsigned int force_mall_ss_num_ways; 1084 1073 bool alloc_extra_way_for_cursor; 1085 1074 uint32_t subvp_extra_lines; 1075 + bool disable_force_pstate_allow_on_hw_release; 1086 1076 bool force_usr_allow; 1087 1077 /* uses value at boot and disables switch */ 1088 1078 bool disable_dtb_ref_clk_switch; ··· 1157 1145 bool enable_hblank_borrow; 1158 1146 bool force_subvp_df_throttle; 1159 1147 uint32_t acpi_transition_bitmasks[MAX_PIPES]; 1148 + unsigned int auxless_alpm_lfps_setup_ns; 1149 + unsigned int auxless_alpm_lfps_period_ns; 1150 + unsigned int auxless_alpm_lfps_silence_ns; 1151 + unsigned int auxless_alpm_lfps_t1t2_us; 1152 + short auxless_alpm_lfps_t1t2_offset_us; 1160 1153 }; 1161 1154 1162 1155 ··· 1321 1304 uint32_t raw; 1322 1305 }; 1323 1306 1307 + 1308 + #define MATRIX_9C__DIM_128_ALIGNED_LEN 16 // 9+8 : 9 * 8 + 7 * 8 = 72 + 56 = 128 % 128 = 0 1309 + #define MATRIX_17C__DIM_128_ALIGNED_LEN 32 //17+15: 17 * 8 + 15 * 8 = 136 + 120 = 256 % 128 = 0 1310 + #define MATRIX_33C__DIM_128_ALIGNED_LEN 64 //17+47: 17 * 8 + 47 * 8 = 136 + 376 = 512 % 128 = 0 1311 + 1312 + struct lut_rgb { 1313 + uint16_t b; 1314 + uint16_t g; 1315 + uint16_t r; 1316 + uint16_t padding; 1317 + }; 1318 + 1319 + //this structure maps directly to how the lut will read it from memory 1320 + struct lut_mem_mapping { 1321 + union { 1322 + //NATIVE MODE 1, 2 1323 + //RGB layout [b][g][r] //red is 128 byte aligned 1324 + //BGR layout [r][g][b] //blue is 128 byte aligned 1325 + struct lut_rgb rgb_17c[17][17][MATRIX_17C__DIM_128_ALIGNED_LEN]; 1326 + struct lut_rgb rgb_33c[33][33][MATRIX_33C__DIM_128_ALIGNED_LEN]; 1327 + 1328 + //TRANSFORMED 1329 + uint16_t linear_rgb[(33*33*33*4/128+1)*128]; 1330 + }; 1331 + uint16_t size; 1332 + }; 1324 1333 1325 1334 struct dc_rmcm_3dlut { 1326 1335 bool isInUse; ··· 1776 1733 struct dml2_configuration_options dml2_options; 1777 1734 struct dml2_configuration_options dml2_dc_power_options; 1778 1735 enum dc_acpi_cm_power_state power_state; 1779 - 1736 + struct soc_and_ip_translator *soc_and_ip_translator; 1780 1737 }; 1781 1738 1782 1739 struct dc_scaling_info { ··· 1829 1786 struct dc_bias_and_scale bias_and_scale; 1830 1787 }; 1831 1788 1789 + struct dc_underflow_debug_data { 1790 + uint32_t otg_inst; 1791 + uint32_t otg_underflow; 1792 + uint32_t h_position; 1793 + uint32_t v_position; 1794 + uint32_t otg_frame_count; 1795 + struct dc_underflow_per_hubp_debug_data { 1796 + uint32_t hubp_underflow; 1797 + uint32_t hubp_in_blank; 1798 + uint32_t hubp_readline; 1799 + uint32_t det_config_error; 1800 + } hubps[MAX_PIPES]; 1801 + uint32_t curr_det_sizes[MAX_PIPES]; 1802 + uint32_t target_det_sizes[MAX_PIPES]; 1803 + uint32_t compbuf_config_error; 1804 + }; 1805 + 1832 1806 /* 1833 1807 * Create a new surface with default parameters; 1834 1808 */ ··· 1863 1803 1864 1804 void dc_post_update_surfaces_to_stream( 1865 1805 struct dc *dc); 1866 - 1867 - #include "dc_stream.h" 1868 1806 1869 1807 /** 1870 1808 * struct dc_validation_set - Struct to store surface/stream associations for validation ··· 2505 2447 */ 2506 2448 enum dc_status dc_link_validate_dp_tunneling_bandwidth(const struct dc *dc, const struct dc_state *new_ctx); 2507 2449 2450 + /* 2451 + * Get if ALPM is supported by the link 2452 + */ 2453 + void dc_link_get_alpm_support(struct dc_link *link, bool *auxless_support, 2454 + bool *auxwake_support); 2455 + 2508 2456 /* Sink Interfaces - A sink corresponds to a display output device */ 2509 2457 2510 2458 struct dc_container_id { ··· 2737 2673 2738 2674 bool dc_is_cursor_limit_pending(struct dc *dc); 2739 2675 bool dc_can_clear_cursor_limit(struct dc *dc); 2676 + 2677 + /** 2678 + * dc_get_underflow_debug_data_for_otg() - Retrieve underflow debug data. 2679 + * 2680 + * @dc: Pointer to the display core context. 2681 + * @primary_otg_inst: Instance index of the primary OTG that underflowed. 2682 + * @out_data: Pointer to a dc_underflow_debug_data struct to be filled with debug information. 2683 + * 2684 + * This function collects and logs underflow-related HW states when underflow happens, 2685 + * including OTG underflow status, current read positions, frame count, and per-HUBP debug data. 2686 + * The results are stored in the provided out_data structure for further analysis or logging. 2687 + */ 2688 + void dc_get_underflow_debug_data_for_otg(struct dc *dc, int primary_otg_inst, struct dc_underflow_debug_data *out_data); 2740 2689 2741 2690 #endif /* DC_INTERFACE_H_ */
+57 -9
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
··· 2010 2010 return result; 2011 2011 } 2012 2012 2013 - bool dmub_lsdma_send_linear_copy_packet( 2013 + bool dmub_lsdma_send_linear_copy_command( 2014 2014 struct dc_dmub_srv *dc_dmub_srv, 2015 2015 uint64_t src_addr, 2016 2016 uint64_t dst_addr, 2017 - uint32_t count) 2017 + uint32_t count 2018 + ) 2018 2019 { 2019 2020 struct dc_context *dc_ctx = dc_dmub_srv->ctx; 2020 2021 union dmub_rb_cmd cmd; ··· 2043 2042 return result; 2044 2043 } 2045 2044 2045 + bool dmub_lsdma_send_linear_sub_window_copy_command( 2046 + struct dc_dmub_srv *dc_dmub_srv, 2047 + struct lsdma_linear_sub_window_copy_params copy_data 2048 + ) 2049 + { 2050 + struct dc_context *dc_ctx = dc_dmub_srv->ctx; 2051 + union dmub_rb_cmd cmd; 2052 + enum dm_dmub_wait_type wait_type; 2053 + struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data; 2054 + bool result; 2055 + 2056 + memset(&cmd, 0, sizeof(cmd)); 2057 + 2058 + cmd.cmd_common.header.type = DMUB_CMD__LSDMA; 2059 + cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_LINEAR_SUB_WINDOW_COPY; 2060 + wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT; 2061 + 2062 + lsdma_data->u.linear_sub_window_copy_data.tmz = copy_data.tmz; 2063 + lsdma_data->u.linear_sub_window_copy_data.element_size = copy_data.element_size; 2064 + lsdma_data->u.linear_sub_window_copy_data.src_lo = copy_data.src_lo; 2065 + lsdma_data->u.linear_sub_window_copy_data.src_hi = copy_data.src_hi; 2066 + lsdma_data->u.linear_sub_window_copy_data.src_x = copy_data.src_x; 2067 + lsdma_data->u.linear_sub_window_copy_data.src_y = copy_data.src_y; 2068 + lsdma_data->u.linear_sub_window_copy_data.src_pitch = copy_data.src_pitch; 2069 + lsdma_data->u.linear_sub_window_copy_data.src_slice_pitch = copy_data.src_slice_pitch; 2070 + lsdma_data->u.linear_sub_window_copy_data.dst_lo = copy_data.dst_lo; 2071 + lsdma_data->u.linear_sub_window_copy_data.dst_hi = copy_data.dst_hi; 2072 + lsdma_data->u.linear_sub_window_copy_data.dst_x = copy_data.dst_x; 2073 + lsdma_data->u.linear_sub_window_copy_data.dst_y = copy_data.dst_y; 2074 + lsdma_data->u.linear_sub_window_copy_data.dst_pitch = copy_data.dst_pitch; 2075 + lsdma_data->u.linear_sub_window_copy_data.dst_slice_pitch = copy_data.dst_slice_pitch; 2076 + lsdma_data->u.linear_sub_window_copy_data.rect_x = copy_data.rect_x; 2077 + lsdma_data->u.linear_sub_window_copy_data.rect_y = copy_data.rect_y; 2078 + lsdma_data->u.linear_sub_window_copy_data.src_cache_policy = copy_data.src_cache_policy; 2079 + lsdma_data->u.linear_sub_window_copy_data.dst_cache_policy = copy_data.dst_cache_policy; 2080 + 2081 + result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type); 2082 + 2083 + if (!result) 2084 + DC_ERROR("LSDMA Linear Sub Window Copy failed in DMUB"); 2085 + 2086 + return result; 2087 + } 2088 + 2046 2089 bool dmub_lsdma_send_tiled_to_tiled_copy_command( 2047 2090 struct dc_dmub_srv *dc_dmub_srv, 2048 - struct lsdma_send_tiled_to_tiled_copy_command_params params) 2091 + struct lsdma_send_tiled_to_tiled_copy_command_params params 2092 + ) 2049 2093 { 2050 2094 struct dc_context *dc_ctx = dc_dmub_srv->ctx; 2051 2095 union dmub_rb_cmd cmd; ··· 2112 2066 lsdma_data->u.tiled_copy_data.src_y = params.src_y; 2113 2067 lsdma_data->u.tiled_copy_data.dst_x = params.dst_x; 2114 2068 lsdma_data->u.tiled_copy_data.dst_y = params.dst_y; 2115 - lsdma_data->u.tiled_copy_data.src_width = params.src_width - 1; // LSDMA controller expects width -1 2116 - lsdma_data->u.tiled_copy_data.dst_width = params.dst_width - 1; // LSDMA controller expects width -1 2069 + lsdma_data->u.tiled_copy_data.src_width = params.src_width; 2070 + lsdma_data->u.tiled_copy_data.dst_width = params.dst_width; 2117 2071 lsdma_data->u.tiled_copy_data.src_swizzle_mode = params.swizzle_mode; 2118 2072 lsdma_data->u.tiled_copy_data.dst_swizzle_mode = params.swizzle_mode; 2119 2073 lsdma_data->u.tiled_copy_data.src_element_size = params.element_size; ··· 2124 2078 lsdma_data->u.tiled_copy_data.tmz = params.tmz; 2125 2079 lsdma_data->u.tiled_copy_data.read_compress = params.read_compress; 2126 2080 lsdma_data->u.tiled_copy_data.write_compress = params.write_compress; 2127 - lsdma_data->u.tiled_copy_data.src_height = params.src_height - 1; // LSDMA controller expects height -1 2128 - lsdma_data->u.tiled_copy_data.dst_height = params.dst_height - 1; // LSDMA controller expects height -1 2081 + lsdma_data->u.tiled_copy_data.src_height = params.src_height; 2082 + lsdma_data->u.tiled_copy_data.dst_height = params.dst_height; 2129 2083 lsdma_data->u.tiled_copy_data.data_format = params.data_format; 2130 2084 lsdma_data->u.tiled_copy_data.max_com = params.max_com; 2131 2085 lsdma_data->u.tiled_copy_data.max_uncom = params.max_uncom; ··· 2143 2097 uint64_t src_addr, 2144 2098 uint64_t dst_addr, 2145 2099 uint32_t byte_count, 2146 - uint32_t overlap_disable) 2100 + uint32_t overlap_disable 2101 + ) 2147 2102 { 2148 2103 struct dc_context *dc_ctx = dc_dmub_srv->ctx; 2149 2104 union dmub_rb_cmd cmd; ··· 2177 2130 struct dc_dmub_srv *dc_dmub_srv, 2178 2131 uint64_t dst_addr, 2179 2132 uint32_t byte_count, 2180 - uint32_t data) 2133 + uint32_t data 2134 + ) 2181 2135 { 2182 2136 struct dc_context *dc_ctx = dc_dmub_srv->ctx; 2183 2137 union dmub_rb_cmd cmd;
+35 -1
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
··· 211 211 int surface_count); 212 212 213 213 bool dmub_lsdma_init(struct dc_dmub_srv *dc_dmub_srv); 214 - bool dmub_lsdma_send_linear_copy_packet( 214 + bool dmub_lsdma_send_linear_copy_command( 215 215 struct dc_dmub_srv *dc_dmub_srv, 216 216 uint64_t src_addr, 217 217 uint64_t dst_addr, 218 218 uint32_t count); 219 + 220 + struct lsdma_linear_sub_window_copy_params { 221 + uint32_t src_lo; 222 + uint32_t src_hi; 223 + 224 + uint32_t dst_lo; 225 + uint32_t dst_hi; 226 + 227 + uint32_t src_x : 16; 228 + uint32_t src_y : 16; 229 + 230 + uint32_t dst_x : 16; 231 + uint32_t dst_y : 16; 232 + 233 + uint32_t rect_x : 16; 234 + uint32_t rect_y : 16; 235 + 236 + uint32_t src_pitch : 16; 237 + uint32_t dst_pitch : 16; 238 + 239 + uint32_t src_slice_pitch; 240 + uint32_t dst_slice_pitch; 241 + 242 + uint32_t tmz : 1; 243 + uint32_t element_size : 3; 244 + uint32_t src_cache_policy : 3; 245 + uint32_t dst_cache_policy : 3; 246 + uint32_t padding : 22; 247 + }; 248 + 249 + bool dmub_lsdma_send_linear_sub_window_copy_command( 250 + struct dc_dmub_srv *dc_dmub_srv, 251 + struct lsdma_linear_sub_window_copy_params copy_data 252 + ); 219 253 bool dmub_lsdma_send_pio_copy_command( 220 254 struct dc_dmub_srv *dc_dmub_srv, 221 255 uint64_t src_addr,
+10 -6
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
··· 1021 1021 union dp_alpm_lttpr_cap { 1022 1022 struct { 1023 1023 uint8_t AUX_LESS_ALPM_SUPPORTED :1; 1024 - uint8_t RESERVED :7; 1024 + uint8_t ASSR_SUPPORTED :1; 1025 + uint8_t RESERVED :6; 1025 1026 } bits; 1026 1027 uint8_t raw; 1027 1028 }; ··· 1120 1119 1121 1120 union edp_alpm_caps { 1122 1121 struct { 1123 - uint8_t AUX_WAKE_ALPM_CAP :1; 1124 - uint8_t PM_STATE_2A_SUPPORT :1; 1125 - uint8_t AUX_LESS_ALPM_CAP :1; 1126 - uint8_t RESERVED :5; 1122 + uint8_t AUX_WAKE_ALPM_CAP :1; 1123 + uint8_t PM_STATE_2A_SUPPORT :1; 1124 + uint8_t AUX_LESS_ALPM_CAP :1; 1125 + uint8_t AUX_LESS_ALPM_ML_PHY_SLEEP_STATUS_SUPPORTED :1; 1126 + uint8_t RESERVED :4; 1127 1127 } bits; 1128 1128 uint8_t raw; 1129 1129 }; ··· 1349 1347 struct { 1350 1348 unsigned char ENABLE : 1; 1351 1349 unsigned char IRQ_HPD_ENABLE : 1; 1352 - unsigned char RESERVED : 6; 1350 + unsigned char ALPM_MODE_SEL : 1; 1351 + unsigned char ACDS_PERIOD_DURATION : 1; 1352 + unsigned char RESERVED : 4; 1353 1353 } bits; 1354 1354 unsigned char raw; 1355 1355 };
+1 -1
drivers/gpu/drm/amd/display/dc/dc_helper.c
··· 732 732 case DCN_VERSION_3_03: 733 733 return "DCN 3.0.3"; 734 734 case DCN_VERSION_3_1: 735 - return "DCN 3.1"; 735 + return "DCN 3.1.2"; 736 736 case DCN_VERSION_3_14: 737 737 return "DCN 3.1.4"; 738 738 case DCN_VERSION_3_15:
+18
drivers/gpu/drm/amd/display/dc/dc_types.h
··· 563 563 uint8_t sb[128]; 564 564 }; 565 565 566 + struct dc_edid_read_policy { 567 + uint32_t max_retry_count; 568 + uint32_t delay_time_ms; 569 + uint32_t ignore_checksum; 570 + }; 571 + 566 572 #define DC_PLANE_UPDATE_TIMES_MAX 10 567 573 568 574 struct dc_plane_flip_time { 569 575 unsigned int time_elapsed_in_us[DC_PLANE_UPDATE_TIMES_MAX]; 570 576 unsigned int index; 571 577 unsigned int prev_update_time_in_us; 578 + }; 579 + 580 + enum dc_alpm_mode { 581 + DC_ALPM_AUXWAKE = 0, 582 + DC_ALPM_AUXLESS = 1, 583 + DC_ALPM_UNSUPPORTED = 0xF, 572 584 }; 573 585 574 586 enum dc_psr_state { ··· 628 616 unsigned int line_time_in_us; 629 617 uint8_t rate_control_caps; 630 618 uint16_t dsc_slice_height; 619 + bool os_request_force_ffu; 631 620 }; 632 621 633 622 union dmcu_psr_level { ··· 741 728 unsigned int line_time_in_us; 742 729 uint8_t rate_control_caps; 743 730 uint16_t dsc_slice_height; 731 + bool os_request_force_ffu; 744 732 }; 745 733 746 734 struct colorspace_transform { ··· 1151 1137 bool low_rr_supported; 1152 1138 /* Replay Video Conferencing Optimization Enabled */ 1153 1139 bool replay_video_conferencing_optimization_enabled; 1140 + /* Replay alpm mode */ 1141 + enum dc_alpm_mode alpm_mode; 1142 + /* Replay full screen only */ 1143 + bool os_request_force_ffu; 1154 1144 }; 1155 1145 1156 1146 /* Replay feature flags*/
+1 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
··· 619 619 dto_integer = div_u64(params->pixclk_hz, dto_modulo_hz); 620 620 dto_phase_hz = params->pixclk_hz - dto_integer * dto_modulo_hz; 621 621 622 - if (dto_phase_hz <= 0) { 622 + if (dto_phase_hz <= 0 && dto_integer <= 0) { 623 623 /* negative pixel rate should never happen */ 624 624 BREAK_TO_DEBUGGER(); 625 625 return;
+1 -1
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
··· 591 591 DCE_I2C_TRANSACTION_ACTION_I2C_WRITE; 592 592 593 593 594 - request.address = (uint8_t) ((payload->address << 1) | !payload->write); 594 + request.address = (uint8_t) ((payload->address << 1) | (payload->write ? 0 : 1)); 595 595 request.length = payload->length; 596 596 request.data = payload->data; 597 597
+1 -1
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c
··· 451 451 DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT : 452 452 DCE_I2C_TRANSACTION_ACTION_I2C_WRITE; 453 453 454 - request.address = (uint8_t) ((payload->address << 1) | !payload->write); 454 + request.address = (uint8_t) ((payload->address << 1) | (payload->write ? 0 : 1)); 455 455 request.length = payload->length; 456 456 request.data = payload->data; 457 457
+1 -1
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
··· 391 391 sizeof(DP_SINK_DEVICE_STR_ID_1))) 392 392 link->psr_settings.force_ffu_mode = 1; 393 393 394 - copy_settings_data->force_ffu_mode = link->psr_settings.force_ffu_mode; 394 + copy_settings_data->force_ffu_mode = link->psr_settings.force_ffu_mode || psr_context->os_request_force_ffu; 395 395 396 396 if (((link->dpcd_caps.fec_cap.bits.FEC_CAPABLE && 397 397 !link->dc->debug.disable_fec) &&
+16 -40
drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
··· 3 3 // Copyright 2024 Advanced Micro Devices, Inc. 4 4 5 5 #include "dc.h" 6 + #include "link.h" 6 7 #include "dc_dmub_srv.h" 7 - #include "dc_dp_types.h" 8 8 #include "dmub/dmub_srv.h" 9 9 #include "core_types.h" 10 10 #include "dmub_replay.h" ··· 44 44 /* 45 45 * Enable/Disable Replay. 46 46 */ 47 - static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst, 48 - struct dc_link *link) 47 + static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst) 49 48 { 50 49 union dmub_rb_cmd cmd; 51 50 struct dc_context *dc = dmub->ctx; 52 51 uint32_t retry_count; 53 52 enum replay_state state = REPLAY_STATE_0; 54 - struct pipe_ctx *pipe_ctx = NULL; 55 - struct resource_context *res_ctx = &link->ctx->dc->current_state->res_ctx; 56 - uint8_t i; 57 53 58 54 memset(&cmd, 0, sizeof(cmd)); 59 55 cmd.replay_enable.header.type = DMUB_CMD__REPLAY; 60 56 cmd.replay_enable.data.panel_inst = panel_inst; 61 57 62 58 cmd.replay_enable.header.sub_type = DMUB_CMD__REPLAY_ENABLE; 63 - if (enable) { 59 + if (enable) 64 60 cmd.replay_enable.data.enable = REPLAY_ENABLE; 65 - // hpo stream/link encoder assignments are not static, need to update everytime we try to enable replay 66 - if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) { 67 - for (i = 0; i < MAX_PIPES; i++) { 68 - if (res_ctx && 69 - res_ctx->pipe_ctx[i].stream && 70 - res_ctx->pipe_ctx[i].stream->link && 71 - res_ctx->pipe_ctx[i].stream->link == link && 72 - res_ctx->pipe_ctx[i].stream->link->connector_signal == SIGNAL_TYPE_EDP) { 73 - pipe_ctx = &res_ctx->pipe_ctx[i]; 74 - //TODO: refactor for multi edp support 75 - break; 76 - } 77 - } 78 - 79 - if (!pipe_ctx) 80 - return; 81 - 82 - cmd.replay_enable.data.hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; 83 - cmd.replay_enable.data.hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst; 84 - } 85 - } else 61 + else 86 62 cmd.replay_enable.data.enable = REPLAY_DISABLE; 87 63 88 64 cmd.replay_enable.header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_enable_data); ··· 150 174 copy_settings_data->digbe_inst = replay_context->digbe_inst; 151 175 copy_settings_data->digfe_inst = replay_context->digfe_inst; 152 176 153 - if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) { 154 - if (pipe_ctx->stream_res.hpo_dp_stream_enc) 155 - copy_settings_data->hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; 156 - else 157 - copy_settings_data->hpo_stream_enc_inst = 0; 158 - if (pipe_ctx->link_res.hpo_dp_link_enc) 159 - copy_settings_data->hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst; 160 - else 161 - copy_settings_data->hpo_link_enc_inst = 0; 162 - } 163 - 164 177 if (pipe_ctx->plane_res.dpp) 165 178 copy_settings_data->dpp_inst = pipe_ctx->plane_res.dpp->inst; 166 179 else ··· 190 225 else 191 226 copy_settings_data->flags.bitfields.force_wakeup_by_tps3 = 0; 192 227 228 + copy_settings_data->flags.bitfields.alpm_mode = (enum dmub_alpm_mode)link->replay_settings.config.alpm_mode; 229 + if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) { 230 + copy_settings_data->auxless_alpm_data.lfps_setup_ns = dc->dc->debug.auxless_alpm_lfps_setup_ns; 231 + copy_settings_data->auxless_alpm_data.lfps_period_ns = dc->dc->debug.auxless_alpm_lfps_period_ns; 232 + copy_settings_data->auxless_alpm_data.lfps_silence_ns = dc->dc->debug.auxless_alpm_lfps_silence_ns; 233 + copy_settings_data->auxless_alpm_data.lfps_t1_t2_override_us = 234 + dc->dc->debug.auxless_alpm_lfps_t1t2_us; 235 + copy_settings_data->auxless_alpm_data.lfps_t1_t2_offset_us = 236 + dc->dc->debug.auxless_alpm_lfps_t1t2_offset_us; 237 + copy_settings_data->auxless_alpm_data.lttpr_count = link->dc->link_srv->dp_get_lttpr_count(link); 238 + } 239 + 193 240 dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 194 241 195 242 return true; ··· 224 247 pCmd->header.type = DMUB_CMD__REPLAY; 225 248 pCmd->header.sub_type = DMUB_CMD__REPLAY_SET_COASTING_VTOTAL; 226 249 pCmd->header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data); 227 - pCmd->replay_set_coasting_vtotal_data.panel_inst = panel_inst; 228 250 pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF); 229 251 pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16; 230 252
+1 -1
drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h
··· 19 19 void (*replay_get_state)(struct dmub_replay *dmub, enum replay_state *state, 20 20 uint8_t panel_inst); 21 21 void (*replay_enable)(struct dmub_replay *dmub, bool enable, bool wait, 22 - uint8_t panel_inst, struct dc_link *link); 22 + uint8_t panel_inst); 23 23 bool (*replay_copy_settings)(struct dmub_replay *dmub, struct dc_link *link, 24 24 struct replay_context *replay_context, uint8_t panel_inst); 25 25 void (*replay_set_power_opt)(struct dmub_replay *dmub, unsigned int power_opt,
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
··· 646 646 647 647 // the dpte_group_bytes is reduced for the specific case of vertical 648 648 // access of a tile surface that has dpte request of 8x1 ptes. 649 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 649 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 650 650 rq_sizing_param->dpte_group_bytes = 512; 651 651 else 652 652 //full size
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
··· 646 646 647 647 // the dpte_group_bytes is reduced for the specific case of vertical 648 648 // access of a tile surface that has dpte request of 8x1 ptes. 649 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 649 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 650 650 rq_sizing_param->dpte_group_bytes = 512; 651 651 else 652 652 //full size
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
··· 652 652 if (hostvm_enable) 653 653 rq_sizing_param->dpte_group_bytes = 512; 654 654 else { 655 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 655 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 656 656 rq_sizing_param->dpte_group_bytes = 512; 657 657 else 658 658 //full size
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
··· 620 620 if (hostvm_enable) 621 621 rq_sizing_param->dpte_group_bytes = 512; 622 622 else { 623 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 623 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 624 624 rq_sizing_param->dpte_group_bytes = 512; 625 625 else 626 626 rq_sizing_param->dpte_group_bytes = 2048;
+19 -5
drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
··· 326 326 struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); 327 327 struct clk_limit_table *clk_table = &bw_params->clk_table; 328 328 unsigned int i, closest_clk_lvl; 329 - int j; 329 + int j = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0; 330 330 331 331 dc_assert_fp_enabled(); 332 332 ··· 338 338 dcn3_01_soc.num_chans = bw_params->num_channels; 339 339 340 340 ASSERT(clk_table->num_entries); 341 + 342 + /* Prepass to find max clocks independent of voltage level. */ 343 + for (i = 0; i < clk_table->num_entries; ++i) { 344 + if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) 345 + max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; 346 + if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) 347 + max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; 348 + } 349 + 341 350 for (i = 0; i < clk_table->num_entries; i++) { 342 351 /* loop backwards*/ 343 352 for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) { ··· 362 353 s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 363 354 s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; 364 355 365 - s[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; 366 - s[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; 356 + /* Clocks independent of voltage level. */ 357 + s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : 358 + dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; 359 + 360 + s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : 361 + dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; 362 + 367 363 s[i].dram_bw_per_chan_gbps = 368 364 dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; 369 365 s[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; ··· 449 435 &context->bw_ctx.dml, pipes, pipe_cnt); 450 436 /* WM Set C */ 451 437 table_entry = &bw_params->wm_table.entries[WM_C]; 452 - vlevel = min(max(vlevel_req, 2), vlevel_max); 438 + vlevel = clamp(vlevel_req, 2, vlevel_max); 453 439 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, 454 440 &context->bw_ctx.dml, pipes, pipe_cnt); 455 441 /* WM Set B */ 456 442 table_entry = &bw_params->wm_table.entries[WM_B]; 457 - vlevel = min(max(vlevel_req, 1), vlevel_max); 443 + vlevel = clamp(vlevel_req, 1, vlevel_max); 458 444 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, 459 445 &context->bw_ctx.dml, pipes, pipe_cnt); 460 446
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
··· 280 280 j = 0; 281 281 /* create the final dcfclk and uclk table */ 282 282 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { 283 - if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { 283 + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { 284 284 dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; 285 285 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; 286 286 } else {
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
··· 285 285 j = 0; 286 286 /* create the final dcfclk and uclk table */ 287 287 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { 288 - if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { 288 + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { 289 289 dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; 290 290 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; 291 291 } else {
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c
··· 615 615 if (hostvm_enable) 616 616 rq_sizing_param->dpte_group_bytes = 512; 617 617 else { 618 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 618 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 619 619 rq_sizing_param->dpte_group_bytes = 512; 620 620 else 621 621 rq_sizing_param->dpte_group_bytes = 2048;
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c
··· 703 703 if (hostvm_enable) 704 704 rq_sizing_param->dpte_group_bytes = 512; 705 705 else { 706 - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group 706 + if (!surf_linear && (log2_dpte_req_height_ptes == 0) && surf_vert) //reduced, in this case, will have page fault within a group 707 707 rq_sizing_param->dpte_group_bytes = 512; 708 708 else 709 709 rq_sizing_param->dpte_group_bytes = 2048;
+2 -2
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
··· 3229 3229 j = 0; 3230 3230 // create the final dcfclk and uclk table 3231 3231 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { 3232 - if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { 3232 + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { 3233 3233 dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; 3234 3234 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; 3235 3235 } else { ··· 3401 3401 uint32_t height = subvp_active_margin_list.res[i].height; 3402 3402 3403 3403 refresh_rate = (pipe->stream->timing.pix_clk_100hz * (uint64_t)100 + 3404 - pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1); 3404 + (uint64_t)pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1); 3405 3405 refresh_rate = div_u64(refresh_rate, pipe->stream->timing.v_total); 3406 3406 refresh_rate = div_u64(refresh_rate, pipe->stream->timing.h_total); 3407 3407
-1
drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
··· 139 139 if (dual_plane) { 140 140 unsigned int p1_pte_row_height_linear = get_dpte_row_height_linear_c(mode_lib, e2e_pipe_param, 141 141 num_pipes, pipe_idx); 142 - ; 143 142 if (src->sw_mode == dm_sw_linear) 144 143 ASSERT(p1_pte_row_height_linear >= 8); 145 144
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
··· 779 779 j = 0; 780 780 // create the final dcfclk and uclk table 781 781 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { 782 - if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { 782 + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { 783 783 dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; 784 784 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; 785 785 } else {
+20 -360
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
··· 8 8 #include "dml2_internal_types.h" 9 9 #include "dml21_utils.h" 10 10 #include "dml21_translation_helper.h" 11 - #include "bounding_boxes/dcn4_soc_bb.h" 11 + #include "soc_and_ip_translator.h" 12 12 13 13 static void dml21_populate_pmo_options(struct dml2_pmo_options *pmo_options, 14 14 const struct dc *in_dc, ··· 38 38 pmo_options->disable_drr_clamped_when_var_active = in_dc->debug.disable_fams_gaming == INGAME_FAMS_DISABLE; 39 39 } 40 40 41 - /* 42 - * Populate dml_init based on default static values in soc bb. The default 43 - * values are for reference and support at least minimal operation of current 44 - * SoC and DCN hardware. The values could be modifed by subsequent override 45 - * functions to reflect our true hardware capability. 46 - */ 47 - static void populate_default_dml_init_params(struct dml2_initialize_instance_in_out *dml_init, 48 - const struct dml2_configuration_options *config, 49 - const struct dc *in_dc) 41 + static enum dml2_project_id dml21_dcn_revision_to_dml2_project_id(enum dce_version dcn_version) 50 42 { 51 - switch (in_dc->ctx->dce_version) { 43 + enum dml2_project_id project_id; 44 + switch (dcn_version) { 52 45 case DCN_VERSION_4_01: 53 - dml_init->options.project_id = dml2_project_dcn4x_stage2_auto_drr_svp; 54 - dml21_populate_pmo_options(&dml_init->options.pmo_options, in_dc, config); 55 - dml_init->soc_bb = dml2_socbb_dcn401; 56 - dml_init->soc_bb.qos_parameters = dml_dcn4_variant_a_soc_qos_params; 57 - dml_init->ip_caps = dml2_dcn401_max_ip_caps; 46 + project_id = dml2_project_dcn4x_stage2_auto_drr_svp; 58 47 break; 59 48 default: 60 - memset(dml_init, 0, sizeof(*dml_init)); 49 + project_id = dml2_project_invalid; 61 50 DC_ERR("unsupported dcn version for DML21!"); 62 - return; 63 - } 64 - } 65 - 66 - static void override_dml_init_with_values_from_hardware_default(struct dml2_initialize_instance_in_out *dml_init, 67 - const struct dml2_configuration_options *config, 68 - const struct dc *in_dc) 69 - { 70 - dml_init->soc_bb.dchub_refclk_mhz = in_dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000; 71 - dml_init->soc_bb.dprefclk_mhz = in_dc->clk_mgr->dprefclk_khz / 1000; 72 - dml_init->soc_bb.dispclk_dppclk_vco_speed_mhz = in_dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 73 - } 74 - 75 - /* 76 - * SMU stands for System Management Unit. It is a power management processor. 77 - * It owns the initialization of dc's clock table and programming of clock values 78 - * based on dc's requests. 79 - * Our clock values in base soc bb is a dummy placeholder. The real clock values 80 - * are retrieved from SMU firmware to dc clock table at runtime. 81 - * This function overrides our dummy placeholder values with real values in dc 82 - * clock table. 83 - */ 84 - static void override_dml_init_with_values_from_smu( 85 - struct dml2_initialize_instance_in_out *dml_init, 86 - const struct dml2_configuration_options *config, 87 - const struct dc *in_dc) 88 - { 89 - int i; 90 - const struct clk_bw_params *dc_bw_params = in_dc->clk_mgr->bw_params; 91 - const struct clk_limit_table *dc_clk_table = &dc_bw_params->clk_table; 92 - struct dml2_soc_state_table *dml_clk_table = &dml_init->soc_bb.clk_table; 93 - 94 - if (!in_dc->clk_mgr->funcs->is_smu_present || 95 - !in_dc->clk_mgr->funcs->is_smu_present(in_dc->clk_mgr)) 96 - /* skip if smu is not present */ 97 - return; 98 - 99 - /* dcfclk */ 100 - if (dc_clk_table->num_entries_per_clk.num_dcfclk_levels) { 101 - dml_clk_table->dcfclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dcfclk_levels; 102 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 103 - if (i < dml_clk_table->dcfclk.num_clk_values) { 104 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dcfclk_mhz && 105 - dc_clk_table->entries[i].dcfclk_mhz > dc_bw_params->dc_mode_limit.dcfclk_mhz) { 106 - if (i == 0 || dc_clk_table->entries[i-1].dcfclk_mhz < dc_bw_params->dc_mode_limit.dcfclk_mhz) { 107 - dml_clk_table->dcfclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dcfclk_mhz * 1000; 108 - dml_clk_table->dcfclk.num_clk_values = i + 1; 109 - } else { 110 - dml_clk_table->dcfclk.clk_values_khz[i] = 0; 111 - dml_clk_table->dcfclk.num_clk_values = i; 112 - } 113 - } else { 114 - dml_clk_table->dcfclk.clk_values_khz[i] = dc_clk_table->entries[i].dcfclk_mhz * 1000; 115 - } 116 - } else { 117 - dml_clk_table->dcfclk.clk_values_khz[i] = 0; 118 - } 119 - } 51 + break; 120 52 } 121 53 122 - /* fclk */ 123 - if (dc_clk_table->num_entries_per_clk.num_fclk_levels) { 124 - dml_clk_table->fclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_fclk_levels; 125 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 126 - if (i < dml_clk_table->fclk.num_clk_values) { 127 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.fclk_mhz && 128 - dc_clk_table->entries[i].fclk_mhz > dc_bw_params->dc_mode_limit.fclk_mhz) { 129 - if (i == 0 || dc_clk_table->entries[i-1].fclk_mhz < dc_bw_params->dc_mode_limit.fclk_mhz) { 130 - dml_clk_table->fclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.fclk_mhz * 1000; 131 - dml_clk_table->fclk.num_clk_values = i + 1; 132 - } else { 133 - dml_clk_table->fclk.clk_values_khz[i] = 0; 134 - dml_clk_table->fclk.num_clk_values = i; 135 - } 136 - } else { 137 - dml_clk_table->fclk.clk_values_khz[i] = dc_clk_table->entries[i].fclk_mhz * 1000; 138 - } 139 - } else { 140 - dml_clk_table->fclk.clk_values_khz[i] = 0; 141 - } 142 - } 143 - } 144 - 145 - /* uclk */ 146 - if (dc_clk_table->num_entries_per_clk.num_memclk_levels) { 147 - dml_clk_table->uclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_memclk_levels; 148 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 149 - if (i < dml_clk_table->uclk.num_clk_values) { 150 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.memclk_mhz && 151 - dc_clk_table->entries[i].memclk_mhz > dc_bw_params->dc_mode_limit.memclk_mhz) { 152 - if (i == 0 || dc_clk_table->entries[i-1].memclk_mhz < dc_bw_params->dc_mode_limit.memclk_mhz) { 153 - dml_clk_table->uclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.memclk_mhz * 1000; 154 - dml_clk_table->uclk.num_clk_values = i + 1; 155 - } else { 156 - dml_clk_table->uclk.clk_values_khz[i] = 0; 157 - dml_clk_table->uclk.num_clk_values = i; 158 - } 159 - } else { 160 - dml_clk_table->uclk.clk_values_khz[i] = dc_clk_table->entries[i].memclk_mhz * 1000; 161 - } 162 - } else { 163 - dml_clk_table->uclk.clk_values_khz[i] = 0; 164 - } 165 - } 166 - } 167 - 168 - /* dispclk */ 169 - if (dc_clk_table->num_entries_per_clk.num_dispclk_levels) { 170 - dml_clk_table->dispclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dispclk_levels; 171 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 172 - if (i < dml_clk_table->dispclk.num_clk_values) { 173 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dispclk_mhz && 174 - dc_clk_table->entries[i].dispclk_mhz > dc_bw_params->dc_mode_limit.dispclk_mhz) { 175 - if (i == 0 || dc_clk_table->entries[i-1].dispclk_mhz < dc_bw_params->dc_mode_limit.dispclk_mhz) { 176 - dml_clk_table->dispclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dispclk_mhz * 1000; 177 - dml_clk_table->dispclk.num_clk_values = i + 1; 178 - } else { 179 - dml_clk_table->dispclk.clk_values_khz[i] = 0; 180 - dml_clk_table->dispclk.num_clk_values = i; 181 - } 182 - } else { 183 - dml_clk_table->dispclk.clk_values_khz[i] = dc_clk_table->entries[i].dispclk_mhz * 1000; 184 - } 185 - } else { 186 - dml_clk_table->dispclk.clk_values_khz[i] = 0; 187 - } 188 - } 189 - } 190 - 191 - /* dppclk */ 192 - if (dc_clk_table->num_entries_per_clk.num_dppclk_levels) { 193 - dml_clk_table->dppclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dppclk_levels; 194 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 195 - if (i < dml_clk_table->dppclk.num_clk_values) { 196 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dppclk_mhz && 197 - dc_clk_table->entries[i].dppclk_mhz > dc_bw_params->dc_mode_limit.dppclk_mhz) { 198 - if (i == 0 || dc_clk_table->entries[i-1].dppclk_mhz < dc_bw_params->dc_mode_limit.dppclk_mhz) { 199 - dml_clk_table->dppclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dppclk_mhz * 1000; 200 - dml_clk_table->dppclk.num_clk_values = i + 1; 201 - } else { 202 - dml_clk_table->dppclk.clk_values_khz[i] = 0; 203 - dml_clk_table->dppclk.num_clk_values = i; 204 - } 205 - } else { 206 - dml_clk_table->dppclk.clk_values_khz[i] = dc_clk_table->entries[i].dppclk_mhz * 1000; 207 - } 208 - } else { 209 - dml_clk_table->dppclk.clk_values_khz[i] = 0; 210 - } 211 - } 212 - } 213 - 214 - /* dtbclk */ 215 - if (dc_clk_table->num_entries_per_clk.num_dtbclk_levels) { 216 - dml_clk_table->dtbclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dtbclk_levels; 217 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 218 - if (i < dml_clk_table->dtbclk.num_clk_values) { 219 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dtbclk_mhz && 220 - dc_clk_table->entries[i].dtbclk_mhz > dc_bw_params->dc_mode_limit.dtbclk_mhz) { 221 - if (i == 0 || dc_clk_table->entries[i-1].dtbclk_mhz < dc_bw_params->dc_mode_limit.dtbclk_mhz) { 222 - dml_clk_table->dtbclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dtbclk_mhz * 1000; 223 - dml_clk_table->dtbclk.num_clk_values = i + 1; 224 - } else { 225 - dml_clk_table->dtbclk.clk_values_khz[i] = 0; 226 - dml_clk_table->dtbclk.num_clk_values = i; 227 - } 228 - } else { 229 - dml_clk_table->dtbclk.clk_values_khz[i] = dc_clk_table->entries[i].dtbclk_mhz * 1000; 230 - } 231 - } else { 232 - dml_clk_table->dtbclk.clk_values_khz[i] = 0; 233 - } 234 - } 235 - } 236 - 237 - /* socclk */ 238 - if (dc_clk_table->num_entries_per_clk.num_socclk_levels) { 239 - dml_clk_table->socclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_socclk_levels; 240 - for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 241 - if (i < dml_clk_table->socclk.num_clk_values) { 242 - if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.socclk_mhz && 243 - dc_clk_table->entries[i].socclk_mhz > dc_bw_params->dc_mode_limit.socclk_mhz) { 244 - if (i == 0 || dc_clk_table->entries[i-1].socclk_mhz < dc_bw_params->dc_mode_limit.socclk_mhz) { 245 - dml_clk_table->socclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.socclk_mhz * 1000; 246 - dml_clk_table->socclk.num_clk_values = i + 1; 247 - } else { 248 - dml_clk_table->socclk.clk_values_khz[i] = 0; 249 - dml_clk_table->socclk.num_clk_values = i; 250 - } 251 - } else { 252 - dml_clk_table->socclk.clk_values_khz[i] = dc_clk_table->entries[i].socclk_mhz * 1000; 253 - } 254 - } else { 255 - dml_clk_table->socclk.clk_values_khz[i] = 0; 256 - } 257 - } 258 - } 259 - } 260 - 261 - static void override_dml_init_with_values_from_vbios( 262 - struct dml2_initialize_instance_in_out *dml_init, 263 - const struct dml2_configuration_options *config, 264 - const struct dc *in_dc) 265 - { 266 - const struct clk_bw_params *dc_bw_params = in_dc->clk_mgr->bw_params; 267 - struct dml2_soc_bb *dml_soc_bb = &dml_init->soc_bb; 268 - struct dml2_soc_state_table *dml_clk_table = &dml_init->soc_bb.clk_table; 269 - 270 - if (in_dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns > 0) 271 - dml_soc_bb->power_management_parameters.dram_clk_change_blackout_us = 272 - (in_dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns + 9) / 10; 273 - 274 - if (in_dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns > 0) 275 - dml_soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us = 276 - (in_dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns + 9) / 10; 277 - 278 - if (in_dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns > 0) 279 - dml_soc_bb->power_management_parameters.stutter_exit_latency_us = 280 - (in_dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns + 9) / 10; 281 - 282 - if (dc_bw_params->num_channels) { 283 - dml_clk_table->dram_config.channel_count = dc_bw_params->num_channels; 284 - dml_soc_bb->mall_allocated_for_dcn_mbytes = in_dc->caps.mall_size_total / 1048576; 285 - } else if (in_dc->ctx->dc_bios->vram_info.num_chans) { 286 - dml_clk_table->dram_config.channel_count = in_dc->ctx->dc_bios->vram_info.num_chans; 287 - dml_soc_bb->mall_allocated_for_dcn_mbytes = in_dc->caps.mall_size_total / 1048576; 288 - } 289 - 290 - if (dc_bw_params->dram_channel_width_bytes) { 291 - dml_clk_table->dram_config.channel_width_bytes = dc_bw_params->dram_channel_width_bytes; 292 - } else if (in_dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) { 293 - dml_clk_table->dram_config.channel_width_bytes = in_dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; 294 - } 295 - 296 - dml_init->soc_bb.xtalclk_mhz = in_dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency / 1000; 297 - } 298 - 299 - 300 - static void override_dml_init_with_values_from_dmub(struct dml2_initialize_instance_in_out *dml_init, 301 - const struct dml2_configuration_options *config, 302 - const struct dc *in_dc) 303 - { 304 - /* 305 - * TODO - There seems to be overlaps between the values overriden from 306 - * dmub and vbios. Investigate and identify the values that DMUB needs 307 - * to own. 308 - */ 309 - // const struct dmub_soc_bb_params *dmub_bb_params = 310 - // (const struct dmub_soc_bb_params *)config->bb_from_dmub; 311 - 312 - // if (dmub_bb_params == NULL) 313 - // return; 314 - 315 - // if (dmub_bb_params->dram_clk_change_blackout_ns > 0) 316 - // dml_init->soc_bb.power_management_parameters.dram_clk_change_blackout_us = 317 - // (double) dmub_bb_params->dram_clk_change_blackout_ns / 1000.0; 318 - // if (dmub_bb_params->dram_clk_change_read_only_ns > 0) 319 - // dml_init->soc_bb.power_management_parameters.dram_clk_change_read_only_us = 320 - // (double) dmub_bb_params->dram_clk_change_read_only_ns / 1000.0; 321 - // if (dmub_bb_params->dram_clk_change_write_only_ns > 0) 322 - // dml_init->soc_bb.power_management_parameters.dram_clk_change_write_only_us = 323 - // (double) dmub_bb_params->dram_clk_change_write_only_ns / 1000.0; 324 - // if (dmub_bb_params->fclk_change_blackout_ns > 0) 325 - // dml_init->soc_bb.power_management_parameters.fclk_change_blackout_us = 326 - // (double) dmub_bb_params->fclk_change_blackout_ns / 1000.0; 327 - // if (dmub_bb_params->g7_ppt_blackout_ns > 0) 328 - // dml_init->soc_bb.power_management_parameters.g7_ppt_blackout_us = 329 - // (double) dmub_bb_params->g7_ppt_blackout_ns / 1000.0; 330 - // if (dmub_bb_params->stutter_enter_plus_exit_latency_ns > 0) 331 - // dml_init->soc_bb.power_management_parameters.stutter_enter_plus_exit_latency_us = 332 - // (double) dmub_bb_params->stutter_enter_plus_exit_latency_ns / 1000.0; 333 - // if (dmub_bb_params->stutter_exit_latency_ns > 0) 334 - // dml_init->soc_bb.power_management_parameters.stutter_exit_latency_us = 335 - // (double) dmub_bb_params->stutter_exit_latency_ns / 1000.0; 336 - // if (dmub_bb_params->z8_stutter_enter_plus_exit_latency_ns > 0) 337 - // dml_init->soc_bb.power_management_parameters.z8_stutter_enter_plus_exit_latency_us = 338 - // (double) dmub_bb_params->z8_stutter_enter_plus_exit_latency_ns / 1000.0; 339 - // if (dmub_bb_params->z8_stutter_exit_latency_ns > 0) 340 - // dml_init->soc_bb.power_management_parameters.z8_stutter_exit_latency_us = 341 - // (double) dmub_bb_params->z8_stutter_exit_latency_ns / 1000.0; 342 - // if (dmub_bb_params->z8_min_idle_time_ns > 0) 343 - // dml_init->soc_bb.power_management_parameters.z8_min_idle_time = 344 - // (double) dmub_bb_params->z8_min_idle_time_ns / 1000.0; 345 - // #ifndef TRIM_DML2_DCN6B_IP_SENSITIVE 346 - // if (dmub_bb_params->type_b_dram_clk_change_blackout_ns > 0) 347 - // dml_init->soc_bb.power_management_parameters.lpddr5_dram_clk_change_blackout_us = 348 - // (double) dmub_bb_params->type_b_dram_clk_change_blackout_ns / 1000.0; 349 - // if (dmub_bb_params->type_b_ppt_blackout_ns > 0) 350 - // dml_init->soc_bb.power_management_parameters.lpddr5_ppt_blackout_us = 351 - // (double) dmub_bb_params->type_b_ppt_blackout_ns / 1000.0; 352 - // #else 353 - // if (dmub_bb_params->type_b_dram_clk_change_blackout_ns > 0) 354 - // dml_init->soc_bb.power_management_parameters.type_b_dram_clk_change_blackout_us = 355 - // (double) dmub_bb_params->type_b_dram_clk_change_blackout_ns / 1000.0; 356 - // if (dmub_bb_params->type_b_ppt_blackout_ns > 0) 357 - // dml_init->soc_bb.power_management_parameters.type_b_ppt_blackout_us = 358 - // (double) dmub_bb_params->type_b_ppt_blackout_ns / 1000.0; 359 - // #endif 360 - // if (dmub_bb_params->vmin_limit_dispclk_khz > 0) 361 - // dml_init->soc_bb.vmin_limit.dispclk_khz = dmub_bb_params->vmin_limit_dispclk_khz; 362 - // if (dmub_bb_params->vmin_limit_dcfclk_khz > 0) 363 - // dml_init->soc_bb.vmin_limit.dcfclk_khz = dmub_bb_params->vmin_limit_dcfclk_khz; 364 - // if (dmub_bb_params->g7_temperature_read_blackout_ns > 0) 365 - // dml_init->soc_bb.power_management_parameters.g7_temperature_read_blackout_us = 366 - // (double) dmub_bb_params->g7_temperature_read_blackout_ns / 1000.0; 367 - } 368 - 369 - static void override_dml_init_with_values_from_software_policy(struct dml2_initialize_instance_in_out *dml_init, 370 - const struct dml2_configuration_options *config, 371 - const struct dc *in_dc) 372 - { 373 - if (!config->use_native_soc_bb_construction) { 374 - dml_init->soc_bb = config->external_socbb_ip_params->soc_bb; 375 - dml_init->ip_caps = config->external_socbb_ip_params->ip_params; 376 - } 377 - 378 - if (in_dc->bb_overrides.sr_exit_time_ns) 379 - dml_init->soc_bb.power_management_parameters.stutter_exit_latency_us = 380 - in_dc->bb_overrides.sr_exit_time_ns / 1000.0; 381 - 382 - if (in_dc->bb_overrides.sr_enter_plus_exit_time_ns) 383 - dml_init->soc_bb.power_management_parameters.stutter_enter_plus_exit_latency_us = 384 - in_dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 385 - 386 - if (in_dc->bb_overrides.dram_clock_change_latency_ns) 387 - dml_init->soc_bb.power_management_parameters.dram_clk_change_blackout_us = 388 - in_dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 389 - 390 - if (in_dc->bb_overrides.fclk_clock_change_latency_ns) 391 - dml_init->soc_bb.power_management_parameters.fclk_change_blackout_us = 392 - in_dc->bb_overrides.fclk_clock_change_latency_ns / 1000.0; 54 + return project_id; 393 55 } 394 56 395 57 void dml21_populate_dml_init_params(struct dml2_initialize_instance_in_out *dml_init, 396 58 const struct dml2_configuration_options *config, 397 59 const struct dc *in_dc) 398 60 { 399 - populate_default_dml_init_params(dml_init, config, in_dc); 61 + dml_init->options.project_id = dml21_dcn_revision_to_dml2_project_id(in_dc->ctx->dce_version); 400 62 401 - override_dml_init_with_values_from_hardware_default(dml_init, config, in_dc); 63 + if (config->use_native_soc_bb_construction) { 64 + in_dc->soc_and_ip_translator->translator_funcs->get_soc_bb(&dml_init->soc_bb, in_dc, config); 65 + in_dc->soc_and_ip_translator->translator_funcs->get_ip_caps(&dml_init->ip_caps); 66 + } else { 67 + dml_init->soc_bb = config->external_socbb_ip_params->soc_bb; 68 + dml_init->ip_caps = config->external_socbb_ip_params->ip_params; 69 + } 402 70 403 - override_dml_init_with_values_from_smu(dml_init, config, in_dc); 404 - 405 - override_dml_init_with_values_from_vbios(dml_init, config, in_dc); 406 - 407 - override_dml_init_with_values_from_dmub(dml_init, config, in_dc); 408 - 409 - override_dml_init_with_values_from_software_policy(dml_init, config, in_dc); 71 + dml21_populate_pmo_options(&dml_init->options.pmo_options, in_dc, config); 410 72 } 411 73 412 74 static unsigned int calc_max_hardware_v_total(const struct dc_stream_state *stream) ··· 125 463 (stream->timing.h_total * (long long)calc_max_hardware_v_total(stream))); 126 464 } 127 465 128 - if (stream->timing.min_refresh_in_uhz > min_hardware_refresh_in_uhz) { 129 - timing->drr_config.min_refresh_uhz = stream->timing.min_refresh_in_uhz; 130 - } else { 131 - timing->drr_config.min_refresh_uhz = min_hardware_refresh_in_uhz; 132 - } 466 + timing->drr_config.min_refresh_uhz = max(stream->timing.min_refresh_in_uhz, min_hardware_refresh_in_uhz); 133 467 134 468 if (dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase && 135 469 stream->ctx->dc->config.enable_fpo_flicker_detection == 1) ··· 823 1165 context->bw_ctx.bw.dcn.clk.socclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.socclk_khz; 824 1166 context->bw_ctx.bw.dcn.clk.subvp_prefetch_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz; 825 1167 context->bw_ctx.bw.dcn.clk.subvp_prefetch_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz; 1168 + context->bw_ctx.bw.dcn.clk.stutter_efficiency.base_efficiency = in_ctx->v21.mode_programming.programming->stutter.base_percent_efficiency; 1169 + context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency; 826 1170 } 827 1171 828 1172 static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index wm_index)
+1 -1
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
··· 60 60 61 61 DC_FP_START(); 62 62 63 - dml21_populate_dml_init_params(&dml_ctx->v21.dml_init, config, in_dc); 63 + dml21_populate_dml_init_params(&dml_ctx->v21.dml_init, &dml_ctx->config, in_dc); 64 64 65 65 dml2_initialize_instance(&dml_ctx->v21.dml_init); 66 66
+2
drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h
··· 159 159 uint32_t sr_exit; 160 160 uint32_t sr_enter_z8; 161 161 uint32_t sr_exit_z8; 162 + uint32_t sr_enter_low_power; 163 + uint32_t sr_exit_low_power; 162 164 uint32_t uclk_pstate; 163 165 uint32_t fclk_pstate; 164 166 uint32_t temp_read_or_ppt;
+2
drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h
··· 96 96 double g7_temperature_read_blackout_us; 97 97 double stutter_enter_plus_exit_latency_us; 98 98 double stutter_exit_latency_us; 99 + double low_power_stutter_enter_plus_exit_latency_us; 100 + double low_power_stutter_exit_latency_us; 99 101 double z8_stutter_enter_plus_exit_latency_us; 100 102 double z8_stutter_exit_latency_us; 101 103 double z8_min_idle_time;
+2
drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h
··· 417 417 418 418 struct { 419 419 bool supported_in_blank; // Changing to configurations where this is false requires stutter to be disabled during the transition 420 + uint8_t base_percent_efficiency; //LP1 421 + uint8_t low_power_percent_efficiency; //LP2 420 422 } stutter; 421 423 422 424 struct {
+19 -9
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
··· 1238 1238 1239 1239 static double CalculateRequiredDispclk( 1240 1240 enum dml2_odm_mode ODMMode, 1241 - double PixelClock) 1241 + double PixelClock, 1242 + bool isTMDS420) 1242 1243 { 1244 + double DispClk; 1243 1245 1244 1246 if (ODMMode == dml2_odm_mode_combine_4to1) { 1245 - return PixelClock / 4.0; 1247 + DispClk = PixelClock / 4.0; 1246 1248 } else if (ODMMode == dml2_odm_mode_combine_3to1) { 1247 - return PixelClock / 3.0; 1249 + DispClk = PixelClock / 3.0; 1248 1250 } else if (ODMMode == dml2_odm_mode_combine_2to1) { 1249 - return PixelClock / 2.0; 1251 + DispClk = PixelClock / 2.0; 1250 1252 } else { 1251 - return PixelClock; 1253 + DispClk = PixelClock; 1252 1254 } 1255 + 1256 + if (isTMDS420) { 1257 + double TMDS420MinPixClock = PixelClock / 2.0; 1258 + DispClk = math_max2(DispClk, TMDS420MinPixClock); 1259 + } 1260 + 1261 + return DispClk; 1253 1262 } 1254 1263 1255 1264 static double TruncToValidBPP( ··· 4131 4122 bool success; 4132 4123 bool UseDSC = DSCEnable && (NumberOfDSCSlices > 0); 4133 4124 enum dml2_odm_mode DecidedODMMode; 4125 + bool isTMDS420 = (OutFormat == dml2_420 && Output == dml2_hdmi); 4134 4126 4135 - SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml2_odm_mode_bypass, PixelClock); 4136 - SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_2to1, PixelClock); 4137 - SurfaceRequiredDISPCLKWithODMCombineThreeToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_3to1, PixelClock); 4138 - SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_4to1, PixelClock); 4127 + SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml2_odm_mode_bypass, PixelClock, isTMDS420); 4128 + SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_2to1, PixelClock, isTMDS420); 4129 + SurfaceRequiredDISPCLKWithODMCombineThreeToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_3to1, PixelClock, isTMDS420); 4130 + SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_4to1, PixelClock, isTMDS420); 4139 4131 #ifdef __DML_VBA_DEBUG__ 4140 4132 DML_LOG_VERBOSE("DML::%s: ODMUse = %d\n", __func__, ODMUse); 4141 4133 DML_LOG_VERBOSE("DML::%s: Output = %d\n", __func__, Output);
+1 -1
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c
··· 10 10 { 11 11 bool result = false; 12 12 13 - if (out == 0) 13 + if (!out) 14 14 return false; 15 15 16 16 memset(out, 0, sizeof(struct dml2_core_instance));
+12
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
··· 201 201 double WritebackFCLKChangeWatermark; 202 202 double StutterExitWatermark; 203 203 double StutterEnterPlusExitWatermark; 204 + double LowPowerStutterExitWatermark; 205 + double LowPowerStutterEnterPlusExitWatermark; 204 206 double Z8StutterExitWatermark; 205 207 double Z8StutterEnterPlusExitWatermark; 206 208 double USRRetrainingWatermark; ··· 879 877 double Z8StutterEfficiency; 880 878 unsigned int Z8NumberOfStutterBurstsPerFrame; 881 879 double Z8StutterEfficiencyNotIncludingVBlank; 880 + double LowPowerStutterEfficiency; 881 + double LowPowerStutterEfficiencyNotIncludingVBlank; 882 + unsigned int LowPowerNumberOfStutterBurstsPerFrame; 882 883 double StutterPeriod; 883 884 double Z8StutterEfficiencyBestCase; 884 885 unsigned int Z8NumberOfStutterBurstsPerFrameBestCase; ··· 1021 1016 double FCLKChangeLatency; 1022 1017 double SRExitTime; 1023 1018 double SREnterPlusExitTime; 1019 + double SRExitTimeLowPower; 1020 + double SREnterPlusExitTimeLowPower; 1024 1021 double SRExitZ8Time; 1025 1022 double SREnterPlusExitZ8Time; 1026 1023 double USRRetrainingLatency; ··· 1858 1851 unsigned int CompbufReservedSpaceZs; 1859 1852 bool hw_debug5; 1860 1853 double SRExitTime; 1854 + double SRExitTimeLowPower; 1861 1855 double SRExitZ8Time; 1862 1856 bool SynchronizeTimings; 1863 1857 double StutterEnterPlusExitWatermark; 1858 + double LowPowerStutterEnterPlusExitWatermark; 1864 1859 double Z8StutterEnterPlusExitWatermark; 1865 1860 bool ProgressiveToInterlaceUnitInOPP; 1866 1861 double *MinTTUVBlank; ··· 1888 1879 // output 1889 1880 double *StutterEfficiencyNotIncludingVBlank; 1890 1881 double *StutterEfficiency; 1882 + double *LowPowerStutterEfficiencyNotIncludingVBlank; 1883 + double *LowPowerStutterEfficiency; 1891 1884 unsigned int *NumberOfStutterBurstsPerFrame; 1885 + unsigned int *LowPowerNumberOfStutterBurstsPerFrame; 1892 1886 double *Z8StutterEfficiencyNotIncludingVBlank; 1893 1887 double *Z8StutterEfficiency; 1894 1888 unsigned int *Z8NumberOfStutterBurstsPerFrame;
+1 -1
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
··· 20 20 { 21 21 bool result = false; 22 22 23 - if (out == 0) 23 + if (!out) 24 24 return false; 25 25 26 26 memset(out, 0, sizeof(struct dml2_dpmm_instance));
+1 -1
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c
··· 15 15 { 16 16 bool result = false; 17 17 18 - if (out == 0) 18 + if (!out) 19 19 return false; 20 20 21 21 memset(out, 0, sizeof(struct dml2_mcg_instance));
+1 -1
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c
··· 26 26 { 27 27 bool result = false; 28 28 29 - if (out == 0) 29 + if (!out) 30 30 return false; 31 31 32 32 memset(out, 0, sizeof(struct dml2_pmo_instance));
+2 -4
drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
··· 473 473 { 474 474 bool sorted, swapped; 475 475 unsigned int cur_index; 476 - unsigned int temp; 477 476 int odm_slice_index; 478 477 479 478 for (odm_slice_index = 0; odm_slice_index < pipes->num_pipes_assigned_to_plane_for_odm_combine; odm_slice_index++) { ··· 488 489 swapped = false; 489 490 while (!sorted) { 490 491 if (pipes->pipes_assigned_to_plane[odm_slice_index][cur_index] > pipes->pipes_assigned_to_plane[odm_slice_index][cur_index + 1]) { 491 - temp = pipes->pipes_assigned_to_plane[odm_slice_index][cur_index]; 492 - pipes->pipes_assigned_to_plane[odm_slice_index][cur_index] = pipes->pipes_assigned_to_plane[odm_slice_index][cur_index + 1]; 493 - pipes->pipes_assigned_to_plane[odm_slice_index][cur_index + 1] = temp; 492 + swap(pipes->pipes_assigned_to_plane[odm_slice_index][cur_index + 1], 493 + pipes->pipes_assigned_to_plane[odm_slice_index][cur_index]); 494 494 495 495 swapped = true; 496 496 }
+2 -4
drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
··· 654 654 unsigned int svp_height, 655 655 unsigned int svp_vstartup) 656 656 { 657 - unsigned int i, pipe_idx; 657 + unsigned int i; 658 658 double line_time, fp_and_sync_width_time; 659 659 struct pipe_ctx *pipe; 660 660 uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines; 661 661 static const double cvt_rb_vblank_max = ((double) 460 / (1000 * 1000)); 662 662 663 663 // Find DML pipe index (pipe_idx) using dc_pipe_idx 664 - for (i = 0, pipe_idx = 0; i < ctx->config.dcn_pipe_count; i++) { 664 + for (i = 0; i < ctx->config.dcn_pipe_count; i++) { 665 665 pipe = &state->res_ctx.pipe_ctx[i]; 666 666 667 667 if (!pipe->stream) ··· 669 669 670 670 if (i == dc_pipe_idx) 671 671 break; 672 - 673 - pipe_idx++; 674 672 } 675 673 676 674 // Calculate lines required for pstate allow width and FW processing delays
+9
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
··· 520 520 REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0); 521 521 } 522 522 523 + void dpp_force_disable_cursor(struct dpp *dpp_base) 524 + { 525 + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); 526 + 527 + /* Force disable cursor */ 528 + REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, 0); 529 + dpp_base->pos.cur0_ctl.bits.cur0_enable = 0; 530 + } 531 + 523 532 static const struct dpp_funcs dcn10_dpp_funcs = { 524 533 .dpp_read_state = dpp_read_state, 525 534 .dpp_reset = dpp_reset,
+2
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.h
··· 1525 1525 1526 1526 void dpp1_cm_get_gamut_remap(struct dpp *dpp_base, 1527 1527 struct dpp_grph_csc_adjustment *adjust); 1528 + void dpp_force_disable_cursor(struct dpp *dpp_base); 1529 + 1528 1530 #endif
+1
drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c
··· 1494 1494 .dpp_dppclk_control = dpp1_dppclk_control, 1495 1495 .dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier, 1496 1496 .dpp_get_gamut_remap = dpp3_cm_get_gamut_remap, 1497 + .dpp_force_disable_cursor = dpp_force_disable_cursor, 1497 1498 }; 1498 1499 1499 1500
+10
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h
··· 673 673 struct pwl_params pwl_data; 674 674 }; 675 675 676 + enum dcn401_dscl_mode_sel { 677 + DCN401_DSCL_MODE_SCALING_444_BYPASS = 0, 678 + DCN401_DSCL_MODE_SCALING_444_RGB_ENABLE = 1, 679 + DCN401_DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2, 680 + DCN401_DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3, 681 + DCN401_DSCL_MODE_SCALING_420_LUMA_BYPASS = 4, 682 + DCN401_DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5, 683 + DCN401_DSCL_MODE_DSCL_BYPASS = 6 684 + }; 685 + 676 686 bool dpp401_construct(struct dcn401_dpp *dpp401, 677 687 struct dc_context *ctx, 678 688 uint32_t inst,
+13 -23
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
··· 78 78 AUTOCAL_MODE_AUTOREPLICATE = 3 79 79 }; 80 80 81 - enum dscl_mode_sel { 82 - DSCL_MODE_SCALING_444_BYPASS = 0, 83 - DSCL_MODE_SCALING_444_RGB_ENABLE = 1, 84 - DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2, 85 - DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3, 86 - DSCL_MODE_SCALING_420_LUMA_BYPASS = 4, 87 - DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5, 88 - DSCL_MODE_DSCL_BYPASS = 6 89 - }; 90 - 91 81 static int dpp401_dscl_get_pixel_depth_val(enum lb_pixel_depth depth) 92 82 { 93 83 if (depth == LB_PIXEL_DEPTH_30BPP) ··· 112 122 return false; 113 123 } 114 124 115 - static enum dscl_mode_sel dpp401_dscl_get_dscl_mode( 125 + static enum dcn401_dscl_mode_sel dpp401_dscl_get_dscl_mode( 116 126 struct dpp *dpp_base, 117 127 const struct scaler_data *data, 118 128 bool dbg_always_scale) ··· 122 132 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { 123 133 /* DSCL is processing data in fixed format */ 124 134 if (data->format == PIXEL_FORMAT_FP16) 125 - return DSCL_MODE_DSCL_BYPASS; 135 + return DCN401_DSCL_MODE_DSCL_BYPASS; 126 136 } 127 137 128 138 if (data->ratios.horz.value == one ··· 130 140 && data->ratios.horz_c.value == one 131 141 && data->ratios.vert_c.value == one 132 142 && !dbg_always_scale) 133 - return DSCL_MODE_SCALING_444_BYPASS; 143 + return DCN401_DSCL_MODE_SCALING_444_BYPASS; 134 144 135 145 if (!dpp401_dscl_is_420_format(data->format)) { 136 146 if (dpp401_dscl_is_video_format(data->format)) 137 - return DSCL_MODE_SCALING_444_YCBCR_ENABLE; 147 + return DCN401_DSCL_MODE_SCALING_444_YCBCR_ENABLE; 138 148 else 139 - return DSCL_MODE_SCALING_444_RGB_ENABLE; 149 + return DCN401_DSCL_MODE_SCALING_444_RGB_ENABLE; 140 150 } 141 151 if (data->ratios.horz.value == one && data->ratios.vert.value == one) 142 - return DSCL_MODE_SCALING_420_LUMA_BYPASS; 152 + return DCN401_DSCL_MODE_SCALING_420_LUMA_BYPASS; 143 153 if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) 144 - return DSCL_MODE_SCALING_420_CHROMA_BYPASS; 154 + return DCN401_DSCL_MODE_SCALING_420_CHROMA_BYPASS; 145 155 146 - return DSCL_MODE_SCALING_420_YCBCR_ENABLE; 156 + return DCN401_DSCL_MODE_SCALING_420_YCBCR_ENABLE; 147 157 } 148 158 149 159 static void dpp401_power_on_dscl( ··· 1061 1071 uint32_t v_num_taps_c = scl_data->taps.v_taps_c - 1; 1062 1072 uint32_t h_num_taps = scl_data->taps.h_taps - 1; 1063 1073 uint32_t h_num_taps_c = scl_data->taps.h_taps_c - 1; 1064 - enum dscl_mode_sel dscl_mode = dpp401_dscl_get_dscl_mode( 1074 + enum dcn401_dscl_mode_sel dscl_mode = dpp401_dscl_get_dscl_mode( 1065 1075 dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); 1066 1076 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 1067 1077 && scl_data->format <= PIXEL_FORMAT_VIDEO_END; ··· 1092 1102 dpp->scl_data = *scl_data; 1093 1103 1094 1104 if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) { 1095 - dscl_mode = (enum dscl_mode_sel) scl_data->dscl_prog_data.dscl_mode; 1105 + dscl_mode = (enum dcn401_dscl_mode_sel) scl_data->dscl_prog_data.dscl_mode; 1096 1106 rect = (struct rect *)&scl_data->dscl_prog_data.recout; 1097 1107 mpc_width = scl_data->dscl_prog_data.mpc_size.width; 1098 1108 mpc_height = scl_data->dscl_prog_data.mpc_size.height; ··· 1102 1112 h_num_taps_c = scl_data->dscl_prog_data.taps.h_taps_c; 1103 1113 } 1104 1114 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl) { 1105 - if (dscl_mode != DSCL_MODE_DSCL_BYPASS) 1115 + if (dscl_mode != DCN401_DSCL_MODE_DSCL_BYPASS) 1106 1116 dpp401_power_on_dscl(dpp_base, true); 1107 1117 } 1108 1118 ··· 1129 1139 /* SCL mode */ 1130 1140 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); 1131 1141 1132 - if (dscl_mode == DSCL_MODE_DSCL_BYPASS) { 1142 + if (dscl_mode == DCN401_DSCL_MODE_DSCL_BYPASS) { 1133 1143 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl) 1134 1144 dpp401_power_on_dscl(dpp_base, false); 1135 1145 return; ··· 1139 1149 lb_config = dpp401_dscl_find_lb_memory_config(dpp, scl_data); 1140 1150 dpp401_dscl_set_lb(dpp, &scl_data->lb_params, lb_config); 1141 1151 1142 - if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) { 1152 + if (dscl_mode == DCN401_DSCL_MODE_SCALING_444_BYPASS) { 1143 1153 if (dpp->base.ctx->dc->config.prefer_easf) 1144 1154 dpp401_dscl_disable_easf(dpp_base, scl_data); 1145 1155 dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
+5
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
··· 1157 1157 if (!is_dsc_possible) 1158 1158 goto done; 1159 1159 1160 + /* increase miniumum slice count to meet sink slice width limitations */ 1161 + min_slices_h = dc_fixpt_ceil(dc_fixpt_max( 1162 + dc_fixpt_div_int(dc_fixpt_from_int(pic_width), dsc_common_caps.max_slice_width), // sink min 1163 + dc_fixpt_from_int(min_slices_h))); // source min 1164 + 1160 1165 min_slices_h = fit_num_slices_up(dsc_common_caps.slice_caps, min_slices_h); 1161 1166 1162 1167 /* increase minimum slice count to meet sink throughput limitations */
+31
drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c
··· 440 440 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, reg); 441 441 } 442 442 443 + void hubbub3_get_det_sizes(struct hubbub *hubbub, uint32_t *curr_det_sizes, uint32_t *target_det_sizes) 444 + { 445 + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 446 + 447 + REG_GET_2(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, &curr_det_sizes[0], 448 + DET0_SIZE, &target_det_sizes[0]); 449 + 450 + REG_GET_2(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, &curr_det_sizes[1], 451 + DET1_SIZE, &target_det_sizes[1]); 452 + 453 + REG_GET_2(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, &curr_det_sizes[2], 454 + DET2_SIZE, &target_det_sizes[2]); 455 + 456 + REG_GET_2(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, &curr_det_sizes[3], 457 + DET3_SIZE, &target_det_sizes[3]); 458 + 459 + } 460 + 461 + uint32_t hubbub3_compbuf_config_error(struct hubbub *hubbub) 462 + { 463 + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 464 + uint32_t compbuf_config_error = 0; 465 + 466 + REG_GET(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, 467 + &compbuf_config_error); 468 + 469 + return compbuf_config_error; 470 + } 471 + 443 472 static const struct hubbub_funcs hubbub30_funcs = { 444 473 .update_dchub = hubbub2_update_dchub, 445 474 .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, ··· 486 457 .force_pstate_change_control = hubbub3_force_pstate_change_control, 487 458 .init_watermarks = hubbub3_init_watermarks, 488 459 .hubbub_read_state = hubbub2_read_state, 460 + .get_det_sizes = hubbub3_get_det_sizes, 461 + .compbuf_config_error = hubbub3_compbuf_config_error, 489 462 }; 490 463 491 464 void hubbub3_construct(struct dcn20_hubbub *hubbub3,
+6
drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h
··· 133 133 134 134 void hubbub3_init_watermarks(struct hubbub *hubbub); 135 135 136 + void hubbub3_get_det_sizes(struct hubbub *hubbub, 137 + uint32_t *curr_det_sizes, 138 + uint32_t *target_det_sizes); 139 + 140 + uint32_t hubbub3_compbuf_config_error(struct hubbub *hubbub); 141 + 136 142 #endif
+2
drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c
··· 1071 1071 .program_compbuf_size = dcn31_program_compbuf_size, 1072 1072 .init_crb = dcn31_init_crb, 1073 1073 .hubbub_read_state = hubbub2_read_state, 1074 + .get_det_sizes = hubbub3_get_det_sizes, 1075 + .compbuf_config_error = hubbub3_compbuf_config_error, 1074 1076 }; 1075 1077 1076 1078 void hubbub31_construct(struct dcn20_hubbub *hubbub31,
+2
drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c
··· 1009 1009 .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow, 1010 1010 .set_request_limit = hubbub32_set_request_limit, 1011 1011 .get_mall_en = hubbub32_get_mall_en, 1012 + .get_det_sizes = hubbub3_get_det_sizes, 1013 + .compbuf_config_error = hubbub3_compbuf_config_error, 1012 1014 }; 1013 1015 1014 1016 void hubbub32_construct(struct dcn20_hubbub *hubbub2,
+2
drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
··· 589 589 .hubbub_read_state = hubbub2_read_state, 590 590 .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow, 591 591 .dchubbub_init = hubbub35_init, 592 + .get_det_sizes = hubbub3_get_det_sizes, 593 + .compbuf_config_error = hubbub3_compbuf_config_error, 592 594 }; 593 595 594 596 void hubbub35_construct(struct dcn20_hubbub *hubbub2,
+2
drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
··· 1247 1247 .program_compbuf_segments = dcn401_program_compbuf_segments, 1248 1248 .wait_for_det_update = dcn401_wait_for_det_update, 1249 1249 .program_arbiter = dcn401_program_arbiter, 1250 + .get_det_sizes = hubbub3_get_det_sizes, 1251 + .compbuf_config_error = hubbub3_compbuf_config_error, 1250 1252 }; 1251 1253 1252 1254 void hubbub401_construct(struct dcn20_hubbub *hubbub2,
+7 -2
drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h
··· 104 104 SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\ 105 105 SRI(DCN_CUR0_TTU_CNTL0, HUBPREQ, id),\ 106 106 SRI(DCN_CUR0_TTU_CNTL1, HUBPREQ, id),\ 107 - SRI(HUBP_CLK_CNTL, HUBP, id) 107 + SRI(HUBP_CLK_CNTL, HUBP, id),\ 108 + SRI(HUBPRET_READ_LINE_VALUE, HUBPRET, id) 108 109 109 110 /* Register address initialization macro for ASICs with VM */ 110 111 #define HUBP_REG_LIST_DCN_VM(id)\ ··· 250 249 uint32_t CURSOR_POSITION; \ 251 250 uint32_t CURSOR_HOT_SPOT; \ 252 251 uint32_t CURSOR_DST_OFFSET; \ 253 - uint32_t HUBP_CLK_CNTL 252 + uint32_t HUBP_CLK_CNTL; \ 253 + uint32_t HUBPRET_READ_LINE_VALUE 254 254 255 255 #define HUBP_SF(reg_name, field_name, post_fix)\ 256 256 .field_name = reg_name ## __ ## field_name ## post_fix ··· 624 622 type DCN_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\ 625 623 type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\ 626 624 type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\ 625 + type PIPE_READ_LINE;\ 626 + type HUBP_SEG_ALLOC_ERR_STATUS;\ 627 627 /* todo: get these from GVM instead of reading registers ourselves */\ 628 628 type PAGE_DIRECTORY_ENTRY_HI32;\ 629 629 type PAGE_DIRECTORY_ENTRY_LO32;\ ··· 675 671 uint32_t lut_done; 676 672 uint32_t lut_addr_mode; 677 673 uint32_t lut_width; 674 + uint32_t lut_mpc_width; 678 675 uint32_t lut_tmz; 679 676 uint32_t lut_crossbar_sel_r; 680 677 uint32_t lut_crossbar_sel_g;
+1
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h
··· 264 264 type HUBP_3DLUT_DONE;\ 265 265 type HUBP_3DLUT_ADDRESSING_MODE;\ 266 266 type HUBP_3DLUT_WIDTH;\ 267 + type HUBP_3DLUT_MPC_WIDTH;\ 267 268 type HUBP_3DLUT_TMZ;\ 268 269 type HUBP_3DLUT_CROSSBAR_SELECT_Y_G;\ 269 270 type HUBP_3DLUT_CROSSBAR_SELECT_CB_B;\
+26
drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
··· 505 505 hubp_reset(hubp); 506 506 } 507 507 508 + uint32_t hubp3_get_current_read_line(struct hubp *hubp) 509 + { 510 + uint32_t read_line = 0; 511 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 512 + 513 + REG_GET(HUBPRET_READ_LINE_VALUE, 514 + PIPE_READ_LINE, 515 + &read_line); 516 + 517 + return read_line; 518 + } 519 + 520 + unsigned int hubp3_get_underflow_status(struct hubp *hubp) 521 + { 522 + uint32_t hubp_underflow = 0; 523 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 524 + 525 + REG_GET(DCHUBP_CNTL, 526 + HUBP_UNDERFLOW_STATUS, 527 + &hubp_underflow); 528 + 529 + return hubp_underflow; 530 + } 531 + 508 532 static struct hubp_funcs dcn30_hubp_funcs = { 509 533 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, 510 534 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, ··· 558 534 .hubp_soft_reset = hubp1_soft_reset, 559 535 .hubp_set_flip_int = hubp1_set_flip_int, 560 536 .hubp_clear_tiling = hubp3_clear_tiling, 537 + .hubp_get_underflow_status = hubp3_get_underflow_status, 538 + .hubp_get_current_read_line = hubp3_get_current_read_line, 561 539 }; 562 540 563 541 bool hubp3_construct(
+7 -1
drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h
··· 243 243 HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_6, REFCYC_PER_META_CHUNK_FLIP_C, mask_sh),\ 244 244 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, mask_sh),\ 245 245 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_6, REFCYC_PER_VM_REQ_VBLANK, mask_sh),\ 246 - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh) 246 + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh),\ 247 + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh) 247 248 248 249 bool hubp3_construct( 249 250 struct dcn20_hubp *hubp2, ··· 299 298 void hubp3_init(struct hubp *hubp); 300 299 301 300 void hubp3_clear_tiling(struct hubp *hubp); 301 + 302 + uint32_t hubp3_get_current_read_line(struct hubp *hubp); 303 + 304 + uint32_t hubp3_get_underflow_status(struct hubp *hubp); 305 + 302 306 303 307 #endif /* __DC_HUBP_DCN30_H__ */ 304 308
+15
drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c
··· 68 68 hubp31_program_extended_blank(hubp, min_dst_y_next_start_optimized); 69 69 } 70 70 71 + uint32_t hubp31_get_det_config_error(struct hubp *hubp) 72 + { 73 + uint32_t config_error = 0; 74 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 75 + 76 + REG_GET(DCHUBP_CNTL, 77 + HUBP_SEG_ALLOC_ERR_STATUS, 78 + &config_error); 79 + 80 + return config_error; 81 + } 82 + 71 83 static struct hubp_funcs dcn31_hubp_funcs = { 72 84 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, 73 85 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, ··· 110 98 .hubp_in_blank = hubp1_in_blank, 111 99 .program_extended_blank = hubp31_program_extended_blank, 112 100 .hubp_clear_tiling = hubp3_clear_tiling, 101 + .hubp_get_underflow_status = hubp3_get_underflow_status, 102 + .hubp_get_current_read_line = hubp3_get_current_read_line, 103 + .hubp_get_det_config_error = hubp31_get_det_config_error, 113 104 }; 114 105 115 106 bool hubp31_construct(
+5 -1
drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h
··· 228 228 HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_6, REFCYC_PER_META_CHUNK_FLIP_C, mask_sh),\ 229 229 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, mask_sh),\ 230 230 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_6, REFCYC_PER_VM_REQ_VBLANK, mask_sh),\ 231 - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh) 231 + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh),\ 232 + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh),\ 233 + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_SEG_ALLOC_ERR_STATUS, mask_sh) 232 234 233 235 234 236 bool hubp31_construct( ··· 247 245 248 246 void hubp31_program_extended_blank_value( 249 247 struct hubp *hubp, unsigned int min_dst_y_next_start_optimized); 248 + 249 + uint32_t hubp31_get_det_config_error(struct hubp *hubp); 250 250 251 251 #endif /* __DC_HUBP_DCN31_H__ */
+3
drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c
··· 206 206 .hubp_update_mall_sel = hubp32_update_mall_sel, 207 207 .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering, 208 208 .hubp_clear_tiling = hubp3_clear_tiling, 209 + .hubp_get_underflow_status = hubp3_get_underflow_status, 210 + .hubp_get_current_read_line = hubp3_get_current_read_line, 211 + .hubp_get_det_config_error = hubp31_get_det_config_error, 209 212 }; 210 213 211 214 bool hubp32_construct(
+3
drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
··· 218 218 .hubp_in_blank = hubp1_in_blank, 219 219 .program_extended_blank = hubp31_program_extended_blank_value, 220 220 .hubp_clear_tiling = hubp3_clear_tiling, 221 + .hubp_get_underflow_status = hubp3_get_underflow_status, 222 + .hubp_get_current_read_line = hubp3_get_current_read_line, 223 + .hubp_get_det_config_error = hubp31_get_det_config_error, 221 224 }; 222 225 223 226 bool hubp35_construct(
+41
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
··· 127 127 REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format); 128 128 } 129 129 130 + void hubp401_program_3dlut_fl_config( 131 + struct hubp *hubp, 132 + struct hubp_fl_3dlut_config *cfg) 133 + { 134 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 135 + 136 + uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1}; 137 + uint32_t width = {cfg->width}; 138 + 139 + if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR) 140 + width = (cfg->width == 17) ? 4916 : 35940; 141 + 142 + REG_UPDATE_2(_3DLUT_FL_CONFIG, 143 + HUBP0_3DLUT_FL_MODE, cfg->mode, 144 + HUBP0_3DLUT_FL_FORMAT, cfg->format); 145 + 146 + REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, 147 + HUBP0_3DLUT_FL_BIAS, cfg->bias, 148 + HUBP0_3DLUT_FL_SCALE, cfg->scale); 149 + 150 + REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, 151 + HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part); 152 + REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW, 153 + HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part); 154 + 155 + //cross bar 156 + REG_UPDATE_8(HUBP_3DLUT_CONTROL, 157 + HUBP_3DLUT_MPC_WIDTH, mpc_width, 158 + HUBP_3DLUT_WIDTH, width, 159 + HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r, 160 + HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g, 161 + HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b, 162 + HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode, 163 + HUBP_3DLUT_TMZ, cfg->protection_bits, 164 + HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0); 165 + } 166 + 130 167 void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor) 131 168 { 132 169 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ··· 1070 1033 .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar, 1071 1034 .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, 1072 1035 .hubp_clear_tiling = hubp401_clear_tiling, 1036 + .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, 1037 + .hubp_get_underflow_status = hubp3_get_underflow_status, 1038 + .hubp_get_current_read_line = hubp3_get_current_read_line, 1039 + .hubp_get_det_config_error = hubp31_get_det_config_error, 1073 1040 }; 1074 1041 1075 1042 bool hubp401_construct(
+7 -1
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
··· 252 252 HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_1H_P0, mask_sh),\ 253 253 HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P0, mask_sh),\ 254 254 HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_1H_P1, mask_sh),\ 255 - HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P1, mask_sh) 255 + HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P1, mask_sh),\ 256 + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh),\ 257 + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_SEG_ALLOC_ERR_STATUS, mask_sh) 256 258 257 259 void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor); 258 260 ··· 350 348 void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format); 351 349 352 350 void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode); 351 + 352 + void hubp401_program_3dlut_fl_config( 353 + struct hubp *hubp, 354 + struct hubp_fl_3dlut_config *cfg); 353 355 354 356 void hubp401_clear_tiling(struct hubp *hubp); 355 357
+18 -21
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
··· 671 671 uint32_t early_control = 0; 672 672 struct timing_generator *tg = pipe_ctx->stream_res.tg; 673 673 674 + link_hwss->setup_stream_attribute(pipe_ctx); 674 675 link_hwss->setup_stream_encoder(pipe_ctx); 675 676 676 677 dc->hwss.update_info_frame(pipe_ctx); ··· 1270 1269 pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 1271 1270 } 1272 1271 1273 - static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 1272 + enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 1274 1273 { 1275 1274 switch (crtc_id) { 1276 1275 case CONTROLLER_ID_D0: ··· 1290 1289 } 1291 1290 } 1292 1291 1293 - static void populate_audio_dp_link_info( 1292 + void populate_audio_dp_link_info( 1294 1293 const struct pipe_ctx *pipe_ctx, 1295 1294 struct audio_dp_link_info *dp_link_info) 1296 1295 { ··· 1601 1600 } 1602 1601 1603 1602 if (pipe_ctx->stream_res.audio != NULL) { 1604 - struct audio_output audio_output = {0}; 1603 + build_audio_output(context, pipe_ctx, &pipe_ctx->stream_res.audio_output); 1605 1604 1606 - build_audio_output(context, pipe_ctx, &audio_output); 1607 - 1608 - link_hwss->setup_audio_output(pipe_ctx, &audio_output, 1605 + link_hwss->setup_audio_output(pipe_ctx, &pipe_ctx->stream_res.audio_output, 1609 1606 pipe_ctx->stream_res.audio->inst); 1610 1607 1611 1608 pipe_ctx->stream_res.audio->funcs->az_configure( 1612 1609 pipe_ctx->stream_res.audio, 1613 1610 pipe_ctx->stream->signal, 1614 - &audio_output.crtc_info, 1611 + &pipe_ctx->stream_res.audio_output.crtc_info, 1615 1612 &pipe_ctx->stream->audio_info, 1616 - &audio_output.dp_link_info); 1613 + &pipe_ctx->stream_res.audio_output.dp_link_info); 1617 1614 1618 1615 if (dc->config.disable_hbr_audio_dp2) 1619 1616 if (pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio && ··· 2253 2254 /* 2254 2255 * Enable FBC 2255 2256 */ 2256 - static void enable_fbc( 2257 + void enable_fbc( 2257 2258 struct dc *dc, 2258 2259 struct dc_state *context) 2259 2260 { ··· 2385 2386 if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 2386 2387 continue; 2387 2388 if (pipe_ctx->stream_res.audio != NULL) { 2388 - struct audio_output audio_output; 2389 - 2390 - build_audio_output(context, pipe_ctx, &audio_output); 2389 + build_audio_output(context, pipe_ctx, &pipe_ctx->stream_res.audio_output); 2391 2390 2392 2391 if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) { 2393 2392 struct dtbclk_dto_params dto_params = {0}; ··· 2396 2399 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2397 2400 pipe_ctx->stream_res.audio, 2398 2401 pipe_ctx->stream->signal, 2399 - &audio_output.crtc_info, 2400 - &audio_output.pll_info); 2402 + &pipe_ctx->stream_res.audio_output.crtc_info, 2403 + &pipe_ctx->stream_res.audio_output.pll_info); 2401 2404 } else 2402 2405 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2403 2406 pipe_ctx->stream_res.audio, 2404 2407 pipe_ctx->stream->signal, 2405 - &audio_output.crtc_info, 2406 - &audio_output.pll_info); 2408 + &pipe_ctx->stream_res.audio_output.crtc_info, 2409 + &pipe_ctx->stream_res.audio_output.pll_info); 2407 2410 break; 2408 2411 } 2409 2412 } ··· 2423 2426 continue; 2424 2427 2425 2428 if (pipe_ctx->stream_res.audio != NULL) { 2426 - struct audio_output audio_output = {0}; 2427 - 2428 - build_audio_output(context, pipe_ctx, &audio_output); 2429 + build_audio_output(context, 2430 + pipe_ctx, 2431 + &pipe_ctx->stream_res.audio_output); 2429 2432 2430 2433 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2431 2434 pipe_ctx->stream_res.audio, 2432 2435 pipe_ctx->stream->signal, 2433 - &audio_output.crtc_info, 2434 - &audio_output.pll_info); 2436 + &pipe_ctx->stream_res.audio_output.crtc_info, 2437 + &pipe_ctx->stream_res.audio_output.pll_info); 2435 2438 break; 2436 2439 } 2437 2440 }
+7
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.h
··· 114 114 struct dc_state *state, 115 115 const struct pipe_ctx *pipe_ctx, 116 116 struct audio_output *audio_output); 117 + enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id); 118 + void populate_audio_dp_link_info( 119 + const struct pipe_ctx *pipe_ctx, 120 + struct audio_dp_link_info *dp_link_info); 121 + void enable_fbc( 122 + struct dc *dc, 123 + struct dc_state *context); 117 124 #endif /* __DC_HWSS_DCE110_H__ */ 118 125
+76 -60
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
··· 328 328 } 329 329 330 330 DTN_INFO("\n=======HUBP FL======\n"); 331 - DTN_INFO( 332 - "HUBP FL: Enabled Done adr_mode width tmz xbar_sel_R xbar_sel_G xbar_sel_B adr_hi adr_low REFCYC Bias Scale Mode Format\n"); 331 + static const char * const pLabels[] = { 332 + "inst", "Enabled ", "Done ", "adr_mode ", "width ", "mpc_width ", 333 + "tmz", "xbar_sel_R", "xbar_sel_G", "xbar_sel_B", "adr_hi ", 334 + "adr_low", "REFCYC", "Bias", "Scale", "Mode", 335 + "Format", "prefetch"}; 336 + 333 337 for (i = 0; i < pool->pipe_count; i++) { 334 338 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); 335 339 struct dcn_fl_regs_st *fl_regs = &s->fl_regs; 340 + struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr; 336 341 337 342 if (!s->blank_en) { 338 - DTN_INFO("[%2d]: %5xh %6xh %5d %6d %8xh %2xh %6xh %6d %8d %8d %7d %8xh %5x %5x %5x", 343 + uint32_t values[] = { 339 344 pool->hubps[i]->inst, 340 345 fl_regs->lut_enable, 341 346 fl_regs->lut_done, 342 347 fl_regs->lut_addr_mode, 343 348 fl_regs->lut_width, 349 + fl_regs->lut_mpc_width, 344 350 fl_regs->lut_tmz, 345 351 fl_regs->lut_crossbar_sel_r, 346 352 fl_regs->lut_crossbar_sel_g, ··· 357 351 fl_regs->lut_fl_bias, 358 352 fl_regs->lut_fl_scale, 359 353 fl_regs->lut_fl_mode, 360 - fl_regs->lut_fl_format); 361 - DTN_INFO("\n"); 354 + fl_regs->lut_fl_format, 355 + dlg_regs->dst_y_prefetch}; 356 + 357 + int num_elements = 18; 358 + 359 + for (int j = 0; j < num_elements; j++) 360 + DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]); 362 361 } 363 362 } 364 363 ··· 552 541 dc->caps.color.mpc.ogam_ram, 553 542 dc->caps.color.mpc.ocsc); 554 543 DTN_INFO("===== MPC RMCM 3DLUT =====\n"); 555 - DTN_INFO("MPCC: SIZE MODE MODE_CUR RD_SEL 30BIT_EN WR_EN_MASK RAM_SEL OUT_NORM_FACTOR FL_SEL OUT_OFFSET OUT_SCALE FL_DONE SOFT_UNDERFLOW HARD_UNDERFLOW MEM_PWR_ST FORCE DIS MODE\n"); 544 + static const char * const pLabels[] = { 545 + "MPCC", "SIZE", "MODE", "MODE_CUR", "RD_SEL", 546 + "30BIT_EN", "WR_EN_MASK", "RAM_SEL", "OUT_NORM_FACTOR", "FL_SEL", 547 + "OUT_OFFSET", "OUT_SCALE", "FL_DONE", "SOFT_UNDERFLOW", "HARD_UNDERFLOW", 548 + "MEM_PWR_ST", "FORCE", "DIS", "MODE"}; 549 + 556 550 for (i = 0; i < pool->mpcc_count; i++) { 557 551 struct mpcc_state s = {0}; 558 552 559 553 pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s); 560 - if (s.opp_id != 0xf) 561 - DTN_INFO("[%2d]: %4xh %4xh %6xh %4x %4x %4x %4x %4x %4xh %4xh %6xh %4x %4x %4x %4x %4x %4x %4x\n", 562 - i, s.rmcm_regs.rmcm_3dlut_size, s.rmcm_regs.rmcm_3dlut_mode, s.rmcm_regs.rmcm_3dlut_mode_cur, 563 - s.rmcm_regs.rmcm_3dlut_read_sel, s.rmcm_regs.rmcm_3dlut_30bit_en, s.rmcm_regs.rmcm_3dlut_wr_en_mask, 564 - s.rmcm_regs.rmcm_3dlut_ram_sel, s.rmcm_regs.rmcm_3dlut_out_norm_factor, s.rmcm_regs.rmcm_3dlut_fl_sel, 565 - s.rmcm_regs.rmcm_3dlut_out_offset_r, s.rmcm_regs.rmcm_3dlut_out_scale_r, s.rmcm_regs.rmcm_3dlut_fl_done, 566 - s.rmcm_regs.rmcm_3dlut_fl_soft_underflow, s.rmcm_regs.rmcm_3dlut_fl_hard_underflow, s.rmcm_regs.rmcm_3dlut_mem_pwr_state, 567 - s.rmcm_regs.rmcm_3dlut_mem_pwr_force, s.rmcm_regs.rmcm_3dlut_mem_pwr_dis, s.rmcm_regs.rmcm_3dlut_mem_pwr_mode); 554 + if (s.opp_id != 0xf) { 555 + uint32_t values[] = { 556 + i, 557 + s.rmcm_regs.rmcm_3dlut_size, 558 + s.rmcm_regs.rmcm_3dlut_mode, 559 + s.rmcm_regs.rmcm_3dlut_mode_cur, 560 + s.rmcm_regs.rmcm_3dlut_read_sel, 561 + s.rmcm_regs.rmcm_3dlut_30bit_en, 562 + s.rmcm_regs.rmcm_3dlut_wr_en_mask, 563 + s.rmcm_regs.rmcm_3dlut_ram_sel, 564 + s.rmcm_regs.rmcm_3dlut_out_norm_factor, 565 + s.rmcm_regs.rmcm_3dlut_fl_sel, 566 + s.rmcm_regs.rmcm_3dlut_out_offset_r, 567 + s.rmcm_regs.rmcm_3dlut_out_scale_r, 568 + s.rmcm_regs.rmcm_3dlut_fl_done, 569 + s.rmcm_regs.rmcm_3dlut_fl_soft_underflow, 570 + s.rmcm_regs.rmcm_3dlut_fl_hard_underflow, 571 + s.rmcm_regs.rmcm_3dlut_mem_pwr_state, 572 + s.rmcm_regs.rmcm_3dlut_mem_pwr_force, 573 + s.rmcm_regs.rmcm_3dlut_mem_pwr_dis, 574 + s.rmcm_regs.rmcm_3dlut_mem_pwr_mode}; 575 + 576 + int num_elements = 19; 577 + 578 + for (int j = 0; j < num_elements; j++) 579 + DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]); 580 + } 568 581 } 569 582 DTN_INFO("\n"); 570 583 DTN_INFO("===== MPC RMCM Shaper =====\n"); ··· 3663 3628 int y_plane = pipe_ctx->plane_state->dst_rect.y; 3664 3629 int x_pos = pos_cpy.x; 3665 3630 int y_pos = pos_cpy.y; 3631 + int clip_x = pipe_ctx->plane_state->clip_rect.x; 3632 + int clip_width = pipe_ctx->plane_state->clip_rect.width; 3666 3633 3667 3634 if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) { 3668 3635 if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) || ··· 3683 3646 */ 3684 3647 3685 3648 /** 3686 - * Translate cursor from stream space to plane space. 3649 + * Translate cursor and clip offset from stream space to plane space. 3687 3650 * 3688 3651 * If the cursor is scaled then we need to scale the position 3689 3652 * to be in the approximately correct place. We can't do anything ··· 3700 3663 pipe_ctx->plane_state->dst_rect.width; 3701 3664 y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.height / 3702 3665 pipe_ctx->plane_state->dst_rect.height; 3666 + clip_x = (clip_x - x_plane) * pipe_ctx->plane_state->src_rect.width / 3667 + pipe_ctx->plane_state->dst_rect.width; 3668 + clip_width = clip_width * pipe_ctx->plane_state->src_rect.width / 3669 + pipe_ctx->plane_state->dst_rect.width; 3703 3670 } 3704 3671 3705 3672 /** ··· 3750 3709 3751 3710 3752 3711 if (param.rotation == ROTATION_ANGLE_0) { 3753 - int viewport_width = 3754 - pipe_ctx->plane_res.scl_data.viewport.width; 3755 - int viewport_x = 3756 - pipe_ctx->plane_res.scl_data.viewport.x; 3757 3712 3758 3713 if (param.mirror) { 3759 - if (pipe_split_on || odm_combine_on) { 3760 - if (pos_cpy.x >= viewport_width + viewport_x) { 3761 - pos_cpy.x = 2 * viewport_width 3762 - - pos_cpy.x + 2 * viewport_x; 3763 - } else { 3764 - uint32_t temp_x = pos_cpy.x; 3765 - 3766 - pos_cpy.x = 2 * viewport_x - pos_cpy.x; 3767 - if (temp_x >= viewport_x + 3768 - (int)hubp->curs_attr.width || pos_cpy.x 3769 - <= (int)hubp->curs_attr.width + 3770 - pipe_ctx->plane_state->src_rect.x) { 3771 - pos_cpy.x = 2 * viewport_width - temp_x; 3772 - } 3773 - } 3774 - } else { 3775 - pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x; 3776 - } 3714 + /* 3715 + * The plane is split into multiple viewports. 3716 + * The combination of all viewports span the 3717 + * entirety of the clip rect. 3718 + * 3719 + * For no pipe_split, viewport_width is represents 3720 + * the full width of the clip_rect, so we can just 3721 + * mirror it. 3722 + */ 3723 + pos_cpy.x = clip_width - pos_cpy.x + 2 * clip_x; 3777 3724 } 3778 3725 } 3779 3726 // Swap axis and mirror horizontally ··· 3831 3802 } 3832 3803 // Mirror horizontally and vertically 3833 3804 else if (param.rotation == ROTATION_ANGLE_180) { 3834 - int viewport_width = 3835 - pipe_ctx->plane_res.scl_data.viewport.width; 3836 - int viewport_x = 3837 - pipe_ctx->plane_res.scl_data.viewport.x; 3838 - 3839 3805 if (!param.mirror) { 3840 - if (pipe_split_on || odm_combine_on) { 3841 - if (pos_cpy.x >= viewport_width + viewport_x) { 3842 - pos_cpy.x = 2 * viewport_width 3843 - - pos_cpy.x + 2 * viewport_x; 3844 - } else { 3845 - uint32_t temp_x = pos_cpy.x; 3846 - 3847 - pos_cpy.x = 2 * viewport_x - pos_cpy.x; 3848 - if (temp_x >= viewport_x + 3849 - (int)hubp->curs_attr.width || pos_cpy.x 3850 - <= (int)hubp->curs_attr.width + 3851 - pipe_ctx->plane_state->src_rect.x) { 3852 - pos_cpy.x = temp_x + viewport_width; 3853 - } 3854 - } 3855 - } else { 3856 - pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x; 3857 - } 3806 + /* 3807 + * The plane is split into multiple viewports. 3808 + * The combination of all viewports span the 3809 + * entirety of the clip rect. 3810 + * 3811 + * For no pipe_split, viewport_width is represents 3812 + * the full width of the clip_rect, so we can just 3813 + * mirror it. 3814 + */ 3815 + pos_cpy.x = clip_width - pos_cpy.x + 2 * clip_x; 3858 3816 } 3859 3817 3860 3818 /**
+2
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
··· 3054 3054 link_enc->transmitter - TRANSMITTER_UNIPHY_A); 3055 3055 } 3056 3056 3057 + link_hwss->setup_stream_attribute(pipe_ctx); 3058 + 3057 3059 if (dc->res_pool->dccg->funcs->set_pixel_rate_div) 3058 3060 dc->res_pool->dccg->funcs->set_pixel_rate_div( 3059 3061 dc->res_pool->dccg,
+48
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
··· 1228 1228 } 1229 1229 } 1230 1230 } 1231 + 1232 + void dcn30_get_underflow_debug_data(const struct dc *dc, 1233 + struct timing_generator *tg, 1234 + struct dc_underflow_debug_data *out_data) 1235 + { 1236 + struct hubbub *hubbub = dc->res_pool->hubbub; 1237 + 1238 + if (tg) { 1239 + uint32_t v_blank_start = 0, v_blank_end = 0; 1240 + 1241 + out_data->otg_inst = tg->inst; 1242 + 1243 + tg->funcs->get_scanoutpos(tg, 1244 + &v_blank_start, 1245 + &v_blank_end, 1246 + &out_data->h_position, 1247 + &out_data->v_position); 1248 + 1249 + out_data->otg_frame_count = tg->funcs->get_frame_count(tg); 1250 + 1251 + out_data->otg_underflow = tg->funcs->is_optc_underflow_occurred(tg); 1252 + } 1253 + 1254 + for (int i = 0; i < MAX_PIPES; i++) { 1255 + struct hubp *hubp = dc->res_pool->hubps[i]; 1256 + 1257 + if (hubp) { 1258 + if (hubp->funcs->hubp_get_underflow_status) 1259 + out_data->hubps[i].hubp_underflow = hubp->funcs->hubp_get_underflow_status(hubp); 1260 + 1261 + if (hubp->funcs->hubp_in_blank) 1262 + out_data->hubps[i].hubp_in_blank = hubp->funcs->hubp_in_blank(hubp); 1263 + 1264 + if (hubp->funcs->hubp_get_current_read_line) 1265 + out_data->hubps[i].hubp_readline = hubp->funcs->hubp_get_current_read_line(hubp); 1266 + 1267 + if (hubp->funcs->hubp_get_det_config_error) 1268 + out_data->hubps[i].det_config_error = hubp->funcs->hubp_get_det_config_error(hubp); 1269 + } 1270 + } 1271 + 1272 + if (hubbub->funcs->get_det_sizes) 1273 + hubbub->funcs->get_det_sizes(hubbub, out_data->curr_det_sizes, out_data->target_det_sizes); 1274 + 1275 + if (hubbub->funcs->compbuf_config_error) 1276 + out_data->compbuf_config_error = hubbub->funcs->compbuf_config_error(hubbub); 1277 + 1278 + }
+5
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h
··· 29 29 #include "hw_sequencer_private.h" 30 30 31 31 struct dc; 32 + struct dc_underflow_debug_data; 32 33 33 34 void dcn30_init_hw(struct dc *dc); 34 35 void dcn30_program_all_writeback_pipes_in_tree( ··· 98 97 struct dc_state *context); 99 98 100 99 void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx); 100 + 101 + void dcn30_get_underflow_debug_data(const struct dc *dc, 102 + struct timing_generator *tg, 103 + struct dc_underflow_debug_data *out_data); 101 104 102 105 #endif /* __DC_HWSS_DCN30_H__ */
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
··· 110 110 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 111 111 .is_abm_supported = dcn21_is_abm_supported, 112 112 .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates, 113 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 113 114 }; 114 115 115 116 static const struct hwseq_private_funcs dcn30_private_funcs = {
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
··· 112 112 .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, 113 113 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 114 114 .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, 115 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 115 116 }; 116 117 117 118 static const struct hwseq_private_funcs dcn31_private_funcs = {
+72
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
··· 528 528 529 529 apply_symclk_on_tx_off_wa(link); 530 530 } 531 + 532 + /** 533 + * dcn314_dpp_pg_control - DPP power gate control. 534 + * 535 + * @hws: dce_hwseq reference. 536 + * @dpp_inst: DPP instance reference. 537 + * @power_on: true if we want to enable power gate, false otherwise. 538 + * 539 + * Enable or disable power gate in the specific DPP instance. 540 + * If power gating is disabled, will force disable cursor in the DPP instance. 541 + */ 542 + void dcn314_dpp_pg_control( 543 + struct dce_hwseq *hws, 544 + unsigned int dpp_inst, 545 + bool power_on) 546 + { 547 + uint32_t power_gate = power_on ? 0 : 1; 548 + uint32_t pwr_status = power_on ? 0 : 2; 549 + 550 + 551 + if (hws->ctx->dc->debug.disable_dpp_power_gate) { 552 + /* Workaround for DCN314 with disabled power gating */ 553 + if (!power_on) { 554 + 555 + /* Force disable cursor if power gating is disabled */ 556 + struct dpp *dpp = hws->ctx->dc->res_pool->dpps[dpp_inst]; 557 + if (dpp && dpp->funcs->dpp_force_disable_cursor) 558 + dpp->funcs->dpp_force_disable_cursor(dpp); 559 + } 560 + return; 561 + } 562 + if (REG(DOMAIN1_PG_CONFIG) == 0) 563 + return; 564 + 565 + switch (dpp_inst) { 566 + case 0: /* DPP0 */ 567 + REG_UPDATE(DOMAIN1_PG_CONFIG, 568 + DOMAIN1_POWER_GATE, power_gate); 569 + 570 + REG_WAIT(DOMAIN1_PG_STATUS, 571 + DOMAIN1_PGFSM_PWR_STATUS, pwr_status, 572 + 1, 1000); 573 + break; 574 + case 1: /* DPP1 */ 575 + REG_UPDATE(DOMAIN3_PG_CONFIG, 576 + DOMAIN3_POWER_GATE, power_gate); 577 + 578 + REG_WAIT(DOMAIN3_PG_STATUS, 579 + DOMAIN3_PGFSM_PWR_STATUS, pwr_status, 580 + 1, 1000); 581 + break; 582 + case 2: /* DPP2 */ 583 + REG_UPDATE(DOMAIN5_PG_CONFIG, 584 + DOMAIN5_POWER_GATE, power_gate); 585 + 586 + REG_WAIT(DOMAIN5_PG_STATUS, 587 + DOMAIN5_PGFSM_PWR_STATUS, pwr_status, 588 + 1, 1000); 589 + break; 590 + case 3: /* DPP3 */ 591 + REG_UPDATE(DOMAIN7_PG_CONFIG, 592 + DOMAIN7_POWER_GATE, power_gate); 593 + 594 + REG_WAIT(DOMAIN7_PG_STATUS, 595 + DOMAIN7_PGFSM_PWR_STATUS, pwr_status, 596 + 1, 1000); 597 + break; 598 + default: 599 + BREAK_TO_DEBUGGER(); 600 + break; 601 + } 602 + }
+2
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
··· 47 47 48 48 void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal); 49 49 50 + void dcn314_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on); 51 + 50 52 #endif /* __DC_HWSS_DCN314_H__ */
+2
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
··· 115 115 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 116 116 .calculate_pix_rate_divider = dcn314_calculate_pix_rate_divider, 117 117 .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, 118 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 118 119 }; 119 120 120 121 static const struct hwseq_private_funcs dcn314_private_funcs = { ··· 142 141 .enable_power_gating_plane = dcn314_enable_power_gating_plane, 143 142 .dpp_root_clock_control = dcn314_dpp_root_clock_control, 144 143 .hubp_pg_control = dcn31_hubp_pg_control, 144 + .dpp_pg_control = dcn314_dpp_pg_control, 145 145 .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, 146 146 .update_odm = dcn314_update_odm, 147 147 .dsc_pg_control = dcn314_dsc_pg_control,
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
··· 121 121 .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider, 122 122 .program_outstanding_updates = dcn32_program_outstanding_updates, 123 123 .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates, 124 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 124 125 }; 125 126 126 127 static const struct hwseq_private_funcs dcn32_private_funcs = {
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
··· 128 128 .enable_plane = dcn20_enable_plane, 129 129 .update_dchubp_dpp = dcn20_update_dchubp_dpp, 130 130 .post_unlock_reset_opp = dcn20_post_unlock_reset_opp, 131 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 131 132 }; 132 133 133 134 static const struct hwseq_private_funcs dcn35_private_funcs = {
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
··· 123 123 .set_long_vtotal = dcn35_set_long_vblank, 124 124 .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider, 125 125 .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, 126 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 126 127 }; 127 128 128 129 static const struct hwseq_private_funcs dcn351_private_funcs = {
+22 -12
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
··· 965 965 } 966 966 } 967 967 968 + link_hwss->setup_stream_attribute(pipe_ctx); 969 + 968 970 if (dc->res_pool->dccg->funcs->set_pixel_rate_div) { 969 971 dc->res_pool->dccg->funcs->set_pixel_rate_div( 970 972 dc->res_pool->dccg, ··· 1621 1619 1622 1620 void dcn401_hardware_release(struct dc *dc) 1623 1621 { 1624 - dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); 1622 + if (!dc->debug.disable_force_pstate_allow_on_hw_release) { 1623 + dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); 1625 1624 1626 - /* If pstate unsupported, or still supported 1627 - * by firmware, force it supported by dcn 1628 - */ 1629 - if (dc->current_state) { 1630 - if ((!dc->clk_mgr->clks.p_state_change_support || 1631 - dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) && 1632 - dc->res_pool->hubbub->funcs->force_pstate_change_control) 1633 - dc->res_pool->hubbub->funcs->force_pstate_change_control( 1634 - dc->res_pool->hubbub, true, true); 1625 + /* If pstate unsupported, or still supported 1626 + * by firmware, force it supported by dcn 1627 + */ 1628 + if (dc->current_state) { 1629 + if ((!dc->clk_mgr->clks.p_state_change_support || 1630 + dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) && 1631 + dc->res_pool->hubbub->funcs->force_pstate_change_control) 1632 + dc->res_pool->hubbub->funcs->force_pstate_change_control( 1633 + dc->res_pool->hubbub, true, true); 1635 1634 1636 - dc->current_state->bw_ctx.bw.dcn.clk.p_state_change_support = true; 1637 - dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); 1635 + dc->current_state->bw_ctx.bw.dcn.clk.p_state_change_support = true; 1636 + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); 1637 + } 1638 + } else { 1639 + if (dc->current_state) { 1640 + dc->clk_mgr->clks.p_state_change_support = false; 1641 + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); 1642 + } 1643 + dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); 1638 1644 } 1639 1645 } 1640 1646
+1
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
··· 104 104 .enable_plane = dcn20_enable_plane, 105 105 .update_dchubp_dpp = dcn20_update_dchubp_dpp, 106 106 .post_unlock_reset_opp = dcn20_post_unlock_reset_opp, 107 + .get_underflow_debug_data = dcn30_get_underflow_debug_data, 107 108 }; 108 109 109 110 static const struct hwseq_private_funcs dcn401_private_funcs = {
+4
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
··· 47 47 struct dc_dmub_cmd; 48 48 struct pg_block_update; 49 49 struct drr_params; 50 + struct dc_underflow_debug_data; 50 51 51 52 struct subvp_pipe_control_lock_fast_params { 52 53 struct dc *dc; ··· 476 475 struct dc_state *context); 477 476 void (*post_unlock_reset_opp)(struct dc *dc, 478 477 struct pipe_ctx *opp_head); 478 + void (*get_underflow_debug_data)(const struct dc *dc, 479 + struct timing_generator *tg, 480 + struct dc_underflow_debug_data *out_data); 479 481 }; 480 482 481 483 void color_space_to_black_color(
+5 -3
drivers/gpu/drm/amd/display/dc/inc/core_types.h
··· 228 228 enum dc_status (*update_dc_state_for_encoder_switch)(struct dc_link *link, 229 229 struct dc_link_settings *link_setting, 230 230 uint8_t pipe_count, 231 - struct pipe_ctx *pipes, 232 - struct audio_output *audio_output); 231 + struct pipe_ctx *pipes); 233 232 }; 234 233 235 234 struct audio_support{ ··· 360 361 uint8_t gsl_group; 361 362 362 363 struct test_pattern_params test_pattern_params; 364 + 365 + struct audio_output audio_output; 363 366 }; 364 367 365 368 struct plane_resource { ··· 434 433 P_STATE_V_ACTIVE, 435 434 P_STATE_SUB_VP, 436 435 P_STATE_DRR_SUB_VP, 437 - P_STATE_V_BLANK_SUB_VP 436 + P_STATE_V_BLANK_SUB_VP, 438 437 }; 439 438 440 439 struct pipe_ctx { ··· 684 683 /* Controller Id used for Dig Fe source select */ 685 684 enum controller_id controllerId; 686 685 unsigned int line_time_in_ns; 686 + bool os_request_force_ffu; 687 687 }; 688 688 689 689 enum dc_replay_enable {
+2
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
··· 229 229 void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); 230 230 void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst); 231 231 bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower); 232 + void (*get_det_sizes)(struct hubbub *hubbub, uint32_t *curr_det_sizes, uint32_t *target_det_sizes); 233 + uint32_t (*compbuf_config_error)(struct hubbub *hubbub); 232 234 }; 233 235 234 236 struct hubbub {
+3
drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
··· 349 349 struct dpp *dpp_base, 350 350 enum dc_color_space color_space, 351 351 struct dc_csc_transform cursor_csc_color_matrix); 352 + 353 + void (*dpp_force_disable_cursor)(struct dpp *dpp_base); 354 + 352 355 }; 353 356 354 357
+20 -1
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
··· 89 89 enum hubp_3dlut_fl_width { 90 90 hubp_3dlut_fl_width_17 = 17, 91 91 hubp_3dlut_fl_width_33 = 33, 92 - hubp_3dlut_fl_width_transformed = 4916 92 + hubp_3dlut_fl_width_transformed = 4916, //mpc default 93 93 }; 94 94 95 95 enum hubp_3dlut_fl_crossbar_bit_slice { ··· 97 97 hubp_3dlut_fl_crossbar_bit_slice_16_31 = 1, 98 98 hubp_3dlut_fl_crossbar_bit_slice_32_47 = 2, 99 99 hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3 100 + }; 101 + 102 + struct hubp_fl_3dlut_config { 103 + bool enabled; 104 + enum hubp_3dlut_fl_width width; 105 + enum hubp_3dlut_fl_mode mode; 106 + enum hubp_3dlut_fl_format format; 107 + uint16_t bias; 108 + uint16_t scale; 109 + struct dc_plane_address address; 110 + enum hubp_3dlut_fl_addressing_mode addr_mode; 111 + enum dc_cm2_gpu_mem_layout layout; 112 + uint8_t protection_bits; 113 + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; 114 + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; 115 + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; 100 116 }; 101 117 102 118 struct hubp { ··· 304 288 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, 305 289 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); 306 290 int (*hubp_get_3dlut_fl_done)(struct hubp *hubp); 291 + void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg); 307 292 void (*hubp_clear_tiling)(struct hubp *hubp); 293 + uint32_t (*hubp_get_current_read_line)(struct hubp *hubp); 294 + uint32_t (*hubp_get_det_config_error)(struct hubp *hubp); 308 295 }; 309 296 310 297 #endif
+11 -15
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
··· 115 115 MCM_LUT_SHAPER 116 116 }; 117 117 118 + struct mpc_fl_3dlut_config { 119 + bool enabled; 120 + uint16_t width; 121 + bool select_lut_bank_a; 122 + uint16_t bit_depth; 123 + int hubp_index; 124 + uint16_t bias; 125 + uint16_t scale; 126 + }; 127 + 118 128 union mcm_lut_params { 119 129 const struct pwl_params *pwl; 120 130 const struct tetrahedral_params *lut3d; ··· 1069 1059 */ 1070 1060 void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable, 1071 1061 bool lut_bank_a, int mpcc_id); 1072 - /** 1073 - * @program_3dlut_size: 1074 - * 1075 - * Program 3D LUT size. 1076 - * 1077 - * Parameters: 1078 - * - [in/out] mpc - MPC context. 1079 - * - [in] is_17x17x17 - is 3dlut 17x17x17 1080 - * - [in] mpcc_id 1081 - * 1082 - * Return: 1083 - * 1084 - * void 1085 - */ 1086 - void (*program_3dlut_size)(struct mpc *mpc, bool is_17x17x17, int mpcc_id); 1087 1062 1088 1063 /** 1089 1064 * @mcm: ··· 1093 1098 * MPC RMCM new HW sequential programming functions 1094 1099 */ 1095 1100 struct { 1101 + void (*fl_3dlut_configure)(struct mpc *mpc, struct mpc_fl_3dlut_config *cfg, int mpcc_id); 1096 1102 void (*enable_3dlut_fl)(struct mpc *mpc, bool enable, int mpcc_id); 1097 1103 void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); 1098 1104 void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
+1
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
··· 374 374 void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg); 375 375 void (*set_long_vtotal)(struct timing_generator *optc, const struct long_vtotal_params *params); 376 376 void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg); 377 + void (*wait_otg_disable)(struct timing_generator *optc); 377 378 bool (*get_optc_double_buffer_pending)(struct timing_generator *tg); 378 379 bool (*get_otg_double_buffer_pending)(struct timing_generator *tg); 379 380 bool (*get_pipe_update_pending)(struct timing_generator *tg);
+4 -1
drivers/gpu/drm/amd/display/dc/inc/link.h
··· 218 218 bool (*dp_overwrite_extended_receiver_cap)(struct dc_link *link); 219 219 enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link, 220 220 struct dc_link_settings *link_setting); 221 - 221 + uint8_t (*dp_get_lttpr_count)(struct dc_link *link); 222 + void (*edp_get_alpm_support)(struct dc_link *link, 223 + bool *auxless_support, 224 + bool *auxwake_support); 222 225 223 226 /*************************** DP DPIA/PHY ******************************/ 224 227 void (*dpia_handle_usb4_bandwidth_allocation_for_link)(
+24
drivers/gpu/drm/amd/display/dc/inc/soc_and_ip_translator.h
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #ifndef __SOC_AND_IP_TRANSLATOR_H__ 6 + #define __SOC_AND_IP_TRANSLATOR_H__ 7 + 8 + #include "dc.h" 9 + #include "dml_top_soc_parameter_types.h" 10 + 11 + struct soc_and_ip_translator_funcs { 12 + void (*get_soc_bb)(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config); 13 + void (*get_ip_caps)(struct dml2_ip_capabilities *dml_ip_caps); 14 + }; 15 + 16 + struct soc_and_ip_translator { 17 + const struct soc_and_ip_translator_funcs *translator_funcs; 18 + }; 19 + 20 + struct soc_and_ip_translator *dc_create_soc_and_ip_translator(enum dce_version dc_version); 21 + void dc_destroy_soc_and_ip_translator(struct soc_and_ip_translator **soc_and_ip_translator); 22 + 23 + 24 + #endif // __SOC_AND_IP_TRANSLATOR_H__
+1 -1
drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c
··· 284 284 285 285 REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, 0xf); 286 286 287 - memcpy(dest_luma_buffer, luma_buffer, mcif_params->luma_pitch * dest_height); 287 + memcpy(dest_luma_buffer, luma_buffer, (size_t)mcif_params->luma_pitch * dest_height); 288 288 memcpy(dest_chroma_buffer, chroma_buffer, mcif_params->chroma_pitch * dest_height / 2); 289 289 290 290 REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, 0x0);
-8
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
··· 287 287 } 288 288 } 289 289 290 - void mpc401_program_3dlut_size(struct mpc *mpc, bool is_17x17x17, int mpcc_id) 291 - { 292 - struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 293 - 294 - REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, is_17x17x17 ? 0 : 1); 295 - } 296 - 297 290 void mpc_program_gamut_remap( 298 291 struct mpc *mpc, 299 292 unsigned int mpcc_id, ··· 604 611 .populate_lut = mpc401_populate_lut, 605 612 .program_lut_read_write_control = mpc401_program_lut_read_write_control, 606 613 .program_lut_mode = mpc401_program_lut_mode, 607 - .program_3dlut_size = mpc401_program_3dlut_size, 608 614 }; 609 615 610 616
-5
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
··· 221 221 bool lut_bank_a, 222 222 int mpcc_id); 223 223 224 - void mpc401_program_3dlut_size( 225 - struct mpc *mpc, 226 - bool is_17x17x17, 227 - int mpcc_id); 228 - 229 224 void mpc401_set_gamut_remap( 230 225 struct mpc *mpc, 231 226 int mpcc_id,
+1
drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
··· 62 62 SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\ 63 63 SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\ 64 64 SF(OTG0_OTG_CONTROL, OTG_OUT_MUX, mask_sh),\ 65 + SF(OTG0_OTG_CONTROL, OTG_CURRENT_MASTER_EN_STATE, mask_sh),\ 65 66 SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\ 66 67 SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\ 67 68 SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\
+18
drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
··· 162 162 REG_WAIT(OTG_CLOCK_CONTROL, 163 163 OTG_BUSY, 0, 164 164 1, 100000); 165 + REG_WAIT(OTG_CONTROL, OTG_CURRENT_MASTER_EN_STATE, 0, 1, 100000); 166 + 165 167 optc1_clear_optc_underflow(optc); 166 168 167 169 return true; ··· 430 428 } 431 429 } 432 430 431 + static void optc35_wait_otg_disable(struct timing_generator *optc) 432 + { 433 + struct optc *optc1; 434 + uint32_t is_master_en; 435 + 436 + if (!optc || !optc->ctx) 437 + return; 438 + 439 + optc1 = DCN10TG_FROM_TG(optc); 440 + 441 + REG_GET(OTG_CONTROL, OTG_MASTER_EN, &is_master_en); 442 + if (!is_master_en) 443 + REG_WAIT(OTG_CLOCK_CONTROL, OTG_CURRENT_MASTER_EN_STATE, 0, 1, 100000); 444 + } 445 + 433 446 static const struct timing_generator_funcs dcn35_tg_funcs = { 434 447 .validate_timing = optc1_validate_timing, 435 448 .program_timing = optc1_program_timing, ··· 496 479 .set_odm_bypass = optc32_set_odm_bypass, 497 480 .set_odm_combine = optc35_set_odm_combine, 498 481 .get_optc_source = optc2_get_optc_source, 482 + .wait_otg_disable = optc35_wait_otg_disable, 499 483 .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode, 500 484 .set_out_mux = optc3_set_out_mux, 501 485 .set_drr_trigger_window = optc3_set_drr_trigger_window,
+5
drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
··· 226 226 REG_UPDATE(CONTROL, 227 227 VTG0_ENABLE, 0); 228 228 229 + // wait until CRTC_CURRENT_MASTER_EN_STATE == 0 230 + REG_WAIT(OTG_CONTROL, 231 + OTG_CURRENT_MASTER_EN_STATE, 232 + 0, 10, 15000); 233 + 229 234 /* CRTC disabled, so disable clock. */ 230 235 REG_WAIT(OTG_CLOCK_CONTROL, 231 236 OTG_BUSY, 0,
+6 -6
drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
··· 1111 1111 &clks); 1112 1112 1113 1113 dc->bw_vbios->low_yclk = bw_frc_to_fixed( 1114 - clks.clocks_in_khz[0] * memory_type_multiplier, 1000); 1114 + (int64_t)clks.clocks_in_khz[0] * memory_type_multiplier, 1000); 1115 1115 dc->bw_vbios->mid_yclk = bw_frc_to_fixed( 1116 - clks.clocks_in_khz[clks.num_levels>>1] * memory_type_multiplier, 1116 + (int64_t)clks.clocks_in_khz[clks.num_levels>>1] * memory_type_multiplier, 1117 1117 1000); 1118 1118 dc->bw_vbios->high_yclk = bw_frc_to_fixed( 1119 - clks.clocks_in_khz[clks.num_levels-1] * memory_type_multiplier, 1119 + (int64_t)clks.clocks_in_khz[clks.num_levels-1] * memory_type_multiplier, 1120 1120 1000); 1121 1121 1122 1122 return; ··· 1152 1152 * YCLK = UMACLK*m_memoryTypeMultiplier 1153 1153 */ 1154 1154 dc->bw_vbios->low_yclk = bw_frc_to_fixed( 1155 - mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000); 1155 + (int64_t)mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000); 1156 1156 dc->bw_vbios->mid_yclk = bw_frc_to_fixed( 1157 - mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier, 1157 + (int64_t)mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier, 1158 1158 1000); 1159 1159 dc->bw_vbios->high_yclk = bw_frc_to_fixed( 1160 - mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier, 1160 + (int64_t)mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier, 1161 1161 1000); 1162 1162 1163 1163 /* Now notify PPLib/SMU about which Watermarks sets they should select
+3 -3
drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
··· 990 990 memory_type_multiplier = MEMORY_TYPE_HBM; 991 991 992 992 dc->bw_vbios->low_yclk = bw_frc_to_fixed( 993 - mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000); 993 + (int64_t)mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000); 994 994 dc->bw_vbios->mid_yclk = bw_frc_to_fixed( 995 - mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier, 995 + (int64_t)mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier, 996 996 1000); 997 997 dc->bw_vbios->high_yclk = bw_frc_to_fixed( 998 - mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier, 998 + (int64_t)mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier, 999 999 1000); 1000 1000 1001 1001 /* Now notify PPLib/SMU about which Watermarks sets they should select
+1 -1
drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
··· 2192 2192 j = 0; 2193 2193 // create the final dcfclk and uclk table 2194 2194 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { 2195 - if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { 2195 + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { 2196 2196 dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; 2197 2197 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; 2198 2198 } else {
+2 -3
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
··· 2239 2239 enum dc_status dcn31_update_dc_state_for_encoder_switch(struct dc_link *link, 2240 2240 struct dc_link_settings *link_setting, 2241 2241 uint8_t pipe_count, 2242 - struct pipe_ctx *pipes, 2243 - struct audio_output *audio_output) 2242 + struct pipe_ctx *pipes) 2244 2243 { 2245 2244 struct dc_state *state = link->dc->current_state; 2246 2245 int i; ··· 2254 2255 2255 2256 // Setup audio 2256 2257 if (pipes[i].stream_res.audio != NULL) 2257 - build_audio_output(state, &pipes[i], &audio_output[i]); 2258 + build_audio_output(state, &pipes[i], &pipes[i].stream_res.audio_output); 2258 2259 } 2259 2260 #else 2260 2261 /* This DCN requires rate divider updates and audio reprogramming to allow DP1<-->DP2 link rate switching,
+1 -2
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h
··· 69 69 enum dc_status dcn31_update_dc_state_for_encoder_switch(struct dc_link *link, 70 70 struct dc_link_settings *link_setting, 71 71 uint8_t pipe_count, 72 - struct pipe_ctx *pipes, 73 - struct audio_output *audio_output); 72 + struct pipe_ctx *pipes); 74 73 75 74 /*temp: B0 specific before switch to dcn313 headers*/ 76 75 #ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL
+2 -1
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
··· 1141 1141 SRI_ARR(DCN_SURF1_TTU_CNTL1, HUBPREQ, id), \ 1142 1142 SRI_ARR(DCN_CUR0_TTU_CNTL0, HUBPREQ, id), \ 1143 1143 SRI_ARR(DCN_CUR0_TTU_CNTL1, HUBPREQ, id), \ 1144 - SRI_ARR(HUBP_CLK_CNTL, HUBP, id) 1144 + SRI_ARR(HUBP_CLK_CNTL, HUBP, id), \ 1145 + SRI_ARR(HUBPRET_READ_LINE_VALUE, HUBPRET, id) 1145 1146 #define HUBP_REG_LIST_DCN2_COMMON_RI(id) \ 1146 1147 HUBP_REG_LIST_DCN_RI(id), HUBP_REG_LIST_DCN_VM_RI(id), \ 1147 1148 SRI_ARR(PREFETCH_SETTINGS, HUBPREQ, id), \
+1
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
··· 708 708 }, 709 709 .use_max_lb = true, 710 710 .force_disable_subvp = false, 711 + .disable_force_pstate_allow_on_hw_release = false, 711 712 .exit_idle_opt_for_cursor_updates = true, 712 713 .using_dml2 = true, 713 714 .using_dml21 = true,
+2 -1
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
··· 140 140 SRI_ARR(UCLK_PSTATE_FORCE, HUBPREQ, id), \ 141 141 HUBP_3DLUT_FL_REG_LIST_DCN401(id), \ 142 142 SRI_ARR(DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE, HUBP, id), \ 143 - SRI_ARR(DCHUBP_MCACHEID_CONFIG, HUBP, id) 143 + SRI_ARR(DCHUBP_MCACHEID_CONFIG, HUBP, id), \ 144 + SRI_ARR(HUBPRET_READ_LINE_VALUE, HUBPRET, id) 144 145 145 146 /* ABM */ 146 147 #define ABM_DCN401_REG_LIST_RI(id) \
+19
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/Makefile
··· 1 + # SPDX-License-Identifier: MIT 2 + # 3 + # Copyright 2025 Advanced Micro Devices, Inc. 4 + # Makefile for bounding box component. 5 + # Floating point required due to nature of bounding box values 6 + 7 + soc_and_ip_translator_ccflags := $(CC_FLAGS_FPU) 8 + soc_and_ip_translator_rcflags := $(CC_FLAGS_NO_FPU) 9 + 10 + CFLAGS_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.o := $(soc_and_ip_translator_ccflags) 11 + 12 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.o := $(soc_and_ip_translator_rcflags) 13 + 14 + soc_and_ip_translator := soc_and_ip_translator.o 15 + soc_and_ip_translator += dcn401/dcn401_soc_and_ip_translator.o 16 + 17 + AMD_DAL_soc_and_ip_translator := $(addprefix $(AMDDALPATH)/dc/soc_and_ip_translator/, $(soc_and_ip_translator)) 18 + 19 + AMD_DISPLAY_FILES += $(AMD_DAL_soc_and_ip_translator)
+304
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #include "dcn401_soc_and_ip_translator.h" 6 + #include "bounding_boxes/dcn4_soc_bb.h" 7 + 8 + /* soc_and_ip_translator component used to get up-to-date values for bounding box. 9 + * Bounding box values are stored in several locations and locations can vary with DCN revision. 10 + * This component provides an interface to get DCN-specific bounding box values. 11 + */ 12 + 13 + static void get_default_soc_bb(struct dml2_soc_bb *soc_bb) 14 + { 15 + memcpy(soc_bb, &dml2_socbb_dcn401, sizeof(struct dml2_soc_bb)); 16 + memcpy(&soc_bb->qos_parameters, &dml_dcn4_variant_a_soc_qos_params, sizeof(struct dml2_soc_qos_parameters)); 17 + } 18 + 19 + /* 20 + * DC clock table is obtained from SMU during runtime. 21 + * SMU stands for System Management Unit. It is a power management processor. 22 + * It owns the initialization of dc's clock table and programming of clock values 23 + * based on dc's requests. 24 + * Our clock values in base soc bb is a dummy placeholder. The real clock values 25 + * are retrieved from SMU firmware to dc clock table at runtime. 26 + * This function overrides our dummy placeholder values with real values in dc 27 + * clock table. 28 + */ 29 + static void dcn401_convert_dc_clock_table_to_soc_bb_clock_table( 30 + struct dml2_soc_state_table *dml_clk_table, 31 + const struct clk_bw_params *dc_bw_params, 32 + bool use_clock_dc_limits) 33 + { 34 + int i; 35 + const struct clk_limit_table *dc_clk_table; 36 + 37 + if (dc_bw_params == NULL) 38 + /* skip if bw params could not be obtained from smu */ 39 + return; 40 + 41 + dc_clk_table = &dc_bw_params->clk_table; 42 + 43 + /* dcfclk */ 44 + if (dc_clk_table->num_entries_per_clk.num_dcfclk_levels) { 45 + dml_clk_table->dcfclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dcfclk_levels; 46 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 47 + if (i < dml_clk_table->dcfclk.num_clk_values) { 48 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.dcfclk_mhz && 49 + dc_clk_table->entries[i].dcfclk_mhz > dc_bw_params->dc_mode_limit.dcfclk_mhz) { 50 + if (i == 0 || dc_clk_table->entries[i-1].dcfclk_mhz < dc_bw_params->dc_mode_limit.dcfclk_mhz) { 51 + dml_clk_table->dcfclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dcfclk_mhz * 1000; 52 + dml_clk_table->dcfclk.num_clk_values = i + 1; 53 + } else { 54 + dml_clk_table->dcfclk.clk_values_khz[i] = 0; 55 + dml_clk_table->dcfclk.num_clk_values = i; 56 + } 57 + } else { 58 + dml_clk_table->dcfclk.clk_values_khz[i] = dc_clk_table->entries[i].dcfclk_mhz * 1000; 59 + } 60 + } else { 61 + dml_clk_table->dcfclk.clk_values_khz[i] = 0; 62 + } 63 + } 64 + } 65 + 66 + /* fclk */ 67 + if (dc_clk_table->num_entries_per_clk.num_fclk_levels) { 68 + dml_clk_table->fclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_fclk_levels; 69 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 70 + if (i < dml_clk_table->fclk.num_clk_values) { 71 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.fclk_mhz && 72 + dc_clk_table->entries[i].fclk_mhz > dc_bw_params->dc_mode_limit.fclk_mhz) { 73 + if (i == 0 || dc_clk_table->entries[i-1].fclk_mhz < dc_bw_params->dc_mode_limit.fclk_mhz) { 74 + dml_clk_table->fclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.fclk_mhz * 1000; 75 + dml_clk_table->fclk.num_clk_values = i + 1; 76 + } else { 77 + dml_clk_table->fclk.clk_values_khz[i] = 0; 78 + dml_clk_table->fclk.num_clk_values = i; 79 + } 80 + } else { 81 + dml_clk_table->fclk.clk_values_khz[i] = dc_clk_table->entries[i].fclk_mhz * 1000; 82 + } 83 + } else { 84 + dml_clk_table->fclk.clk_values_khz[i] = 0; 85 + } 86 + } 87 + } 88 + 89 + /* uclk */ 90 + if (dc_clk_table->num_entries_per_clk.num_memclk_levels) { 91 + dml_clk_table->uclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_memclk_levels; 92 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 93 + if (i < dml_clk_table->uclk.num_clk_values) { 94 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.memclk_mhz && 95 + dc_clk_table->entries[i].memclk_mhz > dc_bw_params->dc_mode_limit.memclk_mhz) { 96 + if (i == 0 || dc_clk_table->entries[i-1].memclk_mhz < dc_bw_params->dc_mode_limit.memclk_mhz) { 97 + dml_clk_table->uclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.memclk_mhz * 1000; 98 + dml_clk_table->uclk.num_clk_values = i + 1; 99 + } else { 100 + dml_clk_table->uclk.clk_values_khz[i] = 0; 101 + dml_clk_table->uclk.num_clk_values = i; 102 + } 103 + } else { 104 + dml_clk_table->uclk.clk_values_khz[i] = dc_clk_table->entries[i].memclk_mhz * 1000; 105 + } 106 + } else { 107 + dml_clk_table->uclk.clk_values_khz[i] = 0; 108 + } 109 + } 110 + } 111 + 112 + /* dispclk */ 113 + if (dc_clk_table->num_entries_per_clk.num_dispclk_levels) { 114 + dml_clk_table->dispclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dispclk_levels; 115 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 116 + if (i < dml_clk_table->dispclk.num_clk_values) { 117 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.dispclk_mhz && 118 + dc_clk_table->entries[i].dispclk_mhz > dc_bw_params->dc_mode_limit.dispclk_mhz) { 119 + if (i == 0 || dc_clk_table->entries[i-1].dispclk_mhz < dc_bw_params->dc_mode_limit.dispclk_mhz) { 120 + dml_clk_table->dispclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dispclk_mhz * 1000; 121 + dml_clk_table->dispclk.num_clk_values = i + 1; 122 + } else { 123 + dml_clk_table->dispclk.clk_values_khz[i] = 0; 124 + dml_clk_table->dispclk.num_clk_values = i; 125 + } 126 + } else { 127 + dml_clk_table->dispclk.clk_values_khz[i] = dc_clk_table->entries[i].dispclk_mhz * 1000; 128 + } 129 + } else { 130 + dml_clk_table->dispclk.clk_values_khz[i] = 0; 131 + } 132 + } 133 + } 134 + 135 + /* dppclk */ 136 + if (dc_clk_table->num_entries_per_clk.num_dppclk_levels) { 137 + dml_clk_table->dppclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dppclk_levels; 138 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 139 + if (i < dml_clk_table->dppclk.num_clk_values) { 140 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.dppclk_mhz && 141 + dc_clk_table->entries[i].dppclk_mhz > dc_bw_params->dc_mode_limit.dppclk_mhz) { 142 + if (i == 0 || dc_clk_table->entries[i-1].dppclk_mhz < dc_bw_params->dc_mode_limit.dppclk_mhz) { 143 + dml_clk_table->dppclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dppclk_mhz * 1000; 144 + dml_clk_table->dppclk.num_clk_values = i + 1; 145 + } else { 146 + dml_clk_table->dppclk.clk_values_khz[i] = 0; 147 + dml_clk_table->dppclk.num_clk_values = i; 148 + } 149 + } else { 150 + dml_clk_table->dppclk.clk_values_khz[i] = dc_clk_table->entries[i].dppclk_mhz * 1000; 151 + } 152 + } else { 153 + dml_clk_table->dppclk.clk_values_khz[i] = 0; 154 + } 155 + } 156 + } 157 + 158 + /* dtbclk */ 159 + if (dc_clk_table->num_entries_per_clk.num_dtbclk_levels) { 160 + dml_clk_table->dtbclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dtbclk_levels; 161 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 162 + if (i < dml_clk_table->dtbclk.num_clk_values) { 163 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.dtbclk_mhz && 164 + dc_clk_table->entries[i].dtbclk_mhz > dc_bw_params->dc_mode_limit.dtbclk_mhz) { 165 + if (i == 0 || dc_clk_table->entries[i-1].dtbclk_mhz < dc_bw_params->dc_mode_limit.dtbclk_mhz) { 166 + dml_clk_table->dtbclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dtbclk_mhz * 1000; 167 + dml_clk_table->dtbclk.num_clk_values = i + 1; 168 + } else { 169 + dml_clk_table->dtbclk.clk_values_khz[i] = 0; 170 + dml_clk_table->dtbclk.num_clk_values = i; 171 + } 172 + } else { 173 + dml_clk_table->dtbclk.clk_values_khz[i] = dc_clk_table->entries[i].dtbclk_mhz * 1000; 174 + } 175 + } else { 176 + dml_clk_table->dtbclk.clk_values_khz[i] = 0; 177 + } 178 + } 179 + } 180 + 181 + /* socclk */ 182 + if (dc_clk_table->num_entries_per_clk.num_socclk_levels) { 183 + dml_clk_table->socclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_socclk_levels; 184 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 185 + if (i < dml_clk_table->socclk.num_clk_values) { 186 + if (use_clock_dc_limits && dc_bw_params->dc_mode_limit.socclk_mhz && 187 + dc_clk_table->entries[i].socclk_mhz > dc_bw_params->dc_mode_limit.socclk_mhz) { 188 + if (i == 0 || dc_clk_table->entries[i-1].socclk_mhz < dc_bw_params->dc_mode_limit.socclk_mhz) { 189 + dml_clk_table->socclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.socclk_mhz * 1000; 190 + dml_clk_table->socclk.num_clk_values = i + 1; 191 + } else { 192 + dml_clk_table->socclk.clk_values_khz[i] = 0; 193 + dml_clk_table->socclk.num_clk_values = i; 194 + } 195 + } else { 196 + dml_clk_table->socclk.clk_values_khz[i] = dc_clk_table->entries[i].socclk_mhz * 1000; 197 + } 198 + } else { 199 + dml_clk_table->socclk.clk_values_khz[i] = 0; 200 + } 201 + } 202 + } 203 + 204 + /* dram config */ 205 + dml_clk_table->dram_config.channel_count = dc_bw_params->num_channels; 206 + dml_clk_table->dram_config.channel_width_bytes = dc_bw_params->dram_channel_width_bytes; 207 + } 208 + 209 + void dcn401_update_soc_bb_with_values_from_clk_mgr(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) 210 + { 211 + soc_bb->dprefclk_mhz = dc->clk_mgr->dprefclk_khz / 1000; 212 + soc_bb->dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 213 + soc_bb->mall_allocated_for_dcn_mbytes = dc->caps.mall_size_total / (1024 * 1024); 214 + 215 + if (dc->clk_mgr->funcs->is_smu_present && 216 + dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr)) { 217 + dcn401_convert_dc_clock_table_to_soc_bb_clock_table(&soc_bb->clk_table, 218 + dc->clk_mgr->bw_params, 219 + config->use_clock_dc_limits); 220 + } 221 + } 222 + 223 + void dcn401_update_soc_bb_with_values_from_vbios(struct dml2_soc_bb *soc_bb, const struct dc *dc) 224 + { 225 + soc_bb->dchub_refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000; 226 + soc_bb->xtalclk_mhz = dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency / 1000; 227 + 228 + /* latencies in vbios are platform specific and should be used if provided */ 229 + if (dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns) 230 + soc_bb->power_management_parameters.dram_clk_change_blackout_us = 231 + dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns / 10.0; 232 + 233 + if (dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns) 234 + soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us = 235 + dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns / 10.0; 236 + 237 + if (dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns) 238 + soc_bb->power_management_parameters.stutter_exit_latency_us = 239 + dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns / 10.0; 240 + } 241 + 242 + void dcn401_update_soc_bb_with_values_from_software_policy(struct dml2_soc_bb *soc_bb, const struct dc *dc) 243 + { 244 + /* set if the value is provided */ 245 + if (dc->bb_overrides.sr_exit_time_ns) 246 + soc_bb->power_management_parameters.stutter_exit_latency_us = 247 + dc->bb_overrides.sr_exit_time_ns / 1000.0; 248 + 249 + if (dc->bb_overrides.sr_enter_plus_exit_time_ns) 250 + soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us = 251 + dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 252 + 253 + if (dc->bb_overrides.dram_clock_change_latency_ns) 254 + soc_bb->power_management_parameters.dram_clk_change_blackout_us = 255 + dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 256 + 257 + if (dc->bb_overrides.fclk_clock_change_latency_ns) 258 + soc_bb->power_management_parameters.fclk_change_blackout_us = 259 + dc->bb_overrides.fclk_clock_change_latency_ns / 1000.0; 260 + 261 + //Z8 values not expected nor used on DCN401 but still added for completeness 262 + if (dc->bb_overrides.sr_exit_z8_time_ns) 263 + soc_bb->power_management_parameters.z8_stutter_exit_latency_us = 264 + dc->bb_overrides.sr_exit_z8_time_ns / 1000.0; 265 + 266 + if (dc->bb_overrides.sr_enter_plus_exit_z8_time_ns) 267 + soc_bb->power_management_parameters.z8_stutter_enter_plus_exit_latency_us = 268 + dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0; 269 + } 270 + 271 + static void apply_soc_bb_updates(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) 272 + { 273 + /* Individual modification can be overwritten even if it was obtained by a previous function. 274 + * Modifications are acquired in order of priority (lowest to highest). 275 + */ 276 + dc_assert_fp_enabled(); 277 + 278 + dcn401_update_soc_bb_with_values_from_clk_mgr(soc_bb, dc, config); 279 + dcn401_update_soc_bb_with_values_from_vbios(soc_bb, dc); 280 + dcn401_update_soc_bb_with_values_from_software_policy(soc_bb, dc); 281 + } 282 + 283 + void dcn401_get_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) 284 + { 285 + //get default soc_bb with static values 286 + get_default_soc_bb(soc_bb); 287 + //update soc_bb values with more accurate values 288 + apply_soc_bb_updates(soc_bb, dc, config); 289 + } 290 + 291 + static void dcn401_get_ip_caps(struct dml2_ip_capabilities *ip_caps) 292 + { 293 + *ip_caps = dml2_dcn401_max_ip_caps; 294 + } 295 + 296 + static struct soc_and_ip_translator_funcs dcn401_translator_funcs = { 297 + .get_soc_bb = dcn401_get_soc_bb, 298 + .get_ip_caps = dcn401_get_ip_caps, 299 + }; 300 + 301 + void dcn401_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator) 302 + { 303 + soc_and_ip_translator->translator_funcs = &dcn401_translator_funcs; 304 + }
+22
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #ifndef _DCN401_SOC_AND_IP_TRANSLATOR_H_ 6 + #define _DCN401_SOC_AND_IP_TRANSLATOR_H_ 7 + 8 + #include "core_types.h" 9 + #include "dc.h" 10 + #include "clk_mgr.h" 11 + #include "soc_and_ip_translator.h" 12 + #include "dml2/dml21/inc/dml_top_soc_parameter_types.h" 13 + 14 + void dcn401_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator); 15 + 16 + /* Functions that can be re-used by higher DCN revisions of this component */ 17 + void dcn401_get_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config); 18 + void dcn401_update_soc_bb_with_values_from_clk_mgr(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config); 19 + void dcn401_update_soc_bb_with_values_from_vbios(struct dml2_soc_bb *soc_bb, const struct dc *dc); 20 + void dcn401_update_soc_bb_with_values_from_software_policy(struct dml2_soc_bb *soc_bb, const struct dc *dc); 21 + 22 + #endif /* _DCN401_SOC_AND_IP_TRANSLATOR_H_ */
+27
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #include "dcn42_soc_and_ip_translator.h" 6 + #include "soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h" 7 + #include "bounding_boxes/dcn42_soc_bb.h" 8 + 9 + /* soc_and_ip_translator component used to get up-to-date values for bounding box. 10 + * Bounding box values are stored in several locations and locations can vary with DCN revision. 11 + * This component provides an interface to get DCN-specific bounding box values. 12 + */ 13 + 14 + static void dcn42_get_ip_caps(struct dml2_ip_capabilities *ip_caps) 15 + { 16 + *ip_caps = dml2_dcn42_max_ip_caps; 17 + } 18 + 19 + static struct soc_and_ip_translator_funcs dcn42_translator_funcs = { 20 + .get_soc_bb = dcn401_get_soc_bb, 21 + .get_ip_caps = dcn42_get_ip_caps, 22 + }; 23 + 24 + void dcn42_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator) 25 + { 26 + soc_and_ip_translator->translator_funcs = &dcn42_translator_funcs; 27 + }
+16
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.h
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #ifndef _DCN42_SOC_AND_IP_TRANSLATOR_H_ 6 + #define _DCN42_SOC_AND_IP_TRANSLATOR_H_ 7 + 8 + #include "core_types.h" 9 + #include "dc.h" 10 + #include "clk_mgr.h" 11 + #include "dml_top_soc_parameter_types.h" 12 + #include "soc_and_ip_translator.h" 13 + 14 + void dcn42_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator); 15 + 16 + #endif /* _DCN42_SOC_AND_IP_TRANSLATOR_H_ */
+37
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2025 Advanced Micro Devices, Inc. 4 + 5 + #include "soc_and_ip_translator.h" 6 + #include "soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h" 7 + 8 + static void dc_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator, 9 + enum dce_version dc_version) 10 + { 11 + switch (dc_version) { 12 + case DCN_VERSION_4_01: 13 + dcn401_construct_soc_and_ip_translator(soc_and_ip_translator); 14 + break; 15 + default: 16 + break; 17 + } 18 + } 19 + 20 + struct soc_and_ip_translator *dc_create_soc_and_ip_translator(enum dce_version dc_version) 21 + { 22 + struct soc_and_ip_translator *soc_and_ip_translator; 23 + 24 + soc_and_ip_translator = kzalloc(sizeof(*soc_and_ip_translator), GFP_KERNEL); 25 + if (!soc_and_ip_translator) 26 + return NULL; 27 + 28 + dc_construct_soc_and_ip_translator(soc_and_ip_translator, dc_version); 29 + 30 + return soc_and_ip_translator; 31 + } 32 + 33 + void dc_destroy_soc_and_ip_translator(struct soc_and_ip_translator **soc_and_ip_translator) 34 + { 35 + kfree(*soc_and_ip_translator); 36 + *soc_and_ip_translator = NULL; 37 + }
+7
drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c
··· 44 44 struct dc_crtc_timing *crtc_timing, 45 45 bool is_dual_link) {} 46 46 47 + static void virtual_stream_encoder_lvds_set_stream_attribute( 48 + struct stream_encoder *enc, 49 + struct dc_crtc_timing *crtc_timing) 50 + {} 51 + 47 52 static void virtual_stream_encoder_set_throttled_vcp_size( 48 53 struct stream_encoder *enc, 49 54 struct fixed31_32 avg_time_slots_per_mtp) ··· 120 115 virtual_stream_encoder_hdmi_set_stream_attribute, 121 116 .dvi_set_stream_attribute = 122 117 virtual_stream_encoder_dvi_set_stream_attribute, 118 + .lvds_set_stream_attribute = 119 + virtual_stream_encoder_lvds_set_stream_attribute, 123 120 .set_throttled_vcp_size = 124 121 virtual_stream_encoder_set_throttled_vcp_size, 125 122 .update_hdmi_info_packets =
+4
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 316 316 bool disable_sldo_opt; 317 317 bool enable_non_transparent_setconfig; 318 318 bool lower_hbr3_phy_ssc; 319 + bool override_hbr3_pll_vco; 319 320 }; 320 321 321 322 /** ··· 568 567 569 568 bool sw_init; 570 569 bool hw_init; 570 + bool dpia_supported; 571 571 572 572 uint64_t fb_base; 573 573 uint64_t fb_offset; ··· 599 597 enum dmub_notification_type type; 600 598 uint8_t link_index; 601 599 uint8_t result; 600 + /* notify instance from DMUB */ 601 + uint8_t instance; 602 602 bool pending_notification; 603 603 union { 604 604 struct aux_reply_data aux_reply;
+170 -39
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 843 843 uint32_t ips_sequential_ono: 1; /**< 1 to enable sequential ONO IPS sequence */ 844 844 uint32_t disable_sldo_opt: 1; /**< 1 to disable SLDO optimizations */ 845 845 uint32_t lower_hbr3_phy_ssc: 1; /**< 1 to lower hbr3 phy ssc to 0.125 percent */ 846 - uint32_t reserved : 6; /**< reserved */ 846 + uint32_t override_hbr3_pll_vco: 1; /**< 1 to override the hbr3 pll vco to 0 */ 847 + uint32_t reserved : 5; /**< reserved */ 847 848 } bits; /**< boot bits */ 848 849 uint32_t all; /**< 32-bit access to bits */ 849 850 }; ··· 883 882 /** 884 883 * struct dmub_shared_state_ips_fw - Firmware signals for IPS. 885 884 */ 886 - union dmub_shared_state_ips_fw_signals { 885 + union dmub_shared_state_ips_fw_signals { 887 886 struct { 888 887 uint32_t ips1_commit : 1; /**< 1 if in IPS1 or IPS0 RCG */ 889 888 uint32_t ips2_commit : 1; /**< 1 if in IPS2 */ ··· 898 897 /** 899 898 * struct dmub_shared_state_ips_signals - Firmware signals for IPS. 900 899 */ 901 - union dmub_shared_state_ips_driver_signals { 900 + union dmub_shared_state_ips_driver_signals { 902 901 struct { 903 902 uint32_t allow_pg : 1; /**< 1 if PG is allowed */ 904 903 uint32_t allow_ips1 : 1; /**< 1 is IPS1 is allowed */ ··· 1991 1990 struct lsdma_tiled_copy_data { 1992 1991 uint32_t src_addr_lo; 1993 1992 uint32_t src_addr_hi; 1993 + 1994 1994 uint32_t dst_addr_lo; 1995 1995 uint32_t dst_addr_hi; 1996 1996 1997 1997 uint32_t src_x : 16; 1998 1998 uint32_t src_y : 16; 1999 1999 2000 - uint32_t src_width : 16; 2001 - uint32_t src_height : 16; 2002 - 2003 2000 uint32_t dst_x : 16; 2004 2001 uint32_t dst_y : 16; 2002 + 2003 + uint32_t src_width : 16; 2004 + uint32_t src_height : 16; 2005 2005 2006 2006 uint32_t dst_width : 16; 2007 2007 uint32_t dst_height : 16; ··· 2036 2034 uint32_t padding : 30; 2037 2035 } tiled_copy_data; 2038 2036 struct lsdma_linear_copy_data { 2037 + uint32_t src_lo; 2038 + uint32_t src_hi; 2039 + 2040 + uint32_t dst_lo; 2041 + uint32_t dst_hi; 2042 + 2039 2043 uint32_t count : 30; 2040 2044 uint32_t cache_policy_dst : 2; 2041 2045 2042 2046 uint32_t tmz : 1; 2043 2047 uint32_t cache_policy_src : 2; 2044 2048 uint32_t padding : 29; 2045 - 2049 + } linear_copy_data; 2050 + struct lsdma_linear_sub_window_copy_data { 2046 2051 uint32_t src_lo; 2047 2052 uint32_t src_hi; 2053 + 2048 2054 uint32_t dst_lo; 2049 2055 uint32_t dst_hi; 2050 - } linear_copy_data; 2056 + 2057 + uint32_t src_x : 16; 2058 + uint32_t src_y : 16; 2059 + 2060 + uint32_t dst_x : 16; 2061 + uint32_t dst_y : 16; 2062 + 2063 + uint32_t rect_x : 16; 2064 + uint32_t rect_y : 16; 2065 + 2066 + uint32_t src_pitch : 16; 2067 + uint32_t dst_pitch : 16; 2068 + 2069 + uint32_t src_slice_pitch; 2070 + uint32_t dst_slice_pitch; 2071 + 2072 + uint32_t tmz : 1; 2073 + uint32_t element_size : 3; 2074 + uint32_t src_cache_policy : 3; 2075 + uint32_t dst_cache_policy : 3; 2076 + uint32_t reserved0 : 22; 2077 + } linear_sub_window_copy_data; 2051 2078 struct lsdma_reg_write_data { 2052 2079 uint32_t reg_addr; 2053 2080 uint32_t reg_data; 2054 2081 } reg_write_data; 2055 2082 struct lsdma_pio_copy_data { 2056 - union { 2057 - struct { 2058 - uint32_t byte_count : 26; 2059 - uint32_t src_loc : 1; 2060 - uint32_t dst_loc : 1; 2061 - uint32_t src_addr_inc : 1; 2062 - uint32_t dst_addr_inc : 1; 2063 - uint32_t overlap_disable : 1; 2064 - uint32_t constant_fill : 1; 2065 - } fields; 2066 - uint32_t raw; 2067 - } packet; 2068 2083 uint32_t src_lo; 2069 2084 uint32_t src_hi; 2085 + 2070 2086 uint32_t dst_lo; 2071 2087 uint32_t dst_hi; 2072 - } pio_copy_data; 2073 - struct lsdma_pio_constfill_data { 2088 + 2074 2089 union { 2075 2090 struct { 2076 2091 uint32_t byte_count : 26; ··· 2100 2081 } fields; 2101 2082 uint32_t raw; 2102 2083 } packet; 2084 + } pio_copy_data; 2085 + struct lsdma_pio_constfill_data { 2103 2086 uint32_t dst_lo; 2104 2087 uint32_t dst_hi; 2088 + 2089 + union { 2090 + struct { 2091 + uint32_t byte_count : 26; 2092 + uint32_t src_loc : 1; 2093 + uint32_t dst_loc : 1; 2094 + uint32_t src_addr_inc : 1; 2095 + uint32_t dst_addr_inc : 1; 2096 + uint32_t overlap_disable : 1; 2097 + uint32_t constant_fill : 1; 2098 + } fields; 2099 + uint32_t raw; 2100 + } packet; 2101 + 2105 2102 uint32_t data; 2106 2103 } pio_constfill_data; 2107 2104 2108 2105 uint32_t all[14]; 2109 2106 } u; 2110 - 2111 2107 }; 2112 2108 2113 2109 struct dmub_rb_cmd_lsdma { ··· 2364 2330 union dmub_fams2_global_feature_config features; 2365 2331 uint32_t recovery_timeout_us; 2366 2332 uint32_t hwfq_flip_programming_delay_us; 2333 + uint32_t max_allow_to_target_delta_us; // how early DCN could assert P-State allow compared to the P-State target 2367 2334 }; 2368 2335 2369 2336 union dmub_cmd_fams2_config { ··· 4021 3986 */ 4022 3987 DMUB_CMD__REPLAY_DISABLED_ADAPTIVE_SYNC_SDP = 8, 4023 3988 /** 3989 + * Set version 3990 + */ 3991 + DMUB_CMD__REPLAY_SET_VERSION = 9, 3992 + /** 4024 3993 * Set Replay General command. 4025 3994 */ 4026 3995 DMUB_CMD__REPLAY_SET_GENERAL_CMD = 16, ··· 4054 4015 uint16_t lfps_t1_t2_override_us; 4055 4016 short lfps_t1_t2_offset_us; 4056 4017 uint8_t lttpr_count; 4018 + /* 4019 + * Padding to align structure to 4 byte boundary. 4020 + */ 4021 + uint8_t pad[1]; 4057 4022 }; 4058 4023 4059 4024 /** ··· 4090 4047 * DIG BE HW instance. 4091 4048 */ 4092 4049 uint8_t digbe_inst; 4093 - /** 4094 - * @hpo_stream_enc_inst: HPO stream encoder instance 4095 - */ 4096 - uint8_t hpo_stream_enc_inst; 4097 - /** 4098 - * @hpo_link_enc_inst: HPO link encoder instance 4099 - */ 4100 - uint8_t hpo_link_enc_inst; 4101 4050 /** 4102 4051 * AUX HW instance. 4103 4052 */ ··· 4134 4099 * Use for AUX-less ALPM LFPS wake operation 4135 4100 */ 4136 4101 struct dmub_alpm_auxless_data auxless_alpm_data; 4137 - 4102 + /** 4103 + * @hpo_stream_enc_inst: HPO stream encoder instance 4104 + */ 4105 + uint8_t hpo_stream_enc_inst; 4106 + /** 4107 + * @hpo_link_enc_inst: HPO link encoder instance 4108 + */ 4109 + uint8_t hpo_link_enc_inst; 4138 4110 /** 4139 4111 * @pad: Align structure to 4 byte boundary. 4140 4112 */ 4141 4113 uint8_t pad[2]; 4114 + }; 4115 + 4116 + 4117 + /** 4118 + * Replay versions. 4119 + */ 4120 + enum replay_version { 4121 + /** 4122 + * FreeSync Replay 4123 + */ 4124 + REPLAY_VERSION_FREESYNC_REPLAY = 0, 4125 + /** 4126 + * Panel Replay 4127 + */ 4128 + REPLAY_VERSION_PANEL_REPLAY = 1, 4129 + /** 4130 + * Replay not supported. 4131 + */ 4132 + REPLAY_VERSION_UNSUPPORTED = 0xFF, 4133 + }; 4134 + 4135 + /** 4136 + * Data passed from driver to FW in a DMUB_CMD___SET_REPLAY_VERSION command. 4137 + */ 4138 + struct dmub_cmd_replay_set_version_data { 4139 + /** 4140 + * Panel Instance. 4141 + * Panel instance to identify which psr_state to use 4142 + * Currently the support is only for 0 or 1 4143 + */ 4144 + uint8_t panel_inst; 4145 + /** 4146 + * PSR version that FW should implement. 4147 + */ 4148 + enum replay_version version; 4149 + /** 4150 + * PSR control version. 4151 + */ 4152 + uint8_t cmd_version; 4153 + /** 4154 + * Explicit padding to 4 byte boundary. 4155 + */ 4156 + uint8_t pad[2]; 4157 + }; 4158 + 4159 + /** 4160 + * Definition of a DMUB_CMD__REPLAY_SET_VERSION command. 4161 + */ 4162 + struct dmub_rb_cmd_replay_set_version { 4163 + /** 4164 + * Command header. 4165 + */ 4166 + struct dmub_cmd_header header; 4167 + /** 4168 + * Data passed from driver to FW in a DMUB_CMD__REPLAY_SET_VERSION command. 4169 + */ 4170 + struct dmub_cmd_replay_set_version_data replay_set_version_data; 4142 4171 }; 4143 4172 4144 4173 /** ··· 4569 4470 */ 4570 4471 struct dmub_cmd_replay_disabled_adaptive_sync_sdp_data disabled_adaptive_sync_sdp_data; 4571 4472 /** 4473 + * Definition of DMUB_CMD__REPLAY_SET_VERSION command data. 4474 + */ 4475 + struct dmub_cmd_replay_set_version_data version_data; 4476 + /** 4572 4477 * Definition of DMUB_CMD__REPLAY_SET_GENERAL_CMD command data. 4573 4478 */ 4574 4479 struct dmub_cmd_replay_set_general_cmd_data set_general_cmd_data; ··· 4788 4685 */ 4789 4686 DMUB_CMD__LSDMA_LINEAR_COPY = 1, 4790 4687 /** 4688 + * LSDMA copies data from source to destination linearly in sub window 4689 + */ 4690 + DMUB_CMD__LSDMA_LINEAR_SUB_WINDOW_COPY = 2, 4691 + /** 4791 4692 * Send the tiled-to-tiled copy command 4792 4693 */ 4793 - DMUB_CMD__LSDMA_TILED_TO_TILED_COPY = 2, 4694 + DMUB_CMD__LSDMA_TILED_TO_TILED_COPY = 3, 4794 4695 /** 4795 4696 * Send the poll reg write command 4796 4697 */ 4797 - DMUB_CMD__LSDMA_POLL_REG_WRITE = 3, 4698 + DMUB_CMD__LSDMA_POLL_REG_WRITE = 4, 4798 4699 /** 4799 4700 * Send the pio copy command 4800 4701 */ 4801 - DMUB_CMD__LSDMA_PIO_COPY = 4, 4702 + DMUB_CMD__LSDMA_PIO_COPY = 5, 4802 4703 /** 4803 4704 * Send the pio constfill command 4804 4705 */ 4805 - DMUB_CMD__LSDMA_PIO_CONSTFILL = 5, 4706 + DMUB_CMD__LSDMA_PIO_CONSTFILL = 6, 4806 4707 }; 4807 4708 4808 4709 struct abm_ace_curve { ··· 6021 5914 IPS_RESIDENCY__IPS2, 6022 5915 IPS_RESIDENCY__IPS1_RCG, 6023 5916 IPS_RESIDENCY__IPS1_ONO2_ON, 5917 + IPS_RESIDENCY__IPS1_Z8_RETENTION, 5918 + IPS_RESIDENCY__PG_ONO_LAST_SEEN_IN_IPS, 5919 + IPS_RESIDENCY__PG_ONO_CURRENT_STATE 6024 5920 }; 6025 5921 6026 5922 #define NUM_IPS_HISTOGRAM_BUCKETS 16 ··· 6037 5927 uint32_t histogram[NUM_IPS_HISTOGRAM_BUCKETS]; 6038 5928 uint64_t total_time_us; 6039 5929 uint64_t total_inactive_time_us; 5930 + uint32_t ono_pg_state_at_collection; 5931 + uint32_t ono_pg_state_last_seen_in_ips; 6040 5932 }; 6041 5933 6042 5934 /** ··· 6335 6223 * Definition of a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command. 6336 6224 */ 6337 6225 struct dmub_rb_cmd_idle_opt_set_dc_power_state idle_opt_set_dc_power_state; 6226 + /** 6227 + * Definition of a DMUB_CMD__REPLAY_SET_VERSION command. 6228 + */ 6229 + struct dmub_rb_cmd_replay_set_version replay_set_version; 6338 6230 /* 6339 6231 * Definition of a DMUB_CMD__REPLAY_COPY_SETTINGS command. 6340 6232 */ ··· 6547 6431 static inline bool dmub_rb_push_front(struct dmub_rb *rb, 6548 6432 const union dmub_rb_cmd *cmd) 6549 6433 { 6550 - uint64_t volatile *dst = (uint64_t volatile *)((uint8_t *)(rb->base_address) + rb->wrpt); 6551 - const uint64_t *src = (const uint64_t *)cmd; 6434 + uint8_t *dst = (uint8_t *)(rb->base_address) + rb->wrpt; 6435 + const uint8_t *src = (const uint8_t *)cmd; 6552 6436 uint8_t i; 6437 + 6438 + if (rb->capacity == 0) 6439 + return false; 6553 6440 6554 6441 if (dmub_rb_full(rb)) 6555 6442 return false; 6556 6443 6557 6444 // copying data 6558 - for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) 6445 + for (i = 0; i < DMUB_RB_CMD_SIZE; i++) 6559 6446 *dst++ = *src++; 6560 6447 6561 6448 rb->wrpt += DMUB_RB_CMD_SIZE; ··· 6582 6463 { 6583 6464 uint8_t *dst = (uint8_t *)(rb->base_address) + rb->wrpt; 6584 6465 const uint8_t *src = (const uint8_t *)cmd; 6466 + 6467 + if (rb->capacity == 0) 6468 + return false; 6585 6469 6586 6470 if (dmub_rb_full(rb)) 6587 6471 return false; ··· 6631 6509 uint32_t num_cmds, 6632 6510 uint32_t *next_rptr) 6633 6511 { 6512 + if (rb->capacity == 0) 6513 + return; 6514 + 6634 6515 *next_rptr = rb->rptr + DMUB_RB_CMD_SIZE * num_cmds; 6635 6516 6636 6517 if (*next_rptr >= rb->capacity) ··· 6697 6572 */ 6698 6573 static inline bool dmub_rb_pop_front(struct dmub_rb *rb) 6699 6574 { 6575 + if (rb->capacity == 0) 6576 + return false; 6577 + 6700 6578 if (dmub_rb_empty(rb)) 6701 6579 return false; 6702 6580 ··· 6723 6595 { 6724 6596 uint32_t rptr = rb->rptr; 6725 6597 uint32_t wptr = rb->wrpt; 6598 + 6599 + if (rb->capacity == 0) 6600 + return; 6726 6601 6727 6602 while (rptr != wptr) { 6728 6603 uint64_t *data = (uint64_t *)((uint8_t *)(rb->base_address) + rptr);
+1
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
··· 377 377 boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported; 378 378 boot_options.bits.power_optimization = params->power_optimization; 379 379 boot_options.bits.lower_hbr3_phy_ssc = params->lower_hbr3_phy_ssc; 380 + boot_options.bits.override_hbr3_pll_vco = params->override_hbr3_pll_vco; 380 381 381 382 boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; 382 383
+4 -3
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
··· 400 400 void dmub_dcn35_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params) 401 401 { 402 402 union dmub_fw_boot_options boot_options = {0}; 403 - union dmub_fw_boot_options cur_boot_options = {0}; 404 403 405 - cur_boot_options = dmub_dcn35_get_fw_boot_option(dmub); 404 + if (!dmub->dpia_supported) { 405 + dmub->dpia_supported = dmub_dcn35_get_fw_boot_option(dmub).bits.enable_dpia; 406 + } 406 407 407 408 boot_options.bits.z10_disable = params->disable_z10; 408 409 boot_options.bits.dpia_supported = params->dpia_supported; 409 - boot_options.bits.enable_dpia = cur_boot_options.bits.enable_dpia && !params->disable_dpia; 410 + boot_options.bits.enable_dpia = dmub->dpia_supported && !params->disable_dpia; 410 411 boot_options.bits.usb4_cm_version = params->usb4_cm_version; 411 412 boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported; 412 413 boot_options.bits.power_optimization = params->power_optimization;
+4 -4
drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
··· 71 71 switch (cmd.cmd_common.header.type) { 72 72 case DMUB_OUT_CMD__DP_AUX_REPLY: 73 73 notify->type = DMUB_NOTIFICATION_AUX_REPLY; 74 - notify->link_index = cmd.dp_aux_reply.control.instance; 74 + notify->instance = cmd.dp_aux_reply.control.instance; 75 75 notify->result = cmd.dp_aux_reply.control.result; 76 76 dmub_memcpy((void *)&notify->aux_reply, 77 77 (void *)&cmd.dp_aux_reply.reply_data, sizeof(struct aux_reply_data)); ··· 84 84 notify->type = DMUB_NOTIFICATION_HPD_IRQ; 85 85 } 86 86 87 - notify->link_index = cmd.dp_hpd_notify.hpd_data.instance; 87 + notify->instance = cmd.dp_hpd_notify.hpd_data.instance; 88 88 notify->result = AUX_RET_SUCCESS; 89 89 break; 90 90 case DMUB_OUT_CMD__SET_CONFIG_REPLY: 91 91 notify->type = DMUB_NOTIFICATION_SET_CONFIG_REPLY; 92 - notify->link_index = cmd.set_config_reply.set_config_reply_control.instance; 92 + notify->instance = cmd.set_config_reply.set_config_reply_control.instance; 93 93 notify->sc_status = cmd.set_config_reply.set_config_reply_control.status; 94 94 break; 95 95 case DMUB_OUT_CMD__DPIA_NOTIFICATION: 96 96 notify->type = DMUB_NOTIFICATION_DPIA_NOTIFICATION; 97 - notify->link_index = cmd.dpia_notification.payload.header.instance; 97 + notify->instance = cmd.dpia_notification.payload.header.instance; 98 98 break; 99 99 case DMUB_OUT_CMD__HPD_SENSE_NOTIFY: 100 100 notify->type = DMUB_NOTIFICATION_HPD_SENSE_NOTIFY;
+5
drivers/gpu/drm/amd/display/include/dal_asic_id.h
··· 213 213 #endif 214 214 #define DEVICE_ID_NV_13FE 0x13FE // CYAN_SKILLFISH 215 215 #define DEVICE_ID_NV_143F 0x143F 216 + #define DEVICE_ID_NV_13F9 0x13F9 217 + #define DEVICE_ID_NV_13FA 0x13FA 218 + #define DEVICE_ID_NV_13FB 0x13FB 219 + #define DEVICE_ID_NV_13FC 0x13FC 220 + #define DEVICE_ID_NV_13DB 0x13DB 216 221 #define FAMILY_VGH 144 217 222 #define DEVICE_ID_VGH_163F 0x163F 218 223 #define DEVICE_ID_VGH_1435 0x1435
+3
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
··· 260 260 return MOD_HDCP_STATUS_FAILURE; 261 261 } 262 262 263 + if (!display) 264 + return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; 265 + 263 266 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; 264 267 265 268 mutex_lock(&psp->hdcp_context.mutex);
+15 -15
drivers/gpu/drm/amd/include/atomfirmware.h
··· 211 211 }; 212 212 */ 213 213 214 - #pragma pack(1) /* BIOS data must use byte aligment*/ 214 + #pragma pack(1) /* BIOS data must use byte alignment*/ 215 215 216 216 enum atombios_image_offset{ 217 217 OFFSET_TO_ATOM_ROM_HEADER_POINTER = 0x00000048, ··· 255 255 uint16_t subsystem_vendor_id; 256 256 uint16_t subsystem_id; 257 257 uint16_t pci_info_offset; 258 - uint16_t masterhwfunction_offset; //Offest for SW to get all command function offsets, Don't change the position 259 - uint16_t masterdatatable_offset; //Offest for SW to get all data table offsets, Don't change the position 258 + uint16_t masterhwfunction_offset; //Offset for SW to get all command function offsets, Don't change the position 259 + uint16_t masterdatatable_offset; //Offset for SW to get all data table offsets, Don't change the position 260 260 uint16_t reserved; 261 261 uint32_t pspdirtableoffset; 262 262 }; ··· 453 453 uint8_t refreshrate; 454 454 }; 455 455 456 - /* atom_dtd_format.modemiscinfo defintion */ 456 + /* atom_dtd_format.modemiscinfo definition */ 457 457 enum atom_dtd_format_modemiscinfo{ 458 458 ATOM_HSYNC_POLARITY = 0x0002, 459 459 ATOM_VSYNC_POLARITY = 0x0004, ··· 678 678 uint32_t reserved1[8]; 679 679 }; 680 680 681 - /* lcd_info_v2_1.panel_misc defintion */ 681 + /* lcd_info_v2_1.panel_misc definition */ 682 682 enum atom_lcd_info_panel_misc{ 683 683 ATOM_PANEL_MISC_FPDI =0x0002, 684 684 }; ··· 716 716 /* gpio_id pre-define id for multiple usage */ 717 717 /* GPIO use to control PCIE_VDDC in certain SLT board */ 718 718 PCIE_VDDC_CONTROL_GPIO_PINID = 56, 719 - /* if PP_AC_DC_SWITCH_GPIO_PINID in Gpio_Pin_LutTable, AC/DC swithing feature is enable */ 719 + /* if PP_AC_DC_SWITCH_GPIO_PINID in Gpio_Pin_LutTable, AC/DC switching feature is enable */ 720 720 PP_AC_DC_SWITCH_GPIO_PINID = 60, 721 721 /* VDDC_REGULATOR_VRHOT_GPIO_PINID in Gpio_Pin_LutTable, VRHot feature is enable */ 722 722 VDDC_VRHOT_GPIO_PINID = 61, ··· 734 734 struct atom_gpio_pin_lut_v2_1 735 735 { 736 736 struct atom_common_table_header table_header; 737 - /*the real number of this included in the structure is calcualted by using the (whole structure size - the header size)/size of atom_gpio_pin_lut */ 737 + /*the real number of this included in the structure is calculated by using the (whole structure size - the header size)/size of atom_gpio_pin_lut */ 738 738 struct atom_gpio_pin_assignment gpio_pin[]; 739 739 }; 740 740 ··· 997 997 998 998 enum atom_display_device_tag_def{ 999 999 ATOM_DISPLAY_LCD1_SUPPORT = 0x0002, //an embedded display is either an LVDS or eDP signal type of display 1000 - ATOM_DISPLAY_LCD2_SUPPORT = 0x0020, //second edp device tag 0x0020 for backward compability 1000 + ATOM_DISPLAY_LCD2_SUPPORT = 0x0020, //second edp device tag 0x0020 for backward compatibility 1001 1001 ATOM_DISPLAY_DFP1_SUPPORT = 0x0008, 1002 1002 ATOM_DISPLAY_DFP2_SUPPORT = 0x0080, 1003 1003 ATOM_DISPLAY_DFP3_SUPPORT = 0x0200, ··· 1011 1011 { 1012 1012 uint16_t display_objid; //Connector Object ID or Misc Object ID 1013 1013 uint16_t disp_recordoffset; 1014 - uint16_t encoderobjid; //first encoder closer to the connector, could be either an external or intenal encoder 1014 + uint16_t encoderobjid; //first encoder closer to the connector, could be either an external or internal encoder 1015 1015 uint16_t extencoderobjid; //2nd encoder after the first encoder, from the connector point of view; 1016 1016 uint16_t encoder_recordoffset; 1017 1017 uint16_t extencoder_recordoffset; ··· 1023 1023 struct atom_display_object_path_v3 { 1024 1024 uint16_t display_objid; //Connector Object ID or Misc Object ID 1025 1025 uint16_t disp_recordoffset; 1026 - uint16_t encoderobjid; //first encoder closer to the connector, could be either an external or intenal encoder 1026 + uint16_t encoderobjid; //first encoder closer to the connector, could be either an external or internal encoder 1027 1027 uint16_t reserved1; //only on USBC case, otherwise always = 0 1028 1028 uint16_t reserved2; //reserved and always = 0 1029 1029 uint16_t reserved3; //reserved and always = 0 ··· 3547 3547 enum atom_voltage_object_mode 3548 3548 { 3549 3549 VOLTAGE_OBJ_GPIO_LUT = 0, //VOLTAGE and GPIO Lookup table ->atom_gpio_voltage_object_v4 3550 - VOLTAGE_OBJ_VR_I2C_INIT_SEQ = 3, //VOLTAGE REGULATOR INIT sequece through I2C -> atom_i2c_voltage_object_v4 3550 + VOLTAGE_OBJ_VR_I2C_INIT_SEQ = 3, //VOLTAGE REGULATOR INIT sequence through I2C -> atom_i2c_voltage_object_v4 3551 3551 VOLTAGE_OBJ_PHASE_LUT = 4, //Set Vregulator Phase lookup table ->atom_gpio_voltage_object_v4 3552 3552 VOLTAGE_OBJ_SVID2 = 7, //Indicate voltage control by SVID2 ->atom_svid2_voltage_object_v4 3553 3553 VOLTAGE_OBJ_EVV = 8, ··· 3585 3585 { 3586 3586 struct atom_voltage_object_header_v4 header; // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT 3587 3587 uint8_t gpio_control_id; // default is 0 which indicate control through CG VID mode 3588 - uint8_t gpio_entry_num; // indiate the entry numbers of Votlage/Gpio value Look up table 3588 + uint8_t gpio_entry_num; // indicate the entry numbers of Votlage/Gpio value Look up table 3589 3589 uint8_t phase_delay_us; // phase delay in unit of micro second 3590 3590 uint8_t reserved; 3591 3591 uint32_t gpio_mask_val; // GPIO Mask value ··· 4507 4507 struct uefi_acpi_vfct{ 4508 4508 struct amd_acpi_description_header sheader; 4509 4509 uint8_t tableUUID[16]; //0x24 4510 - uint32_t vbiosimageoffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture. 4511 - uint32_t lib1Imageoffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture. 4510 + uint32_t vbiosimageoffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the structure. 4511 + uint32_t lib1Imageoffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the structure. 4512 4512 uint32_t reserved[4]; //0x3C 4513 4513 }; 4514 4514 ··· 4540 4540 /* 4541 4541 *************************************************************************** 4542 4542 Scratch Register definitions 4543 - Each number below indicates which scratch regiser request, Active and 4543 + Each number below indicates which scratch register request, Active and 4544 4544 Connect all share the same definitions as display_device_tag defines 4545 4545 *************************************************************************** 4546 4546 */
+81
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 30 30 extern const struct amdgpu_ip_block_version smu_v13_0_ip_block; 31 31 extern const struct amdgpu_ip_block_version smu_v14_0_ip_block; 32 32 33 + enum smu_temp_metric_type { 34 + SMU_TEMP_METRIC_BASEBOARD, 35 + SMU_TEMP_METRIC_GPUBOARD, 36 + SMU_TEMP_METRIC_MAX, 37 + }; 38 + 33 39 enum smu_event_type { 34 40 SMU_EVENT_RESET_COMPLETE = 0, 35 41 }; ··· 502 496 int (*set_df_cstate)(void *handle, enum pp_df_cstate state); 503 497 int (*set_xgmi_pstate)(void *handle, uint32_t pstate); 504 498 ssize_t (*get_gpu_metrics)(void *handle, void **table); 499 + ssize_t (*get_temp_metrics)(void *handle, enum smu_temp_metric_type type, void *table); 500 + bool (*temp_metrics_is_supported)(void *handle, enum smu_temp_metric_type type); 505 501 ssize_t (*get_xcp_metrics)(void *handle, int xcp_id, void *table); 506 502 ssize_t (*get_pm_metrics)(void *handle, void *pmmetrics, size_t size); 507 503 int (*set_watermarks_for_clock_ranges)(void *handle, ··· 1601 1593 struct amdgpu_pmmetrics_header common_header; 1602 1594 1603 1595 uint8_t data[]; 1596 + }; 1597 + 1598 + enum amdgpu_vr_temp { 1599 + AMDGPU_VDDCR_VDD0_TEMP, 1600 + AMDGPU_VDDCR_VDD1_TEMP, 1601 + AMDGPU_VDDCR_VDD2_TEMP, 1602 + AMDGPU_VDDCR_VDD3_TEMP, 1603 + AMDGPU_VDDCR_SOC_A_TEMP, 1604 + AMDGPU_VDDCR_SOC_C_TEMP, 1605 + AMDGPU_VDDCR_SOCIO_A_TEMP, 1606 + AMDGPU_VDDCR_SOCIO_C_TEMP, 1607 + AMDGPU_VDD_085_HBM_TEMP, 1608 + AMDGPU_VDDCR_11_HBM_B_TEMP, 1609 + AMDGPU_VDDCR_11_HBM_D_TEMP, 1610 + AMDGPU_VDD_USR_TEMP, 1611 + AMDGPU_VDDIO_11_E32_TEMP, 1612 + AMDGPU_VR_MAX_TEMP_ENTRIES, 1613 + }; 1614 + 1615 + enum amdgpu_system_temp { 1616 + AMDGPU_UBB_FPGA_TEMP, 1617 + AMDGPU_UBB_FRONT_TEMP, 1618 + AMDGPU_UBB_BACK_TEMP, 1619 + AMDGPU_UBB_OAM7_TEMP, 1620 + AMDGPU_UBB_IBC_TEMP, 1621 + AMDGPU_UBB_UFPGA_TEMP, 1622 + AMDGPU_UBB_OAM1_TEMP, 1623 + AMDGPU_OAM_0_1_HSC_TEMP, 1624 + AMDGPU_OAM_2_3_HSC_TEMP, 1625 + AMDGPU_OAM_4_5_HSC_TEMP, 1626 + AMDGPU_OAM_6_7_HSC_TEMP, 1627 + AMDGPU_UBB_FPGA_0V72_VR_TEMP, 1628 + AMDGPU_UBB_FPGA_3V3_VR_TEMP, 1629 + AMDGPU_RETIMER_0_1_2_3_1V2_VR_TEMP, 1630 + AMDGPU_RETIMER_4_5_6_7_1V2_VR_TEMP, 1631 + AMDGPU_RETIMER_0_1_0V9_VR_TEMP, 1632 + AMDGPU_RETIMER_4_5_0V9_VR_TEMP, 1633 + AMDGPU_RETIMER_2_3_0V9_VR_TEMP, 1634 + AMDGPU_RETIMER_6_7_0V9_VR_TEMP, 1635 + AMDGPU_OAM_0_1_2_3_3V3_VR_TEMP, 1636 + AMDGPU_OAM_4_5_6_7_3V3_VR_TEMP, 1637 + AMDGPU_IBC_HSC_TEMP, 1638 + AMDGPU_IBC_TEMP, 1639 + AMDGPU_SYSTEM_MAX_TEMP_ENTRIES = 32, 1640 + }; 1641 + 1642 + enum amdgpu_node_temp { 1643 + AMDGPU_RETIMER_X_TEMP, 1644 + AMDGPU_OAM_X_IBC_TEMP, 1645 + AMDGPU_OAM_X_IBC_2_TEMP, 1646 + AMDGPU_OAM_X_VDD18_VR_TEMP, 1647 + AMDGPU_OAM_X_04_HBM_B_VR_TEMP, 1648 + AMDGPU_OAM_X_04_HBM_D_VR_TEMP, 1649 + AMDGPU_NODE_MAX_TEMP_ENTRIES = 12, 1650 + }; 1651 + 1652 + struct amdgpu_gpuboard_temp_metrics_v1_0 { 1653 + struct metrics_table_header common_header; 1654 + uint16_t label_version; 1655 + uint16_t node_id; 1656 + uint64_t accumulation_counter; 1657 + /* Encoded temperature in Celcius, 24:31 is sensor id 0:23 is temp value */ 1658 + uint32_t node_temp[AMDGPU_NODE_MAX_TEMP_ENTRIES]; 1659 + uint32_t vr_temp[AMDGPU_VR_MAX_TEMP_ENTRIES]; 1660 + }; 1661 + 1662 + struct amdgpu_baseboard_temp_metrics_v1_0 { 1663 + struct metrics_table_header common_header; 1664 + uint16_t label_version; 1665 + uint16_t node_id; 1666 + uint64_t accumulation_counter; 1667 + /* Encoded temperature in Celcius, 24:31 is sensor id 0:23 is temp value */ 1668 + uint32_t system_temp[AMDGPU_SYSTEM_MAX_TEMP_ENTRIES]; 1604 1669 }; 1605 1670 1606 1671 struct amdgpu_partition_metrics_v1_0 {
+30
drivers/gpu/drm/amd/include/mes_v12_api_def.h
··· 66 66 MES_SCH_API_SET_SE_MODE = 17, 67 67 MES_SCH_API_SET_GANG_SUBMIT = 18, 68 68 MES_SCH_API_SET_HW_RSRC_1 = 19, 69 + MES_SCH_API_INV_TLBS = 20, 69 70 70 71 MES_SCH_API_MAX = 0xFF 71 72 }; ··· 866 865 union MES_API_HEADER header; 867 866 struct MES_API_STATUS api_status; 868 867 struct SET_GANG_SUBMIT set_gang_submit; 868 + }; 869 + 870 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 871 + }; 872 + 873 + /* 874 + * @inv_sel 0-select pasid as input to do the invalidation , 1-select vmid 875 + * @flush_type 0-old style, 1-light weight, 2-heavyweight, 3-heavyweight2 876 + * @inv_sel_id specific pasid when inv_sel is 0 and specific vmid if inv_sel is 1 877 + * @hub_id 0-gc_hub, 1-mm_hub 878 + */ 879 + struct INV_TLBS { 880 + uint8_t inv_sel; 881 + uint8_t flush_type; 882 + uint16_t inv_sel_id; 883 + uint32_t hub_id; 884 + /* If following two inv_range setting are all 0 , whole VM will be invalidated, 885 + * otherwise only required range be invalidated 886 + */ 887 + uint64_t inv_range_va_start; 888 + uint64_t inv_range_size; 889 + uint64_t reserved; 890 + }; 891 + 892 + union MESAPI__INV_TLBS { 893 + struct { 894 + union MES_API_HEADER header; 895 + struct MES_API_STATUS api_status; 896 + struct INV_TLBS invalidate_tlbs; 869 897 }; 870 898 871 899 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
+75 -4
drivers/gpu/drm/amd/pm/amdgpu_dpm.c
··· 764 764 ret = smu_send_rma_reason(smu); 765 765 mutex_unlock(&adev->pm.mutex); 766 766 767 - if (adev->cper.enabled) 768 - if (amdgpu_cper_generate_bp_threshold_record(adev)) 769 - dev_warn(adev->dev, "fail to generate bad page threshold cper records\n"); 770 - 771 767 return ret; 772 768 } 773 769 ··· 815 819 816 820 mutex_lock(&adev->pm.mutex); 817 821 ret = smu_reset_vcn(smu, inst_mask); 822 + mutex_unlock(&adev->pm.mutex); 823 + 824 + return ret; 825 + } 826 + 827 + bool amdgpu_dpm_reset_vcn_is_supported(struct amdgpu_device *adev) 828 + { 829 + struct smu_context *smu = adev->powerplay.pp_handle; 830 + bool ret; 831 + 832 + if (!is_support_sw_smu(adev)) 833 + return false; 834 + 835 + mutex_lock(&adev->pm.mutex); 836 + ret = smu_reset_vcn_is_supported(smu); 818 837 mutex_unlock(&adev->pm.mutex); 819 838 820 839 return ret; ··· 2046 2035 mutex_unlock(&adev->pm.mutex); 2047 2036 2048 2037 return ret; 2038 + } 2039 + 2040 + /** 2041 + * amdgpu_dpm_get_temp_metrics - Retrieve metrics for a specific compute 2042 + * partition 2043 + * @adev: Pointer to the device. 2044 + * @type: Identifier for the temperature type metrics to be fetched. 2045 + * @table: Pointer to a buffer where the metrics will be stored. If NULL, the 2046 + * function returns the size of the metrics structure. 2047 + * 2048 + * This function retrieves metrics for a specific temperature type, If the 2049 + * table parameter is NULL, the function returns the size of the metrics 2050 + * structure without populating it. 2051 + * 2052 + * Return: Size of the metrics structure on success, or a negative error code on failure. 2053 + */ 2054 + ssize_t amdgpu_dpm_get_temp_metrics(struct amdgpu_device *adev, 2055 + enum smu_temp_metric_type type, void *table) 2056 + { 2057 + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 2058 + int ret; 2059 + 2060 + if (!pp_funcs->get_temp_metrics || 2061 + !amdgpu_dpm_is_temp_metrics_supported(adev, type)) 2062 + return -EOPNOTSUPP; 2063 + 2064 + mutex_lock(&adev->pm.mutex); 2065 + ret = pp_funcs->get_temp_metrics(adev->powerplay.pp_handle, type, table); 2066 + mutex_unlock(&adev->pm.mutex); 2067 + 2068 + return ret; 2069 + } 2070 + 2071 + /** 2072 + * amdgpu_dpm_is_temp_metrics_supported - Return if specific temperature metrics support 2073 + * is available 2074 + * @adev: Pointer to the device. 2075 + * @type: Identifier for the temperature type metrics to be fetched. 2076 + * 2077 + * This function returns metrics if specific temperature metrics type is supported or not. 2078 + * 2079 + * Return: True in case of metrics type supported else false. 2080 + */ 2081 + bool amdgpu_dpm_is_temp_metrics_supported(struct amdgpu_device *adev, 2082 + enum smu_temp_metric_type type) 2083 + { 2084 + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 2085 + bool support_temp_metrics = false; 2086 + 2087 + if (!pp_funcs->temp_metrics_is_supported) 2088 + return support_temp_metrics; 2089 + 2090 + if (is_support_sw_smu(adev)) { 2091 + mutex_lock(&adev->pm.mutex); 2092 + support_temp_metrics = 2093 + pp_funcs->temp_metrics_is_supported(adev->powerplay.pp_handle, type); 2094 + mutex_unlock(&adev->pm.mutex); 2095 + } 2096 + 2097 + return support_temp_metrics; 2049 2098 } 2050 2099 2051 2100 /**
+145 -8
drivers/gpu/drm/amd/pm/amdgpu_pm.c
··· 2073 2073 return 0; 2074 2074 } 2075 2075 2076 + /** 2077 + * DOC: board 2078 + * 2079 + * Certain SOCs can support various board attributes reporting. This is useful 2080 + * for user application to monitor various board reated attributes. 2081 + * 2082 + * The amdgpu driver provides a sysfs API for reporting board attributes. Presently, 2083 + * only two types of attributes are reported, baseboard temperature and 2084 + * gpu board temperature. Both of them are reported as binary files. 2085 + * 2086 + * * .. code-block:: console 2087 + * 2088 + * hexdump /sys/bus/pci/devices/.../board/baseboard_temp 2089 + * 2090 + * hexdump /sys/bus/pci/devices/.../board/gpuboard_temp 2091 + * 2092 + */ 2093 + 2094 + /** 2095 + * DOC: baseboard_temp 2096 + * 2097 + * The amdgpu driver provides a sysfs API for retrieving current baseboard 2098 + * temperature metrics data. The file baseboard_temp is used for this. 2099 + * Reading the file will dump all the current baseboard temperature metrics data. 2100 + */ 2101 + static ssize_t amdgpu_get_baseboard_temp_metrics(struct device *dev, 2102 + struct device_attribute *attr, char *buf) 2103 + { 2104 + struct drm_device *ddev = dev_get_drvdata(dev); 2105 + struct amdgpu_device *adev = drm_to_adev(ddev); 2106 + ssize_t size; 2107 + int ret; 2108 + 2109 + ret = amdgpu_pm_get_access_if_active(adev); 2110 + if (ret) 2111 + return ret; 2112 + 2113 + size = amdgpu_dpm_get_temp_metrics(adev, SMU_TEMP_METRIC_BASEBOARD, NULL); 2114 + if (size <= 0) 2115 + goto out; 2116 + if (size >= PAGE_SIZE) { 2117 + ret = -ENOSPC; 2118 + goto out; 2119 + } 2120 + 2121 + amdgpu_dpm_get_temp_metrics(adev, SMU_TEMP_METRIC_BASEBOARD, buf); 2122 + 2123 + out: 2124 + amdgpu_pm_put_access(adev); 2125 + 2126 + if (ret) 2127 + return ret; 2128 + 2129 + return size; 2130 + } 2131 + 2132 + /** 2133 + * DOC: gpuboard_temp 2134 + * 2135 + * The amdgpu driver provides a sysfs API for retrieving current gpuboard 2136 + * temperature metrics data. The file gpuboard_temp is used for this. 2137 + * Reading the file will dump all the current gpuboard temperature metrics data. 2138 + */ 2139 + static ssize_t amdgpu_get_gpuboard_temp_metrics(struct device *dev, 2140 + struct device_attribute *attr, char *buf) 2141 + { 2142 + struct drm_device *ddev = dev_get_drvdata(dev); 2143 + struct amdgpu_device *adev = drm_to_adev(ddev); 2144 + ssize_t size; 2145 + int ret; 2146 + 2147 + ret = amdgpu_pm_get_access_if_active(adev); 2148 + if (ret) 2149 + return ret; 2150 + 2151 + size = amdgpu_dpm_get_temp_metrics(adev, SMU_TEMP_METRIC_GPUBOARD, NULL); 2152 + if (size <= 0) 2153 + goto out; 2154 + if (size >= PAGE_SIZE) { 2155 + ret = -ENOSPC; 2156 + goto out; 2157 + } 2158 + 2159 + amdgpu_dpm_get_temp_metrics(adev, SMU_TEMP_METRIC_GPUBOARD, buf); 2160 + 2161 + out: 2162 + amdgpu_pm_put_access(adev); 2163 + 2164 + if (ret) 2165 + return ret; 2166 + 2167 + return size; 2168 + } 2169 + 2170 + static DEVICE_ATTR(baseboard_temp, 0444, amdgpu_get_baseboard_temp_metrics, NULL); 2171 + static DEVICE_ATTR(gpuboard_temp, 0444, amdgpu_get_gpuboard_temp_metrics, NULL); 2172 + 2173 + static struct attribute *board_attrs[] = { 2174 + &dev_attr_baseboard_temp.attr, 2175 + &dev_attr_gpuboard_temp.attr, 2176 + NULL 2177 + }; 2178 + 2179 + static umode_t amdgpu_board_attr_visible(struct kobject *kobj, struct attribute *attr, int n) 2180 + { 2181 + struct device *dev = kobj_to_dev(kobj); 2182 + struct drm_device *ddev = dev_get_drvdata(dev); 2183 + struct amdgpu_device *adev = drm_to_adev(ddev); 2184 + 2185 + if (attr == &dev_attr_baseboard_temp.attr) { 2186 + if (!amdgpu_dpm_is_temp_metrics_supported(adev, SMU_TEMP_METRIC_BASEBOARD)) 2187 + return 0; 2188 + } 2189 + 2190 + if (attr == &dev_attr_gpuboard_temp.attr) { 2191 + if (!amdgpu_dpm_is_temp_metrics_supported(adev, SMU_TEMP_METRIC_GPUBOARD)) 2192 + return 0; 2193 + } 2194 + 2195 + return attr->mode; 2196 + } 2197 + 2198 + const struct attribute_group amdgpu_board_attr_group = { 2199 + .name = "board", 2200 + .attrs = board_attrs, 2201 + .is_visible = amdgpu_board_attr_visible, 2202 + }; 2203 + 2076 2204 /* pm policy attributes */ 2077 2205 struct amdgpu_pm_policy_attr { 2078 2206 struct device_attribute dev_attr; ··· 3586 3458 effective_mode &= ~S_IWUSR; 3587 3459 3588 3460 /* not implemented yet for APUs other than GC 10.3.1 (vangogh) and 9.4.3 */ 3589 - if (((adev->family == AMDGPU_FAMILY_SI) || 3590 - ((adev->flags & AMD_IS_APU) && (gc_ver != IP_VERSION(10, 3, 1)) && 3591 - (gc_ver != IP_VERSION(9, 4, 3) && gc_ver != IP_VERSION(9, 4, 4)))) && 3592 - (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || 3593 - attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr || 3594 - attr == &sensor_dev_attr_power1_cap.dev_attr.attr || 3595 - attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr)) 3596 - return 0; 3461 + if (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || 3462 + attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr || 3463 + attr == &sensor_dev_attr_power1_cap.dev_attr.attr || 3464 + attr == &sensor_dev_attr_power1_cap_default.dev_attr.attr) { 3465 + if (adev->family == AMDGPU_FAMILY_SI || 3466 + ((adev->flags & AMD_IS_APU) && gc_ver != IP_VERSION(10, 3, 1) && 3467 + (gc_ver != IP_VERSION(9, 4, 3) && gc_ver != IP_VERSION(9, 4, 4))) || 3468 + (amdgpu_sriov_vf(adev) && gc_ver == IP_VERSION(11, 0, 3))) 3469 + return 0; 3470 + } 3597 3471 3598 3472 /* not implemented yet for APUs having < GC 9.3.0 (Renoir) */ 3599 3473 if (((adev->family == AMDGPU_FAMILY_SI) || ··· 4587 4457 -EOPNOTSUPP) { 4588 4458 ret = devm_device_add_group(adev->dev, 4589 4459 &amdgpu_pm_policy_attr_group); 4460 + if (ret) 4461 + goto err_out0; 4462 + } 4463 + 4464 + if (amdgpu_dpm_is_temp_metrics_supported(adev, SMU_TEMP_METRIC_GPUBOARD)) { 4465 + ret = devm_device_add_group(adev->dev, 4466 + &amdgpu_board_attr_group); 4590 4467 if (ret) 4591 4468 goto err_out0; 4592 4469 }
+5
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
··· 526 526 int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table); 527 527 ssize_t amdgpu_dpm_get_xcp_metrics(struct amdgpu_device *adev, int xcp_id, 528 528 void *table); 529 + ssize_t amdgpu_dpm_get_temp_metrics(struct amdgpu_device *adev, 530 + enum smu_temp_metric_type type, void *table); 529 531 530 532 /** 531 533 * @get_pm_metrics: Get one snapshot of power management metrics from PMFW. The ··· 615 613 int amdgpu_dpm_reset_sdma(struct amdgpu_device *adev, uint32_t inst_mask); 616 614 bool amdgpu_dpm_reset_sdma_is_supported(struct amdgpu_device *adev); 617 615 int amdgpu_dpm_reset_vcn(struct amdgpu_device *adev, uint32_t inst_mask); 616 + bool amdgpu_dpm_reset_vcn_is_supported(struct amdgpu_device *adev); 617 + bool amdgpu_dpm_is_temp_metrics_supported(struct amdgpu_device *adev, 618 + enum smu_temp_metric_type type); 618 619 619 620 #endif
+58
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
··· 766 766 case IP_VERSION(13, 0, 14): 767 767 case IP_VERSION(13, 0, 12): 768 768 smu_v13_0_6_set_ppt_funcs(smu); 769 + smu_v13_0_6_set_temp_funcs(smu); 769 770 /* Enable pp_od_clk_voltage node */ 770 771 smu->od_enabled = true; 771 772 break; ··· 3832 3831 return ret; 3833 3832 } 3834 3833 3834 + static ssize_t smu_sys_get_temp_metrics(void *handle, enum smu_temp_metric_type type, void *table) 3835 + { 3836 + struct smu_context *smu = handle; 3837 + struct smu_table_context *smu_table = &smu->smu_table; 3838 + struct smu_table *tables = smu_table->tables; 3839 + enum smu_table_id table_id; 3840 + 3841 + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) 3842 + return -EOPNOTSUPP; 3843 + 3844 + if (!smu->smu_temp.temp_funcs || !smu->smu_temp.temp_funcs->get_temp_metrics) 3845 + return -EOPNOTSUPP; 3846 + 3847 + table_id = smu_metrics_get_temp_table_id(type); 3848 + 3849 + if (table_id == SMU_TABLE_COUNT) 3850 + return -EINVAL; 3851 + 3852 + /* If the request is to get size alone, return the cached table size */ 3853 + if (!table && tables[table_id].cache.size) 3854 + return tables[table_id].cache.size; 3855 + 3856 + if (smu_table_cache_is_valid(&tables[table_id])) { 3857 + memcpy(table, tables[table_id].cache.buffer, 3858 + tables[table_id].cache.size); 3859 + return tables[table_id].cache.size; 3860 + } 3861 + 3862 + return smu->smu_temp.temp_funcs->get_temp_metrics(smu, type, table); 3863 + } 3864 + 3865 + static bool smu_temp_metrics_is_supported(void *handle, enum smu_temp_metric_type type) 3866 + { 3867 + struct smu_context *smu = handle; 3868 + bool ret = false; 3869 + 3870 + if (!smu->pm_enabled) 3871 + return false; 3872 + 3873 + if (smu->smu_temp.temp_funcs && smu->smu_temp.temp_funcs->temp_metrics_is_supported) 3874 + ret = smu->smu_temp.temp_funcs->temp_metrics_is_supported(smu, type); 3875 + 3876 + return ret; 3877 + } 3878 + 3835 3879 static ssize_t smu_sys_get_xcp_metrics(void *handle, int xcp_id, void *table) 3836 3880 { 3837 3881 struct smu_context *smu = handle; ··· 3949 3903 .get_dpm_clock_table = smu_get_dpm_clock_table, 3950 3904 .get_smu_prv_buf_details = smu_get_prv_buffer_details, 3951 3905 .get_xcp_metrics = smu_sys_get_xcp_metrics, 3906 + .get_temp_metrics = smu_sys_get_temp_metrics, 3907 + .temp_metrics_is_supported = smu_temp_metrics_is_supported, 3952 3908 }; 3953 3909 3954 3910 int smu_wait_for_event(struct smu_context *smu, enum smu_event_type event, ··· 4120 4072 4121 4073 if (smu->ppt_funcs && smu->ppt_funcs->reset_sdma) 4122 4074 ret = smu->ppt_funcs->reset_sdma(smu, inst_mask); 4075 + 4076 + return ret; 4077 + } 4078 + 4079 + bool smu_reset_vcn_is_supported(struct smu_context *smu) 4080 + { 4081 + bool ret = false; 4082 + 4083 + if (smu->ppt_funcs && smu->ppt_funcs->reset_vcn_is_supported) 4084 + ret = smu->ppt_funcs->reset_vcn_is_supported(smu); 4123 4085 4124 4086 return ret; 4125 4087 }
+108
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
··· 249 249 tables[table_id].domain = d; \ 250 250 } while (0) 251 251 252 + struct smu_table_cache { 253 + void *buffer; 254 + size_t size; 255 + /* interval in ms*/ 256 + uint32_t interval; 257 + unsigned long last_cache_time; 258 + }; 259 + 252 260 struct smu_table { 253 261 uint64_t size; 254 262 uint32_t align; ··· 265 257 void *cpu_addr; 266 258 struct amdgpu_bo *bo; 267 259 uint32_t version; 260 + struct smu_table_cache cache; 268 261 }; 269 262 270 263 enum smu_perf_level_designation { ··· 331 322 SMU_TABLE_ECCINFO, 332 323 SMU_TABLE_COMBO_PPTABLE, 333 324 SMU_TABLE_WIFIBAND, 325 + SMU_TABLE_GPUBOARD_TEMP_METRICS, 326 + SMU_TABLE_BASEBOARD_TEMP_METRICS, 334 327 SMU_TABLE_COUNT, 335 328 }; 336 329 ··· 405 394 struct smu_power_state *dpm_current_power_state; 406 395 struct mclock_latency_table *mclk_latency_table; 407 396 struct smu_dpm_policy_ctxt *dpm_policies; 397 + }; 398 + 399 + struct smu_temp_context { 400 + const struct smu_temp_funcs *temp_funcs; 408 401 }; 409 402 410 403 struct smu_power_gate { ··· 544 529 struct smu_table_context smu_table; 545 530 struct smu_dpm_context smu_dpm; 546 531 struct smu_power_context smu_power; 532 + struct smu_temp_context smu_temp; 547 533 struct smu_feature smu_feature; 548 534 struct amd_pp_display_configuration *display_config; 549 535 struct smu_baco_context smu_baco; ··· 638 622 }; 639 623 640 624 struct i2c_adapter; 625 + 626 + /** 627 + * struct smu_temp_funcs - Callbacks used to get temperature data. 628 + */ 629 + struct smu_temp_funcs { 630 + /** 631 + * @get_temp_metrics: Calibrate voltage/frequency curve to fit the system's 632 + * power delivery and voltage margins. Required for adaptive 633 + * @type Temperature metrics type(baseboard/gpuboard) 634 + * Return: Size of &table 635 + */ 636 + ssize_t (*get_temp_metrics)(struct smu_context *smu, 637 + enum smu_temp_metric_type type, void *table); 638 + 639 + /** 640 + * @temp_metrics_is_support: Get if specific temperature metrics is supported 641 + * @type Temperature metrics type(baseboard/gpuboard) 642 + * Return: true if supported else false 643 + */ 644 + bool (*temp_metrics_is_supported)(struct smu_context *smu, enum smu_temp_metric_type type); 645 + 646 + }; 641 647 642 648 /** 643 649 * struct pptable_funcs - Callbacks used to interact with the SMU. ··· 1435 1397 * @reset_vcn: message SMU to soft reset vcn instance. 1436 1398 */ 1437 1399 int (*dpm_reset_vcn)(struct smu_context *smu, uint32_t inst_mask); 1400 + /** 1401 + * @reset_vcn_is_supported: Check if support resets vcn. 1402 + */ 1403 + bool (*reset_vcn_is_supported)(struct smu_context *smu); 1438 1404 1439 1405 /** 1440 1406 * @get_ecc_table: message SMU to get ECC INFO table. ··· 1664 1622 struct smu_dpm_policy *smu_get_pm_policy(struct smu_context *smu, 1665 1623 enum pp_pm_policy p_type); 1666 1624 1625 + static inline enum smu_table_id 1626 + smu_metrics_get_temp_table_id(enum smu_temp_metric_type type) 1627 + { 1628 + switch (type) { 1629 + case SMU_TEMP_METRIC_BASEBOARD: 1630 + return SMU_TABLE_BASEBOARD_TEMP_METRICS; 1631 + case SMU_TEMP_METRIC_GPUBOARD: 1632 + return SMU_TABLE_GPUBOARD_TEMP_METRICS; 1633 + default: 1634 + return SMU_TABLE_COUNT; 1635 + } 1636 + 1637 + return SMU_TABLE_COUNT; 1638 + } 1639 + 1640 + static inline void smu_table_cache_update_time(struct smu_table *table, 1641 + unsigned long time) 1642 + { 1643 + table->cache.last_cache_time = time; 1644 + } 1645 + 1646 + static inline bool smu_table_cache_is_valid(struct smu_table *table) 1647 + { 1648 + if (!table->cache.buffer || !table->cache.last_cache_time || 1649 + !table->cache.interval || !table->cache.size || 1650 + time_after(jiffies, 1651 + table->cache.last_cache_time + 1652 + msecs_to_jiffies(table->cache.interval))) 1653 + return false; 1654 + 1655 + return true; 1656 + } 1657 + 1658 + static inline int smu_table_cache_init(struct smu_context *smu, 1659 + enum smu_table_id table_id, size_t size, 1660 + uint32_t cache_interval) 1661 + { 1662 + struct smu_table_context *smu_table = &smu->smu_table; 1663 + struct smu_table *tables = smu_table->tables; 1664 + 1665 + tables[table_id].cache.buffer = kzalloc(size, GFP_KERNEL); 1666 + if (!tables[table_id].cache.buffer) 1667 + return -ENOMEM; 1668 + 1669 + tables[table_id].cache.last_cache_time = 0; 1670 + tables[table_id].cache.interval = cache_interval; 1671 + tables[table_id].cache.size = size; 1672 + 1673 + return 0; 1674 + } 1675 + 1676 + static inline void smu_table_cache_fini(struct smu_context *smu, 1677 + enum smu_table_id table_id) 1678 + { 1679 + struct smu_table_context *smu_table = &smu->smu_table; 1680 + struct smu_table *tables = smu_table->tables; 1681 + 1682 + if (tables[table_id].cache.buffer) { 1683 + kfree(tables[table_id].cache.buffer); 1684 + tables[table_id].cache.buffer = NULL; 1685 + tables[table_id].cache.last_cache_time = 0; 1686 + tables[table_id].cache.interval = 0; 1687 + } 1688 + } 1689 + 1667 1690 #if !defined(SWSMU_CODE_LAYER_L2) && !defined(SWSMU_CODE_LAYER_L3) && !defined(SWSMU_CODE_LAYER_L4) 1668 1691 int smu_get_power_limit(void *handle, 1669 1692 uint32_t *limit, ··· 1780 1673 int smu_reset_sdma(struct smu_context *smu, uint32_t inst_mask); 1781 1674 bool smu_reset_sdma_is_supported(struct smu_context *smu); 1782 1675 int smu_reset_vcn(struct smu_context *smu, uint32_t inst_mask); 1676 + bool smu_reset_vcn_is_supported(struct smu_context *smu); 1783 1677 int smu_set_pm_policy(struct smu_context *smu, enum pp_pm_policy p_type, 1784 1678 int level); 1785 1679 ssize_t smu_get_pm_policy_info(struct smu_context *smu,
+73 -1
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_12_pmfw.h
··· 135 135 GFX_DVM_MARGIN_COUNT 136 136 } GFX_DVM_MARGIN_e; 137 137 138 - #define SMU_METRICS_TABLE_VERSION 0x13 138 + typedef enum{ 139 + SYSTEM_TEMP_UBB_FPGA, 140 + SYSTEM_TEMP_UBB_FRONT, 141 + SYSTEM_TEMP_UBB_BACK, 142 + SYSTEM_TEMP_UBB_OAM7, 143 + SYSTEM_TEMP_UBB_IBC, 144 + SYSTEM_TEMP_UBB_UFPGA, 145 + SYSTEM_TEMP_UBB_OAM1, 146 + SYSTEM_TEMP_OAM_0_1_HSC, 147 + SYSTEM_TEMP_OAM_2_3_HSC, 148 + SYSTEM_TEMP_OAM_4_5_HSC, 149 + SYSTEM_TEMP_OAM_6_7_HSC, 150 + SYSTEM_TEMP_UBB_FPGA_0V72_VR, 151 + SYSTEM_TEMP_UBB_FPGA_3V3_VR, 152 + SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR, 153 + SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR, 154 + SYSTEM_TEMP_RETIMER_0_1_0V9_VR, 155 + SYSTEM_TEMP_RETIMER_4_5_0V9_VR, 156 + SYSTEM_TEMP_RETIMER_2_3_0V9_VR, 157 + SYSTEM_TEMP_RETIMER_6_7_0V9_VR, 158 + SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR, 159 + SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR, 160 + SYSTEM_TEMP_IBC_HSC, 161 + SYSTEM_TEMP_IBC, 162 + SYSTEM_TEMP_MAX_ENTRIES = 32 163 + } SYSTEM_TEMP_e; 164 + 165 + typedef enum{ 166 + NODE_TEMP_RETIMER, 167 + NODE_TEMP_IBC_TEMP, 168 + NODE_TEMP_IBC_2_TEMP, 169 + NODE_TEMP_VDD18_VR_TEMP, 170 + NODE_TEMP_04_HBM_B_VR_TEMP, 171 + NODE_TEMP_04_HBM_D_VR_TEMP, 172 + NODE_TEMP_MAX_TEMP_ENTRIES = 12 173 + } NODE_TEMP_e; 174 + 175 + typedef enum { 176 + SVI_VDDCR_VDD0_TEMP, 177 + SVI_VDDCR_VDD1_TEMP, 178 + SVI_VDDCR_VDD2_TEMP, 179 + SVI_VDDCR_VDD3_TEMP, 180 + SVI_VDDCR_SOC_A_TEMP, 181 + SVI_VDDCR_SOC_C_TEMP, 182 + SVI_VDDCR_SOCIO_A_TEMP, 183 + SVI_VDDCR_SOCIO_C_TEMP, 184 + SVI_VDD_085_HBM_TEMP, 185 + SVI_VDDCR_11_HBM_B_TEMP, 186 + SVI_VDDCR_11_HBM_D_TEMP, 187 + SVI_VDD_USR_TEMP, 188 + SVI_VDDIO_11_E32_TEMP, 189 + SVI_MAX_TEMP_ENTRIES, // 13 190 + } SVI_TEMP_e; 191 + 192 + #define SMU_METRICS_TABLE_VERSION 0x14 193 + 194 + #define SMU_SYSTEM_METRICS_TABLE_VERSION 0x0 139 195 140 196 typedef struct __attribute__((packed, aligned(4))) { 141 197 uint64_t AccumulationCounter; ··· 287 231 uint64_t GfxclkBelowHostLimitThmAcc[8]; 288 232 uint64_t GfxclkBelowHostLimitTotalAcc[8]; 289 233 uint64_t GfxclkLowUtilizationAcc[8]; 234 + 235 + uint32_t AidTemperature[4]; 236 + uint32_t XcdTemperature[8]; 237 + uint32_t HbmTemperature[8]; 290 238 } MetricsTable_t; 291 239 292 240 #define SMU_VF_METRICS_TABLE_MASK (1 << 31) 293 241 #define SMU_VF_METRICS_TABLE_VERSION (0x6 | SMU_VF_METRICS_TABLE_MASK) 242 + 243 + #pragma pack(push, 4) 244 + typedef struct { 245 + uint64_t AccumulationCounter; // Last update timestamp 246 + uint16_t LabelVersion; // Defaults to 0. 247 + uint16_t NodeIdentifier; // Unique identifier to each node on system. 248 + int16_t SystemTemperatures[SYSTEM_TEMP_MAX_ENTRIES]; // Signed integer temperature value in Celsius, unused fields are set to 0xFFFF 249 + int16_t NodeTemperatures[NODE_TEMP_MAX_TEMP_ENTRIES]; // Signed integer temperature value in Celsius, unused fields are set to 0xFFFF 250 + int16_t VrTemperatures[SVI_MAX_TEMP_ENTRIES]; // Signed integer temperature value in Celsius 251 + int16_t spare[3]; 252 + } SystemMetricsTable_t; 253 + #pragma pack(pop) 294 254 295 255 typedef struct __attribute__((packed, aligned(4))) { 296 256 uint32_t AccumulationCounter;
+5 -1
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_12_ppsmc.h
··· 116 116 #define PPSMC_MSG_DumpErrorRecord 0x57 117 117 #define PPSMC_MSG_EraseRasTable 0x58 118 118 #define PPSMC_MSG_GetStaticMetricsTable 0x59 119 - #define PPSMC_Message_Count 0x5A 119 + #define PPSMC_MSG_ResetVfArbitersByIndex 0x5A 120 + #define PPSMC_MSG_GetBadPageSeverity 0x5B 121 + #define PPSMC_MSG_GetSystemMetricsTable 0x5C 122 + #define PPSMC_MSG_GetSystemMetricsVersion 0x5D 123 + #define PPSMC_Message_Count 0x5E 120 124 121 125 //PPSMC Reset Types for driver msg argument 122 126 #define PPSMC_RESET_TYPE_DRIVER_MODE_1_RESET 0x1
+2 -2
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_ppsmc.h
··· 94 94 #define PPSMC_MSG_RmaDueToBadPageThreshold 0x43 95 95 #define PPSMC_MSG_SetThrottlingPolicy 0x44 96 96 #define PPSMC_MSG_ResetSDMA 0x4D 97 - #define PPSMC_MSG_ResetVCN 0x4E 98 97 #define PPSMC_MSG_GetStaticMetricsTable 0x59 99 - #define PPSMC_Message_Count 0x5A 98 + #define PPSMC_MSG_ResetVCN 0x5B 99 + #define PPSMC_Message_Count 0x5C 100 100 101 101 //PPSMC Reset Types for driver msg argument 102 102 #define PPSMC_RESET_TYPE_DRIVER_MODE_1_RESET 0x1
+3 -1
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
··· 278 278 __SMU_DUMMY_MAP(MALLPowerState), \ 279 279 __SMU_DUMMY_MAP(ResetSDMA), \ 280 280 __SMU_DUMMY_MAP(ResetVCN), \ 281 - __SMU_DUMMY_MAP(GetStaticMetricsTable), 281 + __SMU_DUMMY_MAP(GetStaticMetricsTable), \ 282 + __SMU_DUMMY_MAP(GetSystemMetricsTable), 282 283 283 284 #undef __SMU_DUMMY_MAP 284 285 #define __SMU_DUMMY_MAP(type) SMU_MSG_##type ··· 470 469 /* Message category flags */ 471 470 #define SMU_MSG_VF_FLAG (1U << 0) 472 471 #define SMU_MSG_RAS_PRI (1U << 1) 472 + #define SMU_MSG_NO_PRECHECK (1U << 2) 473 473 474 474 /* Firmware capability flags */ 475 475 #define SMU_FW_CAP_RAS_PRI (1U << 0)
+1 -1
drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
··· 1897 1897 1898 1898 ret = smu_cmn_get_metrics_table(smu, 1899 1899 &metrics, 1900 - true); 1900 + false); 1901 1901 if (ret) 1902 1902 return ret; 1903 1903
+1 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
··· 1781 1781 1782 1782 ret = smu_cmn_get_metrics_table(smu, 1783 1783 &metrics, 1784 - true); 1784 + false); 1785 1785 if (ret) 1786 1786 return ret; 1787 1787
+301 -4
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
··· 83 83 SMU_13_0_12_FEA_MAP(SMU_FEATURE_PIT_BIT, FEATURE_PIT), 84 84 }; 85 85 86 - // clang-format off 87 86 const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[SMU_MSG_MAX_COUNT] = { 88 87 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), 89 88 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), ··· 105 106 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1), 106 107 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), 107 108 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1), 108 - MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, SMU_MSG_RAS_PRI), 109 + MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, SMU_MSG_RAS_PRI | SMU_MSG_NO_PRECHECK), 109 110 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0), 110 111 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0), 111 112 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0), ··· 137 138 MSG_MAP(SetThrottlingPolicy, PPSMC_MSG_SetThrottlingPolicy, 0), 138 139 MSG_MAP(ResetSDMA, PPSMC_MSG_ResetSDMA, 0), 139 140 MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 1), 141 + MSG_MAP(GetSystemMetricsTable, PPSMC_MSG_GetSystemMetricsTable, 0), 140 142 }; 143 + 144 + int smu_v13_0_12_tables_init(struct smu_context *smu) 145 + { 146 + struct amdgpu_baseboard_temp_metrics_v1_0 *baseboard_temp_metrics; 147 + struct amdgpu_gpuboard_temp_metrics_v1_0 *gpuboard_temp_metrics; 148 + struct smu_table_context *smu_table = &smu->smu_table; 149 + struct smu_table *tables = smu_table->tables; 150 + struct smu_table_cache *cache; 151 + int ret; 152 + 153 + ret = smu_table_cache_init(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS, 154 + sizeof(*baseboard_temp_metrics), 50); 155 + if (ret) 156 + return ret; 157 + /* Initialize base board temperature metrics */ 158 + cache = &(tables[SMU_TABLE_BASEBOARD_TEMP_METRICS].cache); 159 + baseboard_temp_metrics = 160 + (struct amdgpu_baseboard_temp_metrics_v1_0 *) cache->buffer; 161 + smu_cmn_init_baseboard_temp_metrics(baseboard_temp_metrics, 1, 0); 162 + /* Initialize GPU board temperature metrics */ 163 + ret = smu_table_cache_init(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS, 164 + sizeof(*gpuboard_temp_metrics), 50); 165 + if (ret) { 166 + smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS); 167 + return ret; 168 + } 169 + cache = &(tables[SMU_TABLE_GPUBOARD_TEMP_METRICS].cache); 170 + gpuboard_temp_metrics = (struct amdgpu_gpuboard_temp_metrics_v1_0 *)cache->buffer; 171 + smu_cmn_init_gpuboard_temp_metrics(gpuboard_temp_metrics, 1, 0); 172 + 173 + return 0; 174 + } 175 + 176 + void smu_v13_0_12_tables_fini(struct smu_context *smu) 177 + { 178 + smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS); 179 + smu_table_cache_fini(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS); 180 + } 141 181 142 182 static int smu_v13_0_12_get_enabled_mask(struct smu_context *smu, 143 183 uint64_t *feature_mask) ··· 222 184 223 185 int smu_v13_0_12_get_max_metrics_size(void) 224 186 { 225 - return max(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t)); 187 + return max3(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t), 188 + sizeof(SystemMetricsTable_t)); 226 189 } 227 190 228 191 static void smu_v13_0_12_init_xgmi_data(struct smu_context *smu, ··· 259 220 struct PPTable_t *pptable = 260 221 (struct PPTable_t *)smu_table->driver_pptable; 261 222 uint32_t table_version; 262 - int ret, i; 223 + int ret, i, n; 263 224 264 225 if (!pptable->Init) { 265 226 ret = smu_v13_0_6_get_static_metrics_table(smu); ··· 298 259 /* use AID0 serial number by default */ 299 260 pptable->PublicSerialNumber_AID = 300 261 static_metrics->PublicSerialNumber_AID[0]; 262 + 263 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC, 264 + 0, pptable->PublicSerialNumber_AID); 265 + n = ARRAY_SIZE(static_metrics->PublicSerialNumber_AID); 266 + for (i = 0; i < n; i++) { 267 + amdgpu_device_set_uid( 268 + smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i, 269 + static_metrics->PublicSerialNumber_AID[i]); 270 + } 271 + n = ARRAY_SIZE(static_metrics->PublicSerialNumber_XCD); 272 + for (i = 0; i < n; i++) { 273 + amdgpu_device_set_uid( 274 + smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i, 275 + static_metrics->PublicSerialNumber_XCD[i]); 276 + } 277 + 301 278 ret = smu_v13_0_12_fru_get_product_info(smu, static_metrics); 302 279 if (ret) 303 280 return ret; ··· 412 357 } 413 358 414 359 return 0; 360 + } 361 + 362 + static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu, 363 + void *metrics_table) 364 + { 365 + struct smu_table_context *smu_table = &smu->smu_table; 366 + uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; 367 + struct smu_table *table = &smu_table->driver_table; 368 + int ret; 369 + 370 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSystemMetricsTable, NULL); 371 + if (ret) { 372 + dev_info(smu->adev->dev, 373 + "Failed to export system metrics table!\n"); 374 + return ret; 375 + } 376 + 377 + amdgpu_asic_invalidate_hdp(smu->adev, NULL); 378 + memcpy(smu_table->metrics_table, table->cpu_addr, table_size); 379 + 380 + if (metrics_table) 381 + memcpy(metrics_table, smu_table->metrics_table, sizeof(SystemMetricsTable_t)); 382 + 383 + return 0; 384 + } 385 + 386 + static enum amdgpu_node_temp smu_v13_0_12_get_node_sensor_type(NODE_TEMP_e type) 387 + { 388 + switch (type) { 389 + case NODE_TEMP_RETIMER: 390 + return AMDGPU_RETIMER_X_TEMP; 391 + case NODE_TEMP_IBC_TEMP: 392 + return AMDGPU_OAM_X_IBC_TEMP; 393 + case NODE_TEMP_IBC_2_TEMP: 394 + return AMDGPU_OAM_X_IBC_2_TEMP; 395 + case NODE_TEMP_VDD18_VR_TEMP: 396 + return AMDGPU_OAM_X_VDD18_VR_TEMP; 397 + case NODE_TEMP_04_HBM_B_VR_TEMP: 398 + return AMDGPU_OAM_X_04_HBM_B_VR_TEMP; 399 + case NODE_TEMP_04_HBM_D_VR_TEMP: 400 + return AMDGPU_OAM_X_04_HBM_D_VR_TEMP; 401 + default: 402 + return -EINVAL; 403 + } 404 + } 405 + 406 + static enum amdgpu_vr_temp smu_v13_0_12_get_vr_sensor_type(SVI_TEMP_e type) 407 + { 408 + switch (type) { 409 + case SVI_VDDCR_VDD0_TEMP: 410 + return AMDGPU_VDDCR_VDD0_TEMP; 411 + case SVI_VDDCR_VDD1_TEMP: 412 + return AMDGPU_VDDCR_VDD1_TEMP; 413 + case SVI_VDDCR_VDD2_TEMP: 414 + return AMDGPU_VDDCR_VDD2_TEMP; 415 + case SVI_VDDCR_VDD3_TEMP: 416 + return AMDGPU_VDDCR_VDD3_TEMP; 417 + case SVI_VDDCR_SOC_A_TEMP: 418 + return AMDGPU_VDDCR_SOC_A_TEMP; 419 + case SVI_VDDCR_SOC_C_TEMP: 420 + return AMDGPU_VDDCR_SOC_C_TEMP; 421 + case SVI_VDDCR_SOCIO_A_TEMP: 422 + return AMDGPU_VDDCR_SOCIO_A_TEMP; 423 + case SVI_VDDCR_SOCIO_C_TEMP: 424 + return AMDGPU_VDDCR_SOCIO_C_TEMP; 425 + case SVI_VDD_085_HBM_TEMP: 426 + return AMDGPU_VDD_085_HBM_TEMP; 427 + case SVI_VDDCR_11_HBM_B_TEMP: 428 + return AMDGPU_VDDCR_11_HBM_B_TEMP; 429 + case SVI_VDDCR_11_HBM_D_TEMP: 430 + return AMDGPU_VDDCR_11_HBM_D_TEMP; 431 + case SVI_VDD_USR_TEMP: 432 + return AMDGPU_VDD_USR_TEMP; 433 + case SVI_VDDIO_11_E32_TEMP: 434 + return AMDGPU_VDDIO_11_E32_TEMP; 435 + default: 436 + return -EINVAL; 437 + } 438 + } 439 + 440 + static enum amdgpu_system_temp smu_v13_0_12_get_system_sensor_type(SYSTEM_TEMP_e type) 441 + { 442 + switch (type) { 443 + case SYSTEM_TEMP_UBB_FPGA: 444 + return AMDGPU_UBB_FPGA_TEMP; 445 + case SYSTEM_TEMP_UBB_FRONT: 446 + return AMDGPU_UBB_FRONT_TEMP; 447 + case SYSTEM_TEMP_UBB_BACK: 448 + return AMDGPU_UBB_BACK_TEMP; 449 + case SYSTEM_TEMP_UBB_OAM7: 450 + return AMDGPU_UBB_OAM7_TEMP; 451 + case SYSTEM_TEMP_UBB_IBC: 452 + return AMDGPU_UBB_IBC_TEMP; 453 + case SYSTEM_TEMP_UBB_UFPGA: 454 + return AMDGPU_UBB_UFPGA_TEMP; 455 + case SYSTEM_TEMP_UBB_OAM1: 456 + return AMDGPU_UBB_OAM1_TEMP; 457 + case SYSTEM_TEMP_OAM_0_1_HSC: 458 + return AMDGPU_OAM_0_1_HSC_TEMP; 459 + case SYSTEM_TEMP_OAM_2_3_HSC: 460 + return AMDGPU_OAM_2_3_HSC_TEMP; 461 + case SYSTEM_TEMP_OAM_4_5_HSC: 462 + return AMDGPU_OAM_4_5_HSC_TEMP; 463 + case SYSTEM_TEMP_OAM_6_7_HSC: 464 + return AMDGPU_OAM_6_7_HSC_TEMP; 465 + case SYSTEM_TEMP_UBB_FPGA_0V72_VR: 466 + return AMDGPU_UBB_FPGA_0V72_VR_TEMP; 467 + case SYSTEM_TEMP_UBB_FPGA_3V3_VR: 468 + return AMDGPU_UBB_FPGA_3V3_VR_TEMP; 469 + case SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR: 470 + return AMDGPU_RETIMER_0_1_2_3_1V2_VR_TEMP; 471 + case SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR: 472 + return AMDGPU_RETIMER_4_5_6_7_1V2_VR_TEMP; 473 + case SYSTEM_TEMP_RETIMER_0_1_0V9_VR: 474 + return AMDGPU_RETIMER_0_1_0V9_VR_TEMP; 475 + case SYSTEM_TEMP_RETIMER_4_5_0V9_VR: 476 + return AMDGPU_RETIMER_4_5_0V9_VR_TEMP; 477 + case SYSTEM_TEMP_RETIMER_2_3_0V9_VR: 478 + return AMDGPU_RETIMER_2_3_0V9_VR_TEMP; 479 + case SYSTEM_TEMP_RETIMER_6_7_0V9_VR: 480 + return AMDGPU_RETIMER_6_7_0V9_VR_TEMP; 481 + case SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR: 482 + return AMDGPU_OAM_0_1_2_3_3V3_VR_TEMP; 483 + case SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR: 484 + return AMDGPU_OAM_4_5_6_7_3V3_VR_TEMP; 485 + case SYSTEM_TEMP_IBC_HSC: 486 + return AMDGPU_IBC_HSC_TEMP; 487 + case SYSTEM_TEMP_IBC: 488 + return AMDGPU_IBC_TEMP; 489 + default: 490 + return -EINVAL; 491 + } 492 + } 493 + 494 + static bool smu_v13_0_12_is_temp_metrics_supported(struct smu_context *smu, 495 + enum smu_temp_metric_type type) 496 + { 497 + switch (type) { 498 + case SMU_TEMP_METRIC_BASEBOARD: 499 + if (smu->adev->gmc.xgmi.physical_node_id == 0 && 500 + smu->adev->gmc.xgmi.num_physical_nodes > 1 && 501 + smu_v13_0_6_cap_supported(smu, SMU_CAP(TEMP_METRICS))) 502 + return true; 503 + break; 504 + case SMU_TEMP_METRIC_GPUBOARD: 505 + return smu_v13_0_6_cap_supported(smu, SMU_CAP(TEMP_METRICS)); 506 + default: 507 + break; 508 + } 509 + 510 + return false; 511 + } 512 + 513 + static ssize_t smu_v13_0_12_get_temp_metrics(struct smu_context *smu, 514 + enum smu_temp_metric_type type, void *table) 515 + { 516 + struct amdgpu_baseboard_temp_metrics_v1_0 *baseboard_temp_metrics; 517 + struct amdgpu_gpuboard_temp_metrics_v1_0 *gpuboard_temp_metrics; 518 + struct smu_table_context *smu_table = &smu->smu_table; 519 + SystemMetricsTable_t *metrics = 520 + (SystemMetricsTable_t *)smu_table->metrics_table; 521 + 522 + struct smu_table *data_table; 523 + int ret, sensor_type; 524 + u32 idx, sensors; 525 + ssize_t size; 526 + 527 + if (type == SMU_TEMP_METRIC_BASEBOARD) { 528 + /* Initialize base board temperature metrics */ 529 + data_table = 530 + &smu->smu_table.tables[SMU_TABLE_BASEBOARD_TEMP_METRICS]; 531 + baseboard_temp_metrics = 532 + (struct amdgpu_baseboard_temp_metrics_v1_0 *) 533 + data_table->cache.buffer; 534 + size = sizeof(*baseboard_temp_metrics); 535 + } else { 536 + data_table = 537 + &smu->smu_table.tables[SMU_TABLE_GPUBOARD_TEMP_METRICS]; 538 + gpuboard_temp_metrics = 539 + (struct amdgpu_gpuboard_temp_metrics_v1_0 *) 540 + data_table->cache.buffer; 541 + size = sizeof(*baseboard_temp_metrics); 542 + } 543 + 544 + ret = smu_v13_0_12_get_system_metrics_table(smu, NULL); 545 + if (ret) 546 + return ret; 547 + 548 + smu_table_cache_update_time(data_table, jiffies); 549 + 550 + if (type == SMU_TEMP_METRIC_GPUBOARD) { 551 + gpuboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter; 552 + gpuboard_temp_metrics->label_version = metrics->LabelVersion; 553 + gpuboard_temp_metrics->node_id = metrics->NodeIdentifier; 554 + 555 + idx = 0; 556 + for (sensors = 0; sensors < NODE_TEMP_MAX_TEMP_ENTRIES; sensors++) { 557 + if (metrics->NodeTemperatures[sensors] != -1) { 558 + sensor_type = smu_v13_0_12_get_node_sensor_type(sensors); 559 + gpuboard_temp_metrics->node_temp[idx] = 560 + ((int)metrics->NodeTemperatures[sensors]) & 0xFFFFFF; 561 + gpuboard_temp_metrics->node_temp[idx] |= (sensor_type << 24); 562 + idx++; 563 + } 564 + } 565 + 566 + idx = 0; 567 + 568 + for (sensors = 0; sensors < SVI_MAX_TEMP_ENTRIES; sensors++) { 569 + if (metrics->VrTemperatures[sensors] != -1) { 570 + sensor_type = smu_v13_0_12_get_vr_sensor_type(sensors); 571 + gpuboard_temp_metrics->vr_temp[idx] = 572 + ((int)metrics->VrTemperatures[sensors]) & 0xFFFFFF; 573 + gpuboard_temp_metrics->vr_temp[idx] |= (sensor_type << 24); 574 + idx++; 575 + } 576 + } 577 + } else if (type == SMU_TEMP_METRIC_BASEBOARD) { 578 + baseboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter; 579 + baseboard_temp_metrics->label_version = metrics->LabelVersion; 580 + baseboard_temp_metrics->node_id = metrics->NodeIdentifier; 581 + 582 + idx = 0; 583 + for (sensors = 0; sensors < SYSTEM_TEMP_MAX_ENTRIES; sensors++) { 584 + if (metrics->SystemTemperatures[sensors] != -1) { 585 + sensor_type = smu_v13_0_12_get_system_sensor_type(sensors); 586 + baseboard_temp_metrics->system_temp[idx] = 587 + ((int)metrics->SystemTemperatures[sensors]) & 0xFFFFFF; 588 + baseboard_temp_metrics->system_temp[idx] |= (sensor_type << 24); 589 + idx++; 590 + } 591 + } 592 + } 593 + 594 + memcpy(table, data_table->cache.buffer, size); 595 + 596 + return size; 415 597 } 416 598 417 599 ssize_t smu_v13_0_12_get_xcp_metrics(struct smu_context *smu, struct amdgpu_xcp *xcp, void *table, void *smu_metrics) ··· 864 572 865 573 return sizeof(*gpu_metrics); 866 574 } 575 + 576 + const struct smu_temp_funcs smu_v13_0_12_temp_funcs = { 577 + .temp_metrics_is_supported = smu_v13_0_12_is_temp_metrics_supported, 578 + .get_temp_metrics = smu_v13_0_12_get_temp_metrics, 579 + };
+107 -46
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
··· 145 145 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1), 146 146 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), 147 147 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1), 148 - MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, SMU_MSG_RAS_PRI), 148 + MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, SMU_MSG_RAS_PRI | SMU_MSG_NO_PRECHECK), 149 149 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0), 150 150 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0), 151 151 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0), ··· 177 177 MSG_MAP(SetThrottlingPolicy, PPSMC_MSG_SetThrottlingPolicy, 0), 178 178 MSG_MAP(ResetSDMA, PPSMC_MSG_ResetSDMA, 0), 179 179 MSG_MAP(ResetVCN, PPSMC_MSG_ResetVCN, 0), 180 - MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 0), 180 + MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 1), 181 181 }; 182 182 183 183 // clang-format on ··· 312 312 smu_v13_0_6_cap_set(smu, SMU_CAP(PER_INST_METRICS)); 313 313 if (fw_ver >= 0x5551200) 314 314 smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET)); 315 + if (fw_ver >= 0x5551800) 316 + smu_v13_0_6_cap_set(smu, SMU_CAP(VCN_RESET)); 315 317 if (fw_ver >= 0x5551600) { 316 318 smu_v13_0_6_cap_set(smu, SMU_CAP(STATIC_METRICS)); 317 319 smu_v13_0_6_cap_set(smu, SMU_CAP(BOARD_VOLTAGE)); ··· 351 349 if (fw_ver >= 0x04560100) { 352 350 smu_v13_0_6_cap_set(smu, SMU_CAP(BOARD_VOLTAGE)); 353 351 smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); 352 + } 353 + 354 + if (fw_ver >= 0x04560700) { 355 + if (!amdgpu_sriov_vf(smu->adev)) 356 + smu_v13_0_6_cap_set(smu, SMU_CAP(TEMP_METRICS)); 357 + } else { 358 + smu_v13_0_12_tables_fini(smu); 354 359 } 355 360 } 356 361 ··· 411 402 if ((pgm == 7 && fw_ver >= 0x7550E00) || 412 403 (pgm == 0 && fw_ver >= 0x00557E00)) 413 404 smu_v13_0_6_cap_set(smu, SMU_CAP(HST_LIMIT_METRICS)); 414 - if ((pgm == 0 && fw_ver >= 0x00557F01) || 415 - (pgm == 7 && fw_ver >= 0x7551000)) { 416 - smu_v13_0_6_cap_set(smu, SMU_CAP(STATIC_METRICS)); 417 - smu_v13_0_6_cap_set(smu, SMU_CAP(BOARD_VOLTAGE)); 405 + 406 + if (amdgpu_sriov_vf(adev)) { 407 + if ((pgm == 0 && fw_ver >= 0x00558000) || 408 + (pgm == 7 && fw_ver >= 0x7551000)) { 409 + smu_v13_0_6_cap_set(smu, 410 + SMU_CAP(STATIC_METRICS)); 411 + smu_v13_0_6_cap_set(smu, 412 + SMU_CAP(BOARD_VOLTAGE)); 413 + smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); 414 + } 415 + } else { 416 + if ((pgm == 0 && fw_ver >= 0x00557F01) || 417 + (pgm == 7 && fw_ver >= 0x7551000)) { 418 + smu_v13_0_6_cap_set(smu, 419 + SMU_CAP(STATIC_METRICS)); 420 + smu_v13_0_6_cap_set(smu, 421 + SMU_CAP(BOARD_VOLTAGE)); 422 + } 423 + if ((pgm == 0 && fw_ver >= 0x00558000) || 424 + (pgm == 7 && fw_ver >= 0x7551000)) 425 + smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); 418 426 } 419 - if ((pgm == 0 && fw_ver >= 0x00558000) || 420 - (pgm == 7 && fw_ver >= 0x7551000)) 421 - smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); 422 427 } 423 428 if (((pgm == 7) && (fw_ver >= 0x7550700)) || 424 429 ((pgm == 0) && (fw_ver >= 0x00557900)) || 425 430 ((pgm == 4) && (fw_ver >= 0x4557000))) 426 431 smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET)); 432 + 433 + if (((pgm == 0) && (fw_ver >= 0x00558200)) || 434 + ((pgm == 4) && (fw_ver >= 0x04557100))) 435 + smu_v13_0_6_cap_set(smu, SMU_CAP(VCN_RESET)); 427 436 } 428 437 429 438 static void smu_v13_0_x_init_caps(struct smu_context *smu) ··· 538 511 { 539 512 struct smu_table_context *smu_table = &smu->smu_table; 540 513 struct smu_table *tables = smu_table->tables; 514 + void *gpu_metrics_table __free(kfree) = NULL; 515 + void *driver_pptable __free(kfree) = NULL; 516 + void *metrics_table __free(kfree) = NULL; 541 517 struct amdgpu_device *adev = smu->adev; 542 518 int gpu_metrcs_size = METRICS_TABLE_SIZE; 519 + int ret; 543 520 544 521 if (!(adev->flags & AMD_IS_APU)) 545 522 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE, ··· 559 528 PAGE_SIZE, 560 529 AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT); 561 530 562 - smu_table->metrics_table = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL); 563 - if (!smu_table->metrics_table) 531 + metrics_table = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL); 532 + if (!metrics_table) 564 533 return -ENOMEM; 565 534 smu_table->metrics_time = 0; 566 535 567 536 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_8); 568 - smu_table->gpu_metrics_table = 537 + gpu_metrics_table = 569 538 kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 570 - if (!smu_table->gpu_metrics_table) { 571 - kfree(smu_table->metrics_table); 539 + if (!gpu_metrics_table) 572 540 return -ENOMEM; 541 + 542 + driver_pptable = kzalloc(sizeof(struct PPTable_t), GFP_KERNEL); 543 + if (!driver_pptable) 544 + return -ENOMEM; 545 + 546 + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 547 + IP_VERSION(13, 0, 12)) { 548 + ret = smu_v13_0_12_tables_init(smu); 549 + if (ret) 550 + return ret; 573 551 } 574 552 575 - smu_table->driver_pptable = 576 - kzalloc(sizeof(struct PPTable_t), GFP_KERNEL); 577 - if (!smu_table->driver_pptable) { 578 - kfree(smu_table->metrics_table); 579 - kfree(smu_table->gpu_metrics_table); 580 - return -ENOMEM; 581 - } 553 + smu_table->gpu_metrics_table = no_free_ptr(gpu_metrics_table); 554 + smu_table->metrics_table = no_free_ptr(metrics_table); 555 + smu_table->driver_pptable = no_free_ptr(driver_pptable); 582 556 583 557 return 0; 584 558 } ··· 713 677 return ret; 714 678 } 715 679 680 + static int smu_v13_0_6_fini_smc_tables(struct smu_context *smu) 681 + { 682 + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12)) 683 + smu_v13_0_12_tables_fini(smu); 684 + return smu_v13_0_fini_smc_tables(smu); 685 + } 686 + 716 687 static int smu_v13_0_6_get_allowed_feature_mask(struct smu_context *smu, 717 688 uint32_t *feature_mask, 718 689 uint32_t num) ··· 846 803 struct PPTable_t *pptable = 847 804 (struct PPTable_t *)smu_table->driver_pptable; 848 805 int version = smu_v13_0_6_get_metrics_version(smu); 849 - int ret, i, retry = 100; 806 + int ret, i, retry = 100, n; 850 807 uint32_t table_version; 851 808 uint16_t max_speed; 852 809 uint8_t max_width; ··· 907 864 /* use AID0 serial number by default */ 908 865 pptable->PublicSerialNumber_AID = 909 866 GET_METRIC_FIELD(PublicSerialNumber_AID, version)[0]; 867 + 868 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC, 869 + 0, pptable->PublicSerialNumber_AID); 870 + n = ARRAY_SIZE(metrics_v0->PublicSerialNumber_AID); 871 + for (i = 0; i < n; i++) { 872 + amdgpu_device_set_uid( 873 + smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i, 874 + GET_METRIC_FIELD(PublicSerialNumber_AID, 875 + version)[i]); 876 + } 877 + n = ARRAY_SIZE(metrics_v0->PublicSerialNumber_XCD); 878 + for (i = 0; i < n; i++) { 879 + amdgpu_device_set_uid( 880 + smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i, 881 + GET_METRIC_FIELD(PublicSerialNumber_XCD, 882 + version)[i]); 883 + } 910 884 911 885 pptable->Init = true; 912 886 if (smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) { ··· 2620 2560 const u8 num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS_4_0_3; 2621 2561 int version = smu_v13_0_6_get_metrics_version(smu); 2622 2562 struct amdgpu_partition_metrics_v1_0 *xcp_metrics; 2563 + MetricsTableV0_t *metrics_v0 __free(kfree) = NULL; 2623 2564 struct amdgpu_device *adev = smu->adev; 2624 2565 int ret, inst, i, j, k, idx; 2625 - MetricsTableV0_t *metrics_v0; 2626 2566 MetricsTableV1_t *metrics_v1; 2627 2567 MetricsTableV2_t *metrics_v2; 2628 2568 struct amdgpu_xcp *xcp; ··· 2647 2587 return -ENOMEM; 2648 2588 2649 2589 ret = smu_v13_0_6_get_metrics_table(smu, metrics_v0, false); 2650 - if (ret) { 2651 - kfree(metrics_v0); 2590 + if (ret) 2652 2591 return ret; 2653 - } 2654 2592 2655 2593 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 2656 2594 IP_VERSION(13, 0, 12) && 2657 - smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) { 2658 - ret = smu_v13_0_12_get_xcp_metrics(smu, xcp, table, metrics_v0); 2659 - goto out; 2660 - } 2595 + smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) 2596 + return smu_v13_0_12_get_xcp_metrics(smu, xcp, table, 2597 + metrics_v0); 2661 2598 2662 2599 metrics_v1 = (MetricsTableV1_t *)metrics_v0; 2663 2600 metrics_v2 = (MetricsTableV2_t *)metrics_v0; ··· 2725 2668 idx++; 2726 2669 } 2727 2670 } 2728 - out: 2729 - kfree(metrics_v0); 2730 2671 2731 2672 return sizeof(*xcp_metrics); 2732 2673 } ··· 2735 2680 struct gpu_metrics_v1_8 *gpu_metrics = 2736 2681 (struct gpu_metrics_v1_8 *)smu_table->gpu_metrics_table; 2737 2682 int version = smu_v13_0_6_get_metrics_version(smu); 2683 + MetricsTableV0_t *metrics_v0 __free(kfree) = NULL; 2738 2684 int ret = 0, xcc_id, inst, i, j, k, idx; 2739 2685 struct amdgpu_device *adev = smu->adev; 2740 - MetricsTableV0_t *metrics_v0; 2741 2686 MetricsTableV1_t *metrics_v1; 2742 2687 MetricsTableV2_t *metrics_v2; 2743 2688 struct amdgpu_xcp *xcp; 2744 2689 u16 link_width_level; 2745 - ssize_t num_bytes; 2746 2690 u8 num_jpeg_rings; 2747 2691 u32 inst_mask; 2748 2692 bool per_inst; 2749 2693 2750 2694 metrics_v0 = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL); 2751 2695 ret = smu_v13_0_6_get_metrics_table(smu, metrics_v0, false); 2752 - if (ret) { 2753 - kfree(metrics_v0); 2696 + if (ret) 2754 2697 return ret; 2755 - } 2756 2698 2757 - if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12) && 2758 - smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) { 2759 - num_bytes = smu_v13_0_12_get_gpu_metrics(smu, table, metrics_v0); 2760 - kfree(metrics_v0); 2761 - return num_bytes; 2762 - } 2699 + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 2700 + IP_VERSION(13, 0, 12) && 2701 + smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) 2702 + return smu_v13_0_12_get_gpu_metrics(smu, table, metrics_v0); 2763 2703 2764 2704 metrics_v1 = (MetricsTableV1_t *)metrics_v0; 2765 2705 metrics_v2 = (MetricsTableV2_t *)metrics_v0; ··· 2940 2890 gpu_metrics->firmware_timestamp = GET_METRIC_FIELD(Timestamp, version); 2941 2891 2942 2892 *table = (void *)gpu_metrics; 2943 - kfree(metrics_v0); 2944 2893 2945 2894 return sizeof(*gpu_metrics); 2946 2895 } ··· 3125 3076 struct amdgpu_device *adev = smu->adev; 3126 3077 int var = (adev->pdev->device & 0xF); 3127 3078 3128 - if (var == 0x1) 3079 + if (var == 0x0 || var == 0x1 || var == 0x3) 3129 3080 return true; 3130 3081 3131 3082 return false; ··· 3199 3150 inst_mask); 3200 3151 3201 3152 return ret; 3153 + } 3154 + 3155 + static bool smu_v13_0_6_reset_vcn_is_supported(struct smu_context *smu) 3156 + { 3157 + return smu_v13_0_6_cap_supported(smu, SMU_CAP(VCN_RESET)); 3202 3158 } 3203 3159 3204 3160 static int smu_v13_0_6_reset_vcn(struct smu_context *smu, uint32_t inst_mask) ··· 3851 3797 .init_microcode = smu_v13_0_6_init_microcode, 3852 3798 .fini_microcode = smu_v13_0_fini_microcode, 3853 3799 .init_smc_tables = smu_v13_0_6_init_smc_tables, 3854 - .fini_smc_tables = smu_v13_0_fini_smc_tables, 3800 + .fini_smc_tables = smu_v13_0_6_fini_smc_tables, 3855 3801 .init_power = smu_v13_0_init_power, 3856 3802 .fini_power = smu_v13_0_fini_power, 3857 3803 .check_fw_status = smu_v13_0_6_check_fw_status, ··· 3894 3840 .reset_sdma = smu_v13_0_6_reset_sdma, 3895 3841 .reset_sdma_is_supported = smu_v13_0_6_reset_sdma_is_supported, 3896 3842 .dpm_reset_vcn = smu_v13_0_6_reset_vcn, 3843 + .reset_vcn_is_supported = smu_v13_0_6_reset_vcn_is_supported, 3897 3844 }; 3898 3845 3899 3846 void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu) ··· 3911 3856 smu_v13_0_set_smu_mailbox_registers(smu); 3912 3857 amdgpu_mca_smu_init_funcs(smu->adev, &smu_v13_0_6_mca_smu_funcs); 3913 3858 amdgpu_aca_set_smu_funcs(smu->adev, &smu_v13_0_6_aca_smu_funcs); 3859 + } 3860 + 3861 + void smu_v13_0_6_set_temp_funcs(struct smu_context *smu) 3862 + { 3863 + smu->smu_temp.temp_funcs = (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) 3864 + == IP_VERSION(13, 0, 12)) ? &smu_v13_0_12_temp_funcs : NULL; 3914 3865 }
+6
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h
··· 64 64 SMU_CAP(RMA_MSG), 65 65 SMU_CAP(ACA_SYND), 66 66 SMU_CAP(SDMA_RESET), 67 + SMU_CAP(VCN_RESET), 67 68 SMU_CAP(STATIC_METRICS), 68 69 SMU_CAP(HST_LIMIT_METRICS), 69 70 SMU_CAP(BOARD_VOLTAGE), 70 71 SMU_CAP(PLDM_VERSION), 72 + SMU_CAP(TEMP_METRICS), 71 73 SMU_CAP(ALL), 72 74 }; 73 75 74 76 extern void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu); 77 + extern void smu_v13_0_6_set_temp_funcs(struct smu_context *smu); 75 78 bool smu_v13_0_6_cap_supported(struct smu_context *smu, enum smu_v13_0_6_caps cap); 76 79 int smu_v13_0_6_get_static_metrics_table(struct smu_context *smu); 77 80 int smu_v13_0_6_get_metrics_table(struct smu_context *smu, void *metrics_table, ··· 89 86 ssize_t smu_v13_0_12_get_xcp_metrics(struct smu_context *smu, 90 87 struct amdgpu_xcp *xcp, void *table, 91 88 void *smu_metrics); 89 + int smu_v13_0_12_tables_init(struct smu_context *smu); 90 + void smu_v13_0_12_tables_fini(struct smu_context *smu); 92 91 extern const struct cmn2asic_mapping smu_v13_0_12_feature_mask_map[]; 93 92 extern const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[]; 93 + extern const struct smu_temp_funcs smu_v13_0_12_temp_funcs; 94 94 #endif
+25 -5
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
··· 1697 1697 uint32_t *min_power_limit) 1698 1698 { 1699 1699 struct smu_table_context *table_context = &smu->smu_table; 1700 + struct smu_14_0_2_powerplay_table *powerplay_table = 1701 + table_context->power_play_table; 1700 1702 PPTable_t *pptable = table_context->driver_pptable; 1701 1703 CustomSkuTable_t *skutable = &pptable->CustomSkuTable; 1702 - uint32_t power_limit; 1704 + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; 1703 1705 uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; 1704 1706 1705 1707 if (smu_v14_0_get_current_power_limit(smu, &power_limit)) ··· 1714 1712 if (default_power_limit) 1715 1713 *default_power_limit = power_limit; 1716 1714 1717 - if (max_power_limit) 1718 - *max_power_limit = msg_limit; 1715 + if (powerplay_table) { 1716 + if (smu->od_enabled && 1717 + smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { 1718 + od_percent_upper = pptable->SkuTable.OverDriveLimitsBasicMax.Ppt; 1719 + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; 1720 + } else if (smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { 1721 + od_percent_upper = 0; 1722 + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; 1723 + } 1724 + } 1719 1725 1720 - if (min_power_limit) 1721 - *min_power_limit = 0; 1726 + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", 1727 + od_percent_upper, od_percent_lower, power_limit); 1728 + 1729 + if (max_power_limit) { 1730 + *max_power_limit = msg_limit * (100 + od_percent_upper); 1731 + *max_power_limit /= 100; 1732 + } 1733 + 1734 + if (min_power_limit) { 1735 + *min_power_limit = power_limit * (100 + od_percent_lower); 1736 + *min_power_limit /= 100; 1737 + } 1722 1738 1723 1739 return 0; 1724 1740 }
+9 -5
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
··· 256 256 { 257 257 struct amdgpu_device *adev = smu->adev; 258 258 uint32_t flags, resp; 259 - bool fed_status; 259 + bool fed_status, pri; 260 260 261 261 flags = __smu_cmn_get_msg_flags(smu, msg); 262 262 *poll = true; 263 263 264 + pri = !!(flags & SMU_MSG_NO_PRECHECK); 264 265 /* When there is RAS fatal error, FW won't process non-RAS priority 265 266 * messages. Don't allow any messages other than RAS priority messages. 266 267 */ ··· 273 272 smu_get_message_name(smu, msg)); 274 273 return -EACCES; 275 274 } 275 + } 276 276 277 + if (pri || fed_status) { 277 278 /* FW will ignore non-priority messages when a RAS fatal error 278 - * is detected. Hence it is possible that a previous message 279 - * wouldn't have got response. Allow to continue without polling 280 - * for response status for priority messages. 279 + * or reset condition is detected. Hence it is possible that a 280 + * previous message wouldn't have got response. Allow to 281 + * continue without polling for response status for priority 282 + * messages. 281 283 */ 282 284 resp = RREG32(smu->resp_reg); 283 285 dev_dbg(adev->dev, 284 - "Sending RAS priority message %s response status: %x", 286 + "Sending priority message %s response status: %x", 285 287 smu_get_message_name(smu, msg), resp); 286 288 if (resp == 0) 287 289 *poll = false;
+26
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
··· 65 65 header->structure_size = sizeof(*tmp); \ 66 66 } while (0) 67 67 68 + #define smu_cmn_init_baseboard_temp_metrics(ptr, fr, cr) \ 69 + do { \ 70 + typecheck(struct amdgpu_baseboard_temp_metrics_v##fr##_##cr *, \ 71 + (ptr)); \ 72 + struct amdgpu_baseboard_temp_metrics_v##fr##_##cr *tmp = (ptr); \ 73 + struct metrics_table_header *header = \ 74 + (struct metrics_table_header *)tmp; \ 75 + memset(header, 0xFF, sizeof(*tmp)); \ 76 + header->format_revision = fr; \ 77 + header->content_revision = cr; \ 78 + header->structure_size = sizeof(*tmp); \ 79 + } while (0) 80 + 81 + #define smu_cmn_init_gpuboard_temp_metrics(ptr, fr, cr) \ 82 + do { \ 83 + typecheck(struct amdgpu_gpuboard_temp_metrics_v##fr##_##cr *, \ 84 + (ptr)); \ 85 + struct amdgpu_gpuboard_temp_metrics_v##fr##_##cr *tmp = (ptr); \ 86 + struct metrics_table_header *header = \ 87 + (struct metrics_table_header *)tmp; \ 88 + memset(header, 0xFF, sizeof(*tmp)); \ 89 + header->format_revision = fr; \ 90 + header->content_revision = cr; \ 91 + header->structure_size = sizeof(*tmp); \ 92 + } while (0) 93 + 68 94 extern const int link_speed[]; 69 95 70 96 /* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */
+2 -2
drivers/gpu/drm/radeon/r600_cs.c
··· 1408 1408 unsigned block_align, unsigned height_align, unsigned base_align, 1409 1409 unsigned *l0_size, unsigned *mipmap_size) 1410 1410 { 1411 - unsigned offset, i, level; 1411 + unsigned offset, i; 1412 1412 unsigned width, height, depth, size; 1413 1413 unsigned blocksize; 1414 1414 unsigned nbx, nby; ··· 1420 1420 w0 = r600_mip_minify(w0, 0); 1421 1421 h0 = r600_mip_minify(h0, 0); 1422 1422 d0 = r600_mip_minify(d0, 0); 1423 - for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { 1423 + for (i = 0, offset = 0; i < nlevels; i++) { 1424 1424 width = r600_mip_minify(w0, i); 1425 1425 nbx = r600_fmt_get_nblocksx(format, width); 1426 1426
+2 -2
drivers/gpu/drm/radeon/radeon_device.c
··· 554 554 * cover the whole aperture even if VRAM size is inferior to aperture size 555 555 * Novell bug 204882 + along with lots of ubuntu ones 556 556 * 557 - * Note 3: when limiting vram it's safe to overwritte real_vram_size because 557 + * Note 3: when limiting vram it's safe to overwrite real_vram_size because 558 558 * we are not in case where real_vram_size is inferior to mc_vram_size (ie 559 559 * not affected by bogus hw of Novell bug 204882 + along with lots of ubuntu 560 560 * ones) ··· 562 562 * Note 4: IGP TOM addr should be the same as the aperture addr, we don't 563 563 * explicitly check for that thought. 564 564 * 565 - * FIXME: when reducing VRAM size align new size on power of 2. 565 + * FIXME: when reducing VRAM size, align new size on power of 2. 566 566 */ 567 567 void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) 568 568 {
+2 -2
drivers/gpu/drm/radeon/radeon_display.c
··· 926 926 unsigned *fb_div, unsigned *ref_div) 927 927 { 928 928 /* limit reference * post divider to a maximum */ 929 - ref_div_max = max(min(100 / post_div, ref_div_max), 1u); 929 + ref_div_max = clamp(100 / post_div, 1u, ref_div_max); 930 930 931 931 /* get matching reference and feedback divider */ 932 - *ref_div = min(max(den/post_div, 1u), ref_div_max); 932 + *ref_div = clamp(den / post_div, 1u, ref_div_max); 933 933 *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den); 934 934 935 935 /* limit fb divider to its maximum */
+4 -4
drivers/gpu/drm/radeon/radeon_gart.c
··· 346 346 DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", 347 347 rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); 348 348 /* Allocate pages table */ 349 - rdev->gart.pages = vzalloc(array_size(sizeof(void *), 350 - rdev->gart.num_cpu_pages)); 349 + rdev->gart.pages = vcalloc(rdev->gart.num_cpu_pages, 350 + sizeof(void *)); 351 351 if (rdev->gart.pages == NULL) { 352 352 radeon_gart_fini(rdev); 353 353 return -ENOMEM; 354 354 } 355 - rdev->gart.pages_entry = vmalloc(array_size(sizeof(uint64_t), 356 - rdev->gart.num_gpu_pages)); 355 + rdev->gart.pages_entry = vmalloc_array(rdev->gart.num_gpu_pages, 356 + sizeof(uint64_t)); 357 357 if (rdev->gart.pages_entry == NULL) { 358 358 radeon_gart_fini(rdev); 359 359 return -ENOMEM;
+2 -2
drivers/gpu/drm/radeon/radeon_test.c
··· 455 455 456 456 r = radeon_ring_lock(rdev, ringC, 64); 457 457 if (r) { 458 - DRM_ERROR("Failed to lock ring B %p\n", ringC); 458 + DRM_ERROR("Failed to lock ring C %p\n", ringC); 459 459 goto out_cleanup; 460 460 } 461 461 radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); ··· 481 481 482 482 r = radeon_ring_lock(rdev, ringC, 64); 483 483 if (r) { 484 - DRM_ERROR("Failed to lock ring B %p\n", ringC); 484 + DRM_ERROR("Failed to lock ring C %p\n", ringC); 485 485 goto out_cleanup; 486 486 } 487 487 radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore);
+3 -3
drivers/gpu/drm/radeon/radeon_vce.c
··· 86 86 87 87 r = request_firmware(&rdev->vce_fw, fw_name, rdev->dev); 88 88 if (r) { 89 - dev_err(rdev->dev, "radeon_vce: Can't load firmware \"%s\"\n", 89 + dev_err(rdev->dev, "radeon_vce: can't load firmware \"%s\"\n", 90 90 fw_name); 91 91 return r; 92 92 } ··· 126 126 127 127 rdev->vce.fw_version = (start << 24) | (mid << 16) | (end << 8); 128 128 129 - /* we can only work with this fw version for now */ 129 + /* we can only work with these fw versions for now */ 130 130 if ((rdev->vce.fw_version != ((40 << 24) | (2 << 16) | (2 << 8))) && 131 131 (rdev->vce.fw_version != ((50 << 24) | (0 << 16) | (1 << 8))) && 132 132 (rdev->vce.fw_version != ((50 << 24) | (1 << 16) | (2 << 8)))) ··· 281 281 * 282 282 * @rdev: radeon_device pointer 283 283 * 284 - * Make sure VCE is powerd up when we want to use it 284 + * Make sure VCE is powered up when we want to use it 285 285 */ 286 286 void radeon_vce_note_usage(struct radeon_device *rdev) 287 287 {