// SPDX-License-Identifier: GPL-2.0-only
/*
 * Performance events - AMD Processor Power Reporting Mechanism
 *
 * Copyright (C) 2016 Advanced Micro Devices, Inc.
 *
 * Author: Huang Rui <ray.huang@amd.com>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <asm/cpu_device_id.h>
#include "../perf_event.h"

/* Event code: LSB 8 bits, passed in attr->config any other bit is reserved. */
#define AMD_POWER_EVENT_MASK		0xFFULL

/*
 * Accumulated power status counters.
 */
#define AMD_POWER_EVENTSEL_PKG		1

/*
 * The ratio of compute unit power accumulator sample period to the
 * PTSC period.
 */
static unsigned int cpu_pwr_sample_ratio;

/* Maximum accumulated power of a compute unit. */
static u64 max_cu_acc_power;

static struct pmu pmu_class;

/*
 * Accumulated power represents the sum of each compute unit's (CU) power
 * consumption. On any core of each CU we read the total accumulated power from
 * MSR_F15H_CU_PWR_ACCUMULATOR. cpu_mask represents CPU bit map of all cores
 * which are picked to measure the power for the CUs they belong to.
 */
static cpumask_t cpu_mask;

static void event_update(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	u64 prev_pwr_acc, new_pwr_acc, prev_ptsc, new_ptsc;
	u64 delta, tdelta;

	prev_pwr_acc = hwc->pwr_acc;
	prev_ptsc = hwc->ptsc;
	rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, new_pwr_acc);
	rdmsrl(MSR_F15H_PTSC, new_ptsc);

	/*
	 * Calculate the CU power consumption over a time period, the unit of
	 * final value (delta) is micro-Watts. Then add it to the event count.
	 */
	if (new_pwr_acc < prev_pwr_acc) {
		delta = max_cu_acc_power + new_pwr_acc;
		delta -= prev_pwr_acc;
	} else
		delta = new_pwr_acc - prev_pwr_acc;

	delta *= cpu_pwr_sample_ratio * 1000;
	tdelta = new_ptsc - prev_ptsc;

	do_div(delta, tdelta);
	local64_add(delta, &event->count);
}

static void __pmu_event_start(struct perf_event *event)
{
	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
		return;

	event->hw.state = 0;

	rdmsrl(MSR_F15H_PTSC, event->hw.ptsc);
	rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, event->hw.pwr_acc);
}

static void pmu_event_start(struct perf_event *event, int mode)
{
	__pmu_event_start(event);
}

static void pmu_event_stop(struct perf_event *event, int mode)
{
	struct hw_perf_event *hwc = &event->hw;

	/* Mark event as deactivated and stopped. */
	if (!(hwc->state & PERF_HES_STOPPED))
		hwc->state |= PERF_HES_STOPPED;

	/* Check if software counter update is necessary. */
	if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
		/*
		 * Drain the remaining delta count out of an event
		 * that we are disabling:
		 */
		event_update(event);
		hwc->state |= PERF_HES_UPTODATE;
	}
}

static int pmu_event_add(struct perf_event *event, int mode)
{
	struct hw_perf_event *hwc = &event->hw;

	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;

	if (mode & PERF_EF_START)
		__pmu_event_start(event);

	return 0;
}

static void pmu_event_del(struct perf_event *event, int flags)
{
	pmu_event_stop(event, PERF_EF_UPDATE);
}

static int pmu_event_init(struct perf_event *event)
{
	u64 cfg = event->attr.config & AMD_POWER_EVENT_MASK;

	/* Only look at AMD power events. */
	if (event->attr.type != pmu_class.type)
		return -ENOENT;

	/* Unsupported modes and filters. */
	if (event->attr.sample_period)
		return -EINVAL;

	if (cfg != AMD_POWER_EVENTSEL_PKG)
		return -EINVAL;

	return 0;
}

static void pmu_event_read(struct perf_event *event)
{
	event_update(event);
}

static ssize_t
get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf)
{
	return cpumap_print_to_pagebuf(true, buf, &cpu_mask);
}

static DEVICE_ATTR(cpumask, S_IRUGO, get_attr_cpumask, NULL);

static struct attribute *pmu_attrs[] = {
	&dev_attr_cpumask.attr,
	NULL,
};

static struct attribute_group pmu_attr_group = {
	.attrs = pmu_attrs,
};

/*
 * Currently it only supports to report the power of each
 * processor/package.
 */
EVENT_ATTR_STR(power-pkg, power_pkg, "event=0x01");

EVENT_ATTR_STR(power-pkg.unit, power_pkg_unit, "mWatts");

/* Convert the count from micro-Watts to milli-Watts. */
EVENT_ATTR_STR(power-pkg.scale, power_pkg_scale, "1.000000e-3");

static struct attribute *events_attr[] = {
	EVENT_PTR(power_pkg),
	EVENT_PTR(power_pkg_unit),
	EVENT_PTR(power_pkg_scale),
	NULL,
};

static struct attribute_group pmu_events_group = {
	.name	= "events",
	.attrs	= events_attr,
};

PMU_FORMAT_ATTR(event, "config:0-7");

static struct attribute *formats_attr[] = {
	&format_attr_event.attr,
	NULL,
};

static struct attribute_group pmu_format_group = {
	.name	= "format",
	.attrs	= formats_attr,
};

static const struct attribute_group *attr_groups[] = {
	&pmu_attr_group,
	&pmu_format_group,
	&pmu_events_group,
	NULL,
};

static struct pmu pmu_class = {
	.attr_groups	= attr_groups,
	/* system-wide only */
	.task_ctx_nr	= perf_invalid_context,
	.event_init	= pmu_event_init,
	.add		= pmu_event_add,
	.del		= pmu_event_del,
	.start		= pmu_event_start,
	.stop		= pmu_event_stop,
	.read		= pmu_event_read,
	.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
	.module		= THIS_MODULE,
};

static int power_cpu_exit(unsigned int cpu)
{
	int target;

	if (!cpumask_test_and_clear_cpu(cpu, &cpu_mask))
		return 0;

	/*
	 * Find a new CPU on the same compute unit, if was set in cpumask
	 * and still some CPUs on compute unit. Then migrate event and
	 * context to new CPU.
	 */
	target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
	if (target < nr_cpumask_bits) {
		cpumask_set_cpu(target, &cpu_mask);
		perf_pmu_migrate_context(&pmu_class, cpu, target);
	}
	return 0;
}

static int power_cpu_init(unsigned int cpu)
{
	int target;

	/*
	 * 1) If any CPU is set at cpu_mask in the same compute unit, do
	 * nothing.
	 * 2) If no CPU is set at cpu_mask in the same compute unit,
	 * set current ONLINE CPU.
	 *
	 * Note: if there is a CPU aside of the new one already in the
	 * sibling mask, then it is also in cpu_mask.
	 */
	target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
	if (target >= nr_cpumask_bits)
		cpumask_set_cpu(cpu, &cpu_mask);
	return 0;
}

static const struct x86_cpu_id cpu_match[] = {
	X86_MATCH_VENDOR_FAM(AMD, 0x15, NULL),
	{},
};

static int __init amd_power_pmu_init(void)
{
	int ret;

	if (!x86_match_cpu(cpu_match))
		return -ENODEV;

	if (!boot_cpu_has(X86_FEATURE_ACC_POWER))
		return -ENODEV;

	cpu_pwr_sample_ratio = cpuid_ecx(0x80000007);

	if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &max_cu_acc_power)) {
		pr_err("Failed to read max compute unit power accumulator MSR\n");
		return -ENODEV;
	}


	cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_POWER_ONLINE,
			  "perf/x86/amd/power:online",
			  power_cpu_init, power_cpu_exit);

	ret = perf_pmu_register(&pmu_class, "power", -1);
	if (WARN_ON(ret)) {
		pr_warn("AMD Power PMU registration failed\n");
		return ret;
	}

	pr_info("AMD Power PMU detected\n");
	return ret;
}
module_init(amd_power_pmu_init);

static void __exit amd_power_pmu_exit(void)
{
	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_AMD_POWER_ONLINE);
	perf_pmu_unregister(&pmu_class);
}
module_exit(amd_power_pmu_exit);

MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
MODULE_DESCRIPTION("AMD Processor Power Reporting Mechanism");
MODULE_LICENSE("GPL v2");
