diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 79 |
1 files changed, 58 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 22c7e8ec0b9a..0d8c3fc6eace 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | |||
@@ -65,6 +65,8 @@ struct amdgpu_atif_functions { | |||
65 | }; | 65 | }; |
66 | 66 | ||
67 | struct amdgpu_atif { | 67 | struct amdgpu_atif { |
68 | acpi_handle handle; | ||
69 | |||
68 | struct amdgpu_atif_notifications notifications; | 70 | struct amdgpu_atif_notifications notifications; |
69 | struct amdgpu_atif_functions functions; | 71 | struct amdgpu_atif_functions functions; |
70 | struct amdgpu_atif_notification_cfg notification_cfg; | 72 | struct amdgpu_atif_notification_cfg notification_cfg; |
@@ -83,8 +85,9 @@ struct amdgpu_atif { | |||
83 | * Executes the requested ATIF function (all asics). | 85 | * Executes the requested ATIF function (all asics). |
84 | * Returns a pointer to the acpi output buffer. | 86 | * Returns a pointer to the acpi output buffer. |
85 | */ | 87 | */ |
86 | static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, | 88 | static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif, |
87 | struct acpi_buffer *params) | 89 | int function, |
90 | struct acpi_buffer *params) | ||
88 | { | 91 | { |
89 | acpi_status status; | 92 | acpi_status status; |
90 | union acpi_object atif_arg_elements[2]; | 93 | union acpi_object atif_arg_elements[2]; |
@@ -107,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, | |||
107 | atif_arg_elements[1].integer.value = 0; | 110 | atif_arg_elements[1].integer.value = 0; |
108 | } | 111 | } |
109 | 112 | ||
110 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); | 113 | status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, |
114 | &buffer); | ||
111 | 115 | ||
112 | /* Fail only if calling the method fails and ATIF is supported */ | 116 | /* Fail only if calling the method fails and ATIF is supported */ |
113 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 117 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
@@ -178,15 +182,14 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas | |||
178 | * (all asics). | 182 | * (all asics). |
179 | * returns 0 on success, error on failure. | 183 | * returns 0 on success, error on failure. |
180 | */ | 184 | */ |
181 | static int amdgpu_atif_verify_interface(acpi_handle handle, | 185 | static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif) |
182 | struct amdgpu_atif *atif) | ||
183 | { | 186 | { |
184 | union acpi_object *info; | 187 | union acpi_object *info; |
185 | struct atif_verify_interface output; | 188 | struct atif_verify_interface output; |
186 | size_t size; | 189 | size_t size; |
187 | int err = 0; | 190 | int err = 0; |
188 | 191 | ||
189 | info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); | 192 | info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); |
190 | if (!info) | 193 | if (!info) |
191 | return -EIO; | 194 | return -EIO; |
192 | 195 | ||
@@ -213,6 +216,35 @@ out: | |||
213 | return err; | 216 | return err; |
214 | } | 217 | } |
215 | 218 | ||
219 | static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle) | ||
220 | { | ||
221 | acpi_handle handle = NULL; | ||
222 | char acpi_method_name[255] = { 0 }; | ||
223 | struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name }; | ||
224 | acpi_status status; | ||
225 | |||
226 | /* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only | ||
227 | * systems, ATIF is in the dGPU's namespace. | ||
228 | */ | ||
229 | status = acpi_get_handle(dhandle, "ATIF", &handle); | ||
230 | if (ACPI_SUCCESS(status)) | ||
231 | goto out; | ||
232 | |||
233 | if (amdgpu_has_atpx()) { | ||
234 | status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF", | ||
235 | &handle); | ||
236 | if (ACPI_SUCCESS(status)) | ||
237 | goto out; | ||
238 | } | ||
239 | |||
240 | DRM_DEBUG_DRIVER("No ATIF handle found\n"); | ||
241 | return NULL; | ||
242 | out: | ||
243 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
244 | DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name); | ||
245 | return handle; | ||
246 | } | ||
247 | |||
216 | /** | 248 | /** |
217 | * amdgpu_atif_get_notification_params - determine notify configuration | 249 | * amdgpu_atif_get_notification_params - determine notify configuration |
218 | * | 250 | * |
@@ -225,15 +257,16 @@ out: | |||
225 | * where n is specified in the result if a notifier is used. | 257 | * where n is specified in the result if a notifier is used. |
226 | * Returns 0 on success, error on failure. | 258 | * Returns 0 on success, error on failure. |
227 | */ | 259 | */ |
228 | static int amdgpu_atif_get_notification_params(acpi_handle handle, | 260 | static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif) |
229 | struct amdgpu_atif_notification_cfg *n) | ||
230 | { | 261 | { |
231 | union acpi_object *info; | 262 | union acpi_object *info; |
263 | struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg; | ||
232 | struct atif_system_params params; | 264 | struct atif_system_params params; |
233 | size_t size; | 265 | size_t size; |
234 | int err = 0; | 266 | int err = 0; |
235 | 267 | ||
236 | info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); | 268 | info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, |
269 | NULL); | ||
237 | if (!info) { | 270 | if (!info) { |
238 | err = -EIO; | 271 | err = -EIO; |
239 | goto out; | 272 | goto out; |
@@ -287,14 +320,15 @@ out: | |||
287 | * (all asics). | 320 | * (all asics). |
288 | * Returns 0 on success, error on failure. | 321 | * Returns 0 on success, error on failure. |
289 | */ | 322 | */ |
290 | static int amdgpu_atif_get_sbios_requests(acpi_handle handle, | 323 | static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif, |
291 | struct atif_sbios_requests *req) | 324 | struct atif_sbios_requests *req) |
292 | { | 325 | { |
293 | union acpi_object *info; | 326 | union acpi_object *info; |
294 | size_t size; | 327 | size_t size; |
295 | int count = 0; | 328 | int count = 0; |
296 | 329 | ||
297 | info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); | 330 | info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, |
331 | NULL); | ||
298 | if (!info) | 332 | if (!info) |
299 | return -EIO; | 333 | return -EIO; |
300 | 334 | ||
@@ -327,11 +361,10 @@ out: | |||
327 | * Returns NOTIFY code | 361 | * Returns NOTIFY code |
328 | */ | 362 | */ |
329 | static int amdgpu_atif_handler(struct amdgpu_device *adev, | 363 | static int amdgpu_atif_handler(struct amdgpu_device *adev, |
330 | struct acpi_bus_event *event) | 364 | struct acpi_bus_event *event) |
331 | { | 365 | { |
332 | struct amdgpu_atif *atif = adev->atif; | 366 | struct amdgpu_atif *atif = adev->atif; |
333 | struct atif_sbios_requests req; | 367 | struct atif_sbios_requests req; |
334 | acpi_handle handle; | ||
335 | int count; | 368 | int count; |
336 | 369 | ||
337 | DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", | 370 | DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", |
@@ -347,8 +380,7 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, | |||
347 | return NOTIFY_DONE; | 380 | return NOTIFY_DONE; |
348 | 381 | ||
349 | /* Check pending SBIOS requests */ | 382 | /* Check pending SBIOS requests */ |
350 | handle = ACPI_HANDLE(&adev->pdev->dev); | 383 | count = amdgpu_atif_get_sbios_requests(atif, &req); |
351 | count = amdgpu_atif_get_sbios_requests(handle, &req); | ||
352 | 384 | ||
353 | if (count <= 0) | 385 | if (count <= 0) |
354 | return NOTIFY_DONE; | 386 | return NOTIFY_DONE; |
@@ -679,7 +711,7 @@ static int amdgpu_acpi_event(struct notifier_block *nb, | |||
679 | */ | 711 | */ |
680 | int amdgpu_acpi_init(struct amdgpu_device *adev) | 712 | int amdgpu_acpi_init(struct amdgpu_device *adev) |
681 | { | 713 | { |
682 | acpi_handle handle; | 714 | acpi_handle handle, atif_handle; |
683 | struct amdgpu_atif *atif; | 715 | struct amdgpu_atif *atif; |
684 | struct amdgpu_atcs *atcs = &adev->atcs; | 716 | struct amdgpu_atcs *atcs = &adev->atcs; |
685 | int ret; | 717 | int ret; |
@@ -696,14 +728,20 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) | |||
696 | DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); | 728 | DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); |
697 | } | 729 | } |
698 | 730 | ||
699 | /* Call the ATIF method */ | 731 | /* Probe for ATIF, and initialize it if found */ |
732 | atif_handle = amdgpu_atif_probe_handle(handle); | ||
733 | if (!atif_handle) | ||
734 | goto out; | ||
735 | |||
700 | atif = kzalloc(sizeof(*atif), GFP_KERNEL); | 736 | atif = kzalloc(sizeof(*atif), GFP_KERNEL); |
701 | if (!atif) { | 737 | if (!atif) { |
702 | DRM_WARN("Not enough memory to initialize ATIF\n"); | 738 | DRM_WARN("Not enough memory to initialize ATIF\n"); |
703 | goto out; | 739 | goto out; |
704 | } | 740 | } |
741 | atif->handle = atif_handle; | ||
705 | 742 | ||
706 | ret = amdgpu_atif_verify_interface(handle, atif); | 743 | /* Call the ATIF method */ |
744 | ret = amdgpu_atif_verify_interface(atif); | ||
707 | if (ret) { | 745 | if (ret) { |
708 | DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); | 746 | DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); |
709 | kfree(atif); | 747 | kfree(atif); |
@@ -739,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) | |||
739 | } | 777 | } |
740 | 778 | ||
741 | if (atif->functions.system_params) { | 779 | if (atif->functions.system_params) { |
742 | ret = amdgpu_atif_get_notification_params(handle, | 780 | ret = amdgpu_atif_get_notification_params(atif); |
743 | &atif->notification_cfg); | ||
744 | if (ret) { | 781 | if (ret) { |
745 | DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", | 782 | DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", |
746 | ret); | 783 | ret); |