/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpigen.h>
#include <acpi/acpigen_dptf.h>
#include <stdbool.h>
#include <stdint.h>

/* Defaults */
#define DEFAULT_RAW_UNIT		"ma"

/* DPTF-specific UUIDs */
#define DPTF_PASSIVE_POLICY_1_0_UUID	"42A441D6-AE6A-462B-A84B-4A8CE79027D3"
#define DPTF_CRITICAL_POLICY_UUID	"97C68AE7-15FA-499c-B8C9-5DA81D606E0A"
#define DPTF_ACTIVE_POLICY_UUID		"3A95C389-E4B8-4629-A526-C52C88626BAE"

enum {
	ART_REVISION			= 0,
	DEFAULT_PRIORITY		= 100,
	DEFAULT_TRIP_POINT		= 0xFFFFFFFFull,
	DEFAULT_WEIGHT			= 100,
	DPTF_MAX_ART_THRESHOLDS		= 10,
	FPS_REVISION			= 0,
	PPCC_REVISION			= 2,
	RAPL_PL1_INDEX			= 0,
	RAPL_PL2_INDEX			= 1,
};

/* Convert degrees C to 1/10 degree Kelvin for ACPI */
static int to_acpi_temp(int deg_c)
{
	return deg_c * 10 + 2732;
}

/* Converts ms to 1/10th second for ACPI */
static int to_acpi_time(int ms)
{
	return ms / 100;
}

/* Writes out a 0-argument non-Serialized Method that returns an Integer */
static void write_simple_return_method(const char *name, int value)
{
	acpigen_write_method(name, 0);
	acpigen_write_return_integer(value);
	acpigen_pop_len(); /* Method */
}

/* Writes out 'count' ZEROs in a row */
static void write_zeros(int count)
{
	for (; count; --count)
		acpigen_write_integer(0);
}

/* Return the assigned namestring of any participant */
static const char *namestring_of(enum dptf_participant participant)
{
	switch (participant) {
	case DPTF_CPU:
		return "TCPU";
	case DPTF_CHARGER:
		return "TCHG";
	case DPTF_FAN:
		return "TFN1";
	case DPTF_TEMP_SENSOR_0:
		return "TSR0";
	case DPTF_TEMP_SENSOR_1:
		return "TSR1";
	case DPTF_TEMP_SENSOR_2:
		return "TSR2";
	case DPTF_TEMP_SENSOR_3:
		return "TSR3";
	case DPTF_TPCH:
		return "TPCH";
	default:
		return "";
	}
}

/* Helper to get Scope for participants underneath \_SB.DPTF */
static const char *scope_of(enum dptf_participant participant)
{
	static char scope[16];

	if (participant == DPTF_CPU)
		snprintf(scope, sizeof(scope), TCPU_SCOPE ".%s", namestring_of(participant));
	else
		snprintf(scope, sizeof(scope), DPTF_DEVICE_PATH ".%s",
			 namestring_of(participant));

	return scope;
}

/*
 * Most of the DPTF participants are underneath the \_SB.DPTF scope, so we can just get away
 * with using the simple namestring for references, but the TCPU has a different scope, so
 * either an absolute or relative path must be used instead.
 */
static const char *path_of(enum dptf_participant participant)
{
	if (participant == DPTF_CPU)
		return scope_of(participant);
	else
		return namestring_of(participant);
}

/* Write out scope of a participant */
void dptf_write_scope(enum dptf_participant participant)
{
	acpigen_write_scope(scope_of(participant));
}

/*
 * This table describes active cooling relationships between the system's fan and the
 * temperature sensors that it can have an effect on. As ever-increasing temperature thresholds
 * are crossed (_AC9.._AC0, low to high), the corresponding fan percentages listed in this table
 * are used to increase the speed of the fan in order to speed up cooling.
 */
static void write_active_relationship_table(const struct dptf_active_policy *policies,
					    int max_count)
{
	char *pkg_count;
	int i, j;

	/* Nothing to do */
	if (!max_count || policies[0].target == DPTF_NONE)
		return;

	acpigen_write_scope(DPTF_DEVICE_PATH);
	acpigen_write_method("_ART", 0);

	/* Return this package */
	acpigen_emit_byte(RETURN_OP);

	/* Keep track of items added to the package */
	pkg_count = acpigen_write_package(1); /* The '1' here is for the revision */
	acpigen_write_integer(ART_REVISION);

	for (i = 0; i < max_count; ++i) {
		/*
		 * These have to be filled out from AC0 down to AC9, filling in only as many
		 * as are used. As soon as one isn't filled in, we're done.
		 */
		if (policies[i].target == DPTF_NONE)
			break;

		(*pkg_count)++;

		/* Source, Target, Percent, Fan % for each of _AC0 ... _AC9 */
		acpigen_write_package(13);
		acpigen_emit_namestring(path_of(DPTF_FAN));
		acpigen_emit_namestring(path_of(policies[i].target));
		acpigen_write_integer(DEFAULT_IF_0(policies[i].weight, DEFAULT_WEIGHT));

		/* Write out fan %; corresponds with target's _ACx methods */
		for (j = 0; j < DPTF_MAX_ART_THRESHOLDS; ++j)
			acpigen_write_integer(policies[i].thresholds[j].fan_pct);

		acpigen_pop_len(); /* inner Package */
	}

	acpigen_pop_len(); /* outer Package */
	acpigen_pop_len(); /* Method _ART */
	acpigen_pop_len(); /* Scope */
}

/*
 * _AC9 through _AC0 represent temperature thresholds, in increasing order, defined from _AC0
 * down, that, when reached, DPTF will activate TFN1 in order to actively cool the temperature
 * sensor(s). As increasing thresholds are reached, the fan is spun faster.
 */
static void write_active_cooling_methods(const struct dptf_active_policy *policies,
					 int max_count)
{
	char name[5];
	int i, j;

	/* Nothing to do */
	if (!max_count || policies[0].target == DPTF_NONE)
		return;

	for (i = 0; i < max_count; ++i) {
		if (policies[i].target == DPTF_NONE)
			break;

		dptf_write_scope(policies[i].target);

		/* Write out as many of _AC0 through _AC9 that are applicable */
		for (j = 0; j < DPTF_MAX_ACX; ++j) {
			if (!policies[i].thresholds[j].temp)
				break;

			snprintf(name, sizeof(name), "_AC%1X", j);
			write_simple_return_method(name, to_acpi_temp(
							   policies[i].thresholds[j].temp));
		}

		acpigen_pop_len(); /* Scope */
	}
}

void dptf_write_active_policies(const struct dptf_active_policy *policies, int max_count)
{
	write_active_relationship_table(policies, max_count);
	write_active_cooling_methods(policies, max_count);
}

/*
 * This writes out the Thermal Relationship Table, which describes the thermal relationships
 * between participants in a thermal zone. This information is used to passively cool (i.e.,
 * throttle) the Source (source of heat), in order to indirectly cool the Target (temperature
 * sensor).
 */
static void write_thermal_relationship_table(const struct dptf_passive_policy *policies,
					     int max_count)
{
	char *pkg_count;
	int i;

	/* Nothing to do */
	if (!max_count || policies[0].source == DPTF_NONE)
		return;

	acpigen_write_scope(DPTF_DEVICE_PATH);

	/*
	 * A _TRT Revision (TRTR) of 1 means that the 'Priority' field is an arbitrary priority
	 * value to be used for this specific relationship. The priority value determines the
	 * order in which various sources are used in a passive thermal action for a given
	 * target.
	 */
	acpigen_write_name_integer("TRTR", 1);

	/* Thermal Relationship Table */
	acpigen_write_method("_TRT", 0);

	/* Return this package */
	acpigen_emit_byte(RETURN_OP);
	pkg_count = acpigen_write_package(0);

	for (i = 0; i < max_count; ++i) {
		/* Stop writing the table once an entry is empty */
		if (policies[i].source == DPTF_NONE)
			break;

		/* Keep track of outer package item count */
		(*pkg_count)++;

		acpigen_write_package(8);

		/* Source, Target, Priority, Sampling Period */
		acpigen_emit_namestring(path_of(policies[i].source));
		acpigen_emit_namestring(path_of(policies[i].target));
		acpigen_write_integer(DEFAULT_IF_0(policies[i].priority, DEFAULT_PRIORITY));
		acpigen_write_integer(to_acpi_time(policies[i].period));

		/* Reserved */
		write_zeros(4);

		acpigen_pop_len(); /* Package */
	}

	acpigen_pop_len(); /* Package */
	acpigen_pop_len(); /* Method */
	acpigen_pop_len(); /* Scope */
}

/*
 * When a temperature sensor measures above its the temperature returned in its _PSV Method,
 * DPTF will begin throttling Sources in order to indirectly cool the sensor.
 */
static void write_all_PSV(const struct dptf_passive_policy *policies, int max_count)
{
	int i;

	for (i = 0; i < max_count; ++i) {
		if (policies[i].source == DPTF_NONE)
			break;

		dptf_write_scope(policies[i].target);
		write_simple_return_method("_PSV", to_acpi_temp(policies[i].temp));
		acpigen_pop_len(); /* Scope */
	}
}

void dptf_write_passive_policies(const struct dptf_passive_policy *policies, int max_count)
{
	write_thermal_relationship_table(policies, max_count);
	write_all_PSV(policies, max_count);
}

void dptf_write_critical_policies(const struct dptf_critical_policy *policies, int max_count)
{
	int i;

	for (i = 0; i < max_count; ++i) {
		if (policies[i].source == DPTF_NONE)
			break;

		dptf_write_scope(policies[i].source);

		/* Choose _CRT or _HOT */
		write_simple_return_method(policies[i].type == DPTF_CRITICAL_SHUTDOWN ?
					   "_CRT" : "_HOT", to_acpi_temp(policies[i].temp));

		acpigen_pop_len(); /* Scope */
	}
}

void dptf_write_charger_perf(const struct dptf_charger_perf *states, int max_count)
{
	char *pkg_count;
	int i;

	if (!max_count || !states[0].control)
		return;

	dptf_write_scope(DPTF_CHARGER);

	/* PPSS - Participant Performance Supported States */
	acpigen_write_method("PPSS", 0);
	acpigen_emit_byte(RETURN_OP);

	pkg_count = acpigen_write_package(0);
	for (i = 0; i < max_count; ++i) {
		if (!states[i].control)
			break;

		(*pkg_count)++;

		/*
		 * 0, 0, 0, 0, # Reserved
		 * Control, Raw Performance, Raw Unit, 0 # Reserved
		 */
		acpigen_write_package(8);
		write_zeros(4);
		acpigen_write_integer(states[i].control);
		acpigen_write_integer(states[i].raw_perf);
		acpigen_write_string(DEFAULT_RAW_UNIT);
		acpigen_write_integer(0);
		acpigen_pop_len(); /* inner Package */
	}

	acpigen_pop_len(); /* outer Package */
	acpigen_pop_len(); /* Method PPSS */
	acpigen_pop_len(); /* Scope */
}

void dptf_write_fan_perf(const struct dptf_fan_perf *states, int max_count)
{
	char *pkg_count;
	int i;

	if (!max_count || !states[0].percent)
		return;

	dptf_write_scope(DPTF_FAN);

	/* _FPS - Fan Performance States */
	acpigen_write_name("_FPS");
	pkg_count = acpigen_write_package(1); /* 1 for Revision */
	acpigen_write_integer(FPS_REVISION); /* revision */

	for (i = 0; i < max_count; ++i) {
		/*
		 * Some _FPS tables do include a last entry where Percent is 0, but Power is
		 * called out, so this table is finished when both are zero.
		 */
		if (!states[i].percent && !states[i].power)
			break;

		(*pkg_count)++;
		acpigen_write_package(5);
		acpigen_write_integer(states[i].percent);
		acpigen_write_integer(DEFAULT_TRIP_POINT);
		acpigen_write_integer(states[i].speed);
		acpigen_write_integer(states[i].noise_level);
		acpigen_write_integer(states[i].power);
		acpigen_pop_len(); /* inner Package */
	}

	acpigen_pop_len(); /* Package */
	acpigen_pop_len(); /* Scope */
}

void dptf_write_power_limits(const struct dptf_power_limits *limits)
{
	char *pkg_count;

	/* Nothing to do */
	if (!limits->pl1.min_power && !limits->pl2.min_power)
		return;

	dptf_write_scope(DPTF_CPU);
	acpigen_write_method("PPCC", 0);

	pkg_count = acpigen_write_package(1); /* 1 for the Revision */
	acpigen_write_integer(PPCC_REVISION); /* revision */

	if (limits->pl1.min_power) {
		(*pkg_count)++;
		acpigen_write_package(6);
		acpigen_write_integer(RAPL_PL1_INDEX);
		acpigen_write_integer(limits->pl1.min_power);
		acpigen_write_integer(limits->pl1.max_power);
		acpigen_write_integer(limits->pl1.time_window_min);
		acpigen_write_integer(limits->pl1.time_window_max);
		acpigen_write_integer(limits->pl1.granularity);
		acpigen_pop_len(); /* inner Package */
	}

	if (limits->pl2.min_power) {
		(*pkg_count)++;
		acpigen_write_package(6);
		acpigen_write_integer(RAPL_PL2_INDEX);
		acpigen_write_integer(limits->pl2.min_power);
		acpigen_write_integer(limits->pl2.max_power);
		acpigen_write_integer(limits->pl2.time_window_min);
		acpigen_write_integer(limits->pl2.time_window_max);
		acpigen_write_integer(limits->pl2.granularity);
		acpigen_pop_len(); /* inner Package */
	}

	acpigen_pop_len(); /* outer Package */
	acpigen_pop_len(); /* Method */
	acpigen_pop_len(); /* Scope */
}

void dptf_write_STR(const char *str)
{
	if (!str)
		return;

	acpigen_write_name_string("_STR", str);
}

void dptf_write_fan_options(bool fine_grained, int step_size, bool low_speed_notify)
{
	acpigen_write_name("_FIF");
	acpigen_write_package(4);

	acpigen_write_integer(0); /* Revision */
	acpigen_write_integer(fine_grained);
	acpigen_write_integer(step_size);
	acpigen_write_integer(low_speed_notify);
	acpigen_pop_len(); /* Package */
}

void dptf_write_tsr_hysteresis(uint8_t hysteresis)
{
	if (!hysteresis)
		return;

	acpigen_write_name_integer("GTSH", hysteresis);
}

void dptf_write_enabled_policies(const struct dptf_active_policy *active_policies,
				 int active_count,
				 const struct dptf_passive_policy *passive_policies,
				 int passive_count,
				 const struct dptf_critical_policy *critical_policies,
				 int critical_count)
{
	bool is_active_used;
	bool is_passive_used;
	bool is_critical_used;
	int pkg_count;

	is_active_used = (active_count && active_policies[0].target != DPTF_NONE);
	is_passive_used = (passive_count && passive_policies[0].target != DPTF_NONE);
	is_critical_used = (critical_count && critical_policies[0].source != DPTF_NONE);
	pkg_count = is_active_used + is_passive_used + is_critical_used;

	if (!pkg_count)
		return;

	acpigen_write_scope(DPTF_DEVICE_PATH);
	acpigen_write_name("IDSP");
	acpigen_write_package(pkg_count);

	if (is_active_used)
		acpigen_write_uuid(DPTF_ACTIVE_POLICY_UUID);

	if (is_passive_used)
		acpigen_write_uuid(DPTF_PASSIVE_POLICY_1_0_UUID);

	if (is_critical_used)
		acpigen_write_uuid(DPTF_CRITICAL_POLICY_UUID);

	acpigen_pop_len(); /* Package */
	acpigen_pop_len(); /* Scope */
}
