// SPDX-License-Identifier: MIT
/*
 * Copyright 2012 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/backlight.h>
#include <linux/slab.h>
#include <linux/xarray.h>
#include <linux/power_supply.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <acpi/video.h>
#include <acpi/actbl.h>

#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "amdgpu_display.h"
#include "amd_acpi.h"
#include "atom.h"

/* Declare GUID for AMD _DSM method for XCCs */
static const guid_t amd_xcc_dsm_guid = GUID_INIT(0x8267f5d5, 0xa556, 0x44f2,
						 0xb8, 0xb4, 0x45, 0x56, 0x2e,
						 0x8c, 0x5b, 0xec);

#define AMD_XCC_HID_START 3000
#define AMD_XCC_DSM_GET_NUM_FUNCS 0
#define AMD_XCC_DSM_GET_SUPP_MODE 1
#define AMD_XCC_DSM_GET_XCP_MODE 2
#define AMD_XCC_DSM_GET_VF_XCC_MAPPING 4
#define AMD_XCC_DSM_GET_TMR_INFO 5
#define AMD_XCC_DSM_NUM_FUNCS 5

#define AMD_XCC_MAX_HID 24

struct xarray numa_info_xa;

/* Encapsulates the XCD acpi object information */
struct amdgpu_acpi_xcc_info {
	struct list_head list;
	struct amdgpu_numa_info *numa_info;
	uint8_t xcp_node;
	uint8_t phy_id;
	acpi_handle handle;
};

struct amdgpu_acpi_dev_info {
	struct list_head list;
	struct list_head xcc_list;
	uint32_t sbdf;
	uint16_t supp_xcp_mode;
	uint16_t xcp_mode;
	uint16_t mem_mode;
	uint64_t tmr_base;
	uint64_t tmr_size;
};

struct list_head amdgpu_acpi_dev_list;

struct amdgpu_atif_notification_cfg {
	bool enabled;
	int command_code;
};

struct amdgpu_atif_notifications {
	bool thermal_state;
	bool forced_power_state;
	bool system_power_state;
	bool brightness_change;
	bool dgpu_display_event;
	bool gpu_package_power_limit;
};

struct amdgpu_atif_functions {
	bool system_params;
	bool sbios_requests;
	bool temperature_change;
	bool query_backlight_transfer_characteristics;
	bool ready_to_undock;
	bool external_gpu_information;
};

struct amdgpu_atif {
	acpi_handle handle;

	struct amdgpu_atif_notifications notifications;
	struct amdgpu_atif_functions functions;
	struct amdgpu_atif_notification_cfg notification_cfg;
	struct backlight_device *bd;
	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;
	bool power_shift_control;
};

struct amdgpu_atcs {
	acpi_handle handle;

	struct amdgpu_atcs_functions functions;
};

static struct amdgpu_acpi_priv {
	struct amdgpu_atif atif;
	struct amdgpu_atcs atcs;
} amdgpu_acpi_priv;

/* Call the ATIF method
 */
/**
 * amdgpu_atif_call - call an ATIF method
 *
 * @atif: atif structure
 * @function: the ATIF function to execute
 * @params: ATIF function params
 *
 * Executes the requested ATIF function (all asics).
 * Returns a pointer to the acpi output buffer.
 */
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];
	struct acpi_object_list atif_arg;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	atif_arg.count = 2;
	atif_arg.pointer = &atif_arg_elements[0];

	atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
	atif_arg_elements[0].integer.value = function;

	if (params) {
		atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
		atif_arg_elements[1].buffer.length = params->length;
		atif_arg_elements[1].buffer.pointer = params->pointer;
	} else {
		/* We need a second fake parameter */
		atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
		atif_arg_elements[1].integer.value = 0;
	}

	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) {
		DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
				 acpi_format_exception(status));
		kfree(buffer.pointer);
		return NULL;
	}

	return buffer.pointer;
}

/**
 * amdgpu_atif_parse_notification - parse supported notifications
 *
 * @n: supported notifications struct
 * @mask: supported notifications mask from ATIF
 *
 * Use the supported notifications mask from ATIF function
 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
 * are supported (all asics).
 */
static void amdgpu_atif_parse_notification(struct amdgpu_atif_notifications *n, u32 mask)
{
	n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
	n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
	n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
	n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
	n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
	n->gpu_package_power_limit = mask & ATIF_GPU_PACKAGE_POWER_LIMIT_REQUEST_SUPPORTED;
}

/**
 * amdgpu_atif_parse_functions - parse supported functions
 *
 * @f: supported functions struct
 * @mask: supported functions mask from ATIF
 *
 * Use the supported functions mask from ATIF function
 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
 * are supported (all asics).
 */
static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mask)
{
	f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
	f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
	f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
	f->query_backlight_transfer_characteristics =
		mask & ATIF_QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS_SUPPORTED;
	f->ready_to_undock = mask & ATIF_READY_TO_UNDOCK_NOTIFICATION_SUPPORTED;
	f->external_gpu_information = mask & ATIF_GET_EXTERNAL_GPU_INFORMATION_SUPPORTED;
}

/**
 * amdgpu_atif_verify_interface - verify ATIF
 *
 * @atif: amdgpu atif struct
 *
 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
 * to initialize ATIF and determine what features are supported
 * (all asics).
 * returns 0 on success, error on failure.
 */
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(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
	if (!info)
		return -EIO;

	memset(&output, 0, sizeof(output));

	size = *(u16 *) info->buffer.pointer;
	if (size < 12) {
		DRM_INFO("ATIF buffer is too small: %zu\n", size);
		err = -EINVAL;
		goto out;
	}
	size = min(sizeof(output), size);

	memcpy(&output, info->buffer.pointer, size);

	/* TODO: check version? */
	DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);

	amdgpu_atif_parse_notification(&atif->notifications, output.notification_mask);
	amdgpu_atif_parse_functions(&atif->functions, output.function_bits);

out:
	kfree(info);
	return err;
}

/**
 * amdgpu_atif_get_notification_params - determine notify configuration
 *
 * @atif: acpi handle
 *
 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
 * to determine if a notifier is used and if so which one
 * (all asics).  This is either Notify(VGA, 0x81) or Notify(VGA, n)
 * 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(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(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
				NULL);
	if (!info) {
		err = -EIO;
		goto out;
	}

	size = *(u16 *) info->buffer.pointer;
	if (size < 10) {
		err = -EINVAL;
		goto out;
	}

	memset(&params, 0, sizeof(params));
	size = min(sizeof(params), size);
	memcpy(&params, info->buffer.pointer, size);

	DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
			params.flags, params.valid_mask);
	params.flags = params.flags & params.valid_mask;

	if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
		n->enabled = false;
		n->command_code = 0;
	} else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
		n->enabled = true;
		n->command_code = 0x81;
	} else {
		if (size < 11) {
			err = -EINVAL;
			goto out;
		}
		n->enabled = true;
		n->command_code = params.command_code;
	}

out:
	DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
			(n->enabled ? "enabled" : "disabled"),
			n->command_code);
	kfree(info);
	return err;
}

/**
 * amdgpu_atif_query_backlight_caps - get min and max backlight input signal
 *
 * @atif: acpi handle
 *
 * Execute the QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS ATIF function
 * to determine the acceptable range of backlight values
 *
 * Backlight_caps.caps_valid will be set to true if the query is successful
 *
 * The input signals are in range 0-255
 *
 * This function assumes the display with backlight is the first LCD
 *
 * Returns 0 on success, error on failure.
 */
static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
{
	union acpi_object *info;
	struct atif_qbtc_output characteristics;
	struct atif_qbtc_arguments arguments;
	struct acpi_buffer params;
	size_t size;
	int err = 0;

	arguments.size = sizeof(arguments);
	arguments.requested_display = ATIF_QBTC_REQUEST_LCD1;

	params.length = sizeof(arguments);
	params.pointer = (void *)&arguments;

	info = amdgpu_atif_call(atif,
		ATIF_FUNCTION_QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS,
		&params);
	if (!info) {
		err = -EIO;
		goto out;
	}

	size = *(u16 *) info->buffer.pointer;
	if (size < 10) {
		err = -EINVAL;
		goto out;
	}

	memset(&characteristics, 0, sizeof(characteristics));
	size = min(sizeof(characteristics), size);
	memcpy(&characteristics, info->buffer.pointer, size);

	atif->backlight_caps.caps_valid = true;
	atif->backlight_caps.min_input_signal =
			characteristics.min_input_signal;
	atif->backlight_caps.max_input_signal =
			characteristics.max_input_signal;
out:
	kfree(info);
	return err;
}

/**
 * amdgpu_atif_get_sbios_requests - get requested sbios event
 *
 * @atif: acpi handle
 * @req: atif sbios request struct
 *
 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
 * to determine what requests the sbios is making to the driver
 * (all asics).
 * Returns 0 on success, error on failure.
 */
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(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
				NULL);
	if (!info)
		return -EIO;

	size = *(u16 *)info->buffer.pointer;
	if (size < 0xd) {
		count = -EINVAL;
		goto out;
	}
	memset(req, 0, sizeof(*req));

	size = min(sizeof(*req), size);
	memcpy(req, info->buffer.pointer, size);
	DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);

	count = hweight32(req->pending);

out:
	kfree(info);
	return count;
}

/**
 * amdgpu_atif_handler - handle ATIF notify requests
 *
 * @adev: amdgpu_device pointer
 * @event: atif sbios request struct
 *
 * Checks the acpi event and if it matches an atif event,
 * handles it.
 *
 * Returns:
 * NOTIFY_BAD or NOTIFY_DONE, depending on the event.
 */
static int amdgpu_atif_handler(struct amdgpu_device *adev,
			       struct acpi_bus_event *event)
{
	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
	int count;

	DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
			event->device_class, event->type);

	if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
		return NOTIFY_DONE;

	/* Is this actually our event? */
	if (!atif->notification_cfg.enabled ||
	    event->type != atif->notification_cfg.command_code) {
		/* These events will generate keypresses otherwise */
		if (event->type == ACPI_VIDEO_NOTIFY_PROBE)
			return NOTIFY_BAD;
		else
			return NOTIFY_DONE;
	}

	if (atif->functions.sbios_requests) {
		struct atif_sbios_requests req;

		/* Check pending SBIOS requests */
		count = amdgpu_atif_get_sbios_requests(atif, &req);

		if (count <= 0)
			return NOTIFY_BAD;

		DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);

		if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
			if (atif->bd) {
				DRM_DEBUG_DRIVER("Changing brightness to %d\n",
						 req.backlight_level);
				/*
				 * XXX backlight_device_set_brightness() is
				 * hardwired to post BACKLIGHT_UPDATE_SYSFS.
				 * It probably should accept 'reason' parameter.
				 */
				backlight_device_set_brightness(atif->bd, req.backlight_level);
			}
		}

		if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
			if (adev->flags & AMD_IS_PX) {
				pm_runtime_get_sync(adev_to_drm(adev)->dev);
				/* Just fire off a uevent and let userspace tell us what to do */
				drm_helper_hpd_irq_event(adev_to_drm(adev));
				pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
				pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
			}
		}
		/* TODO: check other events */
	}

	/* We've handled the event, stop the notifier chain. The ACPI interface
	 * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
	 * userspace if the event was generated only to signal a SBIOS
	 * request.
	 */
	return NOTIFY_BAD;
}

/* Call the ATCS method
 */
/**
 * amdgpu_atcs_call - call an ATCS method
 *
 * @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(struct amdgpu_atcs *atcs,
					   int function,
					   struct acpi_buffer *params)
{
	acpi_status status;
	union acpi_object atcs_arg_elements[2];
	struct acpi_object_list atcs_arg;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	atcs_arg.count = 2;
	atcs_arg.pointer = &atcs_arg_elements[0];

	atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
	atcs_arg_elements[0].integer.value = function;

	if (params) {
		atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
		atcs_arg_elements[1].buffer.length = params->length;
		atcs_arg_elements[1].buffer.pointer = params->pointer;
	} else {
		/* We need a second fake parameter */
		atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
		atcs_arg_elements[1].integer.value = 0;
	}

	status = acpi_evaluate_object(atcs->handle, NULL, &atcs_arg, &buffer);

	/* Fail only if calling the method fails and ATIF is supported */
	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
		DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
				 acpi_format_exception(status));
		kfree(buffer.pointer);
		return NULL;
	}

	return buffer.pointer;
}

/**
 * amdgpu_atcs_parse_functions - parse supported functions
 *
 * @f: supported functions struct
 * @mask: supported functions mask from ATCS
 *
 * Use the supported functions mask from ATCS function
 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
 * are supported (all asics).
 */
static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mask)
{
	f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
	f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
	f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
	f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
	f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED;
}

/**
 * amdgpu_atcs_verify_interface - verify ATCS
 *
 * @atcs: amdgpu atcs struct
 *
 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
 * to initialize ATCS and determine what features are supported
 * (all asics).
 * returns 0 on success, error on failure.
 */
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(atcs, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
	if (!info)
		return -EIO;

	memset(&output, 0, sizeof(output));

	size = *(u16 *) info->buffer.pointer;
	if (size < 8) {
		DRM_INFO("ATCS buffer is too small: %zu\n", size);
		err = -EINVAL;
		goto out;
	}
	size = min(sizeof(output), size);

	memcpy(&output, info->buffer.pointer, size);

	/* TODO: check version? */
	DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);

	amdgpu_atcs_parse_functions(&atcs->functions, output.function_bits);

out:
	kfree(info);
	return err;
}

/**
 * amdgpu_acpi_is_pcie_performance_request_supported
 *
 * @adev: amdgpu_device pointer
 *
 * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
 * are supported (all asics).
 * returns true if supported, false if not.
 */
bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
{
	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;

	if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
		return true;

	return false;
}

/**
 * amdgpu_acpi_is_power_shift_control_supported
 *
 * Check if the ATCS power shift control method
 * is supported.
 * returns true if supported, false if not.
 */
bool amdgpu_acpi_is_power_shift_control_supported(void)
{
	return amdgpu_acpi_priv.atcs.functions.power_shift_control;
}

/**
 * amdgpu_acpi_pcie_notify_device_ready
 *
 * @adev: amdgpu_device pointer
 *
 * Executes the PCIE_DEVICE_READY_NOTIFICATION method
 * (all asics).
 * returns 0 on success, error on failure.
 */
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
{
	union acpi_object *info;
	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;

	if (!atcs->functions.pcie_dev_rdy)
		return -EINVAL;

	info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
	if (!info)
		return -EIO;

	kfree(info);

	return 0;
}

/**
 * amdgpu_acpi_pcie_performance_request
 *
 * @adev: amdgpu_device pointer
 * @perf_req: requested perf level (pcie gen speed)
 * @advertise: set advertise caps flag if set
 *
 * Executes the PCIE_PERFORMANCE_REQUEST method to
 * change the pcie gen speed (all asics).
 * returns 0 on success, error on failure.
 */
int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
					 u8 perf_req, bool advertise)
{
	union acpi_object *info;
	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.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))
		return -EINVAL;

	if (!atcs->functions.pcie_perf_req)
		return -EINVAL;

	atcs_input.size = sizeof(struct atcs_pref_req_input);
	/* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
	atcs_input.client_id = pci_dev_id(adev->pdev);
	atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
	atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
	if (advertise)
		atcs_input.flags |= ATCS_ADVERTISE_CAPS;
	atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
	atcs_input.perf_req = perf_req;

	params.length = sizeof(struct atcs_pref_req_input);
	params.pointer = &atcs_input;

	while (retry--) {
		info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
		if (!info)
			return -EIO;

		memset(&atcs_output, 0, sizeof(atcs_output));

		size = *(u16 *) info->buffer.pointer;
		if (size < 3) {
			DRM_INFO("ATCS buffer is too small: %zu\n", size);
			kfree(info);
			return -EINVAL;
		}
		size = min(sizeof(atcs_output), size);

		memcpy(&atcs_output, info->buffer.pointer, size);

		kfree(info);

		switch (atcs_output.ret_val) {
		case ATCS_REQUEST_REFUSED:
		default:
			return -EINVAL;
		case ATCS_REQUEST_COMPLETE:
			return 0;
		case ATCS_REQUEST_IN_PROGRESS:
			udelay(10);
			break;
		}
	}

	return 0;
}

/**
 * amdgpu_acpi_power_shift_control
 *
 * @adev: amdgpu_device pointer
 * @dev_state: device acpi state
 * @drv_state: driver state
 *
 * Executes the POWER_SHIFT_CONTROL method to
 * communicate current dGPU device state and
 * driver state to APU/SBIOS.
 * returns 0 on success, error on failure.
 */
int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
				    u8 dev_state, bool drv_state)
{
	union acpi_object *info;
	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
	struct atcs_pwr_shift_input atcs_input;
	struct acpi_buffer params;

	if (!amdgpu_acpi_is_power_shift_control_supported())
		return -EINVAL;

	atcs_input.size = sizeof(struct atcs_pwr_shift_input);
	/* dGPU id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
	atcs_input.dgpu_id = pci_dev_id(adev->pdev);
	atcs_input.dev_acpi_state = dev_state;
	atcs_input.drv_state = drv_state;

	params.length = sizeof(struct atcs_pwr_shift_input);
	params.pointer = &atcs_input;

	info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_POWER_SHIFT_CONTROL, &params);
	if (!info) {
		DRM_ERROR("ATCS PSC update failed\n");
		return -EIO;
	}

	return 0;
}

/**
 * amdgpu_acpi_smart_shift_update - update dGPU device state to SBIOS
 *
 * @dev: drm_device pointer
 * @ss_state: current smart shift event
 *
 * returns 0 on success,
 * otherwise return error number.
 */
int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state)
{
	struct amdgpu_device *adev = drm_to_adev(dev);
	int r;

	if (!amdgpu_device_supports_smart_shift(dev))
		return 0;

	switch (ss_state) {
	/* SBIOS trigger “stop”, “enable” and “start” at D0, Driver Operational.
	 * SBIOS trigger “stop” at D3, Driver Not Operational.
	 * SBIOS trigger “stop” and “disable” at D0, Driver NOT operational.
	 */
	case AMDGPU_SS_DRV_LOAD:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_OPR);
		break;
	case AMDGPU_SS_DEV_D0:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_OPR);
		break;
	case AMDGPU_SS_DEV_D3:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT,
						    AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
		break;
	case AMDGPU_SS_DRV_UNLOAD:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
		break;
	default:
		return -EINVAL;
	}

	return r;
}

#ifdef CONFIG_ACPI_NUMA
static inline uint64_t amdgpu_acpi_get_numa_size(int nid)
{
	/* This is directly using si_meminfo_node implementation as the
	 * function is not exported.
	 */
	int zone_type;
	uint64_t managed_pages = 0;

	pg_data_t *pgdat = NODE_DATA(nid);

	for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++)
		managed_pages +=
			zone_managed_pages(&pgdat->node_zones[zone_type]);
	return managed_pages * PAGE_SIZE;
}

static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm)
{
	struct amdgpu_numa_info *numa_info;
	int nid;

	numa_info = xa_load(&numa_info_xa, pxm);

	if (!numa_info) {
		struct sysinfo info;

		numa_info = kzalloc(sizeof(*numa_info), GFP_KERNEL);
		if (!numa_info)
			return NULL;

		nid = pxm_to_node(pxm);
		numa_info->pxm = pxm;
		numa_info->nid = nid;

		if (numa_info->nid == NUMA_NO_NODE) {
			si_meminfo(&info);
			numa_info->size = info.totalram * info.mem_unit;
		} else {
			numa_info->size = amdgpu_acpi_get_numa_size(nid);
		}
		xa_store(&numa_info_xa, numa_info->pxm, numa_info, GFP_KERNEL);
	}

	return numa_info;
}
#endif

/**
 * amdgpu_acpi_get_node_id - obtain the NUMA node id for corresponding amdgpu
 * acpi device handle
 *
 * @handle: acpi handle
 * @numa_info: amdgpu_numa_info structure holding numa information
 *
 * Queries the ACPI interface to fetch the corresponding NUMA Node ID for a
 * given amdgpu acpi device.
 *
 * Returns ACPI STATUS OK with Node ID on success or the corresponding failure reason
 */
static acpi_status amdgpu_acpi_get_node_id(acpi_handle handle,
				    struct amdgpu_numa_info **numa_info)
{
#ifdef CONFIG_ACPI_NUMA
	u64 pxm;
	acpi_status status;

	if (!numa_info)
		return_ACPI_STATUS(AE_ERROR);

	status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);

	if (ACPI_FAILURE(status))
		return status;

	*numa_info = amdgpu_acpi_get_numa_info(pxm);

	if (!*numa_info)
		return_ACPI_STATUS(AE_ERROR);

	return_ACPI_STATUS(AE_OK);
#else
	return_ACPI_STATUS(AE_NOT_EXIST);
#endif
}

static struct amdgpu_acpi_dev_info *amdgpu_acpi_get_dev(u32 sbdf)
{
	struct amdgpu_acpi_dev_info *acpi_dev;

	if (list_empty(&amdgpu_acpi_dev_list))
		return NULL;

	list_for_each_entry(acpi_dev, &amdgpu_acpi_dev_list, list)
		if (acpi_dev->sbdf == sbdf)
			return acpi_dev;

	return NULL;
}

static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info,
				struct amdgpu_acpi_xcc_info *xcc_info, u32 sbdf)
{
	struct amdgpu_acpi_dev_info *tmp;
	union acpi_object *obj;
	int ret = -ENOENT;

	*dev_info = NULL;
	tmp = kzalloc(sizeof(struct amdgpu_acpi_dev_info), GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	INIT_LIST_HEAD(&tmp->xcc_list);
	INIT_LIST_HEAD(&tmp->list);
	tmp->sbdf = sbdf;

	obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
				      AMD_XCC_DSM_GET_SUPP_MODE, NULL,
				      ACPI_TYPE_INTEGER);

	if (!obj) {
		acpi_handle_debug(xcc_info->handle,
				  "_DSM function %d evaluation failed",
				  AMD_XCC_DSM_GET_SUPP_MODE);
		ret = -ENOENT;
		goto out;
	}

	tmp->supp_xcp_mode = obj->integer.value & 0xFFFF;
	ACPI_FREE(obj);

	obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
				      AMD_XCC_DSM_GET_XCP_MODE, NULL,
				      ACPI_TYPE_INTEGER);

	if (!obj) {
		acpi_handle_debug(xcc_info->handle,
				  "_DSM function %d evaluation failed",
				  AMD_XCC_DSM_GET_XCP_MODE);
		ret = -ENOENT;
		goto out;
	}

	tmp->xcp_mode = obj->integer.value & 0xFFFF;
	tmp->mem_mode = (obj->integer.value >> 32) & 0xFFFF;
	ACPI_FREE(obj);

	/* Evaluate DSMs and fill XCC information */
	obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
				      AMD_XCC_DSM_GET_TMR_INFO, NULL,
				      ACPI_TYPE_PACKAGE);

	if (!obj || obj->package.count < 2) {
		acpi_handle_debug(xcc_info->handle,
				  "_DSM function %d evaluation failed",
				  AMD_XCC_DSM_GET_TMR_INFO);
		ret = -ENOENT;
		goto out;
	}

	tmp->tmr_base = obj->package.elements[0].integer.value;
	tmp->tmr_size = obj->package.elements[1].integer.value;
	ACPI_FREE(obj);

	DRM_DEBUG_DRIVER(
		"New dev(%x): Supported xcp mode: %x curr xcp_mode : %x mem mode : %x, tmr base: %llx tmr size: %llx  ",
		tmp->sbdf, tmp->supp_xcp_mode, tmp->xcp_mode, tmp->mem_mode,
		tmp->tmr_base, tmp->tmr_size);
	list_add_tail(&tmp->list, &amdgpu_acpi_dev_list);
	*dev_info = tmp;

	return 0;

out:
	if (obj)
		ACPI_FREE(obj);
	kfree(tmp);

	return ret;
}

static int amdgpu_acpi_get_xcc_info(struct amdgpu_acpi_xcc_info *xcc_info,
				    u32 *sbdf)
{
	union acpi_object *obj;
	acpi_status status;
	int ret = -ENOENT;

	obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
				      AMD_XCC_DSM_GET_NUM_FUNCS, NULL,
				      ACPI_TYPE_INTEGER);

	if (!obj || obj->integer.value != AMD_XCC_DSM_NUM_FUNCS)
		goto out;
	ACPI_FREE(obj);

	/* Evaluate DSMs and fill XCC information */
	obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
				      AMD_XCC_DSM_GET_VF_XCC_MAPPING, NULL,
				      ACPI_TYPE_INTEGER);

	if (!obj) {
		acpi_handle_debug(xcc_info->handle,
				  "_DSM function %d evaluation failed",
				  AMD_XCC_DSM_GET_VF_XCC_MAPPING);
		ret = -EINVAL;
		goto out;
	}

	/* PF xcc id [39:32] */
	xcc_info->phy_id = (obj->integer.value >> 32) & 0xFF;
	/* xcp node of this xcc [47:40] */
	xcc_info->xcp_node = (obj->integer.value >> 40) & 0xFF;
	/* PF domain of this xcc [31:16] */
	*sbdf = (obj->integer.value) & 0xFFFF0000;
	/* PF bus/dev/fn of this xcc [63:48] */
	*sbdf |= (obj->integer.value >> 48) & 0xFFFF;
	ACPI_FREE(obj);
	obj = NULL;

	status =
		amdgpu_acpi_get_node_id(xcc_info->handle, &xcc_info->numa_info);

	/* TODO: check if this check is required */
	if (ACPI_SUCCESS(status))
		ret = 0;
out:
	if (obj)
		ACPI_FREE(obj);

	return ret;
}

static int amdgpu_acpi_enumerate_xcc(void)
{
	struct amdgpu_acpi_dev_info *dev_info = NULL;
	struct amdgpu_acpi_xcc_info *xcc_info;
	struct acpi_device *acpi_dev;
	char hid[ACPI_ID_LEN];
	int ret, id;
	u32 sbdf;

	INIT_LIST_HEAD(&amdgpu_acpi_dev_list);
	xa_init(&numa_info_xa);

	for (id = 0; id < AMD_XCC_MAX_HID; id++) {
		sprintf(hid, "%s%d", "AMD", AMD_XCC_HID_START + id);
		acpi_dev = acpi_dev_get_first_match_dev(hid, NULL, -1);
		/* These ACPI objects are expected to be in sequential order. If
		 * one is not found, no need to check the rest.
		 */
		if (!acpi_dev) {
			DRM_DEBUG_DRIVER("No matching acpi device found for %s",
					 hid);
			break;
		}

		xcc_info = kzalloc(sizeof(struct amdgpu_acpi_xcc_info),
				   GFP_KERNEL);
		if (!xcc_info) {
			DRM_ERROR("Failed to allocate memory for xcc info\n");
			return -ENOMEM;
		}

		INIT_LIST_HEAD(&xcc_info->list);
		xcc_info->handle = acpi_device_handle(acpi_dev);
		acpi_dev_put(acpi_dev);

		ret = amdgpu_acpi_get_xcc_info(xcc_info, &sbdf);
		if (ret) {
			kfree(xcc_info);
			continue;
		}

		dev_info = amdgpu_acpi_get_dev(sbdf);

		if (!dev_info)
			ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf);

		if (ret == -ENOMEM)
			return ret;

		if (!dev_info) {
			kfree(xcc_info);
			continue;
		}

		list_add_tail(&xcc_info->list, &dev_info->xcc_list);
	}

	return 0;
}

int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
			     u64 *tmr_size)
{
	struct amdgpu_acpi_dev_info *dev_info;
	u32 sbdf;

	if (!tmr_offset || !tmr_size)
		return -EINVAL;

	sbdf = (pci_domain_nr(adev->pdev->bus) << 16);
	sbdf |= pci_dev_id(adev->pdev);
	dev_info = amdgpu_acpi_get_dev(sbdf);
	if (!dev_info)
		return -ENOENT;

	*tmr_offset = dev_info->tmr_base;
	*tmr_size = dev_info->tmr_size;

	return 0;
}

int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id,
			     struct amdgpu_numa_info *numa_info)
{
	struct amdgpu_acpi_dev_info *dev_info;
	struct amdgpu_acpi_xcc_info *xcc_info;
	u32 sbdf;

	if (!numa_info)
		return -EINVAL;

	sbdf = (pci_domain_nr(adev->pdev->bus) << 16);
	sbdf |= pci_dev_id(adev->pdev);
	dev_info = amdgpu_acpi_get_dev(sbdf);
	if (!dev_info)
		return -ENOENT;

	list_for_each_entry(xcc_info, &dev_info->xcc_list, list) {
		if (xcc_info->phy_id == xcc_id) {
			memcpy(numa_info, xcc_info->numa_info,
			       sizeof(*numa_info));
			return 0;
		}
	}

	return -ENOENT;
}

/**
 * amdgpu_acpi_event - handle notify events
 *
 * @nb: notifier block
 * @val: val
 * @data: acpi event
 *
 * Calls relevant amdgpu functions in response to various
 * acpi events.
 * Returns NOTIFY code
 */
static int amdgpu_acpi_event(struct notifier_block *nb,
			     unsigned long val,
			     void *data)
{
	struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, acpi_nb);
	struct acpi_bus_event *entry = (struct acpi_bus_event *)data;

	if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
		if (power_supply_is_system_supplied() > 0)
			DRM_DEBUG_DRIVER("pm: AC\n");
		else
			DRM_DEBUG_DRIVER("pm: DC\n");

		amdgpu_pm_acpi_event_handler(adev);
	}

	/* Check for pending SBIOS requests */
	return amdgpu_atif_handler(adev, entry);
}

/* Call all ACPI methods here */
/**
 * amdgpu_acpi_init - init driver acpi support
 *
 * @adev: amdgpu_device pointer
 *
 * Verifies the AMD ACPI interfaces and registers with the acpi
 * notifier chain (all asics).
 * Returns 0 on success, error on failure.
 */
int amdgpu_acpi_init(struct amdgpu_device *adev)
{
	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;

	if (atif->notifications.brightness_change) {
		if (adev->dc_enabled) {
#if defined(CONFIG_DRM_AMD_DC)
			struct amdgpu_display_manager *dm = &adev->dm;

			if (dm->backlight_dev[0])
				atif->bd = dm->backlight_dev[0];
#endif
		} else {
			struct drm_encoder *tmp;

			/* Find the encoder controlling the brightness */
			list_for_each_entry(tmp, &adev_to_drm(adev)->mode_config.encoder_list,
					    head) {
				struct amdgpu_encoder *enc = to_amdgpu_encoder(tmp);

				if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
				    enc->enc_priv) {
					struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;

					if (dig->bl_dev) {
						atif->bd = dig->bl_dev;
						break;
					}
				}
			}
		}
	}
	adev->acpi_nb.notifier_call = amdgpu_acpi_event;
	register_acpi_notifier(&adev->acpi_nb);

	return 0;
}

void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps)
{
	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;

	caps->caps_valid = atif->backlight_caps.caps_valid;
	caps->min_input_signal = atif->backlight_caps.min_input_signal;
	caps->max_input_signal = atif->backlight_caps.max_input_signal;
}

/**
 * amdgpu_acpi_fini - tear down driver acpi support
 *
 * @adev: amdgpu_device pointer
 *
 * Unregisters with the acpi notifier chain (all asics).
 */
void amdgpu_acpi_fini(struct amdgpu_device *adev)
{
	unregister_acpi_notifier(&adev->acpi_nb);
}

/**
 * amdgpu_atif_pci_probe_handle - look up the ATIF handle
 *
 * @pdev: pci device
 *
 * Look up the ATIF handles (all asics).
 * Returns true if the handle is found, false if not.
 */
static bool amdgpu_atif_pci_probe_handle(struct pci_dev *pdev)
{
	char acpi_method_name[255] = { 0 };
	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
	acpi_handle dhandle, atif_handle;
	acpi_status status;
	int ret;

	dhandle = ACPI_HANDLE(&pdev->dev);
	if (!dhandle)
		return false;

	status = acpi_get_handle(dhandle, "ATIF", &atif_handle);
	if (ACPI_FAILURE(status))
		return false;

	amdgpu_acpi_priv.atif.handle = atif_handle;
	acpi_get_name(amdgpu_acpi_priv.atif.handle, ACPI_FULL_PATHNAME, &buffer);
	DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
	ret = amdgpu_atif_verify_interface(&amdgpu_acpi_priv.atif);
	if (ret) {
		amdgpu_acpi_priv.atif.handle = 0;
		return false;
	}
	return true;
}

/**
 * amdgpu_atcs_pci_probe_handle - look up the ATCS handle
 *
 * @pdev: pci device
 *
 * Look up the ATCS handles (all asics).
 * Returns true if the handle is found, false if not.
 */
static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
{
	char acpi_method_name[255] = { 0 };
	struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
	acpi_handle dhandle, atcs_handle;
	acpi_status status;
	int ret;

	dhandle = ACPI_HANDLE(&pdev->dev);
	if (!dhandle)
		return false;

	status = acpi_get_handle(dhandle, "ATCS", &atcs_handle);
	if (ACPI_FAILURE(status))
		return false;

	amdgpu_acpi_priv.atcs.handle = atcs_handle;
	acpi_get_name(amdgpu_acpi_priv.atcs.handle, ACPI_FULL_PATHNAME, &buffer);
	DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name);
	ret = amdgpu_atcs_verify_interface(&amdgpu_acpi_priv.atcs);
	if (ret) {
		amdgpu_acpi_priv.atcs.handle = 0;
		return false;
	}
	return true;
}


/**
 * amdgpu_acpi_should_gpu_reset
 *
 * @adev: amdgpu_device_pointer
 *
 * returns true if should reset GPU, false if not
 */
bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev)
{
	if ((adev->flags & AMD_IS_APU) &&
	    adev->gfx.imu.funcs) /* Not need to do mode2 reset for IMU enabled APUs */
		return false;

	if ((adev->flags & AMD_IS_APU) &&
	    amdgpu_acpi_is_s3_active(adev))
		return false;

	if (amdgpu_sriov_vf(adev))
		return false;

#if IS_ENABLED(CONFIG_SUSPEND)
	return pm_suspend_target_state != PM_SUSPEND_TO_IDLE;
#else
	return true;
#endif
}

/*
 * amdgpu_acpi_detect - detect ACPI ATIF/ATCS methods
 *
 * Check if we have the ATIF/ATCS methods and populate
 * the structures in the driver.
 */
void amdgpu_acpi_detect(void)
{
	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
	struct pci_dev *pdev = NULL;
	int ret;

	while ((pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) {
		if ((pdev->class != PCI_CLASS_DISPLAY_VGA << 8) &&
		    (pdev->class != PCI_CLASS_DISPLAY_OTHER << 8))
			continue;

		if (!atif->handle)
			amdgpu_atif_pci_probe_handle(pdev);
		if (!atcs->handle)
			amdgpu_atcs_pci_probe_handle(pdev);
	}

	if (atif->functions.sbios_requests && !atif->functions.system_params) {
		/* XXX check this workraround, if sbios request function is
		 * present we have to see how it's configured in the system
		 * params
		 */
		atif->functions.system_params = true;
	}

	if (atif->functions.system_params) {
		ret = amdgpu_atif_get_notification_params(atif);
		if (ret) {
			DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
					ret);
			/* Disable notification */
			atif->notification_cfg.enabled = false;
		}
	}

	if (atif->functions.query_backlight_transfer_characteristics) {
		ret = amdgpu_atif_query_backlight_caps(atif);
		if (ret) {
			DRM_DEBUG_DRIVER("Call to QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS failed: %d\n",
					ret);
			atif->backlight_caps.caps_valid = false;
		}
	} else {
		atif->backlight_caps.caps_valid = false;
	}

	amdgpu_acpi_enumerate_xcc();
}

void amdgpu_acpi_release(void)
{
	struct amdgpu_acpi_dev_info *dev_info, *dev_tmp;
	struct amdgpu_acpi_xcc_info *xcc_info, *xcc_tmp;
	struct amdgpu_numa_info *numa_info;
	unsigned long index;

	xa_for_each(&numa_info_xa, index, numa_info) {
		kfree(numa_info);
		xa_erase(&numa_info_xa, index);
	}

	if (list_empty(&amdgpu_acpi_dev_list))
		return;

	list_for_each_entry_safe(dev_info, dev_tmp, &amdgpu_acpi_dev_list,
				 list) {
		list_for_each_entry_safe(xcc_info, xcc_tmp, &dev_info->xcc_list,
					 list) {
			list_del(&xcc_info->list);
			kfree(xcc_info);
		}

		list_del(&dev_info->list);
		kfree(dev_info);
	}
}

#if IS_ENABLED(CONFIG_SUSPEND)
/**
 * amdgpu_acpi_is_s3_active
 *
 * @adev: amdgpu_device_pointer
 *
 * returns true if supported, false if not.
 */
bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev)
{
	return !(adev->flags & AMD_IS_APU) ||
		(pm_suspend_target_state == PM_SUSPEND_MEM);
}

/**
 * amdgpu_acpi_is_s0ix_active
 *
 * @adev: amdgpu_device_pointer
 *
 * returns true if supported, false if not.
 */
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
{
	if (!(adev->flags & AMD_IS_APU) ||
	    (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
		return false;

	if (adev->asic_type < CHIP_RAVEN)
		return false;

	if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
		return false;

	/*
	 * If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
	 * risky to do any special firmware-related preparations for entering
	 * S0ix even though the system is suspending to idle, so return false
	 * in that case.
	 */
	if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
		dev_err_once(adev->dev,
			      "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
			      "To use suspend-to-idle change the sleep mode in BIOS setup.\n");
		return false;
	}

#if !IS_ENABLED(CONFIG_AMD_PMC)
	dev_err_once(adev->dev,
		      "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n");
	return false;
#else
	return true;
#endif /* CONFIG_AMD_PMC */
}

/**
 * amdgpu_choose_low_power_state
 *
 * @adev: amdgpu_device_pointer
 *
 * Choose the target low power state for the GPU
 */
void amdgpu_choose_low_power_state(struct amdgpu_device *adev)
{
	if (adev->in_runpm)
		return;

	if (amdgpu_acpi_is_s0ix_active(adev))
		adev->in_s0ix = true;
	else if (amdgpu_acpi_is_s3_active(adev))
		adev->in_s3 = true;
}

#endif /* CONFIG_SUSPEND */
