// SPDX-License-Identifier: MIT
/*
 * Copyright © 2020 Intel Corporation
 */

#include <linux/pm_qos.h>
#include <linux/sort.h>

#include "intel_engine_heartbeat.h"
#include "intel_engine_pm.h"
#include "intel_gpu_commands.h"
#include "intel_gt_clock_utils.h"
#include "intel_gt_pm.h"
#include "intel_rc6.h"
#include "selftest_engine_heartbeat.h"
#include "selftest_rps.h"
#include "selftests/igt_flush_test.h"
#include "selftests/igt_spinner.h"
#include "selftests/librapl.h"

/* Try to isolate the impact of cstates from determing frequency response */
#define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */

static void dummy_rps_work(struct work_struct *wrk)
{
}

static int cmp_u64(const void *A, const void *B)
{
	const u64 *a = A, *b = B;

	if (*a < *b)
		return -1;
	else if (*a > *b)
		return 1;
	else
		return 0;
}

static int cmp_u32(const void *A, const void *B)
{
	const u32 *a = A, *b = B;

	if (*a < *b)
		return -1;
	else if (*a > *b)
		return 1;
	else
		return 0;
}

static struct i915_vma *
create_spin_counter(struct intel_engine_cs *engine,
		    struct i915_address_space *vm,
		    bool srm,
		    u32 **cancel,
		    u32 **counter)
{
	enum {
		COUNT,
		INC,
		__NGPR__,
	};
#define CS_GPR(x) GEN8_RING_CS_GPR(engine->mmio_base, x)
	struct drm_i915_gem_object *obj;
	struct i915_vma *vma;
	unsigned long end;
	u32 *base, *cs;
	int loop, i;
	int err;

	obj = i915_gem_object_create_internal(vm->i915, 64 << 10);
	if (IS_ERR(obj))
		return ERR_CAST(obj);

	end = obj->base.size / sizeof(u32) - 1;

	vma = i915_vma_instance(obj, vm, NULL);
	if (IS_ERR(vma)) {
		err = PTR_ERR(vma);
		goto err_put;
	}

	err = i915_vma_pin(vma, 0, 0, PIN_USER);
	if (err)
		goto err_unlock;

	i915_vma_lock(vma);

	base = i915_gem_object_pin_map(obj, I915_MAP_WC);
	if (IS_ERR(base)) {
		err = PTR_ERR(base);
		goto err_unpin;
	}
	cs = base;

	*cs++ = MI_LOAD_REGISTER_IMM(__NGPR__ * 2);
	for (i = 0; i < __NGPR__; i++) {
		*cs++ = i915_mmio_reg_offset(CS_GPR(i));
		*cs++ = 0;
		*cs++ = i915_mmio_reg_offset(CS_GPR(i)) + 4;
		*cs++ = 0;
	}

	*cs++ = MI_LOAD_REGISTER_IMM(1);
	*cs++ = i915_mmio_reg_offset(CS_GPR(INC));
	*cs++ = 1;

	loop = cs - base;

	/* Unroll the loop to avoid MI_BB_START stalls impacting measurements */
	for (i = 0; i < 1024; i++) {
		*cs++ = MI_MATH(4);
		*cs++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(COUNT));
		*cs++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(INC));
		*cs++ = MI_MATH_ADD;
		*cs++ = MI_MATH_STORE(MI_MATH_REG(COUNT), MI_MATH_REG_ACCU);

		if (srm) {
			*cs++ = MI_STORE_REGISTER_MEM_GEN8;
			*cs++ = i915_mmio_reg_offset(CS_GPR(COUNT));
			*cs++ = lower_32_bits(vma->node.start + end * sizeof(*cs));
			*cs++ = upper_32_bits(vma->node.start + end * sizeof(*cs));
		}
	}

	*cs++ = MI_BATCH_BUFFER_START_GEN8;
	*cs++ = lower_32_bits(vma->node.start + loop * sizeof(*cs));
	*cs++ = upper_32_bits(vma->node.start + loop * sizeof(*cs));
	GEM_BUG_ON(cs - base > end);

	i915_gem_object_flush_map(obj);

	*cancel = base + loop;
	*counter = srm ? memset32(base + end, 0, 1) : NULL;
	return vma;

err_unpin:
	i915_vma_unpin(vma);
err_unlock:
	i915_vma_unlock(vma);
err_put:
	i915_gem_object_put(obj);
	return ERR_PTR(err);
}

static u8 wait_for_freq(struct intel_rps *rps, u8 freq, int timeout_ms)
{
	u8 history[64], i;
	unsigned long end;
	int sleep;

	i = 0;
	memset(history, freq, sizeof(history));
	sleep = 20;

	/* The PCU does not change instantly, but drifts towards the goal? */
	end = jiffies + msecs_to_jiffies(timeout_ms);
	do {
		u8 act;

		act = read_cagf(rps);
		if (time_after(jiffies, end))
			return act;

		/* Target acquired */
		if (act == freq)
			return act;

		/* Any change within the last N samples? */
		if (!memchr_inv(history, act, sizeof(history)))
			return act;

		history[i] = act;
		i = (i + 1) % ARRAY_SIZE(history);

		usleep_range(sleep, 2 * sleep);
		sleep *= 2;
		if (sleep > timeout_ms * 20)
			sleep = timeout_ms * 20;
	} while (1);
}

static u8 rps_set_check(struct intel_rps *rps, u8 freq)
{
	mutex_lock(&rps->lock);
	GEM_BUG_ON(!intel_rps_is_active(rps));
	if (wait_for(!intel_rps_set(rps, freq), 50)) {
		mutex_unlock(&rps->lock);
		return 0;
	}
	GEM_BUG_ON(rps->last_freq != freq);
	mutex_unlock(&rps->lock);

	return wait_for_freq(rps, freq, 50);
}

static void show_pstate_limits(struct intel_rps *rps)
{
	struct drm_i915_private *i915 = rps_to_i915(rps);

	if (IS_BROXTON(i915)) {
		pr_info("P_STATE_CAP[%x]: 0x%08x\n",
			i915_mmio_reg_offset(BXT_RP_STATE_CAP),
			intel_uncore_read(rps_to_uncore(rps),
					  BXT_RP_STATE_CAP));
	} else if (GRAPHICS_VER(i915) == 9) {
		pr_info("P_STATE_LIMITS[%x]: 0x%08x\n",
			i915_mmio_reg_offset(GEN9_RP_STATE_LIMITS),
			intel_uncore_read(rps_to_uncore(rps),
					  GEN9_RP_STATE_LIMITS));
	}
}

int live_rps_clock_interval(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	void (*saved_work)(struct work_struct *wrk);
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	int err = 0;

	if (!intel_rps_is_enabled(rps) || GRAPHICS_VER(gt->i915) < 6)
		return 0;

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	intel_gt_pm_get(gt);
	intel_rps_disable(&gt->rps);

	intel_gt_check_clock_frequency(gt);

	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		u32 cycles;
		u64 dt;

		if (!intel_engine_can_store_dword(engine))
			continue;

		st_engine_heartbeat_disable(engine);

		rq = igt_spinner_create_request(&spin,
						engine->kernel_context,
						MI_NOOP);
		if (IS_ERR(rq)) {
			st_engine_heartbeat_enable(engine);
			err = PTR_ERR(rq);
			break;
		}

		i915_request_add(rq);

		if (!igt_wait_for_spinner(&spin, rq)) {
			pr_err("%s: RPS spinner did not start\n",
			       engine->name);
			igt_spinner_end(&spin);
			st_engine_heartbeat_enable(engine);
			intel_gt_set_wedged(engine->gt);
			err = -EIO;
			break;
		}

		intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL);

		intel_uncore_write_fw(gt->uncore, GEN6_RP_CUR_UP_EI, 0);

		/* Set the evaluation interval to infinity! */
		intel_uncore_write_fw(gt->uncore,
				      GEN6_RP_UP_EI, 0xffffffff);
		intel_uncore_write_fw(gt->uncore,
				      GEN6_RP_UP_THRESHOLD, 0xffffffff);

		intel_uncore_write_fw(gt->uncore, GEN6_RP_CONTROL,
				      GEN6_RP_ENABLE | GEN6_RP_UP_BUSY_AVG);

		if (wait_for(intel_uncore_read_fw(gt->uncore,
						  GEN6_RP_CUR_UP_EI),
			     10)) {
			/* Just skip the test; assume lack of HW support */
			pr_notice("%s: rps evaluation interval not ticking\n",
				  engine->name);
			err = -ENODEV;
		} else {
			ktime_t dt_[5];
			u32 cycles_[5];
			int i;

			for (i = 0; i < 5; i++) {
				preempt_disable();

				dt_[i] = ktime_get();
				cycles_[i] = -intel_uncore_read_fw(gt->uncore, GEN6_RP_CUR_UP_EI);

				udelay(1000);

				dt_[i] = ktime_sub(ktime_get(), dt_[i]);
				cycles_[i] += intel_uncore_read_fw(gt->uncore, GEN6_RP_CUR_UP_EI);

				preempt_enable();
			}

			/* Use the median of both cycle/dt; close enough */
			sort(cycles_, 5, sizeof(*cycles_), cmp_u32, NULL);
			cycles = (cycles_[1] + 2 * cycles_[2] + cycles_[3]) / 4;
			sort(dt_, 5, sizeof(*dt_), cmp_u64, NULL);
			dt = div_u64(dt_[1] + 2 * dt_[2] + dt_[3], 4);
		}

		intel_uncore_write_fw(gt->uncore, GEN6_RP_CONTROL, 0);
		intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);

		igt_spinner_end(&spin);
		st_engine_heartbeat_enable(engine);

		if (err == 0) {
			u64 time = intel_gt_pm_interval_to_ns(gt, cycles);
			u32 expected =
				intel_gt_ns_to_pm_interval(gt, dt);

			pr_info("%s: rps counted %d C0 cycles [%lldns] in %lldns [%d cycles], using GT clock frequency of %uKHz\n",
				engine->name, cycles, time, dt, expected,
				gt->clock_frequency / 1000);

			if (10 * time < 8 * dt ||
			    8 * time > 10 * dt) {
				pr_err("%s: rps clock time does not match walltime!\n",
				       engine->name);
				err = -EINVAL;
			}

			if (10 * expected < 8 * cycles ||
			    8 * expected > 10 * cycles) {
				pr_err("%s: walltime does not match rps clock ticks!\n",
				       engine->name);
				err = -EINVAL;
			}
		}

		if (igt_flush_test(gt->i915))
			err = -EIO;

		break; /* once is enough */
	}

	intel_rps_enable(&gt->rps);
	intel_gt_pm_put(gt);

	igt_spinner_fini(&spin);

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	if (err == -ENODEV) /* skipped, don't report a fail */
		err = 0;

	return err;
}

int live_rps_control(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	void (*saved_work)(struct work_struct *wrk);
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	int err = 0;

	/*
	 * Check that the actual frequency matches our requested frequency,
	 * to verify our control mechanism. We have to be careful that the
	 * PCU may throttle the GPU in which case the actual frequency used
	 * will be lowered than requested.
	 */

	if (!intel_rps_is_enabled(rps))
		return 0;

	if (IS_CHERRYVIEW(gt->i915)) /* XXX fragile PCU */
		return 0;

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	intel_gt_pm_get(gt);
	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		ktime_t min_dt, max_dt;
		int f, limit;
		int min, max;

		if (!intel_engine_can_store_dword(engine))
			continue;

		st_engine_heartbeat_disable(engine);

		rq = igt_spinner_create_request(&spin,
						engine->kernel_context,
						MI_NOOP);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			break;
		}

		i915_request_add(rq);

		if (!igt_wait_for_spinner(&spin, rq)) {
			pr_err("%s: RPS spinner did not start\n",
			       engine->name);
			igt_spinner_end(&spin);
			st_engine_heartbeat_enable(engine);
			intel_gt_set_wedged(engine->gt);
			err = -EIO;
			break;
		}

		if (rps_set_check(rps, rps->min_freq) != rps->min_freq) {
			pr_err("%s: could not set minimum frequency [%x], only %x!\n",
			       engine->name, rps->min_freq, read_cagf(rps));
			igt_spinner_end(&spin);
			st_engine_heartbeat_enable(engine);
			show_pstate_limits(rps);
			err = -EINVAL;
			break;
		}

		for (f = rps->min_freq + 1; f < rps->max_freq; f++) {
			if (rps_set_check(rps, f) < f)
				break;
		}

		limit = rps_set_check(rps, f);

		if (rps_set_check(rps, rps->min_freq) != rps->min_freq) {
			pr_err("%s: could not restore minimum frequency [%x], only %x!\n",
			       engine->name, rps->min_freq, read_cagf(rps));
			igt_spinner_end(&spin);
			st_engine_heartbeat_enable(engine);
			show_pstate_limits(rps);
			err = -EINVAL;
			break;
		}

		max_dt = ktime_get();
		max = rps_set_check(rps, limit);
		max_dt = ktime_sub(ktime_get(), max_dt);

		min_dt = ktime_get();
		min = rps_set_check(rps, rps->min_freq);
		min_dt = ktime_sub(ktime_get(), min_dt);

		igt_spinner_end(&spin);
		st_engine_heartbeat_enable(engine);

		pr_info("%s: range:[%x:%uMHz, %x:%uMHz] limit:[%x:%uMHz], %x:%x response %lluns:%lluns\n",
			engine->name,
			rps->min_freq, intel_gpu_freq(rps, rps->min_freq),
			rps->max_freq, intel_gpu_freq(rps, rps->max_freq),
			limit, intel_gpu_freq(rps, limit),
			min, max, ktime_to_ns(min_dt), ktime_to_ns(max_dt));

		if (limit == rps->min_freq) {
			pr_err("%s: GPU throttled to minimum!\n",
			       engine->name);
			show_pstate_limits(rps);
			err = -ENODEV;
			break;
		}

		if (igt_flush_test(gt->i915)) {
			err = -EIO;
			break;
		}
	}
	intel_gt_pm_put(gt);

	igt_spinner_fini(&spin);

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	return err;
}

static void show_pcu_config(struct intel_rps *rps)
{
	struct drm_i915_private *i915 = rps_to_i915(rps);
	unsigned int max_gpu_freq, min_gpu_freq;
	intel_wakeref_t wakeref;
	int gpu_freq;

	if (!HAS_LLC(i915))
		return;

	min_gpu_freq = rps->min_freq;
	max_gpu_freq = rps->max_freq;
	if (GRAPHICS_VER(i915) >= 9) {
		/* Convert GT frequency to 50 HZ units */
		min_gpu_freq /= GEN9_FREQ_SCALER;
		max_gpu_freq /= GEN9_FREQ_SCALER;
	}

	wakeref = intel_runtime_pm_get(rps_to_uncore(rps)->rpm);

	pr_info("%5s  %5s  %5s\n", "GPU", "eCPU", "eRing");
	for (gpu_freq = min_gpu_freq; gpu_freq <= max_gpu_freq; gpu_freq++) {
		int ia_freq = gpu_freq;

		sandybridge_pcode_read(i915,
				       GEN6_PCODE_READ_MIN_FREQ_TABLE,
				       &ia_freq, NULL);

		pr_info("%5d  %5d  %5d\n",
			gpu_freq * 50,
			((ia_freq >> 0) & 0xff) * 100,
			((ia_freq >> 8) & 0xff) * 100);
	}

	intel_runtime_pm_put(rps_to_uncore(rps)->rpm, wakeref);
}

static u64 __measure_frequency(u32 *cntr, int duration_ms)
{
	u64 dc, dt;

	dt = ktime_get();
	dc = READ_ONCE(*cntr);
	usleep_range(1000 * duration_ms, 2000 * duration_ms);
	dc = READ_ONCE(*cntr) - dc;
	dt = ktime_get() - dt;

	return div64_u64(1000 * 1000 * dc, dt);
}

static u64 measure_frequency_at(struct intel_rps *rps, u32 *cntr, int *freq)
{
	u64 x[5];
	int i;

	*freq = rps_set_check(rps, *freq);
	for (i = 0; i < 5; i++)
		x[i] = __measure_frequency(cntr, 2);
	*freq = (*freq + read_cagf(rps)) / 2;

	/* A simple triangle filter for better result stability */
	sort(x, 5, sizeof(*x), cmp_u64, NULL);
	return div_u64(x[1] + 2 * x[2] + x[3], 4);
}

static u64 __measure_cs_frequency(struct intel_engine_cs *engine,
				  int duration_ms)
{
	u64 dc, dt;

	dt = ktime_get();
	dc = intel_uncore_read_fw(engine->uncore, CS_GPR(0));
	usleep_range(1000 * duration_ms, 2000 * duration_ms);
	dc = intel_uncore_read_fw(engine->uncore, CS_GPR(0)) - dc;
	dt = ktime_get() - dt;

	return div64_u64(1000 * 1000 * dc, dt);
}

static u64 measure_cs_frequency_at(struct intel_rps *rps,
				   struct intel_engine_cs *engine,
				   int *freq)
{
	u64 x[5];
	int i;

	*freq = rps_set_check(rps, *freq);
	for (i = 0; i < 5; i++)
		x[i] = __measure_cs_frequency(engine, 2);
	*freq = (*freq + read_cagf(rps)) / 2;

	/* A simple triangle filter for better result stability */
	sort(x, 5, sizeof(*x), cmp_u64, NULL);
	return div_u64(x[1] + 2 * x[2] + x[3], 4);
}

static bool scaled_within(u64 x, u64 y, u32 f_n, u32 f_d)
{
	return f_d * x > f_n * y && f_n * x < f_d * y;
}

int live_rps_frequency_cs(void *arg)
{
	void (*saved_work)(struct work_struct *wrk);
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	struct intel_engine_cs *engine;
	struct pm_qos_request qos;
	enum intel_engine_id id;
	int err = 0;

	/*
	 * The premise is that the GPU does change frequency at our behest.
	 * Let's check there is a correspondence between the requested
	 * frequency, the actual frequency, and the observed clock rate.
	 */

	if (!intel_rps_is_enabled(rps))
		return 0;

	if (GRAPHICS_VER(gt->i915) < 8) /* for CS simplicity */
		return 0;

	if (CPU_LATENCY >= 0)
		cpu_latency_qos_add_request(&qos, CPU_LATENCY);

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		struct i915_vma *vma;
		u32 *cancel, *cntr;
		struct {
			u64 count;
			int freq;
		} min, max;

		st_engine_heartbeat_disable(engine);

		vma = create_spin_counter(engine,
					  engine->kernel_context->vm, false,
					  &cancel, &cntr);
		if (IS_ERR(vma)) {
			err = PTR_ERR(vma);
			st_engine_heartbeat_enable(engine);
			break;
		}

		rq = intel_engine_create_kernel_request(engine);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			goto err_vma;
		}

		err = i915_request_await_object(rq, vma->obj, false);
		if (!err)
			err = i915_vma_move_to_active(vma, rq, 0);
		if (!err)
			err = rq->engine->emit_bb_start(rq,
							vma->node.start,
							PAGE_SIZE, 0);
		i915_request_add(rq);
		if (err)
			goto err_vma;

		if (wait_for(intel_uncore_read(engine->uncore, CS_GPR(0)),
			     10)) {
			pr_err("%s: timed loop did not start\n",
			       engine->name);
			goto err_vma;
		}

		min.freq = rps->min_freq;
		min.count = measure_cs_frequency_at(rps, engine, &min.freq);

		max.freq = rps->max_freq;
		max.count = measure_cs_frequency_at(rps, engine, &max.freq);

		pr_info("%s: min:%lluKHz @ %uMHz, max:%lluKHz @ %uMHz [%d%%]\n",
			engine->name,
			min.count, intel_gpu_freq(rps, min.freq),
			max.count, intel_gpu_freq(rps, max.freq),
			(int)DIV64_U64_ROUND_CLOSEST(100 * min.freq * max.count,
						     max.freq * min.count));

		if (!scaled_within(max.freq * min.count,
				   min.freq * max.count,
				   2, 3)) {
			int f;

			pr_err("%s: CS did not scale with frequency! scaled min:%llu, max:%llu\n",
			       engine->name,
			       max.freq * min.count,
			       min.freq * max.count);
			show_pcu_config(rps);

			for (f = min.freq + 1; f <= rps->max_freq; f++) {
				int act = f;
				u64 count;

				count = measure_cs_frequency_at(rps, engine, &act);
				if (act < f)
					break;

				pr_info("%s: %x:%uMHz: %lluKHz [%d%%]\n",
					engine->name,
					act, intel_gpu_freq(rps, act), count,
					(int)DIV64_U64_ROUND_CLOSEST(100 * min.freq * count,
								     act * min.count));

				f = act; /* may skip ahead [pcu granularity] */
			}

			err = -EINTR; /* ignore error, continue on with test */
		}

err_vma:
		*cancel = MI_BATCH_BUFFER_END;
		i915_gem_object_flush_map(vma->obj);
		i915_gem_object_unpin_map(vma->obj);
		i915_vma_unpin(vma);
		i915_vma_unlock(vma);
		i915_vma_put(vma);

		st_engine_heartbeat_enable(engine);
		if (igt_flush_test(gt->i915))
			err = -EIO;
		if (err)
			break;
	}

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	if (CPU_LATENCY >= 0)
		cpu_latency_qos_remove_request(&qos);

	return err;
}

int live_rps_frequency_srm(void *arg)
{
	void (*saved_work)(struct work_struct *wrk);
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	struct intel_engine_cs *engine;
	struct pm_qos_request qos;
	enum intel_engine_id id;
	int err = 0;

	/*
	 * The premise is that the GPU does change frequency at our behest.
	 * Let's check there is a correspondence between the requested
	 * frequency, the actual frequency, and the observed clock rate.
	 */

	if (!intel_rps_is_enabled(rps))
		return 0;

	if (GRAPHICS_VER(gt->i915) < 8) /* for CS simplicity */
		return 0;

	if (CPU_LATENCY >= 0)
		cpu_latency_qos_add_request(&qos, CPU_LATENCY);

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		struct i915_vma *vma;
		u32 *cancel, *cntr;
		struct {
			u64 count;
			int freq;
		} min, max;

		st_engine_heartbeat_disable(engine);

		vma = create_spin_counter(engine,
					  engine->kernel_context->vm, true,
					  &cancel, &cntr);
		if (IS_ERR(vma)) {
			err = PTR_ERR(vma);
			st_engine_heartbeat_enable(engine);
			break;
		}

		rq = intel_engine_create_kernel_request(engine);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			goto err_vma;
		}

		err = i915_request_await_object(rq, vma->obj, false);
		if (!err)
			err = i915_vma_move_to_active(vma, rq, 0);
		if (!err)
			err = rq->engine->emit_bb_start(rq,
							vma->node.start,
							PAGE_SIZE, 0);
		i915_request_add(rq);
		if (err)
			goto err_vma;

		if (wait_for(READ_ONCE(*cntr), 10)) {
			pr_err("%s: timed loop did not start\n",
			       engine->name);
			goto err_vma;
		}

		min.freq = rps->min_freq;
		min.count = measure_frequency_at(rps, cntr, &min.freq);

		max.freq = rps->max_freq;
		max.count = measure_frequency_at(rps, cntr, &max.freq);

		pr_info("%s: min:%lluKHz @ %uMHz, max:%lluKHz @ %uMHz [%d%%]\n",
			engine->name,
			min.count, intel_gpu_freq(rps, min.freq),
			max.count, intel_gpu_freq(rps, max.freq),
			(int)DIV64_U64_ROUND_CLOSEST(100 * min.freq * max.count,
						     max.freq * min.count));

		if (!scaled_within(max.freq * min.count,
				   min.freq * max.count,
				   1, 2)) {
			int f;

			pr_err("%s: CS did not scale with frequency! scaled min:%llu, max:%llu\n",
			       engine->name,
			       max.freq * min.count,
			       min.freq * max.count);
			show_pcu_config(rps);

			for (f = min.freq + 1; f <= rps->max_freq; f++) {
				int act = f;
				u64 count;

				count = measure_frequency_at(rps, cntr, &act);
				if (act < f)
					break;

				pr_info("%s: %x:%uMHz: %lluKHz [%d%%]\n",
					engine->name,
					act, intel_gpu_freq(rps, act), count,
					(int)DIV64_U64_ROUND_CLOSEST(100 * min.freq * count,
								     act * min.count));

				f = act; /* may skip ahead [pcu granularity] */
			}

			err = -EINTR; /* ignore error, continue on with test */
		}

err_vma:
		*cancel = MI_BATCH_BUFFER_END;
		i915_gem_object_flush_map(vma->obj);
		i915_gem_object_unpin_map(vma->obj);
		i915_vma_unpin(vma);
		i915_vma_unlock(vma);
		i915_vma_put(vma);

		st_engine_heartbeat_enable(engine);
		if (igt_flush_test(gt->i915))
			err = -EIO;
		if (err)
			break;
	}

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	if (CPU_LATENCY >= 0)
		cpu_latency_qos_remove_request(&qos);

	return err;
}

static void sleep_for_ei(struct intel_rps *rps, int timeout_us)
{
	/* Flush any previous EI */
	usleep_range(timeout_us, 2 * timeout_us);

	/* Reset the interrupt status */
	rps_disable_interrupts(rps);
	GEM_BUG_ON(rps->pm_iir);
	rps_enable_interrupts(rps);

	/* And then wait for the timeout, for real this time */
	usleep_range(2 * timeout_us, 3 * timeout_us);
}

static int __rps_up_interrupt(struct intel_rps *rps,
			      struct intel_engine_cs *engine,
			      struct igt_spinner *spin)
{
	struct intel_uncore *uncore = engine->uncore;
	struct i915_request *rq;
	u32 timeout;

	if (!intel_engine_can_store_dword(engine))
		return 0;

	rps_set_check(rps, rps->min_freq);

	rq = igt_spinner_create_request(spin, engine->kernel_context, MI_NOOP);
	if (IS_ERR(rq))
		return PTR_ERR(rq);

	i915_request_get(rq);
	i915_request_add(rq);

	if (!igt_wait_for_spinner(spin, rq)) {
		pr_err("%s: RPS spinner did not start\n",
		       engine->name);
		i915_request_put(rq);
		intel_gt_set_wedged(engine->gt);
		return -EIO;
	}

	if (!intel_rps_is_active(rps)) {
		pr_err("%s: RPS not enabled on starting spinner\n",
		       engine->name);
		igt_spinner_end(spin);
		i915_request_put(rq);
		return -EINVAL;
	}

	if (!(rps->pm_events & GEN6_PM_RP_UP_THRESHOLD)) {
		pr_err("%s: RPS did not register UP interrupt\n",
		       engine->name);
		i915_request_put(rq);
		return -EINVAL;
	}

	if (rps->last_freq != rps->min_freq) {
		pr_err("%s: RPS did not program min frequency\n",
		       engine->name);
		i915_request_put(rq);
		return -EINVAL;
	}

	timeout = intel_uncore_read(uncore, GEN6_RP_UP_EI);
	timeout = intel_gt_pm_interval_to_ns(engine->gt, timeout);
	timeout = DIV_ROUND_UP(timeout, 1000);

	sleep_for_ei(rps, timeout);
	GEM_BUG_ON(i915_request_completed(rq));

	igt_spinner_end(spin);
	i915_request_put(rq);

	if (rps->cur_freq != rps->min_freq) {
		pr_err("%s: Frequency unexpectedly changed [up], now %d!\n",
		       engine->name, intel_rps_read_actual_frequency(rps));
		return -EINVAL;
	}

	if (!(rps->pm_iir & GEN6_PM_RP_UP_THRESHOLD)) {
		pr_err("%s: UP interrupt not recorded for spinner, pm_iir:%x, prev_up:%x, up_threshold:%x, up_ei:%x\n",
		       engine->name, rps->pm_iir,
		       intel_uncore_read(uncore, GEN6_RP_PREV_UP),
		       intel_uncore_read(uncore, GEN6_RP_UP_THRESHOLD),
		       intel_uncore_read(uncore, GEN6_RP_UP_EI));
		return -EINVAL;
	}

	return 0;
}

static int __rps_down_interrupt(struct intel_rps *rps,
				struct intel_engine_cs *engine)
{
	struct intel_uncore *uncore = engine->uncore;
	u32 timeout;

	rps_set_check(rps, rps->max_freq);

	if (!(rps->pm_events & GEN6_PM_RP_DOWN_THRESHOLD)) {
		pr_err("%s: RPS did not register DOWN interrupt\n",
		       engine->name);
		return -EINVAL;
	}

	if (rps->last_freq != rps->max_freq) {
		pr_err("%s: RPS did not program max frequency\n",
		       engine->name);
		return -EINVAL;
	}

	timeout = intel_uncore_read(uncore, GEN6_RP_DOWN_EI);
	timeout = intel_gt_pm_interval_to_ns(engine->gt, timeout);
	timeout = DIV_ROUND_UP(timeout, 1000);

	sleep_for_ei(rps, timeout);

	if (rps->cur_freq != rps->max_freq) {
		pr_err("%s: Frequency unexpectedly changed [down], now %d!\n",
		       engine->name,
		       intel_rps_read_actual_frequency(rps));
		return -EINVAL;
	}

	if (!(rps->pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT))) {
		pr_err("%s: DOWN interrupt not recorded for idle, pm_iir:%x, prev_down:%x, down_threshold:%x, down_ei:%x [prev_up:%x, up_threshold:%x, up_ei:%x]\n",
		       engine->name, rps->pm_iir,
		       intel_uncore_read(uncore, GEN6_RP_PREV_DOWN),
		       intel_uncore_read(uncore, GEN6_RP_DOWN_THRESHOLD),
		       intel_uncore_read(uncore, GEN6_RP_DOWN_EI),
		       intel_uncore_read(uncore, GEN6_RP_PREV_UP),
		       intel_uncore_read(uncore, GEN6_RP_UP_THRESHOLD),
		       intel_uncore_read(uncore, GEN6_RP_UP_EI));
		return -EINVAL;
	}

	return 0;
}

int live_rps_interrupt(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	void (*saved_work)(struct work_struct *wrk);
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	u32 pm_events;
	int err = 0;

	/*
	 * First, let's check whether or not we are receiving interrupts.
	 */

	if (!intel_rps_has_interrupts(rps) || GRAPHICS_VER(gt->i915) < 6)
		return 0;

	intel_gt_pm_get(gt);
	pm_events = rps->pm_events;
	intel_gt_pm_put(gt);
	if (!pm_events) {
		pr_err("No RPS PM events registered, but RPS is enabled?\n");
		return -ENODEV;
	}

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	for_each_engine(engine, gt, id) {
		/* Keep the engine busy with a spinner; expect an UP! */
		if (pm_events & GEN6_PM_RP_UP_THRESHOLD) {
			intel_gt_pm_wait_for_idle(engine->gt);
			GEM_BUG_ON(intel_rps_is_active(rps));

			st_engine_heartbeat_disable(engine);

			err = __rps_up_interrupt(rps, engine, &spin);

			st_engine_heartbeat_enable(engine);
			if (err)
				goto out;

			intel_gt_pm_wait_for_idle(engine->gt);
		}

		/* Keep the engine awake but idle and check for DOWN */
		if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) {
			st_engine_heartbeat_disable(engine);
			intel_rc6_disable(&gt->rc6);

			err = __rps_down_interrupt(rps, engine);

			intel_rc6_enable(&gt->rc6);
			st_engine_heartbeat_enable(engine);
			if (err)
				goto out;
		}
	}

out:
	if (igt_flush_test(gt->i915))
		err = -EIO;

	igt_spinner_fini(&spin);

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	return err;
}

static u64 __measure_power(int duration_ms)
{
	u64 dE, dt;

	dt = ktime_get();
	dE = librapl_energy_uJ();
	usleep_range(1000 * duration_ms, 2000 * duration_ms);
	dE = librapl_energy_uJ() - dE;
	dt = ktime_get() - dt;

	return div64_u64(1000 * 1000 * dE, dt);
}

static u64 measure_power_at(struct intel_rps *rps, int *freq)
{
	u64 x[5];
	int i;

	*freq = rps_set_check(rps, *freq);
	for (i = 0; i < 5; i++)
		x[i] = __measure_power(5);
	*freq = (*freq + read_cagf(rps)) / 2;

	/* A simple triangle filter for better result stability */
	sort(x, 5, sizeof(*x), cmp_u64, NULL);
	return div_u64(x[1] + 2 * x[2] + x[3], 4);
}

int live_rps_power(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	void (*saved_work)(struct work_struct *wrk);
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	int err = 0;

	/*
	 * Our fundamental assumption is that running at lower frequency
	 * actually saves power. Let's see if our RAPL measurement support
	 * that theory.
	 */

	if (!intel_rps_is_enabled(rps) || GRAPHICS_VER(gt->i915) < 6)
		return 0;

	if (!librapl_supported(gt->i915))
		return 0;

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	intel_gt_pm_wait_for_idle(gt);
	saved_work = rps->work.func;
	rps->work.func = dummy_rps_work;

	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		struct {
			u64 power;
			int freq;
		} min, max;

		if (!intel_engine_can_store_dword(engine))
			continue;

		st_engine_heartbeat_disable(engine);

		rq = igt_spinner_create_request(&spin,
						engine->kernel_context,
						MI_NOOP);
		if (IS_ERR(rq)) {
			st_engine_heartbeat_enable(engine);
			err = PTR_ERR(rq);
			break;
		}

		i915_request_add(rq);

		if (!igt_wait_for_spinner(&spin, rq)) {
			pr_err("%s: RPS spinner did not start\n",
			       engine->name);
			igt_spinner_end(&spin);
			st_engine_heartbeat_enable(engine);
			intel_gt_set_wedged(engine->gt);
			err = -EIO;
			break;
		}

		max.freq = rps->max_freq;
		max.power = measure_power_at(rps, &max.freq);

		min.freq = rps->min_freq;
		min.power = measure_power_at(rps, &min.freq);

		igt_spinner_end(&spin);
		st_engine_heartbeat_enable(engine);

		pr_info("%s: min:%llumW @ %uMHz, max:%llumW @ %uMHz\n",
			engine->name,
			min.power, intel_gpu_freq(rps, min.freq),
			max.power, intel_gpu_freq(rps, max.freq));

		if (10 * min.freq >= 9 * max.freq) {
			pr_notice("Could not control frequency, ran at [%d:%uMHz, %d:%uMhz]\n",
				  min.freq, intel_gpu_freq(rps, min.freq),
				  max.freq, intel_gpu_freq(rps, max.freq));
			continue;
		}

		if (11 * min.power > 10 * max.power) {
			pr_err("%s: did not conserve power when setting lower frequency!\n",
			       engine->name);
			err = -EINVAL;
			break;
		}

		if (igt_flush_test(gt->i915)) {
			err = -EIO;
			break;
		}
	}

	igt_spinner_fini(&spin);

	intel_gt_pm_wait_for_idle(gt);
	rps->work.func = saved_work;

	return err;
}

int live_rps_dynamic(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_rps *rps = &gt->rps;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	int err = 0;

	/*
	 * We've looked at the bascs, and have established that we
	 * can change the clock frequency and that the HW will generate
	 * interrupts based on load. Now we check how we integrate those
	 * moving parts into dynamic reclocking based on load.
	 */

	if (!intel_rps_is_enabled(rps) || GRAPHICS_VER(gt->i915) < 6)
		return 0;

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	if (intel_rps_has_interrupts(rps))
		pr_info("RPS has interrupt support\n");
	if (intel_rps_uses_timer(rps))
		pr_info("RPS has timer support\n");

	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		struct {
			ktime_t dt;
			u8 freq;
		} min, max;

		if (!intel_engine_can_store_dword(engine))
			continue;

		intel_gt_pm_wait_for_idle(gt);
		GEM_BUG_ON(intel_rps_is_active(rps));
		rps->cur_freq = rps->min_freq;

		intel_engine_pm_get(engine);
		intel_rc6_disable(&gt->rc6);
		GEM_BUG_ON(rps->last_freq != rps->min_freq);

		rq = igt_spinner_create_request(&spin,
						engine->kernel_context,
						MI_NOOP);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			goto err;
		}

		i915_request_add(rq);

		max.dt = ktime_get();
		max.freq = wait_for_freq(rps, rps->max_freq, 500);
		max.dt = ktime_sub(ktime_get(), max.dt);

		igt_spinner_end(&spin);

		min.dt = ktime_get();
		min.freq = wait_for_freq(rps, rps->min_freq, 2000);
		min.dt = ktime_sub(ktime_get(), min.dt);

		pr_info("%s: dynamically reclocked to %u:%uMHz while busy in %lluns, and %u:%uMHz while idle in %lluns\n",
			engine->name,
			max.freq, intel_gpu_freq(rps, max.freq),
			ktime_to_ns(max.dt),
			min.freq, intel_gpu_freq(rps, min.freq),
			ktime_to_ns(min.dt));
		if (min.freq >= max.freq) {
			pr_err("%s: dynamic reclocking of spinner failed\n!",
			       engine->name);
			err = -EINVAL;
		}

err:
		intel_rc6_enable(&gt->rc6);
		intel_engine_pm_put(engine);

		if (igt_flush_test(gt->i915))
			err = -EIO;
		if (err)
			break;
	}

	igt_spinner_fini(&spin);

	return err;
}
