/*
 * Intel ACPI functions
 *
 * _DSM related code stolen from nouveau_acpi.c.
 */
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/vga_switcheroo.h>
#include <acpi/acpi_drivers.h>

#include "drmP.h"

#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */

#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */
#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */

static struct intel_dsm_priv {
	acpi_handle dhandle;
} intel_dsm_priv;

static const u8 intel_dsm_guid[] = {
	0xd3, 0x73, 0xd8, 0x7e,
	0xd0, 0xc2,
	0x4f, 0x4e,
	0xa8, 0x54,
	0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
};

static int intel_dsm(acpi_handle handle, int func, int arg)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_object_list input;
	union acpi_object params[4];
	union acpi_object *obj;
	u32 result;
	int ret = 0;

	input.count = 4;
	input.pointer = params;
	params[0].type = ACPI_TYPE_BUFFER;
	params[0].buffer.length = sizeof(intel_dsm_guid);
	params[0].buffer.pointer = (char *)intel_dsm_guid;
	params[1].type = ACPI_TYPE_INTEGER;
	params[1].integer.value = INTEL_DSM_REVISION_ID;
	params[2].type = ACPI_TYPE_INTEGER;
	params[2].integer.value = func;
	params[3].type = ACPI_TYPE_INTEGER;
	params[3].integer.value = arg;

	ret = acpi_evaluate_object(handle, "_DSM", &input, &output);
	if (ret) {
		DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
		return ret;
	}

	obj = (union acpi_object *)output.pointer;

	result = 0;
	switch (obj->type) {
	case ACPI_TYPE_INTEGER:
		result = obj->integer.value;
		break;

	case ACPI_TYPE_BUFFER:
		if (obj->buffer.length == 4) {
			result =(obj->buffer.pointer[0] |
				(obj->buffer.pointer[1] <<  8) |
				(obj->buffer.pointer[2] << 16) |
				(obj->buffer.pointer[3] << 24));
			break;
		}
	default:
		ret = -EINVAL;
		break;
	}
	if (result == 0x80000002)
		ret = -ENODEV;

	kfree(output.pointer);
	return ret;
}

static char *intel_dsm_port_name(u8 id)
{
	switch (id) {
	case 0:
		return "Reserved";
	case 1:
		return "Analog VGA";
	case 2:
		return "LVDS";
	case 3:
		return "Reserved";
	case 4:
		return "HDMI/DVI_B";
	case 5:
		return "HDMI/DVI_C";
	case 6:
		return "HDMI/DVI_D";
	case 7:
		return "DisplayPort_A";
	case 8:
		return "DisplayPort_B";
	case 9:
		return "DisplayPort_C";
	case 0xa:
		return "DisplayPort_D";
	case 0xb:
	case 0xc:
	case 0xd:
		return "Reserved";
	case 0xe:
		return "WiDi";
	default:
		return "bad type";
	}
}

static char *intel_dsm_mux_type(u8 type)
{
	switch (type) {
	case 0:
		return "unknown";
	case 1:
		return "No MUX, iGPU only";
	case 2:
		return "No MUX, dGPU only";
	case 3:
		return "MUXed between iGPU and dGPU";
	default:
		return "bad type";
	}
}

static void intel_dsm_platform_mux_info(void)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_object_list input;
	union acpi_object params[4];
	union acpi_object *pkg;
	int i, ret;

	input.count = 4;
	input.pointer = params;
	params[0].type = ACPI_TYPE_BUFFER;
	params[0].buffer.length = sizeof(intel_dsm_guid);
	params[0].buffer.pointer = (char *)intel_dsm_guid;
	params[1].type = ACPI_TYPE_INTEGER;
	params[1].integer.value = INTEL_DSM_REVISION_ID;
	params[2].type = ACPI_TYPE_INTEGER;
	params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO;
	params[3].type = ACPI_TYPE_INTEGER;
	params[3].integer.value = 0;

	ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input,
				   &output);
	if (ret) {
		DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
		goto out;
	}

	pkg = (union acpi_object *)output.pointer;

	if (pkg->type == ACPI_TYPE_PACKAGE) {
		union acpi_object *connector_count = &pkg->package.elements[0];
		DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
			  (unsigned long long)connector_count->integer.value);
		for (i = 1; i < pkg->package.count; i++) {
			union acpi_object *obj = &pkg->package.elements[i];
			union acpi_object *connector_id =
				&obj->package.elements[0];
			union acpi_object *info = &obj->package.elements[1];
			DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
				  (unsigned long long)connector_id->integer.value);
			DRM_DEBUG_DRIVER("  port id: %s\n",
			       intel_dsm_port_name(info->buffer.pointer[0]));
			DRM_DEBUG_DRIVER("  display mux info: %s\n",
			       intel_dsm_mux_type(info->buffer.pointer[1]));
			DRM_DEBUG_DRIVER("  aux/dc mux info: %s\n",
			       intel_dsm_mux_type(info->buffer.pointer[2]));
			DRM_DEBUG_DRIVER("  hpd mux info: %s\n",
			       intel_dsm_mux_type(info->buffer.pointer[3]));
		}
	} else {
		DRM_ERROR("MUX INFO call failed\n");
	}

out:
	kfree(output.pointer);
}

static bool intel_dsm_pci_probe(struct pci_dev *pdev)
{
	acpi_handle dhandle, intel_handle;
	acpi_status status;
	int ret;

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

	status = acpi_get_handle(dhandle, "_DSM", &intel_handle);
	if (ACPI_FAILURE(status)) {
		DRM_DEBUG_KMS("no _DSM method for intel device\n");
		return false;
	}

	ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0);
	if (ret < 0) {
		DRM_ERROR("failed to get supported _DSM functions\n");
		return false;
	}

	intel_dsm_priv.dhandle = dhandle;

	intel_dsm_platform_mux_info();
	return true;
}

static bool intel_dsm_detect(void)
{
	char acpi_method_name[255] = { 0 };
	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
	struct pci_dev *pdev = NULL;
	bool has_dsm = false;
	int vga_count = 0;

	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
		vga_count++;
		has_dsm |= intel_dsm_pci_probe(pdev);
	}

	if (vga_count == 2 && has_dsm) {
		acpi_get_name(intel_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
		DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n",
				 acpi_method_name);
		return true;
	}

	return false;
}

void intel_register_dsm_handler(void)
{
	if (!intel_dsm_detect())
		return;
}

void intel_unregister_dsm_handler(void)
{
}
