struct amdgpu_dm_backlight_caps backlight_caps;
 };
 
+struct amdgpu_atcs_functions {
+       bool get_ext_state;
+       bool pcie_perf_req;
+       bool pcie_dev_rdy;
+       bool pcie_bus_width;
+};
+
+struct amdgpu_atcs {
+       acpi_handle handle;
+
+       struct amdgpu_atcs_functions functions;
+};
+
 /* Call the ATIF method
  */
 /**
  * amdgpu_atif_call - call an ATIF method
  *
- * @atif: acpi handle
+ * @atif: atif structure
  * @function: the ATIF function to execute
  * @params: ATIF function params
  *
        return handle;
 }
 
+static acpi_handle amdgpu_atcs_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, ATCS and ATPX are in the iGPU's namespace, on dGPU only
+        * systems, ATIF is in the dGPU's namespace.
+        */
+       status = acpi_get_handle(dhandle, "ATCS", &handle);
+       if (ACPI_SUCCESS(status))
+               goto out;
+
+       if (amdgpu_has_atpx()) {
+               status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATCS",
+                                        &handle);
+               if (ACPI_SUCCESS(status))
+                       goto out;
+       }
+
+       DRM_DEBUG_DRIVER("No ATCS handle found\n");
+       return NULL;
+out:
+       acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+       DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name);
+       return handle;
+}
+
 /**
  * amdgpu_atif_get_notification_params - determine notify configuration
  *
 /**
  * amdgpu_atcs_call - call an ATCS method
  *
- * @handle: acpi handle
+ * @atcs: atcs structure
  * @function: the ATCS function to execute
  * @params: ATCS function params
  *
  * Executes the requested ATCS function (all asics).
  * Returns a pointer to the acpi output buffer.
  */
-static union acpi_object *amdgpu_atcs_call(acpi_handle handle, int function,
+static union acpi_object *amdgpu_atcs_call(struct amdgpu_atcs *atcs,
+                                          int function,
                                           struct acpi_buffer *params)
 {
        acpi_status status;
                atcs_arg_elements[1].integer.value = 0;
        }
 
-       status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
+       status = acpi_evaluate_object(atcs->handle, "ATCS", &atcs_arg, &buffer);
 
        /* Fail only if calling the method fails and ATIF is supported */
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 /**
  * amdgpu_atcs_verify_interface - verify ATCS
  *
- * @handle: acpi handle
  * @atcs: amdgpu atcs struct
  *
  * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
  * (all asics).
  * returns 0 on success, error on failure.
  */
-static int amdgpu_atcs_verify_interface(acpi_handle handle,
-                                       struct amdgpu_atcs *atcs)
+static int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs)
 {
        union acpi_object *info;
        struct atcs_verify_interface output;
        size_t size;
        int err = 0;
 
-       info = amdgpu_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
+       info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
        if (!info)
                return -EIO;
 
  */
 bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
 {
-       struct amdgpu_atcs *atcs = &adev->atcs;
+       struct amdgpu_atcs *atcs = adev->atcs;
 
+       if (!atcs)
+               return false;
        if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
                return true;
 
  */
 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
 {
-       acpi_handle handle;
        union acpi_object *info;
-       struct amdgpu_atcs *atcs = &adev->atcs;
+       struct amdgpu_atcs *atcs = adev->atcs;
 
-       /* Get the device handle */
-       handle = ACPI_HANDLE(&adev->pdev->dev);
-       if (!handle)
+       if (!atcs)
                return -EINVAL;
-
        if (!atcs->functions.pcie_dev_rdy)
                return -EINVAL;
 
-       info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
+       info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
        if (!info)
                return -EIO;
 
 int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
                                         u8 perf_req, bool advertise)
 {
-       acpi_handle handle;
        union acpi_object *info;
-       struct amdgpu_atcs *atcs = &adev->atcs;
+       struct amdgpu_atcs *atcs = adev->atcs;
        struct atcs_pref_req_input atcs_input;
        struct atcs_pref_req_output atcs_output;
        struct acpi_buffer params;
        size_t size;
        u32 retry = 3;
 
-       if (amdgpu_acpi_pcie_notify_device_ready(adev))
+       if (!atcs)
                return -EINVAL;
 
-       /* Get the device handle */
-       handle = ACPI_HANDLE(&adev->pdev->dev);
-       if (!handle)
+       if (amdgpu_acpi_pcie_notify_device_ready(adev))
                return -EINVAL;
 
        if (!atcs->functions.pcie_perf_req)
        params.pointer = &atcs_input;
 
        while (retry--) {
-               info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms);
+               info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms);
                if (!info)
                        return -EIO;
 
  */
 int amdgpu_acpi_init(struct amdgpu_device *adev)
 {
-       acpi_handle handle, atif_handle;
+       acpi_handle handle, atif_handle, atcs_handle;
        struct amdgpu_atif *atif;
-       struct amdgpu_atcs *atcs = &adev->atcs;
-       int ret;
+       struct amdgpu_atcs *atcs;
+       int ret = 0;
 
        /* Get the device handle */
        handle = ACPI_HANDLE(&adev->pdev->dev);
 
        if (!adev->bios || !handle)
-               return 0;
-
-       /* Call the ATCS method */
-       ret = amdgpu_atcs_verify_interface(handle, atcs);
-       if (ret) {
-               DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
-       }
+               return ret;
 
        /* Probe for ATIF, and initialize it if found */
        atif_handle = amdgpu_atif_probe_handle(handle);
        if (!atif_handle)
-               goto out;
+               goto atcs;
 
        atif = kzalloc(sizeof(*atif), GFP_KERNEL);
        if (!atif) {
                DRM_WARN("Not enough memory to initialize ATIF\n");
-               goto out;
+               goto atcs;
        }
        atif->handle = atif_handle;
 
        if (ret) {
                DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
                kfree(atif);
-               goto out;
+               goto atcs;
        }
        adev->atif = atif;
 
                if (amdgpu_device_has_dc_support(adev)) {
 #if defined(CONFIG_DRM_AMD_DC)
                        struct amdgpu_display_manager *dm = &adev->dm;
-                       atif->bd = dm->backlight_dev;
+                       if (dm->backlight_dev)
+                               atif->bd = dm->backlight_dev;
 #endif
                } else {
                        struct drm_encoder *tmp;
                atif->backlight_caps.caps_valid = false;
        }
 
+atcs:
+       /* Probe for ATCS, and initialize it if found */
+       atcs_handle = amdgpu_atcs_probe_handle(handle);
+       if (!atcs_handle)
+               goto out;
+
+       atcs = kzalloc(sizeof(*atcs), GFP_KERNEL);
+       if (!atcs) {
+               DRM_WARN("Not enough memory to initialize ATCS\n");
+               goto out;
+       }
+       atcs->handle = atcs_handle;
+
+       /* Call the ATCS method */
+       ret = amdgpu_atcs_verify_interface(atcs);
+       if (ret) {
+               DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
+               kfree(atcs);
+               goto out;
+       }
+       adev->atcs = atcs;
+
 out:
        adev->acpi_nb.notifier_call = amdgpu_acpi_event;
        register_acpi_notifier(&adev->acpi_nb);
 {
        unregister_acpi_notifier(&adev->acpi_nb);
        kfree(adev->atif);
+       kfree(adev->atcs);
 }
 
 /**