Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6848d73e authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/pp: Remove the wrap functions for acpi in powerplay

parent e1deba28
Loading
Loading
Loading
Loading
+0 −212
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include <drm/drmP.h>
#include <linux/firmware.h>
#include <drm/amdgpu_drm.h>
@@ -964,216 +963,6 @@ static int amdgpu_cgs_notify_dpm_enabled(struct cgs_device *cgs_device, bool ena
	return 0;
}

/** \brief evaluate acpi namespace object, handle or pathname must be valid
 *  \param cgs_device
 *  \param info input/output arguments for the control method
 *  \return status
 */

#if defined(CONFIG_ACPI)
static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
				    struct cgs_acpi_method_info *info)
{
	CGS_FUNC_ADEV;
	acpi_handle handle;
	struct acpi_object_list input;
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *params, *obj;
	uint8_t name[5] = {'\0'};
	struct cgs_acpi_method_argument *argument;
	uint32_t i, count;
	acpi_status status;
	int result;

	handle = ACPI_HANDLE(&adev->pdev->dev);
	if (!handle)
		return -ENODEV;

	memset(&input, 0, sizeof(struct acpi_object_list));

	/* validate input info */
	if (info->size != sizeof(struct cgs_acpi_method_info))
		return -EINVAL;

	input.count = info->input_count;
	if (info->input_count > 0) {
		if (info->pinput_argument == NULL)
			return -EINVAL;
		argument = info->pinput_argument;
		for (i = 0; i < info->input_count; i++) {
			if (((argument->type == ACPI_TYPE_STRING) ||
			     (argument->type == ACPI_TYPE_BUFFER)) &&
			    (argument->pointer == NULL))
				return -EINVAL;
			argument++;
		}
	}

	if (info->output_count > 0) {
		if (info->poutput_argument == NULL)
			return -EINVAL;
		argument = info->poutput_argument;
		for (i = 0; i < info->output_count; i++) {
			if (((argument->type == ACPI_TYPE_STRING) ||
				(argument->type == ACPI_TYPE_BUFFER))
				&& (argument->pointer == NULL))
				return -EINVAL;
			argument++;
		}
	}

	/* The path name passed to acpi_evaluate_object should be null terminated */
	if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) {
		strncpy(name, (char *)&(info->name), sizeof(uint32_t));
		name[4] = '\0';
	}

	/* parse input parameters */
	if (input.count > 0) {
		input.pointer = params =
				kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL);
		if (params == NULL)
			return -EINVAL;

		argument = info->pinput_argument;

		for (i = 0; i < input.count; i++) {
			params->type = argument->type;
			switch (params->type) {
			case ACPI_TYPE_INTEGER:
				params->integer.value = argument->value;
				break;
			case ACPI_TYPE_STRING:
				params->string.length = argument->data_length;
				params->string.pointer = argument->pointer;
				break;
			case ACPI_TYPE_BUFFER:
				params->buffer.length = argument->data_length;
				params->buffer.pointer = argument->pointer;
				break;
			default:
				break;
			}
			params++;
			argument++;
		}
	}

	/* parse output info */
	count = info->output_count;
	argument = info->poutput_argument;

	/* evaluate the acpi method */
	status = acpi_evaluate_object(handle, name, &input, &output);

	if (ACPI_FAILURE(status)) {
		result = -EIO;
		goto free_input;
	}

	/* return the output info */
	obj = output.pointer;

	if (count > 1) {
		if ((obj->type != ACPI_TYPE_PACKAGE) ||
			(obj->package.count != count)) {
			result = -EIO;
			goto free_obj;
		}
		params = obj->package.elements;
	} else
		params = obj;

	if (params == NULL) {
		result = -EIO;
		goto free_obj;
	}

	for (i = 0; i < count; i++) {
		if (argument->type != params->type) {
			result = -EIO;
			goto free_obj;
		}
		switch (params->type) {
		case ACPI_TYPE_INTEGER:
			argument->value = params->integer.value;
			break;
		case ACPI_TYPE_STRING:
			if ((params->string.length != argument->data_length) ||
				(params->string.pointer == NULL)) {
				result = -EIO;
				goto free_obj;
			}
			strncpy(argument->pointer,
				params->string.pointer,
				params->string.length);
			break;
		case ACPI_TYPE_BUFFER:
			if (params->buffer.pointer == NULL) {
				result = -EIO;
				goto free_obj;
			}
			memcpy(argument->pointer,
				params->buffer.pointer,
				argument->data_length);
			break;
		default:
			break;
		}
		argument++;
		params++;
	}

	result = 0;
free_obj:
	kfree(obj);
free_input:
	kfree((void *)input.pointer);
	return result;
}
#else
static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
				struct cgs_acpi_method_info *info)
{
	return -EIO;
}
#endif

static int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device,
					uint32_t acpi_method,
					uint32_t acpi_function,
					void *pinput, void *poutput,
					uint32_t output_count,
					uint32_t input_size,
					uint32_t output_size)
{
	struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} };
	struct cgs_acpi_method_argument acpi_output = {0};
	struct cgs_acpi_method_info info = {0};

	acpi_input[0].type = CGS_ACPI_TYPE_INTEGER;
	acpi_input[0].data_length = sizeof(uint32_t);
	acpi_input[0].value = acpi_function;

	acpi_input[1].type = CGS_ACPI_TYPE_BUFFER;
	acpi_input[1].data_length = input_size;
	acpi_input[1].pointer = pinput;

	acpi_output.type = CGS_ACPI_TYPE_BUFFER;
	acpi_output.data_length = output_size;
	acpi_output.pointer = poutput;

	info.size = sizeof(struct cgs_acpi_method_info);
	info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT;
	info.input_count = 2;
	info.name = acpi_method;
	info.pinput_argument = acpi_input;
	info.output_count = output_count;
	info.poutput_argument = &acpi_output;

	return amdgpu_cgs_acpi_eval_object(cgs_device, &info);
}

static int amdgpu_cgs_set_temperature_range(struct cgs_device *cgs_device,
					int min_temperature,
					int max_temperature)
@@ -1207,7 +996,6 @@ static const struct cgs_ops amdgpu_cgs_ops = {
	.set_clockgating_state = amdgpu_cgs_set_clockgating_state,
	.get_active_displays_info = amdgpu_cgs_get_active_displays_info,
	.notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled,
	.call_acpi_method = amdgpu_cgs_call_acpi_method,
	.query_system_info = amdgpu_cgs_query_system_info,
	.is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
	.enter_safe_mode = amdgpu_cgs_enter_safe_mode,
+0 −44
Original line number Diff line number Diff line
@@ -157,38 +157,6 @@ struct cgs_display_info {

typedef unsigned long cgs_handle_t;

#define CGS_ACPI_METHOD_ATCS          0x53435441
#define CGS_ACPI_METHOD_ATIF          0x46495441
#define CGS_ACPI_METHOD_ATPX          0x58505441
#define CGS_ACPI_FIELD_METHOD_NAME                      0x00000001
#define CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT             0x00000002
#define CGS_ACPI_MAX_BUFFER_SIZE     256
#define CGS_ACPI_TYPE_ANY                      0x00
#define CGS_ACPI_TYPE_INTEGER               0x01
#define CGS_ACPI_TYPE_STRING                0x02
#define CGS_ACPI_TYPE_BUFFER                0x03
#define CGS_ACPI_TYPE_PACKAGE               0x04

struct cgs_acpi_method_argument {
	uint32_t type;
	uint32_t data_length;
	union{
		uint32_t value;
		void *pointer;
	};
};

struct cgs_acpi_method_info {
	uint32_t size;
	uint32_t field;
	uint32_t input_count;
	uint32_t name;
	struct cgs_acpi_method_argument *pinput_argument;
	uint32_t output_count;
	struct cgs_acpi_method_argument *poutput_argument;
	uint32_t padding[9];
};

/**
 * cgs_alloc_gpu_mem() - Allocate GPU memory
 * @cgs_device:	opaque device handle
@@ -407,14 +375,6 @@ typedef int(*cgs_get_active_displays_info)(

typedef int (*cgs_notify_dpm_enabled)(struct cgs_device *cgs_device, bool enabled);

typedef int (*cgs_call_acpi_method)(struct cgs_device *cgs_device,
					uint32_t acpi_method,
					uint32_t acpi_function,
					void *pinput, void *poutput,
					uint32_t output_count,
					uint32_t input_size,
					uint32_t output_size);

typedef int (*cgs_query_system_info)(struct cgs_device *cgs_device,
				struct cgs_system_info *sys_info);

@@ -456,8 +416,6 @@ struct cgs_ops {
	cgs_get_active_displays_info get_active_displays_info;
	/* notify dpm enabled */
	cgs_notify_dpm_enabled notify_dpm_enabled;
	/* ACPI */
	cgs_call_acpi_method call_acpi_method;
	/* get system info */
	cgs_query_system_info query_system_info;
	cgs_is_virtualization_enabled_t is_virtualization_enabled;
@@ -525,8 +483,6 @@ struct cgs_device
#define cgs_get_active_displays_info(dev, info)	\
	CGS_CALL(get_active_displays_info, dev, info)

#define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)	\
	CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)
#define cgs_query_system_info(dev, sys_info)	\
	CGS_CALL(query_system_info, dev, sys_info)
#define cgs_get_pci_resource(cgs_device, resource_type, size, offset, \
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
# It provides the hardware management services for the driver.

HARDWARE_MGR = hwmgr.o processpptables.o \
		hardwaremanager.o pp_acpi.o cz_hwmgr.o \
		hardwaremanager.o cz_hwmgr.o \
		cz_clockpowergating.o pppcielanes.o\
		process_pptables_v1_0.o ppatomctrl.o ppatomfwctrl.o \
		smu7_hwmgr.o smu7_powertune.o smu7_thermal.o \
+0 −114
Original line number Diff line number Diff line
/*
 * Copyright 2016 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/delay.h>
#include <linux/errno.h>
#include "hwmgr.h"
#include "amd_acpi.h"
#include "pp_acpi.h"

bool acpi_atcs_functions_supported(void *device, uint32_t index)
{
	int32_t result;
	struct atcs_verify_interface output_buf = {0};

	int32_t temp_buffer = 1;

	result = cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
						ATCS_FUNCTION_VERIFY_INTERFACE,
						&temp_buffer,
						&output_buf,
						1,
						sizeof(temp_buffer),
						sizeof(output_buf));

	return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
}

bool acpi_atcs_notify_pcie_device_ready(void *device)
{
	int32_t temp_buffer = 1;

	return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
				ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
						&temp_buffer,
						NULL,
						0,
						sizeof(temp_buffer),
						0);
}


int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
{
	struct atcs_pref_req_input atcs_input;
	struct atcs_pref_req_output atcs_output;
	u32 retry = 3;
	int result;
	struct cgs_system_info info = {0};

	if (acpi_atcs_notify_pcie_device_ready(device))
		return -EINVAL;

	info.size = sizeof(struct cgs_system_info);
	info.info_id = CGS_SYSTEM_INFO_ADAPTER_BDF_ID;
	result = cgs_query_system_info(device, &info);
	if (result != 0)
		return -EINVAL;
	atcs_input.client_id = (uint16_t)info.value;
	atcs_input.size = sizeof(struct atcs_pref_req_input);
	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;

	atcs_output.size = sizeof(struct atcs_pref_req_input);

	while (retry--) {
		result = cgs_call_acpi_method(device,
						CGS_ACPI_METHOD_ATCS,
						ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
						&atcs_input,
						&atcs_output,
						1,
						sizeof(atcs_input),
						sizeof(atcs_output));
		if (result != 0)
			return -EIO;

		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;
}
+0 −26
Original line number Diff line number Diff line
/*
 * Copyright 2015 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.
 *
 */

bool acpi_atcs_functions_supported(void *device, uint32_t index);
int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise);
bool acpi_atcs_notify_pcie_device_ready(void *device);