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

#include <acpi/acpigen.h>
#include <acpi/acpigen_dptf.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.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_FAN_2:
		return "TFN2";
	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_TEMP_SENSOR_4:
		return "TSR4";
	case DPTF_TPCH:
		return "TPCH";
	case DPTF_POWER:
		return "TPWR";
	case DPTF_BATTERY:
		return "TBAT";
	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, bool dptf_multifan_support)
{
	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);
		if (dptf_multifan_support)
			acpigen_emit_namestring(path_of(policies[i].source));
		else
			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, bool dptf_multifan_support)
{
	write_active_relationship_table(policies, max_count, dptf_multifan_support);
	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 */
}

int dptf_write_fan_perf_fps(uint8_t percent, uint16_t power, uint16_t speed,
		uint16_t noise_level)
{
	/*
	 * 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 (!percent && !power)
		return 1;

	acpigen_write_package(5);
	acpigen_write_integer(percent);
	acpigen_write_integer(DEFAULT_TRIP_POINT);
	acpigen_write_integer(speed);
	acpigen_write_integer(noise_level);
	acpigen_write_integer(power);
	acpigen_pop_len(); /* inner Package */

	return 0;
}

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

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

	dptf_write_scope(participant);

	/* _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) {
		(*pkg_count)++;
		if (dptf_write_fan_perf_fps(states[i].percent, states[i].power,
			states[i].speed, states[i].noise_level))
			break;
	}

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

void dptf_write_multifan_perf(
		const struct dptf_multifan_perf
			states[DPTF_MAX_FAN_PARTICIPANTS][DPTF_MAX_FAN_PERF_STATES],
		int max_count, enum dptf_participant participant, int fan_num)
{
	char *pkg_count;
	int i;

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

	dptf_write_scope(participant);

	/* _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) {
		(*pkg_count)++;
		if (dptf_write_fan_perf_fps(states[fan_num][i].percent, states[fan_num][i].power,
				states[fan_num][i].speed, states[fan_num][i].noise_level))
			break;
	}

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

	acpigen_emit_byte(RETURN_OP);

	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_unicode("_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 */
}
