diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2018-03-15 18:39:45 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-03-21 00:43:05 -0400 |
commit | e3ecdffac9ccdbb201a6daf158faae1060e1b565 (patch) | |
tree | 2f2da27ccd3e72e7e89901c64a017d4fb794d128 /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
parent | 3ac952b10dec55e50312340ca4cf8f631944ae17 (diff) |
drm/amdgpu: add documentation for amdgpu_device.c
Add kernel doc for the functions in amdgpu_device.c
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 439 |
1 files changed, 427 insertions, 12 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 690cf77b950e..beabb90e595a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -89,6 +89,14 @@ static const char *amdgpu_asic_name[] = { | |||
89 | 89 | ||
90 | static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev); | 90 | static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev); |
91 | 91 | ||
92 | /** | ||
93 | * amdgpu_device_is_px - Is the device is a dGPU with HG/PX power control | ||
94 | * | ||
95 | * @dev: drm_device pointer | ||
96 | * | ||
97 | * Returns true if the device is a dGPU with HG/PX power control, | ||
98 | * otherwise return false. | ||
99 | */ | ||
92 | bool amdgpu_device_is_px(struct drm_device *dev) | 100 | bool amdgpu_device_is_px(struct drm_device *dev) |
93 | { | 101 | { |
94 | struct amdgpu_device *adev = dev->dev_private; | 102 | struct amdgpu_device *adev = dev->dev_private; |
@@ -101,6 +109,15 @@ bool amdgpu_device_is_px(struct drm_device *dev) | |||
101 | /* | 109 | /* |
102 | * MMIO register access helper functions. | 110 | * MMIO register access helper functions. |
103 | */ | 111 | */ |
112 | /** | ||
113 | * amdgpu_mm_rreg - read a memory mapped IO register | ||
114 | * | ||
115 | * @adev: amdgpu_device pointer | ||
116 | * @reg: dword aligned register offset | ||
117 | * @acc_flags: access flags which require special behavior | ||
118 | * | ||
119 | * Returns the 32 bit value from the offset specified. | ||
120 | */ | ||
104 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | 121 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, |
105 | uint32_t acc_flags) | 122 | uint32_t acc_flags) |
106 | { | 123 | { |
@@ -129,6 +146,14 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | |||
129 | * | 146 | * |
130 | */ | 147 | */ |
131 | 148 | ||
149 | /** | ||
150 | * amdgpu_mm_rreg8 - read a memory mapped IO register | ||
151 | * | ||
152 | * @adev: amdgpu_device pointer | ||
153 | * @offset: byte aligned register offset | ||
154 | * | ||
155 | * Returns the 8 bit value from the offset specified. | ||
156 | */ | ||
132 | uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) { | 157 | uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) { |
133 | if (offset < adev->rmmio_size) | 158 | if (offset < adev->rmmio_size) |
134 | return (readb(adev->rmmio + offset)); | 159 | return (readb(adev->rmmio + offset)); |
@@ -141,6 +166,15 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) { | |||
141 | * @value: the value want to be written to the register | 166 | * @value: the value want to be written to the register |
142 | * | 167 | * |
143 | */ | 168 | */ |
169 | /** | ||
170 | * amdgpu_mm_wreg8 - read a memory mapped IO register | ||
171 | * | ||
172 | * @adev: amdgpu_device pointer | ||
173 | * @offset: byte aligned register offset | ||
174 | * @value: 8 bit value to write | ||
175 | * | ||
176 | * Writes the value specified to the offset specified. | ||
177 | */ | ||
144 | void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) { | 178 | void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) { |
145 | if (offset < adev->rmmio_size) | 179 | if (offset < adev->rmmio_size) |
146 | writeb(value, adev->rmmio + offset); | 180 | writeb(value, adev->rmmio + offset); |
@@ -148,7 +182,16 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) | |||
148 | BUG(); | 182 | BUG(); |
149 | } | 183 | } |
150 | 184 | ||
151 | 185 | /** | |
186 | * amdgpu_mm_wreg - write to a memory mapped IO register | ||
187 | * | ||
188 | * @adev: amdgpu_device pointer | ||
189 | * @reg: dword aligned register offset | ||
190 | * @v: 32 bit value to write to the register | ||
191 | * @acc_flags: access flags which require special behavior | ||
192 | * | ||
193 | * Writes the value specified to the offset specified. | ||
194 | */ | ||
152 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | 195 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, |
153 | uint32_t acc_flags) | 196 | uint32_t acc_flags) |
154 | { | 197 | { |
@@ -177,6 +220,14 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | |||
177 | } | 220 | } |
178 | } | 221 | } |
179 | 222 | ||
223 | /** | ||
224 | * amdgpu_io_rreg - read an IO register | ||
225 | * | ||
226 | * @adev: amdgpu_device pointer | ||
227 | * @reg: dword aligned register offset | ||
228 | * | ||
229 | * Returns the 32 bit value from the offset specified. | ||
230 | */ | ||
180 | u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg) | 231 | u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg) |
181 | { | 232 | { |
182 | if ((reg * 4) < adev->rio_mem_size) | 233 | if ((reg * 4) < adev->rio_mem_size) |
@@ -187,6 +238,15 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg) | |||
187 | } | 238 | } |
188 | } | 239 | } |
189 | 240 | ||
241 | /** | ||
242 | * amdgpu_io_wreg - write to an IO register | ||
243 | * | ||
244 | * @adev: amdgpu_device pointer | ||
245 | * @reg: dword aligned register offset | ||
246 | * @v: 32 bit value to write to the register | ||
247 | * | ||
248 | * Writes the value specified to the offset specified. | ||
249 | */ | ||
190 | void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | 250 | void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v) |
191 | { | 251 | { |
192 | if (adev->asic_type >= CHIP_VEGA10 && reg == 0) { | 252 | if (adev->asic_type >= CHIP_VEGA10 && reg == 0) { |
@@ -355,6 +415,14 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev, | |||
355 | BUG(); | 415 | BUG(); |
356 | } | 416 | } |
357 | 417 | ||
418 | /** | ||
419 | * amdgpu_device_vram_scratch_init - allocate the VRAM scratch page | ||
420 | * | ||
421 | * @adev: amdgpu device pointer | ||
422 | * | ||
423 | * Allocates a scratch page of VRAM for use by various things in the | ||
424 | * driver. | ||
425 | */ | ||
358 | static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) | 426 | static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) |
359 | { | 427 | { |
360 | return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, | 428 | return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, |
@@ -364,6 +432,13 @@ static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) | |||
364 | (void **)&adev->vram_scratch.ptr); | 432 | (void **)&adev->vram_scratch.ptr); |
365 | } | 433 | } |
366 | 434 | ||
435 | /** | ||
436 | * amdgpu_device_vram_scratch_fini - Free the VRAM scratch page | ||
437 | * | ||
438 | * @adev: amdgpu device pointer | ||
439 | * | ||
440 | * Frees the VRAM scratch page. | ||
441 | */ | ||
367 | static void amdgpu_device_vram_scratch_fini(struct amdgpu_device *adev) | 442 | static void amdgpu_device_vram_scratch_fini(struct amdgpu_device *adev) |
368 | { | 443 | { |
369 | amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL); | 444 | amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL); |
@@ -405,6 +480,14 @@ void amdgpu_device_program_register_sequence(struct amdgpu_device *adev, | |||
405 | } | 480 | } |
406 | } | 481 | } |
407 | 482 | ||
483 | /** | ||
484 | * amdgpu_device_pci_config_reset - reset the GPU | ||
485 | * | ||
486 | * @adev: amdgpu_device pointer | ||
487 | * | ||
488 | * Resets the GPU using the pci config reset sequence. | ||
489 | * Only applicable to asics prior to vega10. | ||
490 | */ | ||
408 | void amdgpu_device_pci_config_reset(struct amdgpu_device *adev) | 491 | void amdgpu_device_pci_config_reset(struct amdgpu_device *adev) |
409 | { | 492 | { |
410 | pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA); | 493 | pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA); |
@@ -565,6 +648,7 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) | |||
565 | 648 | ||
566 | /** | 649 | /** |
567 | * amdgpu_device_vram_location - try to find VRAM location | 650 | * amdgpu_device_vram_location - try to find VRAM location |
651 | * | ||
568 | * @adev: amdgpu device structure holding all necessary informations | 652 | * @adev: amdgpu device structure holding all necessary informations |
569 | * @mc: memory controller structure holding memory informations | 653 | * @mc: memory controller structure holding memory informations |
570 | * @base: base address at which to put VRAM | 654 | * @base: base address at which to put VRAM |
@@ -588,6 +672,7 @@ void amdgpu_device_vram_location(struct amdgpu_device *adev, | |||
588 | 672 | ||
589 | /** | 673 | /** |
590 | * amdgpu_device_gart_location - try to find GTT location | 674 | * amdgpu_device_gart_location - try to find GTT location |
675 | * | ||
591 | * @adev: amdgpu device structure holding all necessary informations | 676 | * @adev: amdgpu device structure holding all necessary informations |
592 | * @mc: memory controller structure holding memory informations | 677 | * @mc: memory controller structure holding memory informations |
593 | * | 678 | * |
@@ -774,6 +859,16 @@ static unsigned int amdgpu_device_vga_set_decode(void *cookie, bool state) | |||
774 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | 859 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
775 | } | 860 | } |
776 | 861 | ||
862 | /** | ||
863 | * amdgpu_device_check_block_size - validate the vm block size | ||
864 | * | ||
865 | * @adev: amdgpu_device pointer | ||
866 | * | ||
867 | * Validates the vm block size specified via module parameter. | ||
868 | * The vm block size defines number of bits in page table versus page directory, | ||
869 | * a page is 4KB so we have 12 bits offset, minimum 9 bits in the | ||
870 | * page table and the remaining bits are in the page directory. | ||
871 | */ | ||
777 | static void amdgpu_device_check_block_size(struct amdgpu_device *adev) | 872 | static void amdgpu_device_check_block_size(struct amdgpu_device *adev) |
778 | { | 873 | { |
779 | /* defines number of bits in page table versus page directory, | 874 | /* defines number of bits in page table versus page directory, |
@@ -789,6 +884,14 @@ static void amdgpu_device_check_block_size(struct amdgpu_device *adev) | |||
789 | } | 884 | } |
790 | } | 885 | } |
791 | 886 | ||
887 | /** | ||
888 | * amdgpu_device_check_vm_size - validate the vm size | ||
889 | * | ||
890 | * @adev: amdgpu_device pointer | ||
891 | * | ||
892 | * Validates the vm size in GB specified via module parameter. | ||
893 | * The VM size is the size of the GPU virtual memory space in GB. | ||
894 | */ | ||
792 | static void amdgpu_device_check_vm_size(struct amdgpu_device *adev) | 895 | static void amdgpu_device_check_vm_size(struct amdgpu_device *adev) |
793 | { | 896 | { |
794 | /* no need to check the default value */ | 897 | /* no need to check the default value */ |
@@ -923,6 +1026,17 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { | |||
923 | .can_switch = amdgpu_switcheroo_can_switch, | 1026 | .can_switch = amdgpu_switcheroo_can_switch, |
924 | }; | 1027 | }; |
925 | 1028 | ||
1029 | /** | ||
1030 | * amdgpu_device_ip_set_clockgating_state - set the CG state | ||
1031 | * | ||
1032 | * @adev: amdgpu_device pointer | ||
1033 | * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) | ||
1034 | * @state: clockgating state (gate or ungate) | ||
1035 | * | ||
1036 | * Sets the requested clockgating state for all instances of | ||
1037 | * the hardware IP specified. | ||
1038 | * Returns the error code from the last instance. | ||
1039 | */ | ||
926 | int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev, | 1040 | int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev, |
927 | enum amd_ip_block_type block_type, | 1041 | enum amd_ip_block_type block_type, |
928 | enum amd_clockgating_state state) | 1042 | enum amd_clockgating_state state) |
@@ -945,6 +1059,17 @@ int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev, | |||
945 | return r; | 1059 | return r; |
946 | } | 1060 | } |
947 | 1061 | ||
1062 | /** | ||
1063 | * amdgpu_device_ip_set_powergating_state - set the PG state | ||
1064 | * | ||
1065 | * @adev: amdgpu_device pointer | ||
1066 | * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) | ||
1067 | * @state: powergating state (gate or ungate) | ||
1068 | * | ||
1069 | * Sets the requested powergating state for all instances of | ||
1070 | * the hardware IP specified. | ||
1071 | * Returns the error code from the last instance. | ||
1072 | */ | ||
948 | int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev, | 1073 | int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev, |
949 | enum amd_ip_block_type block_type, | 1074 | enum amd_ip_block_type block_type, |
950 | enum amd_powergating_state state) | 1075 | enum amd_powergating_state state) |
@@ -967,6 +1092,17 @@ int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev, | |||
967 | return r; | 1092 | return r; |
968 | } | 1093 | } |
969 | 1094 | ||
1095 | /** | ||
1096 | * amdgpu_device_ip_get_clockgating_state - get the CG state | ||
1097 | * | ||
1098 | * @adev: amdgpu_device pointer | ||
1099 | * @flags: clockgating feature flags | ||
1100 | * | ||
1101 | * Walks the list of IPs on the device and updates the clockgating | ||
1102 | * flags for each IP. | ||
1103 | * Updates @flags with the feature flags for each hardware IP where | ||
1104 | * clockgating is enabled. | ||
1105 | */ | ||
970 | void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, | 1106 | void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, |
971 | u32 *flags) | 1107 | u32 *flags) |
972 | { | 1108 | { |
@@ -980,6 +1116,15 @@ void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, | |||
980 | } | 1116 | } |
981 | } | 1117 | } |
982 | 1118 | ||
1119 | /** | ||
1120 | * amdgpu_device_ip_wait_for_idle - wait for idle | ||
1121 | * | ||
1122 | * @adev: amdgpu_device pointer | ||
1123 | * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) | ||
1124 | * | ||
1125 | * Waits for the request hardware IP to be idle. | ||
1126 | * Returns 0 for success or a negative error code on failure. | ||
1127 | */ | ||
983 | int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, | 1128 | int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, |
984 | enum amd_ip_block_type block_type) | 1129 | enum amd_ip_block_type block_type) |
985 | { | 1130 | { |
@@ -999,6 +1144,15 @@ int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, | |||
999 | 1144 | ||
1000 | } | 1145 | } |
1001 | 1146 | ||
1147 | /** | ||
1148 | * amdgpu_device_ip_is_idle - is the hardware IP idle | ||
1149 | * | ||
1150 | * @adev: amdgpu_device pointer | ||
1151 | * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) | ||
1152 | * | ||
1153 | * Check if the hardware IP is idle or not. | ||
1154 | * Returns true if it the IP is idle, false if not. | ||
1155 | */ | ||
1002 | bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev, | 1156 | bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev, |
1003 | enum amd_ip_block_type block_type) | 1157 | enum amd_ip_block_type block_type) |
1004 | { | 1158 | { |
@@ -1014,6 +1168,15 @@ bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev, | |||
1014 | 1168 | ||
1015 | } | 1169 | } |
1016 | 1170 | ||
1171 | /** | ||
1172 | * amdgpu_device_ip_get_ip_block - get a hw IP pointer | ||
1173 | * | ||
1174 | * @adev: amdgpu_device pointer | ||
1175 | * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) | ||
1176 | * | ||
1177 | * Returns a pointer to the hardware IP block structure | ||
1178 | * if it exists for the asic, otherwise NULL. | ||
1179 | */ | ||
1017 | struct amdgpu_ip_block * | 1180 | struct amdgpu_ip_block * |
1018 | amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, | 1181 | amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, |
1019 | enum amd_ip_block_type type) | 1182 | enum amd_ip_block_type type) |
@@ -1075,6 +1238,18 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev, | |||
1075 | return 0; | 1238 | return 0; |
1076 | } | 1239 | } |
1077 | 1240 | ||
1241 | /** | ||
1242 | * amdgpu_device_enable_virtual_display - enable virtual display feature | ||
1243 | * | ||
1244 | * @adev: amdgpu_device pointer | ||
1245 | * | ||
1246 | * Enabled the virtual display feature if the user has enabled it via | ||
1247 | * the module parameter virtual_display. This feature provides a virtual | ||
1248 | * display hardware on headless boards or in virtualized environments. | ||
1249 | * This function parses and validates the configuration string specified by | ||
1250 | * the user and configues the virtual display configuration (number of | ||
1251 | * virtual connectors, crtcs, etc.) specified. | ||
1252 | */ | ||
1078 | static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev) | 1253 | static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev) |
1079 | { | 1254 | { |
1080 | adev->enable_virtual_display = false; | 1255 | adev->enable_virtual_display = false; |
@@ -1120,6 +1295,16 @@ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev) | |||
1120 | } | 1295 | } |
1121 | } | 1296 | } |
1122 | 1297 | ||
1298 | /** | ||
1299 | * amdgpu_device_parse_gpu_info_fw - parse gpu info firmware | ||
1300 | * | ||
1301 | * @adev: amdgpu_device pointer | ||
1302 | * | ||
1303 | * Parses the asic configuration parameters specified in the gpu info | ||
1304 | * firmware and makes them availale to the driver for use in configuring | ||
1305 | * the asic. | ||
1306 | * Returns 0 on success, -EINVAL on failure. | ||
1307 | */ | ||
1123 | static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) | 1308 | static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) |
1124 | { | 1309 | { |
1125 | const char *chip_name; | 1310 | const char *chip_name; |
@@ -1218,6 +1403,16 @@ out: | |||
1218 | return err; | 1403 | return err; |
1219 | } | 1404 | } |
1220 | 1405 | ||
1406 | /** | ||
1407 | * amdgpu_device_ip_early_init - run early init for hardware IPs | ||
1408 | * | ||
1409 | * @adev: amdgpu_device pointer | ||
1410 | * | ||
1411 | * Early initialization pass for hardware IPs. The hardware IPs that make | ||
1412 | * up each asic are discovered each IP's early_init callback is run. This | ||
1413 | * is the first stage in initializing the asic. | ||
1414 | * Returns 0 on success, negative error code on failure. | ||
1415 | */ | ||
1221 | static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) | 1416 | static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) |
1222 | { | 1417 | { |
1223 | int i, r; | 1418 | int i, r; |
@@ -1327,6 +1522,17 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) | |||
1327 | return 0; | 1522 | return 0; |
1328 | } | 1523 | } |
1329 | 1524 | ||
1525 | /** | ||
1526 | * amdgpu_device_ip_init - run init for hardware IPs | ||
1527 | * | ||
1528 | * @adev: amdgpu_device pointer | ||
1529 | * | ||
1530 | * Main initialization pass for hardware IPs. The list of all the hardware | ||
1531 | * IPs that make up the asic is walked and the sw_init and hw_init callbacks | ||
1532 | * are run. sw_init initializes the software state associated with each IP | ||
1533 | * and hw_init initializes the hardware associated with each IP. | ||
1534 | * Returns 0 on success, negative error code on failure. | ||
1535 | */ | ||
1330 | static int amdgpu_device_ip_init(struct amdgpu_device *adev) | 1536 | static int amdgpu_device_ip_init(struct amdgpu_device *adev) |
1331 | { | 1537 | { |
1332 | int i, r; | 1538 | int i, r; |
@@ -1394,17 +1600,47 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) | |||
1394 | return 0; | 1600 | return 0; |
1395 | } | 1601 | } |
1396 | 1602 | ||
1603 | /** | ||
1604 | * amdgpu_device_fill_reset_magic - writes reset magic to gart pointer | ||
1605 | * | ||
1606 | * @adev: amdgpu_device pointer | ||
1607 | * | ||
1608 | * Writes a reset magic value to the gart pointer in VRAM. The driver calls | ||
1609 | * this function before a GPU reset. If the value is retained after a | ||
1610 | * GPU reset, VRAM has not been lost. Some GPU resets may destry VRAM contents. | ||
1611 | */ | ||
1397 | static void amdgpu_device_fill_reset_magic(struct amdgpu_device *adev) | 1612 | static void amdgpu_device_fill_reset_magic(struct amdgpu_device *adev) |
1398 | { | 1613 | { |
1399 | memcpy(adev->reset_magic, adev->gart.ptr, AMDGPU_RESET_MAGIC_NUM); | 1614 | memcpy(adev->reset_magic, adev->gart.ptr, AMDGPU_RESET_MAGIC_NUM); |
1400 | } | 1615 | } |
1401 | 1616 | ||
1617 | /** | ||
1618 | * amdgpu_device_check_vram_lost - check if vram is valid | ||
1619 | * | ||
1620 | * @adev: amdgpu_device pointer | ||
1621 | * | ||
1622 | * Checks the reset magic value written to the gart pointer in VRAM. | ||
1623 | * The driver calls this after a GPU reset to see if the contents of | ||
1624 | * VRAM is lost or now. | ||
1625 | * returns true if vram is lost, false if not. | ||
1626 | */ | ||
1402 | static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev) | 1627 | static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev) |
1403 | { | 1628 | { |
1404 | return !!memcmp(adev->gart.ptr, adev->reset_magic, | 1629 | return !!memcmp(adev->gart.ptr, adev->reset_magic, |
1405 | AMDGPU_RESET_MAGIC_NUM); | 1630 | AMDGPU_RESET_MAGIC_NUM); |
1406 | } | 1631 | } |
1407 | 1632 | ||
1633 | /** | ||
1634 | * amdgpu_device_ip_late_set_cg_state - late init for clockgating | ||
1635 | * | ||
1636 | * @adev: amdgpu_device pointer | ||
1637 | * | ||
1638 | * Late initialization pass enabling clockgating for hardware IPs. | ||
1639 | * The list of all the hardware IPs that make up the asic is walked and the | ||
1640 | * set_clockgating_state callbacks are run. This stage is run late | ||
1641 | * in the init process. | ||
1642 | * Returns 0 on success, negative error code on failure. | ||
1643 | */ | ||
1408 | static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) | 1644 | static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) |
1409 | { | 1645 | { |
1410 | int i = 0, r; | 1646 | int i = 0, r; |
@@ -1432,6 +1668,18 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) | |||
1432 | return 0; | 1668 | return 0; |
1433 | } | 1669 | } |
1434 | 1670 | ||
1671 | /** | ||
1672 | * amdgpu_device_ip_late_init - run late init for hardware IPs | ||
1673 | * | ||
1674 | * @adev: amdgpu_device pointer | ||
1675 | * | ||
1676 | * Late initialization pass for hardware IPs. The list of all the hardware | ||
1677 | * IPs that make up the asic is walked and the late_init callbacks are run. | ||
1678 | * late_init covers any special initialization that an IP requires | ||
1679 | * after all of the have been initialized or something that needs to happen | ||
1680 | * late in the init process. | ||
1681 | * Returns 0 on success, negative error code on failure. | ||
1682 | */ | ||
1435 | static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) | 1683 | static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) |
1436 | { | 1684 | { |
1437 | int i = 0, r; | 1685 | int i = 0, r; |
@@ -1458,6 +1706,17 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) | |||
1458 | return 0; | 1706 | return 0; |
1459 | } | 1707 | } |
1460 | 1708 | ||
1709 | /** | ||
1710 | * amdgpu_device_ip_fini - run fini for hardware IPs | ||
1711 | * | ||
1712 | * @adev: amdgpu_device pointer | ||
1713 | * | ||
1714 | * Main teardown pass for hardware IPs. The list of all the hardware | ||
1715 | * IPs that make up the asic is walked and the hw_fini and sw_fini callbacks | ||
1716 | * are run. hw_fini tears down the hardware associated with each IP | ||
1717 | * and sw_fini tears down any software state associated with each IP. | ||
1718 | * Returns 0 on success, negative error code on failure. | ||
1719 | */ | ||
1461 | static int amdgpu_device_ip_fini(struct amdgpu_device *adev) | 1720 | static int amdgpu_device_ip_fini(struct amdgpu_device *adev) |
1462 | { | 1721 | { |
1463 | int i, r; | 1722 | int i, r; |
@@ -1552,6 +1811,15 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) | |||
1552 | return 0; | 1811 | return 0; |
1553 | } | 1812 | } |
1554 | 1813 | ||
1814 | /** | ||
1815 | * amdgpu_device_ip_late_init_func_handler - work handler for clockgating | ||
1816 | * | ||
1817 | * @work: work_struct | ||
1818 | * | ||
1819 | * Work handler for amdgpu_device_ip_late_set_cg_state. We put the | ||
1820 | * clockgating setup into a worker thread to speed up driver init and | ||
1821 | * resume from suspend. | ||
1822 | */ | ||
1555 | static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) | 1823 | static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) |
1556 | { | 1824 | { |
1557 | struct amdgpu_device *adev = | 1825 | struct amdgpu_device *adev = |
@@ -1559,6 +1827,17 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) | |||
1559 | amdgpu_device_ip_late_set_cg_state(adev); | 1827 | amdgpu_device_ip_late_set_cg_state(adev); |
1560 | } | 1828 | } |
1561 | 1829 | ||
1830 | /** | ||
1831 | * amdgpu_device_ip_suspend - run suspend for hardware IPs | ||
1832 | * | ||
1833 | * @adev: amdgpu_device pointer | ||
1834 | * | ||
1835 | * Main suspend function for hardware IPs. The list of all the hardware | ||
1836 | * IPs that make up the asic is walked, clockgating is disabled and the | ||
1837 | * suspend callbacks are run. suspend puts the hardware and software state | ||
1838 | * in each IP into a state suitable for suspend. | ||
1839 | * Returns 0 on success, negative error code on failure. | ||
1840 | */ | ||
1562 | int amdgpu_device_ip_suspend(struct amdgpu_device *adev) | 1841 | int amdgpu_device_ip_suspend(struct amdgpu_device *adev) |
1563 | { | 1842 | { |
1564 | int i, r; | 1843 | int i, r; |
@@ -1667,6 +1946,18 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev) | |||
1667 | return 0; | 1946 | return 0; |
1668 | } | 1947 | } |
1669 | 1948 | ||
1949 | /** | ||
1950 | * amdgpu_device_ip_resume_phase1 - run resume for hardware IPs | ||
1951 | * | ||
1952 | * @adev: amdgpu_device pointer | ||
1953 | * | ||
1954 | * First resume function for hardware IPs. The list of all the hardware | ||
1955 | * IPs that make up the asic is walked and the resume callbacks are run for | ||
1956 | * COMMON, GMC, and IH. resume puts the hardware into a functional state | ||
1957 | * after a suspend and updates the software state as necessary. This | ||
1958 | * function is also used for restoring the GPU after a GPU reset. | ||
1959 | * Returns 0 on success, negative error code on failure. | ||
1960 | */ | ||
1670 | static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) | 1961 | static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) |
1671 | { | 1962 | { |
1672 | int i, r; | 1963 | int i, r; |
@@ -1675,9 +1966,8 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) | |||
1675 | if (!adev->ip_blocks[i].status.valid) | 1966 | if (!adev->ip_blocks[i].status.valid) |
1676 | continue; | 1967 | continue; |
1677 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || | 1968 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || |
1678 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || | 1969 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || |
1679 | adev->ip_blocks[i].version->type == | 1970 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) { |
1680 | AMD_IP_BLOCK_TYPE_IH) { | ||
1681 | r = adev->ip_blocks[i].version->funcs->resume(adev); | 1971 | r = adev->ip_blocks[i].version->funcs->resume(adev); |
1682 | if (r) { | 1972 | if (r) { |
1683 | DRM_ERROR("resume of IP block <%s> failed %d\n", | 1973 | DRM_ERROR("resume of IP block <%s> failed %d\n", |
@@ -1690,6 +1980,19 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) | |||
1690 | return 0; | 1980 | return 0; |
1691 | } | 1981 | } |
1692 | 1982 | ||
1983 | /** | ||
1984 | * amdgpu_device_ip_resume_phase2 - run resume for hardware IPs | ||
1985 | * | ||
1986 | * @adev: amdgpu_device pointer | ||
1987 | * | ||
1988 | * First resume function for hardware IPs. The list of all the hardware | ||
1989 | * IPs that make up the asic is walked and the resume callbacks are run for | ||
1990 | * all blocks except COMMON, GMC, and IH. resume puts the hardware into a | ||
1991 | * functional state after a suspend and updates the software state as | ||
1992 | * necessary. This function is also used for restoring the GPU after a GPU | ||
1993 | * reset. | ||
1994 | * Returns 0 on success, negative error code on failure. | ||
1995 | */ | ||
1693 | static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) | 1996 | static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) |
1694 | { | 1997 | { |
1695 | int i, r; | 1998 | int i, r; |
@@ -1698,8 +2001,8 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) | |||
1698 | if (!adev->ip_blocks[i].status.valid) | 2001 | if (!adev->ip_blocks[i].status.valid) |
1699 | continue; | 2002 | continue; |
1700 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || | 2003 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || |
1701 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || | 2004 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || |
1702 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ) | 2005 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) |
1703 | continue; | 2006 | continue; |
1704 | r = adev->ip_blocks[i].version->funcs->resume(adev); | 2007 | r = adev->ip_blocks[i].version->funcs->resume(adev); |
1705 | if (r) { | 2008 | if (r) { |
@@ -1712,6 +2015,18 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) | |||
1712 | return 0; | 2015 | return 0; |
1713 | } | 2016 | } |
1714 | 2017 | ||
2018 | /** | ||
2019 | * amdgpu_device_ip_resume - run resume for hardware IPs | ||
2020 | * | ||
2021 | * @adev: amdgpu_device pointer | ||
2022 | * | ||
2023 | * Main resume function for hardware IPs. The hardware IPs | ||
2024 | * are split into two resume functions because they are | ||
2025 | * are also used in in recovering from a GPU reset and some additional | ||
2026 | * steps need to be take between them. In this case (S3/S4) they are | ||
2027 | * run sequentially. | ||
2028 | * Returns 0 on success, negative error code on failure. | ||
2029 | */ | ||
1715 | static int amdgpu_device_ip_resume(struct amdgpu_device *adev) | 2030 | static int amdgpu_device_ip_resume(struct amdgpu_device *adev) |
1716 | { | 2031 | { |
1717 | int r; | 2032 | int r; |
@@ -1724,6 +2039,13 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) | |||
1724 | return r; | 2039 | return r; |
1725 | } | 2040 | } |
1726 | 2041 | ||
2042 | /** | ||
2043 | * amdgpu_device_detect_sriov_bios - determine if the board supports SR-IOV | ||
2044 | * | ||
2045 | * @adev: amdgpu_device pointer | ||
2046 | * | ||
2047 | * Query the VBIOS data tables to determine if the board supports SR-IOV. | ||
2048 | */ | ||
1727 | static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) | 2049 | static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) |
1728 | { | 2050 | { |
1729 | if (amdgpu_sriov_vf(adev)) { | 2051 | if (amdgpu_sriov_vf(adev)) { |
@@ -1740,6 +2062,14 @@ static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) | |||
1740 | } | 2062 | } |
1741 | } | 2063 | } |
1742 | 2064 | ||
2065 | /** | ||
2066 | * amdgpu_device_asic_has_dc_support - determine if DC supports the asic | ||
2067 | * | ||
2068 | * @asic_type: AMD asic type | ||
2069 | * | ||
2070 | * Check if there is DC (new modesetting infrastructre) support for an asic. | ||
2071 | * returns true if DC has support, false if not. | ||
2072 | */ | ||
1743 | bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) | 2073 | bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) |
1744 | { | 2074 | { |
1745 | switch (asic_type) { | 2075 | switch (asic_type) { |
@@ -2378,6 +2708,16 @@ unlock: | |||
2378 | return r; | 2708 | return r; |
2379 | } | 2709 | } |
2380 | 2710 | ||
2711 | /** | ||
2712 | * amdgpu_device_ip_check_soft_reset - did soft reset succeed | ||
2713 | * | ||
2714 | * @adev: amdgpu_device pointer | ||
2715 | * | ||
2716 | * The list of all the hardware IPs that make up the asic is walked and | ||
2717 | * the check_soft_reset callbacks are run. check_soft_reset determines | ||
2718 | * if the asic is still hung or not. | ||
2719 | * Returns true if any of the IPs are still in a hung state, false if not. | ||
2720 | */ | ||
2381 | static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev) | 2721 | static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev) |
2382 | { | 2722 | { |
2383 | int i; | 2723 | int i; |
@@ -2400,6 +2740,17 @@ static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev) | |||
2400 | return asic_hang; | 2740 | return asic_hang; |
2401 | } | 2741 | } |
2402 | 2742 | ||
2743 | /** | ||
2744 | * amdgpu_device_ip_pre_soft_reset - prepare for soft reset | ||
2745 | * | ||
2746 | * @adev: amdgpu_device pointer | ||
2747 | * | ||
2748 | * The list of all the hardware IPs that make up the asic is walked and the | ||
2749 | * pre_soft_reset callbacks are run if the block is hung. pre_soft_reset | ||
2750 | * handles any IP specific hardware or software state changes that are | ||
2751 | * necessary for a soft reset to succeed. | ||
2752 | * Returns 0 on success, negative error code on failure. | ||
2753 | */ | ||
2403 | static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev) | 2754 | static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev) |
2404 | { | 2755 | { |
2405 | int i, r = 0; | 2756 | int i, r = 0; |
@@ -2418,6 +2769,15 @@ static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev) | |||
2418 | return 0; | 2769 | return 0; |
2419 | } | 2770 | } |
2420 | 2771 | ||
2772 | /** | ||
2773 | * amdgpu_device_ip_need_full_reset - check if a full asic reset is needed | ||
2774 | * | ||
2775 | * @adev: amdgpu_device pointer | ||
2776 | * | ||
2777 | * Some hardware IPs cannot be soft reset. If they are hung, a full gpu | ||
2778 | * reset is necessary to recover. | ||
2779 | * Returns true if a full asic reset is required, false if not. | ||
2780 | */ | ||
2421 | static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev) | 2781 | static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev) |
2422 | { | 2782 | { |
2423 | int i; | 2783 | int i; |
@@ -2439,6 +2799,17 @@ static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev) | |||
2439 | return false; | 2799 | return false; |
2440 | } | 2800 | } |
2441 | 2801 | ||
2802 | /** | ||
2803 | * amdgpu_device_ip_soft_reset - do a soft reset | ||
2804 | * | ||
2805 | * @adev: amdgpu_device pointer | ||
2806 | * | ||
2807 | * The list of all the hardware IPs that make up the asic is walked and the | ||
2808 | * soft_reset callbacks are run if the block is hung. soft_reset handles any | ||
2809 | * IP specific hardware or software state changes that are necessary to soft | ||
2810 | * reset the IP. | ||
2811 | * Returns 0 on success, negative error code on failure. | ||
2812 | */ | ||
2442 | static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev) | 2813 | static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev) |
2443 | { | 2814 | { |
2444 | int i, r = 0; | 2815 | int i, r = 0; |
@@ -2457,6 +2828,17 @@ static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev) | |||
2457 | return 0; | 2828 | return 0; |
2458 | } | 2829 | } |
2459 | 2830 | ||
2831 | /** | ||
2832 | * amdgpu_device_ip_post_soft_reset - clean up from soft reset | ||
2833 | * | ||
2834 | * @adev: amdgpu_device pointer | ||
2835 | * | ||
2836 | * The list of all the hardware IPs that make up the asic is walked and the | ||
2837 | * post_soft_reset callbacks are run if the asic was hung. post_soft_reset | ||
2838 | * handles any IP specific hardware or software state changes that are | ||
2839 | * necessary after the IP has been soft reset. | ||
2840 | * Returns 0 on success, negative error code on failure. | ||
2841 | */ | ||
2460 | static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev) | 2842 | static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev) |
2461 | { | 2843 | { |
2462 | int i, r = 0; | 2844 | int i, r = 0; |
@@ -2474,6 +2856,19 @@ static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev) | |||
2474 | return 0; | 2856 | return 0; |
2475 | } | 2857 | } |
2476 | 2858 | ||
2859 | /** | ||
2860 | * amdgpu_device_recover_vram_from_shadow - restore shadowed VRAM buffers | ||
2861 | * | ||
2862 | * @adev: amdgpu_device pointer | ||
2863 | * @ring: amdgpu_ring for the engine handling the buffer operations | ||
2864 | * @bo: amdgpu_bo buffer whose shadow is being restored | ||
2865 | * @fence: dma_fence associated with the operation | ||
2866 | * | ||
2867 | * Restores the VRAM buffer contents from the shadow in GTT. Used to | ||
2868 | * restore things like GPUVM page tables after a GPU reset where | ||
2869 | * the contents of VRAM might be lost. | ||
2870 | * Returns 0 on success, negative error code on failure. | ||
2871 | */ | ||
2477 | static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev, | 2872 | static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev, |
2478 | struct amdgpu_ring *ring, | 2873 | struct amdgpu_ring *ring, |
2479 | struct amdgpu_bo *bo, | 2874 | struct amdgpu_bo *bo, |
@@ -2509,6 +2904,16 @@ err: | |||
2509 | return r; | 2904 | return r; |
2510 | } | 2905 | } |
2511 | 2906 | ||
2907 | /** | ||
2908 | * amdgpu_device_handle_vram_lost - Handle the loss of VRAM contents | ||
2909 | * | ||
2910 | * @adev: amdgpu_device pointer | ||
2911 | * | ||
2912 | * Restores the contents of VRAM buffers from the shadows in GTT. Used to | ||
2913 | * restore things like GPUVM page tables after a GPU reset where | ||
2914 | * the contents of VRAM might be lost. | ||
2915 | * Returns 0 on success, 1 on failure. | ||
2916 | */ | ||
2512 | static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev) | 2917 | static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev) |
2513 | { | 2918 | { |
2514 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; | 2919 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; |
@@ -2562,17 +2967,17 @@ static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev) | |||
2562 | else | 2967 | else |
2563 | DRM_ERROR("recover vram bo from shadow failed\n"); | 2968 | DRM_ERROR("recover vram bo from shadow failed\n"); |
2564 | 2969 | ||
2565 | return (r > 0?0:1); | 2970 | return (r > 0) ? 0 : 1; |
2566 | } | 2971 | } |
2567 | 2972 | ||
2568 | /* | 2973 | /** |
2569 | * amdgpu_device_reset - reset ASIC/GPU for bare-metal or passthrough | 2974 | * amdgpu_device_reset - reset ASIC/GPU for bare-metal or passthrough |
2570 | * | 2975 | * |
2571 | * @adev: amdgpu device pointer | 2976 | * @adev: amdgpu device pointer |
2572 | * | 2977 | * |
2573 | * attempt to do soft-reset or full-reset and reinitialize Asic | 2978 | * attempt to do soft-reset or full-reset and reinitialize Asic |
2574 | * return 0 means successed otherwise failed | 2979 | * return 0 means successed otherwise failed |
2575 | */ | 2980 | */ |
2576 | static int amdgpu_device_reset(struct amdgpu_device *adev) | 2981 | static int amdgpu_device_reset(struct amdgpu_device *adev) |
2577 | { | 2982 | { |
2578 | bool need_full_reset, vram_lost = 0; | 2983 | bool need_full_reset, vram_lost = 0; |
@@ -2642,15 +3047,16 @@ out: | |||
2642 | return r; | 3047 | return r; |
2643 | } | 3048 | } |
2644 | 3049 | ||
2645 | /* | 3050 | /** |
2646 | * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf | 3051 | * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf |
2647 | * | 3052 | * |
2648 | * @adev: amdgpu device pointer | 3053 | * @adev: amdgpu device pointer |
2649 | * | 3054 | * |
2650 | * do VF FLR and reinitialize Asic | 3055 | * do VF FLR and reinitialize Asic |
2651 | * return 0 means successed otherwise failed | 3056 | * return 0 means successed otherwise failed |
2652 | */ | 3057 | */ |
2653 | static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, bool from_hypervisor) | 3058 | static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, |
3059 | bool from_hypervisor) | ||
2654 | { | 3060 | { |
2655 | int r; | 3061 | int r; |
2656 | 3062 | ||
@@ -2790,6 +3196,15 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, | |||
2790 | return r; | 3196 | return r; |
2791 | } | 3197 | } |
2792 | 3198 | ||
3199 | /** | ||
3200 | * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot | ||
3201 | * | ||
3202 | * @adev: amdgpu_device pointer | ||
3203 | * | ||
3204 | * Fetchs and stores in the driver the PCIE capabilities (gen speed | ||
3205 | * and lanes) of the slot the device is in. Handles APUs and | ||
3206 | * virtualized environments where PCIE config space may not be available. | ||
3207 | */ | ||
2793 | static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) | 3208 | static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) |
2794 | { | 3209 | { |
2795 | u32 mask; | 3210 | u32 mask; |