// SPDX-License-Identifier: GPL-2.0-only
/*
 * intel_powerclamp.c - package c-state idle injection
 *
 * Copyright (c) 2012-2023, Intel Corporation.
 *
 * Authors:
 *     Arjan van de Ven <arjan@linux.intel.com>
 *     Jacob Pan <jacob.jun.pan@linux.intel.com>
 *
 *	TODO:
 *           1. better handle wakeup from external interrupts, currently a fixed
 *              compensation is added to clamping duration when excessive amount
 *              of wakeups are observed during idle time. the reason is that in
 *              case of external interrupts without need for ack, clamping down
 *              cpu in non-irq context does not reduce irq. for majority of the
 *              cases, clamping down cpu does help reduce irq as well, we should
 *              be able to differentiate the two cases and give a quantitative
 *              solution for the irqs that we can control. perhaps based on
 *              get_cpu_iowait_time_us()
 *
 *	     2. synchronization with other hw blocks
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/cpu.h>
#include <linux/thermal.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/idle_inject.h>

#include <asm/msr.h>
#include <asm/mwait.h>
#include <asm/cpu_device_id.h>

#define MAX_TARGET_RATIO (100U)
/* For each undisturbed clamping period (no extra wake ups during idle time),
 * we increment the confidence counter for the given target ratio.
 * CONFIDENCE_OK defines the level where runtime calibration results are
 * valid.
 */
#define CONFIDENCE_OK (3)
/* Default idle injection duration, driver adjust sleep time to meet target
 * idle ratio. Similar to frequency modulation.
 */
#define DEFAULT_DURATION_JIFFIES (6)

static struct dentry *debug_dir;
static bool poll_pkg_cstate_enable;

/* Idle ratio observed using package C-state counters */
static unsigned int current_ratio;

/* Skip the idle injection till set to true */
static bool should_skip;

struct powerclamp_data {
	unsigned int cpu;
	unsigned int count;
	unsigned int guard;
	unsigned int window_size_now;
	unsigned int target_ratio;
	bool clamping;
};

static struct powerclamp_data powerclamp_data;

static struct thermal_cooling_device *cooling_dev;

static DEFINE_MUTEX(powerclamp_lock);

/* This duration is in microseconds */
static unsigned int duration;
static unsigned int pkg_cstate_ratio_cur;
static unsigned int window_size;

static int duration_set(const char *arg, const struct kernel_param *kp)
{
	int ret = 0;
	unsigned long new_duration;

	ret = kstrtoul(arg, 10, &new_duration);
	if (ret)
		goto exit;
	if (new_duration > 25 || new_duration < 6) {
		pr_err("Out of recommended range %lu, between 6-25ms\n",
			new_duration);
		ret = -EINVAL;
		goto exit;
	}

	mutex_lock(&powerclamp_lock);
	duration = clamp(new_duration, 6ul, 25ul) * 1000;
	mutex_unlock(&powerclamp_lock);
exit:

	return ret;
}

static int duration_get(char *buf, const struct kernel_param *kp)
{
	int ret;

	mutex_lock(&powerclamp_lock);
	ret = sysfs_emit(buf, "%d\n", duration / 1000);
	mutex_unlock(&powerclamp_lock);

	return ret;
}

static const struct kernel_param_ops duration_ops = {
	.set = duration_set,
	.get = duration_get,
};

module_param_cb(duration, &duration_ops, NULL, 0644);
MODULE_PARM_DESC(duration, "forced idle time for each attempt in msec.");

#define DEFAULT_MAX_IDLE	50
#define MAX_ALL_CPU_IDLE	75

static u8 max_idle = DEFAULT_MAX_IDLE;

static cpumask_var_t idle_injection_cpu_mask;

static int allocate_copy_idle_injection_mask(const struct cpumask *copy_mask)
{
	if (cpumask_available(idle_injection_cpu_mask))
		goto copy_mask;

	/* This mask is allocated only one time and freed during module exit */
	if (!alloc_cpumask_var(&idle_injection_cpu_mask, GFP_KERNEL))
		return -ENOMEM;

copy_mask:
	cpumask_copy(idle_injection_cpu_mask, copy_mask);

	return 0;
}

/* Return true if the cpumask and idle percent combination is invalid */
static bool check_invalid(cpumask_var_t mask, u8 idle)
{
	if (cpumask_equal(cpu_present_mask, mask) && idle > MAX_ALL_CPU_IDLE)
		return true;

	return false;
}

static int cpumask_set(const char *arg, const struct kernel_param *kp)
{
	cpumask_var_t new_mask;
	int ret;

	mutex_lock(&powerclamp_lock);

	/* Can't set mask when cooling device is in use */
	if (powerclamp_data.clamping) {
		ret = -EAGAIN;
		goto skip_cpumask_set;
	}

	ret = alloc_cpumask_var(&new_mask, GFP_KERNEL);
	if (!ret)
		goto skip_cpumask_set;

	ret = bitmap_parse(arg, strlen(arg), cpumask_bits(new_mask),
			   nr_cpumask_bits);
	if (ret)
		goto free_cpumask_set;

	if (cpumask_empty(new_mask) || check_invalid(new_mask, max_idle)) {
		ret = -EINVAL;
		goto free_cpumask_set;
	}

	/*
	 * When module parameters are passed from kernel command line
	 * during insmod, the module parameter callback is called
	 * before powerclamp_init(), so we can't assume that some
	 * cpumask can be allocated and copied before here. Also
	 * in this case this cpumask is used as the default mask.
	 */
	ret = allocate_copy_idle_injection_mask(new_mask);

free_cpumask_set:
	free_cpumask_var(new_mask);
skip_cpumask_set:
	mutex_unlock(&powerclamp_lock);

	return ret;
}

static int cpumask_get(char *buf, const struct kernel_param *kp)
{
	if (!cpumask_available(idle_injection_cpu_mask))
		return -ENODEV;

	return bitmap_print_to_pagebuf(false, buf, cpumask_bits(idle_injection_cpu_mask),
				       nr_cpumask_bits);
}

static const struct kernel_param_ops cpumask_ops = {
	.set = cpumask_set,
	.get = cpumask_get,
};

module_param_cb(cpumask, &cpumask_ops, NULL, 0644);
MODULE_PARM_DESC(cpumask, "Mask of CPUs to use for idle injection.");

static int max_idle_set(const char *arg, const struct kernel_param *kp)
{
	u8 new_max_idle;
	int ret = 0;

	mutex_lock(&powerclamp_lock);

	/* Can't set mask when cooling device is in use */
	if (powerclamp_data.clamping) {
		ret = -EAGAIN;
		goto skip_limit_set;
	}

	ret = kstrtou8(arg, 10, &new_max_idle);
	if (ret)
		goto skip_limit_set;

	if (new_max_idle > MAX_TARGET_RATIO) {
		ret = -EINVAL;
		goto skip_limit_set;
	}

	if (!cpumask_available(idle_injection_cpu_mask)) {
		ret = allocate_copy_idle_injection_mask(cpu_present_mask);
		if (ret)
			goto skip_limit_set;
	}

	if (check_invalid(idle_injection_cpu_mask, new_max_idle)) {
		ret = -EINVAL;
		goto skip_limit_set;
	}

	max_idle = new_max_idle;

skip_limit_set:
	mutex_unlock(&powerclamp_lock);

	return ret;
}

static const struct kernel_param_ops max_idle_ops = {
	.set = max_idle_set,
	.get = param_get_byte,
};

module_param_cb(max_idle, &max_idle_ops, &max_idle, 0644);
MODULE_PARM_DESC(max_idle, "maximum injected idle time to the total CPU time ratio in percent range:1-100");

struct powerclamp_calibration_data {
	unsigned long confidence;  /* used for calibration, basically a counter
				    * gets incremented each time a clamping
				    * period is completed without extra wakeups
				    * once that counter is reached given level,
				    * compensation is deemed usable.
				    */
	unsigned long steady_comp; /* steady state compensation used when
				    * no extra wakeups occurred.
				    */
	unsigned long dynamic_comp; /* compensate excessive wakeup from idle
				     * mostly from external interrupts.
				     */
};

static struct powerclamp_calibration_data cal_data[MAX_TARGET_RATIO];

static int window_size_set(const char *arg, const struct kernel_param *kp)
{
	int ret = 0;
	unsigned long new_window_size;

	ret = kstrtoul(arg, 10, &new_window_size);
	if (ret)
		goto exit_win;
	if (new_window_size > 10 || new_window_size < 2) {
		pr_err("Out of recommended window size %lu, between 2-10\n",
			new_window_size);
		ret = -EINVAL;
	}

	window_size = clamp(new_window_size, 2ul, 10ul);
	smp_mb();

exit_win:

	return ret;
}

static const struct kernel_param_ops window_size_ops = {
	.set = window_size_set,
	.get = param_get_int,
};

module_param_cb(window_size, &window_size_ops, &window_size, 0644);
MODULE_PARM_DESC(window_size, "sliding window in number of clamping cycles\n"
	"\tpowerclamp controls idle ratio within this window. larger\n"
	"\twindow size results in slower response time but more smooth\n"
	"\tclamping results. default to 2.");

struct pkg_cstate_info {
	bool skip;
	int msr_index;
	int cstate_id;
};

#define PKG_CSTATE_INIT(id) {				\
		.msr_index = MSR_PKG_C##id##_RESIDENCY, \
		.cstate_id = id				\
			}

static struct pkg_cstate_info pkg_cstates[] = {
	PKG_CSTATE_INIT(2),
	PKG_CSTATE_INIT(3),
	PKG_CSTATE_INIT(6),
	PKG_CSTATE_INIT(7),
	PKG_CSTATE_INIT(8),
	PKG_CSTATE_INIT(9),
	PKG_CSTATE_INIT(10),
	{NULL},
};

static bool has_pkg_state_counter(void)
{
	u64 val;
	struct pkg_cstate_info *info = pkg_cstates;

	/* check if any one of the counter msrs exists */
	while (info->msr_index) {
		if (!rdmsrl_safe(info->msr_index, &val))
			return true;
		info++;
	}

	return false;
}

static u64 pkg_state_counter(void)
{
	u64 val;
	u64 count = 0;
	struct pkg_cstate_info *info = pkg_cstates;

	while (info->msr_index) {
		if (!info->skip) {
			if (!rdmsrl_safe(info->msr_index, &val))
				count += val;
			else
				info->skip = true;
		}
		info++;
	}

	return count;
}

static unsigned int get_compensation(int ratio)
{
	unsigned int comp = 0;

	if (!poll_pkg_cstate_enable)
		return 0;

	/* we only use compensation if all adjacent ones are good */
	if (ratio == 1 &&
		cal_data[ratio].confidence >= CONFIDENCE_OK &&
		cal_data[ratio + 1].confidence >= CONFIDENCE_OK &&
		cal_data[ratio + 2].confidence >= CONFIDENCE_OK) {
		comp = (cal_data[ratio].steady_comp +
			cal_data[ratio + 1].steady_comp +
			cal_data[ratio + 2].steady_comp) / 3;
	} else if (ratio == MAX_TARGET_RATIO - 1 &&
		cal_data[ratio].confidence >= CONFIDENCE_OK &&
		cal_data[ratio - 1].confidence >= CONFIDENCE_OK &&
		cal_data[ratio - 2].confidence >= CONFIDENCE_OK) {
		comp = (cal_data[ratio].steady_comp +
			cal_data[ratio - 1].steady_comp +
			cal_data[ratio - 2].steady_comp) / 3;
	} else if (cal_data[ratio].confidence >= CONFIDENCE_OK &&
		cal_data[ratio - 1].confidence >= CONFIDENCE_OK &&
		cal_data[ratio + 1].confidence >= CONFIDENCE_OK) {
		comp = (cal_data[ratio].steady_comp +
			cal_data[ratio - 1].steady_comp +
			cal_data[ratio + 1].steady_comp) / 3;
	}

	/* do not exceed limit */
	if (comp + ratio >= MAX_TARGET_RATIO)
		comp = MAX_TARGET_RATIO - ratio - 1;

	return comp;
}

static void adjust_compensation(int target_ratio, unsigned int win)
{
	int delta;
	struct powerclamp_calibration_data *d = &cal_data[target_ratio];

	/*
	 * adjust compensations if confidence level has not been reached.
	 */
	if (d->confidence >= CONFIDENCE_OK)
		return;

	delta = powerclamp_data.target_ratio - current_ratio;
	/* filter out bad data */
	if (delta >= 0 && delta <= (1+target_ratio/10)) {
		if (d->steady_comp)
			d->steady_comp =
				roundup(delta+d->steady_comp, 2)/2;
		else
			d->steady_comp = delta;
		d->confidence++;
	}
}

static bool powerclamp_adjust_controls(unsigned int target_ratio,
				unsigned int guard, unsigned int win)
{
	static u64 msr_last, tsc_last;
	u64 msr_now, tsc_now;
	u64 val64;

	/* check result for the last window */
	msr_now = pkg_state_counter();
	tsc_now = rdtsc();

	/* calculate pkg cstate vs tsc ratio */
	if (!msr_last || !tsc_last)
		current_ratio = 1;
	else if (tsc_now-tsc_last) {
		val64 = 100*(msr_now-msr_last);
		do_div(val64, (tsc_now-tsc_last));
		current_ratio = val64;
	}

	/* update record */
	msr_last = msr_now;
	tsc_last = tsc_now;

	adjust_compensation(target_ratio, win);

	/* if we are above target+guard, skip */
	return powerclamp_data.target_ratio + guard <= current_ratio;
}

/*
 * This function calculates runtime from the current target ratio.
 * This function gets called under powerclamp_lock.
 */
static unsigned int get_run_time(void)
{
	unsigned int compensated_ratio;
	unsigned int runtime;

	/*
	 * make sure user selected ratio does not take effect until
	 * the next round. adjust target_ratio if user has changed
	 * target such that we can converge quickly.
	 */
	powerclamp_data.guard = 1 + powerclamp_data.target_ratio / 20;
	powerclamp_data.window_size_now = window_size;

	/*
	 * systems may have different ability to enter package level
	 * c-states, thus we need to compensate the injected idle ratio
	 * to achieve the actual target reported by the HW.
	 */
	compensated_ratio = powerclamp_data.target_ratio +
		get_compensation(powerclamp_data.target_ratio);
	if (compensated_ratio <= 0)
		compensated_ratio = 1;

	runtime = duration * 100 / compensated_ratio - duration;

	return runtime;
}

/*
 * 1 HZ polling while clamping is active, useful for userspace
 * to monitor actual idle ratio.
 */
static void poll_pkg_cstate(struct work_struct *dummy);
static DECLARE_DELAYED_WORK(poll_pkg_cstate_work, poll_pkg_cstate);
static void poll_pkg_cstate(struct work_struct *dummy)
{
	static u64 msr_last;
	static u64 tsc_last;

	u64 msr_now;
	u64 tsc_now;
	u64 val64;

	msr_now = pkg_state_counter();
	tsc_now = rdtsc();

	/* calculate pkg cstate vs tsc ratio */
	if (!msr_last || !tsc_last)
		pkg_cstate_ratio_cur = 1;
	else {
		if (tsc_now - tsc_last) {
			val64 = 100 * (msr_now - msr_last);
			do_div(val64, (tsc_now - tsc_last));
			pkg_cstate_ratio_cur = val64;
		}
	}

	/* update record */
	msr_last = msr_now;
	tsc_last = tsc_now;

	mutex_lock(&powerclamp_lock);
	if (powerclamp_data.clamping)
		schedule_delayed_work(&poll_pkg_cstate_work, HZ);
	mutex_unlock(&powerclamp_lock);
}

static struct idle_inject_device *ii_dev;

/*
 * This function is called from idle injection core on timer expiry
 * for the run duration. This allows powerclamp to readjust or skip
 * injecting idle for this cycle.
 */
static bool idle_inject_update(void)
{
	bool update = false;

	/* We can't sleep in this callback */
	if (!mutex_trylock(&powerclamp_lock))
		return true;

	if (!(powerclamp_data.count % powerclamp_data.window_size_now)) {

		should_skip = powerclamp_adjust_controls(powerclamp_data.target_ratio,
							 powerclamp_data.guard,
							 powerclamp_data.window_size_now);
		update = true;
	}

	if (update) {
		unsigned int runtime = get_run_time();

		idle_inject_set_duration(ii_dev, runtime, duration);
	}

	powerclamp_data.count++;

	mutex_unlock(&powerclamp_lock);

	if (should_skip)
		return false;

	return true;
}

/* This function starts idle injection by calling idle_inject_start() */
static void trigger_idle_injection(void)
{
	unsigned int runtime = get_run_time();

	idle_inject_set_duration(ii_dev, runtime, duration);
	idle_inject_start(ii_dev);
	powerclamp_data.clamping = true;
}

/*
 * This function is called from start_power_clamp() to register
 * CPUS with powercap idle injection register and set default
 * idle duration and latency.
 */
static int powerclamp_idle_injection_register(void)
{
	poll_pkg_cstate_enable = false;
	if (cpumask_equal(cpu_present_mask, idle_injection_cpu_mask)) {
		ii_dev = idle_inject_register_full(idle_injection_cpu_mask, idle_inject_update);
		if (topology_max_packages() == 1 && topology_max_dies_per_package() == 1)
			poll_pkg_cstate_enable = true;
	} else {
		ii_dev = idle_inject_register(idle_injection_cpu_mask);
	}

	if (!ii_dev) {
		pr_err("powerclamp: idle_inject_register failed\n");
		return -EAGAIN;
	}

	idle_inject_set_duration(ii_dev, TICK_USEC, duration);
	idle_inject_set_latency(ii_dev, UINT_MAX);

	return 0;
}

/*
 * This function is called from end_power_clamp() to stop idle injection
 * and unregister CPUS from powercap idle injection core.
 */
static void remove_idle_injection(void)
{
	if (!powerclamp_data.clamping)
		return;

	powerclamp_data.clamping = false;
	idle_inject_stop(ii_dev);
}

/*
 * This function is called when user change the cooling device
 * state from zero to some other value.
 */
static int start_power_clamp(void)
{
	int ret;

	ret = powerclamp_idle_injection_register();
	if (!ret) {
		trigger_idle_injection();
		if (poll_pkg_cstate_enable)
			schedule_delayed_work(&poll_pkg_cstate_work, 0);
	}

	return ret;
}

/*
 * This function is called when user change the cooling device
 * state from non zero value zero.
 */
static void end_power_clamp(void)
{
	if (powerclamp_data.clamping) {
		remove_idle_injection();
		idle_inject_unregister(ii_dev);
	}
}

static int powerclamp_get_max_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	*state = MAX_TARGET_RATIO;

	return 0;
}

static int powerclamp_get_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	mutex_lock(&powerclamp_lock);
	*state = powerclamp_data.target_ratio;
	mutex_unlock(&powerclamp_lock);

	return 0;
}

static int powerclamp_set_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long new_target_ratio)
{
	int ret = 0;

	mutex_lock(&powerclamp_lock);

	new_target_ratio = clamp(new_target_ratio, 0UL,
				(unsigned long) (max_idle - 1));

	if (powerclamp_data.target_ratio == new_target_ratio)
		goto exit_set;

	if (!powerclamp_data.target_ratio && new_target_ratio > 0) {
		pr_info("Start idle injection to reduce power\n");
		powerclamp_data.target_ratio = new_target_ratio;
		ret = start_power_clamp();
		if (ret)
			powerclamp_data.target_ratio = 0;
		goto exit_set;
	} else	if (powerclamp_data.target_ratio > 0 && new_target_ratio == 0) {
		pr_info("Stop forced idle injection\n");
		end_power_clamp();
		powerclamp_data.target_ratio = 0;
	} else	/* adjust currently running */ {
		unsigned int runtime;

		powerclamp_data.target_ratio = new_target_ratio;
		runtime = get_run_time();
		idle_inject_set_duration(ii_dev, runtime, duration);
	}

exit_set:
	mutex_unlock(&powerclamp_lock);

	return ret;
}

/* bind to generic thermal layer as cooling device*/
static const struct thermal_cooling_device_ops powerclamp_cooling_ops = {
	.get_max_state = powerclamp_get_max_state,
	.get_cur_state = powerclamp_get_cur_state,
	.set_cur_state = powerclamp_set_cur_state,
};

static const struct x86_cpu_id __initconst intel_powerclamp_ids[] = {
	X86_MATCH_VENDOR_FEATURE(INTEL, X86_FEATURE_MWAIT, NULL),
	{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);

static int __init powerclamp_probe(void)
{

	if (!x86_match_cpu(intel_powerclamp_ids)) {
		pr_err("CPU does not support MWAIT\n");
		return -ENODEV;
	}

	/* The goal for idle time alignment is to achieve package cstate. */
	if (!has_pkg_state_counter()) {
		pr_info("No package C-state available\n");
		return -ENODEV;
	}

	return 0;
}

static int powerclamp_debug_show(struct seq_file *m, void *unused)
{
	int i = 0;

	seq_printf(m, "pct confidence steady dynamic (compensation)\n");
	for (i = 0; i < MAX_TARGET_RATIO; i++) {
		seq_printf(m, "%d\t%lu\t%lu\t%lu\n",
			i,
			cal_data[i].confidence,
			cal_data[i].steady_comp,
			cal_data[i].dynamic_comp);
	}

	return 0;
}

DEFINE_SHOW_ATTRIBUTE(powerclamp_debug);

static inline void powerclamp_create_debug_files(void)
{
	debug_dir = debugfs_create_dir("intel_powerclamp", NULL);

	debugfs_create_file("powerclamp_calib", S_IRUGO, debug_dir, cal_data,
			    &powerclamp_debug_fops);
}

static int __init powerclamp_init(void)
{
	int retval;

	/* probe cpu features and ids here */
	retval = powerclamp_probe();
	if (retval)
		return retval;

	mutex_lock(&powerclamp_lock);
	if (!cpumask_available(idle_injection_cpu_mask))
		retval = allocate_copy_idle_injection_mask(cpu_present_mask);
	mutex_unlock(&powerclamp_lock);

	if (retval)
		return retval;

	/* set default limit, maybe adjusted during runtime based on feedback */
	window_size = 2;

	cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL,
						      &powerclamp_cooling_ops);
	if (IS_ERR(cooling_dev))
		return -ENODEV;

	if (!duration)
		duration = jiffies_to_usecs(DEFAULT_DURATION_JIFFIES);

	powerclamp_create_debug_files();

	return 0;
}
module_init(powerclamp_init);

static void __exit powerclamp_exit(void)
{
	mutex_lock(&powerclamp_lock);
	end_power_clamp();
	mutex_unlock(&powerclamp_lock);

	thermal_cooling_device_unregister(cooling_dev);

	cancel_delayed_work_sync(&poll_pkg_cstate_work);
	debugfs_remove_recursive(debug_dir);

	if (cpumask_available(idle_injection_cpu_mask))
		free_cpumask_var(idle_injection_cpu_mask);
}
module_exit(powerclamp_exit);

MODULE_IMPORT_NS(IDLE_INJECT);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@linux.intel.com>");
MODULE_DESCRIPTION("Package Level C-state Idle Injection for Intel CPUs");
