aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch234
1 files changed, 234 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch
new file mode 100644
index 00000000..d4d629d8
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4673-drm-amdgpu-Dynamically-probe-for-ATIF-handle-v2.patch
@@ -0,0 +1,234 @@
+From d928e306d055f05452f92a6b9cf6987969cee6a6 Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Mon, 25 Jun 2018 21:09:07 -0400
+Subject: [PATCH 4673/5725] drm/amdgpu: Dynamically probe for ATIF handle (v2)
+
+The other day I was testing one of the HP laptops at my office with an
+i915/amdgpu hybrid setup and noticed that hotplugging was non-functional
+on almost all of the display outputs. I eventually discovered that all
+of the external outputs were connected to the amdgpu device instead of
+i915, and that the hotplugs weren't being detected so long as the GPU
+was in runtime suspend. After some talking with folks at AMD, I learned
+that amdgpu is actually supposed to support hotplug detection in runtime
+suspend so long as the OEM has implemented it properly in the firmware.
+
+On this HP ZBook 15 G4 (the machine in question), amdgpu wasn't managing
+to find the ATIF handle at all despite the fact that I could see acpi
+events being sent in response to any hotplugging. After going through
+dumps of the firmware, I discovered that this machine did in fact
+support ATIF, but that it's ATIF method lived in an entirely different
+namespace than this device's handle (the device handle was
+\_SB_.PCI0.PEG0.PEGP, but ATIF lives in ATPX's handle at
+\_SB_.PCI0.GFX0).
+
+So, fix this by probing ATPX's ACPI parent's namespace if we can't find
+ATIF elsewhere, along with storing a pointer to the proper handle to use
+for ATIF and using that instead of the device's handle.
+
+This fixes HPD detection while in runtime suspend for this ZBook!
+
+v2: Update the comment to reflect how the namespaces are arranged
+based on the system configuration. (Alex)
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 79 +++++++++++++++++++++++---------
+ 1 file 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 22c7e8e..0d8c3fc 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 {
+ };
+
+ struct amdgpu_atif {
++ acpi_handle handle;
++
+ struct amdgpu_atif_notifications notifications;
+ struct amdgpu_atif_functions functions;
+ struct amdgpu_atif_notification_cfg notification_cfg;
+@@ -83,8 +85,9 @@ struct amdgpu_atif {
+ * Executes the requested ATIF function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+-static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function,
+- struct acpi_buffer *params)
++static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
++ int function,
++ struct acpi_buffer *params)
+ {
+ acpi_status status;
+ union acpi_object atif_arg_elements[2];
+@@ -107,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function,
+ atif_arg_elements[1].integer.value = 0;
+ }
+
+- status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
++ status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
++ &buffer);
+
+ /* Fail only if calling the method fails and ATIF is supported */
+ 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
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+-static int amdgpu_atif_verify_interface(acpi_handle handle,
+- struct amdgpu_atif *atif)
++static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
+ {
+ union acpi_object *info;
+ struct atif_verify_interface output;
+ size_t size;
+ int err = 0;
+
+- info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
++ info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+@@ -213,6 +216,35 @@ static int amdgpu_atif_verify_interface(acpi_handle handle,
+ return err;
+ }
+
++static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle)
++{
++ acpi_handle handle = NULL;
++ char acpi_method_name[255] = { 0 };
++ struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
++ acpi_status status;
++
++ /* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only
++ * systems, ATIF is in the dGPU's namespace.
++ */
++ status = acpi_get_handle(dhandle, "ATIF", &handle);
++ if (ACPI_SUCCESS(status))
++ goto out;
++
++ if (amdgpu_has_atpx()) {
++ status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF",
++ &handle);
++ if (ACPI_SUCCESS(status))
++ goto out;
++ }
++
++ DRM_DEBUG_DRIVER("No ATIF handle found\n");
++ return NULL;
++out:
++ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
++ DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
++ return handle;
++}
++
+ /**
+ * amdgpu_atif_get_notification_params - determine notify configuration
+ *
+@@ -225,15 +257,16 @@ static int amdgpu_atif_verify_interface(acpi_handle handle,
+ * where n is specified in the result if a notifier is used.
+ * Returns 0 on success, error on failure.
+ */
+-static int amdgpu_atif_get_notification_params(acpi_handle handle,
+- struct amdgpu_atif_notification_cfg *n)
++static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
+ {
+ union acpi_object *info;
++ struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
+ struct atif_system_params params;
+ size_t size;
+ int err = 0;
+
+- info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
++ info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
++ NULL);
+ if (!info) {
+ err = -EIO;
+ goto out;
+@@ -287,14 +320,15 @@ static int amdgpu_atif_get_notification_params(acpi_handle handle,
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+-static int amdgpu_atif_get_sbios_requests(acpi_handle handle,
+- struct atif_sbios_requests *req)
++static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
++ struct atif_sbios_requests *req)
+ {
+ union acpi_object *info;
+ size_t size;
+ int count = 0;
+
+- info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
++ info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
++ NULL);
+ if (!info)
+ return -EIO;
+
+@@ -327,11 +361,10 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle,
+ * Returns NOTIFY code
+ */
+ static int amdgpu_atif_handler(struct amdgpu_device *adev,
+- struct acpi_bus_event *event)
++ struct acpi_bus_event *event)
+ {
+ struct amdgpu_atif *atif = adev->atif;
+ struct atif_sbios_requests req;
+- acpi_handle handle;
+ int count;
+
+ DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
+@@ -347,8 +380,7 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
+ return NOTIFY_DONE;
+
+ /* Check pending SBIOS requests */
+- handle = ACPI_HANDLE(&adev->pdev->dev);
+- count = amdgpu_atif_get_sbios_requests(handle, &req);
++ count = amdgpu_atif_get_sbios_requests(atif, &req);
+
+ if (count <= 0)
+ return NOTIFY_DONE;
+@@ -679,7 +711,7 @@ static int amdgpu_acpi_event(struct notifier_block *nb,
+ */
+ int amdgpu_acpi_init(struct amdgpu_device *adev)
+ {
+- acpi_handle handle;
++ acpi_handle handle, atif_handle;
+ struct amdgpu_atif *atif;
+ struct amdgpu_atcs *atcs = &adev->atcs;
+ int ret;
+@@ -696,14 +728,20 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
+ DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
+ }
+
+- /* Call the ATIF method */
++ /* Probe for ATIF, and initialize it if found */
++ atif_handle = amdgpu_atif_probe_handle(handle);
++ if (!atif_handle)
++ goto out;
++
+ atif = kzalloc(sizeof(*atif), GFP_KERNEL);
+ if (!atif) {
+ DRM_WARN("Not enough memory to initialize ATIF\n");
+ goto out;
+ }
++ atif->handle = atif_handle;
+
+- ret = amdgpu_atif_verify_interface(handle, atif);
++ /* Call the ATIF method */
++ ret = amdgpu_atif_verify_interface(atif);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
+ kfree(atif);
+@@ -739,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
+ }
+
+ if (atif->functions.system_params) {
+- ret = amdgpu_atif_get_notification_params(handle,
+- &atif->notification_cfg);
++ ret = amdgpu_atif_get_notification_params(atif);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
+ ret);
+--
+2.7.4
+