// SPDX-License-Identifier: GPL-2.0
/*
 * Intel ACPI functions
 *
 * _DSM related code stolen from nouveau_acpi.c.
 */

#include <linux/pci.h>
#include <linux/acpi.h>

#include "i915_drv.h"
#include "intel_acpi.h"
#include "intel_display_types.h"

#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */

static const guid_t intel_dsm_guid =
	GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f,
		  0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c);

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(acpi_handle dhandle)
{
	int i;
	union acpi_object *pkg, *connector_count;

	pkg = acpi_evaluate_dsm_typed(dhandle, &intel_dsm_guid,
			INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
			NULL, ACPI_TYPE_PACKAGE);
	if (!pkg) {
		DRM_DEBUG_DRIVER("failed to evaluate _DSM\n");
		return;
	}

	if (!pkg->package.count) {
		DRM_DEBUG_DRIVER("no connection in _DSM\n");
		return;
	}

	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;
		union acpi_object *info;

		if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) {
			DRM_DEBUG_DRIVER("Invalid object for MUX #%d\n", i);
			continue;
		}

		connector_id = &obj->package.elements[0];
		info = &obj->package.elements[1];
		if (info->type != ACPI_TYPE_BUFFER || info->buffer.length < 4) {
			DRM_DEBUG_DRIVER("Invalid info for MUX obj #%d\n", i);
			continue;
		}

		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]));
	}

	ACPI_FREE(pkg);
}

static acpi_handle intel_dsm_pci_probe(struct pci_dev *pdev)
{
	acpi_handle dhandle;

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

	if (!acpi_check_dsm(dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID,
			    1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
		DRM_DEBUG_KMS("no _DSM method for intel device\n");
		return NULL;
	}

	intel_dsm_platform_mux_info(dhandle);

	return dhandle;
}

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

	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
		vga_count++;
		dhandle = intel_dsm_pci_probe(pdev) ?: dhandle;
	}

	if (vga_count == 2 && dhandle) {
		acpi_get_name(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)
{
}

/*
 * ACPI Specification, Revision 5.0, Appendix B.3.2 _DOD (Enumerate All Devices
 * Attached to the Display Adapter).
 */
#define ACPI_DISPLAY_INDEX_SHIFT		0
#define ACPI_DISPLAY_INDEX_MASK			(0xf << 0)
#define ACPI_DISPLAY_PORT_ATTACHMENT_SHIFT	4
#define ACPI_DISPLAY_PORT_ATTACHMENT_MASK	(0xf << 4)
#define ACPI_DISPLAY_TYPE_SHIFT			8
#define ACPI_DISPLAY_TYPE_MASK			(0xf << 8)
#define ACPI_DISPLAY_TYPE_OTHER			(0 << 8)
#define ACPI_DISPLAY_TYPE_VGA			(1 << 8)
#define ACPI_DISPLAY_TYPE_TV			(2 << 8)
#define ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL	(3 << 8)
#define ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL	(4 << 8)
#define ACPI_VENDOR_SPECIFIC_SHIFT		12
#define ACPI_VENDOR_SPECIFIC_MASK		(0xf << 12)
#define ACPI_BIOS_CAN_DETECT			(1 << 16)
#define ACPI_DEPENDS_ON_VGA			(1 << 17)
#define ACPI_PIPE_ID_SHIFT			18
#define ACPI_PIPE_ID_MASK			(7 << 18)
#define ACPI_DEVICE_ID_SCHEME			(1ULL << 31)

static u32 acpi_display_type(struct intel_connector *connector)
{
	u32 display_type;

	switch (connector->base.connector_type) {
	case DRM_MODE_CONNECTOR_VGA:
	case DRM_MODE_CONNECTOR_DVIA:
		display_type = ACPI_DISPLAY_TYPE_VGA;
		break;
	case DRM_MODE_CONNECTOR_Composite:
	case DRM_MODE_CONNECTOR_SVIDEO:
	case DRM_MODE_CONNECTOR_Component:
	case DRM_MODE_CONNECTOR_9PinDIN:
	case DRM_MODE_CONNECTOR_TV:
		display_type = ACPI_DISPLAY_TYPE_TV;
		break;
	case DRM_MODE_CONNECTOR_DVII:
	case DRM_MODE_CONNECTOR_DVID:
	case DRM_MODE_CONNECTOR_DisplayPort:
	case DRM_MODE_CONNECTOR_HDMIA:
	case DRM_MODE_CONNECTOR_HDMIB:
		display_type = ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL;
		break;
	case DRM_MODE_CONNECTOR_LVDS:
	case DRM_MODE_CONNECTOR_eDP:
	case DRM_MODE_CONNECTOR_DSI:
		display_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL;
		break;
	case DRM_MODE_CONNECTOR_Unknown:
	case DRM_MODE_CONNECTOR_VIRTUAL:
		display_type = ACPI_DISPLAY_TYPE_OTHER;
		break;
	default:
		MISSING_CASE(connector->base.connector_type);
		display_type = ACPI_DISPLAY_TYPE_OTHER;
		break;
	}

	return display_type;
}

void intel_acpi_device_id_update(struct drm_i915_private *dev_priv)
{
	struct drm_device *drm_dev = &dev_priv->drm;
	struct intel_connector *connector;
	struct drm_connector_list_iter conn_iter;
	u8 display_index[16] = {};

	/* Populate the ACPI IDs for all connectors for a given drm_device */
	drm_connector_list_iter_begin(drm_dev, &conn_iter);
	for_each_intel_connector_iter(connector, &conn_iter) {
		u32 device_id, type;

		device_id = acpi_display_type(connector);

		/* Use display type specific display index. */
		type = (device_id & ACPI_DISPLAY_TYPE_MASK)
			>> ACPI_DISPLAY_TYPE_SHIFT;
		device_id |= display_index[type]++ << ACPI_DISPLAY_INDEX_SHIFT;

		connector->acpi_device_id = device_id;
	}
	drm_connector_list_iter_end(&conn_iter);
}
