// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Speed Select -- Enumerate and control features
 * Copyright (c) 2019 Intel Corporation.
 */

#include "isst.h"

static struct isst_platform_ops		*isst_ops;

#define CHECK_CB(_name)	\
	do {	\
		if (!isst_ops || !isst_ops->_name) {	\
			fprintf(stderr, "Invalid ops\n");	\
			exit(0);	\
		}	\
	} while (0)

int isst_set_platform_ops(int api_version)
{
	switch (api_version) {
	case 1:
		isst_ops = mbox_get_platform_ops();
		break;
	case 2:
		isst_ops = tpmi_get_platform_ops();
		break;
	default:
		isst_ops = NULL;
		break;
	}

	if (!isst_ops)
		return -1;
	return 0;
}

void isst_update_platform_param(enum isst_platform_param param, int value)
{
	CHECK_CB(update_platform_param);

	isst_ops->update_platform_param(param, value);
}

int isst_get_disp_freq_multiplier(void)
{
	CHECK_CB(get_disp_freq_multiplier);
	return isst_ops->get_disp_freq_multiplier();
}

int isst_get_trl_max_levels(void)
{
	CHECK_CB(get_trl_max_levels);
	return isst_ops->get_trl_max_levels();
}

char *isst_get_trl_level_name(int level)
{
	CHECK_CB(get_trl_level_name);
	return isst_ops->get_trl_level_name(level);
}

int isst_is_punit_valid(struct isst_id *id)
{
	CHECK_CB(is_punit_valid);
	return isst_ops->is_punit_valid(id);
}

int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
			  unsigned long long *req_resp)
{
	struct isst_if_msr_cmds msr_cmds;
	const char *pathname = "/dev/isst_interface";
	FILE *outf = get_output_file();
	int fd;

	fd = open(pathname, O_RDWR);
	if (fd < 0)
		err(-1, "%s open failed", pathname);

	msr_cmds.cmd_count = 1;
	msr_cmds.msr_cmd[0].logical_cpu = cpu;
	msr_cmds.msr_cmd[0].msr = msr;
	msr_cmds.msr_cmd[0].read_write = write;
	if (write)
		msr_cmds.msr_cmd[0].data = *req_resp;

	if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
		perror("ISST_IF_MSR_COMMAND");
		fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
			cpu, msr, write);
	} else {
		if (!write)
			*req_resp = msr_cmds.msr_cmd[0].data;

		debug_printf(
			"msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n",
			cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data);
	}

	close(fd);

	return 0;
}

int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap)
{
	CHECK_CB(read_pm_config);
	return isst_ops->read_pm_config(id, cp_state, cp_cap);
}

int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
{
	CHECK_CB(get_config_levels);
	return isst_ops->get_config_levels(id, pkg_dev);
}

int isst_get_ctdp_control(struct isst_id *id, int config_index,
			  struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(get_ctdp_control);
	return isst_ops->get_ctdp_control(id, config_index, ctdp_level);
}

int isst_get_tdp_info(struct isst_id *id, int config_index,
		      struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(get_tdp_info);
	return isst_ops->get_tdp_info(id, config_index, ctdp_level);
}

int isst_get_pwr_info(struct isst_id *id, int config_index,
		      struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(get_pwr_info);
	return isst_ops->get_pwr_info(id, config_index, ctdp_level);
}

int isst_get_coremask_info(struct isst_id *id, int config_index,
			   struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(get_coremask_info);
	return isst_ops->get_coremask_info(id, config_index, ctdp_level);
}

int isst_get_get_trl_from_msr(struct isst_id *id, int *trl)
{
	unsigned long long msr_trl;
	int ret;

	ret = isst_send_msr_command(id->cpu, 0x1AD, 0, &msr_trl);
	if (ret)
		return ret;

	trl[0] = msr_trl & GENMASK(7, 0);
	trl[1] = (msr_trl & GENMASK(15, 8)) >> 8;
	trl[2] = (msr_trl & GENMASK(23, 16)) >> 16;
	trl[3] = (msr_trl & GENMASK(31, 24)) >> 24;
	trl[4] = (msr_trl & GENMASK(39, 32)) >> 32;
	trl[5] = (msr_trl & GENMASK(47, 40)) >> 40;
	trl[6] = (msr_trl & GENMASK(55, 48)) >> 48;
	trl[7] = (msr_trl & GENMASK(63, 56)) >> 56;

	return 0;
}

int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl)
{
	CHECK_CB(get_get_trl);
	return isst_ops->get_get_trl(id, level, avx_level, trl);
}

int isst_get_get_trls(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(get_get_trls);
	return isst_ops->get_get_trls(id, level, ctdp_level);
}

int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info)
{
	CHECK_CB(get_trl_bucket_info);
	return isst_ops->get_trl_bucket_info(id, level, buckets_info);
}

int isst_set_tdp_level(struct isst_id *id, int tdp_level)
{
	CHECK_CB(set_tdp_level);
	return isst_ops->set_tdp_level(id, tdp_level);
}

int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info)
{
	struct isst_pkg_ctdp_level_info ctdp_level;
	struct isst_pkg_ctdp pkg_dev;
	int ret;

	ret = isst_get_ctdp_levels(id, &pkg_dev);
	if (ret) {
		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
		return ret;
	}

	if (level > pkg_dev.levels) {
		isst_display_error_info_message(1, "Invalid level", 1, level);
		return -1;
	}

	ret = isst_get_ctdp_control(id, level, &ctdp_level);
	if (ret)
		return ret;

	if (!ctdp_level.pbf_support) {
		isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
		return -1;
	}

	pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);

	CHECK_CB(get_pbf_info);
	return isst_ops->get_pbf_info(id, level, pbf_info);
}

int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable)
{
	CHECK_CB(set_pbf_fact_status);
	return isst_ops->set_pbf_fact_status(id, pbf, enable);
}



int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info)
{
	struct isst_pkg_ctdp_level_info ctdp_level;
	struct isst_pkg_ctdp pkg_dev;
	int ret;

	ret = isst_get_ctdp_levels(id, &pkg_dev);
	if (ret) {
		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
		return ret;
	}

	if (level > pkg_dev.levels) {
		isst_display_error_info_message(1, "Invalid level", 1, level);
		return -1;
	}

	ret = isst_get_ctdp_control(id, level, &ctdp_level);
	if (ret)
		return ret;

	if (!ctdp_level.fact_support) {
		isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
		return -1;
	}
	CHECK_CB(get_fact_info);
	return isst_ops->get_fact_info(id, level, fact_bucket, fact_info);
}

int isst_get_trl(struct isst_id *id, unsigned long long *trl)
{
	int ret;

	ret = isst_send_msr_command(id->cpu, 0x1AD, 0, trl);
	if (ret)
		return ret;

	return 0;
}

int isst_set_trl(struct isst_id *id, unsigned long long trl)
{
	int ret;

	if (!trl)
		trl = 0xFFFFFFFFFFFFFFFFULL;

	ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &trl);
	if (ret)
		return ret;

	return 0;
}

int isst_set_trl_from_current_tdp(struct isst_id *id, unsigned long long trl)
{
	unsigned long long msr_trl;
	int ret;

	if (id->cpu < 0)
		return 0;

	if (trl) {
		msr_trl = trl;
	} else {
		struct isst_pkg_ctdp pkg_dev;
		int trl[8];
		int i;

		ret = isst_get_ctdp_levels(id, &pkg_dev);
		if (ret)
			return ret;

		ret = isst_get_get_trl(id, pkg_dev.current_level, 0, trl);
		if (ret)
			return ret;

		msr_trl = 0;
		for (i = 0; i < 8; ++i) {
			unsigned long long _trl = trl[i];

			msr_trl |= (_trl << (i * 8));
		}
	}
	ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &msr_trl);
	if (ret)
		return ret;

	return 0;
}

/* Return 1 if locked */
int isst_get_config_tdp_lock_status(struct isst_id *id)
{
	unsigned long long tdp_control = 0;
	int ret;

	ret = isst_send_msr_command(id->cpu, 0x64b, 0, &tdp_control);
	if (ret)
		return ret;

	ret = !!(tdp_control & BIT(31));

	return ret;
}

void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
{
	int i;

	if (!pkg_dev->processed)
		return;

	for (i = 0; i < pkg_dev->levels; ++i) {
		struct isst_pkg_ctdp_level_info *ctdp_level;

		ctdp_level = &pkg_dev->ctdp_level[i];
		if (ctdp_level->pbf_support)
			free_cpu_set(ctdp_level->pbf_info.core_cpumask);
		free_cpu_set(ctdp_level->core_cpumask);
	}
}

void isst_adjust_uncore_freq(struct isst_id *id, int config_index,
				struct isst_pkg_ctdp_level_info *ctdp_level)
{
	CHECK_CB(adjust_uncore_freq);
	return isst_ops->adjust_uncore_freq(id, config_index, ctdp_level);
}

int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
{
	int i, ret, valid = 0;

	if (pkg_dev->processed)
		return 0;

	ret = isst_get_ctdp_levels(id, pkg_dev);
	if (ret)
		return ret;

	debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
		     id->cpu, pkg_dev->enabled, pkg_dev->current_level,
		     pkg_dev->levels);

	if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
		isst_display_error_info_message(1, "Invalid level", 0, 0);
		return -1;
	}

	if (!pkg_dev->enabled)
		isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);

	for (i = 0; i <= pkg_dev->levels; ++i) {
		struct isst_pkg_ctdp_level_info *ctdp_level;

		if (tdp_level != 0xff && i != tdp_level)
			continue;

		debug_printf("cpu:%d Get Information for TDP level:%d\n", id->cpu,
			     i);
		ctdp_level = &pkg_dev->ctdp_level[i];

		ctdp_level->level = i;
		ctdp_level->control_cpu = id->cpu;
		ctdp_level->pkg_id = id->pkg;
		ctdp_level->die_id = id->die;

		ret = isst_get_ctdp_control(id, i, ctdp_level);
		if (ret)
			continue;

		valid = 1;
		pkg_dev->processed = 1;
		ctdp_level->processed = 1;

		if (ctdp_level->pbf_support) {
			ret = isst_get_pbf_info(id, i, &ctdp_level->pbf_info);
			if (!ret)
				ctdp_level->pbf_found = 1;
		}

		if (ctdp_level->fact_support) {
			ret = isst_get_fact_info(id, i, 0xff,
						 &ctdp_level->fact_info);
			if (ret)
				return ret;
		}

		if (!pkg_dev->enabled && is_skx_based_platform()) {
			int freq;

			freq = get_cpufreq_base_freq(id->cpu);
			if (freq > 0) {
				ctdp_level->sse_p1 = freq / 100000;
				ctdp_level->tdp_ratio = ctdp_level->sse_p1;
			}

			isst_get_get_trl_from_msr(id, ctdp_level->trl_ratios[0]);
			isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
			continue;
		}

		ret = isst_get_tdp_info(id, i, ctdp_level);
		if (ret)
			return ret;

		ret = isst_get_pwr_info(id, i, ctdp_level);
		if (ret)
			return ret;

		ctdp_level->core_cpumask_size =
			alloc_cpu_set(&ctdp_level->core_cpumask);
		ret = isst_get_coremask_info(id, i, ctdp_level);
		if (ret)
			return ret;

		ret = isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
		if (ret)
			return ret;

		ret = isst_get_get_trls(id, i, ctdp_level);
		if (ret)
			return ret;
	}

	if (!valid)
		isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, id->cpu);

	return 0;
}

int isst_clos_get_clos_information(struct isst_id *id, int *enable, int *type)
{
	CHECK_CB(get_clos_information);
	return isst_ops->get_clos_information(id, enable, type);
}

int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type)
{
	CHECK_CB(pm_qos_config);
	return isst_ops->pm_qos_config(id, enable_clos, priority_type);
}

int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
{
	CHECK_CB(pm_get_clos);
	return isst_ops->pm_get_clos(id, clos, clos_config);
}

int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
{
	CHECK_CB(set_clos);
	return isst_ops->set_clos(id, clos, clos_config);
}

int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id)
{
	CHECK_CB(clos_get_assoc_status);
	return isst_ops->clos_get_assoc_status(id, clos_id);
}

int isst_clos_associate(struct isst_id *id, int clos_id)
{
	CHECK_CB(clos_associate);
	return isst_ops->clos_associate(id, clos_id);

}
